Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * ##############################
- * ####### E-BIKE PROJECT #######
- * ##############################
- *
- * Author : J
- * Date : June - July 2020
- * Updated : August 2021
- *
- * Version : 1.1
- *
- * For Arduino Nano
- *
- * ##############################
- */
- #include <SPI.h>
- #include <RFID.h>
- #include <EEPROM.h> //only for debugging
- //definition of pins for Arduino Nano
- #define SS_PIN 10
- #define RST_PIN 9
- //variables for inputs and outputs
- const byte BUZZER = 2, //Alarm buzzer
- RELAY = 3, //Main relay
- LIMIT_SPD = 4, //Speed limiter (/!\ mandatory in CH /!\)
- THROTTLE_BT = 6, //Throttle button input
- TRIAC_CTRL = A1, //Triac for the LED lamps
- BT_VOLTAGE = A6, //Voltage of the power button
- RELAY_VOLTAGE = A5, //Voltage of the battery
- THERMISTOR = A4; //Temperature sensor
- const byte BIN_THROTTLE[4] = {A0, 5, 7, 8};
- //customizable settings (can be modified according to your preferences)
- const byte MAIN_BADGE[5] = {0, 0, 0, 0, 0};
- const byte BACKUP_BADGE[5] = {0, 0, 0, 0, 0};
- boolean BIN_THROTTLE_MAX[4] = {true, true, false, false}; //max value to ESC
- boolean BIN_THROTTLE_MIN[4] = {false, false, true, true}; //min value to ESC
- const int MAX_TEMP = 796; //max value for the thermistor security (default 796 = 60°C)
- const int LOW_VOLT_1 = 651; //low voltage : step 1 (default 651 = 35V)
- const int LOW_VOLT_2 = 614; //low voltage : step 2 (default 614 = 33V)
- const int LOW_VOLT_3 = 578; //low voltage : step 3 (default 578 = 31V)
- const int LOW_VOLT_X = 520; //extremely low voltage, immediate power off (default 520 = 28V)
- const byte MAX_TIME_REBOOT = 60; //max time (in seconds) for a reboot without the need of the RFID card (default 60)
- //system variables (do not modify them)
- byte cur_badge[5];
- byte num_badge = 0; //0 for incorrect card, 1 if main card, 2 if backup card
- boolean locked = true;
- boolean acceleration = true; //slows down throttle acceleration
- boolean bin_throttle[4] = {false, false, true, true}; //value sent to ESC
- int voltage = -1;
- int count_voltage = 5;
- int count_shutdown = 0;
- int battery_discharge = 0; //battery discharge state
- int count_throttle = 1;
- RFID rfid(SS_PIN, RST_PIN);
- void setup()
- {
- //Serial.begin(9600); //only for debugging : Serial.println("")
- SPI.begin();
- rfid.init();
- //definition of all pinModes (I/O)
- pinMode(BUZZER, OUTPUT);
- pinMode(RELAY, OUTPUT);
- pinMode(LIMIT_SPD, OUTPUT);
- pinMode(THROTTLE_BT, INPUT_PULLUP);
- pinMode(TRIAC_CTRL, OUTPUT);
- pinMode(BT_VOLTAGE, INPUT); //analog
- pinMode(RELAY_VOLTAGE, INPUT); //analog
- for(byte i = 0; i < 4; i++)
- {
- pinMode(BIN_THROTTLE[i], OUTPUT);
- digitalWrite(BIN_THROTTLE[i], LOW);
- }
- //sets the outputs to initial state
- digitalWrite(RELAY, LOW);
- digitalWrite(LIMIT_SPD, HIGH);
- digitalWrite(TRIAC_CTRL, LOW);
- }
- void loop()
- {
- /*
- * Bike is locked
- */
- while(locked)
- {
- if (rfid.isCard()) { //unlocking
- if(readRFID() && (num_badge == 1 || num_badge == 2)) {
- buzzer(true);
- if(num_badge == 2 || digitalRead(THROTTLE_BT) == LOW) digitalWrite(LIMIT_SPD, LOW);
- digitalWrite(RELAY, HIGH);
- throttleReset();
- delay(100);
- voltage = analogRead(RELAY_VOLTAGE);
- for(byte i = 0; i < 20; i++) {
- if(analogRead(BT_VOLTAGE) < 102) { //executed once, despite being in a for loop
- digitalWrite(TRIAC_CTRL, HIGH);
- delay(100);
- digitalWrite(TRIAC_CTRL, LOW);
- locked = false;
- i = 20;
- }
- //security : user forgot to put the power switch in the initial position
- if(i == 19) {
- digitalWrite(RELAY, LOW);
- while(true) {
- buzzer(false);
- locked = true;
- }
- }
- delay(500);
- }
- } else {
- buzzer(false);
- }
- }
- delay(100);
- }
- /*
- * Bike is unlocked
- */
- while(!locked)
- {
- if(count_voltage == 25) {
- count_voltage = 0;
- ctrlBattery();
- ctrlTemp();
- } else {
- count_voltage++;
- }
- ctrlShutdown();
- ctrlThrottle();
- delay(250);
- }
- }
- /*
- * Compares card to registered cards
- */
- boolean compareBadge()
- {
- if(
- MAIN_BADGE[0] == cur_badge[0] &&
- MAIN_BADGE[1] == cur_badge[1] &&
- MAIN_BADGE[2] == cur_badge[2] &&
- MAIN_BADGE[3] == cur_badge[3] &&
- MAIN_BADGE[4] == cur_badge[4] )
- {
- num_badge = 1;
- return true;
- }
- if(
- BACKUP_BADGE[0] == cur_badge[0] &&
- BACKUP_BADGE[1] == cur_badge[1] &&
- BACKUP_BADGE[2] == cur_badge[2] &&
- BACKUP_BADGE[3] == cur_badge[3] &&
- BACKUP_BADGE[4] == cur_badge[4] )
- {
- num_badge = 2;
- return true;
- }
- return false;
- }
- /*
- * Reads RFID card and compares it to registred cards
- */
- boolean readRFID()
- {
- if (rfid.readCardSerial()) {
- for(byte i = 0; i < 5; i++) {
- cur_badge[i] = rfid.serNum[i]; //copy of the 5 bytes of the card in cur_badge
- }
- rfid.halt();
- return compareBadge();
- }
- rfid.halt();
- }
- /*
- * Activates the buzzer (true = OK ; false = alarm)
- */
- void buzzer(boolean noise)
- {
- if(noise) {
- tone(BUZZER, 523, 50);
- delay(50);
- tone(BUZZER, 783, 50);
- delay(50);
- tone(BUZZER, 1046, 50);
- delay(50);
- tone(BUZZER, 1568, 50);
- delay(50);
- tone(BUZZER, 2093, 70);
- delay(250);
- } else {
- tone(BUZZER, 370, 50);
- delay(100);
- tone(BUZZER, 370, 300);
- delay(1000);
- }
- }
- /*
- * Resets the throttle output
- */
- void throttleReset()
- {
- printThrottle(BIN_THROTTLE_MIN);
- }
- /*
- * Updates the trottle output depending on the button input
- * TODO : use an enum for count_throttle
- */
- void ctrlThrottle()
- {
- if(digitalRead(THROTTLE_BT) == LOW) { //throttle button pressed
- if(count_throttle == 1 || count_throttle == 0) { // if 1 : stopped, if 0 : accelerating
- if(acceleration) { // waits
- for(int i = 3; i >= 0; i--) { // adds 1 to binary throttle array
- bin_throttle[i] = !bin_throttle[i];
- if(bin_throttle[i]) {
- i = -1;
- }
- }
- if(count_throttle == 1) {
- count_throttle = 0;
- }
- if(bin_throttle[0] == BIN_THROTTLE_MAX[0] && // throttle max (= 2)
- bin_throttle[1] == BIN_THROTTLE_MAX[1] &&
- bin_throttle[2] == BIN_THROTTLE_MAX[2] &&
- bin_throttle[3] == BIN_THROTTLE_MAX[3])
- {
- count_throttle = 2;
- }
- }
- acceleration = !acceleration;
- }
- if(count_throttle < 0 && count_throttle >= -5) { // if 2 : stable throttle output (no acceleration)
- count_throttle = 2;
- }
- printThrottle(bin_throttle);
- } else { //throttle button not pressed
- if(count_throttle != 1) {
- throttleReset();
- }
- if(count_throttle < 1 && count_throttle > -5) { // waiting time, from 0 to -5 (1.25 seconds)
- count_throttle--;
- } else if(count_throttle == -5 || count_throttle == 2) { // end of waiting time, throttle completely released
- count_throttle = 1;
- for(int i = 0; i < 4; i++) {
- bin_throttle[i] = BIN_THROTTLE_MIN[i];
- }
- }
- }
- }
- /*
- * Outputs the given value on the throttle output
- */
- void printThrottle(boolean throttle[4])
- {
- for(int i = 0; i < 4; i++) {
- digitalWrite(BIN_THROTTLE[i], throttle[i]);
- }
- }
- /*
- * Controls the battery voltage
- */
- void ctrlBattery()
- {
- voltage = analogRead(RELAY_VOLTAGE);
- //Extremely low voltage security (<28V)
- if(voltage < LOW_VOLT_X) {
- digitalWrite(RELAY, LOW);
- buzzer(false);
- }
- //Low voltage security (steps at 35V, 33V and 31V)
- if(voltage < LOW_VOLT_1 && battery_discharge < 2) {
- battery_discharge++;
- if(battery_discharge == 2) {
- buzzer(false);
- }
- }
- if(voltage < LOW_VOLT_2 && battery_discharge > 1 && battery_discharge < 4) {
- battery_discharge++;
- if(battery_discharge == 4) {
- buzzer(false);
- }
- }
- if(voltage < LOW_VOLT_3 && battery_discharge > 3) {
- battery_discharge++;
- if(battery_discharge >= 6) {
- buzzer(false);
- digitalWrite(RELAY, LOW);
- buzzer(false);
- }
- }
- }
- /**
- * Shutdown system if the power button is pressed
- */
- void ctrlShutdown()
- {
- if(analogRead(BT_VOLTAGE) > 102) {
- count_shutdown++;
- if (count_shutdown == 4) {
- buzzer(false);
- digitalWrite(RELAY, LOW);
- delay(2000);
- eventualReboot();
- }
- } else if(count_shutdown != 0) {
- count_shutdown = 0;
- }
- }
- /**
- * To be called after shutdown, reboot without security if triggered less than 1 min after shutdown
- */
- void eventualReboot()
- {
- byte buttonPressed = 0;
- boolean inLoop = true;
- for(byte i = 0; i < MAX_TIME_REBOOT; i++) {
- delay(1000);
- if(i % 10 == 0) buzzer(false);
- if(digitalRead(THROTTLE_BT) == LOW) {
- buttonPressed++;
- if(buttonPressed >= 5) { //Reboot
- digitalWrite(LIMIT_SPD, HIGH);
- throttleReset();
- buzzer(true);
- count_shutdown = 0;
- count_throttle = 1;
- digitalWrite(RELAY, HIGH);
- inLoop = false;
- i = MAX_TIME_REBOOT + 1;
- }
- } else if(buttonPressed != 0) {
- buttonPressed = 0;
- }
- }
- while(inLoop) { //Time out : reboot impossible
- buzzer(false);
- delay(10000);
- }
- }
- /*
- * Controls the temperature of the battery and the electronics (shutdown if > 60°C)
- */
- void ctrlTemp()
- {
- if(analogRead(THERMISTOR) >= MAX_TEMP) {
- buzzer(false);
- digitalWrite(RELAY, LOW);
- }
- }
Add Comment
Please, Sign In to add comment