Good afternoon,
for a personal project, I need to write code that turns on one light for a delay D and then turns on the second light for 2 seconds. But for delay D I need that the program uses a value from the serial monitor and keep using it until the user writes another value in the serial monitor.
I also need the program doesn't start until there is a value from the serial monitor (so I use the condition if (D>0))
int led1=3; //led red
int led2=4; //led yellow
int D; //delay
void setup() {
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
Serial.begin(9600);
D=0;
}
void loop() {
D = Serial.parseFloat();
D=D*1000;
if (D>0){
digitalWrite(led1,HIGH);
digitalWrite(led2,LOW);
delay (D);
digitalWrite(led1,LOW);
digitalWrite(led2,HIGH);
delay(2000);
}
}
Perform this simple test and then carry out other advanced tests.
Enter 5 in the InputBox of the Serial Monitor (Fig-1) with "No line ending" option in the "Line ending box" and then click on the Send button. Check that the L (built-in LED of UNO) has remained ON for 5-sec.
Before you create the sketch, you have to accept/understand the following facts: 1. The digit 5 travels towards UNO as 00110101 (0x35 = character/ASCII code of 5) and automatically enters into the Buffer of UNO.
2. Before you read the arrived code (0x35) from the Buffer, you must check that the Buffer really contains at least one data item. After that, read the code, convert it to 5 and then turn ON L. This is done by executing the following codes:
byte n = Serial.available();
if(n != 0) //n = 0 means no data is avaiable
{
char y1 = Serial.read(); //y1 = 0x35
byte y2 = y1 - 0x30; //convert 0x35 into 5
digitalWrite(L, HIGH); //L is ON
delay(y2*1000); //5000 ms time delay
digitalWrite(L, LOW); //L is OFF
}
int led1=3; //led red
int led2=4; //led yellow
int D; //delay
void setup() {
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
Serial.begin(9600);
D=0;
}
void loop() {
D = Serial.parseFloat();
D=D*1000;
while(Serial.available()){
digitalWrite(led1,HIGH);
digitalWrite(led2,LOW);
delay (D);
Serial.write(D);
digitalWrite(led1,LOW);
digitalWrite(led2,HIGH);
delay(2000);
}
}
I tried this code but after a cycle, it forgot the previous value.
I tried a few codes more with conditions on serial.available, but I don't have them because I deleted them. I use the condition if (D>0) to impose that the code starts only after a user input
I also already check for the tutorial by Robin2, but I just don't understand how to code according to my requests in the first post
Thing is, there are multiple things you need to straighten out. One, you are inputting a float but 'D' is an integer. Two, you multiply it by 1000. An int type can't hold a value greater than 32,767. Three... there are more problems. But they can't be fixed all at once.
What values do you see printed from this:
Serial.write(D);
Oh, there's another mistake. the 'write' method only prints single ASCII characters. Not readable string values.
I guess we need to fix almost every line of your code.
You're right. In the first draft, I use float D
now I wrote the code by memory and I wrote int D.
But with float D and D = Serial.parseFloat();
doesn't works
I multiply by 1000 to transform seconds (input from the user) in ms for the delay
Why use floats at all? Edit - okay if you want to specify time in seconds. But millis() time variables should be 'unsigned long' or 'uint32_t' not 'int'.
At serial rate 115200 it takes almost 89 micros for each new character to arrive and still compared to Arduino that is slow enough to catch, do something with or about, do a few other things and be ready for the next character ... with un-blocked (delay and like) code. Serial Monitor sends chars at baudrate speed and they arrive just that s-l-o-w. So while void loop() circles around you catch and process serial chars with no delays.
You can evaluate values on the fly or buffer chars and use string to float function. Remember to re-initialize if you want more than one entry.
I misremembered the exact number which I calculate to use, 1sec / 11520 with 10 bit frames. and x 1 million, 86.80555... microsecs.
I posted examples in 2019 of a dictionary utility that keeps up with 25000 baud.
It uses a stored pre-calculated value that drives at least one C++ purist nuts, I called them magic numbers and commented exactly what they are and the alternative takes way longer to find out what's known could take too long to run fast. Purist "cleaned up" my code but left out the part he didn't like... the test text passed but so did false words and I have yet to see the smaller faster C++ that does what my crappy C does.
In the speed test example reading data from flash instead of serial, it averaged 144 cycles per character matched with a worst case dataset of all-matches. I one example I showed trace prints at speed, there is room to act as well as match. The utility gives status to allow matching word-number and word-word combinations. I had written 4 of the same basic tool over 18 years before 2000, I know what I wanted. But this time, no deadlines to zoom by, no pressure, best cut so far.
I'm going to have to dig for a copy, my running backups stick got over-written and I haven't found a way to list my uploads.
Thanks for all the answers. I studied over the weekend and I tried this code and it works! (Or at least it appears to...)
int led1=3; //led red
int led2=4; //led yellow
int D; //delay
int i; //counter
void setup() {
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
Serial.begin(9600);
D=-1;
i=0;
}
void loop() {
if (Serial.available()>0){
i=i+1;
if(D!=0){ //without this condition there were some problems
D = Serial.parseInt();
D=D*1000; // trasform s into ms
}
delay(100);
}
//if at least one value is read from the serial monitor i>0
if (i>0){
digitalWrite(led1,HIGH);
digitalWrite(led2,LOW);
delay (D);
digitalWrite(led1,LOW);
digitalWrite(led2,HIGH);
delay(2000);
}
}