Go Down

Topic: sequencing analogRead (Read 2 times) previous topic - next topic

mgehring

Please help!  I need to get the following code to run sequentially...  read, then on for 30 seconds and stop, read again, then on for 20 seconds and stop, read again, then on for 10 seconds and stop.  then start again from the top.

It seems to me like it should work.  It is doing what is described above, but in random order.  I feel like I've tried everything to get it straight, but this is obviously not the case....

int ledPin = 13;   // LED connected to digital pin 13
int analogPin = 3;   // ir sensor connected to analog pin 3
int val = 0;   // variable to store the read value
int threshold = 275;   // threshold

void setup()
{
 pinMode(ledPin, OUTPUT);   // sets the digital pin 13 as output
}

void loop()
{
 val = analogRead(analogPin);    // read the input pin
 if (val >= threshold)
 {
    digitalWrite(ledPin, HIGH);   // sets the LED on
    if (ledPin, HIGH)
    delay(100);                  // waits for .1 second
    digitalWrite(ledPin, LOW);   // sets the LED off
    delay(30000);
    digitalWrite(ledPin, HIGH);
    delay(100);
    digitalWrite(ledPin, LOW);
    delay(1000);
 }
 else
 {
   digitalWrite(ledPin, LOW);   // sets the LED off
 }



 val = analogRead(analogPin);    // read the input pin
 if (val >= threshold)
 {
    digitalWrite(ledPin, HIGH);   // sets the LED on
    if (ledPin, HIGH)
    delay(100);                  // waits for .1 second
    digitalWrite(ledPin, LOW);   // sets the LED off
    delay(20000);
    digitalWrite(ledPin, HIGH);
    delay(100);
    digitalWrite(ledPin, LOW);
    delay(1000);
 }
 else
 {
   digitalWrite(ledPin, LOW);   // sets the LED off
 }


 val = analogRead(analogPin);    // read the input pin
 if (val >= threshold)
 {
    digitalWrite(ledPin, HIGH);   // sets the LED on
    if (ledPin, HIGH)
    delay(100);                  // waits for .1 second
    digitalWrite(ledPin, LOW);   // sets the LED off
    delay(10000);
    digitalWrite(ledPin, HIGH);
    delay(100);
    digitalWrite(ledPin, LOW);
    delay(1000);
 }
 else
 {
   digitalWrite(ledPin, LOW);   // sets the LED off
 }
}



MikMo

I think you are missing some "{" and "}"

after these statements :

if (ledPin, HIGH)

in each of the 3 main blocks


mgehring

Thanks for responding.  I've tried this sugestion and the program is still running in a random order.  The only thing I've been able to do to get it to run sequentially is to get rid of all bet the beginning and end braces.  But then it just works like a timer... 30 seconds on, twenty seconds off, ten seconds on, etc.  It doesn't read the ir sensor at all.

Any other suggestions?

mem

It would be easier to help if you could say a little more about what the sketch is supposed to do.

As writtne it looks like it will skip sequences if the val drops below the threshold for the analogRead. Is that what you want?

Does it work as expected if val is always greater than the threshold?

mgehring

I'm checking out the function if the value is always greater thann the threshold now.

Here's what's happening...

I've hacked into the face of a CD player and am using the Arduino and it's led function to start/pause the cd.  I'm trying to get it to run sequentially because I have audio tracks of different lengths.  So, when the IR sensor detects someone, the cd player starts(ledpin HIGH), then pauses(led pin high) when the track is over, until the IR sensor is triggered again and continues playing the negt song, etc.


mgehring

You are on point!  If the the threshold is constantly >=, then it does work sequentially.  I need ot to work this way all the time, whether someone is triggering it or not.  can you help?

TJ

#6
Feb 27, 2008, 10:39 pm Last Edit: Feb 27, 2008, 11:15 pm by TJ Reason: 1
Quote
I'm checking out the function if the value is always greater thann the threshold now.

Here's what's happening...

I've hacked into the face of a CD player and am using the Arduino and it's led function to start/pause the cd.  I'm trying to get it to run sequentially because I have audio tracks of different lengths.  So, when the IR sensor detects someone, the cd player starts(ledpin HIGH), then pauses(led pin high) when the track is over, until the IR sensor is triggered again and continues playing the negt song, etc.



I think you've just learned an important lesson:  before you start coding, write out a very clear and concise description of what your program will do, and how it will do it.  Make sure that your description is rational and logical.  Answer any questions that arise while you're analyzing your problem.

From your statements, I gather that your program should work something like this:

Input:

- IR sensor connected to analogPin.  When the sensor detects a person, analogPin will measure greater than threshold

Output:

- ledpin going high triggers the CD player's "Play" button.  (Why do you call it ledpin???)

CD:  

- contains 3 tracks:  30 seconds, 20 seconds, and 10 seconds

Operation:

When the IR sensor detects a person, it plays the next track in sequence.  Timing is done by fixed delays.

At the end of each track, the program makes sure the person is gone.  If necessary, it waits until the person is gone before proceeding.

