#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define TPSpin A0
#define MPHpin A1
#define Apin 10
#define Bpin 9
#define Lpin 6
#define Ppin 5
#define LOTpin A2
#define WOTpin A3
const float DownShiftSlack = 0.8; // difference between upshift and downshift MPH
const int ShiftPoint = 30; // low throttle 3>4 shift
const float GearSpread = 4.0; // (GearSpread)*(ShiftPoint)=theoretical MAX MPH in 3rd
const int ConvSlip = 15; // 1st gear WOT converter slip (new MPH = theoretic - ConvSlip%)
const int WOTthresh = 80; // WOT threshhold for 1-2 shift
const int LockDelay = 5; // MPH adder for lockup after 4th
const int LineMinPres = 30; // idle line duty
const int LineMaxTPS = 50; // max TPS for line reduction
int TPS;
int MPH;
int Gear = 1;
int Lock = 0;
int Line = 0;
int TPSmin = 200; // selfcal TPS
int TPSmax = 800; // selfcal TPS
int LOToffset; // dynamic low throttle shift
int WOToffset; // dynamic WOT shift
float GearRatio[5] {0, 3.06, 1.63, 1.00, 0.70};
void printxy (int value, int x, int y) {
lcd.setCursor(x, y);
lcd.print(value);
if (value < 100) lcd.print(" ");
if (value < 10) lcd.print(" ");
}
void printxyS (int value, int x, int y) {
lcd.setCursor(x, y);
lcd.print(value);
}
int ScaleTPS (int TPSraw) {
if (TPSraw < TPSmin) TPSmin = TPSraw;
if (TPSraw > TPSmax) TPSmax = TPSraw;
return map(TPSraw, TPSmin, TPSmax, 0, 100);
}
void GearSol() {
if (Gear == 1) {
digitalWrite(Apin, HIGH);
digitalWrite(Bpin, HIGH);
}
if (Gear == 2) {
digitalWrite(Apin, LOW);
digitalWrite(Bpin, HIGH);
}
if (Gear == 3) {
digitalWrite(Apin, LOW);
digitalWrite(Bpin, LOW);
}
if (Gear == 4) {
digitalWrite(Apin, HIGH);
digitalWrite(Bpin, LOW);
}
}
int ArrayMPH (int WhatGear) {
float GearOffset = 1 / GearRatio[WhatGear];
int GearLow = ShiftPoint * GearOffset * LOToffset / 100; //always devide last in int calc
int GearHigh = ShiftPoint * GearOffset * WOToffset * GearSpread / 100;
if (TPS<15) return GearLow;
if (TPS>85) return GearHigh;
return map(TPS, 15, 85, GearLow, GearHigh);
}
void GearSelector () {
if (Gear == 4 && MPH < ArrayMPH(3)*DownShiftSlack) Gear = 3;
if (Gear == 3 && MPH < ArrayMPH(2)*DownShiftSlack) Gear = 2;
if (Gear == 2 && MPH < ArrayMPH(1)*DownShiftSlack) Gear = 1;
if (Gear == 1 && TPS > WOTthresh && MPH > ArrayMPH(1)*(100-ConvSlip)/100 )
Gear = 2;
else
if (Gear == 1 && MPH > ArrayMPH(1) ) Gear = 2;
if (Gear == 2 && MPH > ArrayMPH(2) ) Gear = 3;
if (Gear == 3 && MPH > ArrayMPH(3) ) Gear = 4;
}
void LockUpSelector () {
if (Gear == 4) {
if (MPH > (ArrayMPH(3) + LockDelay)) Lock = 1;
if (MPH < (ArrayMPH(3)*DownShiftSlack + LockDelay)) Lock = 0;
}
else Lock = 0;
}
void LockUpSol (){
if (Lock == 1) digitalWrite(Lpin, HIGH);
else digitalWrite(Lpin, LOW);
}
void LineSelector () {
if (TPS > LineMaxTPS) Line=0;
else Line=LineMinPres - map(TPS, 0, LineMaxTPS, 0, LineMinPres);
}
void LineSol () {
analogWrite(Ppin, Line);
}
void setup()
{
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("T=");
lcd.setCursor(0,1);
lcd.print("M=");
lcd.setCursor(5, 0);
lcd.print("G=");
lcd.setCursor(11, 0);
lcd.print("Ln=");
lcd.setCursor(5, 1);
lcd.print("L=");
lcd.setCursor(11, 1);
lcd.print("H=");
pinMode(Apin, OUTPUT);
pinMode(Bpin, OUTPUT);
pinMode(Lpin, OUTPUT);
pinMode(Ppin, OUTPUT);
pinMode(TPSpin, INPUT_PULLUP);
pinMode(MPHpin, INPUT_PULLUP);
pinMode(LOTpin, INPUT_PULLUP);
pinMode(WOTpin, INPUT_PULLUP);
}
void loop()
{
TPS = ScaleTPS(analogRead(TPSpin));
MPH = analogRead(MPHpin)/6.6;
LOToffset = map(analogRead(LOTpin), 0, 1023, 50, 150) ;
WOToffset = map(analogRead(WOTpin), 0, 1023, 50, 150);
GearSelector ();
LockUpSelector ();
LineSelector ();
GearSol();
LockUpSol();
LineSol();
printxy (TPS, 2, 0);
printxy (MPH, 2, 1);
printxyS(Lock, 9,0);
printxyS(Gear, 7, 0);
printxy (Line, 14, 0);
printxy (LOToffset, 7, 1);
printxy (WOToffset, 13, 1);
}