I have completed a functional sketch for my cruise project. I have extensive bench testing and it works very well. I would like to get some feedback on any improvements I might be able to make or ways to shrink the file down. I have a attach interrupt function and another function to average data gathered from the attach interrupt. This has been quite a challenge for me to get working so I don’t know if it was the best way to go about it. I have put notes on everything to try and explain what the program is doing. I will place the rest of the code in a second posting
#include <Bounce.h>
#define interval 500
#define interval2 1500
#include <Servo.h>
/////////void averageMilliTick() and hallSensTicks()//Variables///misc timer variables///////
const int numberOfEntries = 16; //16 millis (magnet readings) = 10 feet and .228576 seconds @ 30 MPH//
unsigned int results[numberOfEntries];
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis2 = 0;
unsigned long currentMillis2 = 0;
volatile int total = 0;
volatile unsigned long lastTime = 0;
volatile byte index = 0;
int average = 0;
int averageOld = 0;
int newAverage = 0;
////////////////////////////////////////////////////////
//////////////////servo settings/////////////////////////////////////////
Servo throttleServo; // Define throttle Servo
int servoPos = 30; // Initial power up “servo position”
int moveServoAmount = 1; // move the servo 1 degrees per 1/125 pulse
int moveServoAmount2 = 3; // move the servo 3 degrees per 1/125 pulse
/////////////////////////////////////////////////////////////////////////
///////////////////////Throttle settings////////////////////////////////
const int pin_ThrottleUp = 4;
const int pin_ThrottleDn = A2; // pin 14
unsigned char encoder_ThrottleUp;
unsigned char encoder_ThrottleDn;
unsigned char encoder_ThrottleUp_prev=0;
////////////////////////////////////////////////////////////////////////
///////////////Buttons settings/////////////////////////////////////////
const int speedUpPin = 11; // the number of the pushbutton pin
const int speedDnPin = 10;
const int clutchPin = 8;
const int brakePin = 9;
unsigned long startPress=0;
int buttonState1 = 0;
int buttonState2 = 0;
////////////////////////////////////////////////////////////////////////
//Debounce objects
// Instantiate a Bounce object with a 10 millisecond debounce time
long debounceDelay = 20;
Bounce cruiseUp = Bounce(speedUpPin, debounceDelay);
Bounce cruiseDn = Bounce(speedDnPin, debounceDelay);
Bounce brakeReleaseToThrottle = Bounce(brakePin, debounceDelay);
Bounce clutchReleaseToThrottle = Bounce(clutchPin, debounceDelay);
void setup(){
Serial.begin(9600);
throttleServo.attach(12); // servo on digital pin 12
throttleServo.write(30);//set initial throttle position to 30 degree//
pinMode(pin_ThrottleUp, INPUT_PULLUP);//initialize throttle encoder//
pinMode(pin_ThrottleDn, INPUT_PULLUP);//initialize throttle encoder//
// initialize the pushbutton pin as an input:
pinMode(speedUpPin, INPUT_PULLUP);//initialize button//
pinMode(speedDnPin, INPUT_PULLUP);//initialize button//
pinMode(clutchPin, INPUT_PULLUP);//initialize button//
pinMode(brakePin, INPUT_PULLUP);//initialize button//
attachInterrupt(1, hallSensTicks, RISING);//attach interrupt to read hall sensor at rear wheel//
}
[code]void loop(){
cruiseUp.update();//update bounce on cruise up button//
cruiseDn.update();//update bounce on cruise down button//
encoder_ThrottleUp = digitalRead(pin_ThrottleUp);//read throttle encoder going up//
encoder_ThrottleDn = digitalRead(pin_ThrottleDn);//read throttle encoder going down//
if (encoder_ThrottleUp != encoder_ThrottleUp_prev){
if (encoder_ThrottleUp == encoder_ThrottleDn){ //if encoder is read going Up, adjust throtte. two steps for progressive throttle//
if(servoPos + moveServoAmount <= 90) servoPos += moveServoAmount; // advance throttle by 1 position if less than 90 degree
else{
if(servoPos + moveServoAmount >= 91 && servoPos + moveServoAmount < 200) servoPos += moveServoAmount2;// advance throttle by 3 position if > 90 or < 200 degree
}
}
else { //if encoder is read going down, adjust throtte. two steps for progressive throttle//
if(servoPos - moveServoAmount >= 91) servoPos -= moveServoAmount2; // retard throttle by 1 position if less than 90 degree
else{
if(servoPos - moveServoAmount <= 90 && servoPos - moveServoAmount >= 20) servoPos -= moveServoAmount;// retard throttle by 3 position if > 90 or < 200 degree
}
}
}
encoder_ThrottleUp_prev = encoder_ThrottleUp;
throttleServo.write(servoPos); //write updated throttle position//
averageMilliTick();//call to function averageMilliTick() to get average millis count between every
//10 readings off the back wheel 10 magnets on the wheel = 1 rotation//
if ((cruiseUp.read() == HIGH) || (cruiseDn.read() == HIGH))//start of cruise control mode//
{
averageMilliTick();//call to function averageMilliTick() to get average millis count between every
//10 readings off the back wheel 10 magnets on the wheel = 1 rotation//
averageOld = average; //set averageOld = to average before entering the button enabled mode//
int ButtonModeEnabled = 1;
if (ButtonModeEnabled == 1)//set button mode to yes locks throttle position and disengages throttle encoder//
while (ButtonModeEnabled == 1){//while in button mode//
cruiseUp.update();//update the status of the cruise up button//
cruiseDn.update();//update the status of the cruise down button//
brakeReleaseToThrottle.update();//update the status of the brake button//
clutchReleaseToThrottle.update();//update the status of the clutch button//
averageMilliTick(); //call to function averageMilliTick() to get average millis count between every
//10 readings off the back wheel 10 magnets on the wheel = 1 rotation//
unsigned long currentMillis = millis();//timer delay to allow program to keep looping but count before continuing//
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;//set currentMillis2 for next pass thru//
if (buttonState1 == 1){
newAverage = average;//set newAverage to match average for refference comparison later//
buttonState1 = 0;
}
if (buttonState2 == 1){
newAverage = average;//set newAverage to match average for refference comparison later//
buttonState2 = 0;
}
if (newAverage != average){//start of comparison of newAverage to average to adjust throttle position to adjust for speed gain or loss//
if (average - newAverage > 2){//if speed has advanced then retard the throttle by 1 position//
throttleServo.write(servoPos -= 1);
}
if (newAverage - average > 2){//if speed has declined then advance the throttle by 1 position//
throttleServo.write(servoPos += 1);
}
unsigned long currentMillis2 = millis();//sets second, longer timer delay to let speed adjust before comparing and making adjustments again//
if(currentMillis2 - previousMillis2 > interval2) {
if (newAverage != average){//start of comparison of newAverage to average to adjust throttle position to adjust for speed gain or loss//
previousMillis2 = currentMillis2;//set currentMillis2 for next pass thru//
if (average - newAverage > 2){//if speed has advanced then retard the throttle by 1 position//
throttleServo.write(servoPos -= 1);
}
if (newAverage- average > 2){//if speed has declined then advance the throttle by 1 position//
throttleServo.write(servoPos += 1);
}
}
}
}
}
//if cruise decrease throttle goes high write -1 to servo//
if (cruiseUp.read() == HIGH)
{
buttonState1 = 1;
throttleServo.write(servoPos += 1); //Add 2 degrees to servo position for increased motor rpm//
servoPos = throttleServo.read();
delay(100);
}
//if cruise increase throttle goes high write +1 to servo//
if (cruiseDn.read() == HIGH)
{
buttonState2 = 1;
throttleServo.write(servoPos -= 1); //Add 2 degrees to servo position for increased motor rpm
servoPos = throttleServo.read();
delay(100);
}
//if clutch or brake lever is pulled the relay is trigered and timer starts to release control to throttle encoder//
else if ((clutchReleaseToThrottle.read() == LOW) & (brakeReleaseToThrottle.read() == LOW))
{
startPress = 0;
}
else if (startPress == 0){//start millis count once clutch or brake relays are read high//
startPress = millis();
}
//if millis is greater than 200 this will release control back to the throttle encoder. button must be held for more than .2 seconds/
//this eliminates button bounce on the relays//
else if (millis() - startPress > 200)
{
servoPos = 30;
ButtonModeEnabled = 0; //Set loop exit condition
}
}
}
}
//function to call total from hallSenseTicks attachinterrupt and averag the total millis count//
void averageMilliTick(){
if(index >= numberOfEntries){
for(byte i=0; i < numberOfEntries; i++){
average = total / numberOfEntries;//I can not say that I understand why i need this part but i know that it works//
}
total = 0;//reset total to 0 for next 16 entry calculation
index = 0;//reset index to 0 for next 16 entry calculation
memset (results, 0, sizeof(results));//reset array for next set of numbers//
}
}
//Hall Sensor interrupt//loads 16 millis readings into Array and totals the array//
void hallSensTicks(){
if (index < numberOfEntries){//if index (16) is not full then add to index
if (index>0); //skip Number one to avoid non movement time//
{
results[index] = millis() - lastTime;//logging elapsed time between hall sensor rising states//
total += results[index];//totaling the 16 readings//
}
index ++;
}
lastTime = millis();//set millis count for next time thru the attachinterrupt loop//
}
[/code]
void hallSensTicks()
{
if (index < numberOfEntries)
{
if (index>0); // NOTE: PROBABLY NOT WHAT YOU WANTED!!!
and this is silly:
int ButtonModeEnabled = 1;
if (ButtonModeEnabled == 1)
ButtonModeEnabled can't be anything but 1 when the "if" statement is executed, so the "if" is redundant.
Pete