Arduino Communication Crashes after some time Running

Hi everyone,

I'm having a problem with the Serial communication between Arduino and a Software that I made in C#.

The problem is, after some time running my communication is lost and replugging USB is needed or restart the PC.

Well the code is very simple:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1);
 
int Sensor_Linha1 = 0;     //Sensor que fará a leitura de luminosidade da primeira linha de luminárias
int DescarregarCap = 0;
const int LedWake          =       13;  //Led que informa que o sistema está em funcionamento.
int atrasoMsg = 50;

boolean Comunicando=0;

int BotaoCalibrar = 8;
int BotaoTeste = 9;

int EstadoBotaoCalibrar;
int EstadoBotaoTeste;

int Leitura_Linha1;     // Valor lido do sensor Linha 1
long acumulador = 0;
int amostras = 2000;
float Peso = 0;
long PesoInt = 0;
float AjusteFino = -2545.5;

int contador = 0;//variável utilizada para chamar Wake

float ConstanteCurva = 5.6692;




void Wake()
{
  digitalWrite(LedWake, HIGH);
  delay(50);
  digitalWrite(LedWake, LOW);

  Comunicando = ~Comunicando;
  if(Comunicando)
  mySerial.println("Balanca_110712v1.0.1 WAKE0000");
  else
  mySerial.println("Balanca_110712v1.0.1 WAKE0001"); 
  mySerial.flush(); 
}

void setup(void) 
{
  // We'll send debugging information via the Serial monitor
  mySerial.begin(9600); 
  mySerial.flush();
  pinMode(LedWake, OUTPUT);
  pinMode(BotaoCalibrar, INPUT);
  pinMode(BotaoTeste, INPUT);
  //Events.addHandler(Wake, 5000); //5segs
}
 
 
 
void Testar()
{
    mySerial.print("Realizando Leitura");
    delay(atrasoMsg);
    mySerial.println("LEDT0001 ");     //Envia o código que o Teste está em andamento
    delay(300);
    mySerial.flush(); 
  
    acumulador = 0;
    for(int count = 0; count<amostras; count++)
    {
      acumulador = acumulador+analogRead(Sensor_Linha1);
      delay(1);
    }
    Leitura_Linha1 = acumulador/amostras;
    mySerial.print("Medicao ");
    delay(atrasoMsg);
    mySerial.print(Leitura_Linha1);
    delay(atrasoMsg);
    
    Peso = ConstanteCurva*Leitura_Linha1+AjusteFino; 
    PesoInt = 1.666666*Peso;//PESO DIVIDIDO POR 6, ANTES ERA 10*PESO, MAS VAMOS PESAR 6 PLACAS POR VEZ
    
    
    if(PesoInt < 0)
    PesoInt = 0;
    
    //O valor comparado já é o de uma placa multiplicado por 10
    if(1200<PesoInt && PesoInt<1500)
    {
      mySerial.print("Aprovada ");
      delay(atrasoMsg);
      mySerial.print(" LEDA0001 ");            //Polo Esquerdo
      mySerial.print(" LEDR0000 ");            //Polo Esquerdo
      delay(atrasoMsg);
    }
    else
    {
      mySerial.print("Reprovada");
      delay(atrasoMsg);
      mySerial.print(" LEDA0000 ");            //Polo Esquerdo
      mySerial.print(" LEDR0001 ");            //Polo Esquerdo
      delay(atrasoMsg);
    }
    
    mySerial.print("Resultado ");
    mySerial.print(" PESO");            //Polo Esquerdo
    delay(atrasoMsg);
    mySerial.print(PesoInt+1000);
    delay(atrasoMsg);
    mySerial.print(" LEDT0000 ");     //Envia o código que o Teste está em andamento
    delay(atrasoMsg);
    mySerial.println("PLOT0001");
    delay(atrasoMsg);
    mySerial.flush(); 
}

void Calibrar()
{
  
    mySerial.print("Realizando Calibracao");
    delay(atrasoMsg);
    mySerial.println("CALB0001 ");     //Envia o código que o Teste está em andamento 
    delay(300);
    mySerial.flush(); 
    
    
    analogRead(DescarregarCap);
    delay(300);
    
    acumulador = 0;
    for(int count = 0; count<amostras; count++)
    {
      acumulador = acumulador+analogRead(Sensor_Linha1);
      delay(1);
    }
    AjusteFino = -ConstanteCurva*acumulador/amostras;
    
    mySerial.print("Fim de Calibracao ");
    delay(atrasoMsg);
    mySerial.println(" CALB0000 "); 
    delay(atrasoMsg);
    mySerial.flush(); 
}

 
 
 
 
void loop(void) {
  EstadoBotaoTeste = digitalRead(BotaoTeste);
  EstadoBotaoCalibrar = digitalRead(BotaoCalibrar);
  
  
  
  if(EstadoBotaoTeste)
  {
    Testar();  
  }

  if(EstadoBotaoCalibrar)
  {
    Calibrar();
    Testar();
  }
  contador++;//incrementa contador
  if(contador>20)
  {
    contador=0;
    Wake();
  }
  delay(50);
}

The circuit is very simple, I have just one signal 0-5V that is sent to the Analog Pin A0 and a USB cable that send this to the computer.
In the C# I use the Serial.Datareceived() event to do something with this value.

Both programs (Arduino and Desktop) run just fine for a while, until the communication crashes :confused:

Maybe the problem is because I'm trying to use this in a Industrial enviroment and we have a lot of noise in the power lines.

Well, please if someone can help me, just do it! 8)

Thanks a lot in advance :grin:
Best regards.

