Basic sketch sends garbage instead of expected strings quickly after startup

Hello,

I have a very basic circuit handled by a very basic sketch. A series of buttons is connected to a single analog input through several resistors, with a different value for each button. So each button or combination of buttons is supposed to provide a different value on the input. Then a corresponding string is printed on the serial port.

The issue:very quickly after startup, instead of the expected messages, I got a complete garbage on the serial monitor.

What's wrong?

Thank you in advance for helping.

Here's the schematics:

Here's the code:

int myVal[] = {1023, 808, 656, 512, 560, 452, 400, 362};
String myString[] = {"No button", "Button 1", "Button 2", "Button 3", "Buttons 1 and 2", "Button 1 and 3", "Button 2 and 3", "All the buttons"};

void setup() {
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // check if it matches a known situation
  for(int i = 0; i < sizeof(myVal); i++)
  {
    if (sensorValue > myVal[i] - 5 && sensorValue < myVal[i] + 5)
    {
      Serial.println(myString[i]);
      break;
    }
  }
  delay(1);        // delay in between reads for stability
}

very quickly after startup, instead of the expected messages, I got a complete garbage on the serial monitor.

Looks like this is the normal "conversation" at start up, exchanging a "have you got code for me" that the boot loader sends.

Only cure is to remove the boot loader and program it with an ISP.

Maybe I was not precise enough: this garbage arrives only a few seconds after the sketch has functioned normally, so I doubt it comes from the bootloader. Also it goes on like this, with sometimes all the possible messages from the sketch inserted in the unexpected data.

A couple of things come to mind here - the first, unless I am mistaken, delay(1) delays for 1ms, not 1 second as I suspect you want. I would expect to use at least 1 second (1000ms) between readings if I was going to be sending out serial data (especially at 9600 baud). It would also be interesting to add a line that first outputs the ascii representation of the raw reading you got - to see if it looks reasonable or if you are getting noise causing all sorts of garbage readings.

I don't think the sizeof operator is giving you the number of elements in the array, which your code clearly expects.

6v6gt:
I don't think the sizeof operator is giving you the number of elements in the array, which your code clearly expects.

You're right, thank you. I have just read this thread and modified my code accordingly:

int myVal[] = {1023, 808, 656, 512, 560, 452, 400, 362};
String myString[] = {"No button", "Button 1", "Button 2", "Button 3", "Buttons 1 and 2", "Button 1 and 3", "Button 2 and 3", "All the buttons"};
const int mySize = 8; // number of items in the String array

void setup() {
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // check if it matches a known situation
  for(int i = 0; i < mySize; i++)
  {
    if (sensorValue > myVal[i] - 5 && sensorValue < myVal[i] + 5)
    {
      Serial.println(myString[i]);
      break;
    }
  }
  delay(1);        // delay in between reads for stability
}

You could also use:

int myVal[] = {1023, 808, 656, 512, 560, 452, 400, 362};
String myString[] = {"No button", "Button 1", "Button 2", "Button 3", "Buttons 1 and 2", "Button 1 and 3", "Button 2 and 3", "All the buttons"};
const int mySize = sizeof myVal / sizeof myVal[0]; // number of items in the myVal array

Interestingly, I had written a button handling class which used a chain or resistors in series, where the buttons, when depressed, shorted out the individual resistors. The idea was to use only one analog pin for 4 buttons. The parallel method which you are using appears to give a better spread of values.

I've modified my core code so I can test the parallel method. It has a feature that you give it the resistor values and it calculates the analog reading in the range 0 to 1024 and loads the array.

The calculated values I got for 3 buttons differed slightly from the values in your array.

Here's the main part. Note also the trick with sizeof (which johanwasser has just published before I got to it )

int myVal[16] ;  // 4 buttons = 16 combinations
float R0 = 2.0 ;  // series resistor
float R1 = 2.0 ;  // button 1 resistor
float R2 = 3.9 ;  // button 2 resistor
float R3 = 8.2 ;  // button 3 resistor
float R4 = 15.0 ; // button 4 resistor

. . . 
. . . 

  // load array with analog values (0 to 1023) for all button combinations
  for ( byte i = 0 ; i < sizeof( myVal)/sizeof( myVal[0]) ; i++ ) {
    float invR = 0  ;
    if ( i & 0b00001 ) invR += 1 / R4 ;
    if ( i & 0b00010 ) invR += 1 / R3 ;
    if ( i & 0b00100 ) invR += 1 / R2 ;
    if ( i & 0b01000 ) invR += 1 / R1 ;
    
    if ( invR > 0 ) {
      float R = 1/invR ;  
      myVal[i] = 1023.0 * R / ( R0 + R ) ;
    }
    else {
      myVal[i ] = 1023.0 ;
    }
  }

. . .
. . .