Problem with code (serial.print exceed?) -<solved> :)

Hello everyone, i'm trying to make a code for arduino UNO to get info about diferent sensors.

I don't know why but i'm having troubles with Serial.print commands, if i add too much serial.print commands the code doesn't works well at Serial COM Print.

I add my code here.. i tested the different functions and all works well alone or with some one.. but ALL together it doesn't work, and impossible to add more code cause doesn't work too..

I tried to use strings to avoid serial.prints but nothing, also serial.print(f(. ..), and nothing

I'm reall really surprised with this problem and i couldn't get any solution searching on internet (maybe bad question to google?)

here it goes, thanks in advance

// STRINGS AHORRO DE SERIAL.PRINT

String TIEMPO = "Tiempo Prueba HH:MM:SS";
String CO2 = "CO2 Expulsado en PPM";
String VOLUM = "Caudal Aire Actual L/min";


//CONTADOR TIEMPO PRUEBA

int segundos=0; // segundos total
int minutos=0; // minutos total
int horas=0; // horas total


// CAUDAL L/MIN

int caudal; //Variável para armazenar o valor em L/min
int contaPulso; //Variável para a quantidade de pulsos
int i=0; //Variável para contagem

// CO2

int sensorValue;


void setup()
{ 
  Serial.begin(9600); //Inicia a serial com um baud rate de 9600
  
  
  pinMode(2, INPUT);
  attachInterrupt(0, incpulso, RISING); //Configura o pino 2(Interrupção 0) para trabalhar como interrupção  
} 


void loop ()
{
   TiempoTotal(); 
   DIOXIDO();
   LitrosMinuto();
 
}
 
//
void incpulso ()
{ 
  contaPulso++; //Incrementa a variável de contagem dos pulsos
} 

//
void TiempoTotal ()   //TIEMPO TOTAL PRUEBA  (reloj hh:mm:ss)
{  
  segundos++;
  i++;  
  TIEMPO = "\n\nTiempo Prueba ";
  TIEMPO += horas;
  TIEMPO += ":";
  TIEMPO += minutos;
  TIEMPO += ":";
  TIEMPO += segundos;
  TIEMPO += "s";
  Serial.println(TIEMPO);
  

    // Contador Tiempo total
  
    if(segundos==59)
    {
      minutos++;
      segundos=-1;
    }
  
    if(minutos==59)
    {
      horas++;
      minutos=-1;
    }
}


//
void DIOXIDO()
{
  sensorValue = analogRead(0);       // read analog input pin 0  at MQ-135

  CO2 = "CO2 Expulsado ";
  CO2 += (sensorValue*2);
  CO2 += " ppm";
  Serial.println(CO2);
}

//
void LitrosMinuto()   //  Caudalímetro
{

  contaPulso = 0;   //Zera a variável para contar os giros por segundos
  sei();      //Habilita interrupção
  delay (1000); //Aguarda 1 segundo
  cli();      //Desabilita interrupção
  
  caudal = contaPulso / 5.5; //Converte para L/min 

  VOLUM = "Caudal Aire ";
  VOLUM += caudal;
  VOLUM += " L/min";
  Serial.println(VOLUM);

 }

Serial COM get stack at frist just with this:

Tiempo Prueba 0:0:1s
CO2 Expulsado 846 ppm

wish anyone could help.. i want to add temperature sensor, pulsioximeter, etc..
thanks!

alfcasmo

Disabling interrupts breaks serial, because Serial uses interrupts in the background to feed data to the UART.

Also - coding style note - to keep your code from confusing others, or yourself later on, don't use variable names that look like register names. TIEMPO looks like it could be the name of a hardware register (all caps, 3-8 letters/numbers - my brain saw TIEMP0)

Don't understand (sorry.. i'm still a newbie).. but at flowmeter i use interrupts and i can see perfectly the liters/minute.

You can try just deleting the rest of the functions but not "litrosminutos()" and it works :S :frowning:

thanks DrAzzy !

Anyone can give me any idea? :[ thanks

alfcasmo:
Don't understand (sorry.. i'm still a newbie).. but at flowmeter i use interrupts and i can see perfectly the liters/minute.

This piece of code:

  sei();      //Habilita interrupção
  delay (1000); //Aguarda 1 segundo
  cli();      //Desabilita interrupção

makes "Serial" hang for one second each time this code is running.

As it looks to me, you are calling this piece of code all the time. So Serial is blocked all the time.

Don't block interrupts for longer than a few microseconds(!), such as copying variables during the time!

And don't use "delay()" to interrupt and block all the program execution of "normal code".

The overall programming logic in your program is not correct.

The String class is incredibly wasteful of memory. What you are doing there should just fit but it could be running out of memory which will cause strange results.

Change:

 TIEMPO = "\n\nTiempo Prueba ";
  TIEMPO += horas;
  TIEMPO += ":";
  TIEMPO += minutos;
  TIEMPO += ":";
  TIEMPO += segundos;
  TIEMPO += "s";
  Serial.println(TIEMPO);

