Go Down

Topic: Problem reading pointer to PROGMEM int variable with pgm_read_word (Read 181 times) previous topic - next topic

Flatomic

Hello:

I am trying to get the INT value stored in the program memory through pgm_read_word. But mySerial.printf() shows 0 instead 85.

What is wrong with my code?


Code: [Select]


#include <SoftwareSerial.h>
SoftwareSerial mySerial(1, 0);

PROGMEM const int num = 85;

const int *pointer;

void setup() {
 
  mySerial.begin(9600);
 

  pointer = &num;
 
  // put your setup code here, to run once:
  int *x = (int*)pgm_read_word(&pointer);

  mySerial.println(*x);   
}

PaulS

Why are you casting the int returned by pgm_read_word() to an int pointer?
The art of getting good answers lies in asking good questions.

westfw

Quote
Code: [Select]
  int *x = (int*)pgm_read_word(&pointer);
You're reading FROM a pointer, not TO a pointer.  (unless you want the word from address 85 of RAM.)
and "pointer" is already a pointer, so you don't need the "&" in front of it.
So that should just be:
Code: [Select]
      int x = pgm_read_word(pointer);
// Or:
      int x = pgm_read_word(&num);

Flatomic

¡Yes! It is unnecesary. pgm_read_word return an 16bit unsigned integer. Furthermore I don't need '&' symbol on
Code: [Select]
pgm_read_word(&pointer);

Now, this is my code, and it returns the correct value!


Code: [Select]

#include <SoftwareSerial.h>

SoftwareSerial mySerial(1, 0);

PROGMEM const int num = 69;

const int *pointer;

void setup() {
 
     mySerial.begin(9600);

     pointer = &num; 
 
     int x = pgm_read_word(pointer);

     mySerial.println(x);  // Print

}


Thanks!!

Flatomic

I have a new problem if I try to reading a PROGREM struct...

Code: [Select]

typedef struct MenuItem {
 const char *name;
 const int *quantity;
} MenuItem;

// Menu Item values
PROGMEM const char name[] = "NAME";
PROGMEM const int num = 69;

// Initialize menuitems
PROGMEM const MenuItem mi = {name,&num};  

const MenuItem *root;

void setup() {
 mySerial.begin(9600);

 // Pointer to menuitem struct
 root = &mi;
 
 // Get the name
 char buf[50];  
 strcpy_P(buf, (char *)pgm_read_word(&root->name));

 // Get the quantity
 int q = pgm_read_word(&root->quantity);

 mySerial.println(buf);  // Prints: NAME
 mySerial.println(q);  // Prints 104. It's incorrect!
}

stowite

Code: [Select]

typedef struct MenuItem {
 PROGMEM const char *name;
 PROGMEM const int *quantity;
} MenuItem;


This will solve your immediate problem but why are you storing a pointer to an 'int' in PROGMEM rather than just the 'int' value.

Flatomic

Code: [Select]

typedef struct MenuItem {
 PROGMEM const char *name;
 PROGMEM const int *quantity;
} MenuItem;


This will solve your immediate problem but why are you storing a pointer to an 'int' in PROGMEM rather than just the 'int' value.
Sorry, but this doesn't work. With your modifications mySerial prints incorrect values:

Code: [Select]

mySerial.println(buf);  // Print: ö
mySerial.println(q);  // Print 250. It's incorrect!


To your question: I need this INT pointer to point to a variable that constantly changes. This code that I have published is a reduced version of a larger one. In the larger one, I have a menu with menu items. Every menu item has a "name" and a "quantity".

Then I combine this values to show texts like "5 Notifications", where name="Notifications" and quantity="5".

Quantity is the pointer who points to notificationsCount.


This is the code with your modifications:
Code: [Select]

typedef struct MenuItem {
  PROGMEM const char *name;
  PROGMEM const int *quantity;
} MenuItem;

// Menu Item values
PROGMEM const char name[] = "NAME";
PROGMEM const int num = 69;

// Initialize menuitems
PROGMEM const MenuItem mi = {name,&num};  

const MenuItem *root;

void setup() {
  mySerial.begin(9600);

  root = &mi;
  
  // Get the name
  char buf[50];  
  strcpy_P(buf, (char *)pgm_read_word(&root->name));

  // Get the quantity
  int q = pgm_read_word(&root->quantity);

  mySerial.println(buf);  // Print: ö.  It's incorrect!
  mySerial.println(q);  // Print 256. It's incorrect!
}

Go Up