[SOLVED] use a variable for an element in pgm_read_float

Hello all,

I think I am trying something that is not allowed by arduino. I am trying to pass a variable to a pgm_read_float to get some configuration data. My test is as follows:

#include <avr/pgmspace.h>;

uint8_t specySelect = 1;

const char specy_0[] PROGMEM = "";
const char specy_1[] PROGMEM = "CHICKEN";
const char specy_2[] PROGMEM = " QUAIL";
const char specy_3[] PROGMEM = " GEESE";
const char specy_4[] PROGMEM = " DUCKS";
const char* const species[] PROGMEM = { specy_0, specy_1, specy_2, specy_3, specy_4};
char specyName[8];

const float CHICKEN[] PROGMEM = {
  1,              // specySelect -- what specy is selected
  19,             // incubateDay -- number of days for incubation
  3,              // hatchingDay -- number of days for hatching
  36,             // minTempEggs -- min temperature for eggs ( embryo is killed under 20°C)
  39,             // maxTempEggs -- max temperature for eggs ( embryo is killed over 41 °C)
  37.5,           // fstPartTemp -- temperature first days         
  45,             // fstPartHumi -- humidity first days
  36.5,           // lstPartTemp -- temperature last days
  75,             // lstPartHumi -- humidity last days
  35              // endPartTemp -- temp after hatching is finnished
};
const float QUAIL[] PROGMEM = {
  2, 15, 3, 36, 39, 37.5, 45, 36.5, 65, 35
};
const float GEESE[] PROGMEM = { // --- don't have the right figures yet ---
  2, 14, 16, 37.4, 60, 36.5, 75, 35, 0, 0
};
const float DUCKS[] PROGMEM = { // --- don't have the right figures yet ---
  2, 14, 16, 38.5, 45, 36.5, 75, 35, 0, 0
};

float displFloat;
uint8_t noDec;
String specyString;


void setup() {
  Serial.begin( 115200);
/*
  for( i = 0; i < 10; i ++){
    displFloat = pgm_read_float( chicken + i);
    Serial.print( displFloat);
    Serial.print( "\t");
    if( i == 5 || i == 7) {
      Serial.println( displFloat);
    } else {
      noDec = displFloat;
      Serial.println( noDec);
    }
  }
*/
  strcpy_P( specyName, ( char*) pgm_read_word( &( species[ specySelect])));
  Serial.println( specyName);

  uint8_t  incubateDay = pgm_read_float( specyName + 1);
  uint8_t  hatchingDay = pgm_read_float( specyName + 2);
  float    minTempEggs = pgm_read_float( specyName + 3);
  float    maxTempEggs = pgm_read_float( specyName + 4);
  float    fstPartTemp = pgm_read_float( specyName + 5);
  uint8_t  fstPartHumi = pgm_read_float( specyName + 6);
  float    lstPartTemp = pgm_read_float( specyName + 7);
  uint8_t  lstPartHumi = pgm_read_float( specyName + 8);
  float    endPartTemp = pgm_read_float( specyName + 9);

  Serial.print( "incubateDay: ");Serial.println( incubateDay);
  Serial.print( "hatchingDay: ");Serial.println( hatchingDay);
  Serial.print( "minTempEggs: ");Serial.println( minTempEggs);
  Serial.print( "maxTempEggs: ");Serial.println( maxTempEggs);
  Serial.print( "fstPartTemp: ");Serial.println( fstPartTemp);
  Serial.print( "fstPartHumi: ");Serial.println( fstPartHumi);
  Serial.print( "lstPartTemp: ");Serial.println( lstPartTemp);
  Serial.print( "lstPartHumi: ");Serial.println( lstPartHumi);
  Serial.print( "endPartTemp: ");Serial.println( endPartTemp);
}


void loop() {}

I would like to pass a variable name to "specyName" to retrieve the data for some of the variables.

The output I get is:

CHICKEN
incubateDay: 0
hatchingDay: 0
minTempEggs: -0.00
maxTempEggs: ovf
fstPartTemp: -0.00
fstPartHumi: 0
lstPartTemp: -0.00
lstPartHumi: 0
endPartTemp: -0.00

