EEPROM.get error with static char

Hello,

I am trying to save data that has been received over SPI. The data is converted to a static character string using dtostrf and saved to EEPROM via EEPROM.put. The program fails to compile with this error
"expected primary-expression before 'static' prev_h = EEPROM.get(0, static char);"

I dont really understand what this is asking me to change. My code can be seen below. Thank you :slight_smile:

/* Slave */

#include <SPI.h>
#include <LiquidCrystal.h>
#include <EEPROM.h> 

LiquidCrystal lcd(9, 8, 5, 4, 3, 2);


byte storage [8];
volatile byte pos;
volatile boolean process;
float buff[2];
static char bufout[16];
static char prev_h;
static char prev_t;
int write_count = 1;

void setup()
{
  lcd.begin(16, 2);
  lcd.clear();
  prev_h = EEPROM.get(0, static char);
  prev_t = EEPROM.get(1, static char);
  pinMode(MISO,OUTPUT);
  SPCR |= _BV(SPE);
  SPCR |= _BV(SPIE);
  pos = 0;
  process = false;
  Serial.begin(9600);


}

ISR(SPI_STC_vect)
{
  byte gathered = SPDR;
  if( pos < sizeof storage)
    {
      storage[pos++] = gathered;
    }
    else 
    process = true;
}

