RAM optimization

This commit is contained in:
2025-12-05 10:37:38 +01:00
parent 71cd463b04
commit c889eec818
4 changed files with 121 additions and 140 deletions

View File

@@ -8,16 +8,44 @@
; Please visit documentation for the other options and examples ; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[env:nanoatmega328new] [platformio]
platform = atmelavr default_envs = nanoatmega328new
board = nanoatmega328new
framework = arduino ; custom common options
[common]
build_flags =
-D VERSION=1.2.3
-D DEBUG=1
lib_deps_external =
[env:megaatmega2560] [env:megaatmega2560]
platform = atmelavr platform = atmelavr
board = megaatmega2560 board = megaatmega2560
framework = arduino framework = arduino
; Build options
build_flags =
${common.build_flags}
-D DISPLAY_ENABLE
; Library options
lib_deps =
${common.lib_deps_external}
adafruit/Adafruit SSD1306 @ ^2.5.13
[env:nanoatmega328new]
platform = atmelavr
board = nanoatmega328new
framework = arduino
; Build options
build_flags =
${common.build_flags}
; Library options
lib_deps =
${common.lib_deps_external}
;upload_protocol = custom ;upload_protocol = custom
;upload_flags = ;upload_flags =
@@ -29,8 +57,5 @@ framework = arduino
; -c ; -c
; jtag3isp ; jtag3isp
;upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i ;upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i
;extra_scripts = fuses.py ;extra_scripts = fuses.py
lib_deps =
adafruit/Adafruit SSD1306 @ ^2.5.13

View File

