Hi Everyone,
Bit of project background first. I have built most of a digital dashboard for my Ural Motorcycle. It's old tech and has noisy electrics so I have electrically isolated my Arduino and sensors from the bike's electrical system and ground. I power the Arduino on the bike via a powerbank, ergo smooth DC supply voltage.
Initially for bike speed I set about using two magnets on opposite sides of the drive shaft, but I got garbage results no matter how much I tried to debounce. I understood that as a magnet approaches, the Hall Effect module will see a rising signal, but I imagined that using RISING to trigger the interrupt would sort that. No dice, so I gave up on that and moved to GPS for the speed.
The ignition module on my bike lights an LED at top dead centre so I figured that would be ideal for using a light sensor (digital output) to opto-isolate the Arduino from the bike - and also because LEDs do not have significant ramp up time vs incandescant bulbs.
Placed the module inside the ignition housing and again got garbage results. My next step would be to use a fibre optic (from HiFi) 'cable' to transmit the LED to the Arduino location, far away from spurious interference etc. But first I decided to do some bench tests.
To prove to myself that interrupts work, I first set up one Arduino with the following script and I connected output pin 7 it to the input pin 2 of my main Arduino. This was to use one Arduino to generate a nice clean square wave to feed the other.
//Simple pulse generator for 20Hz
void setup() {
// put your setup code here, to run once:
pinMode(7, OUTPUT);
pinMode(13, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(7, HIGH);
digitalWrite(13, HIGH);
delay(25);
digitalWrite(7,LOW);
digitalWrite(13, LOW);
delay(25);
}
On the main Arduino I run this script.
volatile byte counter = 0;
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = 0;
long CurrentMillis = 0;
void Interrupt_Function()
{
// If interrupts come faster than X ms, assume it's a bounce and ignore
interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 10)
{
counter++;
}
last_interrupt_time = interrupt_time;
}
/*
void Interrupt_Function()
{
counter++;
}*/
void setup()
{
Serial.begin(9600);
pinMode(2, INPUT);
attachInterrupt(digitalPinToInterrupt(2), Interrupt_Function, HIGH);
}
void loop()
{
if ( millis() > (CurrentMillis + 999))
{
noInterrupts();
CurrentMillis = millis();
Serial.print("Pulses = ");
Serial.println(counter);
interrupts();
counter = 0;
}
}
As you can see I have two available interrupt functions, one with debounce.
Results:
Setting the non debounced interrupt function to RISING or FALLING works perfectly and I get a constant 20 pulses per second on the Print output.
If I set LOW or HIGH I get a constant 40 pulses per second unless I debounce, but then I'm almost restricting the counted pulses by whatever figure I choose for debouncing.
Since I had a very nice constant 20 pulses on this I then attached a light sensor. When held directly over the LED (pin 13) on the signal generating Arduino, I get a constant 40 pulses per second with RISING, FALLING and HIGH (OK this is double the expected pulses, but it's exactly double so I could use it potentially).
If I select LOW, something kooky happens and the reporting interval gets screwy and instead of every second becomes every three seconds or so.
This is all confusingly in contradiction to Arduino's notes on which interrupt triggers are allowed on each board.
Apologies for the lengthy post but I hope all the info is there. The question being really, what the heck is going on.