==>  Question:  what happens after the third track has been played?  How do you reset to the beginning?  (At the moment, I'm just going to pretend that reset to the first track takes place by magic pixie dust.  You can fix it later.)


Let's see what we can do to your code to make it comply with the program description.

Code: [Select]


//
//  CD Player
//
//    <add brief description of program operation here>
//
//

//  Program Constants:

#define threshold 275      // threshold
const int tracktime[] = {30,20,10};   //  Array of track times in seconds
                                     //  These are elements 0, 1, and 2

//  Input/Output:

#define ledPin 13          // LED connected to digital pin 13
#define analogPin 3        // ir sensor connected to analog pin 3


//
//  Start of code
//

void setup()
{
 pinMode(ledPin, OUTPUT);   // sets the digital pin 13 as output
}


void loop()
{

 int tracknum = 0;   //  This will represent the current track number  

 while(1)            //  Outer while loop for fastest loop repeat
 {

   while( analogRead(analogPin) < threshold )  // wait for ir sensor to go high
     ;

   PushTheButton();               // start the track

   delay( tracktime[tracknum] );  // pause for track time

   PushTheButton();               // pause the track

   while( analogRead(analogPin) >= threshold )  // if the person is still near the
     delay(10);                                 // sensor, wait until person goes away

   if( ++tracknum > 2 )           // increment the track number.  If > 2, reset to zero
     tracknum = 0;

 }
}


void PushTheButton()
{
 //  Punch the Play button for 100 milliseconds

 digitalWrite(ledpin,HIGH);
 delay(100);
 digitalWrite(ledpin,LOW);
}



Some program notes:

When you're defining fixed constants, such as pins and the threshold value, use the preprocessor #define, rather than an int declaration.  You won't use extraneous memory locations, and you can't
change those values by mistake.

When using #define statements, note that there are no equal signs or semicolons.

When you must define constants in memory, as I did with the tracktime array, declare them as 'const'.  If you then try to change them, the compiler will (properly) generate an error, reminding you of your logic bomb.

Don't declare a variable as global unless you absolutely need to.  Note how I've declared tracknum in the loop() function.  That's the only place we use that variable, so that's the only function that needs to know about it.

(Technically, we could have declared threshold and tracktime[] in loop(), but those are constants you'll use to tune the behavior of your program.  It's nice to keep those things right up at the top where they're easy to find when you need to change them.)

In loop(), notice that I've built an outer while() endless loop that wraps the rest of your code.  With the Arduino, the loop() function will also run as an endless loop, but there's a little delay, and possibly some other weirdness, that takes place before looping.  Always play it safe and put your own endless loop structure in there to wrap your top level code.

void loop()
{

  while(1)
  {

     //  your top level code goes here

  }

}


In the other while() and if() calls, note that I can perform operations within the test parentheses:

   while( analogRead(analogPin) < threshold )

   if( ++tracknum > 2 )

This is a cleaner way of writing this stuff that, when you get used to reading it, is actually much easier to read and understand.  On PICs, it also lets the compiler generate cleaner machine code.  I presume the same holds for the Arduino's compiler.

Those two plus signs in front of tracknum are the pre-increment operator.   The if expression means "increment tracknum.  If it's greater than 2, do something..."

And finally, I've moved the Play button code to its own function to clean up the top level code.

Good luck!

Tom
Embedded Arduino Digicam Remote & Intervalometer
http://www.mindspring.com/~tom2000/Projects/AI-1_Remote/AI-1_Remote.html

TJ

GOOD GRIEF!

Talk about 'forest for the trees...'  The previous version of your program that I posted would have paused 30, 20, and 10 milliseconds to play each CD track.  Pop!  Pop!  Pop!

Here's a corrected version that will pause 30, 20, and 10 seconds:

Code: [Select]


//
//  CD Player
//
//    <add brief description of program operation here>
//
//

//  Program Constants:

#define threshold 275      // threshold
const int tracktime[] = {30,20,10};   //  Array of track times in seconds
                             //  These are elements 0, 1, and 2

//  Input/Output:

#define ledPin 13        // LED connected to digital pin 13
#define analogPin 3        // ir sensor connected to analog pin 3


//
//  Start of code
//

void setup()
{
 pinMode(ledPin, OUTPUT);   // sets the digital pin 13 as output
}


void loop()
{

 int tracknum = 0;     //  This will represent the current track number  

 while(1)            //  Outer while loop for fastest loop repeat
 {

   while( analogRead(analogPin) < threshold )  // wait for ir sensor to go high
     ;

   PushTheButton();               // start the track

   delay_secs( tracktime[tracknum] );  // delay 'track time' seconds

   PushTheButton();               // pause the track

   while( analogRead(analogPin) >= threshold )  // if the person is still near the
     delay(10);                         // sensor, wait until person goes away

   if( ++tracknum > 2 )           // increment the track number.  If > 2, reset to zero
     tracknum = 0;

 }
}


void delay_secs( int secs )
{
 // delays 'secs' seconds

 int i;

 for(i=0; i<secs; i++)
   delay(1000);
}


void PushTheButton()
{
 //  Punch the Play button for 100 milliseconds

 digitalWrite(ledpin,HIGH);
 delay(100);
 digitalWrite(ledpin,LOW);
}





Sorry 'bout that, Chief!

Tom

Embedded Arduino Digicam Remote & Intervalometer
http://www.mindspring.com/~tom2000/Projects/AI-1_Remote/AI-1_Remote.html

Go Up