Incorporating one last sensor

Hi guys,

I have made a sensor module of many kinds of sensors. I use an lcd screen to display the sensor values. I am having trouble incorporating my last sensor, geiger counter, into the module. When I have the necessary code for the sensor in my main sketch, the lcd is just blue, which means it hasnt gotten to the point where the lcd function are called. What is happening? If I delete the code for the geiger counter, it works as it should. Unfortunately the code is too long to post here, I will upload the sketch.

sensormod.ino (10.6 KB)

String strnmeaProto;
String strutcTime;
String strgpsStatus;
String strlatitude;
String strnsIndicator;
String strlongitude;
String strewIndicator;
String strspeedOverGnd;
String strcourseOverGnd;
String strutcDate;
String strmagVarDegrees;
String strmagVarDirection;
String strmodeIndicator;
String strcheckSum;

I got that far, and I quit reading.

How much memory do you have? How much are you using?

Thanks for the quick response.

I am new to programming and memory usage had escaped from my mind.

You gave a similar answer as another person( to another question I asked about the same project) SD Card fails every 5 or 6 minutes, help! - Storage - Arduino Forum

What do you recommend I do?

What do you recommend I do?

Determine how much memory you are using.
Quit pissing it away on the String class.

So i ran the memory checker, and used the serial port to output the results every 0.5 seconds. The first value came out to 4580, the the values subsequently decreased by about 30 or so every 0.5 seconds. Right before my program crashed, the value was at 302. THen the error(file couldnt be opened) showed up on my lcd.

What is causing this memory leak? How do i fix this?

Also just in case you were wondering, I got those values from this piece of code :

int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

What is causing this memory leak?

My guess would be the String class.

How do i fix this?

Stop using it.

Again, thanks for the quick response.

What are alternatives to String? Char array? My gps sensor, for example, out puts data as a string. what do i do to remove the string?

String strutcTime = gps.dataFields(1); <---- is how I have it coded right now, is there an alternate method?

Try not to store string type data in global memory. If you really want have a sensor store it's data in global memory (so that it can be logged later) try to store just the bare data (say in the form of a byte, int or other basic type). When you are ready to do the logging, this is where all those values can be converted to meaning full strings. This way you can use ONE string, build it up for the data item you are logging. commit that string to your non volatile memory. Then reuse that SAME local string for the next data item.

Other things you could consider. If you are storing temperature accurate to a 10th of a degree, you can mulitply it by 10 and then store it as an integer. This only takes two bytes even though it has a precision of a tenth of a degree. Whereas if you store it as a float, this takes 5 bytes

When you come to store your results on the logger (or present it on a screen) this is where you should format it for the user. You can then use a local string variable for every item. Such as

void function logAllMyStuff()
{
char * tempString[100];
sprintf(tempString,"Temp %i.%i degrees Farenheight",int(temperature/10),temperature%10);
gizmo.write(tempString);
sprintf(tempString,"Humidity %i %i Relative as measured by Brians probe");
gizmo.write(tempString);
}

Not only does this function save memory by reusing a single string variable, but even that string variable only exists for the duration that the function is running.

There are plenty of other tricks to get your memory use down but hopefully this will give you somewhere to start.

What are alternatives to String? Char array?

A NULL-terminated array of chars, also known as a string.

My gps sensor, for example, out puts data as a string.

Then why are you wasting resources wrapping the string in a String, just to unwrap it later so you can use the data?

Actually the String class is probably not the problem, you have an obvious space leak
by opening a SDcard file each time round loop() and never closing it.

On a machine with severely limited resources you have to be ultra careful never to
let them accumulate like this.

Oh, yes, you should open the log file to append, not overwrite.

#define FILE_APPEND (O_READ | O_WRITE | O_APPEND | O_CREAT)

might be a useful definition for that.

PaulS:

What is causing this memory leak?

My guess would be the String class.

How do i fix this?

Stop using it.

Thank you so much!! I fixed up what you said, and now my freeRam stays constant at 6048! (BTW, as for the sd logger being removed, some key parts of my project have changed, and therefore the logger will go on another arduino which recieves the information from sensor module arduino. This probably added to the saving memory bit)

So getting back to my original problem now, I want to incorporate the code for the geiger counter into the main code now.
Here is my code for the geiger counter :

unsigned int count = 0;
unsigned int countStartTime = 0;
int countsPerMinute;

float coefficientOfConversion = 140.0 / 60000.0;
float sV = 0;

void setup() {
  Serial.begin(9600);  // start serial monitor
  Serial1.begin(9600); // start serial port for geiger counter
}
void loop() {
  
  while (Serial1.available() > 0) {  // Check if geiger counter is available
     int inChar = Serial1.read();  // read char from geiger counter
     if (inChar == '0' || inChar == '1') {  // 0 and 1 represent an event
       count++;  // increase count
      }
  }
  unsigned int now = millis();  // now is the time in milliseconds since start of program
  unsigned int elapsedTime = now - countStartTime;  // time elapsed
  if (elapsedTime >= 60000) {
    countsPerMinute = count;
    sV = (float) countsPerMinute * coefficientOfConversion;
    // reset timers
    count = 0;
    countStartTime = now;
    Serial.print("CPM: ");
    Serial.println(countsPerMinute);
    Serial.print("uSv/hr: ");
    Serial.println(sV, 5);
  }
}

When I input this code in my main code, the lcd is just blue which means the arduino hasnt reached the functions where the writing to the lcd is done. I am assuming it gets stuck somewhere in the geiger counter code. However, the code by itself, works when uploaded to the arduino. What could be the problem, and is there any way around the problem?

I have attached the main code as it is too big.

sensormod.ino (9.77 KB)

I have attached the main code as it is too big

But the code you have attached has no reference to Serial1 or the geiger counter stuff. How can we debug the bit that you're leaving out?

aha, sorry. its just that its the exact same code, but inside in the main code, but i see what you mean.

edit: i have attached the updated code here, and the first post

sensormod.ino (10.6 KB)

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600); 
  dht.begin();
}

Don't you need to do anything to set up the LCD? Why are you not printing to it in setup() just to confirm that it is working?

Calling some functions from loop(), instead of all the code being in loop() would help with debugging. Some Serial.print() statements would not be amiss in those functions and in loop().