Getting junk data when trying to retrieve elements from a PROGMEM array on Arduino - arduino

My code looks something like this:
#define SIZE_OF_ARRAY 1000
const long myArray[SIZE_OF_ARRAY] PROGMEM = {
1610514120L,
1613070480L,
1615630980L,
1618194720L,
1620759660L,
1623322440L,
1625879820L,
1628430600L,
1630975920L,
1633518300L,
1636060500L,
1638603840L,
1641148500L,
1643694540L,
... // All the way to 1000 elements
}
void setup() {
Serial.begin(115200);
for( int i = 0; i < SIZE_OF_ARRAY; i++){
long currentNumber = myArray[i];
// These also do not work:
//long currentNumber = pgm_read_word_near(myArray + i);
//long currentNumber = pgm_read_dword_near(myArray + i);
Serial.println(currentNumber);
}
}
But when I run this code, I get completely random junk data:
0
65536
0
-1195853640
8843185
-566231498
-310626819
-854754529
263210495
-325068311
-159567983
-1770239
-29784074
1054840810
-293611553
-436273185
-566231498
-310626819
-854754529
263210495
... all the way up to 1000
How can I access that array to get the data I put in it? I am not very familiar with C and the difference between variables and pointers, but it works without the PROGMEM flag so I assumed it would work with it as well.

Looks like the answer was to use:
void setup() {
Serial.begin(115200);
for( int i = 0; i < SIZE_OF_ARRAY; i++){
unsigned long currentNumber = pgm_read_dword_near(myArray + i);
Serial.println(currentNumber);
}
}
And to redefine the long array as:
const unsigned long myArray[SIZE_OF_ARRAY] PROGMEM = {
1610514120UL,
1613070480UL,
1615630980UL,
1618194720UL,
1620759660UL,
...
}
Because I was also running into long overflow errors

Related

iteration 500 invokes undefined behavior [-Waggressive-loop-optimizations]

