//
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h> // (rc esc)
#define I2C_ADDR 0x27
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
Servo Servo_Pulse; //create servo object
int n = 1;
const int Throttle_Input_pin = A3; // Throttle input A3
//const int Pot_Input_pin = 6; //Pot input A6
const int Isensor_Input_pin = 6; //Isensor input A6
const int Throttle_Output_pin = 3; //Throttle output D3.. RC filter need is e-bike controller .. no RC filter for rcesc
const int Voltage_Input_Pin = A2; //A2
const int Set_Min_Servo = 950; // esc start with this as min throttle default:1000 (rc esc)
const int Set_Max_Servo = 1500; // esc end with this as max throttle default:1800. Modify to set your maximum assist speed (rc esc)
int Servo_time = 1000; // (rc esc)
long phaseCurrent = 0; // phase current variable;
const int currentGain = 25; // (25 default) proportional gain setting for current limiting
// this value sets how fast the system reacts to throttle input, to high a value causes oscillation around the setpoint,
// so need to be mess around with to optimize , same with phasegain value.
const int phaseGain = 6; // (6 default)proportional gain for phase current limiting
const float Current_pot = 450; // un-rem to use a hard codded current limit ( 0-1023 = 0A upto the value of current sensor)
int Sensor_Cal = 512; // grab real value of this is set in setup section
int throttleCurrent = 0; // throttle setting to achieve current limit
int throttlePhase = 0; // throttle setting to achieve phase current limit
int phaseMax = 0;
int max_throttleOut = 1023;
int Throttle_Value=0;
int Throttle_Pulse=0;
int Set_Throt_Min = 55; // this needs to be the min value to remove dead band from throttle output , around 55
int Set_Throt_Max = 180; // this needs to be the max value to achive full throttle without cutting out , around 180
int Cal_Throt_Min = 176; // this needs to be set to the real value of the throttle when fully closed;
int Cal_Throt_Max = 842; // this needs to be set to the real value of the throttle when fully open;
float SensorRT=1023; // variable to store value of current sensor.
//float Current_pot=0; // variable to store value that sets max current/phase limit. //rem out.. if using hard coded current limits
float Battery_Voltage = 0;
float Battery_Current = 0;
float Power = 0;
float AmpHours = 0;
long previousMillis = 0; //time counter variable
long interval = 1000; //screen update interval in milliseconds
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
void setup()
{
lcd.begin (8,2); // <<----- LCD is 8x2
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
//--- initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// initialize the variables we're linked to
// pinMode(Throttle_Output_pin, OUTPUT); // sets the D3 pin as output // (e-bike)
// analogWrite(Throttle_Output_pin,0); // (e-bike)
Servo_Pulse.attach(3); // Attach Servo_Pulse to pin 3 // (rc esc)
Servo_Pulse.writeMicroseconds(Servo_time); // (rc esc)
delay(1000);
Sensor_Cal = analogRead(Isensor_Input_pin); // grabs offset of current sensor that must be connected at power up or the code will not funtion corectly.
lcd.print("Folken's");
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("EBike V1");
delay(2000);
lcd.print("W V");
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("Ah A");
delay(2000);
}
void loop()
{
// throttle, pot, raw current reading/offsetting
Throttle_Value = analogRead(Throttle_Input_pin);
Throttle_Pulse = constrain(map(Throttle_Value,Cal_Throt_Min,Cal_Throt_Max,0,1023),0,1023); // set range on throttle and zero's throttle value
//Current_pot = constrain(analogRead(Pot_Input_pin),0,1023); // rem out.. if this value is hard coded to speed things up a bit and to free up a adc input
SensorRT = map(analogRead(Isensor_Input_pin)- Sensor_Cal ,0,1023-Sensor_Cal,0,1023);
SensorRT = max(0,SensorRT);
//Current_pot = (Throttle_Pulse*Current_pot)/1023; // use current pot to set overall max power%
phaseMax = Current_pot*2;
Throttle_Pulse=max(Throttle_Pulse,120); // Throttle pulse uses highest value
if (Current_pot < 2) max_throttleOut=0; // stop jitter and reset throttle value
// this routine computes the throttle output required for current control
throttleCurrent = max_throttleOut - currentGain*(SensorRT - Current_pot)/100;
throttleCurrent = max(throttleCurrent,0);
// compute the phase current phase current = shunt current/throttle
phaseCurrent = SensorRT * 1023 /max(max_throttleOut,25); //set last term to be appx 2.5% of throttle max - throttle min
throttlePhase = max_throttleOut - phaseGain*(phaseCurrent - phaseMax)/100;
throttlePhase = max(throttlePhase,0);
throttleCurrent = min(throttleCurrent,throttlePhase); //choose lower of phase or current throttle
max_throttleOut = min(Throttle_Pulse,throttleCurrent); // use the lower of current-limited or user requested throttle value
Throttle_Pulse = map(max_throttleOut,0,1023, Set_Throt_Min, Set_Throt_Max);// scale throttle output limits
//analogWrite(Throttle_Output_pin,Throttle_Pulse); // write throttle to controller // (e-bike)
Servo_time = map(max_throttleOut,0,1023,Set_Min_Servo,Set_Max_Servo); // scale output // (rc esc)
Servo_Pulse.writeMicroseconds(Servo_time); //output servo signal to controller // (rc esc)
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
{
previousMillis = currentMillis;
Battery_Voltage = analogRead(Voltage_Input_Pin)/23.4; //adjust this to get accurate voltage display
Battery_Current = SensorRT/15.2; //adjust this to get accurate current display
Power = Battery_Voltage*Battery_Current;
AmpHours = AmpHours + (Battery_Current*interval/3600000);
// erase previous display
// lcd.setCursor (0,0);
// lcd.print(" ");
// lcd.setCursor (0,1);
// lcd.print(" ");
lcd.setCursor (0,0); // go to start of 1st line
lcd.print(Power);
lcd.setCursor (3,0);
lcd.print(" ");
lcd.setCursor (4,0);
lcd.print(Battery_Voltage);
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print(AmpHours);
lcd.setCursor (3,1);
lcd.print(" ");
lcd.setCursor (4,1);
lcd.print(Battery_Current);
}
delay(100);
// DEBUG! Pick whatever variables you want to see, use the Arduino serial monitor
// to view your values in real time. Tools -> Serial Monitor
//Serial.print(Battery_Voltage);
//Serial.print(throttlePhase);
//Serial.print(" ");
//Serial.print(Throttle_Pulse);
//Serial.print(" ");
//Serial.print(SensorRT);
//Serial.print(" ");
//Serial.print(Current_pot);
//Serial.print(" ");
//Serial.println(max_throttleOut);
}