Problems with loading and reading an array

I feel like I understand arrays and how they work fairly well... used them a lot way back in my VB days. But I'm stumped here.

const int btn1 = 19;
const int btn2 = 18;
const int btn3 = 2;
const int btn4 = 3;
const int btnRst = 4;
const int lt1 = 8; //Setting a bunch of Pin Constants
const int lt2 = 9;
const int lt3 = 10;
const int lt4 = 11;
const int ltOk = 6;
const int ltErr = 5;
const int bzz = 7;

int btn1State = 0;
int btn2State = 0;
int btn3State = 0; // initial setting of button states
int btn4State = 0;
int btnRstState = 0;

int btnRstLastState = 0;
int btn1LastState = 0;
int btn2LastState = 0; // initial setting of last state for if statements
int btn3LastState = 0;
int btn4LastState = 0;

int Level = 4; // initial "level" which will determine array size

void setup() {

pinMode(lt1, OUTPUT);
pinMode(lt2, OUTPUT);
pinMode(lt3, OUTPUT);
pinMode(lt4, OUTPUT);
pinMode(ltOk, OUTPUT);
pinMode(ltErr, OUTPUT);

// Load(); // Load pretty display and sounds - commented out to speed up testing

Serial.begin(9600);

}

void loop() {
btn1State = digitalRead(btn1);
btn2State = digitalRead(btn2);
btn3State = digitalRead(btn3); // Check to see if anyone has pressed a button
btn4State = digitalRead(btn4);
btnRstState = digitalRead(btnRst);

int rdmNum[Level]; // initialize the random number Array and assign it a size based on the "Level" (starts off 4)

if (btnRstState != btnRstLastState){ // I only want the state change and I don't want this to continue to loop while the button is still pressed
if (btnRstState == 1){
for (int i = 0; i < Level; i++){ // Loading the array with a random sequence of numbers 1 to 4
randomSeed(analogRead(0));
rdmNum* = random(1, 4);*

  • }*

  • }*

  • }*

  • btnRstLastState = btnRstState; // Save the state so I can detect the change next time around*

  • if (btn2State != btn2LastState){ // I only want the state change and I don't want this to continue to loop while the button is still pressed*

  • if (btn2State == 1){*

  • for (int i = 0; i < Level; i++){ // Testing to just see what was loaded in the array.*
    _ Serial.println(rdmNum*);_
    _
    }_
    _ Serial.println();
    Serial.println(sizeof(rdmNum)); // more testing about Array_

    _
    }_
    _
    }_
    _
    btn2LastState = btn2State; // Save the state so I can detect the change next time around*_
    * delay(150);*

}
// Pretty lights and sounds for startup
void Load() {
* tone(bzz, 50, 400);*
* digitalWrite(lt1, HIGH);*
* digitalWrite(ltOk, HIGH); *
* delay(500);*
* digitalWrite(lt1, LOW);*
* digitalWrite(ltOk, LOW);*
* tone(bzz, 500, 400); //Good Error tone*
* digitalWrite(lt2, HIGH);*
* digitalWrite(ltErr, HIGH);*
* delay(500);*
* digitalWrite(lt2, LOW);*
* digitalWrite(ltErr, LOW);*
* tone(bzz, 1000, 400);*
* digitalWrite(lt3, HIGH);*
* digitalWrite(ltOk, HIGH);*
* delay(500); *
* digitalWrite(lt3, LOW);*
* digitalWrite(ltOk, LOW);*
* tone(bzz, 2000, 400); //Good Ok tone*
* digitalWrite(lt4, HIGH);*
* digitalWrite(ltErr, HIGH);*
* delay(500);*
* digitalWrite(lt4, LOW);*
* digitalWrite(ltErr, LOW);*
}
[/quote]
Quick and dirty explanation is this will be a Simon type of program/device... just trying to test my programming skills (coming up pretty short) for lack of parts to work on my real project right now.
What is happening is that my array size keeps coming up as "8" even though it should be 4 and then when I hit button 2 it spits out what looks like possibly the right numbers for 0,1,2 of the array but then when it hits the fourth spot (index 3) it spits out something odd like "5633". If I keep hitting button 2 it will kick out the same thing a few times then all of a sudden it starts giving odd random numbers like:
8448
130
30211
5633
I have my buttons debounced with 100nF caps, I also have 10k pull down resistors pulling down the digital input pin side to ground when in the off position. When testing it seemed to read find with a steady stream of correct states (that's why there is a lingering delay(150); in there).
I'll even get random negative numbers out of the array, like -19834!

sizeof() returns the number of bytes used to store an item of the type passed. int is 2 bytes so a 4-element
array of int is 8 bytes.

The code you've posted appears to be both incomplete and incorrect - please post compilation errors for
a non-working program.

Ok, so that makes sense... I'll have to look up/figure out how to parse that sizeof().

That is my full code as it stands right now. No compilation errors. Just functioning ones that I mentioned in my post.

It is incomplete in that I'm just hashing it out now and testing each step as I go... like writing to the array then reading back out of the array to see that the results are as expected.

So far, each step has been a task. LOL

Gilligan:
Ok, so that makes sense... I'll have to look up/figure out how to parse that sizeof().

Simple macro for determining the number of elements in an array:

#define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0])

I am curious - if you are familiar with arrays why aren't you using them in the code rather than all those variables names with number 1, 2, 3, 4 after them?

marco_c:
I am curious - if you are familiar with arrays why aren't you using them in the code rather than all those variables names with number 1, 2, 3, 4 after them?

Never said I was a pro... Just that I understand them.

But in my thought process, I will be using these as random buttons that I will be using to press the sequence/pattern. I'm sure it would be done in an array but in the end I am not sure it would save much past the setup phase.

Fair enough, but I would think that you immediately save time, effort and debugging by doing this:

CheckButton(uint8_t i)
{
  if (btnState[i] != btnLastState[i])
  {
    // I only want the state change and I don't want this to continue to loop while the button is still pressed
    if (btnState[i] == 1)
    {
       for (int i = 0; i < Level; i++)
      {    // Testing to just see what was loaded in the array.
         Serial.println(rdmNum);
       }
       Serial.println();
       Serial.println(sizeof(rdmNum));      // more testing about Array
    }
  }
  btnLastState[i] = btnState[i];      // Save the state so I can detect the change next time around
}

and then not repeat the same lines of code all over the place with different variable names.

You might be on to something there.

Once I sort out this glitching issue I will definitely start looking at cleaning up the code with that array trick. It does make sense for some places... maybe just toss in some if the array variable = a number then that meant the button was pressed so do whatever needed for that.

I could see this shortening up some code a bit with some cleverness.

Thanks!

Now, what the hell is going on with the population of this Array though?? :frowning:

That bit is easy, I thought you already fixed that.

rdmNum = random(1, 4);

should be

rdmNum[i] = random(1, 4);

In the first instance I think you are setting the address of the array to a random number. You need the array subscript.

Same goes for other places (eg, in your println);

marco_c:
That bit is easy, I thought you already fixed that.

rdmNum = random(1, 4);

should be

rdmNum[i] = random(1, 4);

You are only setting the first element of the array when you use the array name. You need the array subscript.

Same goes for other place (eg, in your println);

Tada!

Always something simple that I overlook!

I was following the syntax from the reference but I had to make some adjustments and I missed that one. I know better than that too!

Thanks for spotting that... odd how it still was spitting out weird random and randomly changing values.

Well... we'll see in the morning when I get back to it!

Gilligan:
You might be on to something there.

Once I sort out this glitching issue I will definitely start looking at cleaning up the code with that array trick. It does make sense for some places... maybe just toss in some if the array variable = a number then that meant the button was pressed so do whatever needed for that.

I could see this shortening up some code a bit with some cleverness.

Thanks!

Now, what the hell is going on with the population of this Array though?? :frowning:

You keep re-seeding randoms with an analog read to pin 0 that are a fraction of a millisecond apart. If that's an unterminated input, they don't vary that fast. If you're feeding it high-pitched noise then that might work but you say you always get 8? That would be because the seed is the same, so don't seed so often. Once per button press and be feeding the pin something like busy music through a diode.

Yes, you want to use arrays.

byte btnPin[ 4 ] = { 19, 18, 2, 3 };
byte btnState[ 4 ] = { 0,0,0,0 };

for ( byte i = 0; i < 4; i++ )
{
btnState[ i ] = digital.read( btnPin[ i ] );
}

Also read about enum for enumerate. It lets you assign numbers to names in a list that your code uses, like a list version of #define. The compiler replaces the names your code uses to make easier sense (one hopes) with the numbers. The compiler type-checks enums which I don't think it does with #defines.

enum { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec } month;

if ( month == Dec )
{
print( "HO HO HO!" );
}

C strings are char arrays with any text in the first chars and a char == 0 marks the text end. If the array is bigger then you can add characters until the last array character is zero. It's good to either check the limit or code so it never gets passed.
There's a whole set of C string functions but remember the string is a char array that you can read or write any character of just by indexing to it and operating.

char ch = '0'; // sets ch = 48, which is the ASCII code for 0, or NULL, OFF and LOW.
ch = '7'; // sets ch = 55
int val = ch - '0'; // sets val= 7

ch = 'X';
if (( ch >= 'A' ) && ( ch <='Z')) { print( "upper case alpha" );
Of course there -is- a function to do that but you have to remember they exist and it helps to have a bookmark :smiley:
http://www.nongnu.org/avr-libc/user-manual/group__ctype.html

And step by step you learn pointers and on to classes and maybe even templates, your growing bag of tricks will help you write more and more effective code with less effort all the time. It's worth learning.

@ Gilligan offtop question:

What method did you use to copy&paste the code with the Arduino color scheme?

What method did you use to copy&paste the code with the Arduino color scheme?

The "Copy for forum" option in "Edit" in the IDE, but please don't.

GoForSmoke:
You keep re-seeding randoms with an analog read to pin 0 that are a fraction of a millisecond apart. If that's an unterminated input, they don't vary that fast. If you're feeding it high-pitched noise then that might work but you say you always get 8? That would be because the seed is the same, so don't seed so often. Once per button press and be feeding the pin something like busy music through a diode.

Yes, you want to use arrays.

byte btnPin[ 4 ] = { 19, 18, 2, 3 };
byte btnState[ 4 ] = { 0,0,0,0 };

for ( byte i = 0; i < 4; i++ )
{
btnState[ i ] = digital.read( btnPin[ i ] );
}

Also read about enum for enumerate....

I'm only seeding and filling that array when btnRst is pressed, which is only once during my trials. Pressing it a second time actually repeats the problem. 3 good numbers (between 1 and 4) and then the 4 character number (3925 or whatever), after some time it becomes a bunch of random junk.

I don't get 8 in the array, it says the array size is 8 when I do sizeof(), but that is because it's telling me the byte size vs the index count. That was my fault for not fully reading/understanding sizeof(). If my memory serves me right I think there was a function that could check the index count of an array in VB and that was what I was assuming sizeof() was. My fault.

I'll be at my office in a couple hours to check out this fix and see what happens.

Thanks for the tips, I'll be sure to look into all that info and commit what I can to memory and bookmark the rest. :wink:

AWOL:

What method did you use to copy&paste the code with the Arduino color scheme?

The "Copy for forum" option in "Edit" in the IDE, but please don't.

Correct... was that wrong etiquette?

I honestly don't know why it is still in the IDE.
The problem is that "Code" boxes on the forum which scroll, don't support colour highlighting, and "Quote" boxes don't scroll.

Don't sweat it - you weren't to know.

marco_c:
That bit is easy, I thought you already fixed that.

rdmNum = random(1, 4);

should be

rdmNum[i] = random(1, 4);

In the first instance I think you are setting the address of the array to a random number. You need the array subscript.

Same goes for other places (eg, in your println);

Arghh... I was wondering why the code seemed to half work.

I did correct that bug since I posted the code.

So I'm basically back to square one with the problems and that code was corrected and still gives errors. :frowning:

So I'm basically back to square one with the problems and that code was corrected and still gives errors.

You've made some code changes, right? You've not posted that new code, right?

It would be a good idea to summarize your problems, and show/explain the errors.

PaulS:

So I'm basically back to square one with the problems and that code was corrected and still gives errors.

You've made some code changes, right? You've not posted that new code, right?

It would be a good idea to summarize your problems, and show/explain the errors.

I was about to do that... I know it's a bad idea to just change things and leave you guys in the dark.

const int btn1 = 19;
const int btn2 = 18;
const int btn3 = 2;
const int btn4 = 3;
const int btnRst = 4;
const int lt1 = 8;        //Setting a bunch of Pin Constants
const int lt2 = 9;
const int lt3 = 10;
const int lt4 = 11;
const int ltOk = 6;
const int ltErr = 5;
const int bzz = 7;

int btn1State = 0;
int btn2State = 0;
int btn3State = 0;        // initial setting of button states
int btn4State = 0;
int btnRstState = 0;

int btnRstLastState = 0;
int btn1LastState = 0;
int btn2LastState = 0;    // initial setting of last state for if statements
int btn3LastState = 0;
int btn4LastState = 0;

int Level = 4;            // initial "level" which will determine array size



void setup() {

  pinMode(lt1, OUTPUT);
  pinMode(lt2, OUTPUT);
  pinMode(lt3, OUTPUT);
  pinMode(lt4, OUTPUT);
  pinMode(ltOk, OUTPUT);
  pinMode(ltErr, OUTPUT);
  
 // Load();              // Load pretty display and sounds - commented out to speed up testing
    
    Serial.begin(9600);
    
}

void loop() {
  btn1State = digitalRead(btn1);
  btn2State = digitalRead(btn2);
  btn3State = digitalRead(btn3);    // Check to see if anyone has pressed a button
  btn4State = digitalRead(btn4);
  btnRstState = digitalRead(btnRst);
  
  int rdmNum[Level];   // initialize the random number Array and assign it a size based on the "Level" (starts off 4)

  
  if (btnRstState != btnRstLastState){  // I only want the state change and I don't want this to continue to loop while the button is still pressed
    if (btnRstState == 1){
      for (int i = 0; i < Level; i++){    // Loading the array with a random sequence of numbers 1 to 4
        randomSeed(analogRead(0));
        rdmNum[i] = random(1, 4);
      }
    }
  }
  btnRstLastState = btnRstState;  // Save the state so I can detect the change next time around
  
  if (btn2State != btn2LastState){      // I only want the state change and I don't want this to continue to loop while the button is still pressed
    if (btn2State == 1){
       for (int i = 0; i < Level; i++){    // Testing to just see what was loaded in the array.
         Serial.println(rdmNum[i]);
       }
       Serial.println();
       //Serial.println(sizeof(rdmNum));      // more testing about Array
    }
  }
  btn2LastState = btn2State;      // Save the state so I can detect the change next time around
  delay(150);
  
}

// Pretty lights and sounds for startup
void Load() {
    tone(bzz, 50, 400);
    digitalWrite(lt1, HIGH);
    digitalWrite(ltOk, HIGH);  
    delay(500);
    digitalWrite(lt1, LOW);
    digitalWrite(ltOk, LOW);
    tone(bzz, 500, 400);         //Good Error tone
    digitalWrite(lt2, HIGH);
    digitalWrite(ltErr, HIGH);
    delay(500);
    digitalWrite(lt2, LOW);
    digitalWrite(ltErr, LOW);
    tone(bzz, 1000, 400);
    digitalWrite(lt3, HIGH);
    digitalWrite(ltOk, HIGH);
    delay(500);    
    digitalWrite(lt3, LOW);
    digitalWrite(ltOk, LOW);
    tone(bzz, 2000, 400);       //Good Ok tone
    digitalWrite(lt4, HIGH);
    digitalWrite(ltErr, HIGH);
    delay(500);
    digitalWrite(lt4, LOW);
    digitalWrite(ltErr, LOW);
}

Here are my results from pressing the btnRst once then btn2 3 times in a row:

1
3
2
6913

1
3
2
6913

8448
130
-21757
6913

  int rdmNum[Level];   // initialize the random number Array and assign it a size based on the "Level" (starts off 4)

Creating a new array on every pass through loop hardly seems like a good idea, especially since you don't populate the array every time.

1
3
2
6913

Why are there no titles to define what these values mean? I hate guessing.