@@ -1,7 +1,7 @@
// PedalController.cpp // PedalController.cpp
#include "PedalController.h" #include "PedalController.h"
// sinnvolle Defaults grob um deinen Bereich // sinnvolle Defaults grob um den real genutzen Bereich
// nicht gedrückt ~425, gedrückt ~227 // nicht gedrückt ~425, gedrückt ~227
static const PedalConfig defaultConfig = { static const PedalConfig defaultConfig = {
.minRaw = 230, // grob gedrückt .minRaw = 230, // grob gedrückt
@@ -159,7 +159,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step3NearReleased = false; step3NearReleased = false;
step4NearPressed = false; step4NearPressed = false;
Serial.println("CAL: Step 1 - Pedal NICHT drücken (voll loslassen und still halten)."); Serial.println(F("CAL: Step 1 - Pedal NICHT drücken (voll loslassen und still halten)."));
return calState; return calState;
} }
@@ -194,7 +194,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
int16_t noise = maxSeen - minSeen; int16_t noise = maxSeen - minSeen;
if (noise > NOISE_TOLERANCE) if (noise > NOISE_TOLERANCE)
{ {
Serial.print("CAL: FEHLER - zu viel Rauschen im losgelassenen Zustand (noise="); Serial.print(F("CAL: FEHLER - zu viel Rauschen im losgelassenen Zustand (noise="));
Serial.print(noise); Serial.print(noise);
Serial.println(")."); Serial.println(").");
calState = ERROR; calState = ERROR;
@@ -211,9 +211,9 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step2MovedEnough = false; step2MovedEnough = false;
calStep = 2; calStep = 2;
Serial.print("CAL: Step 1 OK. firstReleased="); Serial.print(F("CAL: Step 1 OK. firstReleased="));
Serial.println(firstReleased); Serial.println(firstReleased);
Serial.println("CAL: Step 2 - Pedal JETZT GANZ DURCHDRÜCKEN und halten."); Serial.println(F("CAL: Step 2 - Pedal JETZT GANZ DURCHDRÜCKEN und halten."));
} }
calState = RUNNING; calState = RUNNING;
@@ -230,7 +230,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step2MovedEnough = true; step2MovedEnough = true;
lastSample = raw; lastSample = raw;
lastChangeTime = now; lastChangeTime = now;
Serial.println("CAL: Step 2 - Bewegung erkannt, warte auf stabil gedrückt."); Serial.println(F("CAL: Step 2 - Bewegung erkannt, warte auf stabil gedrückt."));
} }
} }
else else
@@ -253,9 +253,9 @@ CalibrationState PedalController::autoCalibrate(bool reset)
calStep = 3; calStep = 3;
step3NearReleased = false; step3NearReleased = false;
Serial.print("CAL: Step 2 OK. firstPressed="); Serial.print(F("CAL: Step 2 OK. firstPressed="));
Serial.println(firstPressed); Serial.println(firstPressed);
Serial.println("CAL: Step 3 - Pedal wieder LOSLASSEN und still halten."); Serial.println(F("CAL: Step 3 - Pedal wieder LOSLASSEN und still halten."));
} }
} }
@@ -273,7 +273,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step3NearReleased = true; step3NearReleased = true;
lastSample = raw; lastSample = raw;
lastChangeTime = now; lastChangeTime = now;
Serial.println("CAL: Step 3 - in Nähe von losgelassen, warte auf stabile Position."); Serial.println(F("CAL: Step 3 - in Nähe von losgelassen, warte auf stabile Position."));
} }
} }
else else
@@ -291,7 +291,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
if (abs(secondReleased - firstReleased) > NEAR_TOLERANCE) if (abs(secondReleased - firstReleased) > NEAR_TOLERANCE)
{ {
Serial.println("CAL: FEHLER - losgelassene Position inkonsistent zwischen erstem und zweitem Mal."); Serial.println(F("CAL: FEHLER - losgelassene Position inkonsistent zwischen erstem und zweitem Mal."));
calState = ERROR; calState = ERROR;
calStep = 0; calStep = 0;
break; break;
@@ -302,9 +302,9 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step4NearPressed = false; step4NearPressed = false;
calStep = 4; calStep = 4;
Serial.print("CAL: Step 3 OK. secondReleased="); Serial.print(F("CAL: Step 3 OK. secondReleased="));
Serial.println(secondReleased); Serial.println(secondReleased);
Serial.println("CAL: Step 4 - Pedal erneut GANZ DURCHDRÜCKEN und halten."); Serial.println(F("CAL: Step 4 - Pedal erneut GANZ DURCHDRÜCKEN und halten."));
} }
} }
@@ -322,7 +322,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step4NearPressed = true; step4NearPressed = true;
lastSample = raw; lastSample = raw;
lastChangeTime = now; lastChangeTime = now;
Serial.println("CAL: Step 4 - in Nähe von voll gedrückt, warte auf stabile Position."); Serial.println(F("CAL: Step 4 - in Nähe von voll gedrückt, warte auf stabile Position."));
} }
} }
else else
@@ -340,7 +340,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
if (abs(secondPressed - firstPressed) > NEAR_TOLERANCE) if (abs(secondPressed - firstPressed) > NEAR_TOLERANCE)
{ {
Serial.println("CAL: FEHLER - gedrückte Position inkonsistent zwischen erstem und zweitem Mal."); Serial.println(F("CAL: FEHLER - gedrückte Position inkonsistent zwischen erstem und zweitem Mal."));
calState = ERROR; calState = ERROR;
calStep = 0; calStep = 0;
break; break;
@@ -350,9 +350,9 @@ CalibrationState PedalController::autoCalibrate(bool reset)
lastChangeTime = now; lastChangeTime = now;
calStep = 5; calStep = 5;
Serial.print("CAL: Step 4 OK. secondPressed="); Serial.print(F("CAL: Step 4 OK. secondPressed="));
Serial.println(secondPressed); Serial.println(secondPressed);
Serial.println("CAL: Step 5 - Pedal LOSLASSEN und still halten (Finalisierung)."); Serial.println(F("CAL: Step 5 - Pedal LOSLASSEN und still halten (Finalisierung)."));
} }
} }
@@ -399,7 +399,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
if (high - low < MIN_RANGE) if (high - low < MIN_RANGE)
{ {
Serial.println("CAL: FEHLER - Gesamtspanne zu klein. Pedalweg reicht nicht aus."); Serial.println(F("CAL: FEHLER - Gesamtspanne zu klein. Pedalweg reicht nicht aus."));
config.calibrated = false; config.calibrated = false;
calState = ERROR; calState = ERROR;
calStep = 0; calStep = 0;
@@ -412,7 +412,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
if (high <= low) if (high <= low)
{ {
Serial.println("CAL: FEHLER - Sicherheitsmargen zerstören die Spannweite."); Serial.println(F("CAL: FEHLER - Sicherheitsmargen zerstören die Spannweite."));
config.calibrated = false; config.calibrated = false;
calState = ERROR; calState = ERROR;
calStep = 0; calStep = 0;
@@ -436,7 +436,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
} }
default: default:
Serial.println("CAL: INTERNAL ERROR - unerwarteter Step."); Serial.println(F("CAL: INTERNAL ERROR - unerwarteter Step."));
calState = ERROR; calState = ERROR;
calStep = 0; calStep = 0;
break; break;
@@ -483,6 +483,11 @@ void PedalController::maintain()
if (signals_.calibrated) if (signals_.calibrated)
*signals_.calibrated = config.calibrated; *signals_.calibrated = config.calibrated;
if(calState == RUNNING)
{
autoCalibrate(false);
}
} }
PedalConfig PedalController::getConfig() const PedalConfig PedalController::getConfig() const

