Serial monitor issues (VS Code + PlatformIO) - how to debug efficiently?

Hello everybody,

I'm not really sure how to approach this topic - sorry in advance, please feel free to point me in the right direction of which information is a relevant and which is not when it comes to this issue.

The complete code for my project can be found here: GitHub - ThomasDickmann/Irrigation_System: Homemade irrigation system using the arduino platform and custom made circuits
Please let me know which parts of the code I should post as code snippets on here, so I don't bloat the post with irrelevant code.

The problem

I am trying to write the firmware for my Arduino based irrigation system and I'm encountering issues with the serial monitor, which I can't make sense of. For writing the code, I am using the PlatformIO plugin is VS code (lastest release).

The reason why I am so confused is that up until now (in previous projects), the serial communication either worked as intended or it didn't work at all. However, now I am getting a partially working serial communication, which can be proved by a number of things in the code.

My system uses a RTC on the I2C bus and an SD card on the SPI bus. When running, the RTC frequently creates timestamps which I then want to write to the serial monitor and then print to the SD card, together with the obtained sensor data of that loop iteration. An example time stamp (beginning of the loop, after an interrupt by the rtc has woken up the controller from a deep sleep state):

 Serial.println("Controller has been woken up");
 Serial.println("Time: "+String(hour(t))+":"+String(minute(t))+":"+String(second(t)));

For whatever reason, everything worked fine up until I introduce one of multiple thing the the code. E.g. as soon as I initialize a BMP280 object in the setup function, the serial communication still runs, but the time stamps are no longer printed to the monitor. The output of the above mentioned step on the monitor suddenly changes to:

Controller has been woken up
Time:

Initially I thought there might be a conflict between the two peripherals on the I2C bus. But I can provoke the same issue without adding any code regarding the BMP, just by adding this little routine (targeted at opening solenoid valves) later in the loop function, which has nothing to do with the I2C bus whatsoever:

//Loop over sensors and compare values to threshold (needs to be defined in setup.cpp) 
for (int i=1; i <=4; i++){
  if(MySensors[i].read()  <  soil_threshold){
      Serial.print("Watering need detected. Watering plant ");
      Serial.println(i); 
      MyValves[i-1].on(); //open valve I
      Motor2.on(); //switch on pump secondary reservoir
      delay(1000); //TODO pass function to give 5ml of water, optimize with plant specific value through var. list of amount constants 
      Motor2.off(); //turn off pump secondary reservoir 
      MyValves[i-1].off(); //close valve I
    }

  else{ 
      Serial.print("No watering need detected for plant ");
      Serial.println(i); 
    }
  }

I have no idea why the serial communication is affected by this part of the code. Before I continue with developing the firmware, I'd like to understand what is going on. Unfortunately, I am clueless as to how to tackle this issue. My only idea was to try and get a logic analyzer and try to monitor the communication bit by bit to see what changes...

Then recently I tried to run the code on a more powerful Arduino nano 33 IoT (instead of the cheap nano clones I used before) to see if maybe there is a performance bottleneck somewhere. For that, I modified the platformio.ini file to compile the firmware for the new target hardware:

[platformio]
default_envs = nanoatmega328
description = Firmware Development Watering System

[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino

[env:nano_33_iot]
platform = atmelsam
board = nano_33_iot
framework = arduino

monitor_speed = 115200

lib_deps =
paulstoffregen/Time@^1.6.1
arduino-libraries/SD@^1.2.4
jchristensen/DS3232RTC@0.0.0-alpha+sha.261ca7d0e6
adafruit/Adafruit BMP280 Library@^2.6.2

I soon learned that the whole sleep/power saving functionality is entirely different on the newer arduinos, so I commented out the respecive sections of the code. After compiling and running the code on the nano 33 IoT, the serial communication was completely broken. I was getting results identical to what you would see when setting a wrong baud rate.

I am aware that from this description, it is impossible to pinpoint the issue - this is just the description of what I am seeing. If anyone can tell me, where to start looking or which things to focus on in the context of this issue, that would be greatly welcomed! Thanks :slight_smile:

The photo looks like an original Nano 328. Perhaps it is running out of memory. I know nothing about PlatformIO, however, does it tell you how much free memory is left after compilation? If there a PlatformIO equivalent to freeMemory() that you can put in your code as a diagnostic tool?

it's using quite a bit of memory, but it's not overloading anything as far as I can tell. This is what PlatformIO tells me after the build process:

RAM: [========= ] 85.2% (used 1745 bytes from 2048 bytes)
Flash: [======== ] 78.5% (used 24128 bytes from 30720 bytes)

PlatformIO uses the official Arduino core, you can use all built-in Arduino functions and all Arduino libraries with it.

Maybe a bit late :wink: Use of String (capital S) is risky on microcontrollers with little memory. If you can, don't use it. And the way you use it below is definitely a way how NOT to use it.

Serial.println("Controller has been woken up");
Serial.println("Time: "+String(hour(t))+":"+String(minute(t))+":"+String(second(t)));

Concatenation using + creates additional String objects. If you want to use String objects, first build the String object using either concat() or +=. Else just print the individual elements, the effect will be the same.

Serial.print("Time: ");
Serial.print(hour(t));
Serial.print(":");
Serial.print(minute(t));
...
...

Awesome, thanks for the tip! I had no idea about this risk.

I have to thank you again, @sterretje - I finally took the time to re-visit my project last weekend and reworked all the string outputs according to your input.
In addition (because the RAM was getting very much pushed to its limits), I used the Serial.print(F"output here") function everywhere to relax the RAM usage.

My program is now running fine at last and I could wrap up the project after many months of having it just kicking around halfway finished. Thank you! :slight_smile:

Cheers, Thomas

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