I am working on an Arduino code and the code seems to be good and well structured but i have an error in one line of I think or maybe I forgot to add smthg anyway here is the code
#include <SoftwareSerial.h>
#include <avr/pgmspace.h>
const int dsize = 500;
int analogPin = A0;
int data[dsize];
int counter = 0;
unsigned long measurmentDelay = 600000; //10 min
SoftwareSerial mySerial(2, 3); // RX, TX
unsigned long time_now = millis();
void setup() {
// put your setup code here, to run once:
delay(500);
mySerial.begin(9600);
mySerial.println("###Power on###");
int i=0;
for (i = 0; i < dsize+1; i = i+1) {
data[i]=0;
}
time_now = millis();
}
and I have this error and I don't know what to do
H:\Python\sketch_feb19a\sketch_feb19a.ino: In function 'setup':
H:\Python\sketch_feb19a\sketch_feb19a.ino:20:14: warning: iteration 500 invokes undefined behavior [-Waggressive-loop-optimizations]
data[i]=0;
^
H:\Python\sketch_feb19a\sketch_feb19a.ino:19:3: note: containing loop
for (i = 0; i < dsize+1; i = i+1) {
^
Please if anyone can help I would be thankful.
Actually the error is pretty clear. It tells you that in your loop the iteration 500 has something wrong on it.
If you take a closer look, you will see that data is a 500 element array.
You are iterating from 0 to 500 (both included) so it's 501 elements.
To solve it, your loop should only have 500 steps, not 501 (basically remove the +1 in the code)
for (i = 0; i < dsize; i = i+1)

Arduino Deputy function compute array

I use an Arduino Uno with Arduino IDE 1.8.3. I have two arrays. I want to write a Deputy function that can add two arrays, and return the result to the main function and print it.
But I want to use x(sizeof(a)), but it seems not correct...
How do I solve this problem?
This is my code:
int a[]={1,2,3,4,5,6},b[]={1,1,1,1,1,1};
void setup() {
Serial.begin(9600);
int *p;
p = add(a,b);
for(int i=0;i<4;i++){
Serial.print(*(p+i));
}
}
void loop() {
}
int * add(int *a,int *b) {
int x = sizeof(a);
int y = sizeof(b);
static int z[4];
for(int i=0;i<4;i++) {
z[i]=a[i]+b[i];
}
return z;
}
int* a does not know the size of the array.
Easiest pass it as an extra parameter.
The next problem is that your static result cannot change its size dynamically.
static has additional problems anyway, in general.
int* add(const int *a,const int *b, int* result, byte size) {
for(byte i=0; i<size; i++) {
result[i]=a[i]+b[i];
}
return result;
}
Returning the result as the return value may be convenient.

How to retrieve an int array that is stored in a table using PROGMEM?

I'm new to Arduino and currently learn to use PROGMEM to store variables so that I can save dynamic memory. I have 13 variables including these three below that I store using PROGMEM.
Here are some of example of variables that I store and use it in my functions :-
const unsigned int raw_0[62] PROGMEM = {2600,850,400,500,400,500,450,850,450,850,1350,850,450,450,400,500,400,450,450,400,450,450,450,450,400,450,900,850,900,850,900,450,450,850,900,850,900,850,450,450,900,450,400,450,400,900,450,450,450,400,450,450,450,450,400,450,450,450,450,400,450,};
const unsigned int raw_1[60] PROGMEM = {2600,850,450,450,450,450,450,850,450,850,1350,850,500,400,450,400,450,450,450,450,400,450,450,450,400,450,900,850,900,900,850,450,450,850,850,900,900,900,400,450,900,450,450,400,450,850,450,450,450,450,400,450,450,450,450,400,450,450,850,};
const unsigned int raw_a[100] PROGMEM = {3500,1700,400,450,450,1250,450,400,450,400,450,400,500,400,450,400,450,400,450,400,450,450,400,400,500,400,450,400,450,1300,400,450,450,400,450,400,450,400,450,400,450,400,500,350,500,400,450,400,450,1300,400,400,500,400,450,400,450,400,450,450,400,450,450,400,450,400,450,400,450,400,450,450,400,450,450,400,450,1250,450,400,450,400,500,400,450,400,450,400,450,400,450,400,450,1300,450,400,450,1250,450,};
Here is the table that store the variables. I learn this approach from Arduino website; https://www.arduino.cc/en/Reference/PROGMEM .
const unsigned int* const myTable[13] PROGMEM = {
raw_0,
raw_1,
raw_2,
raw_3,
raw_4,
raw_5,
raw_6,
raw_7,
raw_8,
raw_9,
raw_a,
raw_b,
raw_c};
My problem is, how do I retrieve these variables using PROGMEM such as raw_1 and raw_a ?
This is what I did but it did not work :-
unsigned int * ptr = (unsigned int *) pgm_read_word (&myTable [1]);
irsend.sendRaw(ptr,62,38);
Most of examples that I found, they use String or char datatype but in my case, I use array integer.
The ptr is also pointer to PROGMEM, so you have to read the value (or values in this case) by pgm_read_word. The IR library doesn't support that at all (I hope it's the correct one).
Anyway sendRaw implementation is this:
void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz)
{
// Set IR carrier frequency
enableIROut(hz);
for (unsigned int i = 0; i < len; i++) {
if (i & 1) space(buf[i]) ;
else mark (buf[i]) ;
}
space(0); // Always end with the LED off
}
And all used methods are public, so you can implement your own function to do the same:
void mySendRaw (IRsend & dev, const unsigned int buf[], unsigned int len, unsigned int khz)
{
// Set IR carrier frequency
dev.devenableIROut(khz);
for (unsigned int i = 0; i < len; i++) {
if (i & 1) dev.space(pgm_read_word(buf+i));
else dev.mark (pgm_read_word(buf+i));
}
dev.space(0); // Always end with the LED off
}
// And usage:
mySendRaw(irsend, (const uint16_t*)pgm_read_word(myTable+1), 62, 38);
However the size of arrays should be stored somewhere too, so you can use something like:
byte cmd = 1;
mySendRaw(irsend, (const uint16_t*)pgm_read_word(myTable+cmd), pgm_read_word(myTableLenghts+cmd), 38);

