Using my Arduino, I've made a sensor for determining how often I use the adjustable seatpost on my mountain bike. Basically I have a magnet glued to my lever that activates the post, so when I throw the lever it gets close to the sensor and triggers the hall effect sensor. I want it to count the number of times I use the post and write it to the EEPROM. I also need it to measure how long I hold the lever for..take an average time, a minimum time, and a max time for lever activation.
So far the counting portion of it works perfect, but the time measurement has a lot of bugs. When I check the data with the serial monitor the values will change even though the lever/hall effect sensor has not been activated. The sensor activation count stays stable though.
Any guesses as to what I've done wrong? Thank you!
/*
* Andy's Hall Effect GD Sensor V2
*/
#include <EEPROM.h>
#define hallSensor 11 // Set the hall effect sensor input on pin 11
#define ledPin 10 // Set LED pin as 10
#define addr1 0 // EEPROM write address 0-1 for int sensorActivations
#define addr2 2 // EEPROM write address 2-3 for int Max
#define addr3 4 // EEPROM write address 4-5 for int Min
#define addr4 6 // EEPROM write address 6-7 for int Avg
int val; // variable for reading the pin status
int sensorState; // variable to hold the sensor state
int sensorActivations = 0; // how many times the sensor has been activated i.e number of times seapost has been used
int seatpostUses; // written value to the EEPROM for seatpost uses.
unsigned long firstCount; // First time stamp when hall effect sensor activated
unsigned long endCount; // End time stamp when hall effect sensor de-activated
unsigned int maxTime; // Max time that sensor has been activated
unsigned int minTime; // Min time that sensor has been activated
unsigned int avgTime; // Avg time that sensor has been activated
unsigned int timeOn; // The amount of time the sensor is activated in milliseconds /10
unsigned int newAverage; // New Avg time computed by program
void setup()
{
pinMode(hallSensor, INPUT); // Set the hall effect sensor pin as input
pinMode(ledPin, OUTPUT); // Set the LED pin as output
Serial.begin(9600); // Set up serial communication at 9600bps for test
Serial.println("Retrieve Data?");
sensorState = digitalRead(hallSensor); // read the initial state
seatpostUses = EEPROM.readInt(addr1); // Read EEPROM to check seatpostUses
if (sensorActivations < seatpostUses) sensorActivations = seatpostUses;
}
void loop()
{
val = digitalRead(hallSensor); // read input value and store it in val
if (val != sensorState)
{ // the button state has changed!
if (val == LOW)
{ // check if the button is pressed
digitalWrite(ledPin, HIGH); // Turn LED On when hall effect sensor keyed
sensorActivations++; // increment the sensorActivations variable
if (sensorActivations > seatpostUses) EEPROM.writeInt(addr1, sensorActivations); // Write to EEPROM if new value is higher than old
Serial.print("Seatpost has been used "); //diagnostic script to check if sensor is reading on serial monitor. will be remarked out later
Serial.print(sensorActivations);
Serial.println(" times");
delay(100); }
else digitalWrite(ledPin, LOW); //Turn LED off
}
{
maxTime = EEPROM.readInt(addr2); // Read from EEPROM
minTime = EEPROM.readInt(addr3); // Read form EEPROM
avgTime = EEPROM.readInt(addr4); // Read from EEPROM
if (val == LOW)
{ // Start counting
firstCount = millis();
}
if (val == HIGH)
{ // End Counting
endCount = millis();
}
{
timeOn = endCount - firstCount / 100;
// Divide milliseconds by 100 to decrease the byte size
if (minTime <= 0){
EEPROM.writeInt(addr3, timeOn);} // Store first reading if EEPROM empty
if (timeOn > maxTime){
EEPROM.writeInt(addr2, timeOn);} // Replace maxTime on EEPROM if exceeded
if (timeOn < minTime){
EEPROM.writeInt(addr3, timeOn);}
} // replace minTime on EEPROM if exceeded
newAverage = (avgTime * (seatpostUses - 1) + timeOn / seatpostUses);
{ // Calculate average seatpost time usage
EEPROM.writeInt(addr4, newAverage);
}
}
sensorState = val; // save the new state in our variable
if (Serial.available()) // Allow data to be transfered via serial
{
char ch = Serial.read();
if (ch == 'r' || ch == 'R');{
retrieveData();}
}
}
void retrieveData() // retrieve program
{
seatpostUses = EEPROM.readInt(addr1); // Read EEPROM
unsigned int rmaxTime = EEPROM.readInt(addr2); // Read EEPROM and multiply by 10 and allow to read as a decimal value
unsigned int rminTime = EEPROM.readInt(addr3);
unsigned int ravgTime = EEPROM.readInt(addr4);
float maxOn = rmaxTime;
float minOn = rminTime;
float avgOn = ravgTime;
Serial.print("Seatpost has been used " );
Serial.print("\t");
Serial.println(seatpostUses);
Serial.print("Seatpost Max time activated ");
Serial.print("\t");
Serial.println(maxOn / 1000); // Hopefully by diving by 1000 I'll get a reading in seconds like 5.689
Serial.print("Seatpost Min time activated ");
Serial.print("\t");
Serial.println(minOn / 1000);
Serial.print("Seatpost Avg activation ");
Serial.println(avgOn / 1000);
}