Hi. I am unsure if this is the correct sub forum to be posting this, as it could be an issue with my programming, or an issue with the arduino. But I have chosen to post here.
I am making a speedometer/odometer, and have buttons that switch between modes. However, I have come around to testing it, and when left for a long time (probably around an hour) the arduino resets itself when I press the button.
The button is connected via an interrupt pin, and there is an LCD screen attached using LiquidCrystal. I am not sure if this is something that is to be expected, or whether I am doing something wrong, or whether the board is doing something wrong.
I will paste in all my code below, in case this is my fault...
float Version = 0.9;
//Settings
int pulsesPerRev = 4;
int pulsesPerRot = 6;
/*Wheel circumference in metres*/
double wheelCircumference = 1.5;
//Libraries
#include <EEPROM.h>
#include <LiquidCrystal.h>
//LCD Pins
#define rs 32
#define enable 33
#define d4 34
#define d5 35
#define d6 36
#define d7 37
//LCD Initialisation
LiquidCrystal lcd(rs,enable,d4,d5,d6,d7);
//Pins
//Digital
#define RPMPin 41
//Analog
#define lambdaPin 0
#define Temp1Pin 1;
#define Temp2Pin 2;
//Interrupts
/*The line from the speedometer should be attached to digital 2.
The line from button 1 should be attached to digital 3.
The line from button 2 should be attached to digital 21. */
//Variables to be loaded from EEPROM
volatile int setting = 0;
volatile int imperialMetric = 0;
/* The total distance travelled in m. */
double TotalDistance = 0;
double TripDistance = 0;
unsigned long TripTime = 0;
unsigned long LoadedTripTime = 0;
//External Settings
#define numberOfSettings 6
#define rpmSample 1000
#define avgLength 8
//External Variables
double speed;
int newDisplay = 456;
volatile int numPulses = 0;
volatile unsigned long pulseDebounce;
volatile unsigned long buttonDebounce;
unsigned long lastSpeedTime;
unsigned long TimeOnReset;
int rpm = 0;
int counter = 0;
int speedArray[avgLength];
unsigned long timer = 0;
int oldButtonPos;
int refresh = 0;
volatile int pressCount = 0;
//Functions
void setup(){
Serial.begin(9600);
//Start LCD
lcd.begin(16,2);
//Setup interrupts.
//Display startup on LCD
lcd.print("Speeduino");
lcd.setCursor(0,1);
lcd.print("Version ");
lcd.print(Version);
delay(2000);
lcd.clear();
pinMode(RPMPin,INPUT);
}
void loop(){
attachInterrupt(0,pulse,RISING);
attachInterrupt(1,button1Press,FALLING);
attachInterrupt(2,button2Press,FALLING);
if (setting == 0) displayODO();
if (setting == 1) displayRPM();
if (setting == 2) displayTripODO();
if (setting == 3) displayTripTIME();
if (setting == 4) displayAvgSPEED();
if (setting == 5) displayTripReset();
if (millis() > timer + 2000){
updateSpeedDist();
updateTripTime();
timer = millis();
}
}
void pulse(){
if (millis()> pulseDebounce + 30) {
numPulses++;
pulseDebounce = millis();
}
Serial.println("We felt a pulse captain!");
}
void button1Press(){
if ((millis()>buttonDebounce+250) || pressCount > 5) {
setting = setting + 1;
if (setting >= numberOfSettings) setting = 0;
buttonDebounce = millis();
pressCount = 0;
}
pressCount++;
Serial.print("Button 1 pressed, Setting = ");
Serial.println(setting);
}
void button2Press(){
if (millis()>buttonDebounce+250) {
imperialMetric++;
imperialMetric = imperialMetric % 2;
buttonDebounce = millis();
newDisplay = 897;
Serial.println("Button 2 Pressed");
}
}
int updateSpeedDist(){
unsigned long newSpeedTime = millis();
double speedMps = (((double)numPulses/(double)pulsesPerRot)*wheelCircumference)/(((double)newSpeedTime - (double)lastSpeedTime)/1000);
speedArray[counter] = speedMps * 2.23693629;
counter++;
counter % avgLength;
for (int i =0; i<avgLength; i++) {
speed += speedArray[i];
}
speed = speed/avgLength;
double newDist = (((double) numPulses/(double)pulsesPerRot)*wheelCircumference);
TotalDistance += newDist;
TripDistance += newDist;
numPulses = 0;
return 1;
}
int updateTripTime(){
TripTime =LoadedTripTime + millis() - TimeOnReset;
return 1;
}
int resetTrip(){
TripDistance = 0;
TripTime = 0;
LoadedTripTime = 0;
TimeOnReset = millis();
return 1;
}
double getTripAverage(){
double avgMPS = TripDistance/((double)TripTime/1000);
return (avgMPS * 2.23693629);
}
int getRPM(){
unsigned long time = millis();
int voltage = 1;
int previousRead = 0;
unsigned long newtime = time;
int revCount = 0;
while (newtime < time + rpmSample){
voltage = digitalRead(RPMPin);
newtime = millis();
if ((voltage==HIGH)&&(previousRead==0)) {
revCount++;
previousRead = 1;
}
else if (voltage == LOW){
previousRead = 0;
}
}
Serial.print(millis());
Serial.print("RPM: ");
Serial.println(revCount);
return (int)((((double)revCount/(double)((double)rpmSample/1000))*60)/(double)pulsesPerRev);
}
int displayODO(){
if ((newDisplay != 0) || refresh > 1000){
lcd.clear();
newDisplay = 0;
refresh = 0;
}
refresh++;
lcd.setCursor(0,0);
if (imperialMetric == 0){
lcd.print("Speed: ");
lcd.print(speed);
lcd.print("mph");
lcd.setCursor(0,1);
lcd.print("Dist: ");
lcd.print((TotalDistance*0.000621371192));
lcd.print("m");
}
if (imperialMetric == 1){
lcd.print("Speed: ");
lcd.print(speed*1.609344);
lcd.print("kph");
lcd.setCursor(0,1);
lcd.print("Dist: ");
lcd.print(TotalDistance*0.001);
lcd.print("km");
}
return 1;
}
int displayRPM(){
if ((newDisplay != 1) || refresh > 10){
lcd.clear();
newDisplay = 1;
refresh = 0;
}
refresh++;
lcd.setCursor(0,0);
if (imperialMetric == 0){
lcd.print("Speed: ");
lcd.print(speed);
lcd.print("mph");
lcd.setCursor(0,1);
lcd.print("RPM: ");
lcd.print(rpm);
}
if (imperialMetric == 1){
lcd.print("Speed: ");
lcd.print(speed*1.609344);
lcd.print("kph");
lcd.setCursor(0,1);
lcd.print("RPM: ");
lcd.print(rpm);
}
rpm = getRPM();
return 1;
}
int displayTripODO(){
if ((newDisplay != 2) || refresh > 1000) {
lcd.clear();
newDisplay = 2;
refresh=0;
}
refresh++;
lcd.setCursor(0,0);
if (imperialMetric == 0){
lcd.print("Speed: ");
lcd.print(speed);
lcd.print("mph");
lcd.setCursor(0,1);
lcd.print("T Dist: ");
lcd.print(TripDistance*0.000621371192);
lcd.print("M");
}
if (imperialMetric == 1){
lcd.print("Speed: ");
lcd.print(speed*1.609344);
lcd.print("kph");
lcd.setCursor(0,1);
lcd.print("T Dist: ");
lcd.print(TripDistance*0.001);
lcd.print("km");
}
return 1;
}
int displayTripTIME(){
if ((newDisplay != 3) || refresh > 1000){
newDisplay = 3;
lcd.clear();
refresh = 0;
}
refresh++;
lcd.setCursor(0,0);
if (imperialMetric == 0){
lcd.print("Speed: ");
lcd.print(speed);
lcd.print("mph");
}
if (imperialMetric == 1){
lcd.print("Speed: ");
lcd.print(speed*1.609344);
lcd.print("kph");
}
lcd.setCursor(0,1);
lcd.print("T Time: ");
lcd.print((((TripTime/1000)/60)/60));
lcd.print(":");
int minutes = ((TripTime/1000)/60)%60 ;
if (minutes < 10) lcd.print("0");
lcd.print(minutes);
lcd.print(":");
int seconds = (TripTime/1000) % 60;
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
return 1;
}
int displayAvgSPEED(){
if ((newDisplay != 4) || refresh > 1000) {
newDisplay = 4;
lcd.clear();
refresh = 0;
}
refresh++;
double avg = getTripAverage();
lcd.setCursor(0,0);
if (imperialMetric == 0){
lcd.print("Speed: ");
lcd.print(speed);
lcd.print("mph");
lcd.setCursor(0,1);
lcd.print("Av Spd: ");
lcd.print(avg);
lcd.print("mph");
}
if (imperialMetric == 1){
lcd.print("Speed: ");
lcd.print(speed*1.609344);
lcd.print("kph");
lcd.setCursor(0,1);
lcd.print("Av Spd: ");
lcd.print(avg*1.609344);
lcd.print("kph");
}
return 1;
}
int displayTripReset(){
if (newDisplay != 5) {
newDisplay = 5;
lcd.clear();
oldButtonPos = imperialMetric;
}
lcd.setCursor(0,0);
lcd.print("To reset trip,");
lcd.setCursor(0,1);
lcd.print("press button 2");
if (imperialMetric != oldButtonPos) {
resetTrip();
imperialMetric = oldButtonPos;
lcd.clear();
lcd.print("Trip Reset");
delay(1000);
setting = 0;
}
}