Hey,
I am trying to create a program which lets me enter an integer value ranging from 1 to 7. These integers represent days Monday to Sunday. Depending on which integer I enter a corresponding LED is suppossed to light up for 3 seconds. Can anybody please help me to figure out what has gone in the following code:
#define MONDAY 4
#define TUESDAY 5
#define WEDNESDAY 6
#define THURSDAY 7
#define FRIDAY 8
#define SATURDAY 9
#define SUNDAY 10
#define PAUSE 3000
int readDay = 0;
int mon = MONDAY;
int tue = TUESDAY;
int wed = WEDNESDAY;
int thu = THURSDAY;
int fri = FRIDAY;
int sat = SATURDAY;
int sun = SUNDAY;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Enter a number 1 to 7!");
pinMode(mon, OUTPUT);
pinMode(tue, OUTPUT);
pinMode(wed, OUTPUT);
pinMode(thu, OUTPUT);
pinMode(fri, OUTPUT);
pinMode(sat, OUTPUT);
pinMode(sun, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available() > 0){
readDay = Serial.read();
switch(readDay) {
case 1: digitalWrite(mon, HIGH);
delay(PAUSE);
Serial.println("Enter a number 1 to 7!");
break;
case 2: digitalWrite(tue, HIGH);
delay(PAUSE);
Serial.println("Enter a number 1 to 7!");
break;
case 3: digitalWrite(wed, HIGH);
delay(PAUSE);
Serial.println("Enter a number 1 to 7!");
break;
case 4: digitalWrite(thu, HIGH);
delay(PAUSE);
Serial.println("Enter a number 1 to 7!");
break;
case 5: digitalWrite(fri, HIGH);
delay(PAUSE);
Serial.println("Enter a number 1 to 7!");
break;
case 6: digitalWrite(sat, HIGH);
delay(PAUSE);
Serial.println("Enter a number 1 to 7!");
break;
case 7: digitalWrite(sun, HIGH);
delay(PAUSE);
Serial.println("Enter a number 1 to 7!");
break;
default: Serial.println("Something has gone wrong here!");
}
}
}[/code
well, when I run it, first of all I get the message "Enter a number 1 to 7!" twice where I expect it to appeaer only once. Furthermore I can enter whatever value I want and nothing happens. And also Before the second message there is some "So?" which I supposse results from an incorrect baude rate? But I have selected a baude rate of 115200 bps.
Thx so much! I have now put the integer values in single quotation marks: case '1' etc.
And it works! However, I have two questions: Why do I have to treat the integers as characters? And well, my first output is still:
Enter a number 1 to 7!
So⸮Enter a number 1 to 7!
What does this tell me? Where does the 'So?' come from and why are there two output messages although I haven't entered anything so far?!
When you get your version of the program working investigate arrays. Using an array of pin numbers you could remove most of the program including all of the switch/case
ok. Well, it didn't change. What's weird is, that when I for example type in '1', the first LED lights up for 3 seconds, but then I get the message "Something has gone wrong here!" twice. ..
When I add the two lines
// Serial.print("I received: ");
// Serial.println(readDay);
after the switch block, I realize, that apparently when i type in '1', I am sending 49 (ASCII value of '1') and then in a second step I send 13 and in a last step I am sending 10. And this is true for every other value as well (except the first value changes of course from 50 to 55). Any idea why this is happenning?
You can convert the byte read to an integer like this:
readDay = readDay - '0';
if you like. It's difficult to debug when the same prompt is printed in 7 places. The code takes it on faith that the entered value will be between 1 and 7 but if the serial monitor is set for anything other than "No line ending" (on the bottom right) you will get spurious characters.
You can ignore anything but 1-7 by checking the character read before the switch statement. The prompt for a new number can be moved outside the switch and more specific messages can be printed inside.
void loop() {
if (Serial.available() > 0) {
readDay = Serial.read();
if ( (readDay >= '0') && (readDay <= '7') )
{
readDay = readDay - '0';
Serial.print("number read: "); Serial.println(readDay);
switch (readDay) {
case 1: digitalWrite(mon, HIGH);
delay(PAUSE);
Serial.println("mon");
break;
case 2: digitalWrite(tue, HIGH);
delay(PAUSE);
Serial.println("tue");
break;
case 3: digitalWrite(wed, HIGH);
delay(PAUSE);
Serial.println("wed");
break;
case 4: digitalWrite(thu, HIGH);
delay(PAUSE);
Serial.println("thur");
break;
case 5: digitalWrite(fri, HIGH);
delay(PAUSE);
Serial.println("fri");
break;
case 6: digitalWrite(sat, HIGH);
delay(PAUSE);
Serial.println("sat");
break;
case 7: digitalWrite(sun, HIGH);
Serial.println("sun");
delay(PAUSE);
break;
default: Serial.println("Something has gone wrong here!");
}
Serial.println("Enter a number 1 to 7!");
}
}
}
after the switch block, I realize, that apparently when i type in '1', I am sending 49 (ASCII value of '1') and then in a second step I send 13 and in a last step I am sending 10. And this is true for every other value as well (except the first value changes of course from 50 to 55). Any idea why this is happenning?
You are seeing the ascii control characters for line feed and carriage return.
There is a little pull down menu at the bottom right of the monitor window where can set the serial monitor to change what line ending is being sent when you hit the enter command.
Hey,
that's very neat, thx so much!
I have actually changed my code a tiny little bit. Everything works the way I wanted to now, but the question from my previous post remains: When I uncomment the last three comments and enter a '1' , then I receive a 49 and in the next step 13 and next 10. This doesn't change if I include another delay. I don't know why.
#define MONDAY 4
#define TUESDAY 5
#define WEDNESDAY 6
#define THURSDAY 7
#define FRIDAY 8
#define SATURDAY 9
#define SUNDAY 10
#define PAUSE 1000
int readDay;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(MONDAY, OUTPUT);
pinMode(TUESDAY, OUTPUT);
pinMode(WEDNESDAY, OUTPUT);
pinMode(THURSDAY, OUTPUT);
pinMode(FRIDAY, OUTPUT);
pinMode(SATURDAY, OUTPUT);
pinMode(SUNDAY, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available() > 0){
readDay = Serial.read();
switch(readDay) {
case '1': digitalWrite(MONDAY, HIGH);
delay(PAUSE);
digitalWrite(MONDAY, LOW);
break;
case '2': digitalWrite(TUESDAY, HIGH);
delay(PAUSE);
digitalWrite(TUESDAY, LOW);
break;
case '3': digitalWrite(WEDNESDAY, HIGH);
delay(PAUSE);
digitalWrite(WEDNESDAY, LOW);
break;
case '4': digitalWrite(THURSDAY, HIGH);
delay(PAUSE);
digitalWrite(THURSDAY, LOW);
break;
case '5': digitalWrite(FRIDAY, HIGH);
delay(PAUSE);
digitalWrite(FRIDAY, LOW);
break;
case '6': digitalWrite(SATURDAY, HIGH);
delay(PAUSE);
digitalWrite(SATURDAY, LOW);
break;
case '7': digitalWrite(SUNDAY, HIGH);
delay(PAUSE);
digitalWrite(SUNDAY, LOW);
break;
}
//delay(PAUSE);
//Serial.print("I received: ");
//Serial.println(readDay);
}
}
You are showing the char value, try:
Serial.println(readDay -'0');
allright, figured out the problem: When changing the option of the Serial Monitor to "no end of line" it works fine.