Thermistor data logging rig

Hi there, working on another project (previous one is shelved for a while)
I’ve got my mega rigged up so it can save data to an SD card (prompts for input of filename in mm/dd/yy on LCD to be put in by keypad) asks for a time to run for (also prompted by keypad and displays on screen) and a number of thermistors to read (max 16 obv due to thats all the analog ins on a mega)

then it starts to read the therms, math them, output on screen 1 of the thermistor readings (i can set this to a specific one or it cycles through the different therms) runs down until the timer hits zero, then flashes colors with the backlight of the LCD.

Now, this all works. surprisingly well might I add. Problem is, that to do the math on the thermistors to get the temp readings, I’v got this for loop in it,
all the vars are declared and all, most all of them are floats ebcause the math ahs some hardcore decimals in it

for( I = 0; I < thermistoramount; I++)   // sets up the for loop to start at value I and increment by 1
// every tick until I no longer is <2
  {
  test[I] = analogRead(pin[I]);
  voltage = test[I] * 0.0048828;
  Rtherm = (voltage * 10000) / (5 - voltage);
  ratio = Rtherm/R25;
   test[I] = voltage;

/////
//lots more math down here
/////
}

thats but a fraction of the math happening, theres a section to account for the nonlinearity of the thermistor readings, and another section so itll output data in kelvin celcius and farenheight (you can choose which you want to read/write to SD too)

And I’ve hit the sheer problem of the math portion of the code is taking long enough its throwing off the timer (I used basically the blink without delay code to get it to work). Depending on the number of thermistors there are with 1, theres almost no notice ability (because then it only runs through he for loop once per tick) but when running 16 of them it starts to be slow, about 10 mins slow per hour.

Now what I’m wondering, is there any way to make a more efficient timer. Or do i need to gut the math in such a way (get everything into long int math, that might be faster then 16 floats running around)

Ahead of time TY for the help

When you say it's losing ten minutes per hour, what exactly do you mean? Preferably, include all code that is involved in this.

Ill include the whole code tomarrow (its on my computer at my dorm not my laptop).

But when I say loses 10 minutes per hour I mean that as 1 hour goes by in real time, the timer the program makes only shows that 50 mins has gone by. So after 2 hours, it says about an hour and 40 mins is gone by.

Please provide complete code. Regardless how much math if you used blink without delay you should get pretty close to the exact time down to the milliseconds. I'm a bit worried about your "a lot more math". There is not a lot of math:

If you have used the more complex formula, that could be slow but my argument still stands.

Nikarus:
Ill include the whole code tomarrow (its on my computer at my dorm not my laptop).

But when I say loses 10 minutes per hour I mean that as 1 hour goes by in real time, the timer the program makes only shows that 50 mins has gone by. So after 2 hours, it says about an hour and 40 mins is gone by.

That doesn't sound right, and I suspect it'll be obvious why you're getting the times wrong when you post your code.

Ok whole code, well won’t let me put up the whole code because its more then the 9500 char limit, I can break it down in here later for people to look at, but it might just be easier to attach the file itself to this forum post (i guess you can, under additional options, wonder if itll work) .

Don’t have time to break it down now though cause i gotta go to class for the next few hours.

Datalog_cleaned_up_for_posting_to_forums.ino (18.9 KB)

I assume it is the date/time displayed at 'LCD Time location' which is inaccurate.

This seems to be derived from a 'seconds' counter which you decrement each time your loop detects that a second has elapsed.

The method you use to determine whether a second has elapsed is inherently inaccurate because you do not account for processing delay. The loop will not execute your 'one second has elapsed' code until at least one second has elapsed, and then you record the current time as 'now'.

Inevitably there will be some delay between millis ticking over to a new millisecond, and your sketch noticing that it is over the threshold. This means that each second measured by your sketch will be slightly too long.

There are two ways to address this.

