Go Down

Topic: How to pulse a digital output, hardware timers, software timers, delay, mills() (Read 2086 times) previous topic - next topic


Hi there! New to arduino and the board.  Of course that means I have to ask for help :D

The short of it is that I'm trying to figure out how to activate a digital output for a relatively short period of time.  I don't want to use a delay() because I want the program to keep processing and I would like a recommendation (link to a page or brief explanation of what function(s) to use) on how to do that.  I am using a sparkfun arduino Uno rev 2.

The long story:
I'm using an arduino as a safety controller for my R/C lawnmower.  Right now the interface is a Hobby King transmitter and receiver.  I'm using the ServoDecode library to read the inputs from the transmitter.  I'm not intercepting them, just reading the PWM to kill the mower engine and engage the motor brakes. I've tested the relays and imported sample code to control them.

I'm using the amazon.com el cheapo car door lock actuator to mimic the deadman switch on the mower engine.  Due to the nature of the actuator, I can't maintain a relay closure or it will fry the motor (it's meant to be a momentary engage), so I just need to pulse the signal for a bit.  I will make use of the bidirectional capabilities of the actuator by using 2 relays to control it.  Schematic here: http://www.firgelliauto.com/product_info.php?products_id=28 its the first big one.  The jist is I'll have the NC contacts on ground, the C on a wire to the actuator, and the NO will go to power.

I'd like to pulse the digital output for long enough to make sure that the engine dies and stays dead; I'm thinking 1 - 3 seconds.  I don't want to use a delay because I don't want the whole program to stop.  There's not much else going on in the program at the moment, but I want to add more sensors and processing as I grow this project.

I've searched Google and the forum and found an overwhelming amount of data (maybe poor search terms?) and I'm a little confused.  It seems that timers (interrupts?) are hardware resources and in short supply.  I seem to have used one up with the ServoDecode library I want to use.  I don't need much precision, and it doesn't seem that complicated, so I'm not sure if I really need to find a library to import.  I found the mills() function, but I'm concerned that operating on ms values as they come down the pipe for any length of time will be processor intensive/expensive.  If it's not, I could come up with the math to compare time 1 and 2; I don't suspect that would be a problem.

I found a function that would do what I want, but I'm not sure if I should need to import a 3rd party library to do something like this.  Doesn't importing a whole library consume a bunch of RAM or other memory in the arduino?  Is that just the nature of the arduino beast to always need a library or three?  Is this library even 3rd party? It kinda looks official...

Code: [Select]

[i]int pulse(int pin, long period, int startingValue)
Toggle the state of the digital output 'pin' just once after 'period' milliseconds. The pin's starting value is specified in 'startingValue', which should be HIGH or LOW.
Returns the ID of the timer event.[/i]

From http://arduino.cc/playground/Code/Timer

This is what I have so far:

Code: [Select]
// ServoDecodeRelayTest

#include <ServoDecode.h>

char * stateStrings[] = {
  "NOT_SYNCHED", "ACQUIRING", "READY", "in Failsafe"};

// Define readable non-backwards states for relays.
// This is because relays are active LOW.  That means you can ground the pin and activate the relay.
#define RELAY_ON 0
#define RELAY_OFF 1

// Give each relay friendly name and map to Arduino Digital I/O pin number
#define Relay_1  2  // wire 1 of the engine kill actuator.  Pulse to allow engine to run.
#define Relay_2  3  // wire 2 of the engine kill actuator.  Pulse to kill engine.
#define Relay_3  4  // brake controller
#define Relay_4  5

// run once, when the sketch starts
void setup(){

  // ServoDecode setup
  // Seems that some of this is debug info and maybe can be removed for runtime.
  ServoDecode.setFailsafe(3,1234); // set channel 3 failsafe pulse  width
  // Relay Setup
  // Initialize Pins so relays are inactive at reset
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF);
  // THEN set pins as outputs
  pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT); 
  pinMode(Relay_3, OUTPUT); 
  pinMode(Relay_4, OUTPUT);   
  delay(4000); // Check that all relays are inactive at Reset

} // end setup()

// Run over and over again
void loop(){    
  int pulsewidth;
  // print the decoder state
  if( ServoDecode.getState()!= READY_state) {
    //Controller is out of range, acquiring or off
    //turn off engine
    digitalWrite(Relay_1, RELAY_OFF);
    //engage breaks
    Serial.print("The decoder is ");
    for ( int i =0; i <=MAX_CHANNELS; i++ ){ // print the status of the first four channels
Serial.print("Cx"); // if you see this, the decoder does not have a valid signal
Serial.print("= ");
pulsewidth = ServoDecode.GetChannelPulseWidth(i);
Serial.print("  ");
    } //end for

  } // enf if
  else {
    // decoder is ready, print the channel pulse widths
    for ( int i =1; i <=MAX_CHANNELS; i++ ){ // print the status of the first four channels
Serial.print("= ");
pulsewidth = ServoDecode.GetChannelPulseWidth(i);
Serial.print("  ");
    } //end for
  } //end else
  delay(500); // update 2 times a second
} //end loop

Aside from having almost maybe answered my own main question already, I'd like to understand this timer/interrupt/clock thing.  It seems that on the Uno there is 1 hardware timer, and possibly a second.  It seems that there is a way to fake a timer in software, but it's not as precise.  It seems that there is not a clock of any sort in the arduino (I'm not sure if that would even affect what I'm doing right now, but I think it'd be good to know about).  Is there 1 or more pages that explain this in some detail?  It took me 8 - 12 hours of arduino research to come up with that much.  Granted the timer thing only became important in the last 2, but still...

Any help or recommendations would be appreciated!

Arduino that I'm using:
Older version of this: https://www.sparkfun.com/products/11021
I do have a rev 3 laying around if that would be better for what I am doing.

Hobby King Tranceiver pair:


Relay hardware (example):

Relay code

Actuator (example):

Nick Gammon

I'd like to understand this timer/interrupt/clock thing.  It seems that on the Uno there is 1 hardware timer, and possibly a second.

Interrupts: http://www.gammon.com.au/interrupts
Timers: http://www.gammon.com.au/forum/?id=11504

You have 3 hardware timers, plus a watchdog timer.

I don't want to use a delay because I don't want the whole program to stop.  

How would you do that if you were standing near the motor mower with a stopwatch?


There's not much else going on in the program at the moment, but I want to add more sensors and processing as I grow this project

Don't use delay, but certainly read the above links.
Please post technical questions on the forum, not by personal message. Thanks!

More info:


I don't see a "thanks" methodology in this message board's system, but thanks!  I looked over the links you sent just after I saw them and am just now getting back to this project.  These should also point me in the right direction for some other projects I have ideas for.

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131