[Solved] Serial print works for Mega but not Uno/Nano 328p

Hello everyone,
I have this weird behavior when I loaded the below codes into 2 different Arduino. It works fine for the Mega, but print gibberish on the Uno. The program purpose is to take ADC readings for 8 channels for 100 times (I know Uno only has six so I repeated A5 and A6) when there is an external trigger on Pin 2 and 3 (In my code, I actually didn't even use this, I just hard coded it to 1 to make it run). After taking ADC readings and store to a 100 element arrays (8 of them). I then calculate the energy level and try to display it using Serial.print, baudrate is 9600 (I tried different baudrate but it didn't help). Looking for insights/advices from everyone. Thank you,
Below is the code


#include <Arduino.h>
#include <SPI.h>


//global for interrupt  
volatile byte RunA = 0, RunB = 0;

boolean blnRunA, blnRunB;

/* setup */
void setup()
{
   
    //External interrupt stuff
    cli(); //Disable interrupt for setup
    attachInterrupt(digitalPinToInterrupt(2),TriggerA,HIGH); 
    attachInterrupt(digitalPinToInterrupt(3),TriggerB,HIGH);

  
  //Dummy initial read to initialize all ADC
   analogRead(0);
   analogRead(1);
   analogRead(2);
   analogRead(3);
   analogRead(4);
   analogRead(5);

   blnRunA = false;
   blnRunB = false; 

   //delay 100ms to make sure everything initialize 
   delay(100);

   sei(); //Enable interrupt for setup
  

   Serial.begin(9600);
   delay(1000);
   Serial.println("Starting");

   RunA = 1; RunB = 1; //Hard coded to test program

}

/* loop */
void loop()
{
  //Declare variables
  uint32_t tStart_a, tCal_a, micro_cal_a;
  uint32_t tStart_b, tCal_b, micro_cal_b;
  uint16_t A0[100], A1[100], A2[100], A3[100];
  uint16_t A4[100], A5[100], A6[100], A7[100];
  float  R, Stime, ta, tb;
  char *stringresult_a [] = {"N/A", "N/A", "N/A", "N/A"};
  char *stringresult_b [] = {"N/A", "N/A", "N/A", "N/A"}; 
  unsigned long StartTimer;
  char chr_ta[16]; char chr_tb [16];
  int ea [4] = {0}, eb[4] = {0};
 
  //Initialize values
   float EnerThreshold = 1000;
   float Vref = 5.0; float ADC_res = 1024; float Voffset = 0.5;
   float E0 = 0.0, E1 =0.0, E2 = 0.0, E3 = 0.0;
   float E4 = 0.0, E5 =0.0, E6 = 0.0, E7 = 0.0;
   
    //ADC stuff    
    R = 1.4; //1.4 ohm nomial, multiply by 10 to get integer
    Stime = 0.4; //sampling time is about 400 microsecond
    ta = tb = 0.0;
    while ((RunA == 0) && (RunB ==0)) {} //Do nothing if no trigger
    if (RunA == 1)  {
          StartTimer = millis(); 
          tStart_a = micros();  
          for (int i=0; i<100; i++) {
              A0[i] = analogRead(0);
              A1[i] = analogRead(1);
              A2[i] = analogRead(2);
              A3[i] = analogRead(3);                                                
         }//end of for loop -- Data taking loop side A
           micro_cal_a = micros();
           tCal_a = micro_cal_a - tStart_a; //Total Data taking time
           ta = float(tCal_a)/1000.0; //convert to ms
           blnRunA = true; //Make sure it only runs once
           //******************************Process data SIDE A************************************
           //  Array to make coding cleaner
          //Convert 10bit ADC raw data to Energy, E = I^2*R*t (nominal = 7^2*1.4*5ms ~ 343mJ)
          for (int i = 0; i<100; i++) {
              E0 = E0 + sq((float(A0[i])*Vref/ADC_res - Voffset)/0.4)*R*Stime;
              E1 = E1 + sq((float(A1[i])*Vref/ADC_res - Voffset)/0.4)*R*Stime;
              E2 = E2 + sq((float(A2[i])*Vref/ADC_res - Voffset)/0.4)*R*Stime;
              E3 = E3 + sq((float(A3[i])*Vref/ADC_res - Voffset)/0.4)*R*Stime;
                      
          } //i loop
           ea[0] = int (E0);
           ea[1] = int (E1);
           ea[2] = int (E2);
           ea[3] = int (E3);
           dtostrf(ta,8,3,chr_ta); 
             //Assign Energy (string) to an array
             
              Serial.println ("Pulse A received. Waiting for pulse B trigger.");
              while((RunB == 0) & (millis()-StartTimer <2000)) {} //either Pulse B received in 2s or timeout occurs
            //********************************************SIDE B********************************
            //If Pulse B also detected
              if (RunB == 1)  { 
                  Serial.println ("Pulse A and B received.");
                  tStart_b = micros();
                  for (int i=0; i<100; i++) { 
                    A4[i] = analogRead(4);
                    A5[i] = analogRead(5);
                    A6[i] = analogRead(4);
                    A7[i] = analogRead(5);                   
                  }        
                  micro_cal_b = micros();
                  tCal_b = micro_cal_b - tStart_b; //Total Data taking time side B
                  tb = float(tCal_b)/1000.0; //convert to ms
                  dtostrf(tb,8,3,chr_tb);
                  delay(100);
          //******************************Process data SIDE B************************************    
                  for (int i = 0; i<100; i++) {
                      E4 = E4 + sq((float(A4[i])*Vref/ADC_res - Voffset)/0.4)*R*Stime;
                      E5 = E5 + sq((float(A5[i])*Vref/ADC_res - Voffset)/0.4)*R*Stime;
                      E6 = E6 + sq((float(A6[i])*Vref/ADC_res - Voffset)/0.4)*R*Stime;
                      E7 = E7 + sq((float(A7[i])*Vref/ADC_res - Voffset)/0.4)*R*Stime;                     
                   } //i loop                  
                   eb[0] = int (E4);
                   eb[1] = int (E5);
                   eb[2] = int (E6);
                   eb[3] = int (E7);
                   //Display Pulse B info
                   Serial.println("Side B");                     
                    for (int j=0;j<4;j++){
                        if (eb[j] > int(EnerThreshold)){
                          stringresult_b[j] = " mJ  Pass";
                          Serial.print("EB ");Serial.print(eb[j]);Serial.println (stringresult_b[j]);
                        
                        } else 
                        {
                          stringresult_b[j] = "mJ Fail";
                          Serial.print("EB ");Serial.print(eb[j]);Serial.println (stringresult_b[j]);
                        }
                    }
                    Serial.print("Sampling time ");Serial.println(chr_tb);
                    
                    //Display pulse A info
                    Serial.println("Side A");
                    for (int j=0;j<4;j++){
                        if (ea[j] >int (EnerThreshold)){
                           stringresult_a[j] = "mJ  Pass";
                           Serial.print("EA ");Serial.print(ea[j]);Serial.println (stringresult_a[j]);
                          
                        } else 
                        {
                          stringresult_a[j] = "mJ Fail";
                          Serial.print("EA ");Serial.print(ea[j]);Serial.println (stringresult_a[j]);
                        }
                     } 
                    Serial.print("Sampling time ");Serial.println(chr_ta);                                                        
             }
             //No pulse B detected, only display pulse A
           else {
                //start display side A
                Serial.println("Pulse A only. No Pulse B detected");
                for (int j=0;j<4;j++){
                    if (ea[j] >int (EnerThreshold)){
                       stringresult_a[j] = "mJ  Pass";
                       Serial.print("EA ");Serial.print(ea[j]);Serial.println (stringresult_a[j]);                          
                    } else 
                    {
                      stringresult_a[j] = "mJ Fail";
                      Serial.print("EA ");Serial.print(ea[j]);Serial.println (stringresult_a[j]);
                    }
                 } 
                  Serial.println("Press Reset to ready for next run");                                                    
           }
                        
   } //Run A ==1

     while (blnRunA){} //do nothing, force reset for next run
      
  
}//void loop


