If, for instance, it is sample number 37 and the
interval is 12 minutes, then we add 12* 37 = 444
minutes to the origin date/time. If the origin time was
noon, then sample 37 was taken at 12:00 + 444 minutes
(seven hours, 24 minutes) = 9: 24. Wow! Now, all we need
is a single 32-bit datetime variable and a defined sample
period to keep track of all the sample dates and times:
EEPROM using the write functions EEPROM.read and
EEPROM.write. The only thing we need now is to figure
out how we want to structure the three blocks of data
(one in SRAM, two in EEPROM) so that we can deal with
them as a cohesive unit.
// We will pack our data as nibbles into 512
// byte of SRAM structured as four arrays
uint8_t inTemp[NIBBLE_ARRAY_SIZE]
uint8_t outTemp[NIBBLE_ARRAY_SIZE]
uint8_t inHum[NIBBLE_ARRAY_SIZE]
uint8_t outHum[NIBBLE_ARRAY_SIZE]
// We decided to read the sensors once every 12
// minutes
#define SAMPLE_TIME 12
What Data Do We Need to Store?
Well, obviously since we’ve been talking about indoor
and outdoor temperature and humidity, we need to store
those values. Less obvious is that for our nibble packer, we
need to store the initial full values followed by the packed
nibbles. We need some way to tell which are the full bytes
and which are the nibble bytes.
// knowing the SAMPLE_TIME interval we can
// calculate each
// sample datetime
datetime origin_datetime;
Nibble Array Size
We will also need to deal with the case where real
data falls outside our nibble range. (We arbitrarily decided
that our data will never vary more than – 8 to + 7 points
between samples, but what happens when Mother Nature
disagrees?) We will need to know when (the date/time)
the samples were taken, as well. This tells us we need to
store and retrieve several types of data, so let’s look at this
a little closer.
Initial Temperatures and Humidities
We will need to store the initial values for the indoor
and outdoor temperature and humidity:
We defined four arrays for the nibbles. Since earlier
we arbitrarily decided that our data log would be 512
bytes, we must apportion our data into that size memory
so that the four origin bytes and the datetime variable
(along with the arrays) totals 512 bytes. The datetime is 32
bits which is four eight-bit bytes; the four initial byte-sized
sensor readings give us another four bytes. That added
together gives us eight bytes that we have to store at the
beginning or our sampling. We have 512 – 8 = 504 bytes
left for our nibbles; 504 divided by four nibble arrays gives
us 126 bytes per array, so we define:
#define NIBBLE_ARRAY_SIZE 126
uint8_t origin_intemp
uint8_t origin_outtemp
uint8_t origin_inhum
uint8_t origin_outhum
Changes in the Initial Values
We have the arrays of nibbles which we must
define as eight-bit bytes; later, we will write a function
to pack and unpack them:
Dates and Times
Oh darn! We also have to record the date and
time information for each and every sensor reading.
Nibble_test output.
That thing is 32 bits (four whole bytes or 16 nibbles),
so that is going to more that eat up all that memory
we just saved ... unless we get clever again. How about
we just record the datetime variable once when we
first start sampling. Since we will know the sampling
interval, we can use the origin datetime and calculate
the date/time when the sample was taken by
multiplying the sample number times the sample
interval.
November 2013 57
■ FIGURE 5: