ESP32 Cryptic int array Serial print

Hello everyone, this is my first time posting here! I hope I'll give you all the details you need and that I'm not breaking any rules or whatnot... Tell me if I do!

I'm working on a DFRobot Firebeetle ESP32-E in an attempt to measure a 50Hz sinusoidal signal.
But while trying to add debug to my program in the form of Serial.println, the strangest thing happens.

With the following code, everything goes accordingly. The "Hello loop" gets displayed, then all the analogReadValues and finally the "Goodbye loop".

#include <Arduino.h>

const int K_MEASUREMENT_PERIOD = 400000;  //micro seconds -> 2 * 50hz
const int K_MEASUREMENT_STEP = 30;        //micro seconds
const int K_MEASURES_NUMBER = K_MEASUREMENT_PERIOD / K_MEASUREMENT_STEP;

const int K_FIREBEETLE_ADC_BITS = 4095;  //Firebeetle reads 3.3V on a 12 bits scale: 4095
const float K_FIREBEETLE_ADC_MIN_VOLTAGE = 0.1f;
const float K_FIREBEETLE_ADC_MAX_VOLTAGE = 3.3f;

const float K_AMPLFIER_MODULE_GAIN = 0.f;
const float K_ADDED_VOLTAGE = 0.f;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  //Serial.print()
  delay(1000);
}

void loop() {
  Serial.println("Hello loop");
  delay(1000);

  unsigned int a0BitValues[K_MEASURES_NUMBER] {};
  Serial.println(a0BitValues[0]);
  a0BitValues[0] = analogRead(A0);
  Serial.println(a0BitValues[0]);

  for (int i = 0; i < K_MEASURES_NUMBER; i++) {
    a0BitValues[i] = analogRead(A0);
    Serial.println(a0BitValues[i]);
  }
 
  Serial.println("Goodbye loop");
  delay(10000);
}

But if I just add one line. A Serial.println(a0BitValues[0]) after the for loop, then the COM output becomes a cryptic mess.

New code:

void loop() {
  Serial.println("Hello loop");
  delay(1000);

  unsigned int a0BitValues[K_MEASURES_NUMBER] {};
  Serial.println(a0BitValues[0]);
  a0BitValues[0] = analogRead(A0);
  Serial.println(a0BitValues[0]);

  for (int i = 0; i < K_MEASURES_NUMBER; i++) {
    a0BitValues[i] = analogRead(A0);
    Serial.println(a0BitValues[i]);
  }

  Serial.println(a0BitValues[0]);
 
  Serial.println("Goodbye loop");
  delay(10000);
}

Result:

