1

I keep having trouble with getting this code to work properly. My goal is to show strings which are placed in PROGMEM on a LCD. The array with pointers to these strings is also in PROGMEM. The function is called with a variable which in turn is translated to an index number for reading out the array. Ofcourse pgmspace.h is included in the code.

The errors I keep getting are: array subscript has type 'char' [-Wchar-subscripts] - initialization makes pointer from integer without a cast [enabled by default]

Could someone point out what i'm missing here?

Working on code for AVR GCC, my IDE is Eclipse.

    const char wf0[] PROGMEM= "OFF ";
    const char wf1[] PROGMEM= "SIN ";
    const char wf2[] PROGMEM= "TRI ";
    const char wf3[] PROGMEM= "S+T ";
    const char wf4[] PROGMEM= "PUL ";
    const char wf5[] PROGMEM= "P+S ";
    const char wf6[] PROGMEM= "P+T ";
    const char wf7[] PROGMEM= "P+ST";
    const char wf8[] PROGMEM= "NOI ";
    const char wf9[] PROGMEM= "N+S ";
    const char wf10[] PROGMEM= "N+T ";
    const char wf11[] PROGMEM= "NST ";
    const char wf12[] PROGMEM= "N+P ";
    const char wf13[] PROGMEM= "NPS ";
    const char wf14[] PROGMEM= "NPT ";
    const char wf15[] PROGMEM= "NPTS";

    const char * const arrayWaveform[] PROGMEM= {wf0,wf1,wf2,wf3,wf4,wf5,wf6,wf7,wf8,wf9,wf10,wf11,wf12,wf13,wf14,wf15};

...

void showWaveform (char ctrlValue)
{
    char hex = (ctrlValue & 0xf0)>>4;

    char tempText[4];
    char* data = pgm_read_byte(&arrayWaveform[hex]); // <<shows up both errors here
    strcpy_P (tempText, data);
    for (char x=0;x<4;x++)
        {
        char2LCD(tempText[x]);  // <<shows up error: array subscript has type 'char'
        }
}
0

3 Answers 3

3

This should do:

void showWaveform (char ctrlValue)
{
  char hex = (ctrlValue & 0xf0)>>4;
  char *pstr, tempText[5];
  memcpy_P(&pstr, arrayWaveform+hex, sizeof(char*));
  strncpy_P(tempText, pstr, sizeof(tempText));
  for (int x=0; x<4 && tempText[x] != 0; x++)
  {
    char2LCD(tempText[x]); 
  }
}

There were multiple issues with your code. First and foremost arrayWaveform itself is stored in PROGMEM, so you can't simply access it using square brackets. Second, tempText must be at least 5 elements long (otherwise strcpy_P can write past the end of the array).

You may want to carefully read the docs about PROGMEM, to fully understand what's going on. Please note that if you have a recent copy of AVR-GCC there is also the new __flash syntax that allows to get rid of all the pgm_read_* and *_P machinery. I have never tested it, so YMMV.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm checking out your code. Thank you for pointing out stuff. Some minor changes made (temptext and tempText, initializing *pstr =0). It compiles ok, but still gives weird results. That might not have to do with your code, but perhaps somewhere else in my code some other likewise problem is still at hand. That bit also places some data in progmem but doesnt compile correctly aswell. Probably the same error. I'll look into this tomorrow. Thanks for now!
My bad: I forgot the & before pstr in the call to memcpy_P. This is because memcpy_P will load a pointer to PROGMEM, so I have to pass the address of where I want the pointer to be loaded, i.e. a pointer to a char*.
1

In tempText[x] and arrayWaveform[hex] the index is of type signed char which can take up negavtive values too

Change it to unsigned char

See GCC Warnings :

Wchar-subscripts Warn if an array subscript has type char. This is a common cause of error, as programmers often forget that this type is signed on some machines. This warning is enabled by -Wall.

1 Comment

Thanks, your correct, didn't think of that. Normaly I use uint8_t, totally forgot this time.
0

Exactly as your compiler says, you're using chars for array access. Normally array subscripts must be ints.

On both lines, you should cast your variables to ints, or just declare them as ints to begin with.

As for the other error, my guess is that pgm_read_byte returns a raw char which you try to assign to a char*, which is impossible. You should probably return a pointer from pgm_read_byte

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.