Calculate your display time from the value returned by millis(). You would just need to record the milllis() value when you want your countdown to begin, and the value that you want to count down from. Then it's simple arithmetic to work out seconds remaining and from that hours/mins/seconds to display.

The other way is to keep your existing logic but fix your 'blink without delay' test to stay in phase with real time. To do that, change

  if(currentMillis - previousMillis > interval)
  {
    previousMillis = currentMillis;

to

  if(currentMillis - previousMillis > interval)
  {
    previousMillis += interval;

With this change, your sketch will deal with processing latency correctly. If you sketch doesn't notice that a second has elapsed right on the microsecond that it was due, it doesn't matter, because the sketch uses previousMillis to record when the event was due, not when your sketch noticed it.

I assume it is the date/time displayed at 'LCD Time location' which is inaccurate.

the date isnt displayed (date is just used right now for the filename you set) but normally the current time on the timer displays in the bottom left of the LCD in hh:mm:ss and as far as the arduino is concerned it is accurate (just lags due to inefficient programming) but thats all good, it was jsut the sketch going slightly slower.

As for the revision of the millis code, thatll probably do a bit to fix it. after playign with it a bit myself and rearrangeing sections of code i got it so taht over the course of an hour it was only off by 15 seconds instead of like 10 mins. what you gave me will probably fix it so ima go test that out right now.

edit (50 seconds later)
... so it seems, ima work on this for a bit. but when I start the sketch running, setup filename and everything. right when it starts running the actual loop, it runs down about 30 seconds on the timer (in about 5 seconds realtime) before the timer running normally (though it looks like its being good about 1 second realtime per 1 sec on timer)

wonder why thats happening.

Sounds to me that you need to initialize previousMillis in setup(), e.g. to the value returned by millis().

dc42:
Sounds to me that you need to initialize previousMillis in setup(), e.g. to the value returned by millis().

That seems to work. TY (probably shoulda realised that myself but oh well)
we'll see in about an hour though wether or not its still being off (though evertually this will be running for 10+ hours so ill have to run another test later to see if its getting off over long times.

Clock accuracy in Arduinos using a ceramic resonator is only +/- 0.5% which is +/- 18 seconds per hour, so it will drift. For better accuracy, use a real time clock module, or synchronize it to internet time.

dc42:
Clock accuracy in Arduinos using a ceramic resonator is only +/- 0.5% which is +/- 18 seconds per hour, so it will drift. For better accuracy, use a real time clock module, or synchronize it to internet time.

Hmm that seems to be the case, after the fixes people have given me after about an hour its off by about 10 secs now (gonna run it for the whole weekend to see just how far)

guess i can look into an external clock module (not really at liberty to use internet with my current knowledge of programming

If you know you'll always be running your sketch on the same hardware, you could calibrate the Arduino to find how fast/slow the clock is and then account for that in your code. As far as I've seen, the timing varies from unit to unit but tends to be fairly consistent for a given unit.

interesting that would be a thing to try (currently the rig is gonna eb runnign for the whole weekend while im away from the dorms just to see how far it gets off adn if its reading right) I seem to have hit a bit of a snag when it comes to displaying the time onscreen... if I set in a time over 9 hours the screen glitches out and will only show teh first number of the pair (so 20 would just display 2) and it garbles the minutes column a bit. In the SD logger it prints the correct time in and all but idk whats going on.

To note however for the ones who have looked at my code, after the beginning of the loop when it has teh section to display the time, I have a

if(hr >= 10);
{
...
}
else
{...}

replace the ...s with the section in teh minutes part only replacing teh mm s with hr so itll show the hour with a 0 in front so the time is hh:mm:ss instead of the before code's h:mm:ss
but alas it messes up, if I put in 80 hours (enough to go all weekend) itll show a 7 in the 1s column of the hours, a zero to the left of it, and it pushes the 9 (since after 1 sec from 80 hours down is 79:59:59) from the 79 into a mystically generated 100s column on the minutes timer.