persistent Timer broken

This I've been working on for 2 hours. I want it to return the current time, which is calculated by taking a stored offset of hours and minutes and adding that to a stored previous millis, plus the current millis. Then I divide to get Hours and Minutes. It isn't working.

millisTotal sporadically shoots up to 42949429490000 and still increments properly. The returned time is always just the offset values from 00:00, it doesn't "tick" up.

I know Strings are bad but I can't figure out how to concatenate chars. I get null.

So I think there are two problems. One with the odd shooting up, one with the hours and minutes.

The Function:

String currentTime() {
  char currentHHchar[3] = { 0 };
  char currentMMchar[3] = { 0 };
  String currentT;
  String currentHHStr, currentMMStr;
  unsigned long millisTotal;

  millisTotal = millisPrior + millis();
  Serial.println(millisTotal);
  currentHH =  millisTotal / (1000 * 60 * 60);
  currentMM = (millisTotal / (1000 * 60)) - int(millisTotal / (1000 * 60));
  writeEEprom("longmillis", millisTotal);

  HHOffset = readEEprom("HHOffset");
  MMOffset = readEEprom("MMOffset");

  unsigned long HH = currentHH + HHOffset;
  unsigned long MM = currentMM + MMOffset;

  currentHHStr = String(HH);
  currentMMStr = String(MM);
  if (currentHHStr.length() == 1) currentHHStr = '0' + currentHHStr;
  if (currentMMStr.length() == 1) currentMMStr = '0' + currentMMStr;
currentT = currentHHStr + ":" + currentMMStr;

   Serial.println(currentT);
  return currentT;
}

A eeprom.put wrapper function. eaddrRef isn't shown but it gets the address to store. MillisPrior has 10 bytes allocated to it:

void writeEEprom(String itemName, unsigned long value) {
  int eAddr, valueInt;
  valueInt = int(value);
  if (itemName.substring(0, 4) == "long") {
    EEPROM.put(eAddr, value);
  }
  else {
    EEPROM.put(eAddr, valueInt);
  }
  eAddr = eAddrRef(itemName);
  EEPROM.put(eAddr, value);
}

which is calculated by taking a stored offset of hours and minutes and adding that to a stored previous millis, plus the current millis.

I can't make any sense of that. You have saved a previous millis() value and you add it to the current millis() value plus 2 offset values, presumably also in milliseconds. How will that give you the current time ?

mattlogue: This I've been working on for 2 hours.

That's not very long. I can imagine frustration beginning to set in after 2 days.

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

Also, it is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

Robin,

Is it possible to concatenate the char arrays? I wish to make a HH:MM format. would I use strcat?

mattlogue: Robin,

Is it possible to concatenate the char arrays? I wish to make a HH:MM format. would I use strcat?

Have a look at the strcat() function

mattlogue: Is it possible to concatenate the char arrays? I wish to make a HH:MM format. would I use strcat?

It is possible, but why do you you need to put the parts into a single array? What do you propose to do with the single array?

Rather than concatenate two arrays into a longer third array I would define an array that is long enough for the longest message and copy the parts into it. That way I would know exactly how I was using the limited Arduino memory.

But it may still be simpler to keep the parts separate.

...R

I can keep them seperate up until I wish to display them on an LCD. Then I want HH and MM grouped together somehow. If not using strcat(), then moving over the LCD cursor two spaces and redoing lcdWrite(MM). It's to display time on my thermostat project.

Are you doing anything with the string after displaying it? If not, think about using snprintf(). That way you could put in colons, etc.

mattlogue: I can keep them seperate up until I wish to display them on an LCD.

Why can't you put them on the LCD piece by piece - the equivalent of this

Serial.print("The weight is ");
Serial.print(weightValue);
Serial.println(" tonnes");

...R