Go Down

Topic: Problem with buffers after EEPROM read (Read 906 times) previous topic - next topic

harrysfrags

I'm having trouble with a buffer being partially populated with data from an EEPROM read.  I have two buffers (Lobuffer and Hibuffer) with hold a time in the format (hh:mm[a or p]m).  I can read the data from EEPROM into Hibuffer and it works correctly.  Then I read the data into Lobuffer.  That works correctly but it also appends the data (or part of it) onto the end of the Hibuffer string.

Example:

Hibuffer after read from EEPROM:  12:05am (this is correct)
Lobuffer after read from EEPROM:  5:11am (this is correct)
but now the value in Hibuffer is : 12:05am:11am


harrysfrags

Here are parts of the sketch:
Code: [Select]

#include <EEPROM.h>

char Hibuffer[6];
char Lobuffer[6];

/////////////////////////////////////////////////////////////////
// EEPROM map
////////////////////////////////////////////////////////////////
int HiTempAddr = 0;        // 0 - 3
int HiBufferAddr = 4;      // 4 - 10
int LoTempAddr =  11;      // 11 - 14   
int LoBufferAddr = 15;     // 15 - 21 
int HistHiTempAddr = 22;   // 22 - 25
int HistHiBufferAddr = 26; // 26 - 41
int HistLoTempAddr = 42;   // 42 - 45
int HistLoBufferAddr = 46; // 46 - 51
////////////////////////////////////////////////////////////////////////////
void setup()
////////////////////////////////////////////////////////////////////////////
{
  lcd.begin(nColumns,nRows);     
  Wire.begin();
  Serial.begin(9600);
  watchdogSetup();
  ReadFromEEPROM();

 
}

////////////////////////////////////////////////////////////////////////////
void loop()
////////////////////////////////////////////////////////////////////////////
{
    getTemp();
}



////////////////////////////////////////////////////////////////////////////
// Convert decimal numbers to binary coded decimal
////////////////////////////////////////////////////////////////////////////
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

////////////////////////////////////////////////////////////////////////////
// display high temp
////////////////////////////////////////////////////////////////////////////
void DisplayHighTemp()
{
    // print high temp and time of high
    lcd.setCursor(0,1);
    lcd.print("Hi ");
    lcd.print(floatToString(buffer4,HiTemp,1));  // convert temp from float to string and print it
    lcd.print(" ");
    lcd.print(Hibuffer);
}
////////////////////////////////////////////////////////////////////////////
// display low temp
////////////////////////////////////////////////////////////////////////////
void DisplayLowTemp()
{
    // print low temp and time of low
    lcd.setCursor(0,2);
    lcd.print("Lo ");
    lcd.print(floatToString(buffer4,LoTemp,1));  // convert temp from float to string and print it
    lcd.print(" ");
    lcd.print(Lobuffer);

}

////////////////////////////////////////////////////////////////////////////
// read float from eeprom
////////////////////////////////////////////////////////////////////////////
float eepromReadFloat(int address){
   union u_tag {
     byte b[4];
     float fval;
   } u;   
   u.b[0] = EEPROM.read(address);
   u.b[1] = EEPROM.read(address+1);
   u.b[2] = EEPROM.read(address+2);
   u.b[3] = EEPROM.read(address+3);
   return u.fval;
}

////////////////////////////////////////////////////////////////////////////
// read int from eeprom
////////////////////////////////////////////////////////////////////////////
int eepromReadInt(int address){
   int value = 0x0000;
   value = value | (EEPROM.read(address) << 8);
   value = value | EEPROM.read(address+1);
   return value;
}

////////////////////////////////////////////////////////////////////////////
// read string from eeprom
////////////////////////////////////////////////////////////////////////////

void eepromReadString(int address , char string[], int len)
{
for (int i=0; i <= len; i++)
  {string[i] = EEPROM.read(address);
  address++;
  }
}

