Variables not updating in a loop

Hi all,

I'm trying to write a program that will flash LED's attached to a wheel so that they are on for half a revolution and off for half a revolution. Revolutions are detected by a interrupt attached to a hall effect sensor and this works. In other programs I have current MPH displayed on the LED's (i.e. 1 led = 1mph etc), all driven from the interrupt.

The idea for my code is that timing of the LED ON/OFF is governed by variables that are updated every 5 seconds or so as the speed slowly changes the timing changes to maintain the half on, half off behavior.

I set the initial vales to flash every 128 milliseconds and when I start the code and spin the wheel they flash correctly but aren't changing speed of flashing as time elapses. I've tested that the code is firing every 5 seconds by increasing the pixeldelay value by one each time and this behaved as expected and the flashing slowed down every 5 seconds.

I really don't understand why the delay variables aren't updating.

Any help would greatly appreciated and you have all been of such great assistance so far in the project.

Below is the pertinent code:

volatile int revcount;
int duration;
float onerevduration;
float pixeldelay;

void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
pinMode(2, INPUT); // Make digital 2 an input
digitalWrite(2, HIGH); // Enable pull up resistor
attachInterrupt(0, RPMfun, FALLING);
revcount = 0;
duration = 0;
onerevduration = 256.0;
pixeldelay = 1.0;
}

void loop() {

if (duration > 5000) {
onerevduration = duration / revcount;
pixeldelay = onerevduration / 256;
duration =0;
revcount = 0;
}

else {

digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 255);
shiftOut(dataPin, clockPin, 255);
digitalWrite(latchPin, 1);

delay((int)(pixeldelay * 128));
duration = (int)(duration + (pixeldelay * 128));

digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);

delay((int)(pixeldelay * 128));
duration = (int)(duration + (pixeldelay * 128));
}
}

void RPMfun()
{
revcount++;
}

I've been playing around think this line is where the problem lies:

onerevduration = duration / revcount;

Still no idea how to fix it!

I've tried a new approach which is close to working but not quite there. This code should turn on the LED's for a full revolution then off for a full revolution regardless of speed. It seems to work and the blinking slows down as revs decreases and increases as revs increases, the problem is it is very rarely blinking for one full revolution, even though the speed is pretty steady, it varies between about 50% and 90% of a revolution. Does anyone have any idea where this timing inaccuracy may be coming from? The timing is vital as i'm trying to build a bike wheel POV!

Any help would be greatly appreciated.

Here is the code:

int value = LOW;
volatile byte RPMcount = 0;
long previousMillis = 0;
long lightMillis = 0;
long interval = 3000;
long onerevduration = 500;

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

//holders for infromation you're going to pass to shifting function
byte dataRED;
byte dataGREEN;
byte dataArrayRED[10];
byte dataArrayGREEN[10];

void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
pinMode(2, INPUT); // Make digital 2 an input
digitalWrite(2, HIGH); // Enable pull up resistor
attachInterrupt(0, RPMfun, FALLING);
}

void RPMfun()
{
RPMcount++;
}

void loop() {

if (millis() - previousMillis > interval) {
onerevduration = (millis() - previousMillis) / RPMcount;
previousMillis = millis(); // remember the last time we blinked the LED
RPMcount=0;
}

if (millis() - lightMillis > onerevduration) {
if (value == LOW)
value = HIGH;
else
value = LOW;

lightMillis = millis();
}

if (value == LOW)
{
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);
}
else
{
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 255);
shiftOut(dataPin, clockPin, 255);
digitalWrite(latchPin, 1);
}

}

Can you give some idea of the magnitude of the different variables?

Of course AWOL, the interrupt fires about 1-4 times a second depending on speed so the onerevduration variable should be between 1000millseconds and about 250.

So in any given 3 second interval revcount should be big enough to give a pretty accurate value for onerevduration.

Put something else in your RPMfun() function to be sure that it's getting called at all. Blink an LED, print some text, etc.