When I use CHICKEN instead of specyName in pgm_read_float, I am getting the right numbers.
Why can't I get the right data?

Thanks.

This code doesn't make any sense:

  uint8_t  incubateDay = pgm_read_float( specyName + 1);
  uint8_t  hatchingDay = pgm_read_float( specyName + 2);
  float    minTempEggs = pgm_read_float( specyName + 3);
  float    maxTempEggs = pgm_read_float( specyName + 4);
  float    fstPartTemp = pgm_read_float( specyName + 5);
  uint8_t  fstPartHumi = pgm_read_float( specyName + 6);
  float    lstPartTemp = pgm_read_float( specyName + 7);
  uint8_t  lstPartHumi = pgm_read_float( specyName + 8);
  float    endPartTemp = pgm_read_float( specyName + 9);

specyName is a character array of 8 bytes in RAM. You are copying the species name to it from PROGMEM. First you are trying to read it like it is in PROGMEM, Second you are trying to read a character array as if it were a float which is 4 bytes.

I can't tell what you are really trying to do. Are you thinking because you a have string with the contents "CHICKEN" you can try to read the array named "CHICKEN"? If so you cannot do that. C++ is a compiled language. Identifier names are bound at compile time.

You could use a struct and an array of structs to simplify your code:

struct fowl_T
{
  char species[8];
  uint8_t  incubateDay;
  uint8_t  hatchingDay;
  float    minTempEggs;
  float    maxTempEggs;
  float    fstPartTemp;
  uint8_t  fstPartHumi;
  float    lstPartTemp;
  uint8_t  lstPartHumi;
  float    endPartTemp;
};

fowl_T const fowls[] PROGMEM = 
{
  {
    "CHICKEN",
    19,             // incubateDay -- number of days for incubation
    3,              // hatchingDay -- number of days for hatching
    36,             // minTempEggs -- min temperature for eggs ( embryo is killed under 20°C)
    39,             // maxTempEggs -- max temperature for eggs ( embryo is killed over 41 °C)
    37.5,           // fstPartTemp -- temperature first days         
    45,             // fstPartHumi -- humidity first days
    36.5,           // lstPartTemp -- temperature last days
    75,             // lstPartHumi -- humidity last days
    35              // endPartTemp -- temp after hatching is finnished
  },
  {
    "QUAIL", 15, 3, 36, 39, 37.5, 45, 36.5, 65, 35
  },
  { // --- don't have the right figures yet ---
    "GEESE", 14, 16, 37.4, 60, 36.5, 75, 35, 0, 0
  },
  { // --- don't have the right figures yet ---
    "DUCKS", 14, 16, 38.5, 45, 36.5, 75, 35, 0, 0
  }
};

Thanks a lot for this explanation. I thought already I was trying to misuse C++.
The code that does not make sense to you, is for me for testing purposes, and yes that is in my head and I know none of you can read minds, sorry for that.
You explain clearly why I was unable to read the data from the array. You guesed it right that I thought having the name "CHICKEN" in a string, to be able to read the array "CHICKEN". So back to the drawing board with a new snippet of code.

I am writing every hour some data to eeprom. When there is a power failure and the arduino reboots, I retrieve the last reading from eeprom with the selected specy ( also stored in eeprom) to continue the incubation process. Therefor I need to re-apply some variables. Since I have multiple species to select from, the variables are different per specy.

ToddL1962 -> Thanks again for helping. Please find folowing the code I have modified and is working the way I want.

#include <avr/pgmspace.h>;

struct incubateStruct {
  char species[8];
  uint8_t  incubateDay;
  uint8_t  hatchingDay;
  float    minTempEggs;
  float    maxTempEggs;
  float    fstPartTemp;
  uint8_t  fstPartHumi;
  float    lstPartTemp;
  uint8_t  lstPartHumi;
  float    endPartTemp;
};

