arduino,  Microcontrollers

Writing and Reading to the atMega EEPROM

It is time to get the atMega MCU to actually do something useful. In particular, I want it to activate a really to turn on a heater–but first I’ll experiment with a lamp.

The point here is to control the temperature in my hothouse (even though the low quality thermostat on the Walmart heater already killed all of this year’s tomatoes). I want to be able to choose a temperature at which the heater comes on, and another at which it turns off. Eventually I may extend that to change heater power by how much the temperature needs to change–but not today.

I *could* write these into the program, and leave it at that. If I took this path, however, I would need to disassemble it and bring it inside to reprogram. Instead, since we’ve done the work to get it to talk to bluetooth, we’ll simply add commands to set those temperatures, and others to repeat them back. We will store the control temperatures in the EEPROM (Electrically Erasable Read Only Memory).

The EEPROM, unlike the RAM on the Arduino, stores values even with power off. While this is also the case for the flash memory, a running program can write individual bytes of the EEPROM.

At the moment, we only need two one-byte values, Fahrenheit temperatures at which it will turn on and off. So lets define those locations. We add to the program just before setup():

 //where we will put things in the eeprom
int const eeAdrOn = 0x100;
int const eeAdrOff = 0x101;

I could have started at address 0, but something always comes up later, so I started at hex address 0x100, just to leave room for something later.

I added two new commands to doBtInBfr, “t” to set temperatures and “o” to report them back.

t sends a three byte stream: the t itself, a byte for temperature to turn on, and another to turn off. Conveniently, the useful temperatures (above freezing) are all printable ASCII, so I start with 2 and 4 to represent the temperatures 50 and 52–a bit high, but a way to test. Note that I’ve chosen this format to be easy to type from either a cellphone keyboard or from the text-based python interpreter on the raspberry pi.

A new function has been added to write to the EEPROM–somethign the Arduino IDE makes quite easy:

bool setRelayTemps(byte newLow, byte newHigh) {
//write the two temps
EEPROM.write(eeAdrOn, heatOnTemp);
EEPROM.write(eeAdrOff, heatOffTemp);
if ( (EEPROM.read(eeAdrOn) == newLow) && (EEPROM.read(eeAdrOff) == newHigh)) {
//success
monSerial.print("Set to "); monSerial.print(newLow); monSerial.print(" and "); monSerial.println(newHigh);
return true;
} else {
return false;
}
}

Note the error checking here: after writing, it checks to see if the EEPROM now holds those values. There’s no good reason that it shouldn’t, other than the EEPROM having worn out–but it’s a good habit to maintain, and makes debugging easier. If the values are the same, the function returns true, while if they are not, it returns false to indicate failure.

The t command checks this result, and if successful, calls another new function:

void setRelayTempVals() {
// get them from the eeprom
heatOnTemp = EEPROM.read(eeAdrOn);
heatOffTemp = EEPROM.read(eeAdrOff);
}

setRelayTempVals() is also called during setup(). Otherwise, we would nee to set it every time we powered up.

With this compiled, we then simply send “t24” from our BLE, and the temperature is set. I then rebooted, and use “t15” to generate the following:

I can also get the current set temperatures from the phone, too:

And that is really all there is to

Leave a Reply