I use this code, running on an Arduion Nano (clone), to count the pulses from magnetic proximty sensors.
The sensors are pointed at the sprocket teeth on the jackshaft, which drives the robots wheels.
The pulses cause an "Interupt Service Routine" (ISR) to increment a counter. The counter data is written to
the serial port where it can be read by a VB program.
The computer can also send an "R" to the arduino, to set the counters back to zero.
// Zoe_Odometer = Pgm to read pulses from two hall effect sensors pointing at
// sprocket teeth for Zoe's main drive.
// 9-21-21 Added speed measuring
// library code:
#include Wire.h // Need Wire.h to talk to serial port
#include LiquidCrystal.h> // Need LiquidCrystal.h to talk to LCD display
LiquidCrystal lcd (12,11,4,5,6,7); // Define LCD display pins RS,E,D4,D5,D6,D7
// Pins:
const int PinLED = 13;
const int PinReset = 8;
// Varz:
volatile unsigned long CountLeft=0;
volatile unsigned long CountRight=0;
bool LEDOn = true;
bool PinResetValue = HIGH;
// Varz for Speed Measuring
volatile unsigned long PreviousLeft=0;
volatile unsigned long PreviousRight=0;
volatile unsigned long LatestLeft=0;
volatile unsigned long LatestRight=0;
unsigned long PPSLeft=0;
unsigned long PPSRight=0;
// The setup function runs once when you press reset or power on the board
void setup()
{
pinMode(PinReset, INPUT_PULLUP);
// Set up the serial port
Serial.begin(9600);
Wire.begin();
// Set up LCD as 16x2 type
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Zoe The Robot");
lcd.setCursor(0,1);
lcd.print("Odometry");
delay(2000);
lcd.clear();
pinMode(PinLED,OUTPUT); // Built in LED
Serial.println("* Hard Reset");
// Choices are: RISING , LOW , FALLING , CHANGE
attachInterrupt(digitalPinToInterrupt(2),IncrRightISR,RISING); // function for creating external interrupts at pin2 on Rising (LOW to HIGH)
attachInterrupt(digitalPinToInterrupt(3),IncrLeftISR,RISING); // function for creating external interrupts at pin3 on Rising (LOW to HIGH)
}
// The loop function runs over and over again forever
void loop() {
// Main Loop
LatestRight=CountRight;
LatestLeft = CountLeft;
// Calculate pulses per second
PPSRight = (LatestRight-PreviousRight)/2;
PPSLeft = (LatestLeft-PreviousLeft)/2;
// Display Right Count on LCD
lcd.setCursor(0,0); // top line
lcd.print("R ");
lcd.print(LatestRight);
// Display Right Speed on LCD
lcd.setCursor(14,0);
lcd.print(" ");
lcd.setCursor(14,0);
lcd.print(PPSRight);
// Display left Count on LCD
lcd.setCursor(0,1); // second line
lcd.print("L ");
lcd.print(LatestLeft);
// Display Left Speed on LCD
lcd.setCursor(14,1);
lcd.print(" ");
lcd.setCursor(14,1);
lcd.print(PPSLeft);
// Send Counts to serial port
Serial.print("R:");
Serial.print(LatestRight);
Serial.print(" SR:");
Serial.print(PPSRight);
Serial.print(" L:");
Serial.print(LatestLeft);
Serial.print(" SL:");
Serial.println(PPSLeft);
delay(2000);
PreviousLeft=LatestLeft;
PreviousRight=LatestRight;
// Toggle LED
LEDOn= !LEDOn;
if(LEDOn){digitalWrite(PinLED,HIGH);} else {digitalWrite(PinLED,LOW);}
// Check an input pin for counter reset signal
PinResetValue = digitalRead(PinReset); // read the input pin
// Call CounterReset if PinReset goes low
if(PinResetValue == LOW){Serial.println("* Pin Reset"); CounterReset(); }
}
// End of loop
// This code executes if data is recvd by serial port
void serialEvent()
{
while (Serial.available())
{
// get the new byte:
char inChar = (char)Serial.read();
// Call CounterReset if R received
if (inChar == 'R') { Serial.println("* Serial Reset"); CounterReset(); }
}
}
void IncrRightISR() {CountRight++;}
void IncrLeftISR() {CountLeft++;}
void CounterReset() {CountRight=0; CountLeft=0; PreviousLeft=0; PreviousRight=0; lcd.clear();}