Ich stelle folgenden Code zur Verfügung zur Steuerung eines Gleichstrommotors über PWM. In meinem Fall ist der PWM-Pin mit dem Motion Controller von Faulhaber verbunden. Demnächst möchte ich die zuletzt eingestellte Geschwindigkeit auf einer SD-Karte speichern. Ich poste ein Demo-Video zum Anschauen.
#include "DIALOG.h"
static int DrehzahlPin = 9;
static int g_SliderValue = 0;
static int g_NumTicks = 80;
static int g_SliderWidth = 50;
static WM_HWIN hSlider = 0;
#define ID_BUTTON (GUI_ID_USER + 0)
static int g_Locked = 1; // Startzustand: gesperrt (1 = gesperrt, 0 = entsperrt)
static int lastValidPWM = 127.5; // Speichert den letzten PWM-Wert
static int _MySliderDrawSkin(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo) {
return SLIDER_DrawSkinFlex(pDrawItemInfo);
}
static void _SetSliderState(int lock) {
if (lock) {
WM_DisableWindow(hSlider);
} else {
WM_EnableWindow(hSlider);
}
}
static void _cbChildWinSlider(WM_MESSAGE * pMsg) {
int Value;
char acBuffer[32];
static WM_HWIN hButton;
static int lastValidValue = 0;
switch (pMsg->MsgId) {
case WM_CREATE:
hSlider = SLIDER_CreateEx(0, 380, 800, 100,
pMsg->hWin, WM_CF_SHOW,
SLIDER_CF_HORIZONTAL, GUI_ID_SLIDER0);
SLIDER_SetRange(hSlider, -500, 500);
SLIDER_SetNumTicks(hSlider, g_NumTicks);
SLIDER_SetValue(hSlider, 0);
SLIDER_SetWidth(hSlider, g_SliderWidth);
SLIDER_SetSkin(hSlider, _MySliderDrawSkin);
hButton = BUTTON_CreateEx(300, 250, 200, 80, pMsg->hWin, WM_CF_SHOW, 0, ID_BUTTON);
BUTTON_SetText(hButton, g_Locked ? "RPM-Gesperrt" : "RPM-Entsperrt");
_SetSliderState(g_Locked);
break;
case WM_PAINT: {
GUI_SetBkColor(GUI_WHITE);
GUI_Clear();
GUI_SetFont(&GUI_FontD60x80);
GUI_SetColor(GUI_BLACK);
Value = g_Locked ? lastValidValue : g_SliderValue;
sprintf(acBuffer, "%d RPM", Value);
int textWidth = GUI_GetStringDistX(acBuffer);
int xPos = (LCD_GetXSize() - textWidth) / 2;
GUI_DispStringAt(acBuffer, xPos, 100);
GUI_SetFont(&GUI_Font32B_1);
GUI_DispString("RPM");
// Ticks zeichnen
int y0 = 380;
int width = 847;
int height = 100;
int tickThickness = 4;
int shortTickLength = 10;
int longTickLength = 20;
GUI_SetColor(GUI_BLACK);
for (int i = 0; i <= g_NumTicks; i++) {
int x = (width - g_SliderWidth) * i / g_NumTicks;
int currentTickLength = (i % 5 == 0) ? longTickLength : shortTickLength;
for (int t = 0; t < tickThickness; t++) {
GUI_DrawLine(x + t, y0, x + t, y0 + currentTickLength);
}
for (int t = 0; t < tickThickness; t++) {
GUI_DrawLine(x + t, y0 + height - currentTickLength, x + t, y0 + height);
}
}
break;
}
case WM_NOTIFY_PARENT: {
int Id = WM_GetId(pMsg->hWinSrc);
int NCode = pMsg->Data.v;
if (Id == GUI_ID_SLIDER0 && NCode == WM_NOTIFICATION_VALUE_CHANGED) {
if (!g_Locked) {
lastValidValue = SLIDER_GetValue(hSlider);
g_SliderValue = lastValidValue;
// PWM-Wert berechnen und speichern
lastValidPWM = (lastValidValue <= 0) ?
(int)((lastValidValue + 500) / 500.0 * 127.5) :
(int)(lastValidValue / 500.0 * 127.5 + 127.5);
}
WM_InvalidateWindow(pMsg->hWin);
}
else if (Id == ID_BUTTON) {
switch (NCode) {
case WM_NOTIFICATION_RELEASED:
g_Locked = !g_Locked;
BUTTON_SetText(pMsg->hWinSrc, g_Locked ? "RPM-Gesperrt" : "RPM-Entsperrt");
_SetSliderState(g_Locked);
WM_InvalidateWindow(pMsg->hWin);
break;
}
}
break;
}
default:
WM_DefaultProc(pMsg);
break;
}
}
void setup() {
Serial.begin(9600);
delay(100);
pinMode(DrehzahlPin, OUTPUT);
GUI_Init();
LCD_ROTATE_SetSel(1);
WM_MULTIBUF_Enable(1);
WM_CreateWindowAsChild(0, 0, LCD_GetXSize(), LCD_GetYSize(),
WM_HBKWIN, WM_CF_SHOW, _cbChildWinSlider, 0);
}
void loop() {
if (!g_Locked) {
// Im entsperrten Zustand: aktuellen Sliderwert verwenden
int v = g_SliderValue;
if (v < -500) v = -500;
if (v > 500) v = 500;
lastValidPWM = (v <= 0) ? (int)((v + 500) / 500.0 * 127.5)
: (int)(v / 500.0 * 127.5 + 127.5);
}
// Im gesperrten Zustand: letzten PWM-Wert weiterverwenden
analogWrite(DrehzahlPin, lastValidPWM);
Serial.println(lastValidPWM);
GUI_Exec();
}


