Help with code

Hello everybody,

I am trying to figure out some code to do what I want.

Here's the scenario:

If I press a button once, it starts a 'routine(?)' that turns on and off an output (relay) every 5 seconds. When I press the button again, I want this to stop.

Here is the application:

I have a camera that I will put into the air by balloon, and when I press the 'start button' I want it to energize a relay every five seconds, which causes the camera to take a picture. When I get the camera back to the ground, I'll press the same button, which tells it to stop taking pictures.

I copied the bulk of the learning tutorial, where you press the button four times it turns an LED on. I've been playing around with different things for two days, but seeing as I'm just learning, I don't really know what to use yet.

Here is the current code I just tested, and doesn't work(obviously).

/*
  State change detection (edge detection)
       
 Often, you don't need to know the state of a digital input all the time,
 but you just need to know when the input changes from one state to another.
 For example, you want to know when a button goes from OFF to ON.  This is called
 state change detection, or edge detection.

 This example shows how to detect when a button or button changes from off to on
 and on to off.
       
 The circuit:
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground
 * LED attached from pin 13 to ground (or use the built-in LED on
   most Arduino boards)

 created  27 Sep 2005
 modified 14 Oct 2010
 by Tom Igoe

This example code is in the public domain.
       
 http://arduino.cc/en/Tutorial/ButtonStateChange

 */

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int flashState = 0;
void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter, DEC);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  
  // turns on the LED every four button pushes by 
  // checking the modulo of the button push counter.
  // the modulo function gives you the remainder of 
  // the division of two numbers:
  if (buttonPushCounter % 2 == 0) {
    flashState = 1;    
    
  } else {
   digitalWrite(ledPin, LOW);
  }
  
 while (flashState == 1) {
    digitalWrite(ledPin, HIGH);
   delay(1000);
  digitalWrite(ledPin, LOW);
 delay(1000);
  } 
  
  
}

Any help will be greatly appreciated.

Thanks, Joshua

 while (flashState == 1) {
    digitalWrite(ledPin, HIGH);
   delay(1000);
  digitalWrite(ledPin, LOW);
 delay(1000);
  }

Joshua, once it reaches this part, your button is never read again, thus flashState never changes thus pressing your button will have no effect. Get rid of the loop and the delay() and do one part of the flashing every time loop is done. For an example, look at the Blink Without Delay Tutorial (there really should be a button that inserts the link to this tutorial automatically)

Korman

I get scared posting code with Korman around, but hopefully this version might be close to what you need.

#define TRUE 1
#define FALSE 0

void loop() {
      int take_photos = FALSE;
      int buttonState = digitalRead(buttonPin);
      int lastButtonState = buttonState;
      
      buttonState = digitalRead(buttonPin);

        if (buttonState != lastButtonState) {
              delay(50); // debounce
            buttonState = digitalRead(buttonPin);
            if (buttonState != lastButtonState) {
                  lastButtonState = buttonState;
                  take_photos = take_photos == TRUE ? FALSE : TRUE;

              }
        }
  
      if (take_photos == TRUE) {
            digitalWrite(ledPin, HIGH);
            delay(100);  // 100mS pulse, long enough?
            digitalWrite(ledPin, LOW);
            delay(4900);
      }
  
  
}

Note that the pins haven’t been defined.

Not pretty with the delays but if that’s all you need the code to do there’s no reason not to use them I think.


Rob

I get scared posting code with Korman around, but hopefully this version might be close to what you need.

Aww, it really must be my bad breath. But just to fill expectations, here are a few small changes…

#define TRUE 1
#define FALSE 0

void loop() {
      [glow]static[/glow] int take_photos = FALSE;
      int buttonState = digitalRead(buttonPin);
      [glow]static[/glow] int lastButtonState = buttonState;

      buttonState = digitalRead(buttonPin);

        if (buttonState != lastButtonState) {
              delay(50); // debounce
            buttonState = digitalRead(buttonPin);
            if (buttonState != lastButtonState) {
                  lastButtonState = buttonState;
                        [glow]if (buttonState == HIGH) { // or LOW if you use pull up transistors[/glow]
                           [glow]take_photos = ! take_photos;[/glow]
                       [glow]}[/glow]
              }
        }
  
      if [glow](take_photos)[/glow] {
            digitalWrite(ledPin, HIGH);
            delay(100);  // 100mS pulse, long enough?
            digitalWrite(ledPin, LOW);
            delay(4900);
      }
}

Those should be the minimal modifications to make the whole thing work. The button to disable the photography again will appear a little sluggish - (if you press it during the delay(4900) you’ll have to keep it pressed for up to 5 seconds) and the debouncing can be done more cleanly. But without trying it out, the code should work at least.

Korman

if (buttonState == HIGH) { // or LOW if you use pull up transistors
                           take_photos = ! take_photos;
                       }

Thanks, I was just thinking of the edge detection as the comments said in the original code and not thinking that that made no sense for this app.


Rob

Fools rush in where Angels fear to tread :-X

To get around the waiting 5 seconds to switch it off, how about :-

void loop () {
            digitalWrite(ledPin, HIGH);
            delay(100);  // 100mS pulse, long enough?
            digitalWrite(ledPin, LOW);
            delay(4900);
      }

and use a push on/push off switch to the camera ;)

You want to replace a stack of code with a simple switch? Man are you on the wrong forum :)

Yes, very good idea.


Rob

presumably hes going to have an on off switch anyway,,,

Meanwhile lets help him with some telemetry for height etc with Arduino, which is far too good to be an on off switch :)