Hello All,
I tried to make digital speedometer using Uno,Hall effect sensor,TM1637 and and MAX7219. It is worked correctly when the engine is not started. When the engine is started, it is worked like RPM meter (Even when not connected the sensor ). I think that is using sense of ignition pulse.Please help. Here is my code
#include <Arduino.h>
#include <TM1637Display.h>
#include <LEDDisplayDriver.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <EEPROM.h>
#include <Wire.h>
#include <util/atomic.h>//===Max=====
#define DIN_PIN 3
#define CS_PIN 4
#define CLK_PIN 5
// Module connection pins (Digital Pins)
#define CLK 6
#define DIO 7#define PIN_HALL_SPEED_SENSOR 2
void setup() {
Serial.begin( 115200 );
Serial.print( "Initialization complete\n" );
DDRD = B01111011;
ReedMileage();
SpeedPulseCounterSetup();
}void loop() {
SpeedPulseCounterLoop();
}int counter = 0;
unsigned long mileage = 0;
unsigned long oldMileage = 0;
static int lastKMPHDisplayed = -1;
static int lastMileageDisplayed = -1;TM1637Display display1637(CLK, DIO);
LEDDisplayDriver display(DIN_PIN, CLK_PIN, CS_PIN, true, 8); // With 8 digits===Max=====void writeData(int address, long number)
{
if((number >> 24)!=(oldMileage >> 24)) {
EEPROM.write(address, (number >> 24) & 0xFF);}
if((number >> 16)!=(oldMileage >> 16)) {
EEPROM.write(address + 1, (number >> 16) & 0xFF);}
if((number >> 8)!=(oldMileage >> 8)) {
EEPROM.write(address + 2, (number >> 8) & 0xFF); }
EEPROM.write(address + 3, number & 0xFF);
}long readData(int address)
{
return ((long)EEPROM.read(address) << 24) +
((long)EEPROM.read(address + 1) << 16) +
((long)EEPROM.read(address + 2) << 8) +
(long)EEPROM.read(address + 3);
}void ReedMileage(){
mileage = readData(100);
oldMileage=mileage;
}void SpeedPulseCounterSetup() {
// Hall Speed Sensor interrupt setup
pinMode( PIN_HALL_SPEED_SENSOR, INPUT );
attachInterrupt( digitalPinToInterrupt( PIN_HALL_SPEED_SENSOR ), hallSpeedInterruptHandler, RISING );// Set up the 7 segment display, default address
display1637.setBrightness(0x02);
display.setBrightness(0x02);
}#define DISTANCE_PER_PULSE_IN_KM 0.0004625f // wheel circumference 1.85 meters, 4 Pulses per Round)
#define MICROSECONDS_PER_HOUR 3600000000.0f // 60 minutes * 60 seconds * 1,000,000 microsecondsvolatile unsigned long lastPulseTimeUS = 0; // When the last pulse was read via micros()
volatile unsigned long lastPulseLengthUS = 0; // The smoothed pulse length, for use by the main loopvoid hallSpeedInterruptHandler()
{
// - Compute the pulse length, filtered to smooth out noise and timing inaccuracies
unsigned long now = micros();
lastPulseLengthUS = now - lastPulseTimeUS;
lastPulseTimeUS = now;Serial.print( lastPulseLengthUS ); // For test lastPulseLength
Serial.print( "\n" );counter++;
if(counter>=217 ) {
mileage++;
writeData(100, mileage);
delay(1);
counter=0;
}
}static int lastMPHDisplayed = -1;
static unsigned long lastMPHUpdateTime = 0; // The last time we updated the display#define MPH_REFRESH_RATE 500 // How frequently we check for a new speed to display (1/2 second)
void SpeedPulseCounterLoop() {
// If not a lot of time has passed, just return. We don't want to spend all our
// time displaying the speed.
unsigned long now = millis();
if( now - lastMPHUpdateTime < MPH_REFRESH_RATE )
return;lastMPHUpdateTime = now;
// Make local copies of variables changed by interupts
unsigned long _lastPulseTimeUS, _lastPulseLengthUS;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
_lastPulseTimeUS = lastPulseTimeUS;
_lastPulseLengthUS = lastPulseLengthUS;
}// See if we're stopped
if( _lastPulseTimeUS + 500000 < micros() ) {
// We're stopped (no pulses in the last 1/2 second); clear out the speeds
_lastPulseTimeUS=micros();
_lastPulseLengthUS = 0;
}// Microsecond version
float pulseLengthInHours = ((float)_lastPulseLengthUS) / MICROSECONDS_PER_HOUR;
int newKMPH = (int)(DISTANCE_PER_PULSE_IN_KM / pulseLengthInHours );if( lastKMPHDisplayed != newKMPH ) {
if( newKMPH == 0 ) {
display1637.showNumberDec(0, false);
} else {
display1637.showNumberDec(newKMPH, false);
}
lastKMPHDisplayed = newKMPH;
}
if( lastMileageDisplayed != mileage ) {
display.showNumWithPoint(long(mileage),1);
lastMileageDisplayed=mileage;
}
}