Unfortunately since English is the only language I know, it's difficult for me to read that code. It's exactly like reading code that's been lightly obfuscated. However if noise on the power lines is an issue, a capacitor in front of the arduino's power might help. Since the arduino uses so little power even a small capacitor should be able to help some.

Maybe you didnt want this

Reading in your code i see contador ++ in your main loop
I guess you wanted some delay before calling that action if (contador>20)...
However note that adding +1 to a int value will go fine, until it reaches the maximum value of an int.
After that it simply starts over counting from zerro again > and so you code to enable communication (and state check) is run again
not sure if you intended it but then Comunicando = ~Comunicando; is called again too

did you want a small delay or is it okay to do this (because i'm not speaking the language its bit harder to see what you want).

It can also be that buffers on the computer side fill up (or data logging becomes to much, computer out of disk space, and computer becomes non responsive). Other option can indeed be, that power is not stable enough, both computer and arduino relay on stable power.
Zener diodes can give pretty stable power, wont protect i think for HF noice, Elco's can do that, magnetic on radio radiation is another thing.
if people do arch-welding nearby.. then thats terrible for electronics..

SoftwareSerial mySerial(0, 1);

Hardware serial uses pins 0 and 1. Why are you using SoftwareSerial?

PGTBOOS:
Maybe you didnt want this

Reading in your code i see contador ++ in your main loop
I guess you wanted some delay before calling that action if (contador>20)...
However note that adding +1 to a int value will go fine, until it reaches the maximum value of an int.
After that it simply starts over counting from zerro again > and so you code to enable communication (and state check) is run again
not sure if you intended it but then Comunicando = ~Comunicando; is called again too

did you want a small delay or is it okay to do this (because i'm not speaking the language its bit harder to see what you want).

It can also be that buffers on the computer side fill up (or data logging becomes to much, computer out of disk space, and computer becomes non responsive). Other option can indeed be, that power is not stable enough, both computer and arduino relay on stable power.
Zener diodes can give pretty stable power, wont protect i think for HF noice, Elco's can do that, magnetic on radio radiation is another thing.
if people do arch-welding nearby.. then thats terrible for electronics..

Hi PGTBOOS,

Well this counter is just to make a call to the Wake function every time that the contador reaches 20, before I tried to use the Aiko library and call the function every 2 seconds, but as you know my system is losting the Serial Communication and I'm trying a lot of solutions to stop this problem, and one thing that I thought, maybe the Aiko library is responsible, well I don't know, I'm just searching to the answers.

In my instalation we have all of sort of noise, and We have too some arch-welding marchines, in the same power lines of the arduino power suply is connected.

I tried to use a Nobreak and the problem continues.
Now I will try to use a new power source, Mean Well T50D (5V, 12V and 24V), http://www.plcsystems.by/catalog/meanwell/spec/t-50-spec.pdf.

Thanks for your help.
Best regards.

Hi Nick,

Yes you're right, I just thought that maybe the problem was the defalt serial library, than I'm trying to use the SerialSoftware.

I'm just trying every possible thing to stop the Communication Crashes problem :confused:

Thanks!

  mySerial.flush();

I don't think these do anything useful for you.

Try removing them, and going back to hardware serial.

what i tried to say is in simple
that your program has a counter delay that reaches 20
Your program will however often reach 20 and not once.

That might sound strange, just imagine it like this.

void setup{
byte i = 0;
Serial.begin(9600)};
void loop {
i=i+1   // a byte has a ma
serial.println(String(i));  
}

if you run above program you wil get an output that keeps counting fomr 0 to 255, it never gets to 256 as byte cannt store that number it starts over (or crashes).

to set a delay to run something only once (and a bit in the style you did..)

void loop{
runonce=0;
}
void loop{
i=i+1;
if ((i==20)&&(runonce==0)) { 
    //...do my stuff...     
    //...
    //.
    runonce =1;    // ensures this routine is never replayed again note arduino will reach this fast (miliseconds)
                        // you might as well put another AND to also check a pin for for a keypressed button switch, if you run without computer 
    }                   // & = AND symbol looks a bit strange in this text editor

}

As for your power suply concerns, archwelding sure is a problem.
Today i was also reading about PLC's they are more robust..
But looking at their schematics, i noticed they make heavy use of zener diodes
and for 'worse conditions' use optical connections so their main processors never get into contact with the electrical outside world.
But .. also.. their micro controllers, dont talk c++
well effectively neither does arduino (as c++ is compiled to machine code), both run machine code.
But it seams PLC's are compared to arduino development.. surprisingly ... old (but proven) technology; ladder diagrams.. instead of C++

but i'm drifting off
the main point their boards never make contact to the outside electrical world. optical couplers, or zenerdiode protectoin, or relays.
their boxes, inside metal cases (cave of Faraday against electric radiation (radio waves etc)).
If your from india.. it might pay of to build (and put to internet market a board that does do such electrical protection for arduino)
allready there is a rugged arduino version which has some more protection (but not all).. you might try them

for testing purposes.. just create a simple different program
that prints over serial an increasing number
and be sure that you keep recieving numbers
if it stops .. and it is simple .. and it doesnt stop at the maximum value for a varaible type
then sure it is electrical interference... if it is that.. buy another main arduino chip, (most likely it will becomme defective of such strange powers), be sure the arduino chip only has a bootloader >> check ebay to buy a new one.
dont use chips that where once damaged by electrical dis charge. (those chips are cheaper then the boards) >> a good board has a chip that can be replaced (not soldered on the board) >> demilove or the rugged version (uno is soldered not to prefer)