Go Down

Topic: interrupt and button loop probelm (Read 601 times) previous topic - next topic


I've got to make an odometer for an airplane for a school comp.
I'm having trouble getting a good structure down.
I'm using a magnetic sensor to count rotations on a wheel, no problem there.
Basically it has to show the calibration #, measure takeoff then using a switch be able to shut off the takeoff counter and switch to a landing counter when the switch is repressed, then has to display landing and takeoff.
I have it set up right now using the sensor, a takeoff/landing switch, a user button, external reset button, and a  2x16 serial display.

i have the basic flow of the loop as
Code: [Select]
if user button=0
show a splash screen
if user button=1
show calibration #
if user button=2
show press to start
if user button=3
start takeoff/landing function
if user button=4
show distance counters

what I'm having a problem with is ending the takeoff/landing function.
i want to be able to use the same user button to switch to the next function but don't want it polling that button in a while function, I could use an interrupt but that would entail another button.

Would i be able to make the user button an interrupt and have it call an increment function therefore interrupting the takeoff/landing function and passing it to the next show function?

Is there a better way i can structure my code to make it flow better?


Coding Badly

but don't want it polling that button in a while function

Why not?


i dont want it having the chance of skipping a count on the sensor


Are you currently using an interrupt to measure the rotation sensor? I guess you're not, hence your concern about missing beats.

This is the structure I would use, with an interrupt for your sensor, a timed loop for polling (and maybe also periodic calculations), and a state machine. The user input button is de-bounced.

Sorry, I know this compiles but I don't have it hooked up to a device.

Code: [Select]

#include "TimerOne.h" // http://www.arduino.cc/playground/Code/Timer1

int sensorInterrupt = 0; // interrupt zero is hooked up to
int sensorInPin = 2; // pin 2 - so put your sensor here

const int DEBOUNCE = 100/*ms*/; // just a decent number of iterations
int userButtonDebounce = 0;
int userButton = 0;
int userButtonPin = 5;

const int STATE_A = 1;
// etc

int current_state = STATE_A;

// you might need this for your rpm counter
// I put the user button here on an interrupt
// but I saw afterwards that you might prefer an interrupt
// for the sensor to avoid missing anything

void t1_periodic_poll()
// has the button been pressed? - don't overwrite if not processed, and debounce
if(userButtonDebounce == 0 && userButton != 1)
   userButton = digitalRead(userButtonPin);
   if(userButton == 1) userButtonDebounce = DEBOUNCE;
if(userButtonDebounce > 0) --userButtonDebounce;

void setup()
  pinMode(sensorInPin, INPUT);
  attachInterrupt(sensorInterrupt, isr0_sensor, FALLING);

  pinMode(userButtonPin, INPUT);
  Timer1.initialize(/*in us 1msecond*/1000L);
  Timer1.attachInterrupt(t1_periodic_poll, 1000L);

void loop()
  // check polled sensors
  if(userButton == 1)
    userButton = 0;
    current_state = choose_next_state();

  // process current state
    default: break;

int choose_next_state() { return current_state; } // return next

You can put all sorts of counters (that you code and track) in the timer function, then act on them in the loop function. For example, you could write to the serial output only once every second.

Hope it helps!

Go Up