Arduino Uno - EEPROM locations not consistant

I was trying to write items to the EEPROM and later read them out. I was finding the reading back I was not getting the same as I put in at times. I narrow down to an example I can show you. Below I read into variables 2 address.
const int start_add_type = (EEPROM.length() - 10);
const int start_add_id = (EEPROM.length() - 4);
I then look at the value (via RS232)
Serial.begin(9600);
Serial.println(start_add_type);
Serial.println(start_add_id);
of them at the start of the setup() and see I get
1014
1020
I then look again at the end
Serial.println(start_add_type);
Serial.println(start_add_id);
and I get
1014
818
I cannot see why this should change. I did try calling them const e.g. const
const int start_add_type = (EEPROM.length() - 10);
const int start_add_id = (EEPROM.length() - 4);
but this gave the same result. So here I sit very puzzled at what I must have missed. Anyone got any idea?
#include "EEPROM.h"
int start_add_type = (EEPROM.length() - 10);
int start_add_id = (EEPROM.length() - 4);
char ID[7] = "ENCPG2";
char Stored_ID[5];
char Input[10];
//String Type;
void setup()
{
Serial.begin(9600);
Serial.println(start_add_type);
Serial.println(start_add_id);
// start_add = (EEPROM.length() - 10); // use this method to be PCB independent.
for (int i = 0; i < 6; i++)
{
Stored_ID[i] = EEPROM.read(start_add_type + i); // Read the ID into the EEPROM.
}
if (Stored_ID != ID) // Check if the one we have got is the same as the one in this code ID[7]
{
for (int i = 0; i < 6; i++)
{
EEPROM.write(start_add_type + i, ID[i]); // Write the ID into the EEPROM.
}
}
Serial.println(start_add_type);
Serial.println(start_add_id);
}
void loop()
{
}
You are overwriting your memory in this loop:
for (int i = 0; i < 6; i++)
{
Stored_ID[i] = EEPROM.read(start_add_type + i);
}
Stored_ID array is 5 bytes long, so writing to Stored_ID[5] will rewrite also the start_add_id variable, thus the weird value 818, which equals to 0x0332 HEX and 0x32 is the '2' character of your ID
For fixing this issue, declare Stored_ID in this way:
char Stored_ID[6];
if (Stored_ID != ID)
This is nonsense: You compare two different addresses, which are never equal. If you want to compare the content, you should do it in a loop. (e.g. directly when reading the EEPROM value into Stored_ID[i] )
Alternatively, Stored_ID could be a 0-terminated text as well and you might use
if (strcmp(Stored_ID, ID) != 0)

Crashes and strange behaviour when manipulating strings

My chip just stop doing anything. sometimes it prints good results, sometimes its not, i just cant understand whats wrong with this code( and generally any time you using Strings it happens )
void ParseGetRequest(char* data)
{
String parseGET=data;
String from="GET /";
String to="HTTP";
int ind1 = parseGET.indexOf(from);
int ind2 = parseGET.indexOf(to);
parseGET=parseGET.substring(ind1+from.length(), ind2-1);
strcpy(data, parseGET.c_str () );
}
And calling it with :
void readWifDataAsSever(char* reqData)
{
uint8_t buffer[128] = {0};
uint8_t mux_id;
uint32_t len = wifi.recv(&mux_id, buffer, sizeof(buffer), 100);
char serverData[100]={0};
if (len > 0)
{
for(uint32_t i = 0; i < len; i++)
serverData[i]=(char)buffer[i];
ParseGetRequest( serverData ); ///****** the call
Serial.println(serverData); // prints only part of the values
//here the chip just freeze and stop the main loop
NULL termination !!!!
serverData[len ] = '\0';

Resources