I still don't understand how to implement the knowledge from
BlinkWithoutDelay to a non-blinking simple replacement of
"delay(1000)" for an LED to stay on longer upon serial communication.
In this sketch, after putting in an "L" into the serial monitor
the LED comes on and doesn't turn off after a second.
Just stays on.
What can I do to replace the simple "delay(1000)"?
/*
Led staying on without delay
Alexandra Klein
*/
const int ledPin = 13; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into
void setup() {
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}
void loop()
{unsigned long TimerledPin;
// see if there's incoming serial data:
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
incomingByte = Serial.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H')
{
{TimerledPin=millis(),
digitalWrite(ledPin, HIGH);
if (millis()-TimerledPin>= 1000UL)
digitalWrite(ledPin,LOW);
}}
}
}
This part of the code needs { } and moved out of the the "if" that it is inside of.
if (millis()-TimerledPin>= 1000UL)
digitalWrite(ledPin,LOW);
I would recommend moving your time variables out of the loop and using better names like what I am giving you.
const int ledPin = 13; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into
unsigned long Oldtime = 0; // used to note the time the led was turned on
unsigned long Newtime = 0; //used to update to present time when = millis()
void setup() {
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}
void loop()
Thank you cyclegadget.
I think I know what you mean, and put the changes in the code,
but now, the LED doesn't come on at all when I press 'L'
into the serial monitor.
/*
Led staying on without delay
Alexandra Klein
*/
const int ledPin = 13; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into
unsigned long Oldtime = 0; // used to note the time the led was turned on
unsigned long Newtime = 0; //used to update to present time when = millis()
void setup() {
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}
void loop()
{unsigned long TimerledPin;
{if (millis()-TimerledPin>= 1000UL)
digitalWrite(ledPin,LOW);}
// see if there's incoming serial data:
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
incomingByte = Serial.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H')
{
{TimerledPin=millis(),
digitalWrite(ledPin, HIGH);
}}
}
}
This is only my tryout code for the bigger project.
The serial really is an XBee communication trigger
between two Arduino LilyPads that are part of a
interactive jewellery project.
The code is:
/*
By Alexandra da Fonseca-Klein, Digital Jewellery project,
For interactive Jewellery 'proximity sensing hearts'
www.ADFK.co.uk; 2012
2 Arduino Lilypad Simple Boards are connected via Xbee Series 2 radios.
The Simple Board lacks Rx/Tx, therefore the use of SoftwareSerial.
If the 2 wearers are within reach (30 feet approx) one LED
comes on on the other wearers piece, if a button is pressed, another LED
lights up. This is the receiver side.
*/
#include <SoftwareSerial.h> // use these specified set of commands
const int RXPin = 10; // setting the pin to RX
const int TXPin = 11; // setting the pin to TX
const int ButtonLed = 5; // the number of the PushLed pin
const int ledPin = 13; // the number of the LED pin
SoftwareSerial xbee (RXPin, TXPin);// defining the new serial name
void setup() // definitions that are always true
{
pinMode(ledPin, OUTPUT);
pinMode(ButtonLed, OUTPUT);
xbee.begin(9600);// set the data rate for the SoftwareSerial port
}
void loop() // run over and over
{
if
(xbee.available()) // check if there is actually data coming from
{ // communication port
digitalWrite(ledPin, HIGH);// set the LED on
delay(500); // wait for half a second
}
else //if not
{
digitalWrite(ledPin, LOW);// turn the LED off
}
if
(xbee.read() == 'L') // if you read the letter 'L'
{
digitalWrite(ButtonLed, HIGH);// set the ButtonLED on
digitalWrite(ledPin, HIGH);// set the LED on
delay(1000); // wait for a second
}
else
{
digitalWrite(ButtonLed, LOW);// turn the ButtonLED off
}
}
const int ledPin = 13; // the pin that the LED is attached to
unsigned long TimerledPin;
void setup()
{
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}
void loop()
{
if (millis()-TimerledPin>= 1000UL)
{
digitalWrite(ledPin,LOW);
}
// see if there's incoming serial data:
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
int incomingByte = Serial.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H')
{
TimerledPin=millis(),
digitalWrite(ledPin, HIGH);
}
}
}
I implemented the avoid delay routine into my
project which essentially has 2 LEDs to run a few seconds.
One, if there is the letter "H" read from Serial (constantly)
and one, if there is a button pressed from the other board,
sending the letter 'L' out.
Now there are no problems with lighting the first LED without flicker,
but the second, ButtonLed only comes on once for about 5 seconds
after pressing the button, after that it only gives barely visible short
bursts of light when it is triggered.
Why is that?
/*
By Alexandra da Fonseca-Klein, Digital Jewellery project,
For interactive Jewellery 'proximity sensing hearts'
www.ADFK.co.uk; 2012
2 Arduino Lilypad Simple Boards are connected via Xbee Series 2 radios.
The Simple Board lacks Rx/Tx, therefore the use of SoftwareSerial.
If the 2 wearers are within reach (30 feet approx) one LED
comes on on the other wearers piece, if a button is pressed, another LED
lights up. This is the receiver side.
*/
#include <SoftwareSerial.h> // use these specified set of commands
const int RXPin = A4; // setting the pin to RX
const int TXPin = A5; // setting the pin to TX
const int ButtonLed = 5; // the number of the PushLed pin
const int ledPin = 13; // the number of the LED pin
SoftwareSerial xbee (RXPin, TXPin);// defining the new serial name
int incomingByte; // a variable to read incoming serial data into
unsigned long TimerledPin;
unsigned long TimerButtonLed;
void setup() // definitions that are always true
{
xbee.begin(9600);// set the data rate for the SoftwareSerial port
pinMode(ledPin, OUTPUT);
pinMode(ButtonLed, OUTPUT);
}
void loop() // run over and over
{
if (millis()-TimerledPin>= 4000UL)
{
digitalWrite(ledPin,LOW);
}
// see if there's incoming serial data:
if (xbee.available() > 0) {
// read the oldest byte in the serial buffer:
int incomingByte = xbee.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H')
{
TimerledPin=millis(),
digitalWrite(ledPin, HIGH);
}
}
if (millis()-ButtonLed>= 4000UL)
{
digitalWrite(ButtonLed, LOW);
}
// see if there's incoming serial data:
if (xbee.available() > 0) {
// read the oldest byte in the serial buffer:
int incomingByte = xbee.read();
// if it's a capital L, turn on the LED:
if (incomingByte == 'L')
{
TimerButtonLed=millis(),
digitalWrite(ButtonLed, HIGH);
}
}
}
A few things. You are reading the x-bee two times per loop when you only need to that once per loop. I removed one of the x-bee reads.
Second, your sketch was out of order in the way that you want it to work. Your order would probably still work but it makes it hard to find the problems. Try to write the sketch in steps in a way that you want things to happen. It should be: read serial...turn on correct LED....note the time...check the time and turn off LED after "X" millis.
Lastly, I think you had some of your comments placed in less than ideal locations. Also, use Auto format after every change in the sketch. Auto format makes it a bit easier to read. I also recommend a extra line between stages in the code. It makes it easier to follow the flow.
/*
By Alexandra da Fonseca-Klein, Digital Jewellery project,
For interactive Jewellery 'proximity sensing hearts'
www.ADFK.co.uk; 2012
2 Arduino Lilypad Simple Boards are connected via Xbee Series 2 radios.
The Simple Board lacks Rx/Tx, therefore the use of SoftwareSerial.
If the 2 wearers are within reach (30 feet approx) one LED
comes on on the other wearers piece, if a button is pressed, another LED
lights up. This is the receiver side.
*/
#include <SoftwareSerial.h> // use these specified set of commands
const int RXPin = A4; // setting the pin to RX
const int TXPin = A5; // setting the pin to TX
const int ButtonLed = 5; // the number of the PushLed pin
const int ledPin = 13; // the number of the LED pin
SoftwareSerial xbee (RXPin, TXPin);// defining the new serial name
int incomingByte; // a variable to read incoming serial data into
unsigned long TimerledPin;
unsigned long TimerButtonLed;
void setup() // definitions that are always true
{
xbee.begin(9600);// set the data rate for the SoftwareSerial port
pinMode(ledPin, OUTPUT);
pinMode(ButtonLed, OUTPUT);
}
void loop() // run over and over
{
// see if there's incoming serial data:
if (xbee.available() > 0) {
// read the oldest byte in the serial buffer:
int incomingByte = xbee.read();
}
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H')
{
TimerledPin=millis(),
digitalWrite(ledPin, HIGH);
}
if (millis()-TimerledPin>= 4000UL)
{
digitalWrite(ledPin,LOW);
}
// if it's a capital L, turn on the LED:
if (incomingByte == 'L')
{
TimerButtonLed=millis(),
digitalWrite(ButtonLed, HIGH);
}
if (millis()-ButtonLed>= 4000UL)
{
digitalWrite(ButtonLed, LOW);
}
}
Thanks for the valuable tips.
I'll go at it right now.
And sorry for 'crossposting'.
I'm a bit on a tight schedule for the
college deadline...
Now that I had the more complex project
I thought it is better to repost it.
So I tried out the simplified version. This one doesn't work, though.
The LED13 doesn't come on, nor does the ButtonLed.
In the meantime I took my code that worked for
the LED13 and for one time only for the ButtonLed
and reverted back to using 'delay' for the ButtonLed and
leaving the better mills calculation on the top for the
LED13. Now at least it works good enough. There is
the odd time that the button has to be pressed again
because the program is busy, I think.
And of course that would mean we would give in a little,
because we would leave 'delay' in the backdoor again.
I would really like to do away with delay altogether.
Maybe you can spot, what is still wrong in the cleaned up
sketch that was posted by cyclegadget earlier. It looks good to me.
My 'botched' sketch, that works sort of, but with partly with 'delay' is here.
/*
By Alexandra da Fonseca-Klein, Digital Jewellery project,
For interactive Jewellery 'proximity sensing hearts'
www.ADFK.co.uk; 2012
2 Arduino Lilypad Simple Boards are connected via Xbee Series 2 radios.
The Simple Board lacks Rx/Tx, therefore the use of SoftwareSerial.
If the 2 wearers are within reach (30 feet approx) one LED
comes on on the other wearers piece, if a button is pressed, another LED
lights up. This is the receiver side.
*/
#include <SoftwareSerial.h> // use these specified set of commands
const int RXPin = A4 ; // setting the pin to RX
const int TXPin = A5; // setting the pin to TX
const int ButtonLed = 5; // the number of the PushLed pin
const int ledPin = 13; // the number of the LED pin
SoftwareSerial xbee (RXPin, TXPin);// defining the new serial name
int incomingByte; // a variable to read incoming serial data into
unsigned long TimerledPin;
unsigned long TimerButtonLed;
void setup() // definitions that are always true
{
xbee.begin(9600);// set the data rate for the SoftwareSerial port
pinMode(ledPin, OUTPUT);
pinMode(ButtonLed, OUTPUT);
}
void loop() // run over and over
{
if (millis()-TimerledPin>= 4000UL)
{
digitalWrite(ledPin,LOW);
}
// see if there's incoming serial data:
if (xbee.available() > 0) {
// read the oldest byte in the serial buffer:
int incomingByte = xbee.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H')
{
TimerledPin=millis(),
digitalWrite(ledPin, HIGH);
}
}
if
(xbee.read() == 'L') // if you read the letter 'L'
{
digitalWrite(ButtonLed, HIGH);// set the ButtonLED on
digitalWrite(ledPin, HIGH);// set the LED on
delay(1000); // wait for a second
}
else
{
digitalWrite(ButtonLed, LOW);// turn the ButtonLED off
}
}
I'm sorry, I don't understand.
I check if XBee is available and it does read an 'L',
when I press the button,
otherwise the thing wouldn't be working.
What I don't understand is why the
new proposal from cyclegadget
doesn't work at all and my previous one
with both avoiding using delay only
works partly.
What are you suggesting?
So that I could test the sketch I made it a little different and commented out the Xbee setup and used Serial.print and read.
Here is that code. It is not clean but, I didn't want to make a lot of changes and miss the original problem.
/*
By Alexandra da Fonseca-Klein, Digital Jewellery project,
For interactive Jewellery 'proximity sensing hearts'
www.ADFK.co.uk; 2012
2 Arduino Lilypad Simple Boards are connected via Xbee Series 2 radios.
The Simple Board lacks Rx/Tx, therefore the use of SoftwareSerial.
If the 2 wearers are within reach (30 feet approx) one LED
comes on on the other wearers piece, if a button is pressed, another LED
lights up. This is the receiver side.
*/
#include <SoftwareSerial.h> // use these specified set of commands
const int RXPin = A4; // setting the pin to RX
const int TXPin = A5; // setting the pin to TX
const int ButtonLed = 5; // the number of the PushLed pin
const int ledPin = 13; // the number of the LED pin
int ledState = LOW;
int ledState2 = LOW;
SoftwareSerial xbee (RXPin, TXPin);// defining the new serial name
char incomingByte; // a variable to read incoming serial data into
unsigned long TimerledPin;
unsigned long TimerButtonLed;
void setup() // definitions that are always true
{
Serial.begin(9600);
// xbee.begin(9600);// set the data rate for the SoftwareSerial port
pinMode(ledPin, OUTPUT);
pinMode(ButtonLed, OUTPUT);
}
void loop() // run over and over
{
unsigned long newtime = millis();
// see if there's incoming serial data:
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
incomingByte = (char)Serial.read();
Serial.println(incomingByte);
}
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H')
{
TimerledPin = millis(),
digitalWrite(ledPin, HIGH);
ledState = HIGH;
Serial.println("I got an H");
}
if (newtime - TimerledPin >= 4000UL && ledState == HIGH)
{
digitalWrite(ledPin,LOW);
ledState = LOW;
Serial.println("time is up for TimerledPin");
}
// if it's a capital L, turn on the LED:
if (incomingByte == 'L')
{
TimerButtonLed = newtime;
digitalWrite(ButtonLed, HIGH);
ledState2 = HIGH;
Serial.println("I got a L");
}
if (newtime - ButtonLed >= 4000UL && ledState2 == HIGH)
{
digitalWrite(ButtonLed, LOW);
ledState2 = LOW;
Serial.println("time is up for ButtonLed");
}
}