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
; https://docs.platformio.org/page/projectconf.html
[env:nanoatmega328new]
platform = atmelavr
board = nanoatmega328new
framework = arduino
[platformio]
default_envs = nanoatmega328new
; custom common options
[common]
build_flags =
-D VERSION=1.2.3
-D DEBUG=1
lib_deps_external =
[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
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_flags =
@@ -29,8 +57,5 @@ framework = arduino
; -c
; jtag3isp
;upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i
;extra_scripts = fuses.py
lib_deps =
adafruit/Adafruit SSD1306 @ ^2.5.13

View File

@@ -1,7 +1,7 @@
// PedalController.cpp
#include "PedalController.h"
// sinnvolle Defaults grob um deinen Bereich
// sinnvolle Defaults grob um den real genutzen Bereich
// nicht gedrückt ~425, gedrückt ~227
static const PedalConfig defaultConfig = {
.minRaw = 230, // grob gedrückt
@@ -159,7 +159,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step3NearReleased = 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;
}
@@ -194,7 +194,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
int16_t noise = maxSeen - minSeen;
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.println(").");
calState = ERROR;
@@ -211,9 +211,9 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step2MovedEnough = false;
calStep = 2;
Serial.print("CAL: Step 1 OK. firstReleased=");
Serial.print(F("CAL: Step 1 OK. 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;
@@ -230,7 +230,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step2MovedEnough = true;
lastSample = raw;
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
@@ -253,9 +253,9 @@ CalibrationState PedalController::autoCalibrate(bool reset)
calStep = 3;
step3NearReleased = false;
Serial.print("CAL: Step 2 OK. firstPressed=");
Serial.print(F("CAL: Step 2 OK. 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;
lastSample = raw;
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
@@ -291,7 +291,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
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;
calStep = 0;
break;
@@ -302,9 +302,9 @@ CalibrationState PedalController::autoCalibrate(bool reset)
step4NearPressed = false;
calStep = 4;
Serial.print("CAL: Step 3 OK. secondReleased=");
Serial.print(F("CAL: Step 3 OK. 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;
lastSample = raw;
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
@@ -340,7 +340,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
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;
calStep = 0;
break;
@@ -350,9 +350,9 @@ CalibrationState PedalController::autoCalibrate(bool reset)
lastChangeTime = now;
calStep = 5;
Serial.print("CAL: Step 4 OK. secondPressed=");
Serial.print(F("CAL: Step 4 OK. 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)
{
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;
calState = ERROR;
calStep = 0;
@@ -412,7 +412,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
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;
calState = ERROR;
calStep = 0;
@@ -436,7 +436,7 @@ CalibrationState PedalController::autoCalibrate(bool reset)
}
default:
Serial.println("CAL: INTERNAL ERROR - unerwarteter Step.");
Serial.println(F("CAL: INTERNAL ERROR - unerwarteter Step."));
calState = ERROR;
calStep = 0;
break;
@@ -483,6 +483,11 @@ void PedalController::maintain()
if (signals_.calibrated)
*signals_.calibrated = config.calibrated;
if(calState == RUNNING)
{
autoCalibrate(false);
}
}
PedalConfig PedalController::getConfig() const

View File

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

View File

@@ -1,26 +1,28 @@
#include <Arduino.h>
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include "MotorController.h"
#include "PedalController.h"
#include "SerialController.h"
#ifdef DISPLAY_ENABLE
#include <Wire.h>
#include <Adafruit_SSD1306.h>
// OLED display setup
#define OLED_RESET -1
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#endif
// Pin definitions (Werte, keine Pointer)
const int16_t hallSensorPin = 2; // Hall sensor input
const int16_t encoderPinA = 3; // Encoder pin A
const int16_t encoderPinB = 4; // Encoder pin B
const int16_t encoderButtonPin = 5; // Encoder button
const int16_t hallSensorPin = 3; // Hall sensor input
const int16_t encoderPinA = 4; // Encoder pin A
const int16_t encoderPinB = 5; // Encoder pin B
const int16_t encoderButtonPin = 2; // Encoder button
const int16_t motorPwmPin = 13; // Motor PWM 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)
bool debug = false;
@@ -45,16 +47,12 @@ bool gReqDefaults = false;
bool gSerialControl = false;
// Combined settings structure
struct Settings
typedef struct Settings_t
{
MotorConfig motorConfig;
PedalConfig pedalConfig;
uint8_t checksum;
};
Settings settings;
CalibrationState lastCalibrationState = IDLE;
bool autoCalibrating = false;
} Settings_s;
// Signals-Instanzen
MotorSignals motorSignals{
@@ -82,8 +80,7 @@ SerialSignals serialSignals{
.requestLoadEEPROM = &gReqLoadEEPROM,
.requestLoadDefaults = &gReqDefaults,
.serialControlEnabled = &gSerialControl,
.motorConfig = &settings.motorConfig,
.pedalConfig = &settings.pedalConfig};
};
// Global objects
MotorController motor(motorSignals);
@@ -93,14 +90,15 @@ SerialController serialCtrl(serialSignals);
// Function prototypes
void loadSettings();
void saveSettings();
uint8_t calculateChecksum(const Settings &s);
uint8_t calculateChecksum(const Settings_t &s);
void handleEncoder();
void handleEncoderButton();
void updateDisplay();
void configurePWMFrequency();
void stopMotorAtNeedleUp();
void printStatusLine();
#ifdef DISPLAY_ENABLE
void updateDisplay();
#endif
// ----------------- SETUP -----------------
@@ -123,12 +121,14 @@ void setup()
Serial.begin(9600);
loadSettings();
// OLED optional
// if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
// Serial.println(F("SSD1306 allocation failed"));
// }
// display.clearDisplay();
// display.display();
#ifdef DISPLAY_ENABLE
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{
Serial.println(F("SSD1306 allocation failed"));
}
display.clearDisplay();
display.display();
#endif
serialCtrl.printHelp();
}
@@ -144,7 +144,7 @@ void loop()
if (gReqDefaults)
{
gReqDefaults = false;
Serial.println("Loading defaults.");
Serial.println(F("Loading defaults."));
motor.loadDefaults();
pedal.loadDefaults();
}
@@ -152,87 +152,52 @@ void loop()
if (gReqLoadEEPROM)
{
gReqLoadEEPROM = false;
Serial.println("Loading settings from EEPROM.");
Serial.println(F("Loading settings from EEPROM."));
loadSettings();
}
if (gReqSaveEEPROM)
{
gReqSaveEEPROM = false;
Serial.println("Saving settings to EEPROM.");
Serial.println(F("Saving settings to EEPROM."));
saveSettings();
}
if (gReqAutoCal)
{
gReqAutoCal = false;
Serial.println("Starting auto-calibration...");
Serial.println(F("Starting auto-calibration..."));
pedal.autoCalibrate(true);
autoCalibrating = true;
lastCalibrationState = IDLE;
gTargetSpeedPercent = 0;
gSerialControl = false;
}
if (autoCalibrating)
if (!gSerialControl)
{
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
// Standard: Pedal → TargetSpeed
gTargetSpeedPercent = gPedalPercent;
}
else
{
// Nur im Normalbetrieb: Pedal einlesen
pedal.maintain();
if (!gSerialControl)
// Serielle Steuerung ist aktiv, Target wird von SerialController manipuliert
static int16_t lastSpeed = -1;
if (lastSpeed != gCurrentSpeedPercent)
{
// Standard: Pedal → TargetSpeed
gTargetSpeedPercent = gPedalPercent;
}
else
{
// Serielle Steuerung ist aktiv, Target wird von SerialController manipuliert
static int16_t lastSpeed = -1;
if (lastSpeed != gCurrentSpeedPercent)
{
Serial.print("Current Speed: ");
Serial.println(gCurrentSpeedPercent);
lastSpeed = gCurrentSpeedPercent;
}
Serial.print("Current Speed: ");
Serial.println(gCurrentSpeedPercent);
lastSpeed = gCurrentSpeedPercent;
}
}
// pedal verarbeiten
pedal.maintain();
// Motor nachführen
motor.maintain();
// Optional: Display
// updateDisplay();
#ifdef DISPLAY_ENABLE
updateDisplay();
#endif
// Optional: eine Debug-Zeile mit Kerninfos
// printStatusLine();
delay(10);
}
// ----------------- HILFSFUNKTIONEN -----------------
@@ -240,48 +205,50 @@ void loop()
void stopMotorAtNeedleUp()
{
motor.stopMotor();
delay(100);
}
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();
pedal.loadDefaults();
settings.motorConfig = motor.getConfig();
settings.pedalConfig = pedal.getConfig();
settings.checksum = calculateChecksum(settings);
tmp.motorConfig = motor.getConfig();
tmp.pedalConfig = pedal.getConfig();
tmp.checksum = calculateChecksum(tmp);
saveSettings();
EEPROM.put(0, tmp);
Serial.println(F("Defaults written to EEPROM."));
}
else
{
motor.setConfig(settings.motorConfig);
pedal.setConfig(settings.pedalConfig);
Serial.println("Settings loaded from EEPROM.");
motor.setConfig(tmp.motorConfig);
pedal.setConfig(tmp.pedalConfig);
Serial.println(F("Settings loaded from EEPROM."));
}
}
void saveSettings()
{
settings.motorConfig = motor.getConfig();
settings.pedalConfig = pedal.getConfig();
settings.checksum = calculateChecksum(settings);
Settings_t tmp;
tmp.motorConfig = motor.getConfig();
tmp.pedalConfig = pedal.getConfig();
tmp.checksum = calculateChecksum(tmp);
EEPROM.put(0, settings);
Serial.println("Settings saved to EEPROM.");
EEPROM.put(0, tmp);
Serial.println(F("Settings saved to EEPROM."));
}
uint8_t calculateChecksum(const Settings &s)
uint8_t calculateChecksum(const Settings_t &s)
{
uint8_t sum = 0;
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];
}
@@ -314,6 +281,7 @@ void handleEncoderButton()
// Encoder-Button-Logik
}
#ifdef DISPLAY_ENABLED
void updateDisplay()
{
display.clearDisplay();
@@ -334,24 +302,10 @@ void updateDisplay()
display.display();
}
#endif
void configurePWMFrequency()
{
// Configure Timer1 for higher PWM frequency (~4 kHz)
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);
}