diff --git a/LeonardoProMicro/SimplyAutomatedGearShifter/SimplyAutomatedGearShifter.ino b/LeonardoProMicro/SimplyAutomatedGearShifter/SimplyAutomatedGearShifter.ino new file mode 100644 index 0000000..23e3b1c --- /dev/null +++ b/LeonardoProMicro/SimplyAutomatedGearShifter/SimplyAutomatedGearShifter.ino @@ -0,0 +1,406 @@ + #include +#include // model servo: DS3218 PRO +#include +#include +#include +#include +#include + +#define Version "0.0" +////2DO: +//diagnostyka i/lub przeciwdziałanie skokom predkosci +//dlaczego wskaznik odnosi sie do poprawnego biegu a w tym czasie bieg jest zly? bo czas ponizej 2s? +//zmienic system usypiania dodac bezwzglednie czas 3 min, i po czeku z przyciskiem ponowny odczyt magnesu po 0,5sec + +// menu do zmiany zakresu predkosci biegów +// menu do zmiany zakresu kątów biegów, obwodu koła, ilosci magnesow + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) +#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); +#define PinInterrupt 0 //on board: RX deklaracja pod stabilizacje TX +#define PinInSpeed 1 //on board: TX +#define ServoSwitch 4 //on board: 4 +#define ServoPin 8 //on board: 8 +#define BrakingLight 9 //on board: 9 BrakingLight +#define PinLED 10 //on board: 10 ORANGE loop signal +#define Btn1 18 //on board: A0 Button1 +#define VoltInptPin 19 //on board: A1 Battery Voltage + +#define ServoMaxAngle 130 +#define MaxAngle 179 +#define MinAngle 1 +#define MaxGear 8 +#define MinGear 1 +#define WheelCircumference 2.130 +#define MagnetsCnt 8 +#define ms2kmh 3.6 +#define Pi 3.1416 +#define TimeToSleep 5000 //5 sec +#define LongTimeToSleep 150000 //150 sec + +Servo myservo; + + +//SPEED +double speed = 0; +double speed_last = 0.0; +double speed_last_2 = 0.0; +double speed_last_3 = 0.0; +int speedTrend = 0; +double sigleTimeSpd = 0.0; +double sleepSpd = 0.0; +unsigned long millissSpd = millis(); +unsigned long lastMillisSpd = millis(); +unsigned long lastLastMillisSpd = millis(); +unsigned long loopTime = millis(); +//speed validation +double speed4Gear = 0.0; +double speed4Gear_1 = 0.0; +double speed4Gear_2 = 0.0; +double speed4Gear_3 = 0.0; +double speed4Geat_estimated = 0.0; +double speedDiff_1 = 0.0; +double speedDiff_2 = 0.0; +double speedDiff_3 = 0.0; +int avgWeight_2 = 2; +int avgWeight_3 = 1; +//GEAR +int currentGear = 1; +int previousGear = 1; +int calculatedGear = 1; +//Przedziały dia biegów +float spdRange1and2 = 7.5; +float spdRange2and3 = 11.0; +float spdRange3and4 = 15.5; +float spdRange4and5 = 18.0; +float spdRange5and6 = 24.5; +float spdRange6and7 = 29.9; +float spdRange7and8 = 36.5; +double calcTimeDiff = 0.0; +double lastGearCalc = millis(); +double changeDelayMs = 2000.0; +double accelerationShift = 1.0; +int displGear = 9 - currentGear; +float currentGearRangeLower = 0; +float currentGearRangeMiddle = 3.0; +float currentGearRangeUpper = 7.5; +//SERVO +int pos = 0; +int sleepMode = 0; +int servoCurrPos = ServoMaxAngle; +//GearBar +int gearBarHeight = 0; +int gearBarPosition = 0; +float speedForBar = 0; +//DST +int totalDistMemLocation = 60; +int loop_cnt = 0; +double totalDist = 0.0; +unsigned int totalDistReaded = 0; +unsigned int totalDistWrited = 0; +//BATTERY +float referenceVoltage = 5.1; +int maxADCValue = 1023; +float voltageDividerRatio = 3.0; +int adcBattVoltValue = 0; +float inputVoltage = 0.0; +float measuredVoltage = 0.0; +int voltBarHeight = 0; +int voltBarPosition = 0; +//oth +int BrakingLightSwitch; +int ups = 0; +int downs = 0; +int run_hrs = 0; +int run_mins = 0; +void setup() { + //SERVO + digitalWrite(ServoSwitch, HIGH); + myservo.attach(ServoPin); // attaches the servo on pin 4 to the servo object + setPosition(8); +// +// Serial.begin(9600); + +// //DIPLAY settings +// if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { +// Serial.println(F("SSD1306 allocation failed")); +// for (;;); // Don't proceed, loop forever +// } + display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); + display.clearDisplay(); + display.setTextColor(WHITE); + display.setRotation(0); + display.setTextSize(3); + display.setCursor(0, 0); + display.println("Version:"); + display.setCursor(0, 25); + display.println(Version); + display.display(); + delay(500); + //INPUT + pinMode(PinInSpeed, INPUT); + pinMode(PinInterrupt, OUTPUT); + digitalWrite(PinInterrupt, HIGH); + pinMode(Btn1, INPUT); + pinMode(VoltInptPin, INPUT); + //OUTPUT + pinMode(PinLED, OUTPUT); + pinMode(BrakingLight, OUTPUT); + pinMode(ServoSwitch, OUTPUT); + + //Interrupts + attachInterrupt(digitalPinToInterrupt(PinInSpeed), calcSpeed, FALLING); + display.clearDisplay(); + delay(550); + setPosition(7); + display.setTextSize(1); + display.setCursor(0, 0); + display.println("wheelSize:"); + display.setCursor(75, 0); + display.println(WheelCircumference); + display.setCursor(0, 16); + display.println("MagnetsCnt:"); + display.setCursor(75, 16); + display.println(MagnetsCnt); + display.setCursor(0, 30); + display.println("TimeToSleep:"); + display.setCursor(75, 30); + display.println(TimeToSleep); + display.setCursor(0, 45); + display.println("ServoMaxAgl:"); + display.setCursor(75, 45); + display.println(ServoMaxAngle); + display.display(); + for (servoCurrPos = myservo.read(); servoCurrPos <= 180; servoCurrPos++) { + myservo.write(servoCurrPos); + delay(15); + } + //MEMORY + eeprom_read_block(&totalDistReaded, totalDistMemLocation, 2); + totalDist = float(totalDistReaded); +} + +//########################################### LOOP ############################################################ +//########################################### LOOP ############################################################ +void loop() { + + loopTime = millis(); + display.clearDisplay(); +// //DIAG Btn1 +// display.setTextSize(1); +// display.setCursor(0, 30); +// display.println("Btn1:"); +// display.setCursor(30, 20); +// display.println(digitalRead(Btn1)); +// display.setCursor(30, 30); +// display.println(analogRead(Btn1)); +// display.setCursor(55, 30); + + display.setTextSize(3); + + //################################################ + //SPEED + sleepSpd = millis() - lastMillisSpd; + if (sleepSpd >= 1500) { //podaj zerową prędkość jeśli nie było odcztu od 1,5 s + speed4Gear = 0.0; + speed4Gear_2 = 0.0; + speed = 0.0; + speed_last = 0.0; + speed_last_2 = 0.0; + speed_last_3 = 0.0; + //przejście w tryb uśpienia za pomocą odpowiedniego ustawienia koła i magnesu + if ((digitalRead(PinInSpeed) == LOW)|| (sleepSpd >= LongTimeToSleep)) { + display.fillCircle(75, 10, 10, SSD1306_WHITE); + if (sleepSpd >= TimeToSleep) { + prepareTurnOff(); + } + } + } + + if (speed4Gear > 40 || isinf(speed4Gear)) { + speed4Gear = speed4Gear_3; + } + calcGear(); + displGear = 9 - currentGear; + setPosition(currentGear); + + //duzy font + //GEAR + display.setCursor(8, 0); + display.println("G:"); + display.setCursor(40, 0); + display.print(currentGear); + //SPEED_TREND + display.setCursor(75, 00); + if (speedTrend <= -1 ) { + display.write(31); + } else { + if (speedTrend >= 1) { + display.write(30); + } else { + display.println("-"); + } + } + //SPEED + display.setCursor(8, 40); + display.println("S:"); + display.setCursor(40, 40); + display.println(speed, 1); + //GearBar + currentGearRangeMiddle = (currentGearRangeLower + currentGearRangeUpper) / 2; + display.fillRect(115, 32, 7, 1, SSD1306_WHITE); + display.fillRect(115, 0, 7, 1, SSD1306_WHITE); + display.fillRect(115, 63, 7, 1, SSD1306_WHITE); + + display.setTextSize(2); + + gearBarHeight = 64 - int(((speed4Gear - currentGearRangeLower) / (currentGearRangeUpper - currentGearRangeLower)) * 64) - 5; + display.setCursor(115, gearBarHeight); + display.write(16); + display.setTextSize(3); + + + //VOLT_BAR + adcBattVoltValue = analogRead(VoltInptPin); + measuredVoltage = (adcBattVoltValue * referenceVoltage) / maxADCValue; + inputVoltage = measuredVoltage * voltageDividerRatio; + + voltBarHeight = int(((inputVoltage-9)/3)*64); //odjemowanie 9 bo to minimalne napiecie, podział przez 3 bo zakladam max napiecie 12.0V a nie 12.6V + voltBarPosition = 64 - voltBarHeight; + display.fillRect(0, voltBarPosition, 1, voltBarHeight, SSD1306_WHITE); + //########################################## ZAPIS DO WYŚWIETLACZA ###################################################### + display.display(); + loopTime = millis(); + + //wstrzymanie pętli by odczyty były co 0,5s + for (; (millis() - loopTime) < 100 ;) { + delay(10); + } + + + + if (speedTrend == -1 && speed4Gear > 0.0 ) { + if (BrakingLightSwitch == 1) { + digitalWrite(BrakingLight, HIGH); + BrakingLightSwitch = 0; + } else { + digitalWrite(BrakingLight, LOW); + BrakingLightSwitch = 1; + } + } else { + digitalWrite(BrakingLight, LOW); + } + //TTL DST +// totalDist = 0; + loop_cnt = loop_cnt +1; + if (loop_cnt >= 20 //&& totalDistWrited != totalDist + ){ + totalDistWrited = int(totalDist); +// eeprom_write_block(&totalDistWrited,totalDistMemLocation,2); + loop_cnt = 0; + } +} +//########################################### LOOP ############################################################ +//########################################### LOOP ############################################################ +void calcSpeed() { + lastLastMillisSpd = lastMillisSpd; + lastMillisSpd = millissSpd; + millissSpd = millis(); + sigleTimeSpd = double(millissSpd - lastLastMillisSpd) / 1000; + speed = (((2 * Pi) / sigleTimeSpd * ((WheelCircumference) / (Pi)) * ms2kmh)) / MagnetsCnt; + +} + +void calcGear() { + +} + +void setPosition(int currentGear) { + pos = 180 - round((currentGear - 1) * (ServoMaxAngle / (MaxGear - 1) )); + if (pos >= 180) { + pos = MaxAngle; + } + + if (pos <= 0) { + pos = MinAngle; + } + if (sleepMode == 1 && speed > 0.0) { + digitalWrite(ServoSwitch, HIGH); + for (servoCurrPos = myservo.read(); servoCurrPos <= 180; servoCurrPos++) { + myservo.write(servoCurrPos); + delay(4); + } + sleepMode = 0; + } + myservo.write(pos); +} + +void prepareTurnOff() { + sleepMode = 1; + display.clearDisplay(); + display.setTextSize(1); + display.setCursor(0, 0); + display.println("Przygotwywanie..."); + display.display(); + for (servoCurrPos = myservo.read(); servoCurrPos >= 60; servoCurrPos--) { + myservo.write(servoCurrPos); + delay(15); + } +//Na czas diagnostyki +// eeprom_write_block(&totalDist,totalDistMemLocation,2); +// totalDistWrited = totalDist; +// loop_cnt = 0; +// + for (; 1500 < (millis() - lastMillisSpd);) { // zmiana z 1000 na 1500 w 1.13.19 + digitalWrite(ServoSwitch, LOW); + digitalWrite(ServoPin, LOW); + //INFO + display.clearDisplay(); + display.setTextSize(1); + display.setCursor(0, 30); + display.println("Mozna teraz"); + display.setCursor(0, 38); + display.println("bezpiecznie wylaczyc"); + display.setCursor(0, 46); + display.println("komputer."); + display.setCursor(0, 0); + display.write(31); + display.setCursor(5, 0); + display.println("+"); + display.setCursor(10, 0); + display.write(30); + display.setCursor(20, 0); + display.println(downs + ups); + //Version + display.setCursor(0, 13); + display.println("V: "); + display.setCursor(10, 13); + display.println(Version); + //DST + display.setCursor(45, 0); + display.println("Spins: "); + display.setCursor(80, 0); + display.println(totalDistWrited); + display.setCursor(53, 13); + display.println("KM: "); + display.setCursor(90, 13); + display.println((totalDistWrited*WheelCircumference)/1000); + //RUN TIME + run_mins = floor((millis() / 1000) / 60); + run_hrs = floor(run_mins / 60); + run_mins = run_mins - (run_hrs * 60); + display.setCursor(60, 54); + display.println("T:"); + display.setCursor(75, 54); + display.println(run_hrs); + display.setCursor(83, 54); + display.println(":"); + display.setCursor(88, 54); + display.println(run_mins); + display.display(); + delay(500); + } +} diff --git a/LeonardoProMicro/SimplyAutomatedGearShifter/algorytm predykcji.xlsx b/LeonardoProMicro/SimplyAutomatedGearShifter/algorytm predykcji.xlsx new file mode 100644 index 0000000..b9ec78f Binary files /dev/null and b/LeonardoProMicro/SimplyAutomatedGearShifter/algorytm predykcji.xlsx differ diff --git a/LeonardoProMicro/SimplyAutomatedGearShifter/planowanie_pamięci.xlsx b/LeonardoProMicro/SimplyAutomatedGearShifter/planowanie_pamięci.xlsx new file mode 100644 index 0000000..0250597 Binary files /dev/null and b/LeonardoProMicro/SimplyAutomatedGearShifter/planowanie_pamięci.xlsx differ