////////////////////////////////////////////////////////////////////////////
// write int to eeprom
////////////////////////////////////////////////////////////////////////////
void eepromWriteInt(int address, int value){
   EEPROM.write(address, (value >> 8) & 0xFF );
   EEPROM.write(address+1, value & 0xFF);
}

////////////////////////////////////////////////////////////////////////////
// write float to eeprom
////////////////////////////////////////////////////////////////////////////
void eepromWriteFloat(int address, float value){
   union u_tag {
     byte b[4];
     float fval;
   } u;
   u.fval=value;

   EEPROM.write(address  , u.b[0]);
   EEPROM.write(address+1, u.b[1]);
   EEPROM.write(address+2, u.b[2]);
   EEPROM.write(address+3, u.b[3]);
}
////////////////////////////////////////////////////////////////////////////
// write string to eeprom
////////////////////////////////////////////////////////////////////////////
void eepromWriteString(byte address , char string[], int len)
{
for (int i=0; i <= len; i++){EEPROM.write( address , string[i]);
  address++;
  }
}

////////////////////////////////////////////////////////////////////////////
// get temp
////////////////////////////////////////////////////////////////////////////
void getTemp()
{
  if ( !ds.search(addr)) {
    ds.reset_search();
    //Serial.print("bad address");
    return;
  }

/*
if ( OneWire::crc8( addr, 7) != addr[7]) {
  Serial.print("CRC is not valid!\n");
  return;
}
*/


 
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end

  delay(750);     // maybe 750ms is enough, maybe not
 
  present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }

  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  //get the whole and fraction in Celcius
  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;

  temp=(data[1]<<8)+data[0];//take the two bytes from the response relating to temperature
  temp=temp/16;//divide by 16 to get pure celcius readout
  temp=temp*1.8+32; // convert to Fahrenheit

  lcd.setCursor(0,0);
  lcd.print("Temp: ");
  lcd.print(floatToString(buffer4,temp,1));  // convert temp from float to string and print it
  lcd.print(" ");  //blank out trailing character from previous post
 
  // compare to high and low
  if (temp > HiTemp)  // update high temp
  {
    HiTemp = temp;   
    if (DisplayHour < 10)
    {
      sprintf(Hibuffer, "%01d:%02d%c%c%c",DisplayHour, minute, ampm, 'm', ' ');
    }
    else
    {
      sprintf(Hibuffer, "%02d:%02d%c%c%c",DisplayHour, minute, ampm, 'm', ' ');
    }

    // save it to EEPROM
    eepromWriteFloat(HiTempAddr, HiTemp);
    eepromWriteString(HiBufferAddr, Hibuffer, 6);
   
    DisplayHighTemp();
  }
 
  if (temp > HistHiTemp)  // update high temp
  {
    HistHiTemp = temp;   
    if (DisplayHour < 10)
    {
      sprintf(buffer16, "%01d:%02d%c%c%c%d/%d/%d",DisplayHour, minute, ampm, 'm', ' ', month, dayOfMonth, year);
    }
    else
    {
      sprintf(buffer16, "%02d:%02d%c%c%c%d/%d/%d",DisplayHour, minute, ampm, 'm', ' ', month, dayOfMonth, year);
    }

    // save it to EEPROM
    eepromWriteFloat(HistHiTempAddr, HistHiTemp);
    eepromWriteString(HistHiBufferAddr, buffer16, 16);
  }
 
 
  if (temp < LoTemp)  // update low temp
  {
    LoTemp = temp;
    if (DisplayHour < 10)
    {
      sprintf(Lobuffer, "%01d:%02d%c%c%c",DisplayHour, minute, ampm, 'm', ' ');
      sprintf(buffer16, "%01d:%02d%c%c%c%d/%d/%d",DisplayHour, minute, ampm, 'm', ' ', month, dayOfMonth, year);

    }
    else
    {
      sprintf(Lobuffer, "%02d:%02d%c%c%c",DisplayHour, minute, ampm, 'm', ' ');
      sprintf(buffer16, "%02d:%02d%c%c%c%d/%d/%d",DisplayHour, minute, ampm, 'm', ' ', month, dayOfMonth, year);
    }

    // save it to EEPROM
    eepromWriteFloat(LoTempAddr, LoTemp);
    eepromWriteString(LoBufferAddr, Lobuffer, 6);

    DisplayLowTemp();
  }
}

