Pages: [1] 2   Go Down
Author Topic: [SOLVED]Serial input affecting a delay  (Read 1898 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys. Im a bit perplexed! Im trying to set the rate of blinking of an LED (in an optocoupler) by reading what comes through the serial port. Here is my code;
Code:
#define OPTO 13 // optocoupler pin
int val =0; // variable to store the serial
int pause =0; // variable for our blinks

void setup(){
  
 Serial.begin(300);
 pinMode (OPTO, OUTPUT);
 
}

void loop (){
 while (Serial.available() ==0 ); // Arduino waits to recieve data
  
 int val = Serial.read()-('0'); // only reads the first byte of data
 
 int pause = map (val,0,9, 15, 100); // hence maximum of 9

  pause = constrain (pause , 15, 100);
 
  
 digitalWrite(OPTO, HIGH);
 delay(pause);
 digitalWrite (OPTO, LOW);
 delay(pause);
  
   Serial.println (pause);

  
 }

The problem is that it only blinks the LED at the specified rate once, and then the serial goes back to 0.
Any help would be smashing thanks!
« Last Edit: April 03, 2011, 05:22:39 am by gravebond » Logged

Left Coast, USA
Offline Offline
Sr. Member
****
Karma: 7
Posts: 499
Sometimes I just can't help myself.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... perplexed!..
Step away from Arduino for a minute and think about what you need to do.  Sometimes I actually write it out (on the back of a cocktail napkin at the NAME OF WATERING HOLE DELETED).

Often I write it in pseudo-code rather than my native language (American-English, as it happens.)  The point is that I try to express it in logical terms before I actually write code.

 (Instead of scanning the booze-stained napkin from this particular session at the lounge, I'll post my take on it as text):

The loop() function is executed repeatedly:

BEGIN loop function

    IF there is a character available THEN
        Read the character and calculate the "pause" value
    END IF

    Turn on LED
    pause
    Turn off LED
    pause

END loop function


Now if that makes sense, compare with your code.  If it doesn't make sense, ask again.


Regards,

Dave

« Last Edit: April 02, 2011, 04:05:28 pm by davekw7x » Logged

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sound sound advice indeed. Still though i am having trouble. Here's what i tried;
Code:
#define OPTO 13 // optocoupler pin
int val =0; // variable to store the serial
int pause =0; // variable for our blinks

void setup(){
 
 Serial.begin(300);
 pinMode (OPTO, OUTPUT);
 
}

void loop (){


 
  if (Serial.available() > 0) {
   
 int val = Serial.read()-('0'); // only reads the first byte of data
 
 int pause = map (val,0,9, 15, 100); // hence maximum of 9

  pause = constrain (pause , 15, 100);
  }
 
 
 
 digitalWrite(OPTO, HIGH);
 delay(pause);
 digitalWrite (OPTO, LOW);
 delay(pause);
 
   Serial.println (pause);

   
 }

its still doing the same thing. Halp...
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26281
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It isn't doing the same thing.
You have two "pause" - get rid of the local one.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What do you mean by local one?
If i get rid of my "pause" int i cant map new values onto the single serial character i am getting.
Logged

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i see now its just printing 0 constantly regardless of my typing into the serial moniter
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26281
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
pause = map (val,0,9, 15, 100); // hence maximum of 9


You had (always had)two variables called "pause".
Check scope rules.
http://www.arduino.cc/en/Reference/Scope
« Last Edit: April 02, 2011, 04:30:38 pm by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ive now uploaded this and at least the serial moniter is making more sense now. However the Led is still not behaving.
Code:
#define OPTO 13 // optocoupler pin
int val =0; // variable to store the serial
int pause =0; // variable for our blinks

void setup(){
 
 Serial.begin(9600);
 pinMode (OPTO, OUTPUT);
 
}

void loop (){

 while (Serial.available() ==0 );
 
  if (Serial.available() >0 ) {
   
 int val = Serial.read()-('0'); // only reads the first byte of data
 
 pause = map (val,0,9, 15, 100); // hence maximum of 9

  pause = constrain (pause , 15, 100);
 
  Serial.flush();
  }
 
 
 
 digitalWrite(OPTO, HIGH);
 delay(pause);
 digitalWrite (OPTO, LOW);
 delay(pause);
 
   Serial.println (pause);

   
 }

The led just flashes once, do need to make a seperate void and call it with an if?
Logged

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Right ive got it working by adding a do.. while statement.
Code:
#define OPTO 13 // optocoupler pin
int val =0; // variable to store the serial
int pause =0; // variable for our blinks

void setup(){
  
 Serial.begin(9600);
 pinMode (OPTO, OUTPUT);
 
}

void loop (){

 while (Serial.available() ==0 );
 
  if (Serial.available() >0 ) {
    
 int val = Serial.read()-('0'); // only reads the first byte of data
  
 pause = map (val,0,9, 15, 100); // hence maximum of 9

  pause = constrain (pause , 15, 100);
  
  Serial.flush();
  }
 
  
  
  
  
  
  do
{
  digitalWrite(OPTO, HIGH);
 delay(pause);
 digitalWrite (OPTO, LOW);
 delay(pause);// check the sensors

} while (Serial.available() ==0 );

  
   Serial.println (pause);

  
 }
 

However i dont think this is what you guys were getting at, so if theres a much more economic way of achieving the same results i would appreciate any insight. There is also some odd behaviour... When i input into the serial monitor, i have to input the number i want twice before the arduino changes the value of "pause". any ideas?
« Last Edit: April 02, 2011, 05:09:29 pm by gravebond » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26281
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The economic way was described in reply #1 = I can't see why it wouldn't work.
Why did you reintroduce the "while" loop?
It isn't needed.
« Last Edit: April 02, 2011, 05:15:39 pm by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i couldnt get it to work the way described in reply # 1. I was clutching at straws when i added the while loop, and it happened to work. Although it does look very clumsy. Could you explicitly tell me the code involved to make it work as described in reply #1 as i may have made a silly mistake somewhere when i tried my implementation of it?
« Last Edit: April 02, 2011, 05:21:57 pm by gravebond » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26281
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

[uncompiled, untested]
Code:
#define OPTO 13 // optocoupler pin
int pause; // variable for our blinks

void setup()
{
 Serial.begin(9600);
 pinMode (OPTO, OUTPUT);
}

void loop ()
{
  if (Serial.available() >0 ) {
    int val = Serial.read(); // only reads the first byte of data
    pause = map (val, '0', '9', 15, 100); // hence maximum of 9
    pause = constrain (pause , 15, 100); // only needed if you don't get '0' to '9'
  }
 
  digitalWrite(OPTO, HIGH);
  delay(pause);
  digitalWrite (OPTO, LOW);
  delay(pause);// check the sensors
  Serial.println (pause);
}
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

RIght that works, and was in fact the second thing i tried, the problem was declaring pause as an int in the map function in the loop. Thanks for the halp!.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49301
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  if (Serial.available() >0 ) {
    int val = Serial.read(); // only reads the first byte of data
    pause = map (val, '0', '9', 15, 100); // hence maximum of 9
    pause = constrain (pause , 15, 100); // only needed if you don't get '0' to '9'
  }
You might want to modify this code to properly deal with invalid input. Suppose the serial port is sent a 'B'. That is not in the range '0' to '9'. As written, the code will cause pause to be assigned either 15 or 100, depending on which invalid character is sent.

I'd prefer to simply ignore any invalid characters. Your mileage may vary.
Logged

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 31
wewt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Whats the most economical way of doing this? I dont want to have to make a separate if statement for number 1 -9. Another constrain on the val?
Logged

Pages: [1] 2   Go Up
Jump to: