/
CheshirCa
/
ESP32-LED-CPUmeter
Обзор
Документация
Войти
/
CheshirCa
/
ESP32-LED-CPUmeter
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
DebugModeClient/DebugModeClient.pb
419 строк
11 KB
Anton Kovalev
Update
27 июн 2026, 00:15
27 июн 2026, 00:15
2290fdd
Код
Авторство
О чём код?
; Non-Commercial License ; ; Copyright (C) CheshirCa 2026 ; ; https://t.me/cheshircanest ; ; This software may be used, copied, modified, and distributed only for non-commercial purposes, provided that proper attribution is preserved. ; ; The following activities are prohibited without explicit written permission from the author: ; ; - commercial use of the software; ; - selling the software or modified versions; ; - including the software in commercial products or services; ; - paid distribution of source code or binaries. ; ; Any redistribution or modification must preserve the following attribution: ; ; Copyright (C) CheshirCa 2026 https://t.me/cheshircanest ; ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. THE AUTHOR SHALL NOT BE LIABLE FOR ANY DAMAGES ARISING FROM THE USE OF THIS SOFTWARE. ; ; ESP32 CPU Meter Debug Mode Test Client ; PureBasic 6.40, Windows 10/11 ; ; Sends per-pixel RGB data to the controller after DEBUG ON. EnableExplicit #AppName = "ESP32 Debug LED Test" #SerialBaud = 115200 #LedCount = 16 #TimerFrame = 1 #SerialDebug = 0 Enumeration Windows #WindowMain EndEnumeration Enumeration Gadgets #GadgetPort #GadgetRefresh #GadgetStart #GadgetStop #GadgetMode #GadgetFps #GadgetBrightness #GadgetPreview #GadgetStatus #GadgetExit EndEnumeration Global Connected = #False Global FrameIndex.i = 0 Global Dim LedR.i(#LedCount - 1) Global Dim LedG.i(#LedCount - 1) Global Dim LedB.i(#LedCount - 1) Global Dim LedV.i(#LedCount - 1) Declare UpdateControls() Declare SendDebugOff() Procedure.i Clamp(Value.i, MinValue.i, MaxValue.i) If Value < MinValue ProcedureReturn MinValue EndIf If Value > MaxValue ProcedureReturn MaxValue EndIf ProcedureReturn Value EndProcedure Procedure.s PortNameForOpen(DisplayName$) If Left(DisplayName$, 3) = "COM" And Val(Mid(DisplayName$, 4)) >= 10 ProcedureReturn "\\.\" + DisplayName$ EndIf ProcedureReturn DisplayName$ EndProcedure Procedure FillPortList() Protected Index.i Protected Port$ ClearGadgetItems(#GadgetPort) For Index = 1 To 64 Port$ = "COM" + Str(Index) If OpenSerialPort(#SerialDebug, PortNameForOpen(Port$), #SerialBaud, #PB_SerialPort_NoParity, 8, 1.0, #PB_SerialPort_NoHandshake, 512, 512) CloseSerialPort(#SerialDebug) AddGadgetItem(#GadgetPort, -1, Port$) EndIf Next If CountGadgetItems(#GadgetPort) > 0 And GetGadgetText(#GadgetPort) = "" SetGadgetState(#GadgetPort, 0) EndIf EndProcedure Procedure.s ReadSerialText(TimeoutMs.i) Protected Deadline.i = ElapsedMilliseconds() + TimeoutMs Protected Available.i Protected BytesRead.i Protected Result$ = "" Protected *Buffer = AllocateMemory(1024) If *Buffer = 0 ProcedureReturn "" EndIf While ElapsedMilliseconds() < Deadline If IsSerialPort(#SerialDebug) Available = AvailableSerialPortInput(#SerialDebug) If Available > 0 If Available > 1023 Available = 1023 EndIf BytesRead = ReadSerialPortData(#SerialDebug, *Buffer, Available) If BytesRead > 0 Result$ + PeekS(*Buffer, BytesRead, #PB_UTF8) If FindString(Result$, "OK ") Or FindString(Result$, "PONG ") Or FindString(Result$, "ERR ") Break EndIf EndIf EndIf EndIf Delay(5) Wend FreeMemory(*Buffer) ProcedureReturn Result$ EndProcedure Procedure.s SendCommand(Command$, TimeoutMs.i = 300) If IsSerialPort(#SerialDebug) = 0 ProcedureReturn "" EndIf WriteSerialPortString(#SerialDebug, Command$ + #LF$, #PB_UTF8) ProcedureReturn ReadSerialText(TimeoutMs) EndProcedure Procedure.i ConnectDebug() Protected Port$ = GetGadgetText(#GadgetPort) Protected Reply$ If Port$ = "" SetGadgetText(#GadgetStatus, "Select COM port") ProcedureReturn #False EndIf If OpenSerialPort(#SerialDebug, PortNameForOpen(Port$), #SerialBaud, #PB_SerialPort_NoParity, 8, 1.0, #PB_SerialPort_NoHandshake, 8192, 8192) = 0 SetGadgetText(#GadgetStatus, "Cannot open " + Port$) ProcedureReturn #False EndIf SerialPortTimeouts(#SerialDebug, 1, 1, 1, 1, 1) Delay(1500) ReadSerialText(100) Reply$ = SendCommand("PING", 1200) If FindString(Reply$, "PONG ESP32C3LCD_CPUMETER") = 0 CloseSerialPort(#SerialDebug) SetGadgetText(#GadgetStatus, "No controller reply on " + Port$) ProcedureReturn #False EndIf Reply$ = SendCommand("DEBUG ON", 1200) If FindString(Reply$, "OK DEBUG=ON") = 0 CloseSerialPort(#SerialDebug) SetGadgetText(#GadgetStatus, "DEBUG ON failed") ProcedureReturn #False EndIf Connected = #True FrameIndex = 0 SetGadgetText(#GadgetStatus, "Debug connected: " + Port$) UpdateControls() ProcedureReturn #True EndProcedure Procedure SendDebugOff() If IsSerialPort(#SerialDebug) SendCommand("DEBUG OFF", 800) CloseSerialPort(#SerialDebug) EndIf Connected = #False UpdateControls() SetGadgetText(#GadgetStatus, "Disconnected") EndProcedure Procedure.i HsvToRgb(Hue.i, Sat.i, Val.i) Protected Region.i = Hue / 43 Protected Remainder.i = (Hue - (Region * 43)) * 6 Protected P.i = (Val * (255 - Sat)) >> 8 Protected Q.i = (Val * (255 - ((Sat * Remainder) >> 8))) >> 8 Protected T.i = (Val * (255 - ((Sat * (255 - Remainder)) >> 8))) >> 8 Select Region Case 0 ProcedureReturn RGB(Val, T, P) Case 1 ProcedureReturn RGB(Q, Val, P) Case 2 ProcedureReturn RGB(P, Val, T) Case 3 ProcedureReturn RGB(P, Q, Val) Case 4 ProcedureReturn RGB(T, P, Val) Default ProcedureReturn RGB(Val, P, Q) EndSelect EndProcedure Procedure SetLed(Index.i, RedValue.i, GreenValue.i, BlueValue.i, Brightness.i) If Index < 0 Or Index >= #LedCount ProcedureReturn EndIf LedR(Index) = Clamp(RedValue, 0, 255) LedG(Index) = Clamp(GreenValue, 0, 255) LedB(Index) = Clamp(BlueValue, 0, 255) LedV(Index) = Clamp(Brightness, 0, 255) EndProcedure Procedure RenderFrame() Protected Mode.i = GetGadgetState(#GadgetMode) Protected Brightness.i = Clamp(Val(GetGadgetText(#GadgetBrightness)), 0, 255) Protected I.i Protected Color.i Protected Level.i Protected Head.i Protected Dist.i Select Mode Case 0 ; Rainbow For I = 0 To #LedCount - 1 Color = HsvToRgb((FrameIndex * 4 + I * 255 / #LedCount) & $FF, 255, 255) SetLed(I, Red(Color), Green(Color), Blue(Color), Brightness) Next Case 1 ; Comet Head = FrameIndex % #LedCount For I = 0 To #LedCount - 1 Dist = (Head - I + #LedCount) % #LedCount If Dist < 5 Level = Brightness - Dist * (Brightness / 5) SetLed(I, 255, 70, 0, Level) Else SetLed(I, 0, 0, 0, 0) EndIf Next Case 2 ; Fake audio bars For I = 0 To #LedCount - 1 Level = 30 + Abs(Sin((FrameIndex + I * 5) / 8.0) * 225) Color = HsvToRgb(96 - I * 4 + Level / 6, 255, 255) SetLed(I, Red(Color), Green(Color), Blue(Color), (Brightness * Level) / 255) Next Case 3 ; Sparkles For I = 0 To #LedCount - 1 LedV(I) = Clamp(LedV(I) - 20, 0, 255) If LedV(I) = 0 LedR(I) = 0 LedG(I) = 0 LedB(I) = 0 EndIf Next I = Random(#LedCount - 1) Color = HsvToRgb(Random(255), 220, 255) SetLed(I, Red(Color), Green(Color), Blue(Color), Brightness) Case 4 ; Solid color pulse Level = 60 + Abs(Sin(FrameIndex / 10.0) * 195) For I = 0 To #LedCount - 1 SetLed(I, 0, 120, 255, (Brightness * Level) / 255) Next EndSelect FrameIndex + 1 EndProcedure Procedure SendFrame() Protected I.i Protected Line$ If Connected = #False Or IsSerialPort(#SerialDebug) = 0 ProcedureReturn EndIf For I = 0 To #LedCount - 1 Line$ = Str(I) + " " + Str(LedR(I)) + " " + Str(LedG(I)) + " " + Str(LedB(I)) + " " + Str(LedV(I)) + #LF$ WriteSerialPortString(#SerialDebug, Line$, #PB_UTF8) Next EndProcedure Procedure DrawPreview() Protected I.i Protected X.i Protected W.i = 20 Protected H.i = 28 Protected Scale.f Protected Color.i If StartDrawing(CanvasOutput(#GadgetPreview)) DrawingMode(#PB_2DDrawing_Default) Box(0, 0, OutputWidth(), OutputHeight(), RGB(20, 22, 26)) For I = 0 To #LedCount - 1 X = 8 + I * 22 Scale = LedV(I) / 255.0 Color = RGB(LedR(I) * Scale, LedG(I) * Scale, LedB(I) * Scale) DrawingMode(#PB_2DDrawing_Default) Box(X, 12, W, H, Color) DrawingMode(#PB_2DDrawing_Outlined) Box(X, 12, W, H, RGB(60, 60, 64)) Next DrawingMode(#PB_2DDrawing_Default) StopDrawing() EndIf EndProcedure Procedure UpdateControls() DisableGadget(#GadgetStart, Connected) DisableGadget(#GadgetStop, 1 - Connected) DisableGadget(#GadgetPort, Connected) DisableGadget(#GadgetRefresh, Connected) EndProcedure Procedure UpdateTimer() Protected Fps.i = Clamp(Val(GetGadgetText(#GadgetFps)), 1, 60) RemoveWindowTimer(#WindowMain, #TimerFrame) AddWindowTimer(#WindowMain, #TimerFrame, 1000 / Fps) EndProcedure Procedure CreateInterface() If OpenWindow(#WindowMain, 0, 0, 390, 250, #AppName, #PB_Window_SystemMenu | #PB_Window_ScreenCentered) TextGadget(#PB_Any, 14, 18, 60, 20, "COM") ComboBoxGadget(#GadgetPort, 70, 14, 110, 25, #PB_ComboBox_Editable) ButtonGadget(#GadgetRefresh, 190, 14, 80, 25, "Refresh") ButtonGadget(#GadgetStart, 280, 14, 45, 25, "Start") ButtonGadget(#GadgetStop, 330, 14, 45, 25, "Stop") TextGadget(#PB_Any, 14, 58, 60, 20, "Mode") ComboBoxGadget(#GadgetMode, 70, 54, 170, 25) AddGadgetItem(#GadgetMode, -1, "Rainbow") AddGadgetItem(#GadgetMode, -1, "Comet") AddGadgetItem(#GadgetMode, -1, "Fake audio bars") AddGadgetItem(#GadgetMode, -1, "Sparkles") AddGadgetItem(#GadgetMode, -1, "Solid pulse") SetGadgetState(#GadgetMode, 0) TextGadget(#PB_Any, 254, 58, 34, 20, "FPS") StringGadget(#GadgetFps, 288, 54, 38, 25, "30", #PB_String_Numeric) TextGadget(#PB_Any, 14, 94, 70, 20, "Brightness") StringGadget(#GadgetBrightness, 90, 90, 48, 25, "120", #PB_String_Numeric) CanvasGadget(#GadgetPreview, 14, 128, 360, 54) TextGadget(#GadgetStatus, 14, 196, 260, 20, "Disconnected") ButtonGadget(#GadgetExit, 294, 192, 80, 25, "Exit") FillPortList() DrawPreview() UpdateTimer() UpdateControls() EndIf EndProcedure Procedure Main() Protected Event.i Protected Quit.i = #False CreateInterface() Repeat Event = WaitWindowEvent(20) Select Event Case #PB_Event_CloseWindow Quit = #True Case #PB_Event_Timer If EventTimer() = #TimerFrame RenderFrame() If Connected SendFrame() EndIf DrawPreview() EndIf Case #PB_Event_Gadget Select EventGadget() Case #GadgetRefresh FillPortList() Case #GadgetStart UpdateTimer() ConnectDebug() Case #GadgetStop SendDebugOff() Case #GadgetFps If EventType() = #PB_EventType_Change UpdateTimer() EndIf Case #GadgetExit Quit = #True EndSelect EndSelect Until Quit SendDebugOff() EndProcedure Main()