const incubateStruct incubateArrayProgmem[] PROGMEM = {
  {
    "CHICKEN",
    19,             // incubateDay -- number of days for incubation
    3,              // hatchingDay -- number of days for hatching
    36,             // minTempEggs -- min temperature for eggs ( embryo is killed under 20°C)
    39,             // maxTempEggs -- max temperature for eggs ( embryo is killed over 41 °C)
    37.5,           // fstPartTemp -- temperature first days         
    45,             // fstPartHumi -- humidity first days
    36.5,           // lstPartTemp -- temperature last days
    75,             // lstPartHumi -- humidity last days
    35              // endPartTemp -- temp after hatching is finnished
  },
  {
    "QUAIL", 15, 3, 36, 39, 37.5, 45, 36.5, 65, 35
  },
  { // --- don't have the right figures yet ---
    "GEESE", 14, 16, 37.4, 60, 36.5, 75, 35, 0, 0
  },
  { // --- don't have the right figures yet ---
    "DUCKS", 14, 16, 38.5, 45, 36.5, 75, 35, 0, 0
  }
};

incubateStruct incubateArraySram;

void setup() {
  Serial.begin( 115200);

  for( int i = 0; i < (sizeof( incubateArrayProgmem) / sizeof( incubateStruct)); i++){
    Serial.println ( i);
    memcpy_P( &incubateArraySram, &incubateArrayProgmem[i], sizeof( incubateStruct));
    Serial.print( "Specy: ")      ;Serial.println( incubateArraySram.species);
    Serial.print( "incubateDay: ");Serial.println( incubateArraySram.incubateDay);
    Serial.print( "hatchingDay: ");Serial.println( incubateArraySram.hatchingDay);
    Serial.print( "minTempEggs: ");Serial.println( incubateArraySram.minTempEggs);
    Serial.print( "maxTempEggs: ");Serial.println( incubateArraySram.maxTempEggs);
    Serial.print( "fstPartTemp: ");Serial.println( incubateArraySram.fstPartTemp);
    Serial.print( "fstPartHumi: ");Serial.println( incubateArraySram.fstPartHumi);
    Serial.print( "lstPartTemp: ");Serial.println( incubateArraySram.lstPartTemp);
    Serial.print( "lstPartHumi: ");Serial.println( incubateArraySram.lstPartHumi);
    Serial.print( "endPartTemp: ");Serial.println( incubateArraySram.endPartTemp);
    Serial.println();
  }
}


void loop() {}

Outputs the following to Serial:

0
Specy: CHICKEN
incubateDay: 19
hatchingDay: 3
minTempEggs: 36.00
maxTempEggs: 39.00
fstPartTemp: 37.50
fstPartHumi: 45
lstPartTemp: 36.50
lstPartHumi: 75
endPartTemp: 35.00

1
Specy: QUAIL
incubateDay: 15
hatchingDay: 3
minTempEggs: 36.00
maxTempEggs: 39.00
fstPartTemp: 37.50
fstPartHumi: 45
lstPartTemp: 36.50
lstPartHumi: 65
endPartTemp: 35.00

2
Specy: GEESE
incubateDay: 14
hatchingDay: 16
minTempEggs: 37.40
maxTempEggs: 60.00
fstPartTemp: 36.50
fstPartHumi: 75
lstPartTemp: 35.00
lstPartHumi: 0
endPartTemp: 0.00

3
Specy: DUCKS
incubateDay: 14
hatchingDay: 16
minTempEggs: 38.50
maxTempEggs: 45.00
fstPartTemp: 36.50
fstPartHumi: 75
lstPartTemp: 35.00
lstPartHumi: 0
endPartTemp: 0.00

Now I can continue working on the failSafe of my incubator.

Thanks again, now I have to find out how to close this thread..

spa2036:
ToddL1962 -> Thanks again for helping. Please find folowing the code I have modified and is working the way I want.

Now I can continue working on the failSafe of my incubator.

Thanks again, now I have to find out how to close this thread..

Glad it worked out for you!

Just edit the title of the thread to include "[SOLVED]" that way everyone knows it is solved.