void TriggerA()
{
  RunA = 1;
}

void TriggerB()
{
  RunB = 1;   
}

P/S: I know the codes have a lot of repeating lines that can easily put into arrays and make it cleaner...I will do that after I figured out why this was not working :grinning:

Those arrays take up a lot of SRAM. The Uno has only 2K where the Mega has 8K. Could you be running out of memory on the Uno?

Hi groundFungus,
Thanks for the response. That is possible, but after compiling the program, Uno shows that I used 24% of storage space and 19% of dynamic memory. So still plenty left right?
The Mega shows that I only use 3% of storage space and 4% of dynamic memory

The compiler only knows about globally declared variables, not locally declared variables like your arrays. The compiler has no idea of the amount of memory local variable are using. The difference between global and local variables is explained in this article on scope.

Move the array declarations to global space and see how much memory is reported.

Oh, and thank you for properly posting code in your first post. It is a rare thing that a new user bothers to read the guidelines. Kudos.

1 Like

The identifiers A0, A1, A2, etc are already used to name the analog inputs. I think it wise to name your arrays something else.

You are right, I have to rename it to AA array when I moved it to global

//global for interrupt  
volatile byte RunA = 0, RunB = 0;

boolean blnRunA, blnRunB;

uint16_t AA0[100] , AA1[100] , AA2[100] , AA3[100] ;
uint16_t AA4[100], AA5[100] , AA6[100], AA7[100] ;
const char *stringresult_a [] = {"N/A", "N/A", "N/A", "N/A"};
const char *stringresult_b [] = {"N/A", "N/A", "N/A", "N/A"}; 
char chr_ta[16]; char chr_tb [16];
int ea [4] = {0}, eb[4] = {0};

and voila I got this error message of program exceeds memory space, it uses 2065 bytes and Uno only got 2048 bytes. All this time I thought that I was well within the limit, guess I have to be more careful when working with arrays and Arduino. Thank you very much !

Arduino: 1.8.19 (Windows 10), Board: "Arduino Uno

Global variables use 2065 bytes (100%) of dynamic memory, leaving -17 bytes for local variables. Maximum is 2048 bytes.

Not enough memory; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing your footprint.
Error compiling for board Arduino Uno.

Please mark your thread as solved so that other members don't waste their time opening the thread hoping to help only to find the problem solved.

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.