From b9bec53dec3a3aeccf370bcc24a5ea0bf3d90460 Mon Sep 17 00:00:00 2001 From: sieja Date: Mon, 12 May 2025 20:03:40 +0200 Subject: [PATCH] Pierwsze podejscie do HAT Arduino --- ESP32/AutomatedGearShifter/.theia/launch.json | 8 + .../AutomatedGearShifter.ino | 525 ++++++++++++++++++ .../algorytm predykcji.xlsx | Bin 0 -> 11908 bytes .../planowanie_pamięci.xlsx | Bin 0 -> 10034 bytes ESP32/StadlerHomeKitUpgrade/PartList.xlsx | Bin 0 -> 12927 bytes 5 files changed, 533 insertions(+) create mode 100644 ESP32/AutomatedGearShifter/.theia/launch.json create mode 100644 ESP32/AutomatedGearShifter/AutomatedGearShifter.ino create mode 100644 ESP32/AutomatedGearShifter/algorytm predykcji.xlsx create mode 100644 ESP32/AutomatedGearShifter/planowanie_pamięci.xlsx create mode 100644 ESP32/StadlerHomeKitUpgrade/PartList.xlsx diff --git a/ESP32/AutomatedGearShifter/.theia/launch.json b/ESP32/AutomatedGearShifter/.theia/launch.json new file mode 100644 index 0000000..7e4253b --- /dev/null +++ b/ESP32/AutomatedGearShifter/.theia/launch.json @@ -0,0 +1,8 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + "version": "0.2.0", + "configurations": [ + + ] +} diff --git a/ESP32/AutomatedGearShifter/AutomatedGearShifter.ino b/ESP32/AutomatedGearShifter/AutomatedGearShifter.ino new file mode 100644 index 0000000..aeddb30 --- /dev/null +++ b/ESP32/AutomatedGearShifter/AutomatedGearShifter.ino @@ -0,0 +1,525 @@ +// #include +// #include // model servo: DS3218 PRO +#include // model servo: DS3218 PRO + +#include +#include +#include +#include +#include + +#define Version "1.15.8" +////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 4 //on board: D4 +#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 23 //on board: D23 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_last_3 = speed_last_2; +// speed_last_2 = speed_last; +// speed_last = speed; + speed = (((2 * Pi) / sigleTimeSpd * ((WheelCircumference) / (Pi)) * ms2kmh)) / MagnetsCnt; + // diag +// if (((speed_last_3 * 1.5) > speed) && speed > 10.0 && speedTrend > 0) { //zabezpieczenie przed losowymi sygnałami magesu +// speed = speed_last_3; +// } +// speed = (speed + speed_last)/2; + totalDist = totalDist + (1/MagnetsCnt); +} + +void calcGear() { + //speed validation + speedDiff_3 = speed4Gear_3-speed4Gear_2; + speedDiff_2 = speed4Gear_2-speed4Gear_1; + speed4Gear_3 = speed4Gear_2; + speed4Gear_2 = speed4Gear_1; + speed4Gear_1 = speed; + speed4Geat_estimated = (((speedDiff_3 * avgWeight_3 + speedDiff_2 * avgWeight_2)/(avgWeight_3 + avgWeight_2))+ speed4Gear_1) + 4; + if (speed <= 10.0 or speed <= speed4Geat_estimated) { + speed4Gear_2 = speed4Gear; + speed4Gear = speed4Gear_1; + } + + +//poniżej zamienić speed na speed4Gear +//speed_last_3 na speed4Gear_2 + + + + + if ((speed4Gear / speed4Gear_2) >= 1.5) { // przyspieszenie DO weryfikacji czy nie trzeba zamienic na czas lub zwiększyc wartość + speedTrend = 1; + } else if ((speed4Gear - speed4Gear_2) <= -1.5) { + speedTrend = -1; + } else { + speedTrend = 0; + } + + // if (speedTrend > 0){ // wymusza wczerśniejszą zmianę biegów gdy wykryto przyspieszanie + // accelerationShift = 1.05; + // }else { + accelerationShift = 1; + // } + if (speed4Gear * accelerationShift >= 0 && speed4Gear * accelerationShift < spdRange1and2) { + calculatedGear = 1; + currentGearRangeLower = 2.5; + currentGearRangeUpper = spdRange1and2; + } else if (speed4Gear * accelerationShift >= spdRange1and2 && speed4Gear * accelerationShift < spdRange2and3) { + calculatedGear = 2; + currentGearRangeLower = spdRange1and2; + currentGearRangeUpper = spdRange2and3; + } else if (speed4Gear * accelerationShift >= spdRange2and3 && speed4Gear * accelerationShift < spdRange3and4) { + calculatedGear = 3; + currentGearRangeLower = spdRange2and3; + currentGearRangeUpper = spdRange3and4; + } else if (speed4Gear * accelerationShift >= spdRange3and4 && speed4Gear * accelerationShift < spdRange4and5) { + calculatedGear = 4; + currentGearRangeLower = spdRange3and4; + currentGearRangeUpper = spdRange4and5; + } else if (speed4Gear * accelerationShift >= spdRange4and5 && speed4Gear * accelerationShift < spdRange5and6) { + calculatedGear = 5; + currentGearRangeLower = spdRange4and5; + currentGearRangeUpper = spdRange5and6; + } else if (speed4Gear * accelerationShift >= spdRange5and6 && speed4Gear * accelerationShift < spdRange6and7) { + calculatedGear = 6; + currentGearRangeLower = spdRange5and6; + currentGearRangeUpper = spdRange6and7; + } else if (speed4Gear * accelerationShift >= spdRange6and7 && speed4Gear * accelerationShift < spdRange7and8) { + calculatedGear = 7; + currentGearRangeLower = spdRange6and7; + currentGearRangeUpper = spdRange7and8; + } else if (speed4Gear * accelerationShift >= spdRange7and8) { + calculatedGear = 8; + currentGearRangeLower = spdRange7and8; + currentGearRangeUpper = 60.0; + } else { + calculatedGear = 8; //Default + }; + calcTimeDiff = millis() - lastGearCalc; + + if (calculatedGear == currentGear) { + speedForBar = speed4Gear * accelerationShift; + } + if ((calculatedGear + 1) < currentGear || (calculatedGear - 1) > currentGear || calcTimeDiff >= changeDelayMs || speedTrend > 0 ) { + //zmień bieg tylko, gdy rożnica między biegiem wyliczonym a obecnym jest większa niż jeden lub gdy od zmieny biegu minely 3 sec + if (currentGear > calculatedGear) { + downs = downs + 1; + } + if (currentGear < calculatedGear) { + ups = ups + 1; + } + currentGear = calculatedGear; + previousGear = currentGear; + lastGearCalc = millis(); + speedForBar = speed4Gear * accelerationShift; + + } + if (speedTrend >= 1 and calculatedGear < 8) { + if (currentGear > calculatedGear) { + downs = downs + 1; + } + if (currentGear < calculatedGear) { + ups = ups + 1; + } + currentGear = calculatedGear; + previousGear = currentGear; + lastGearCalc = millis(); + speedForBar = speed4Gear * accelerationShift; + + } else if (speedTrend <= -1 and calculatedGear > 1) { + if (currentGear > calculatedGear) { + downs = downs + 1; + } + if (currentGear < calculatedGear) { + ups = ups + 1; + } + previousGear = currentGear; + currentGear = calculatedGear; + lastGearCalc = millis(); + speedForBar = speed4Gear * accelerationShift; + }; +} + +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/ESP32/AutomatedGearShifter/algorytm predykcji.xlsx b/ESP32/AutomatedGearShifter/algorytm predykcji.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b9ec78fa4a4f62b85e911102e2183a04ec1969ee GIT binary patch literal 11908 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