81����␑D)!11�H���!�!��81� ␎D�␑D)!11␑���9�!��    ␘��␑D��(JʄΌ9J�81� ␎Dr␑D)!11�H���!�!��   ␘��L0�(Jʄ␂���Õ
��␐     ~L0J!!!�␂��1�11�␌��␄�␘L0�(Jʄ�9�!���␐    ~L0�(J�8 ���Õ
����␘��␑D)!!    9␌��9�!���␐     ~L0�(j!�␂���Õ
␀1�)��z 1�11�81� ��␑D)!11␑���9�!��␌��␄�␘L0�(JʄΌ9J� ␎D���␘��␑D)!1�9␌��9�!��␌��␄�␘L0�!!!�␂���Õ    ␘��L0�(Jʄ�8Ό9J�81� ␎D�
␀1�))))�Jz 1�11�1� ␎D�1�h)))� ��~L0�(J�8 ���ÕΧJ!!!�␂���Õ��81� ␎D�
␀�1���z 1�11�␌��␄�␘L0�(J�␜ ���Õ
␀1�))��N)�1�11�81�8��␑D)!��81� ␎9␌��9ͥ�181� ��␑D)!11�z���!�     ␘��␑D��(JʄΌ9J��␐        ~L0�(JʄΌ9J��␐   ~L0�(Jʄ����Õ
�81� ␎�␑D)!11�z
��!!81� ␎�␑D)�
␀1U1��z 1�1��L�1␘��␑D)!��Ό9J�81�9␌��9�!��␌��␄�␘L0�(!!�␂���Õ��!)(��95!�1���␘��␑D)�(Jʄ�9��ա81� ␎D�
�␌����␀1�)))��Jz 1�11�8��␘��␑D)!11�z 1�Ճ�       ␘��␑8!)(��9�!���␐       ~L0�(Jʤ␂���Õ
␀1S1��z 1�1�81� ␎D���1!11�z Ѧ!��h␑�␄�␘L0�!!!�␂� 11�81� ␎�␑D)!11`*␄�␘��1�))��N)�1�у�81� ␎D�
��!�    ␘�␘L0�(J�8 ���Õ
␀1�)��z 1�!���␐�~L0�(j!�␂���Õ��81� ␎Ds␑D)!11�z 1�11�81� ␎Č␑D)!11�z Ѧ!�� ␘����!)(��9�!���␐       ~L0�(Jʄ���Õ
�␌��␄�␘L0N(J!!!�␂����11�81� ␎�␑D)!11�z 1�11�    ␘����!)(��9�!�� ␘��␑8!)(��9�!��␌��␄�␘L0�(Jʄ�9��ա␌��␄�␘L�1�))))� ���Õ
␀1!11�z �!��!!!�␘��␑�(Jʄ�9�!�181� ␎D���1!11l*␌��␄�)1�))))� ���Õ��81B␘��␑D)!�    9␌��9�!�        c       ~L0��!!�␂��� 11�␌��␄�␘L01�))))� � 11�81� ␎�␑D)!119␌��9�!��␌� ␎D�
��!�    ␘��␑D)�
␀1�))��N)�1�11␑�␄�␘L0�(J!�␂���Õ��␌���␎D�
����␄�␘L0ΧJ!!!�␂����11��␐       ~L0�(J�8 ���Õ
␀�1�����
␀1�1��z 1�11�!11b��!�!��~L0��!!�␂��1 11�␌��␄�B)1�))��N)�1�11�␌��␄�␘L�1�))))��z 1�1�����␘��␑D��(Jʄ�9�!���␐       ~L0�(!!�␂���Õ��␌��␄�␘L0J!!!�␂���Õ���␐   ~L0�(Jʄ����Õ
�␌��␄�␘L0�(J�8 ���Õ
�␌��␄�␘L0�(Jʄ�9�!��␌��␄�)1�))))��z 1�11�        ␘␓␘L0�(Jʄ�9�!��␌��␄�␘)1�))))� ����c��81C␘��␑D)!11a*
��!!81� ␎D�␑D)!11��
␀1����z Ѧ!��81� ␎Dr␑D)!1�9␌��9�!��81� n�␑D)!11�H���!�!���z 1�!��h␑�␄�␘L0~L0�(j!�␂���Õ��␄�␘L0N(J!!!�␂� 11�␌� ␎D�

Things I already tried:
-Using arudino IDE or VS Studio + Platformio (I thought it could be a compiler issue writing the wrong addresses)

  • Using sprintf
  {
    char buffer [33];
    sprintf(buffer, "%d; %d;",times[i], a0BitValues[i]);
    Serial.println(buffer);
  }
  • Casting the int into pretty much all the other types
  • Passing a reference rather than copy
  • Looking online for what I might be doing wrong, but I'll be honnest I don't really know what to type in the search bar...

Some reasons behind my design choices:
Be cause I'd like the ADC measures to be in the 4 uS realm if possible, I know that the best way to speedup the process is to reduce all the speed choke points in the for loop. Hence I'd like to not be printing my values here but afterwards.
That's also the reason I pre allocate the array with the right size before the loop.
Finally the reason I need to get an actual sinusoïdal curve and not just the highest values or a mean is that I'm measuring voltage coming from a Rogowski coil that I need to integrate from di/dt to i max and doing so, for physical reasons, is only possible if I know the times at which the curve hits a 0 and when it hits its maximum as well as the values in between.

The same code runs fine on my arduino uno R3 (to some extent. As in the full version of my programm I also tried to print the voltage values float array using dtostrf() and it printed the same cryptic messages). However I'd like to be able to do it using the ESP32 as it's way cheaper and from what I understand, way faster than the arduino equivalents.

Finally, while the final version of the code will not be serial printing the values but simply the result of some calculations done afterwards, I know that integration hell is awaiting and I want to be able to check every step of the process to see where things go wrong.

I'm suspecting this has to do with things in the realms of adress pointers, memory alignment and stuff like that but I'm not an embeded systems expert at all (else I wouldn't be asking for help)

If you have any idea of what's wrong I'll gladly listen and if you need more information to help me solve this mystery I'll try my best to answer you.

That's a lot to put on the stack.

I figured, but I thought the math added up and was enough to fit in the ESP's RAM. Thing is, as I said, I need to do the measures as fast as possible and get as many points as possible to ensure the best "wave" of signal is captured.
If I were to change the array size, what would you recommend?

What happens when it's a global?

1 Like

Rather than on the stack, try making it global, or allocating it dynamically on the heap, or allocating it dynamically in PSRAM.

2 Likes

Making it global seems to have worked!

I feel dumb cause I know I tried this solution before and it didn't work but I probably miss wrote something

Thank you very much for your time and expertise :slight_smile:

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