to:

 Serial.println();
  Serial.print(F("Tiempo Prueba "));
  Serial.print(horas);
  Serial.print(':');
  Serial.print(minutos);
  Serial.print(':');
  Serial.print(segundos);
  Serial.print('s');

There's three things I've done there:

  1. Instead of constructing a string to be sent out, just send it out!
  2. Use the F() macro so that larger strings are stored in flash memory and don't occupy RAM.
  3. For single characters, use single quotes - this saves RAM and one byte of program space too.

I've firstly tried just send it out with serial print, also including F() macro, i tried your code, and also put down the delay to the interrupt to 10 ms.. and nothing, the serial output gets stack :frowning:

Don't know if the problem is too much serial.prints together, the strings also doesn't work well, or what happens :frowning: i'm getting crazy, i'm 2 days working just on solving this :[

thanks anyways!

alfcasmo:
Don’t know if the problem is too much serial.prints together, the strings also doesn’t work well, or what happens :frowning: i’m getting crazy, i’m 2 days working just on solving this :[

I don’t understand any Spanish, but I tried to work over your code to fix the problems:

//CONTADOR TIEMPO PRUEBA
int segundos=0; // segundos total
int minutos=0; // minutos total
int horas=0; // horas total

volatile int contaPulso_ISR; //Variável para a quantidade de pulsos for interrupt handling

boolean countSeconds()
{
  // Contador Tiempo total
  // returns true after 1 second has passed
  static unsigned long lastMillis;
  if (millis()-lastMillis<1000) return false;
  lastMillis+=1000;
  segundos++;
  if(segundos==60)
  {
    segundos=0;
    minutos++;
    if(minutos==60)
    {
      minutos=0;
      horas++;
    }
  }
  return true; // second has changed
}


void setup()
{ 
  Serial.begin(9600); //Inicia a serial com um baud rate de 9600
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, incpulso_ISR, RISING); //Configura o pino 2(Interrupção 0) para trabalhar como interrupção  
} 


void loop ()
{
  if (countSeconds())
  {
     TiempoTotal(); 
     DIOXIDO();
     LitrosMinuto();
  }
}
 

void incpulso_ISR ()
{ 
  contaPulso_ISR++; //Incrementa a variável de contagem dos pulsos
} 


void TiempoTotal ()   //TIEMPO TOTAL PRUEBA  (reloj hh:mm:ss)
{  
  char buf[41];
  snprintf(buf,sizeof(buf),"\n\nTiempo Prueba %02d:%02d:%02ds", horas, minutos, segundos);
  Serial.println(buf);
}


//
void DIOXIDO()
{
  int sensorValue = analogRead(0);       // read analog input pin 0  at MQ-135
  char buf[41];
  snprintf(buf,sizeof(buf),"CO2 Expulsado %d ppm", sensorValue*2);
  Serial.println(buf);
}

//
void LitrosMinuto()   //  Caudalímetro
{
  char buf[41];
  cli();      //Desabilita interrupção
  int contaPulso= contaPulso_ISR; //Variável para a quantidade de pulsos for handling in normal code
  contaPulso_ISR=0; // reset counter in ISR
  sei();      //Habilita interrupção

  int caudal = contaPulso / 5.5; //Converte para L/min 
  snprintf(buf,sizeof(buf),"Caudal Aire %d  L/min", caudal);
  Serial.println(buf);
 }

wow Really thanks jurs.. i don't know well what you've done.. i have to study that part :wink: but it's working pretty nice without any problem and no stacks or interrupts at serial port com.

thanks a lot.. hard to be a newbie :stuck_out_tongue:

alfcasmo:
wow Really thanks jurs.. i don't know well what you've done.. i have to study that part :wink:

Then please study about:

Variables have to be declared 'volatile' if the same variable is accessed by normal code and by interrupt handling code.

Variables, that are changed within interrupt handling code and also in normal code, must be accessed and changed in normal code while interrupts are disabled.

Time while interrupts are disabled has to be very, very short.

alfcasmo:
but it's working pretty nice without any problem and no stacks or interrupts at serial port com.

The serial output buffer can take up to 63 chars for sending, then the output buffer is full. If you want to send more than 63 chars at once, this is not possible. If any chars you want to send cannot be stuffed into the serial output buffer, the Serial.print command will delay your program: First some chars must be actually sent, then the next char can be put into the output buffer. If everything is put into the serial putput buffer, the print function will return while the chars are actually sent in the background.

So your program can get "delay()" in it, even if you do not use the delay() function, but if you try to send more chars than will fit into the serial output buffer.

So if your loop() function has to run without any delays, you perhaps better not send all chars for all the values to show at the same time, but in time slices: At the change of the second send time, 100ms later send ppm CO2 value, 100ms later send flow rate.

At least: Do not try to send more than 63 characters at once to Serial if you don't want unwanted delay() appearing in your program.

Thaaaanksss you sooo much! best answer i could ever imagined :stuck_out_tongue: didn't know about 63 characters at once as max. and so on.

I will stuy well all you said to learn :slight_smile:

10 stars jurs :slight_smile:

Variables, that are changed within interrupt handling code and also in normal code, must be accessed and changed in normal code while interrupts are disabled.

Only if they're wider than a byte.