Search code examples
c++arduinoadafruit

Why can't I access a value from this array using a functionally calculated int as an index?


EDIT: I mistakenly assumed I should ask this as a general C++ question, and realized later that this issue came from my usage of C++ within the Arduino environment. In my example, I didn't include my usage of an Arduino modifer PROGMEM on the array which moved its storage from RAM to FLASH and is ultimately what caused the calculation issue. Accessing the PROGMEM array required me to use an accessor method pgm_read_byte instead of an index.

I have an array:

const PROGMEM uint8_t daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

I have a functionally calculated uint8 from a time library:

uint8_t month = tm.month();

I have a size_t:

size_t monthIndex = (size_t)month;

I've tried using either month or monthIndex to access a value from this array, however the same result happens:

# For size_t monthIndex = 1 or uint8 month = 1; ...
uint8_t currentDaysInMonth = daysInMonth[monthIndex];

# >> Expected = 28;
# >> What I actually get = 61;

How do I get the expected array value?

Where is 61 coming from?

EDITS

This is the relevant portion of the DateTime class for tm

class DateTime {
public:
  DateTime (uint16_t year, uint8_t month, uint8_t day,
              uint8_t hour = 0, uint8_t min = 0, uint8_t sec = 0);

  uint8_t month() const       { return m; }
}

Datetime constructor

DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
    if (year >= 2000)
        year -= 2000;
    yOff = year;
    m = month;
    d = day;
    hh = hour;
    mm = min;
    ss = sec;
}

Minimal example:

DateTime tm = DateTime(2020, 2, 1, 0, 0, 0);

const PROGMEM uint8_t daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

uint8_t month = tm.month();

uint8_t currentDaysInMonth = daysInMonth[month];

>> currentDaysInMonth Returns 61
>> expect 31 from this example, though would offset index - 1 once I figure out what the issue is.

Print logs:

std::cout << month << std::endl;
std::cout << tm.month() << std::endl;
std::cout << currentDaysInMonth << std::endl;

# >> 2
# >> 2
# >> 219 -- sometimes its 61, 45, 219, not sure the rhyme or reason to this value


Solution

  • I mistakenly assumed I should ask this as a general C++ question, and realized later that this issue came from my usage of C++ within the Arduino environment. In my example, I didn't include my usage of an Arduino modifer PROGMEM on the array which moved its storage from RAM to FLASH and is ultimately what caused the calculation issue. Accessing the PROGMEM array required me to use an accessor method pgm_read_byte instead of an index.

    Solution:

    DateTime tm = DateTime(2020, 2, 1, 0, 0, 0);
    
    const PROGMEM uint8_t daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    uint8_t month = tm.month();
    
    # use the pgm_read_byte accessor
    uint8_t currentDaysInMonth = pgm_read_byte(&daysInMonth[month - 1]); 
    

    Thanks everyone for your help! Sorry for the initial lack of information.

    Some resources:

    https://www.arduino.cc/reference/tr/language/variables/utilities/progmem/

    https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html