////////////////////////////////////////////////////////////////////////////
// load variables from EEPROM @ startup
////////////////////////////////////////////////////////////////////////////
void ReadFromEEPROM()
{
  HiTemp = eepromReadFloat(HiTempAddr);
  eepromReadString(HiBufferAddr, Hibuffer, 6);
  DisplayHighTemp();
  LoTemp = eepromReadFloat(LoTempAddr);
  eepromReadString(LoBufferAddr, Lobuffer, 6);
  DisplayLowTemp();
  HistHiTemp = eepromReadFloat(HistHiTempAddr);
  HistLoTemp = eepromReadFloat(HistLoTempAddr);

///////////////////////////////////////////////////////////
void watchdogSetup()
///////////////////////////////////////////////////////////
{
  cli();  // disable all interrupts
  wdt_reset(); // reset the WDT timer
  MCUSR &= ~(1<<WDRF);  // because the data sheet said to
  /*
  WDTCSR configuration:
  WDIE = 1 :Interrupt Enable
  WDE = 1  :Reset Enable - I won't be using this on the 2560
  WDP3 = 0 :For 1000ms Time-out
  WDP2 = 1 :bit pattern is
  WDP1 = 1 :0110  change this for a different
  WDP0 = 0 :timeout period.
  */
  // Enter Watchdog Configuration mode:
  WDTCSR = (1<<WDCE) | (1<<WDE);
  // Set Watchdog settings: interrupte enable, 0110 for timer
  WDTCSR = (1<<WDIE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (0<<WDP0);
  sei();
}



This is only the parts of the code that pertains to the problem that I'm having.  The whole sketch is 20174 bytes right now.  Could I have a memory overflow?

PaulS

Quote
Here are parts of the sketch:

Not interested. Post ALL of the sketch.

PaulS

Code: [Select]
      sprintf(Hibuffer, "%01d:%02d%c%c%c",DisplayHour, minute, ampm, 'm', ' ');
%01d requires one space in the array.
: requires one space in the array.
%02d requires two spaces in the array.
%c%c%c requires three spaces in the array.
The terminating NULL requires on space in the array.

That's 8 of the 6 spaces...

harrysfrags

When I try to post the whole sketch I get the error: The message exceeds the maximum allowed length (9500 characters).

PaulS

Quote
When I try to post the whole sketch I get the error: The message exceeds the maximum allowed length (9500 characters).

Nothing to stop you from attaching it to your post, though. Select the Additional Options... link (yes, I know it doesn't look like a link), and then the Browse button.

harrysfrags


PaulS

Doesn't look like you've read replay #3 (or done anything about it...).

harrysfrags


Doesn't look like you've read replay #3 (or done anything about it...).


If you mean the size of the buffer; I figure that

char Hibuffer[6];

is 7 bytes long (starting @ 0); so 10:36am would fit.  You mentioned a NULL byte.  Do I need to added that and if so how.

My problem now is not reading the correct data and putting it in the correct buffer, but also appending it to the data in the previous buffer.

PaulS

Quote
If you mean the size of the buffer; I figure that

char Hibuffer[6];

is 7 bytes long

The value in the brackets is the number of elements, not the upper index.

Quote
so 10:36am would fit.

No, it won't.

Quote
You mentioned a NULL byte.  Do I need to added that and if so how.

No. sprintf() is doing that for you. But, you must provide room in the array for it. The array sizes must both be a minimum of 8.

harrysfrags

Thanx, I'll give that a shot!

Would that have anything to do with appending to another buffer?

PaulS

Quote
Would that have anything to do with appending to another buffer?

Of course, because you are writing outside the bounds of your array(s).

Go Up