//=======================================================
//
// 2 track vehicle controller
//
// by DedGzus
// Started on 01/27/2024 right after the Royal Rumble
//=======================================================
// libraries
#include "ProcessManager.h"
// input pin definitions
#define LThrottlePin A0
#define RThrottlePin A1
#define ThrottleGainPin A2
// led pin definitions
#define LThrottleFwdPin 2
#define LThrottleIdlePin 3
#define LThrottleRevPin 4
#define RThrottleFwdPin 5
#define RThrottleIdlePin 6
#define RThrottleRevPin 7
// constants
#define ThrottleMid 512
#define IdleGap 64
// process manager ptr
ProcessManager* pManager;
// global read variables
volatile unsigned short leftThrottleRead;
volatile unsigned short rightThrottleRead;
volatile unsigned short throttleGainRead;
void setup()
{
// set LED pins for output
pinMode(LThrottleFwdPin, OUTPUT);
pinMode(LThrottleIdlePin, OUTPUT);
pinMode(LThrottleRevPin, OUTPUT);
pinMode(RThrottleFwdPin, OUTPUT);
pinMode(RThrottleIdlePin, OUTPUT);
pinMode(RThrottleRevPin, OUTPUT);
// acquire the process manager
pManager = new ProcessManager();
// attach the read processes
pManager->attach( new analogReadProcess(LThrottlePin, &leftThrottleRead));
pManager->attach( new analogReadProcess(RThrottlePin, &rightThrottleRead));
pManager->attach( new analogReadProcess(ThrottleGainPin, &throttleGainRead));
// Serial.begin(9600);
}
void loop()
{
static byte LThrottleFwdLED(LOW);
static byte LThrottleIdleLED(LOW);
static byte LThrottleRevLED(LOW);
static byte RThrottleFwdLED(LOW);
static byte RThrottleIdleLED(LOW);
static byte RThrottleRevLED(LOW);
// run the process manager
pManager->onLoop();
signed short mappedLThrottle = mapThrottle(leftThrottleRead);
signed short mappedRThrottle = mapThrottle(rightThrottleRead);
float gain(float(map(throttleGainRead, 0, 1023, 0, 1000)) / 1000);
// set left throttle LED
if (mappedLThrottle > 0)
{
LThrottleFwdLED = HIGH;
LThrottleIdleLED = LOW;
LThrottleRevLED = LOW;
}
else if (mappedLThrottle < 0)
{
LThrottleFwdLED = LOW;
LThrottleIdleLED = LOW;
LThrottleRevLED = HIGH;
}
else
{
LThrottleFwdLED = LOW;
LThrottleIdleLED = HIGH;
LThrottleRevLED = LOW;
}
// set right throttle LED
if (mappedRThrottle > 0)
{
RThrottleFwdLED = HIGH;
RThrottleIdleLED = LOW;
RThrottleRevLED = LOW;
}
else if (mappedRThrottle < 0)
{
RThrottleFwdLED = LOW;
RThrottleIdleLED = LOW;
RThrottleRevLED = HIGH;
}
else
{
RThrottleFwdLED = LOW;
RThrottleIdleLED = HIGH;
RThrottleRevLED = LOW;
}
// write to all LEDs
digitalWrite(LThrottleFwdPin, LThrottleFwdLED);
digitalWrite(LThrottleIdlePin, LThrottleIdleLED);
digitalWrite(LThrottleRevPin, LThrottleRevLED);
digitalWrite(RThrottleFwdPin, RThrottleFwdLED);
digitalWrite(RThrottleIdlePin, RThrottleIdleLED);
digitalWrite(RThrottleRevPin, RThrottleRevLED);
// for debugging
/* Serial.print("Left[");
Serial.print(mappedLThrottle * gain);
Serial.print("%] Right[");
Serial.print(mappedRThrottle * gain);
Serial.print("%] Gain Coefficient[");
Serial.print(gain);
Serial.println("]");*/
}
signed short mapThrottle(const int throttle)
{
// negative throttle
if (throttle < ThrottleMid - IdleGap)
{
return map(throttle, 0, (ThrottleMid - IdleGap), -100, 1);
}
// positive throttle
else if (throttle > ThrottleMid + IdleGap)
{
return map(throttle, (ThrottleMid + IdleGap), 1023, 1, 100);
}
// throttle within idle gap
return 0;
}