0

Arduino Uno is connected with PC. In 100 ms intervals PC sends command and then Arduino changes outputs (they control relays through transoptors) and sends an answer (sensors data). After some time (eg. after 100 cycles or after 1000 cycles) Arduino restarts and then I lose connection with it. Code:

//#define DEBUG

#include <OneWire.h>
#include <DallasTemperature.h>

const byte OUTPUT_ARRAY_SIZE = 8;
const byte INPUT_ANALOG_ARRAY_SIZE = 4;

//pins
const byte pinPresse[INPUT_ANALOG_ARRAY_SIZE] = {A0, A1, A2, A3}; //sensors 0-5V
const byte pinTemp[1] = {13}; //temperature sensor/ 1-Wire
const byte pinOut[OUTPUT_ARRAY_SIZE] = {3, 4, 5, 6, 7, 8, 9, 10}; //8 outputs
const byte pinLevel[1] = {12}; //sensor 0-1
const byte pinSecu = 11; //security pin, turns a motor off

//sensors data
unsigned int inputPresse[4] = {0, 0, 0, 0}; //0...1023: 0...400bar
unsigned int inputTemp[1] = {0}; //oC
unsigned int inputLevel[1] = {0}; //LOW/HIGH

//data from pc
bool output[8] =       {1, 1, 1, 1, 1, 1, 1, 1}; 
bool outputPrev[8] =   {1, 1, 1, 1, 1, 1, 1, 1}; 

unsigned long currentMillis=0;
bool flag1 = false;

//temperature sensor/ 1 Wire DS
OneWire oneWire(pinTemp[0]);
DallasTemperature tempSensor(&oneWire);

void setup() {
  //pull-up
  for (int i = 0; i < OUTPUT_ARRAY_SIZE; i++) {
    digitalWrite(pinOut[i], HIGH);
  }
  digitalWrite(pinSecu, HIGH);
  Serial.begin(115200);
  for (int i = 0; i < OUTPUT_ARRAY_SIZE; i++) {
    pinMode(pinOut[i], OUTPUT);
    digitalWrite(pinOut[i], HIGH);
  }
  pinMode(pinSecu, OUTPUT);
  digitalWrite(pinSecu, LOW);
  for (int i = 0; i < INPUT_ANALOG_ARRAY_SIZE; i++) {
    pinMode(pinPresse[i], INPUT);
  }
  pinMode(pinLevel[0], INPUT);
  tempSensor.begin();  
  delay(500);
  digitalWrite(pinSecu, HIGH);
  while(!Serial){
    ;
  }
  Serial.print("READY@");
}

void loop() {
  if( flag1 && millis() - currentMillis > 3000 ) {
      error("0RESET@");
  }

  if (Serial.available()) {
    currentMillis = millis(); 
    readSerial();
    readSensors();
    printResults();
    setOutputs();
    flag1 = true;
#ifdef DEBUG
    Serial.print("Elapsed [ms]: "); Serial.println(millis()-currentMillis); 
#endif
  }
}

void readSerial() {
  String inputString = "";
  byte i = 0;
  char inChar;
  while (i < OUTPUT_ARRAY_SIZE) {
    while (!Serial.available()) {
        if( flag1 && millis() - currentMillis > 3000 ) {
          error("1RESET@");
         }
    }
    inChar = (char)Serial.read();
    if (inChar == 'Q'){
      error((char*)"2RESET@");
    }
    else if (inChar == ';') {
      setValue(&i, &inputString);
      inputString = "";
      i++;
    }
    else inputString += inChar;
  }
}

void setValue(const byte *i, const String *inputString) {
  output[*i] = inputString->toInt();
}

void readSensors() {
    //0-1 sensor
    inputLevel[0] = digitalRead(pinLevel[0]);
    //0-5v sensors
    for (int i = 0; i < INPUT_ANALOG_ARRAY_SIZE; i++) {
      pinMode(pinPresse[i], INPUT);
      inputPresse[i] = analogRead(pinPresse[i]);
    }
    //temperature/ 1-Wire
    if(flag1) {
      inputTemp[0] = tempSensor.getTempCByIndex(0);
    }
    tempSensor.requestTemperatures();
}

void printResults() {
    for (int i = 0; i < INPUT_ANALOG_ARRAY_SIZE; i++) {
      Serial.print(inputPresse[i]);
      Serial.print(';');
    }     
    Serial.print(inputTemp[0]);
    Serial.print(';'); 
    Serial.print(inputLevel[0]);
    Serial.print(';'); 
    Serial.print("@");
}

void setOutputs() {
  if (output[0] == LOW || outputPrev[0] == LOW) {
    digitalWrite(pinSecu, LOW);
  }
  else {
    digitalWrite(pinSecu, HIGH);
  }  
  for (int i = 0; i < OUTPUT_ARRAY_SIZE; i++) { 
    if (output[i] != outputPrev[i]) {
      digitalWrite(pinOut[i], output[i]);
    } 
    outputPrev[i] = output[i];
  }
}

void error(char *code) {
  Serial.print(code);
  Serial.flush();
  softwareReset();
}

void softwareReset() {
  asm volatile ("jmp 0");
}

I suspect memory leakage. But where?

12
  • Post your loop() code. Why the one-element arrays? Planning to expand them later? – CrossRoads Feb 25 '19 at 15:10
  • loop() is under of setup(). I use one element arrays because I'm going to expand them. – kot Feb 25 '19 at 15:17
  • I'll make String object global, I think it may help. Or just replace it with char[]? – kot Feb 25 '19 at 15:19
  • The only way for the Arduino to reset, is when it detected a brown-out, reset-button is pressed, watchdog timer times out, or a jmp 0. Only the first and last could apply in your case. So it's either a power issue, or you code sees an error and resets itself. It seems like you'd need to make your PC software handle serial connection interruptions, anyways (otherwise, what's the point of having the Arduino reset itself, if the PC software can't handle this). And then look into whether your arduino code resets itself, or not, and why. – Gerben Feb 25 '19 at 16:32
  • why flag1 and it is never set back to false? – Juraj Feb 25 '19 at 18:32

Browse other questions tagged or ask your own question.