Hi, i want to make a speed tachometer for my bike with a hall effect sensor
For testing im using a arduino uno and a 16x2 lcd with i2c.
When i connect the hall effect sensors output to the arduino, the closer i get to the bike while its idling the more it "interferes" with it, (it reads 40kmh when the bike is standing still).
The cable that leads to the hall effect sensor is coated with copper tape and grounded.
is there something i can do to stop this form happening, diode? capacitor?
As a demonstration I set up a quite low frequency timer ISR that increments an unsigned long.
loop reads this value and compares it to the last value read.
There should never be a difference bigger than one, as loop is called much more often than the ISR.
void setup() {
Serial.begin(115200);
Serial.println(F("wait for error..."));
// set up Timer 1
TCCR1A = 0; // normal operation
TCCR1B = bit(WGM12) | bit(CS10); // CTC, no pre-scaling
OCR1A = 10999; // compare A register value (1000 * clock speed)
TIMSK1 = bit (OCIE1A); // interrupt on Compare A Match
}
volatile unsigned long Counter;
ISR(TIMER1_COMPA_vect)
{
Counter++;
}
void loop() {
static unsigned long before;
static unsigned long current;
// noInterrupts();
current = Counter;
// interrupts();
unsigned long differenz = current - before;
if (differenz > 1) {
Serial.print(F("from 0x"));
Serial.print(before, HEX);
Serial.print(F(" to 0x"));
Serial.print(current, HEX);
Serial.print(F(" diff 0x"));
Serial.println(differenz, HEX);
}
before = current;
}
gives
wait for error...
from 0x9FF to 0xAFF diff 0x100
from 0xAFF to 0xA01 diff 0xFFFFFF02
from 0x2DFF to 0x2EFF diff 0x100
from 0x2EFF to 0x2E01 diff 0xFFFFFF02
from 0x38FF to 0x39FF diff 0x100
from 0x39FF to 0x3901 diff 0xFFFFFF02
from 0x6BFF to 0x6CFF diff 0x100
from 0x6CFF to 0x6C01 diff 0xFFFFFF02
from 0x6EFF to 0x6FFF diff 0x100
from 0x6FFF to 0x6F01 diff 0xFFFFFF02
from 0x72FF to 0x73FF diff 0x100
from 0x73FF to 0x7301 diff 0xFFFFFF02
from 0x84FF to 0x85FF diff 0x100
from 0x85FF to 0x8501 diff 0xFFFFFF02
from 0x91FF to 0x92FF diff 0x100
from 0x92FF to 0x9201 diff 0xFFFFFF02
from 0xBBFF to 0xBCFF diff 0x100
from 0xBCFF to 0xBC01 diff 0xFFFFFF02
Sorry i dont quite understand what you mean , i implemented the changes you have, made changes to the int/unsigned long that is shared, and the other stuff in setup. Iv done lots of arduino projects, but iv never worked much with interrupts.
it didnt help with the interference with the new code, shoud it?
thx for replying
my code now looks like this
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
unsigned long rpmTimer;
unsigned long rpmTimerSet;
unsigned long lcdTimer;
unsigned long lcdTimerSet;
volatile unsigned long inputRpmCount;
int Rpm;
float RpmEasing = 0.2;
float ArInputRpmCount;
float SmInputRpmCount;
int Sm2InputRpmCount;
int newDigital;
int oldDigital;
void setup() {
Serial.begin(9600);
TCCR1A = 0; // normal operation
TCCR1B = bit(WGM12) | bit(CS10); // CTC, no pre-scaling
OCR1A = 10999; // compare A register value (1000 * clock speed)
pinMode(2,INPUT_PULLUP);
pinMode(3,OUTPUT);
digitalWrite(3,HIGH);
attachInterrupt(digitalPinToInterrupt(2),RpmInterrupt,HIGH);
lcd.backlight(); // Backlight On
lcd.begin(16,2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("TEST!");
lcd.setCursor(11,1);
lcd.print(" KM/T");
}
void loop() {
Interrupt_Loop();
if(lcdTimer > 500){
lcd.setCursor(0,1);
lcd.print(Sm2InputRpmCount);
lcd.print(" ");
lcdTimerSet = millis();
}
lcdTimer = millis() - lcdTimerSet;
}
ok thx i measured the hall effect sensor directly with a oscilloscope, when i get near the spark plugs i get a little spike of voltage, 800mv or so. is this enough to trigger the interrupt? And how much voltage does it take to trigger a interrupt when its set to trigger on "high"?
Example - you are using a Vcc of 5.0 v ==> 0.7 * (5.0 + 0.5) = 3.85v for a guaranteed input seen as a HIGH.
Welcome to the real world - vehicles are notoriously noisy electrically and motorcycles are some of the worst. Without proper signal conditioning on all things going into and out of your controller, you are going to be fighting a losing battle to get things to work the way you want them to.
hi, thanks for the explanation yeah i realized they are a mess when it comes to interference iv measured the length of the voltage spike, and it is 40ns and the voltage is enough to trigger the interrupt. Is there a way to make arduino not count it if the pulse is smaller than lets say 50ns? If someone could make an example code i would appreciate it
You could try to read the hall on ISR entry and ignore the interrupt if it is not active any more.
This would ignore all signals shorter than the time needed to reach the test.
I count 82 cycles there (5.125 µS in total at 16 MHz) as overhead plus whatever is actually done in the supplied interrupt routine. That is, 2.9375 µS before entering your interrupt handler, and another 2.1875 µS after it returns.
You should be conditioning the signal from the sensor - the spikes may be over-voltage and stressing the
protection diodes. Part of conditioning will be protection (series-resistor and two schottky diodes),
part will be band-width limiting to remove/reduce transient pulses (RC). You don't get nice clean
signals near most petrol engines (although some use properly shielded high tension leads, like in
aeroplane engines, apparently, which would be much better)
Thx for your answers but i finally figured it out! Instead of sorting the problem with the arduino i managed to sort it out with the bike. It turns out that this has been a common problem with older bikes/cars (older than mine). so they added resistors in the spark cap and/or in the spark plugs and spark plug wires. Mine has it in the spark caps and plugs (5kohm each), these tend to wear out and mine was totaly gone + previous owner(s) changed the spark plugs and decided to not use resistor plugs. I replace both parts and now it works like a charm!
Thanks a lot for taking your time to help me with this Whandall, gpsmikey and MarkT.
He was getting spikes introduced into his wiring from the magnetic pulses from the spark plug wires every time a plug fired. His solution (which is normal these days) involves using spark plugs with resistors in them - that limits the current in the spark plug wires which lowers the inductive coupling to nearby wires. The best way to deal with noise issues is to do as much as possible to eliminate it at the source - trying to deal with it in software typically is not nearly as successful in solving the problem. Start by making sure your sensor/pickup wires etc. are not near spark plug wires. Recognize that vehicle electrical systems are notoriously noisy when the engine is running - you have the spark system, you have the alternator / regulator and anything else going on in the system (and the voltage can be anywhere between about 11 and 14.5volts).