[SOLVED] Reading incorrect values from an array while inside an interrupt

Hello all. I am having a problem that made me create an account just to post this question.

In essence, I have a hard-coded lookup table (an array) of a sine wave that I would like to access within an interrupt.

Whenever I try to read a value from the array while inside an interrupt, the result is not the correct indexed element. The result is not even an element of the array at all!

I am using a library, the TimerOne library, but I believe it is just a wrapper for easy pwm and timer setups.

I have tried almost every variation of my lookup table variable signature that I can think of. I have tried surrounding different blocks of code with the noInterrupts() and interrupts() method calls. But reading the array still returns a wrong value.

I have no idea what the reasoning could be. Can someone explain why this might be happening?

#include <TimerOne.h>

#define o_pin 10


//I have tried many variants for the variable signature but non seem to work
const static volatile uint8_t my_lut[100] PROGMEM = 
{
  544,  576,  607,  639,  670,  700,  729,  758,  786,  812,
  838,  862,  884,  906,  925,  943,  960,  974,  987,  998, 1007,
 1014, 1019, 1022, 1023, 1022, 1019, 1014, 1007,  998,  987,  974,
  960,  943,  925,  906,  884,  862,  838,  812,  786,  758,  729,
  700,  670,  639,  607,  576,  544,  511,  479,  447,  416,  384,
  353,  323,  294,  265,  237,  211,  185,  161,  139,  117,   98,
   80,   63,   49,   36,   25,   16,    9,    4,    1,    0,    1,
    4,    9,   16,   25,   36,   49,   63,   80,   98,  117,  139,
  161,  185,  211,  237,  265,  294,  323,  353,  384,  416,  447,
  479, 512
};


volatile uint8_t temp = 0;

void setup() {
  Serial.begin(19200);
  pinMode(o_pin,OUTPUT);
  Timer1.initialize(10000);
  Timer1.attachInterrupt(my_int);
}

void loop() {
    noInterrupts(); //Have tried with this line and without this line
    Serial.println(temp);
    interrupts(); //Have tried with this line and without this line
}


void my_int(void){
  noInterrupts(); //Have tried with this line and without this line
  temp = my_lut[0];
  interrupts(); //Have tried with this line and without this line
}

Here are some print results for the above code. I try to access the 0th element (my_lut[0]):

01:23:25.377 -> 0
01:23:25.377 -> 0
01:23:25.377 -> 0
01:23:25.377 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.411 -> 0
01:23:25.445 -> 0
01:23:25.445 -> 0
01:23:25.445 -> 0
01:23:25.445 -> 0
01:23:25.445 -> 0
01:23:25.445 -> 0

And here are some print results from another (random) index of my_lut. In this case I tried reading the 52nd element (my_lut[52]):

01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
01:24:28.945 -> 2
  temp = my_lut[0];

Is that how you read a value from an array in PROGMEM ?

This did not work.

temp = pgm_read_byte(my_lut)

I tried this and still was not reading the correct value.

temp = pgm_read_byte(&my_lut)

Perhaps I am having difficulties understanding how to read from program memory? I checked some other solutions and one of those should work.

Will 544 fit in a byte I wonder ?

Maybe this will help

const static volatile uint16_t my_lut[100] PROGMEM =
{
  544,  576,  607,  639,  670,  700,  729,  758,  786,  812,
  838,  862,  884,  906,  925,  943,  960,  974,  987,  998, 1007,
  1014, 1019, 1022, 1023, 1022, 1019, 1014, 1007,  998,  987,  974,
  960,  943,  925,  906,  884,  862,  838,  812,  786,  758,  729,
  700,  670,  639,  607,  576,  544,  511,  479,  447,  416,  384,
  353,  323,  294,  265,  237,  211,  185,  161,  139,  117,   98,
  80,   63,   49,   36,   25,   16,    9,    4,    1,    0,    1,
  4,    9,   16,   25,   36,   49,   63,   80,   98,  117,  139,
  161,  185,  211,  237,  265,  294,  323,  353,  384,  416,  447,
  479, 512
};

void setup()
{
  Serial.begin(115200);
  for (int x = 0; x < 8; x++)
  {
    Serial.println(pgm_read_word(&my_lut[x]));
  }
}

void loop()
{
}

snooch, is this with an Arduino Uno or similar board ?

The Arduino Uno can only execute code that is in flash memory and can only read and write variables which are in sram. It can not read data from flash.

The PROGMEM puts data in flash, and with special functions that data can be read.

In the first reply by UKHeliBob, he said:

UKHeliBob:
Is that how you read a value from an array in PROGMEM ?

That was meant to make you think if that is possible and why not. You can start for example with this page: PROGMEM - Arduino Reference.

Koepel and UKHeliBob. Thank you two very much. I believe I understand what I was doing wrong.

For starters, I had missed the fact that I needed to be using a 16 bit integer instead of an 8 bit. I can imagine a lot of my problems were coming from there.

Secondly, when that didn't work I tried messing around with PROGMEM without reading too much into how to use it or what it is. I tried using a hammer when I needed a screwdriver.

Thank you for helping me reach this conclusion.

Lastly, I just wanted to say, I cannot believe how active this forum is. I posted my question in the middle of the night and within a couple of hours I had two experienced users come in and help me. I am very surprised and delighted. You guys are awesome!

EDIT: How do I mark as solved?

Sometimes a hammer is the right tool for the job :wink:
This is not stackexchange, you don't have to mark it as 'solved'. If you want to, you can use "Modify" (click "More" in the lower-right corner of your message) for the first message of this thread and put [Solved] in front of the subject title.

I cannot believe how active this forum is. I posted my question in the middle of the night and within a couple of hours I had two experienced users come in and help me.

It helps that your middle of the night is my 07:30 !

Ever since I joined the forum I have been impressed with the speed of response to most posts which I am sure surprises many new users

Incidentally, as Koepel pointed out my initial replies were designed to make you think/research rather than just feeding you the answer, which I believe is a good way of learning, but people differ in their outlook

Good luck with your project