View File

@@ -18,9 +18,6 @@ typedef struct SerialSignals
bool *serialControlEnabled; // schaltet „Serielle Steuerung“ an/aus bool *serialControlEnabled; // schaltet „Serielle Steuerung“ an/aus
// Optional: Zeiger auf Configs für Dumps
MotorConfig *motorConfig;
PedalConfig *pedalConfig;
} SerialSignals; } SerialSignals;
class SerialController class SerialController

View File

@@ -1,26 +1,28 @@
#include <Arduino.h> #include <Arduino.h>
#include <EEPROM.h> #include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include "MotorController.h" #include "MotorController.h"
#include "PedalController.h" #include "PedalController.h"
#include "SerialController.h" #include "SerialController.h"
#ifdef DISPLAY_ENABLE
#include <Wire.h>
#include <Adafruit_SSD1306.h>
// OLED display setup // OLED display setup
#define OLED_RESET -1 #define OLED_RESET -1
#define SCREEN_WIDTH 128 #define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64 #define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#endif
// Pin definitions (Werte, keine Pointer) // Pin definitions (Werte, keine Pointer)
const int16_t hallSensorPin = 2; // Hall sensor input const int16_t hallSensorPin = 3; // Hall sensor input
const int16_t encoderPinA = 3; // Encoder pin A const int16_t encoderPinA = 4; // Encoder pin A
const int16_t encoderPinB = 4; // Encoder pin B const int16_t encoderPinB = 5; // Encoder pin B
const int16_t encoderButtonPin = 5; // Encoder button const int16_t encoderButtonPin = 2; // Encoder button
const int16_t motorPwmPin = 13; // Motor PWM pin const int16_t motorPwmPin = 13; // Motor PWM pin
const int16_t pedalPinAnalog = A0; // Pedal analog Input pin const int16_t pedalPinAnalog = A0; // Pedal analog Input pin
const int16_t pedalPinDigital = 8; // Pedal digital Input pin const int16_t pedalPinDigital = -1; // Pedal digital Input pin
// Debug-Flag (gemeinsam für alle Controller) // Debug-Flag (gemeinsam für alle Controller)
bool debug = false; bool debug = false;
@@ -45,16 +47,12 @@ bool gReqDefaults = false;
bool gSerialControl = false; bool gSerialControl = false;
// Combined settings structure // Combined settings structure
struct Settings typedef struct Settings_t
{ {
MotorConfig motorConfig; MotorConfig motorConfig;
PedalConfig pedalConfig; PedalConfig pedalConfig;
uint8_t checksum; uint8_t checksum;
}; } Settings_s;
Settings settings;
CalibrationState lastCalibrationState = IDLE;
bool autoCalibrating = false;
// Signals-Instanzen // Signals-Instanzen
MotorSignals motorSignals{ MotorSignals motorSignals{
@@ -82,8 +80,7 @@ SerialSignals serialSignals{
.requestLoadEEPROM = &gReqLoadEEPROM, .requestLoadEEPROM = &gReqLoadEEPROM,
.requestLoadDefaults = &gReqDefaults, .requestLoadDefaults = &gReqDefaults,
.serialControlEnabled = &gSerialControl, .serialControlEnabled = &gSerialControl,
.motorConfig = &settings.motorConfig, };
.pedalConfig = &settings.pedalConfig};
// Global objects // Global objects
MotorController motor(motorSignals); MotorController motor(motorSignals);
@@ -93,14 +90,15 @@ SerialController serialCtrl(serialSignals);
// Function prototypes // Function prototypes
void loadSettings(); void loadSettings();
void saveSettings(); void saveSettings();
uint8_t calculateChecksum(const Settings &s); uint8_t calculateChecksum(const Settings_t &s);
void handleEncoder(); void handleEncoder();
void handleEncoderButton(); void handleEncoderButton();
void updateDisplay();
void configurePWMFrequency(); void configurePWMFrequency();
void stopMotorAtNeedleUp(); void stopMotorAtNeedleUp();
void printStatusLine(); #ifdef DISPLAY_ENABLE
void updateDisplay();
#endif
// ----------------- SETUP ----------------- // ----------------- SETUP -----------------
@@ -123,12 +121,14 @@ void setup()
Serial.begin(9600); Serial.begin(9600);
loadSettings(); loadSettings();
// OLED optional #ifdef DISPLAY_ENABLE
// if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
// Serial.println(F("SSD1306 allocation failed")); {
// } Serial.println(F("SSD1306 allocation failed"));
// display.clearDisplay(); }
// display.display(); display.clearDisplay();
display.display();
#endif
serialCtrl.printHelp(); serialCtrl.printHelp();
} }
@@ -144,7 +144,7 @@ void loop()
if (gReqDefaults) if (gReqDefaults)
{ {
gReqDefaults = false; gReqDefaults = false;
Serial.println("Loading defaults."); Serial.println(F("Loading defaults."));
motor.loadDefaults(); motor.loadDefaults();
pedal.loadDefaults(); pedal.loadDefaults();
} }
@@ -152,59 +152,26 @@ void loop()
if (gReqLoadEEPROM) if (gReqLoadEEPROM)
{ {
gReqLoadEEPROM = false; gReqLoadEEPROM = false;
Serial.println("Loading settings from EEPROM."); Serial.println(F("Loading settings from EEPROM."));
loadSettings(); loadSettings();
} }
if (gReqSaveEEPROM) if (gReqSaveEEPROM)
{ {
gReqSaveEEPROM = false; gReqSaveEEPROM = false;
Serial.println("Saving settings to EEPROM."); Serial.println(F("Saving settings to EEPROM."));
saveSettings(); saveSettings();
} }
if (gReqAutoCal) if (gReqAutoCal)
{ {
gReqAutoCal = false; gReqAutoCal = false;
Serial.println("Starting auto-calibration..."); Serial.println(F("Starting auto-calibration..."));
pedal.autoCalibrate(true); pedal.autoCalibrate(true);
autoCalibrating = true;
lastCalibrationState = IDLE;
gTargetSpeedPercent = 0; gTargetSpeedPercent = 0;
gSerialControl = false;
} }
if (autoCalibrating)
{
CalibrationState currentState = pedal.autoCalibrate(false);
if (currentState != lastCalibrationState)
{
lastCalibrationState = currentState;
switch (currentState)
{
case RUNNING:
Serial.println("Calibration running...");
break;
case SUCCESS:
Serial.println("Auto-calibration completed.");
autoCalibrating = false;
break;
case ERROR:
Serial.println("Auto-calibration failed.");
autoCalibrating = false;
break;
default:
break;
}
}
gTargetSpeedPercent = 0; // während Cal immer 0
}
else
{
// Nur im Normalbetrieb: Pedal einlesen
pedal.maintain();
if (!gSerialControl) if (!gSerialControl)
{ {
// Standard: Pedal → TargetSpeed // Standard: Pedal → TargetSpeed
@@ -221,18 +188,16 @@ void loop()
lastSpeed = gCurrentSpeedPercent; lastSpeed = gCurrentSpeedPercent;
} }
} }
}
// pedal verarbeiten
pedal.maintain();
// Motor nachführen // Motor nachführen
motor.maintain(); motor.maintain();
// Optional: Display #ifdef DISPLAY_ENABLE
// updateDisplay(); updateDisplay();
#endif
// Optional: eine Debug-Zeile mit Kerninfos
// printStatusLine();
delay(10);
} }
// ----------------- HILFSFUNKTIONEN ----------------- // ----------------- HILFSFUNKTIONEN -----------------
@@ -240,48 +205,50 @@ void loop()
void stopMotorAtNeedleUp() void stopMotorAtNeedleUp()
{ {
motor.stopMotor(); motor.stopMotor();
delay(100);
} }
void loadSettings() void loadSettings()
{ {
EEPROM.get(0, settings); Settings_t tmp;
EEPROM.get(0, tmp);
if (calculateChecksum(settings) != settings.checksum) if (calculateChecksum(tmp) != tmp.checksum)
{ {
Serial.println("Invalid settings checksum, loading defaults."); Serial.println(F("Invalid settings checksum, loading defaults."));
motor.loadDefaults(); motor.loadDefaults();
pedal.loadDefaults(); pedal.loadDefaults();
settings.motorConfig = motor.getConfig(); tmp.motorConfig = motor.getConfig();
settings.pedalConfig = pedal.getConfig(); tmp.pedalConfig = pedal.getConfig();
settings.checksum = calculateChecksum(settings); tmp.checksum = calculateChecksum(tmp);
saveSettings(); EEPROM.put(0, tmp);
Serial.println(F("Defaults written to EEPROM."));
} }
else else
{ {
motor.setConfig(settings.motorConfig); motor.setConfig(tmp.motorConfig);
pedal.setConfig(settings.pedalConfig); pedal.setConfig(tmp.pedalConfig);
Serial.println("Settings loaded from EEPROM."); Serial.println(F("Settings loaded from EEPROM."));
} }
} }
void saveSettings() void saveSettings()
{ {
settings.motorConfig = motor.getConfig(); Settings_t tmp;
settings.pedalConfig = pedal.getConfig(); tmp.motorConfig = motor.getConfig();
settings.checksum = calculateChecksum(settings); tmp.pedalConfig = pedal.getConfig();
tmp.checksum = calculateChecksum(tmp);
EEPROM.put(0, settings); EEPROM.put(0, tmp);
Serial.println("Settings saved to EEPROM."); Serial.println(F("Settings saved to EEPROM."));
} }
uint8_t calculateChecksum(const Settings &s) uint8_t calculateChecksum(const Settings_t &s)
{ {
uint8_t sum = 0; uint8_t sum = 0;
const uint8_t *data = reinterpret_cast<const uint8_t *>(&s); const uint8_t *data = reinterpret_cast<const uint8_t *>(&s);
for (size_t i = 0; i < sizeof(Settings) - 1; i++) for (size_t i = 0; i < sizeof(Settings_t) - 1; i++)
{ {
sum ^= data[i]; sum ^= data[i];
} }
@@ -314,6 +281,7 @@ void handleEncoderButton()
// Encoder-Button-Logik // Encoder-Button-Logik
} }
#ifdef DISPLAY_ENABLED
void updateDisplay() void updateDisplay()
{ {
display.clearDisplay(); display.clearDisplay();
@@ -334,24 +302,10 @@ void updateDisplay()
display.display(); display.display();
} }
#endif
void configurePWMFrequency() void configurePWMFrequency()
{ {
// Configure Timer1 for higher PWM frequency (~4 kHz) // Configure Timer1 for higher PWM frequency (~4 kHz)
TCCR1B = (1 << CS11); // Set prescaler to 8 TCCR1B = (1 << CS11); // Set prescaler to 8
} }
void printStatusLine()
{
if (!debug)
return;
Serial.print("[STAT] Pedal=");
Serial.print(gPedalPercent);
Serial.print("% Target=");
Serial.print(gTargetSpeedPercent);
Serial.print("% Speed=");
Serial.print(gCurrentSpeedPercent);
Serial.print("% PWM=");
Serial.println(gCurrentPwm);
}