Go Down

Topic: Arduino Sketch - Objects in header file not containing any values. (Read 747 times) previous topic - next topic

fulvio

I have the following in Codes.h, which I access by clicking on the tab within the Arduino Software. So I know the sketch is being loaded properly with the header file.

Code: [Select]

    #ifndef __CODES_H__
    #define __CODES_H__
   
    PROGMEM prog_uint16_t show_hide_info[] = { 4216, 8900, 4380, 580, 500, 600, 500, 580, 1620, 580, 500, 600, 500, 580, 500, 600, 480, 600, 500, 580, 1620, 580, 1620, 600, 500, 580, 1620, 580, 1620, 600, 1600, 600, 1620, 580, 1620, 600, 500, 580, 1620, 580, 500, 600, 1600, 600, 500, 580, 1620, 580, 500, 600, 1620, 580, 1620, 600, 480, 600, 1620, 580, 500, 600, 1600, 600, 500, 580, 1620, 580, 500, 600, 39300, 8860, 2160, 580 };
   
    #endif


I then have in my code a method that uses the show_hide_info[] array.

The problem is that when I try to access the array in the header file it doesn't contain any values.

Instead if I declare the above PROGMEM above the setup() method it does contain values.

Not quite sure why I'm getting this problem. I can confirm I've declared my header file properly by doing the following in my sketch.

#include "Codes.h"

This is an example of how I use the array:

Code: [Select]

    void sendCode(prog_uint16_t inArray[], int nLimit) {
      unsigned int arr[nLimit];
      unsigned int c;
      int index = 0;
     
      while ((c = pgm_read_word(inArray++))) {
        arr[index] = c;
        index++;
      }
     
      for (int i = 0; i < nLimit; i=i+2) {
        Serial.println(arr[i]);
        Serial.println(arr[i+1]);
      }
    }


Nothing outputs in the console if I try to use the array in the header file. It only works if I declare it within my actual main sketch program.

I know it's not a problem with the array itself or my method as a simple string or int does not work either. Very strange.

dc42

It's bad practice to declare initialized data in a header file. Declare it in a .cpp file or in your main sketch file. If other .cpp files need to access it, also declare it as an extern variable in a header file (without the initialization) that those .cpp files can #include.

Your code assumes that there is a 0 to signal the end of the array, however you have't included that 0 in the initialization. Also, you will overflow your buffer if there are more than nLimit elements before the zero. So I suspect the problem is that when the array initialization is in the header file, the buffer overflows and crashes the program.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

fulvio


It's bad practice to declare initialized data in a header file. Declare it in a .cpp file or in your main sketch file. If other .cpp files need to access it, also declare it as an extern variable in a header file (without the initialization) that those .cpp files can #include.

Your code assumes that there is a 0 to signal the end of the array, however you have't included that 0 in the initialization. Also, you will overflow your buffer if there are more than nLimit elements before the zero. So I suspect the problem is that when the array initialization is in the header file, the buffer overflows and crashes the program.


Sorry, what you're saying doesn't make sense about my code assuming there's a 0 to signal the end of the array at all. Please clarify?

dc42

Code: [Select]

      while ((c = pgm_read_word(inArray++))) {
        arr[index] = c;
        index++;
      }


The loop will terminate when 'c' is zero, that is, when you have read a zero value from inArray. I assume that inArray will be address of show_hide_info when this function is called. But your initialization doesn't include any zero elements. String literals get a zero terminator added automatically, but initialized arrays don't.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

fulvio


The loop will terminate when 'c' is zero, that is, when you have read a zero value from inArray. I assume that inArray will be address of show_hide_info when this function is called. But your initialization doesn't include any zero elements. String literals get a zero terminator added automatically, but initialized arrays don't.


Oh, I see what you mean. I didn't realise it terminates when 'c' is zero. Would adding a zero to the end of each of my arrays be better?

dc42

You need to decide whether to add a zero terminator at the end of each array, or whether to count the number of elements you read until you have read nLimit of them, or both. If inArray will always have exactly nLimit elements when the function is called, I would change the loop to copy exactly nLimit elements instead of looking for a zero terminator.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Go Up