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.
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
}
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.
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
}
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 ;
}
}
. . .
. . .