void loop()
{
  if((write_count == 1) && (prev_h <= 0)) {     // If no writes have been made and no previous readings     (SPDR <= 0) && (prev_h <= 0) (millis() < 1500)
   lcd.setCursor(0,0);
   lcd.print("Initiating");
    delay(375);
   lcd.print(".");
    delay(375);  
   lcd.print(".");
    delay(375);
   lcd.print(".");
    delay(375);
   lcd.setCursor(10,0); 
   lcd.print(" ");
   lcd.setCursor(11,0); 
   lcd.print(" ");
   lcd.setCursor(12,0); 
   lcd.print(" ");
   lcd.clear();
  }

  
    if((write_count == 1) && (prev_h > 0)){   // IF nothing in SPI data register and there IS previous readings
     
     lcd.setCursor(0,0);
     lcd.print("Prev Humid = ");
     lcd.print(prev_h);
     lcd.setCursor(0,1);
     lcd.print("Prev Temp = ");
     lcd.print(prev_t);
     lcd.clear();
  } 
  
  if( process ) // IF something has appeared in SPI data register
  {
    memcpy(buff,&storage,8);
    dtostrf(buff[0],3, 0, bufout);
   
    lcd.setCursor(0,0);
    lcd.print("Humidity = ");
    lcd.print(bufout);
    lcd.print(" %");
    write_count++;
    EEPROM.put(0, bufout);
    Serial.print(write_count);

    storage[pos] = 0;
    pos = 0;
    process = false;
    
    delay(1000);
    
    memcpy(buff,&storage,8);
    dtostrf(buff[0],3, 0, bufout);
   
    lcd.setCursor(0,1);
    lcd.print("Temp = ");
    lcd.print(bufout);
    lcd.print((char)223);
    lcd.print("C");
    write_count++;
    EEPROM.put(1, bufout);
    Serial.print(write_count);
    
    storage[pos] = 0;
    pos = 0;
    process = false;

    delay(1000);


  }code here

Where is this syntax described in the documentation???

Arduino - EEPROMGet

1 Like

Sorry I understand i should put my actual variable names there now but this is still not working. When i run the code with prev_h and prev_t where i previously had "static char" my LCD's text looks as though it is flickering and is also not displaying the data only "Prev Humidity =" and "Prev Temp = "

Post the code (there are other issues with what/where you write in memory and what you expect to read)

1 Like
/* Slave */

#include <SPI.h>
#include <LiquidCrystal.h>
#include <EEPROM.h> 

LiquidCrystal lcd(9, 8, 5, 4, 3, 2);


byte storage [8];
volatile byte pos;
volatile boolean process;
float buff[2];
static char bufout[16];
static char prev_h;
static char prev_t;
int write_count = 1;

void setup()
{
  lcd.begin(16, 2);
  lcd.clear();
  prev_h = EEPROM.get(0, prev_h);
  prev_t = EEPROM.get(1, prev_t);
  Serial.print(prev_h);
  Serial.print(prev_t);
  pinMode(MISO,OUTPUT);
  SPCR |= _BV(SPE);
  SPCR |= _BV(SPIE);
  pos = 0;
  process = false;
  Serial.begin(9600);


}

ISR(SPI_STC_vect)
{
  byte gathered = SPDR;
  if( pos < sizeof storage)
    {
      storage[pos++] = gathered;
    }
    else 
    process = true;
}

void loop()
{
  if((write_count == 1) && (prev_h <= 0)) {     // If no writes have been made and nothing in EEPROM
   lcd.setCursor(0,0);
   lcd.print("Initiating");
    delay(375);
   lcd.print(".");
    delay(375);  
   lcd.print(".");
    delay(375);
   lcd.print(".");
    delay(375);
   lcd.setCursor(10,0); 
   lcd.print(" ");
   lcd.setCursor(11,0); 
   lcd.print(" ");
   lcd.setCursor(12,0); 
   lcd.print(" ");
   lcd.clear();
  }

  
    if((write_count == 1) && (prev_h > 0)){   // IF nothing in SPI data register and there IS readings in EEPROM
     
     lcd.setCursor(0,0);
     lcd.print("Prev Humid =");
     lcd.print(prev_h);
     delay(500);
     lcd.setCursor(0,1);
     lcd.print("Prev Temp =");
     lcd.print(prev_t);
    
  } 
  
  if( process ) // IF something has appeared in SPI data register
  {
    memcpy(buff,&storage,8);
    dtostrf(buff[0],3, 0, bufout);
   
    lcd.setCursor(0,0);
    lcd.print("Humidity = ");
    lcd.print(bufout);
    lcd.print(" %");
    write_count++;
    EEPROM.put(0, bufout);
    

    storage[pos] = 0;
    pos = 0;
    process = false;
    
    delay(1000);
    
    memcpy(buff,&storage,8);
    dtostrf(buff[0],3, 0, bufout);
   
    lcd.setCursor(0,1);
    lcd.print("Temp = ");
    lcd.print(bufout);
    lcd.print((char)223);
    lcd.print("C");
    write_count++;
    EEPROM.put(1, bufout);
    
    storage[pos] = 0;
    pos = 0;
    process = false;

    delay(1000);


  }
  
  }

I removed the lcd.clear() which fixed the flickering, I added some serial prints for the EEPROM data but nothing appears in the serial monitor...

What does EEPROM.get return? Is that necessary?
What’s is prev_h’s type?


What is in bufout and what’s it’s type?

1 Like

I do not think EEPROM.put works with arrays, only primitive data types and struct.

Thank you for your responses. Below is my master code. My intention is to have EEPROM.GET return the value from the previous reading of a DHT11 sensor. It currently returns nothing within the serial monitor. prev_h i have declared as a static char as that is the same type as bufout which is a string containing the data converted from the float that is transfered over SPI using dtostrf. I do this so i can display the value on the LCD.

/* Master */
#include <SPI.h>
#include "dht.h" //This is an older version of the dht.h library v0.1.15
#define dht_apin A0

dht DHT;

uint8_t storage [12];
void setup()
{
  digitalWrite(SS, HIGH);
  SPI.begin();
  Serial.begin(9600);
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  delay(2500);
}

void loop()
{

   DHT.read11(dht_apin);
    
    Serial.print("Current humidity = ");
    Serial.print(DHT.humidity);
    Serial.print("%  ");

  digitalWrite(SS, LOW);
  memcpy(storage, &DHT.humidity, 8);
  SPI.transfer(storage, sizeof storage );
   
  delay(1000);
  
  memcpy(storage, &DHT.temperature, 8);
  SPI.transfer(storage, sizeof storage ); 
  
  digitalWrite(SS, HIGH);
  delay(1000);
}

If you store an ascii cString representation at address 0, how many bytes are used?

Can you store something else at address 1?

Does it make sense to try to read that back within just one byte?

1 Like

try simple code to get the concepts:

#include <EEPROM.h>

float temperature = 42.5; // it's hot here
char cString[30] = "42.5 degrees";
uint16_t anAray[5] = {1, 2, 3, 4, 5};

void setup() {
  Serial.begin(115200);
  Serial.println();
  EEPROM.put(0, temperature);   // stores the binary representation of the float (4 bytes) starting at address 0
  EEPROM.put(4, cString);       // stores the 30 bytes of cString starting at address 4
  EEPROM.put(34, anAray);      // stores the 10 bytes of anAray starting at address 34

  char tmpBuf[30] = "";
  float tmpTemp = 0;
  uint16_t tmpAray[5] = {0, 0, 0, 0, 0};

  EEPROM.get(0, tmpTemp);
  EEPROM.get(4, tmpBuf);
  EEPROM.get(34, tmpAray);

  Serial.print("tmpTemp = "); Serial.println(tmpTemp);
  Serial.print("tmpBuf = "); Serial.println(tmpBuf);
  
  for (byte i = 0; i < 5; i++) {
    Serial.print("tmpAray["); Serial.print(i); Serial.print("] = ");
    Serial.println(tmpAray[i]);
  }
}

void loop() {}

the serial monitor will show (at 115200 bauds)

tmpTemp = 42.50
tmpBuf = 42.5 degrees
tmpAray[0] = 1
tmpAray[1] = 2
tmpAray[2] = 3
tmpAray[3] = 4
tmpAray[4] = 5

so we do get our data back.

1 Like

it does work. see example just above. (if you use a parameter to pass the array to a save function, then your parameter has decayed into a pointer and then of course you end up saving the value of the pointer...)

I'll have to look at the source code for EEPROM put and get, it is not obvious how those determine the size of the arrays, particularly when not using a null terminated char array.

that's the source code. They use templates.

It is pretty obvious - they simply call sizeof to know how many bytes the variable needs to be represented.

that's why it does not work with a decayed array (the variable is just a pointer and thus sizeof will be the size of a pointer), but if your array is a global then there is no problem.

cStrings are not dealt with in a specific way, all the bytes are written like other arrays, regardless of the presence or not of an '\0'. (so you have to be sure of what you play with)

Thanks for the help, your responses went a bit over my head but i have managed to get everything working!

Here is my code if interested...

Just need to work on the timing of my transmissions :slight_smile:

/* Slave */

#include <SPI.h>
#include <LiquidCrystal.h>
#include <EEPROM.h> 
//#include <cstring>
//#include <iostream>
//#include <string>

LiquidCrystal lcd(9, 8, 5, 4, 3, 2);


byte storage [8];
volatile byte pos;
volatile boolean process;
float buff[2];
char bufout_h[16];
char bufout_t[16];
char prev_h;
char prev_t;
int write_count = 1;

int writeStringToEEPROM(int addrOffset, const String &strToWrite) // Writes strings to EEPROM bit by bit
{
  byte len = strToWrite.length();
  EEPROM.write(addrOffset, len);
  for (int i = 0; i < len; i++)
  {
    EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
  }
  return addrOffset + 1 + len;
}

int readStringFromEEPROM(int addrOffset, String *strToRead) // Reads strings from EEPROM bit by bit
{
  int newStrLen = EEPROM.read(addrOffset);
  char data[newStrLen + 1];
  for (int i = 0; i < newStrLen; i++)
  {
    data[i] = EEPROM.read(addrOffset + 1 + i);
  }
  data[newStrLen] = '\0'; 
  *strToRead = String(data);
  return addrOffset + 1 + newStrLen;
}

void setup()
{
  
  lcd.begin(16, 2);
  lcd.clear();
  pinMode(MISO,OUTPUT);
  SPCR |= _BV(SPE);
  SPCR |= _BV(SPIE);
  pos = 0;
  process = false;
  Serial.begin(9600);
 
}

ISR(SPI_STC_vect)
{
  byte gathered = SPDR;
  if( pos < sizeof storage)
    {
      storage[pos++] = gathered;
    }
    else 
    process = true;
}

void loop()
{
  int eepromOffset = 0;
  
  if((write_count == 1) && (((EEPROM.read(0)<=0))|(EEPROM.read(1)<=0))) {     // If no writes have been made and nothing in EEPROM
   lcd.setCursor(0,0);
   lcd.print("Initiating");
    delay(600);
   lcd.print(".");
    delay(600);  
   lcd.print(".");
    delay(600);
   lcd.print(".");
    delay(600);
   lcd.setCursor(10,0); 
   lcd.print(" ");
   lcd.setCursor(11,0); 
   lcd.print(" ");
   lcd.setCursor(12,0); 
   lcd.print(" ");
   lcd.clear();
  }

  
    if((write_count == 1) && (((EEPROM.read(0)>0))|(EEPROM.read(1)>0))){   // IF nothing in SPI data register and there IS readings in EEPROM
     
     lcd.setCursor(0,0);
     lcd.print("Prev Humid =");
     String newStr1;
     int newStr1AddrOffset = readStringFromEEPROM(eepromOffset, &newStr1);
     lcd.print(newStr1);

     
     lcd.setCursor(0,1);
     lcd.print("Prev Temp =");
     String newStr2;
     int newStr2AddrOffset = readStringFromEEPROM(newStr1AddrOffset, &newStr2);
     lcd.print(newStr2);
   
  } 
   
   
  if( process ) // IF something has appeared in SPI data register
  {
    int eepromOffset = 0;
    memcpy(buff,&storage,8);
    dtostrf(buff[0],3, 0, bufout_h);
   
    lcd.setCursor(0,0);
    lcd.print("Humidity = ");
    lcd.print(bufout_h);
    lcd.print(" %");
    write_count++;
    String str1 = bufout_h;
    int str1AddrOffset = writeStringToEEPROM(eepromOffset, str1);
    
    
    storage[pos] = 0;
    pos = 0;
    process = false;
    
    delay(750);
    
    memcpy(buff,&storage,8);
    dtostrf(buff[0],3, 0, bufout_t);
   
    lcd.setCursor(0,1);
    lcd.print("Temp = ");
    lcd.print(bufout_t);
    lcd.print((char)223);
    lcd.print("C");
    write_count++;
    String str2 = bufout_t;
    int str2AddrOffset = writeStringToEEPROM(str1AddrOffset, str2);

    
    storage[pos] = 0;
    pos = 0;
    process = false;

    delay(1250);


  }
  
  }