├── .gitattributes ├── 3dprint ├── motor.stl ├── print_me.stl └── screen.stl ├── LICENSE ├── README.md ├── firmware └── MagicGyver │ ├── MagicGyver.ino │ ├── config.h │ ├── data.h │ ├── hub.h │ ├── manual.h │ └── stepper.h ├── libraries ├── GyverHub │ ├── .gitattributes │ ├── LICENSE │ ├── README.md │ ├── examples │ │ ├── basic │ │ │ └── basic.ino │ │ ├── canvas │ │ │ └── canvas.ino │ │ ├── dynamic_components │ │ │ └── dynamic_components.ino │ │ ├── esp32cam-frame │ │ │ ├── camera.h │ │ │ └── esp32cam-frame.ino │ │ ├── esp32cam-stream │ │ │ ├── camera.h │ │ │ ├── camera_stream.h │ │ │ ├── esp32cam-frame.ino │ │ │ └── esp32cam-stream.ino │ │ ├── full_demo │ │ │ └── full_demo.ino │ │ ├── joy_demo │ │ │ └── joy_demo.ino │ │ ├── struct_demo │ │ │ └── struct_demo.ino │ │ └── update │ │ │ └── update.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ │ ├── GyverHub.h │ │ ├── async │ │ ├── http.h │ │ ├── mqtt.h │ │ └── ws.h │ │ ├── builder.h │ │ ├── canvas.h │ │ ├── config.hpp │ │ ├── esp_inc │ │ ├── index.h │ │ ├── script.h │ │ └── style.h │ │ ├── macro.hpp │ │ ├── stream.h │ │ ├── sync │ │ ├── http.h │ │ ├── mqtt.h │ │ └── ws.h │ │ └── utils │ │ ├── action.h │ │ ├── b64.cpp │ │ ├── b64.h │ │ ├── build.h │ │ ├── button.h │ │ ├── client.h │ │ ├── cmd_p.cpp │ │ ├── cmd_p.h │ │ ├── color.h │ │ ├── datatypes.cpp │ │ ├── datatypes.h │ │ ├── flags.h │ │ ├── log.h │ │ ├── mime.h │ │ ├── misc.cpp │ │ ├── misc.h │ │ ├── modules.h │ │ ├── pos.h │ │ ├── pos_geo.cpp │ │ ├── pos_geo.h │ │ ├── stats.h │ │ ├── stats_p.cpp │ │ ├── stats_p.h │ │ └── timer.h ├── GyverStepper │ ├── .gitattributes │ ├── LICENSE │ ├── README.md │ ├── README_EN.md │ ├── examples │ │ ├── Planner │ │ │ ├── PlannerArray │ │ │ │ └── PlannerArray.ino │ │ │ ├── PlannerCircle │ │ │ │ ├── PlannerCircle.ino │ │ │ │ └── stepperPlot │ │ │ │ │ └── stepperPlot.pde │ │ │ ├── PlannerControl │ │ │ │ └── PlannerControl.ino │ │ │ ├── PlannerDemo │ │ │ │ └── PlannerDemo.ino │ │ │ ├── PlannerHoming │ │ │ │ └── PlannerHoming.ino │ │ │ ├── PlannerSpeedControl │ │ │ │ └── PlannerSpeedControl.ino │ │ │ └── PlannerTimerISR │ │ │ │ ├── PlannerTimerISR.ino │ │ │ │ └── timer.ino │ │ ├── Planner2 │ │ │ ├── PlannerArray │ │ │ │ ├── PlannerArray.ino │ │ │ │ └── stepperPlot │ │ │ │ │ └── stepperPlot.pde │ │ │ ├── PlannerCircle │ │ │ │ ├── PlannerCircle.ino │ │ │ │ └── stepperPlot │ │ │ │ │ └── stepperPlot.pde │ │ │ └── PlannerCircleISR │ │ │ │ ├── PlannerCircleISR.ino │ │ │ │ ├── stepperPlot │ │ │ │ └── stepperPlot.pde │ │ │ │ └── timer.ino │ │ ├── Stepper │ │ │ ├── accelDeccelButton │ │ │ │ └── accelDeccelButton.ino │ │ │ ├── demo │ │ │ │ └── demo.ino │ │ │ ├── endSwitch │ │ │ │ └── endSwitch.ino │ │ │ ├── externalDriver │ │ │ │ └── externalDriver.ino │ │ │ ├── multiStepper │ │ │ │ └── multiStepper.ino │ │ │ ├── potPos │ │ │ │ └── potPos.ino │ │ │ ├── potSpeed │ │ │ │ └── potSpeed.ino │ │ │ ├── smoothAlgorithm │ │ │ │ └── smoothAlgorithm.ino │ │ │ ├── speed │ │ │ │ └── speed.ino │ │ │ ├── speedSerialControl │ │ │ │ └── speedSerialControl.ino │ │ │ ├── stop │ │ │ │ └── stop.ino │ │ │ ├── sweep │ │ │ │ └── sweep.ino │ │ │ └── timerISR │ │ │ │ └── timerISR.ino │ │ └── Stepper2 │ │ │ ├── SpeedControl │ │ │ └── SpeedControl.ino │ │ │ ├── StepperControl │ │ │ └── StepperControl.ino │ │ │ ├── homing │ │ │ └── homing.ino │ │ │ ├── sweep │ │ │ └── sweep.ino │ │ │ ├── sweepISR │ │ │ ├── sweepISR.ino │ │ │ └── timer.ino │ │ │ └── sweep_FAST_PROFILE │ │ │ └── sweep_FAST_PROFILE.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ │ ├── FIFO.h │ │ ├── GStypes.h │ │ ├── GyverPlanner.h │ │ ├── GyverPlanner2.h │ │ ├── GyverStepper.h │ │ ├── GyverStepper2.h │ │ └── StepperCore.h └── arduinoWebSockets-2.3.6 │ ├── .clang-format │ ├── .github │ └── workflows │ │ └── main.yml │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── examples │ ├── Nginx │ │ └── esp8266.ssl.reverse.proxy.conf │ ├── avr │ │ └── WebSocketClientAVR │ │ │ └── WebSocketClientAVR.ino │ ├── esp32 │ │ ├── WebSocketClient │ │ │ └── WebSocketClient.ino │ │ ├── WebSocketClientSSL │ │ │ └── WebSocketClientSSL.ino │ │ ├── WebSocketClientSocketIOack │ │ │ └── WebSocketClientSocketIOack.ino │ │ └── WebSocketServer │ │ │ └── WebSocketServer.ino │ ├── esp8266 │ │ ├── WebSocketClient │ │ │ └── WebSocketClient.ino │ │ ├── WebSocketClientOTA │ │ │ ├── README.md │ │ │ ├── WebSocketClientOTA.ino │ │ │ └── python_ota_server │ │ │ │ ├── main.py │ │ │ │ └── requirements.txt │ │ ├── WebSocketClientSSL │ │ │ └── WebSocketClientSSL.ino │ │ ├── WebSocketClientSSLWithCA │ │ │ └── WebSocketClientSSLWithCA.ino │ │ ├── WebSocketClientSocketIO │ │ │ └── WebSocketClientSocketIO.ino │ │ ├── WebSocketClientSocketIOack │ │ │ └── WebSocketClientSocketIOack.ino │ │ ├── WebSocketClientStomp │ │ │ └── WebSocketClientStomp.ino │ │ ├── WebSocketClientStompOverSockJs │ │ │ └── WebSocketClientStompOverSockJs.ino │ │ ├── WebSocketServer │ │ │ └── WebSocketServer.ino │ │ ├── WebSocketServerAllFunctionsDemo │ │ │ └── WebSocketServerAllFunctionsDemo.ino │ │ ├── WebSocketServerFragmentation │ │ │ └── WebSocketServerFragmentation.ino │ │ ├── WebSocketServerHooked │ │ │ ├── WebSocketServerHooked.ino │ │ │ ├── emu │ │ │ └── ws-testclient.py │ │ ├── WebSocketServerHttpHeaderValidation │ │ │ └── WebSocketServerHttpHeaderValidation.ino │ │ └── WebSocketServer_LEDcontrol │ │ │ └── WebSocketServer_LEDcontrol.ino │ └── particle │ │ └── ParticleWebSocketClient │ │ └── application.cpp │ ├── library.json │ ├── library.properties │ ├── src │ ├── SocketIOclient.cpp │ ├── SocketIOclient.h │ ├── WebSockets.cpp │ ├── WebSockets.h │ ├── WebSockets4WebServer.h │ ├── WebSocketsClient.cpp │ ├── WebSocketsClient.h │ ├── WebSocketsServer.cpp │ ├── WebSocketsServer.h │ ├── WebSocketsVersion.h │ ├── libb64 │ │ ├── AUTHORS │ │ ├── LICENSE │ │ ├── cdecode.c │ │ ├── cdecode_inc.h │ │ ├── cencode.c │ │ └── cencode_inc.h │ └── libsha1 │ │ ├── libsha1.c │ │ └── libsha1.h │ ├── tests │ ├── webSocket.html │ └── webSocketServer │ │ ├── index.js │ │ └── package.json │ └── travis │ ├── common.sh │ └── version.py ├── schemes ├── scheme1.jpg └── scheme2.png └── tracer-test ├── index.html └── main.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /3dprint/motor.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexGyver/MagicGyver/b515148034cbed1da88869a296a1107ba9b16f12/3dprint/motor.stl -------------------------------------------------------------------------------- /3dprint/print_me.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexGyver/MagicGyver/b515148034cbed1da88869a296a1107ba9b16f12/3dprint/print_me.stl -------------------------------------------------------------------------------- /3dprint/screen.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexGyver/MagicGyver/b515148034cbed1da88869a296a1107ba9b16f12/3dprint/screen.stl -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 AlexGyver 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MagicGyver 2 | ЧПУ станок из "Волшебного экрана" 3 | 4 | Подготовка изображений - https://alexgyver.github.io/MagicGyver/ -------------------------------------------------------------------------------- /firmware/MagicGyver/MagicGyver.ino: -------------------------------------------------------------------------------- 1 | // НАСТРОЙКИ В ФАЙЛЕ config.h !!! 2 | 3 | #include 4 | #include 5 | 6 | #include "config.h" 7 | #include "stepper.h" 8 | #include "hub.h" 9 | 10 | void setup() { 11 | data_init(); 12 | step_init(); 13 | 14 | Serial.begin(115200); 15 | 16 | WiFi.mode(WIFI_STA); 17 | WiFi.begin(AP_SSID, AP_PASS); 18 | while (WiFi.status() != WL_CONNECTED) { 19 | delay(500); 20 | Serial.print("."); 21 | } 22 | Serial.println("\nConnected!"); 23 | 24 | hub_init(); 25 | } 26 | 27 | void loop() { 28 | hub_tick(); 29 | } -------------------------------------------------------------------------------- /firmware/MagicGyver/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define AP_SSID "" 4 | #define AP_PASS "" 5 | 6 | #define MOTX_STEP D5 7 | #define MOTX_DIR D6 8 | #define MOTX_EN D7 9 | #define MOTY_STEP D1 10 | #define MOTY_DIR D2 11 | #define MOTY_EN D3 -------------------------------------------------------------------------------- /firmware/MagicGyver/data.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | struct Data { 6 | uint16_t width = 10000; 7 | uint16_t height = 8000; 8 | uint16_t max_spd = 2000; 9 | uint8_t lashx = 0; 10 | uint8_t lashy = 0; 11 | uint8_t spp = 18; 12 | } data; 13 | 14 | EEManager memory(data); 15 | 16 | void data_init() { 17 | EEPROM.begin(memory.blockSize()); 18 | memory.begin(0, 'a'); 19 | } -------------------------------------------------------------------------------- /firmware/MagicGyver/manual.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | class ManualStepper { 6 | public: 7 | ManualStepper(Stepper<_DRV>* st) : stepper(st) {} 8 | void start(int16_t speed) { 9 | stepper->dir = (speed > 0) ? 1 : -1; 10 | if (speed) { 11 | prd = 1000000ul / abs(speed); 12 | stepper->enable(); 13 | } else { 14 | prd = 0; 15 | stepper->disable(); 16 | } 17 | } 18 | void stop() { 19 | prd = 0; 20 | stepper->disable(); 21 | } 22 | void tick() { 23 | if (prd) { 24 | uint32_t us = micros(); 25 | if (us - tmr >= prd) { 26 | tmr = us; 27 | stepper->step(); 28 | } 29 | } 30 | } 31 | bool running() { 32 | return prd; 33 | } 34 | 35 | private: 36 | Stepper<_DRV>* stepper; 37 | uint32_t tmr, prd; 38 | }; -------------------------------------------------------------------------------- /firmware/MagicGyver/stepper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "config.h" 5 | #include "data.h" 6 | #include "manual.h" 7 | 8 | Stepper step_x(MOTX_STEP, MOTX_DIR, MOTX_EN); 9 | Stepper step_y(MOTY_STEP, MOTY_DIR, MOTY_EN); 10 | ManualStepper mx(&step_x); 11 | ManualStepper my(&step_y); 12 | GPlanner planner; 13 | 14 | void step_init() { 15 | planner.addStepper(0, step_x); 16 | planner.addStepper(1, step_y); 17 | //planner.autoPower(1); 18 | planner.disable(); 19 | 20 | planner.setAcceleration(0); 21 | planner.setMaxSpeed(data.max_spd); 22 | 23 | planner.setBacklash(0, data.lashx); 24 | planner.setBacklash(1, data.lashy); 25 | } -------------------------------------------------------------------------------- /libraries/GyverHub/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /libraries/GyverHub/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 AlexGyver 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libraries/GyverHub/examples/canvas/canvas.ino: -------------------------------------------------------------------------------- 1 | // CANVAS DEMO 2 | 3 | // WiFi 4 | #define AP_SSID "" 5 | #define AP_PASS "" 6 | 7 | #include 8 | #include 9 | GyverHub hub("MyDevices", "ESP8266", ""); 10 | 11 | GHpos pos1; // обработка кликов по холсту 12 | 13 | void build() { 14 | hub.BeginWidgets(); 15 | 16 | // пустой холст, 400x300px 17 | // зададим имя, чтобы обновлять его ниже в loop() 18 | hub.Canvas_(F("cv")); 19 | 20 | hub.WidgetSize(50); 21 | 22 | // холст с рисунком. Обязательный порядок вызова: создать, начать, рисовать, закончить 23 | GHcanvas cv1; // создать холст 24 | // начать рисование, холст 200x200, обработка кликов 25 | // зададим имя, чтобы обновлять его ниже в loop() 26 | hub.BeginCanvas_(F("cv1"), 200, 200, &cv1, &pos1); 27 | cv1.stroke(0xff0000); 28 | cv1.strokeWeight(5); 29 | cv1.line(0, 0, -1, -1); 30 | cv1.line(0, -1, -1, 0); 31 | hub.EndCanvas(); // закончить холст 32 | 33 | // и ещё один 34 | GHcanvas cv2; 35 | // зададим имя, чтобы обновлять его ниже в loop() 36 | hub.BeginCanvas_(F("cv2"), 300, 300, &cv2); 37 | cv2.fill(0x00ff00); 38 | cv2.noStroke(); 39 | cv2.circle(150, 150, 50); 40 | hub.EndCanvas(); 41 | } 42 | 43 | void setup() { 44 | Serial.begin(115200); 45 | 46 | #ifdef GH_ESP_BUILD 47 | WiFi.mode(WIFI_STA); 48 | WiFi.begin(AP_SSID, AP_PASS); 49 | while (WiFi.status() != WL_CONNECTED) { 50 | delay(500); 51 | Serial.print("."); 52 | } 53 | Serial.println(); 54 | Serial.println(WiFi.localIP()); 55 | 56 | hub.setupMQTT("test.mosquitto.org", 1883); 57 | #endif 58 | 59 | hub.onBuild(build); 60 | hub.begin(); 61 | } 62 | 63 | void loop() { 64 | hub.tick(); 65 | 66 | // обработка кликов 67 | if (pos1.changed()) { 68 | Serial.println("Canvas 1 click:"); 69 | Serial.println(pos1.x); 70 | Serial.println(pos1.y); 71 | 72 | // выведем кружок в место клика 73 | GHcanvas cv; 74 | hub.sendCanvasBegin(F("cv1"), cv); 75 | cv.circle(pos1.x, pos1.y, 10); 76 | hub.sendCanvasEnd(cv); 77 | } 78 | 79 | // обновление холста по таймеру 80 | static GHtimer tmr(300); 81 | if (tmr.ready()) { 82 | // способ 1 83 | GHcanvas cv; // создать холст 84 | cv.noStroke(); 85 | cv.fill(GHcolor(random(255), random(255), random(255)), random(100, 255)); 86 | cv.circle(random(0, 400), random(0, 300), random(5, 30)); 87 | hub.sendCanvas(F("cv"), cv); // отправить холст 88 | 89 | // способ 2 (использует меньше оперативной памяти!) 90 | GHcanvas cv2; // создать холст 91 | hub.sendCanvasBegin(F("cv2"), cv2); // начать отправку 92 | cv2.stroke(0xffffff, 100); 93 | cv2.strokeWeight(5); 94 | cv2.line(random(0, 300), random(0, 300), random(0, 300), random(0, 300)); 95 | hub.sendCanvasEnd(cv2); // закончить отправку 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /libraries/GyverHub/examples/dynamic_components/dynamic_components.ino: -------------------------------------------------------------------------------- 1 | // динамически создаваемые компоненты 2 | 3 | #include 4 | 5 | #define AP_SSID "" 6 | #define AP_PASS "" 7 | 8 | #include 9 | GyverHub hub("MyDevices", "ESP8266", ""); 10 | 11 | #define MAX_TEXT 20 12 | #define DYN_MAX 5 13 | bool sws[DYN_MAX]; 14 | int16_t slds[DYN_MAX]; 15 | char inputs[DYN_MAX][20]; 16 | uint8_t spin_am = 2; 17 | uint8_t tab = 0; 18 | 19 | void build() { 20 | hub.BeginWidgets(); 21 | 22 | hub.WidgetSize(80); 23 | hub.Tabs(&tab, F("Sliders,Switches,Inputs,Buttons")); 24 | 25 | // спиннер с настройкой количества. По клику обновляем страницу 26 | hub.WidgetSize(20); 27 | if (hub.Spinner(&spin_am, GH_UINT8, F("Amount"), 0, DYN_MAX, 1)) { 28 | hub.refresh(); 29 | } 30 | 31 | switch (tab) { 32 | case 0: 33 | hub.WidgetSize(100); 34 | for (int i = 0; i < spin_am; i++) { 35 | bool a = hub.Slider(&slds[i], GH_INT16, String("Slider #") + i); 36 | if (a) Serial.println(String("Set slider: #") + i + ", value: " + slds[i]); 37 | } 38 | break; 39 | case 1: 40 | hub.WidgetSize(25); 41 | for (int i = 0; i < spin_am; i++) { 42 | bool a = hub.Switch(&sws[i], String("Switch #") + i); 43 | if (a) Serial.println(String("Set switch: #") + i + ", value: " + sws[i]); 44 | } 45 | break; 46 | case 2: 47 | hub.WidgetSize(50); 48 | for (int i = 0; i < spin_am; i++) { 49 | bool a = hub.Input(&inputs[i], GH_CSTR, String("Input #") + i); 50 | if (a) Serial.println(String("Set input: #") + i + ", value: " + inputs[i]); 51 | } 52 | break; 53 | case 3: 54 | hub.WidgetSize(25); 55 | for (int i = 0; i < spin_am; i++) { 56 | // имена компонентов тоже можно генерировать, если это нужно 57 | bool a = (hub.Button_(String("btn/") + i, 0, String("Button #") + i) == 1); 58 | if (a) Serial.println(String("Pressed button: btn/") + i); 59 | } 60 | break; 61 | } 62 | } 63 | 64 | void setup() { 65 | Serial.begin(115200); 66 | 67 | #ifdef GH_ESP_BUILD 68 | WiFi.mode(WIFI_STA); 69 | WiFi.begin(AP_SSID, AP_PASS); 70 | while (WiFi.status() != WL_CONNECTED) { 71 | delay(500); 72 | Serial.print("."); 73 | } 74 | Serial.println(); 75 | Serial.println(WiFi.localIP()); 76 | 77 | hub.setupMQTT("test.mosquitto.org", 1883); 78 | #endif 79 | 80 | hub.onBuild(build); 81 | hub.begin(); 82 | } 83 | 84 | void loop() { 85 | hub.tick(); 86 | } -------------------------------------------------------------------------------- /libraries/GyverHub/examples/esp32cam-frame/esp32cam-frame.ino: -------------------------------------------------------------------------------- 1 | // ESP32-CAM DEMO 2 | 3 | // WiFi 4 | #define AP_SSID "" 5 | #define AP_PASS "" 6 | #include 7 | #include 8 | GyverHub hub("MyDevices", "ESP32-CAM", ""); 9 | 10 | #include "camera.h" // идёт в папке со скетчем 11 | camera_fb_t* frame; 12 | 13 | void build() { 14 | hub.BeginWidgets(); 15 | hub.Image_("cam", "frame.jpg"); 16 | } 17 | 18 | void setup() { 19 | Serial.begin(115200); 20 | 21 | #ifdef GH_ESP_BUILD 22 | WiFi.mode(WIFI_STA); 23 | WiFi.begin(AP_SSID, AP_PASS); 24 | while (WiFi.status() != WL_CONNECTED) { 25 | delay(500); 26 | Serial.print("."); 27 | } 28 | Serial.println(); 29 | Serial.println(WiFi.localIP()); 30 | 31 | hub.setupMQTT("test.mosquitto.org", 1883); 32 | #endif 33 | 34 | hub.onBuild(build); 35 | hub.begin(); 36 | 37 | cam_init(FRAMESIZE_QVGA); 38 | 39 | hub.onFetch([](String & path, bool start) { 40 | if (path == "frame.jpg") { 41 | if (start) { 42 | frame = esp_camera_fb_get(); 43 | if (frame) hub.fetchBytes((byte*)frame->buf, frame->len); 44 | } else { 45 | esp_camera_fb_return(frame); 46 | 47 | // сразу начать скачивание следующего кадра 48 | // hub.sendUpdate("cam", ""); 49 | } 50 | } 51 | }); 52 | } 53 | 54 | void loop() { 55 | hub.tick(); 56 | } 57 | -------------------------------------------------------------------------------- /libraries/GyverHub/examples/esp32cam-stream/camera_stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "soc/rtc_cntl_reg.h" 8 | #include "soc/soc.h" 9 | 10 | #define _STREAM_BOUND "==stream==" 11 | static const char* _STREAM_HEADER = "multipart/x-mixed-replace;boundary=" _STREAM_BOUND; 12 | static const char* _CNT_TYPE_LEN = "X-Framerate: 60\r\nContent-Type: image/jpeg\r\nContent-Length: "; 13 | static const char* _RNRN = "\r\n\r\n"; 14 | static const char* _STREAM_END = "\r\n--" _STREAM_BOUND "\r\n"; 15 | httpd_handle_t _stream_httpd = NULL; 16 | bool _stream_state = false; 17 | 18 | static esp_err_t _stream_handler(httpd_req_t* req); 19 | void cam_stream_begin(uint16_t port = 82); 20 | void cam_stream_end(); 21 | 22 | void cam_stream_begin(uint16_t port) { 23 | esp_wifi_set_ps(WIFI_PS_NONE); // no power save 24 | WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout 25 | 26 | httpd_config_t cfg = HTTPD_DEFAULT_CONFIG(); 27 | cfg.server_port = port; 28 | cfg.send_wait_timeout = 1; 29 | cfg.max_uri_handlers = 16; 30 | httpd_uri_t index = {"/", HTTP_GET, _stream_handler, NULL}; 31 | if (httpd_start(&_stream_httpd, &cfg) == ESP_OK) { 32 | httpd_register_uri_handler(_stream_httpd, &index); 33 | _stream_state = 1; 34 | } 35 | } 36 | 37 | void cam_stream_end() { 38 | if (_stream_httpd) httpd_stop(_stream_httpd); 39 | _stream_httpd = NULL; 40 | _stream_state = 0; 41 | } 42 | 43 | static esp_err_t _stream_handler(httpd_req_t* req) { 44 | camera_fb_t* fb = NULL; 45 | char buf[72]; 46 | esp_err_t res = httpd_resp_set_type(req, _STREAM_HEADER); 47 | 48 | while (1) { 49 | if (res != ESP_OK || !_stream_state) break; 50 | 51 | fb = esp_camera_fb_get(); 52 | if (!fb) continue; 53 | 54 | strcpy(buf, _CNT_TYPE_LEN); 55 | utoa(fb->len, buf + strlen(buf), 10); 56 | strcpy(buf + strlen(buf), _RNRN); 57 | 58 | res = httpd_resp_send_chunk(req, (const char*)buf, strlen(buf)); 59 | 60 | if (res == ESP_OK) { 61 | res = httpd_resp_send_chunk(req, (const char*)fb->buf, fb->len); 62 | } 63 | if (res == ESP_OK) { 64 | res = httpd_resp_send_chunk(req, _STREAM_END, strlen(_STREAM_END)); 65 | } 66 | esp_camera_fb_return(fb); 67 | delay(20); 68 | } 69 | return res; 70 | } -------------------------------------------------------------------------------- /libraries/GyverHub/examples/esp32cam-stream/esp32cam-frame.ino: -------------------------------------------------------------------------------- 1 | // ESP32-CAM DEMO 2 | 3 | // WiFi 4 | #define AP_SSID "" 5 | #define AP_PASS "" 6 | #include 7 | #include 8 | GyverHub hub("MyDevices", "ESP32-CAM", ""); 9 | 10 | #include "camera.h" // идёт в папке со скетчем 11 | camera_fb_t* frame; 12 | 13 | void build() { 14 | hub.BeginWidgets(); 15 | hub.Image_("cam", "frame.jpg"); 16 | } 17 | 18 | void setup() { 19 | Serial.begin(115200); 20 | 21 | #ifdef GH_ESP_BUILD 22 | WiFi.mode(WIFI_STA); 23 | WiFi.begin(AP_SSID, AP_PASS); 24 | while (WiFi.status() != WL_CONNECTED) { 25 | delay(500); 26 | Serial.print("."); 27 | } 28 | Serial.println(); 29 | Serial.println(WiFi.localIP()); 30 | 31 | hub.setupMQTT("test.mosquitto.org", 1883); 32 | #endif 33 | 34 | hub.onBuild(build); 35 | hub.begin(); 36 | 37 | cam_init(FRAMESIZE_QVGA); 38 | 39 | hub.onFetch([](String & path, bool start) { 40 | if (path == "frame.jpg") { 41 | if (start) { 42 | frame = esp_camera_fb_get(); 43 | if (frame) hub.fetchBytes((byte*)frame->buf, frame->len); 44 | } else { 45 | esp_camera_fb_return(frame); 46 | 47 | // сразу начать скачивание следующего кадра 48 | // hub.sendUpdate("cam", ""); 49 | } 50 | } 51 | }); 52 | } 53 | 54 | void loop() { 55 | hub.tick(); 56 | } 57 | -------------------------------------------------------------------------------- /libraries/GyverHub/examples/esp32cam-stream/esp32cam-stream.ino: -------------------------------------------------------------------------------- 1 | // HTTPD STREAM DEMO 2 | 3 | #define AP_SSID "" 4 | #define AP_PASS "" 5 | #include 6 | 7 | #include "camera.h" 8 | #include "camera_stream.h" 9 | 10 | #include 11 | GyverHub hub("MyDevices", "ESP8266", ""); 12 | 13 | void build() { 14 | hub.BeginWidgets(); 15 | 16 | hub.WidgetSize(100); 17 | hub.Stream(); 18 | 19 | /*hub.WidgetSize(50); 20 | 21 | static bool sw = 0; 22 | if (hub.Switch(&sw)) { 23 | if (sw) cam_stream_begin(); 24 | else cam_stream_end(); 25 | }*/ 26 | } 27 | 28 | void setup() { 29 | Serial.begin(115200); 30 | 31 | #ifdef GH_ESP_BUILD 32 | WiFi.mode(WIFI_STA); 33 | WiFi.begin(AP_SSID, AP_PASS); 34 | while (WiFi.status() != WL_CONNECTED) { 35 | delay(500); 36 | Serial.print("."); 37 | } 38 | Serial.println(); 39 | Serial.println(WiFi.localIP()); 40 | #endif 41 | 42 | hub.onBuild(build); 43 | hub.begin(); 44 | 45 | cam_init(); 46 | cam_stream_begin(); 47 | } 48 | 49 | void loop() { 50 | hub.tick(); 51 | } 52 | -------------------------------------------------------------------------------- /libraries/GyverHub/examples/joy_demo/joy_demo.ino: -------------------------------------------------------------------------------- 1 | // JOY DEMO 2 | 3 | // WiFi 4 | #define AP_SSID "" 5 | #define AP_PASS "" 6 | 7 | #include 8 | #include 9 | GyverHub hub("MyDevices", "ESP8266", ""); 10 | 11 | GHpos pos2; 12 | 13 | void build() { 14 | hub.BeginWidgets(); 15 | hub.WidgetSize(50); 16 | 17 | // первый обработаем в билдере 18 | GHpos pos1; 19 | if (hub.Joystick(&pos1)) { 20 | Serial.println(pos1.x); 21 | Serial.println(pos1.y); 22 | } 23 | 24 | // второй в loop 25 | hub.Joystick(&pos2, 0, 1, F("my joy"), GH_RED); 26 | } 27 | 28 | void setup() { 29 | Serial.begin(115200); 30 | 31 | #ifdef GH_ESP_BUILD 32 | WiFi.mode(WIFI_STA); 33 | WiFi.begin(AP_SSID, AP_PASS); 34 | while (WiFi.status() != WL_CONNECTED) { 35 | delay(500); 36 | Serial.print("."); 37 | } 38 | Serial.println(); 39 | Serial.println(WiFi.localIP()); 40 | 41 | hub.setupMQTT("test.mosquitto.org", 1883); 42 | #endif 43 | 44 | hub.onBuild(build); 45 | hub.begin(); 46 | } 47 | 48 | void loop() { 49 | hub.tick(); 50 | 51 | if (pos2.changed()) { 52 | Serial.println("joy 2:"); 53 | Serial.println(pos2.x); 54 | Serial.println(pos2.y); 55 | } 56 | } -------------------------------------------------------------------------------- /libraries/GyverHub/examples/struct_demo/struct_demo.ino: -------------------------------------------------------------------------------- 1 | // DATA STRUCT 2 | 3 | // WiFi 4 | #define AP_SSID "" 5 | #define AP_PASS "" 6 | 7 | #include 8 | #include 9 | #include 10 | GyverHub hub("MyDevices", "ESP8266", ""); 11 | 12 | struct Data { 13 | bool sw; 14 | char inp[10]; 15 | uint16_t sld; 16 | float spin; 17 | Stamp date; 18 | GHcolor col; 19 | GHflags flags; 20 | }; 21 | 22 | Data data; 23 | 24 | void build() { 25 | // Задача - получить сигнал о том, что было изменение и 26 | // нужно сохранить данные в память (EEPROM, файл итд) 27 | 28 | // ================= СПОСОБ 1 ================= 29 | GHbuild b = hub.getBuild(); 30 | 31 | hub.Switch(&data.sw, 0); 32 | hub.Input(&data.inp, GH_CSTR, 0, 10); 33 | hub.Slider(&data.sld, GH_INT16); 34 | hub.Spinner(&data.spin, GH_FLOAT); 35 | hub.Date(&data.date); 36 | hub.Color(&data.col); 37 | hub.Flags(&data.flags); 38 | 39 | // было действие установки (ЛЮБОЕ НА СТРАНИЦЕ) 40 | if (b.type == GH_BUILD_ACTION) { 41 | // сохраняем структуру data 42 | } 43 | 44 | // ================= СПОСОБ 2 ================= 45 | bool flag = 0; 46 | flag |= hub.Switch(&data.sw, 0); 47 | flag |= hub.Input(&data.inp, GH_CSTR, 0, 10); 48 | flag |= hub.Slider(&data.sld, GH_INT16); 49 | flag |= hub.Spinner(&data.spin, GH_FLOAT); 50 | flag |= hub.Date(&data.date); 51 | flag |= hub.Color(&data.col); 52 | flag |= hub.Flags(&data.flags); 53 | 54 | // если хоть один из компонентов кликнут, flag будет 1 55 | // в отличие от первого способа, можно гибко разбивать компоненты 56 | // на группы, вводя несколько флагов для разных структур 57 | if (flag) { 58 | // сохраняем структуру data 59 | } 60 | } 61 | 62 | void setup() { 63 | Serial.begin(115200); 64 | 65 | #ifdef GH_ESP_BUILD 66 | WiFi.mode(WIFI_STA); 67 | WiFi.begin(AP_SSID, AP_PASS); 68 | while (WiFi.status() != WL_CONNECTED) { 69 | delay(500); 70 | Serial.print("."); 71 | } 72 | Serial.println(); 73 | Serial.println(WiFi.localIP()); 74 | 75 | hub.setupMQTT("test.mosquitto.org", 1883); 76 | #endif 77 | 78 | hub.onBuild(build); 79 | hub.begin(); 80 | } 81 | 82 | void loop() { 83 | hub.tick(); 84 | } -------------------------------------------------------------------------------- /libraries/GyverHub/examples/update/update.ino: -------------------------------------------------------------------------------- 1 | // UPDATE DEMO 2 | 3 | // WiFi 4 | #define AP_SSID "" 5 | #define AP_PASS "" 6 | 7 | #include 8 | #include 9 | GyverHub hub("MyDevices", "ESP8266", ""); 10 | 11 | void build() { 12 | hub.BeginWidgets(); 13 | hub.WidgetSize(50); 14 | 15 | // обновляемым компонентам нужно присвоить уникальные имена 16 | // чтобы было на кого отправлять обновления 17 | hub.Label_(F("lbl")); 18 | 19 | hub.WidgetSize(25); 20 | hub.LED_(F("led")); 21 | 22 | // по клику по кнопке 23 | if (hub.ButtonIcon(0, F(""))) { 24 | static bool led; 25 | led = !led; 26 | hub.sendUpdate("ga", String(random(100))); // обновляем шкалу 27 | hub.sendUpdate("led", String(led)); // обновляем светодиод 28 | } 29 | 30 | hub.WidgetSize(50); 31 | hub.Canvas_(F("cv")); 32 | hub.Gauge_(F("ga")); 33 | } 34 | 35 | void setup() { 36 | Serial.begin(115200); 37 | 38 | #ifdef GH_ESP_BUILD 39 | WiFi.mode(WIFI_STA); 40 | WiFi.begin(AP_SSID, AP_PASS); 41 | while (WiFi.status() != WL_CONNECTED) { 42 | delay(500); 43 | Serial.print("."); 44 | } 45 | Serial.println(); 46 | Serial.println(WiFi.localIP()); 47 | 48 | hub.setupMQTT("test.mosquitto.org", 1883); 49 | #endif 50 | 51 | hub.onBuild(build); 52 | hub.begin(); 53 | } 54 | 55 | void loop() { 56 | hub.tick(); 57 | 58 | // таймер на 500 мс 59 | // добавим случайных кругов на холст 60 | static GHtimer tmr1(500); 61 | if (tmr1.ready()) { 62 | GHcanvas cv; 63 | cv.fill(GHcolor(random(255), random(255), random(255)), random(100, 255)); 64 | cv.circle(random(0, 40) * 10, random(0, 30) * 10, random(5, 30)); 65 | hub.sendCanvas(F("cv"), cv); 66 | } 67 | 68 | // таймер на 1с 69 | // выведем миллис на label 70 | static GHtimer tmr2(1000); 71 | if (tmr2.ready()) { 72 | hub.sendUpdate("lbl", String(millis())); 73 | } 74 | } -------------------------------------------------------------------------------- /libraries/GyverHub/library.properties: -------------------------------------------------------------------------------- 1 | name=GyverHub 2 | version=1.0 3 | author=AlexGyver 4 | maintainer=AlexGyver 5 | sentence=ESP8266/ESP32/Arduino control panel with in-sketch GUI builder 6 | paragraph=ESP8266/ESP32/Arduino control panel with in-sketch GUI builder 7 | category=Communication 8 | url=https://github.com/GyverLibs/GyverHub 9 | architectures=* 10 | depends=PubSubClient,WebSockets -------------------------------------------------------------------------------- /libraries/GyverHub/src/async/mqtt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../config.hpp" 3 | #include "../macro.hpp" 4 | 5 | #ifdef GH_ESP_BUILD 6 | #ifdef GH_NO_MQTT 7 | class HubMQTT { 8 | public: 9 | void setupMQTT(const char* host, uint16_t port, const char* login = nullptr, const char* pass = nullptr, uint8_t nqos = 0, bool nret = 0) {} 10 | }; 11 | #else 12 | 13 | #include 14 | #include 15 | 16 | #include "../utils/stats.h" 17 | 18 | class HubMQTT { 19 | // ============ PUBLIC ============= 20 | public: 21 | // настроить MQTT (хост брокера, порт, логин, пароль, QoS, retained) 22 | void setupMQTT(const char* host, uint16_t port, const char* login = nullptr, const char* pass = nullptr, uint8_t nqos = 0, bool nret = 0) { 23 | if (!strlen(host)) return; 24 | mqtt.setServer(host, port); 25 | _setupMQTT(login, pass, nqos, nret); 26 | } 27 | void setupMQTT(IPAddress ip, uint16_t port, const char* login = nullptr, const char* pass = nullptr, uint8_t nqos = 0, bool nret = 0) { 28 | mqtt.setServer(ip, port); 29 | _setupMQTT(login, pass, nqos, nret); 30 | } 31 | 32 | // MQTT подключен 33 | bool online() { 34 | return mqtt.connected(); 35 | } 36 | 37 | // ============ PROTECTED ============= 38 | protected: 39 | virtual void parse(char* url, char* value, GHconn_t from) = 0; 40 | virtual const char* getPrefix() = 0; 41 | virtual const char* getID() = 0; 42 | virtual void sendEvent(GHevent_t state, GHconn_t from) = 0; 43 | 44 | void beginMQTT() { 45 | mqtt.onConnect([this](GH_UNUSED bool pres) { 46 | String sub_topic(getPrefix()); 47 | mqtt.subscribe(sub_topic.c_str(), qos); 48 | 49 | sub_topic += '/'; 50 | sub_topic += getID(); 51 | sub_topic += "/#"; 52 | mqtt.subscribe(sub_topic.c_str(), qos); 53 | 54 | String status(getPrefix()); 55 | status += F("/hub/"); 56 | status += getID(); 57 | status += F("/status"); 58 | String offline(F("offline")); 59 | mqtt.setWill(status.c_str(), qos, ret, offline.c_str()); 60 | 61 | String online(F("online")); 62 | sendMQTT(status, online); 63 | sendEvent(GH_CONNECTED, GH_MQTT); 64 | mqtt_tmr = millis(); 65 | }); 66 | 67 | mqtt.onDisconnect([this](GH_UNUSED AsyncMqttClientDisconnectReason reason) { 68 | String m_id("DEV-"); 69 | m_id += String(random(0xffffff), HEX); 70 | mqtt.setClientId(m_id.c_str()); 71 | sendEvent(GH_DISCONNECTED, GH_MQTT); 72 | mqtt_tmr = millis(); 73 | }); 74 | 75 | mqtt.onMessage([this](char* topic, char* data, GH_UNUSED AsyncMqttClientMessageProperties prop, size_t len, GH_UNUSED size_t index, GH_UNUSED size_t total) { 76 | char buf[len + 1]; 77 | memcpy(buf, data, len); 78 | buf[len] = 0; 79 | parse(topic, buf, GH_MQTT); 80 | }); 81 | } 82 | 83 | void endMQTT() { 84 | mqtt.disconnect(); 85 | } 86 | 87 | void tickMQTT() { 88 | if (mq_configured && !mqtt.connected() && (!mqtt_tmr || millis() - mqtt_tmr > GH_MQTT_RECONNECT)) { 89 | mqtt_tmr = millis(); 90 | sendEvent(GH_CONNECTING, GH_MQTT); 91 | mqtt.connect(); 92 | } 93 | } 94 | 95 | void sendMQTT(const String& topic, const String& msg) { 96 | if (mqtt.connected()) mqtt.publish(topic.c_str(), qos, ret, msg.c_str(), msg.length()); 97 | } 98 | 99 | void sendMQTT(const String& msg) { 100 | String topic(getPrefix()); 101 | topic += F("/hub"); 102 | sendMQTT(topic, msg); 103 | } 104 | 105 | void answerMQTT(const String& msg, const char* hubID) { 106 | String topic(getPrefix()); 107 | topic += F("/hub/"); 108 | topic += hubID; 109 | topic += '/'; 110 | topic += getID(); 111 | sendMQTT(topic, msg); 112 | } 113 | 114 | // ============ PRIVATE ============= 115 | private: 116 | void _setupMQTT(const char* login, const char* pass, uint8_t nqos, bool nret) { 117 | if (mqtt.connected()) mqtt.disconnect(); 118 | mqtt.setCredentials(login, pass); 119 | qos = nqos; 120 | ret = nret; 121 | mq_configured = true; 122 | } 123 | 124 | AsyncMqttClient mqtt; 125 | bool mq_configured = false; 126 | uint32_t mqtt_tmr = 0; 127 | uint8_t qos = 0; 128 | bool ret = 0; 129 | }; 130 | #endif 131 | #endif -------------------------------------------------------------------------------- /libraries/GyverHub/src/async/ws.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../config.hpp" 3 | #include "../macro.hpp" 4 | 5 | #ifdef GH_ESP_BUILD 6 | #ifdef GH_NO_WS 7 | class HubWS { 8 | public: 9 | }; 10 | #else 11 | 12 | #include 13 | #include 14 | 15 | #include "../utils/stats.h" 16 | 17 | class HubWS { 18 | // ============ PROTECTED ============= 19 | protected: 20 | HubWS() : server(GH_WS_PORT), ws("/") { 21 | server.addHandler(&ws); 22 | } 23 | 24 | virtual void parse(char* url, GHconn_t from) = 0; 25 | virtual void sendEvent(GHevent_t state, GHconn_t from) = 0; 26 | 27 | void beginWS() { 28 | ws.onEvent([this](GH_UNUSED AsyncWebSocket* server, GH_UNUSED AsyncWebSocketClient* client, AwsEventType etype, void* arg, uint8_t* data, size_t len) { 29 | switch (etype) { 30 | case WS_EVT_CONNECT: 31 | sendEvent(GH_CONNECTED, GH_WS); 32 | break; 33 | 34 | case WS_EVT_DISCONNECT: 35 | sendEvent(GH_DISCONNECTED, GH_WS); 36 | break; 37 | 38 | case WS_EVT_ERROR: 39 | sendEvent(GH_ERROR, GH_WS); 40 | break; 41 | 42 | case WS_EVT_DATA: { 43 | AwsFrameInfo* ws_info = (AwsFrameInfo*)arg; 44 | if (ws_info->final && ws_info->index == 0 && ws_info->len == len && ws_info->opcode == WS_TEXT) { 45 | clientID = client->id(); 46 | parse((char*)data, GH_WS); 47 | } 48 | } break; 49 | 50 | case WS_EVT_PONG: 51 | break; 52 | } 53 | }); 54 | 55 | server.begin(); 56 | } 57 | 58 | void endWS() { 59 | server.end(); 60 | } 61 | 62 | void tickWS() { 63 | ws.cleanupClients(); 64 | } 65 | 66 | void sendWS(const String& answ) { 67 | ws.textAll(answ.c_str()); 68 | } 69 | 70 | void answerWS(String& answ) { 71 | ws.text(clientID, answ.c_str()); 72 | } 73 | 74 | // ============ PRIVATE ============= 75 | private: 76 | AsyncWebServer server; 77 | AsyncWebSocket ws; 78 | uint32_t clientID = 0; 79 | }; 80 | #endif 81 | #endif -------------------------------------------------------------------------------- /libraries/GyverHub/src/config.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define GH_LIB_VERSION "v0.1b" // версия библиотеки 4 | #define GH_HTTP_PATH "/fs/" // путь к папке с файлами с HTTP доступом 5 | #define GH_CONN_TOUT 5 // таймаут соединения, с 6 | #define GH_HTTP_PORT 80 // http порт 7 | #define GH_WS_PORT 81 // websocket порт 8 | #define GH_DOWN_CHUNK_SIZE 512 // размер чанка при скачивании с платы 9 | #define GH_UPL_CHUNK_SIZE 200 // размер чанка при загрузке на плату 10 | #define GH_FS_DEPTH 5 // глубина сканирования файловой системы (esp32) 11 | #define GH_FS LittleFS // файловая система 12 | #define GH_MQTT_RECONNECT 5000 // период переподключения MQTT 13 | #define GH_CACHE_PRD "max-age=604800" // период кеширования файлов для портала 14 | 15 | #if (defined(ESP8266) || defined(ESP32)) 16 | #define GH_ESP_BUILD 17 | #endif -------------------------------------------------------------------------------- /libraries/GyverHub/src/esp_inc/index.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define hub_index_h_len 374 3 | 4 | const uint8_t hub_index_h[] PROGMEM = { 5 | 0x1f, 0x8b, 0x08, 0x08, 0x58, 0x91, 0x9e, 0x64, 0x02, 0xff, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 6 | 0x68, 0x74, 0x6d, 0x6c, 0x00, 0x7d, 0x92, 0x4d, 0x4f, 0xc3, 0x30, 0x0c, 0x86, 0xef, 0x48, 0xfc, 7 | 0x07, 0x93, 0x13, 0x48, 0x6c, 0xe5, 0x73, 0xda, 0xa1, 0x1d, 0x42, 0x7c, 0xde, 0x98, 0x04, 0x08, 8 | 0x71, 0x9a, 0xb2, 0xd4, 0xa3, 0x1e, 0x69, 0x32, 0x25, 0x5e, 0x61, 0xfc, 0x7a, 0x92, 0xa6, 0x03, 9 | 0x04, 0x62, 0x27, 0xbf, 0x76, 0x1e, 0xbf, 0xb2, 0xad, 0xe4, 0x3b, 0x97, 0x77, 0x17, 0x0f, 0xcf, 10 | 0xe3, 0x2b, 0xa8, 0xb8, 0xd6, 0xa3, 0xed, 0xad, 0x3c, 0x46, 0xd0, 0xd2, 0xbc, 0x14, 0x02, 0x8d, 11 | 0x68, 0x2b, 0x28, 0xcb, 0x10, 0x01, 0xf2, 0x1a, 0x59, 0x82, 0xaa, 0xa4, 0xf3, 0xc8, 0x85, 0x78, 12 | 0x7c, 0xb8, 0xee, 0x0d, 0x45, 0x7a, 0x61, 0x62, 0x8d, 0xa3, 0x9b, 0x55, 0x83, 0xee, 0x76, 0x39, 13 | 0x85, 0xe6, 0xa0, 0x7f, 0x72, 0x3a, 0xcd, 0xb3, 0x54, 0xfe, 0xee, 0x35, 0xb2, 0xc6, 0x42, 0x94, 14 | 0xe8, 0x95, 0xa3, 0x05, 0x93, 0x35, 0x02, 0x94, 0x35, 0x8c, 0x26, 0xd8, 0x9d, 0xbb, 0x72, 0x49, 15 | 0xc6, 0x66, 0x57, 0xf7, 0xe3, 0xe1, 0xd1, 0x60, 0x10, 0xe3, 0xf1, 0x11, 0x3c, 0xe1, 0x14, 0x2e, 16 | 0x02, 0xe2, 0xac, 0x86, 0xb1, 0x34, 0xa8, 0xc5, 0x1f, 0xbb, 0x86, 0xf0, 0x6d, 0x61, 0x1d, 0xff, 17 | 0xf0, 0x7a, 0xa3, 0x92, 0xab, 0xa2, 0xc4, 0x86, 0x14, 0xf6, 0xda, 0x64, 0x1f, 0xc8, 0x10, 0x93, 18 | 0xd4, 0x3d, 0xaf, 0xa4, 0xc6, 0xe2, 0x70, 0x1f, 0x6a, 0xf9, 0x4e, 0xf5, 0xb2, 0x5e, 0x17, 0x3a, 19 | 0xe3, 0x34, 0x1a, 0x78, 0xa7, 0x0a, 0x91, 0x74, 0x7f, 0xee, 0xcf, 0xda, 0x7d, 0x0a, 0x31, 0xca, 20 | 0xb3, 0x54, 0x4b, 0xac, 0x26, 0xf3, 0x0a, 0x95, 0xc3, 0x59, 0x40, 0x79, 0xa5, 0xb1, 0xaf, 0xfc, 21 | 0x17, 0x0a, 0x0e, 0x75, 0x57, 0xf6, 0x15, 0x22, 0xb7, 0xa7, 0xcc, 0xba, 0x5b, 0xe6, 0x53, 0x5b, 22 | 0xae, 0xc0, 0x1a, 0x87, 0x9e, 0x3e, 0xc2, 0x0a, 0x29, 0x4e, 0xaa, 0xdd, 0xbd, 0x6e, 0x8a, 0x92, 23 | 0x1a, 0xa0, 0xb2, 0x10, 0xc6, 0x72, 0x58, 0x21, 0x6c, 0xa6, 0xa5, 0xf7, 0x5f, 0x69, 0x18, 0x23, 24 | 0x00, 0xdf, 0x64, 0xf7, 0x1a, 0xcd, 0x45, 0xdb, 0x16, 0xd5, 0x24, 0x5e, 0xe3, 0x3f, 0x94, 0xd1, 25 | 0x73, 0x42, 0xa3, 0xda, 0x88, 0x2e, 0x9c, 0x9d, 0xa3, 0x62, 0x9f, 0xf0, 0x75, 0xb6, 0xb1, 0xa5, 26 | 0x96, 0x64, 0x12, 0x1e, 0xd5, 0x46, 0x54, 0x69, 0x4a, 0x64, 0x10, 0x1b, 0xc1, 0x99, 0xb5, 0x8c, 27 | 0x2e, 0xb1, 0x49, 0xff, 0xc2, 0xf3, 0x2c, 0x1e, 0x35, 0x5d, 0x39, 0xfe, 0xe5, 0x4f, 0x2a, 0x42, 28 | 0x75, 0xf6, 0xdb, 0x02, 0x00, 0x00, 29 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/macro.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define GH_UNUSED __attribute__((unused)) 4 | #define VSPTR const void* 5 | #define CSREF const String& 6 | #define GH_PGM(name, str) static const char name[] PROGMEM = str 7 | #define GH_PGM_LIST(name, ...) const char* const name[] PROGMEM = {__VA_ARGS__}; 8 | #define FSTR const __FlashStringHelper* 9 | #define GH_NO_LABEL F("_no") 10 | #define GH_NUMBERS F("^\\d+$") 11 | #define GH_LETTERS F("^[a-zA-Z]+$") 12 | #define GH_LETTERS_S F("^[a-z]+$") 13 | #define GH_LETTERS_C F("^[A-Z]+$") -------------------------------------------------------------------------------- /libraries/GyverHub/src/stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "config.hpp" 3 | #include "macro.hpp" 4 | 5 | #ifdef GH_NO_STREAM 6 | class HubStream { 7 | public: 8 | }; 9 | #else 10 | 11 | #include 12 | #include 13 | 14 | #include "utils/stats.h" 15 | 16 | class HubStream { 17 | public: 18 | // подключить Stream для связи 19 | void setupStream(Stream* nstream, GHconn_t nfrom) { 20 | stream = nstream; 21 | from = nfrom; 22 | } 23 | 24 | protected: 25 | void tickStream() { 26 | if (stream && stream->available()) { 27 | String str = stream->readStringUntil('\0'); 28 | parse((char*)str.c_str(), from, GH_STREAM); 29 | } 30 | } 31 | 32 | void sendStream(const String& answ) { 33 | if (stream) stream->print(answ); 34 | } 35 | 36 | bool stateStream() { 37 | return stream; 38 | } 39 | GHconn_t connStream() { 40 | return from; 41 | } 42 | 43 | virtual void parse(char* url, GHconn_t from, GHsource_t source) = 0; 44 | 45 | // ============ PRIVATE ============= 46 | private: 47 | Stream* stream = nullptr; 48 | GHconn_t from; 49 | }; 50 | #endif -------------------------------------------------------------------------------- /libraries/GyverHub/src/sync/mqtt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../config.hpp" 3 | #include "../macro.hpp" 4 | 5 | #ifdef GH_ESP_BUILD 6 | #ifdef GH_NO_MQTT 7 | class HubMQTT { 8 | public: 9 | void setupMQTT(const char* host, uint16_t port, const char* login = nullptr, const char* pass = nullptr, uint8_t nqos = 0, bool nret = 0) {} 10 | }; 11 | #else 12 | 13 | #include 14 | #include 15 | 16 | #include "../utils/stats.h" 17 | 18 | class HubMQTT { 19 | // ============ PUBLIC ============= 20 | public: 21 | // настроить MQTT (хост брокера, порт, логин, пароль, QoS, retained) 22 | void setupMQTT(const char* host, uint16_t port, const char* login = nullptr, const char* pass = nullptr, uint8_t nqos = 0, bool nret = 0) { 23 | if (!strlen(host)) return; 24 | mqtt.setServer(host, port); 25 | _setupMQTT(login, pass, nqos, nret); 26 | } 27 | 28 | void setupMQTT(IPAddress ip, uint16_t port, const char* login = nullptr, const char* pass = nullptr, uint8_t nqos = 0, bool nret = 0) { 29 | mqtt.setServer(ip, port); 30 | _setupMQTT(login, pass, nqos, nret); 31 | } 32 | 33 | // MQTT подключен 34 | bool online() { 35 | return mqtt.connected(); 36 | } 37 | 38 | // ============ PROTECTED ============= 39 | protected: 40 | virtual void parse(char* url, char* value, GHconn_t from) = 0; 41 | virtual const char* getPrefix() = 0; 42 | virtual const char* getID() = 0; 43 | virtual void sendEvent(GHevent_t state, GHconn_t from) = 0; 44 | 45 | void beginMQTT() { 46 | mqtt.setCallback([this](char* topic, uint8_t* data, uint16_t len) { 47 | char buf[len + 1]; 48 | memcpy(buf, data, len); 49 | buf[len] = 0; 50 | parse(topic, buf, GH_MQTT); 51 | }); 52 | } 53 | 54 | void endMQTT() { 55 | mqtt.disconnect(); 56 | } 57 | 58 | void tickMQTT() { 59 | if (mq_configured) { 60 | if (!mqtt.connected() && (!mqtt_tmr || millis() - mqtt_tmr > GH_MQTT_RECONNECT)) { 61 | mqtt_tmr = millis(); 62 | sendEvent(GH_CONNECTING, GH_MQTT); 63 | connectMQTT(); 64 | } 65 | mqtt.loop(); 66 | } 67 | } 68 | 69 | void sendMQTT(const String& topic, const String& msg) { 70 | if (!mqtt.connected()) return; 71 | mqtt.beginPublish(topic.c_str(), msg.length(), ret); 72 | mqtt.write((uint8_t*)msg.c_str(), msg.length()); 73 | mqtt.endPublish(); 74 | } 75 | 76 | void sendMQTT(const String& msg) { 77 | String topic(getPrefix()); 78 | topic += F("/hub"); 79 | sendMQTT(topic, msg); 80 | } 81 | 82 | void answerMQTT(const String& msg, const char* hubID) { 83 | String topic(getPrefix()); 84 | topic += F("/hub/"); 85 | topic += hubID; 86 | topic += '/'; 87 | topic += getID(); 88 | sendMQTT(topic, msg); 89 | } 90 | 91 | // ============ PRIVATE ============= 92 | private: 93 | void connectMQTT() { 94 | String m_id("DEV-"); 95 | m_id += String(random(0xffffff), HEX); 96 | bool ok = 0; 97 | 98 | String status(getPrefix()); 99 | status += F("/hub/"); 100 | status += getID(); 101 | status += F("/status"); 102 | 103 | String offline(F("offline")); 104 | 105 | if (mq_login) ok = mqtt.connect(m_id.c_str(), mq_login, mq_pass, status.c_str(), qos, ret, offline.c_str()); 106 | else ok = mqtt.connect(m_id.c_str(), status.c_str(), qos, ret, offline.c_str()); 107 | // if (mq_login) from = mqtt.connect(m_id.c_str(), mq_login, mq_pass); 108 | // else from = mqtt.connect(m_id.c_str()); 109 | 110 | if (ok) { 111 | String online(F("online")); 112 | sendMQTT(status, online); 113 | 114 | String sub_topic(getPrefix()); 115 | mqtt.subscribe(sub_topic.c_str(), qos); 116 | 117 | sub_topic += '/'; 118 | sub_topic += getID(); 119 | sub_topic += "/#"; 120 | mqtt.subscribe(sub_topic.c_str(), qos); 121 | } 122 | sendEvent(ok ? GH_CONNECTED : GH_ERROR, GH_MQTT); 123 | } 124 | void _setupMQTT(const char* login, const char* pass, uint8_t nqos, bool nret) { 125 | mqtt.setClient(mclient); 126 | qos = nqos; 127 | ret = nret; 128 | mq_login = login; 129 | mq_pass = pass; 130 | mq_configured = true; 131 | } 132 | 133 | PubSubClient mqtt; 134 | WiFiClient mclient; 135 | bool mq_configured = false; 136 | uint32_t mqtt_tmr = 0; 137 | uint8_t qos = 0; 138 | bool ret = 0; 139 | const char* mq_login; 140 | const char* mq_pass; 141 | }; 142 | #endif 143 | #endif -------------------------------------------------------------------------------- /libraries/GyverHub/src/sync/ws.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../config.hpp" 3 | #include "../macro.hpp" 4 | 5 | #ifdef GH_ESP_BUILD 6 | #ifdef GH_NO_WS 7 | class HubWS { 8 | public: 9 | }; 10 | #else 11 | 12 | #include 13 | #include 14 | 15 | #include "../utils/stats.h" 16 | 17 | class HubWS { 18 | // ============ PROTECTED ============= 19 | protected: 20 | HubWS() : ws(GH_WS_PORT, "", "hub") {} 21 | 22 | virtual void parse(char* url, GHconn_t from) = 0; 23 | virtual void sendEvent(GHevent_t state, GHconn_t from) = 0; 24 | 25 | void beginWS() { 26 | ws.onEvent([this](uint8_t num, WStype_t type, uint8_t* data, GH_UNUSED size_t len) { 27 | switch (type) { 28 | case WStype_CONNECTED: 29 | sendEvent(GH_CONNECTED, GH_WS); 30 | break; 31 | 32 | case WStype_DISCONNECTED: 33 | sendEvent(GH_DISCONNECTED, GH_WS); 34 | break; 35 | 36 | case WStype_ERROR: 37 | sendEvent(GH_ERROR, GH_WS); 38 | break; 39 | 40 | case WStype_TEXT: { 41 | clientID = num; 42 | /*char buf[len + 1]; 43 | memcpy(buf, data, len); 44 | buf[len] = 0;*/ 45 | parse((char*)data, GH_WS); 46 | } break; 47 | 48 | case WStype_BIN: 49 | case WStype_FRAGMENT_TEXT_START: 50 | case WStype_FRAGMENT_BIN_START: 51 | case WStype_FRAGMENT: 52 | case WStype_FRAGMENT_FIN: 53 | case WStype_PING: 54 | case WStype_PONG: 55 | break; 56 | } 57 | }); 58 | 59 | ws.begin(); 60 | } 61 | 62 | void endWS() { 63 | ws.close(); 64 | } 65 | 66 | void tickWS() { 67 | ws.loop(); 68 | } 69 | 70 | void sendWS(const String& answ) { 71 | ws.broadcastTXT(answ.c_str(), answ.length()); 72 | } 73 | 74 | void answerWS(const String& answ) { 75 | ws.sendTXT(clientID, answ.c_str(), answ.length()); 76 | } 77 | 78 | // ============ PRIVATE ============= 79 | private: 80 | WebSocketsServer ws; 81 | uint8_t clientID = 0; 82 | }; 83 | #endif 84 | #endif -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/action.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "color.h" 5 | #include "flags.h" 6 | #include "pos.h" 7 | 8 | struct GHaction { 9 | // имя компонента 10 | const char* name = nullptr; 11 | 12 | // значение компонента 13 | const char* value = nullptr; 14 | 15 | // value 16 | // получить значение как int (32 бит) 17 | int32_t valueInt() const { 18 | return atol(value); 19 | } 20 | 21 | // получить значение как float 22 | float valueFloat() const { 23 | return atof(value); 24 | } 25 | 26 | // получить значение как const char* 27 | const char* valueStr() const { 28 | return value; 29 | } 30 | 31 | // получить значение как bool 32 | bool valueBool() const { 33 | return (value[0] == '1'); 34 | } 35 | 36 | // получить значение как String 37 | String valueString() const { 38 | return value; 39 | } 40 | 41 | // получить значение как GHcolor 42 | GHcolor valueColor() const { 43 | return GHcolor(atol(value), HEX); 44 | } 45 | 46 | // получить значение как GHflags 47 | GHflags valueFlags() const { 48 | return GHflags(atoi(value)); 49 | } 50 | 51 | // получить значение как GHpos 52 | GHpos valuePos() const { 53 | uint32_t xy = atol(value); 54 | return GHpos(xy >> 16, xy & 0xffff, 1); 55 | } 56 | 57 | // name 58 | // получить имя как String 59 | String nameString() const { 60 | return name; 61 | } 62 | 63 | // получить имя как const char* 64 | const char* nameStr() const { 65 | return name; 66 | } 67 | 68 | // private 69 | bool nameEq(VSPTR cname, bool fstr) { 70 | if (cname) return fstr ? !strcmp_P(name, (PGM_P)cname) : !strcmp(name, (PGM_P)cname); 71 | else return autoNameEq(); 72 | } 73 | bool autoNameEq() { 74 | return name[0] == '_' && name[1] == 'n' && (uint16_t)atoi(name + 2) == count; 75 | } 76 | 77 | uint16_t count = 0; 78 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/b64.cpp: -------------------------------------------------------------------------------- 1 | #include "b64.h" 2 | 3 | static const char _b64chars[] PROGMEM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 4 | 5 | static const uint8_t _b64index[] PROGMEM = { 6 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 9 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 10 | 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 11 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 12 | 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 13 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; 14 | 15 | char GH_b64v(uint8_t n) { 16 | return pgm_read_byte(_b64chars + n); 17 | } 18 | uint8_t GH_b64i(char b) { 19 | return pgm_read_byte(_b64index + b); 20 | } -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/b64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | char GH_b64v(uint8_t n); 5 | uint8_t GH_b64i(char b); -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/build.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../config.hpp" 5 | #include "../macro.hpp" 6 | #include "action.h" 7 | #include "datatypes.h" 8 | #include "client.h" 9 | #include "stats.h" 10 | 11 | // тип билда 12 | enum GHbuild_t { 13 | GH_BUILD_NONE, 14 | GH_BUILD_ACTION, 15 | GH_BUILD_COUNT, 16 | GH_BUILD_READ, 17 | GH_BUILD_UI, 18 | GH_BUILD_TG, 19 | }; 20 | 21 | class GHbuild { 22 | public: 23 | GHbuild(GHbuild_t btype = GH_BUILD_NONE, const char* name = nullptr, const char* value = nullptr, GHclient nclient = GHclient(), GHevent_t ncmd = GH_IDLE) { 24 | type = btype; 25 | action.name = name; 26 | action.value = value; 27 | client = nclient; 28 | cmd = ncmd; 29 | } 30 | 31 | bool parse(VSPTR cname, void* var, GHdata_t dtype, bool fstr) { 32 | if (type == GH_BUILD_ACTION && action.nameEq(cname, fstr)) { 33 | type = GH_BUILD_NONE; 34 | GHtypeFromStr(action.value, var, dtype); 35 | return 1; 36 | } 37 | return 0; 38 | } 39 | 40 | // тип билда 41 | GHbuild_t type = GH_BUILD_NONE; 42 | 43 | // данные клиента 44 | GHclient client; 45 | 46 | // действие 47 | GHaction action; 48 | 49 | // событие 50 | GHevent_t cmd = GH_IDLE; 51 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/button.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class GHbutton { 5 | public: 6 | bool state = 0; 7 | 8 | bool changed() { 9 | return _changed ? (_changed = 0, 1) : 0; 10 | } 11 | 12 | operator bool() { 13 | return state; 14 | } 15 | 16 | bool _changed = 0; 17 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/client.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "stats.h" 5 | 6 | struct GHclient { 7 | GHclient() {} 8 | GHclient(GHconn_t nfrom, const char* nid, GHsource_t nsource = GH_ESP) { 9 | from = nfrom; 10 | if (strlen(nid) <= 8) strcpy(id, nid); 11 | source = nsource; 12 | } 13 | 14 | // тип соединения 15 | GHconn_t from = GH_SYSTEM; 16 | 17 | // id клиента 18 | char id[9] = {'\0'}; 19 | 20 | // id как String 21 | String idString() { 22 | return id; 23 | } 24 | 25 | // источник 26 | GHsource_t source; 27 | 28 | bool eq(GHclient& client) { 29 | return (client.from == from && !strcmp(client.id, id)); 30 | } 31 | bool operator==(GHclient& client) { 32 | return eq(client); 33 | } 34 | bool operator!=(GHclient& client) { 35 | return !eq(client); 36 | } 37 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/cmd_p.cpp: -------------------------------------------------------------------------------- 1 | #include "cmd_p.h" 2 | 3 | GH_PGM(_GH_CMD0, "focus"); 4 | GH_PGM(_GH_CMD1, "ping"); 5 | GH_PGM(_GH_CMD2, "unfocus"); 6 | GH_PGM(_GH_CMD3, "info"); 7 | GH_PGM(_GH_CMD4, "fsbr"); 8 | GH_PGM(_GH_CMD5, "format"); 9 | GH_PGM(_GH_CMD6, "reboot"); 10 | GH_PGM(_GH_CMD7, "data"); 11 | GH_PGM(_GH_CMD8, "set"); 12 | GH_PGM(_GH_CMD9, "cli"); 13 | GH_PGM(_GH_CMD10, "delete"); 14 | GH_PGM(_GH_CMD11, "rename"); 15 | GH_PGM(_GH_CMD12, "fetch"); 16 | GH_PGM(_GH_CMD13, "fetch_chunk"); 17 | GH_PGM(_GH_CMD14, "fetch_stop"); 18 | GH_PGM(_GH_CMD15, "upload"); 19 | GH_PGM(_GH_CMD16, "upload_chunk"); 20 | GH_PGM(_GH_CMD17, "ota"); 21 | GH_PGM(_GH_CMD18, "ota_chunk"); 22 | GH_PGM(_GH_CMD19, "ota_url"); 23 | 24 | #define GH_CMD_LEN 20 25 | GH_PGM_LIST(_GH_cmd_list, _GH_CMD0, _GH_CMD1, _GH_CMD2, _GH_CMD3, _GH_CMD4, _GH_CMD5, _GH_CMD6, _GH_CMD7, _GH_CMD8, _GH_CMD9, _GH_CMD10, _GH_CMD11, _GH_CMD12, _GH_CMD13, _GH_CMD14, _GH_CMD15, _GH_CMD16, _GH_CMD17, _GH_CMD18, _GH_CMD19); 26 | 27 | int GH_getCmd(const char* str) { 28 | for (int i = 0; i < GH_CMD_LEN; i++) { 29 | #ifdef GH_ESP_BUILD 30 | if (!strcmp_P(str, _GH_cmd_list[i])) return i; 31 | #else 32 | if (!strcmp_P(str, (PGM_P)pgm_read_word(_GH_cmd_list + i))) return i; 33 | #endif 34 | } 35 | return -1; 36 | } 37 | 38 | /* 39 | // ======================== CMD ======================== 40 | GH_PGM(_GH_CMD0, "focus"); 41 | GH_PGM(_GH_CMD1, "ping"); 42 | GH_PGM(_GH_CMD2, "unfocus"); 43 | GH_PGM(_GH_CMD3, "info"); 44 | GH_PGM(_GH_CMD4, "fsbr"); 45 | GH_PGM(_GH_CMD5, "format"); 46 | GH_PGM(_GH_CMD6, "reboot"); 47 | GH_PGM(_GH_CMD7, "fetch_chunk"); 48 | GH_PGM(_GH_CMD8, "fetch_stop"); 49 | 50 | #define GH_CMD_LEN 9 51 | GH_PGM_LIST(_GH_cmd_list, _GH_CMD0, _GH_CMD1, _GH_CMD2, _GH_CMD3, _GH_CMD4, _GH_CMD5, _GH_CMD6, _GH_CMD7, _GH_CMD8); 52 | 53 | int GH_getCmd(char* str) { 54 | for (int i = 0; i < GH_CMD_LEN; i++) { 55 | if (!strcmp_P(str, _GH_cmd_list[i])) return i; 56 | } 57 | return -1; 58 | } 59 | 60 | 61 | // ===================== CMD NAME ==================== 62 | GH_PGM(_GH_CMDN0, "set"); 63 | GH_PGM(_GH_CMDN1, "cli"); 64 | GH_PGM(_GH_CMDN2, "delete"); 65 | GH_PGM(_GH_CMDN3, "rename"); 66 | GH_PGM(_GH_CMDN4, "fetch"); 67 | GH_PGM(_GH_CMDN5, "upload"); 68 | GH_PGM(_GH_CMDN6, "upload_chunk"); 69 | GH_PGM(_GH_CMDN7, "ota"); 70 | GH_PGM(_GH_CMDN8, "ota_chunk"); 71 | GH_PGM(_GH_CMDN9, "ota_url"); 72 | 73 | #define GH_CMDN_LEN 10 74 | GH_PGM_LIST(_GH_cmdN_list, _GH_CMDN0, _GH_CMDN1, _GH_CMDN2, _GH_CMDN3, _GH_CMDN4, _GH_CMDN5, _GH_CMDN6, _GH_CMDN7, _GH_CMDN8, _GH_CMDN9); 75 | 76 | int GH_getCmdN(char* str) { 77 | for (int i = 0; i < GH_CMDN_LEN; i++) { 78 | if (!strcmp_P(str, _GH_cmdN_list[i])) return i; 79 | } 80 | return -1; 81 | } 82 | */ -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/cmd_p.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../config.hpp" 4 | #include "../macro.hpp" 5 | 6 | int GH_getCmd(const char* str); 7 | //int GH_getCmdN(char* str); -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/color.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // ==================== COLORS ===================== 5 | enum GHcolors { 6 | GH_RED = 0xcb2839, 7 | GH_ORANGE = 0xd55f30, 8 | GH_YELLOW = 0xd69d27, 9 | GH_GREEN = 0x37A93C, 10 | GH_MINT = 0x25b18f, 11 | GH_AQUA = 0x2ba1cd, 12 | GH_BLUE = 0x297bcd, 13 | GH_VIOLET = 0x825ae7, 14 | GH_PINK = 0xc8589a, 15 | GH_DEFAULT = 0xffffffff, 16 | }; 17 | 18 | // ====================== COLOR ======================= 19 | struct GHcolor { 20 | uint8_t r = 0, g = 0, b = 0; 21 | 22 | GHcolor() {} 23 | GHcolor(const GHcolor& col) = default; 24 | GHcolor(uint8_t gray) { 25 | setGray(gray); 26 | } 27 | GHcolor(uint32_t hex, bool f) { 28 | if (f) setHEX(hex); 29 | } 30 | GHcolor(uint8_t v1, uint8_t v2, uint8_t v3, bool hsv = 0) { 31 | if (hsv) setHSV(v1, v2, v3); 32 | else setRGB(v1, v2, v3); 33 | } 34 | 35 | void setRGB(uint8_t nr, uint8_t ng, uint8_t nb) { 36 | r = nr; 37 | g = ng; 38 | b = nb; 39 | } 40 | void setGray(uint8_t gray) { 41 | setRGB(gray, gray, gray); 42 | } 43 | void setHEX(uint32_t hex) { 44 | r = ((uint8_t*)&hex)[2]; 45 | g = ((uint8_t*)&hex)[1]; 46 | b = ((uint8_t*)&hex)[0]; 47 | } 48 | void setHSV(uint8_t h, uint8_t s, uint8_t v) { 49 | float R, G, B; 50 | 51 | float H = h / 255.0; 52 | float S = s / 255.0; 53 | float V = v / 255.0; 54 | 55 | uint8_t i = H * 6; 56 | float f = H * 6 - i; 57 | float p = V * (1 - S); 58 | float q = V * (1 - f * S); 59 | float t = V * (1 - (1 - f) * S); 60 | 61 | switch (i) { 62 | case 0: 63 | R = V, G = t, B = p; 64 | break; 65 | case 1: 66 | R = q, G = V, B = p; 67 | break; 68 | case 2: 69 | R = p, G = V, B = t; 70 | break; 71 | case 3: 72 | R = p, G = q, B = V; 73 | break; 74 | case 4: 75 | R = t, G = p, B = V; 76 | break; 77 | case 5: 78 | R = V, G = p, B = q; 79 | break; 80 | } 81 | r = R * 255; 82 | g = G * 255; 83 | b = B * 255; 84 | } 85 | void setHue(uint8_t color) { 86 | uint8_t shift; 87 | if (color > 170) { 88 | shift = (color - 170) * 3; 89 | r = shift; 90 | g = 0; 91 | b = 255 - shift; 92 | } else if (color > 85) { 93 | shift = (color - 85) * 3; 94 | r = 0; 95 | g = 255 - shift; 96 | b = shift; 97 | } else { 98 | shift = color * 3; 99 | r = 255 - shift; 100 | g = shift; 101 | b = 0; 102 | } 103 | } 104 | 105 | uint32_t getHEX() { 106 | uint32_t hex = 0; 107 | ((uint8_t*)&hex)[2] = r; 108 | ((uint8_t*)&hex)[1] = g; 109 | ((uint8_t*)&hex)[0] = b; 110 | return hex; 111 | } 112 | operator uint32_t() { 113 | return getHEX(); 114 | } 115 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/datatypes.cpp: -------------------------------------------------------------------------------- 1 | #include "datatypes.h" 2 | 3 | void GHtypeFromStr(const char* str, void* var, GHdata_t type) { 4 | if (!var) return; 5 | switch (type) { 6 | case GH_STR: 7 | *(String*)var = str; 8 | break; 9 | case GH_CSTR: 10 | strcpy((char*)var, str); 11 | break; 12 | 13 | case GH_BOOL: 14 | *(bool*)var = (str[0] == '1'); 15 | break; 16 | 17 | case GH_INT8: 18 | *(int8_t*)var = atoi(str); 19 | break; 20 | 21 | case GH_UINT8: 22 | *(uint8_t*)var = atoi(str); 23 | break; 24 | 25 | case GH_INT16: 26 | *(int16_t*)var = atoi(str); 27 | break; 28 | case GH_UINT16: 29 | *(uint16_t*)var = atoi(str); 30 | break; 31 | 32 | case GH_INT32: 33 | *(int32_t*)var = atol(str); 34 | break; 35 | case GH_UINT32: 36 | *(uint32_t*)var = atol(str); 37 | break; 38 | 39 | case GH_FLOAT: 40 | *(float*)var = atof(str); 41 | break; 42 | case GH_DOUBLE: 43 | *(double*)var = atof(str); 44 | break; 45 | 46 | case GH_COLOR: 47 | ((GHcolor*)var)->setHEX(atol(str)); 48 | break; 49 | case GH_FLAGS: 50 | ((GHflags*)var)->flags = atoi(str); 51 | break; 52 | case GH_POS: { 53 | uint32_t xy = atol(str); 54 | ((GHpos*)var)->_changed = true; 55 | ((GHpos*)var)->x = xy >> 16; 56 | ((GHpos*)var)->y = xy & 0xffff; 57 | } break; 58 | 59 | case GH_NULL: 60 | break; 61 | } 62 | } 63 | 64 | void GHtypeToStr(String* s, void* var, GHdata_t type) { 65 | if (!var) { 66 | *s += '0'; 67 | return; 68 | } 69 | switch (type) { 70 | case GH_STR: 71 | //*s += *(String*)var; 72 | GH_addEsc(s, ((String*)var)->c_str()); 73 | break; 74 | case GH_CSTR: 75 | //*s += (char*)var; 76 | GH_addEsc(s, var); 77 | break; 78 | 79 | case GH_BOOL: 80 | *s += *(bool*)var; 81 | break; 82 | 83 | case GH_INT8: 84 | *s += *(int8_t*)var; 85 | break; 86 | 87 | case GH_UINT8: 88 | *s += *(uint8_t*)var; 89 | break; 90 | 91 | case GH_INT16: 92 | *s += *(int16_t*)var; 93 | break; 94 | case GH_UINT16: 95 | *s += *(uint16_t*)var; 96 | break; 97 | 98 | case GH_INT32: 99 | *s += *(int32_t*)var; 100 | break; 101 | case GH_UINT32: 102 | *s += *(uint32_t*)var; 103 | break; 104 | 105 | case GH_FLOAT: 106 | *s += *(float*)var; 107 | break; 108 | case GH_DOUBLE: 109 | *s += *(double*)var; 110 | break; 111 | 112 | case GH_COLOR: 113 | *s += ((GHcolor*)var)->getHEX(); 114 | break; 115 | case GH_FLAGS: 116 | *s += ((GHflags*)var)->flags; 117 | break; 118 | case GH_POS: 119 | break; 120 | 121 | case GH_NULL: 122 | *s += '0'; 123 | break; 124 | } 125 | } -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/datatypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../config.hpp" 5 | #include "../macro.hpp" 6 | #include "color.h" 7 | #include "flags.h" 8 | #include "pos.h" 9 | #include "misc.h" 10 | 11 | enum GHdata_t { 12 | GH_NULL, 13 | 14 | GH_STR, 15 | GH_CSTR, 16 | 17 | GH_BOOL, 18 | GH_INT8, 19 | GH_UINT8, 20 | GH_INT16, 21 | GH_UINT16, 22 | GH_INT32, 23 | GH_UINT32, 24 | 25 | GH_FLOAT, 26 | GH_DOUBLE, 27 | 28 | GH_COLOR, 29 | GH_FLAGS, 30 | GH_POS, 31 | }; 32 | 33 | void GHtypeToStr(String* s, void* val, GHdata_t type); 34 | void GHtypeFromStr(const char* s, void* val, GHdata_t type); -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/flags.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | struct GHflags { 5 | uint16_t flags = 0; 6 | 7 | GHflags() {} 8 | GHflags(const GHflags& f) = default; 9 | GHflags(uint16_t nflags) { 10 | flags = nflags; 11 | } 12 | 13 | void set(uint8_t idx, uint8_t val) { 14 | if (idx < 16) bitWrite(flags, idx, val); 15 | } 16 | uint8_t get(uint8_t idx) { 17 | if (idx < 16) return bitRead(flags, idx); 18 | else return 0; 19 | } 20 | 21 | String toString() { 22 | String s; 23 | s.reserve(16); 24 | for (int i = 0; i < 16; i++) s += get(i); 25 | return s; 26 | } 27 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/log.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "misc.h" 5 | 6 | class GHlog : public Print { 7 | public: 8 | // начать и указать размер буфера 9 | void begin(int n = 64) { 10 | end(); 11 | size = n; 12 | buffer = new char[size]; 13 | clear(); 14 | } 15 | 16 | ~GHlog() { 17 | end(); 18 | } 19 | 20 | // остановить 21 | void end() { 22 | if (buffer) { 23 | delete[] buffer; 24 | buffer = nullptr; 25 | } 26 | } 27 | 28 | virtual size_t write(uint8_t n) { 29 | if (buffer) { 30 | _write(n); 31 | } 32 | return 1; 33 | } 34 | 35 | // прочитать в строку 36 | void read(String* s, bool esc = false) { 37 | if (!buffer) return; 38 | bool start = 0; 39 | for (uint16_t i = 0; i < len; i++) { 40 | char c = _read(i); 41 | if (start) { 42 | if (esc) { 43 | if (c == '\"') *s += '\\'; 44 | } 45 | *s += c; 46 | } else if (c == '\n') start = 1; 47 | } 48 | } 49 | 50 | // прочитать строкой 51 | String read() { 52 | String s; 53 | s.reserve(len); 54 | read(&s); 55 | return s; 56 | } 57 | 58 | // очистить 59 | void clear() { 60 | len = head = 0; 61 | _write('\n'); 62 | } 63 | 64 | // есть данные 65 | bool available() { 66 | return (buffer && len); 67 | } 68 | 69 | // запущен 70 | bool state() { 71 | return buffer; 72 | } 73 | 74 | // длина 75 | int length() { 76 | return len; 77 | } 78 | 79 | char* buffer = nullptr; 80 | 81 | private: 82 | void _write(uint8_t n) { 83 | if (n == '\r') return; 84 | if (len < size) len++; 85 | buffer[head] = n; 86 | if (++head >= size) head = 0; 87 | } 88 | char _read(uint16_t num) { 89 | return buffer[(len < size) ? num : ((head + num) % size)]; 90 | } 91 | 92 | uint16_t size = 0; 93 | uint16_t len = 0; 94 | uint16_t head = 0; 95 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/mime.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../macro.hpp" 5 | 6 | #define GH_MIME_AMOUNT 17 7 | 8 | GH_PGM(_GH_MIME_EX0, ".avi"); 9 | GH_PGM(_GH_MIME_EX1, ".bin"); 10 | GH_PGM(_GH_MIME_EX2, ".bmp"); 11 | GH_PGM(_GH_MIME_EX3, ".css"); 12 | GH_PGM(_GH_MIME_EX4, ".csv"); 13 | GH_PGM(_GH_MIME_EX5, ".gz"); 14 | GH_PGM(_GH_MIME_EX6, ".gif"); 15 | GH_PGM(_GH_MIME_EX7, ".html"); 16 | GH_PGM(_GH_MIME_EX8, ".jpeg"); 17 | GH_PGM(_GH_MIME_EX9, ".jpg"); 18 | GH_PGM(_GH_MIME_EX10, ".js"); 19 | GH_PGM(_GH_MIME_EX11, ".json"); 20 | GH_PGM(_GH_MIME_EX12, ".png"); 21 | GH_PGM(_GH_MIME_EX13, ".svg"); 22 | GH_PGM(_GH_MIME_EX14, ".txt"); 23 | GH_PGM(_GH_MIME_EX15, ".wav"); 24 | GH_PGM(_GH_MIME_EX16, ".xml"); 25 | GH_PGM_LIST(_GH_mimie_ex_list, _GH_MIME_EX0, _GH_MIME_EX1, _GH_MIME_EX2, _GH_MIME_EX3, _GH_MIME_EX4, _GH_MIME_EX5, _GH_MIME_EX6, _GH_MIME_EX7, _GH_MIME_EX8, _GH_MIME_EX9, _GH_MIME_EX10, _GH_MIME_EX11, _GH_MIME_EX12, _GH_MIME_EX13, _GH_MIME_EX14, _GH_MIME_EX15, _GH_MIME_EX16); 26 | 27 | GH_PGM(_GH_MIME0, "video/x-msvideo"); 28 | GH_PGM(_GH_MIME1, "application/octet-stream"); 29 | GH_PGM(_GH_MIME2, "image/bmp"); 30 | GH_PGM(_GH_MIME3, "text/css"); 31 | GH_PGM(_GH_MIME4, "text/csv"); 32 | GH_PGM(_GH_MIME5, "application/gzip"); 33 | GH_PGM(_GH_MIME6, "image/gif"); 34 | GH_PGM(_GH_MIME7, "text/html"); 35 | GH_PGM(_GH_MIME8, "image/jpeg"); 36 | GH_PGM(_GH_MIME9, "image/jpeg"); 37 | GH_PGM(_GH_MIME10, "text/javascript"); 38 | GH_PGM(_GH_MIME11, "application/json"); 39 | GH_PGM(_GH_MIME12, "image/png"); 40 | GH_PGM(_GH_MIME13, "image/svg+xml"); 41 | GH_PGM(_GH_MIME14, "text/plain"); 42 | GH_PGM(_GH_MIME15, "audio/wav"); 43 | GH_PGM(_GH_MIME16, "application/xml"); 44 | GH_PGM_LIST(_GH_mimie_list, _GH_MIME0, _GH_MIME1, _GH_MIME2, _GH_MIME3, _GH_MIME4, _GH_MIME5, _GH_MIME6, _GH_MIME7, _GH_MIME8, _GH_MIME9, _GH_MIME10, _GH_MIME11, _GH_MIME12, _GH_MIME13, _GH_MIME14, _GH_MIME15, _GH_MIME16); -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/misc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../config.hpp" 5 | #include "../macro.hpp" 6 | #include "utils/b64.h" 7 | 8 | #ifdef GH_ESP_BUILD 9 | #ifndef GH_NO_FS 10 | #include 11 | #if (GH_FS == LittleFS) 12 | #include 13 | #elif (GH_FS == SPIFFS) 14 | #include 15 | #endif 16 | #endif 17 | 18 | #ifdef ESP8266 19 | #else 20 | #ifndef GH_NO_OTA 21 | #include 22 | #endif 23 | #endif 24 | #endif 25 | 26 | extern String _GH_empty_str; 27 | 28 | template 29 | struct GHparser { 30 | GHparser(char* url) { 31 | int16_t len = strlen(url); 32 | for (uint8_t i = 0; i < SIZE; i++) { 33 | char* div = (char*)memchr(url, '/', len); 34 | str[i] = url; 35 | size++; 36 | if (div && i < SIZE - 1) { 37 | uint8_t divlen = div - url; 38 | len -= divlen + 1; 39 | url += divlen + 1; 40 | *div = 0; 41 | } else break; 42 | } 43 | } 44 | ~GHparser() { 45 | for (int i = 1; i < size; i++) { 46 | *(str[i] - 1) = '/'; 47 | } 48 | } 49 | 50 | char* str[SIZE] = {}; 51 | uint8_t size = 0; 52 | }; 53 | 54 | char* GH_splitter(char* list, char div = ','); 55 | String GH_listIdx(const String& li, int idx, char div = ','); 56 | void GH_escapeChar(String* s, char c); 57 | void GH_addEsc(String* s, VSPTR str, bool fstr = 0, char sym = '\"'); 58 | //void GH_addEsc(String* s, VSPTR str, bool fstr = 0, const char* sym = "\""); 59 | 60 | #ifdef GH_ESP_BUILD 61 | #ifndef GH_NO_FS 62 | void GH_listDir(String& str, const String& path = "/", char div = ','); 63 | void GH_showFiles(String& answ, const String& path, GH_UNUSED uint8_t levels = 0, uint16_t* count = nullptr); 64 | void GH_fileToB64(File& file, String& str); 65 | void GH_bytesToB64(byte* bytes, uint32_t& idx, uint32_t& size, String& str); 66 | void GH_B64toFile(File& file, const char* str); 67 | #endif 68 | #ifndef GH_NO_OTA 69 | void GH_B64toUpdate(const char* str); 70 | #endif 71 | #endif -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/modules.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../config.hpp" 5 | 6 | enum GHmodule_t { 7 | GH_MOD_INFO = (1ul << 0), 8 | GH_MOD_FSBR = (1ul << 1), 9 | GH_MOD_FORMAT = (1ul << 2), 10 | GH_MOD_DOWNLOAD = (1ul << 3), 11 | GH_MOD_UPLOAD = (1ul << 4), 12 | GH_MOD_OTA = (1ul << 5), 13 | GH_MOD_OTA_URL = (1ul << 6), 14 | GH_MOD_REBOOT = (1ul << 7), 15 | GH_MOD_SET = (1ul << 8), 16 | GH_MOD_READ = (1ul << 9), 17 | GH_MOD_DELETE = (1ul << 10), 18 | GH_MOD_RENAME = (1ul << 11), 19 | GH_MOD_SERIAL = (1ul << 12), 20 | GH_MOD_BT = (1ul << 13), 21 | GH_MOD_WS = (1ul << 14), 22 | GH_MOD_MQTT = (1ul << 15), 23 | }; 24 | 25 | struct GHmodule { 26 | uint16_t mods = 0; 27 | 28 | void set(uint16_t nmods) { 29 | mods &= ~nmods; 30 | } 31 | void unset(uint16_t nmods) { 32 | mods |= nmods; 33 | } 34 | 35 | void setAll() { 36 | mods = 0; 37 | } 38 | void unsetAll() { 39 | mods = (1ul << 16) - 1; 40 | } 41 | bool read(GHmodule_t m) { 42 | return !(mods & m); 43 | } 44 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/pos.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "pos_geo.h" 4 | 5 | class GHpos { 6 | public: 7 | GHpos() {} 8 | GHpos(int16_t nx, int16_t ny, bool nc = 0) : x(nx), y(ny), _changed(nc) {} 9 | 10 | bool changed() { 11 | return _changed ? (_changed = 0, 1) : 0; 12 | } 13 | 14 | // расстояние до точки 15 | int16_t dist(int16_t x1, int16_t y1) { 16 | return GHdist(x, y, x1, y1); 17 | } 18 | 19 | // точка лежит внутри прямоугольника 20 | bool inRect(int16_t rx, int16_t ry, int16_t w, int16_t h) { 21 | return GHinRect(x, y, rx, ry, w, h); 22 | } 23 | 24 | // точка лежит внутри окружности 25 | bool inCircle(int16_t cx, int16_t cy, int16_t r) { 26 | return GHinCircle(x, y, cx, cy, r); 27 | } 28 | 29 | // координаты 30 | int16_t x = 0; 31 | int16_t y = 0; 32 | 33 | bool _changed = 0; 34 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/pos_geo.cpp: -------------------------------------------------------------------------------- 1 | #include "pos_geo.h" 2 | 3 | int16_t GHdist(int16_t x0, int16_t y0, int16_t x1, int16_t y1) { 4 | x1 -= x0; 5 | y1 -= y0; 6 | return sqrt(x1 * x1 + y1 * y1); 7 | } 8 | 9 | bool GHinRect(int16_t x, int16_t y, int16_t rx, int16_t ry, int16_t w, int16_t h) { 10 | return (x > rx) && (x < rx + w) && (y > ry) && (y < ry + h); 11 | } 12 | 13 | bool GHinCircle(int16_t x, int16_t y, int16_t cx, int16_t cy, int16_t r) { 14 | return GHdist(x, y, cx, cy) < r; 15 | } -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/pos_geo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // расстояние между двумя точками 5 | int16_t GHdist(int16_t x0, int16_t y0, int16_t x1, int16_t y1); 6 | 7 | // точка лежит внутри прямоугольника (координаты угла и размеры) 8 | bool GHinRect(int16_t x, int16_t y, int16_t rx, int16_t ry, int16_t w, int16_t h); 9 | 10 | // точка лежит внутри окружности (координаты центра и радиус) 11 | bool GHinCircle(int16_t x, int16_t y, int16_t cx, int16_t cy, int16_t r); -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/stats.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../config.hpp" 3 | 4 | enum GHsource_t { 5 | GH_ESP, 6 | GH_MANUAL, 7 | GH_STREAM 8 | }; 9 | 10 | // тип info 11 | enum GHinfo_t { 12 | GH_INFO_VERSION, 13 | GH_INFO_NETWORK, 14 | GH_INFO_MEMORY, 15 | GH_INFO_SYSTEM, 16 | }; 17 | 18 | // причина перезагрузки 19 | enum GHreason_t { 20 | GH_REB_NONE, 21 | GH_REB_BUTTON, 22 | GH_REB_OTA, 23 | GH_REB_OTA_URL, 24 | }; 25 | 26 | // тип подключения 27 | enum GHconn_t { 28 | GH_SERIAL, 29 | GH_BT, 30 | GH_WS, 31 | GH_MQTT, 32 | GH_SYSTEM, 33 | }; 34 | 35 | #define GH_CONN_AMOUNT 4 36 | 37 | // системные события 38 | enum GHevent_t { 39 | GH_FOCUS, 40 | GH_PING, 41 | GH_UNFOCUS, 42 | GH_INFO, 43 | GH_FSBR, 44 | GH_FORMAT, 45 | GH_REBOOT, 46 | GH_DOWNLOAD_CHUNK, 47 | GH_DOWNLOAD_ABORTED, 48 | 49 | GH_DATA, 50 | GH_SET, 51 | GH_CLI, 52 | GH_DELETE, 53 | GH_RENAME, 54 | GH_DOWNLOAD, 55 | GH_UPLOAD, 56 | GH_UPLOAD_CHUNK, 57 | GH_OTA, 58 | GH_OTA_CHUNK, 59 | GH_OTA_URL, 60 | 61 | GH_IDLE, 62 | GH_START, 63 | GH_STOP, 64 | 65 | GH_CONNECTING, 66 | GH_CONNECTED, 67 | GH_DISCONNECTED, 68 | GH_ERROR, 69 | 70 | GH_UNKNOWN, 71 | GH_DISCOVER_ALL, 72 | GH_DISCOVER, 73 | 74 | GH_READ_HOOK, 75 | GH_SET_HOOK, 76 | 77 | GH_DOWNLOAD_ERROR, 78 | GH_DOWNLOAD_FINISH, 79 | 80 | GH_UPLOAD_ERROR, 81 | GH_UPLOAD_ABORTED, 82 | GH_UPLOAD_FINISH, 83 | 84 | GH_OTA_ERROR, 85 | GH_OTA_ABORTED, 86 | GH_OTA_FINISH, 87 | }; -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/stats_p.cpp: -------------------------------------------------------------------------------- 1 | #include "stats_p.h" 2 | 3 | GH_PGM(_GH_RES0, "NONE"); 4 | GH_PGM(_GH_RES1, "BUTTON"); 5 | GH_PGM(_GH_RES2, "OTA"); 6 | GH_PGM(_GH_RES3, "OTA_URL"); 7 | GH_PGM_LIST(_GH_res_list, _GH_RES0, _GH_RES1, _GH_RES2, _GH_RES3); 8 | FSTR GHreadReason(GHreason_t n) { 9 | #ifdef GH_ESP_BUILD 10 | return (FSTR)_GH_res_list[n]; 11 | #else 12 | return (FSTR)pgm_read_word(_GH_res_list + n); 13 | #endif 14 | } 15 | 16 | GH_PGM(_GH_BLD0, "NONE"); 17 | GH_PGM(_GH_BLD1, "ACTION"); 18 | GH_PGM(_GH_BLD2, "COUNT"); 19 | GH_PGM(_GH_BLD3, "READ"); 20 | GH_PGM(_GH_BLD4, "UI"); 21 | GH_PGM(_GH_BLD5, "TG"); 22 | GH_PGM(_GH_BLD6, "INFO"); 23 | GH_PGM_LIST(_GH_bld_list, _GH_BLD0, _GH_BLD1, _GH_BLD2, _GH_BLD3, _GH_BLD4, _GH_BLD5, _GH_BLD6); 24 | FSTR GHreadBuild(GHbuild_t n) { 25 | #ifdef GH_ESP_BUILD 26 | return (FSTR)_GH_bld_list[n]; 27 | #else 28 | return (FSTR)pgm_read_word(_GH_bld_list + n); 29 | #endif 30 | } 31 | 32 | GH_PGM(_GH_CON0, "SERIAL"); 33 | GH_PGM(_GH_CON1, "BT"); 34 | GH_PGM(_GH_CON2, "WS"); 35 | GH_PGM(_GH_CON3, "MQTT"); 36 | GH_PGM(_GH_CON4, "SYSTEM"); 37 | GH_PGM_LIST(_GH_con_list, _GH_CON0, _GH_CON1, _GH_CON2, _GH_CON3, _GH_CON4); 38 | FSTR GHreadConn(GHconn_t n) { 39 | #ifdef GH_ESP_BUILD 40 | return (FSTR)_GH_con_list[n]; 41 | #else 42 | return (FSTR)pgm_read_word(_GH_con_list + n); 43 | #endif 44 | } 45 | 46 | GH_PGM(_GH_STA0, "FOCUS"); 47 | GH_PGM(_GH_STA1, "PING"); 48 | GH_PGM(_GH_STA2, "UNFOCUS"); 49 | GH_PGM(_GH_STA3, "INFO"); 50 | GH_PGM(_GH_STA4, "FSBR"); 51 | GH_PGM(_GH_STA5, "FORMAT"); 52 | GH_PGM(_GH_STA6, "REBOOT"); 53 | GH_PGM(_GH_STA7, "DOWNLOAD_CHUNK"); 54 | GH_PGM(_GH_STA8, "DOWNLOAD_ABORTED"); 55 | GH_PGM(_GH_STA9, "DATA"); 56 | GH_PGM(_GH_STA10, "SET"); 57 | GH_PGM(_GH_STA11, "CLI"); 58 | GH_PGM(_GH_STA12, "DELETE"); 59 | GH_PGM(_GH_STA13, "RENAME"); 60 | GH_PGM(_GH_STA14, "DOWNLOAD"); 61 | GH_PGM(_GH_STA15, "UPLOAD"); 62 | GH_PGM(_GH_STA16, "UPLOAD_CHUNK"); 63 | GH_PGM(_GH_STA17, "OTA"); 64 | GH_PGM(_GH_STA18, "OTA_CHUNK"); 65 | GH_PGM(_GH_STA19, "OTA_URL"); 66 | GH_PGM(_GH_STA20, "IDLE"); 67 | GH_PGM(_GH_STA21, "START"); 68 | GH_PGM(_GH_STA22, "STOP"); 69 | GH_PGM(_GH_STA23, "CONNECTING"); 70 | GH_PGM(_GH_STA24, "CONNECTED"); 71 | GH_PGM(_GH_STA25, "DISCONNECTED"); 72 | GH_PGM(_GH_STA26, "ERROR"); 73 | GH_PGM(_GH_STA27, "UNKNOWN"); 74 | GH_PGM(_GH_STA28, "DISCOVER_ALL"); 75 | GH_PGM(_GH_STA29, "DISCOVER"); 76 | GH_PGM(_GH_STA30, "READ_HOOK"); 77 | GH_PGM(_GH_STA31, "SET_HOOK"); 78 | GH_PGM(_GH_STA32, "DOWNLOAD_ERROR"); 79 | GH_PGM(_GH_STA33, "DOWNLOAD_FINISH"); 80 | GH_PGM(_GH_STA34, "UPLOAD_ERROR"); 81 | GH_PGM(_GH_STA35, "UPLOAD_ABORTED"); 82 | GH_PGM(_GH_STA36, "UPLOAD_FINISH"); 83 | GH_PGM(_GH_STA37, "OTA_ERROR"); 84 | GH_PGM(_GH_STA38, "OTA_ABORTED"); 85 | GH_PGM(_GH_STA39, "OTA_FINISH"); 86 | GH_PGM_LIST(_GH_sta_list, _GH_STA0, _GH_STA1, _GH_STA2, _GH_STA3, _GH_STA4, _GH_STA5, _GH_STA6, _GH_STA7, _GH_STA8, _GH_STA9, _GH_STA10, _GH_STA11, _GH_STA12, _GH_STA13, _GH_STA14, _GH_STA15, _GH_STA16, _GH_STA17, _GH_STA18, _GH_STA19, _GH_STA20, _GH_STA21, _GH_STA22, _GH_STA23, _GH_STA24, _GH_STA25, _GH_STA26, _GH_STA27, _GH_STA28, _GH_STA29, _GH_STA30, _GH_STA31, _GH_STA32, _GH_STA33, _GH_STA34, _GH_STA35, _GH_STA36, _GH_STA37, _GH_STA38, _GH_STA39); 87 | FSTR GHreadEvent(GHevent_t n) { 88 | #ifdef GH_ESP_BUILD 89 | return (FSTR)_GH_sta_list[n]; 90 | #else 91 | return (FSTR)pgm_read_word(_GH_sta_list + n); 92 | #endif 93 | } -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/stats_p.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../config.hpp" 4 | #include "../macro.hpp" 5 | #include "stats.h" 6 | #include "action.h" 7 | #include "build.h" 8 | 9 | // получить текстовое значение типа GHevent_t для вывода в порт 10 | FSTR GHreadEvent(GHevent_t n); 11 | 12 | // получить текстовое значение типа GHconn_t для вывода в порт 13 | FSTR GHreadConn(GHconn_t n); 14 | 15 | // получить текстовое значение типа GHbuild_t для вывода в порт 16 | FSTR GHreadBuild(GHbuild_t n); 17 | 18 | // получить текстовое значение типа GHreason_t для вывода в порт 19 | FSTR GHreadReason(GHreason_t n); -------------------------------------------------------------------------------- /libraries/GyverHub/src/utils/timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // ====================== TIMER ======================= 5 | struct GHtimer { 6 | GHtimer() {} 7 | GHtimer(uint32_t ms, uint8_t seconds = 0, uint8_t minutes = 0, uint8_t hours = 0, uint8_t days = 0) { 8 | start(ms, seconds, minutes, hours, days); 9 | } 10 | 11 | void start(uint32_t ms, uint8_t seconds = 0, uint8_t minutes = 0, uint8_t hours = 0, uint8_t days = 0) { 12 | prd = days * 86400ul + hours * 3600ul + minutes * 60 + seconds; 13 | prd *= 1000ul; 14 | prd += ms; 15 | if (prd) start(); 16 | } 17 | void start() { 18 | if (!prd) return; 19 | tmr = millis(); 20 | if (!tmr) tmr = 1; 21 | } 22 | void stop() { 23 | tmr = 0; 24 | } 25 | bool ready() { 26 | return (tmr && millis() - tmr >= prd) ? (start(), true) : false; 27 | } 28 | operator bool() { 29 | return ready(); 30 | } 31 | 32 | uint32_t tmr = 0, prd = 0; 33 | }; 34 | -------------------------------------------------------------------------------- /libraries/GyverStepper/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /libraries/GyverStepper/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 AlexGyver 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerArray/PlannerArray.ino: -------------------------------------------------------------------------------- 1 | // пример с записанным в памяти маршрутом 2 | // смотри график 3 | 4 | int path[][2] = { 5 | {10, 10}, 6 | {100, 5}, 7 | {200, 200}, 8 | {150, 150}, 9 | {0, 0}, 10 | {0, 50}, 11 | }; 12 | 13 | // количество точек (пусть компилятор сам считает) 14 | // как вес всего массива / (2+2) байта 15 | int nodeAmount = sizeof(path) / 4; 16 | 17 | #include "GyverPlanner.h" 18 | Stepper stepper1(2, 5); 19 | Stepper stepper2(3, 6); 20 | GPlanner planner; 21 | 22 | void setup() { 23 | Serial.begin(115200); 24 | // добавляем шаговики на оси 25 | planner.addStepper(0, stepper1); // ось 0 26 | planner.addStepper(1, stepper2); // ось 1 27 | 28 | // устанавливаем ускорение и скорость 29 | planner.setAcceleration(100); 30 | planner.setMaxSpeed(300); 31 | } 32 | 33 | int count = 0; // счётчик точек маршрута 34 | void loop() { 35 | // здесь происходит движение моторов, вызывать как можно чаще 36 | planner.tick(); 37 | 38 | // вернёт true, если все моторы доехали 39 | if (planner.ready()) { 40 | 41 | if (count < nodeAmount) { // ограничиваем на количество точек, чтобы не бахнуло 42 | planner.setTarget(path[count]); // загружаем новую точку (начнётся с 0) 43 | count++; 44 | } 45 | } 46 | 47 | // асинхронно вывожу в порт графики 48 | static uint32_t tmr; 49 | if (millis() - tmr >= 20) { 50 | tmr = millis(); 51 | Serial.print(stepper1.pos); 52 | Serial.print(','); 53 | Serial.println(stepper2.pos); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerCircle/PlannerCircle.ino: -------------------------------------------------------------------------------- 1 | // пример с записанным в памяти маршрутом окружности 2 | // работу можно посмотреть в плоттере, а лучше в приложенном stepperPlot 3 | 4 | const int pointAm = 30; // количество точек в круге 5 | int radius = 100; // радиус круга 6 | int32_t path[pointAm + 2][2]; // буфер круга 7 | 8 | #include "GyverPlanner.h" 9 | Stepper stepper1(2, 5); 10 | Stepper stepper2(3, 6); 11 | GPlanner planner; 12 | 13 | void setup() { 14 | Serial.begin(115200); 15 | // добавляем шаговики на оси 16 | planner.addStepper(0, stepper1); // ось 0 17 | planner.addStepper(1, stepper2); // ось 1 18 | 19 | // устанавливаем ускорение и скорость 20 | planner.setAcceleration(500); 21 | planner.setMaxSpeed(500); 22 | 23 | // заполняем буфер 24 | for (int i = 0; i <= pointAm; i++) { 25 | path[i + 1][0] = radius + radius * cos(TWO_PI * i / pointAm); 26 | path[i + 1][1] = radius + radius * sin(TWO_PI * i / pointAm); 27 | } 28 | } 29 | 30 | int count = 0; // счётчик точек маршрута 31 | void loop() { 32 | // здесь происходит движение моторов, вызывать как можно чаще 33 | planner.tick(); 34 | 35 | // вернёт true, если все моторы доехали 36 | if (planner.ready()) { 37 | planner.setTarget(path[count]); // загружаем новую точку (начнётся с 0) 38 | if (++count >= sizeof(path) / 8) count = 0; 39 | } 40 | 41 | // асинхронно вывожу в порт графики 42 | static uint32_t tmr; 43 | if (millis() - tmr >= 20) { 44 | tmr = millis(); 45 | Serial.print(stepper1.pos); 46 | Serial.print(','); 47 | Serial.println(stepper2.pos); 48 | } 49 | } -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerCircle/stepperPlot/stepperPlot.pde: -------------------------------------------------------------------------------- 1 | String port = "COM6"; // имя порта 2 | 3 | import processing.serial.*; 4 | Serial myPort; 5 | 6 | void setup() { 7 | size(500, 500); 8 | myPort = new Serial(this, port, 115200); 9 | fill(0); 10 | noStroke(); 11 | } 12 | 13 | void draw() { 14 | if (myPort.available() > 0) { 15 | String str = myPort.readStringUntil('\n').trim(); 16 | if (str != null) { 17 | String[] pos = split(str, ','); 18 | int x = int(pos[0]); 19 | int y = int(pos[1]); 20 | fill(10); 21 | circle(x+10, y+10, 4); 22 | fill(200, 1); 23 | rect(0, 0, width, height); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerControl/PlannerControl.ino: -------------------------------------------------------------------------------- 1 | // здесь у нас моторы движутся по трём точкам траектории 2 | // можно открыть плоттер, наблюать за этим и отправлять команды: 3 | // s - стоп 4 | // b - тормоз 5 | // p - пауза 6 | // r - продолжить 7 | 8 | #include "GyverPlanner.h" 9 | Stepper stepper1(2, 5); 10 | Stepper stepper2(3, 6); 11 | GPlanner planner; 12 | 13 | void setup() { 14 | Serial.begin(57600); 15 | // добавляем шаговики на оси 16 | planner.addStepper(0, stepper1); // ось 0 17 | planner.addStepper(1, stepper2); // ось 1 18 | 19 | // устанавливаем ускорение и скорость 20 | planner.setAcceleration(200); 21 | planner.setMaxSpeed(200); 22 | } 23 | 24 | byte count = 0; 25 | int32_t path[][2] = { 26 | {0, 0}, 27 | {100, 150}, 28 | {200, 200}, 29 | }; 30 | 31 | void loop() { 32 | // здесь происходит движение моторов, вызывать как можно чаще 33 | planner.tick(); 34 | 35 | // вернёт true, если все моторы доехали 36 | if (planner.ready()) { 37 | planner.setTarget(path[count]); // загружаем новую точку (начнётся с 0) 38 | if (++count >= sizeof(path) / 8) count = 0; 39 | } 40 | 41 | // управляем процессом 42 | if (Serial.available() > 0) { 43 | char incoming = Serial.read(); 44 | switch (incoming) { 45 | case 's': planner.stop(); break; 46 | case 'b': planner.brake(); break; 47 | case 'r': planner.resume(); break; 48 | case 'p': planner.pause(); break; 49 | } 50 | } 51 | 52 | // асинхронно вывожу в порт графики 53 | static uint32_t tmr; 54 | if (millis() - tmr >= 20) { 55 | tmr = millis(); 56 | Serial.print(planner.getTarget(0)); 57 | Serial.print(','); 58 | Serial.print(planner.getTarget(1)); 59 | Serial.print(','); 60 | Serial.print(stepper1.pos); 61 | Serial.print(','); 62 | Serial.println(stepper2.pos); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerDemo/PlannerDemo.ino: -------------------------------------------------------------------------------- 1 | // базовый пример: как создать и запустить планировщик 2 | // при запуске моторы будут отправлены на первую позицию 3 | // при достижении - на вторую. После этого движение прекратится 4 | // открой плоттер и смотри графики 5 | 6 | #include "GyverPlanner.h" 7 | // создаём моторы класса Stepper с указанием типа драйвера и пинов. Примеры: 8 | // Stepper stepper(step, dir); // драйвер step-dir 9 | // Stepper stepper(step, dir, en); // драйвер step-dir + пин enable 10 | // Stepper stepper(pin1, pin2, pin3, pin4); // драйвер 4 пин 11 | // Stepper stepper(pin1, pin2, pin3, pin4, en); // драйвер 4 пин + enable 12 | // Stepper stepper(pin1, pin2, pin3, pin4); // драйвер 4 пин полушаг 13 | // Stepper stepper(pin1, pin2, pin3, pin4, en); // драйвер 4 пин полушаг + enable 14 | 15 | // МОТОРЫ ДОЛЖНЫ БЫТЬ С ОДИНАКОВЫМ ТИПОМ ДРАЙВЕРА 16 | // вот они красавцы 17 | Stepper stepper1(2, 5); 18 | Stepper stepper2(3, 6); 19 | 20 | // создаём планировщик, указываем в <> тип драйвера КАК У МОТОРОВ 21 | // и количество осей, равное количеству моторов (любое больше 1) 22 | GPlanner planner; 23 | 24 | void setup() { 25 | Serial.begin(115200); 26 | // добавляем шаговики на оси 27 | planner.addStepper(0, stepper1); // ось 0 28 | planner.addStepper(1, stepper2); // ось 1 29 | 30 | // устанавливаем ускорение и скорость 31 | planner.setAcceleration(100); 32 | planner.setMaxSpeed(300); 33 | 34 | planner.reset(); // сбрасываем все позиции в 0 (они и так в 0 при запуске) 35 | 36 | // массив с целевыми позициями осей, размер массива равен количеству осей 37 | int target[] = {300, 200}; 38 | 39 | // отправляем 40 | planner.setTarget(target); 41 | } 42 | 43 | void loop() { 44 | // здесь происходит движение моторов, вызывать как можно чаще 45 | planner.tick(); 46 | 47 | // вернёт true, если все моторы доехали 48 | if (planner.ready()) { 49 | // загружаем новую точку 50 | int newTarget[] = {10, 50}; 51 | planner.setTarget(newTarget); 52 | } 53 | 54 | // асинхронно вывожу в порт графики 55 | static uint32_t tmr; 56 | if (millis() - tmr >= 20) { 57 | tmr = millis(); 58 | Serial.print(stepper1.pos); 59 | Serial.print(','); 60 | Serial.println(stepper2.pos); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerHoming/PlannerHoming.ino: -------------------------------------------------------------------------------- 1 | // пример калибровки нуля по концевикам 2 | // концевики на D6 и D7 3 | #define LIMSW_X 6 4 | #define LIMSW_Y 7 5 | 6 | #include "GyverPlanner.h" 7 | Stepper stepper1(2, 5); 8 | Stepper stepper2(3, 6); 9 | GPlanner planner; 10 | 11 | void setup() { 12 | // добавляем шаговики на оси 13 | planner.addStepper(0, stepper1); // ось 0 14 | planner.addStepper(1, stepper2); // ось 1 15 | 16 | // устанавливаем ускорение и скорость 17 | planner.setAcceleration(100); 18 | planner.setMaxSpeed(300); 19 | 20 | // пуллапим. Кнопки замыкают на GND 21 | pinMode(LIMSW_X, INPUT_PULLUP); 22 | pinMode(LIMSW_Y, INPUT_PULLUP); 23 | } 24 | 25 | void loop() { 26 | } 27 | 28 | void homing() { 29 | if (digitalRead(LIMSW_X)) { // если концевик X не нажат 30 | planner.setSpeed(0, -10); // ось Х, -10 шаг/сек 31 | while (digitalRead(LIMSW_X)) { // пока кнопка не нажата 32 | planner.tick(); // крутим 33 | } 34 | // кнопка нажалась - покидаем цикл 35 | planner.brake(); // тормозим, приехали 36 | } 37 | 38 | if (digitalRead(LIMSW_Y)) { // если концевик Y не нажат 39 | planner.setSpeed(1, -10); // ось Y, -10 шаг/сек 40 | while (digitalRead(LIMSW_Y)) { // пока кнопка не нажата 41 | planner.tick(); // крутим 42 | } 43 | // кнопка нажалась - покидаем цикл 44 | planner.brake(); // тормозим, приехали 45 | } 46 | planner.reset(); // сбрасываем координаты в 0 47 | } 48 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerSpeedControl/PlannerSpeedControl.ino: -------------------------------------------------------------------------------- 1 | // крутим мотор. Отправляй в сериал целое число, шаг/сек 2 | 3 | #include "GyverPlanner.h" 4 | Stepper stepper1(2, 5); 5 | Stepper stepper2(3, 6); 6 | GPlanner planner; 7 | 8 | void setup() { 9 | Serial.begin(57600); 10 | // добавляем шаговики на оси 11 | planner.addStepper(0, stepper1); // ось 0 12 | planner.addStepper(1, stepper2); // ось 1 13 | 14 | Serial.setTimeout(10); 15 | } 16 | 17 | void loop() { 18 | // здесь происходит движение моторов, вызывать как можно чаще 19 | planner.tick(); 20 | 21 | // управляем скоростью 22 | if (Serial.available() > 0) { 23 | int val = Serial.parseInt(); 24 | planner.setSpeed(0, val); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerTimerISR/PlannerTimerISR.ino: -------------------------------------------------------------------------------- 1 | // пример с движением моторов в прерывании 2 | // используется Timer1 на atmega328 3 | 4 | #include "GyverPlanner.h" 5 | Stepper stepper1(2, 5); 6 | Stepper stepper2(3, 6); 7 | GPlanner planner; 8 | 9 | void setup() { 10 | Serial.begin(115200); 11 | // добавляем шаговики на оси 12 | planner.addStepper(0, stepper1); // ось 0 13 | planner.addStepper(1, stepper2); // ось 1 14 | 15 | initTimer(); 16 | startTimer(); 17 | } 18 | 19 | // прерывание таймера 20 | ISR(TIMER1_COMPA_vect) { 21 | // здесь происходит движение моторов 22 | // если мотор должен двигаться (true) - ставим новый период таймеру 23 | if (planner.tickManual()) setPeriod(planner.getPeriod()); 24 | else stopTimer(); 25 | // если нет - останавливаем таймер 26 | } 27 | 28 | int path[][2] = { 29 | {10, 10}, 30 | {100, 5}, 31 | {200, 200}, 32 | {150, 150}, 33 | {0, 0}, 34 | {0, 50}, 35 | }; 36 | 37 | int count = 0; // счётчик точек маршрута 38 | 39 | void loop() { 40 | // вернёт true, если все моторы доехали 41 | if (planner.ready()) { 42 | if (count < sizeof(path) / 4) { // ограничиваем на количество точек 43 | if (planner.setTarget(path[count])) { // загружаем новую точку (начнётся с 0) 44 | // выполняем дальше код, если есть куда двигаться (получили true) 45 | // после вызова setTarget обновляется период! можно его юзать 46 | startTimer(); // запускаем таймер 47 | setPeriod(planner.getPeriod()); // устанавливаем период 48 | count++; 49 | } 50 | } 51 | } 52 | 53 | // асинхронно вывожу в порт графики 54 | static uint32_t tmr; 55 | if (millis() - tmr >= 20) { 56 | tmr = millis(); 57 | Serial.print(stepper1.pos); 58 | Serial.print(','); 59 | Serial.println(stepper2.pos); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner/PlannerTimerISR/timer.ino: -------------------------------------------------------------------------------- 1 | // настроить таймер 2 | void initTimer() { 3 | TCCR1A = 0; 4 | // CTC по OCR1A, делитель /64 5 | TCCR1B = bit(WGM12) | 0b011; 6 | } 7 | 8 | // установить период 9 | void setPeriod(uint32_t prd) { 10 | // один тик таймера - 4 мкс (при 16 МГц клоке) 11 | OCR1A = (uint32_t)prd >> 2; 12 | } 13 | 14 | // запустить и сбросить таймер 15 | void startTimer() { 16 | TIMSK1 = bit(OCIE1A); 17 | TCNT1 = 0; 18 | } 19 | 20 | // остановить таймер 21 | void stopTimer() { 22 | TIMSK1 = 0; 23 | TCNT1 = 0; 24 | } 25 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner2/PlannerArray/PlannerArray.ino: -------------------------------------------------------------------------------- 1 | // пример с записанным в памяти маршрутом 2 | // смотри график 3 | 4 | int path[][2] = { 5 | {100, 250}, 6 | {160, 30}, 7 | {230, 250}, 8 | {60, 100}, 9 | {270, 100}, 10 | }; 11 | 12 | // количество точек (пусть компилятор сам считает) 13 | // как вес всего массива / (2+2) байта 14 | int nodeAmount = sizeof(path) / 4; 15 | 16 | #include "GyverPlanner2.h" 17 | Stepper stepper1(2, 5); 18 | Stepper stepper2(3, 6); 19 | GPlanner2 planner; 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | // добавляем шаговики на оси 24 | planner.addStepper(0, stepper1); // ось 0 25 | planner.addStepper(1, stepper2); // ось 1 26 | 27 | // устанавливаем ускорение и скорость 28 | planner.setAcceleration(500); 29 | planner.setMaxSpeed(500); 30 | 31 | // начальная точка системы должна совпадать с первой точкой маршрута 32 | planner.setCurrent(path[0]); 33 | planner.start(); 34 | } 35 | 36 | int count = 0; // счётчик точек маршрута 37 | void loop() { 38 | // здесь происходит движение моторов, вызывать как можно чаще 39 | planner.tick(); 40 | 41 | // если в буфере планировщика есть место 42 | if (planner.available()) { 43 | // добавляем точку маршрута и является ли она точкой остановки (0 - нет) 44 | planner.addTarget(path[count], 0); 45 | if (++count >= sizeof(path) / 4) count = 0; // закольцевать 46 | } 47 | 48 | // асинхронно вывожу в порт графики 49 | static uint32_t tmr; 50 | if (millis() - tmr >= 20) { 51 | tmr = millis(); 52 | Serial.print(stepper1.pos); 53 | Serial.print(','); 54 | Serial.println(stepper2.pos); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner2/PlannerArray/stepperPlot/stepperPlot.pde: -------------------------------------------------------------------------------- 1 | String port = "COM6"; // имя порта 2 | 3 | import processing.serial.*; 4 | Serial myPort; 5 | 6 | void setup() { 7 | size(500, 500); 8 | myPort = new Serial(this, port, 115200); 9 | fill(0); 10 | noStroke(); 11 | } 12 | 13 | void draw() { 14 | if (myPort.available() > 0) { 15 | String str = myPort.readStringUntil('\n').trim(); 16 | if (str != null) { 17 | String[] pos = split(str, ','); 18 | if (pos.length < 2) return; 19 | int x = int(pos[0]); 20 | int y = int(pos[1]); 21 | fill(10); 22 | circle(x+10, y+10, 4); 23 | fill(200, 2); 24 | rect(0, 0, width, height); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner2/PlannerCircle/PlannerCircle.ino: -------------------------------------------------------------------------------- 1 | // пример с записанным в памяти маршрутом окружности 2 | // работу можно посмотреть в плоттере, а лучше в приложенном stepperPlot для Processing 3 | 4 | const int pointAm = 30; // количество точек в круге 5 | int radius = 100; // радиус круга 6 | int32_t path[pointAm + 1 + 1][2]; // буфер круга 7 | // +1 на стартовую точку +1 на замыкание круга 8 | 9 | #include "GyverPlanner2.h" 10 | Stepper stepper1(2, 5); 11 | Stepper stepper2(3, 6); 12 | GPlanner2 planner; 13 | 14 | void setup() { 15 | Serial.begin(115200); 16 | // добавляем шаговики на оси 17 | planner.addStepper(0, stepper1); // ось 0 18 | planner.addStepper(1, stepper2); // ось 1 19 | 20 | // устанавливаем ускорение и скорость 21 | planner.setAcceleration(500); 22 | planner.setMaxSpeed(500); 23 | 24 | // начальная точка системы должна совпадать с первой точкой маршрута 25 | planner.setCurrent(path[0]); 26 | 27 | // заполняем буфер 28 | for (int i = 0; i <= pointAm; i++) { 29 | path[i + 1][0] = radius + radius * cos(TWO_PI * i / pointAm); 30 | path[i + 1][1] = radius + radius * sin(TWO_PI * i / pointAm); 31 | } 32 | // 0 - координата 0,0 33 | // 1 - первая координата круга 34 | // итд 35 | 36 | planner.start(); 37 | } 38 | 39 | int count = 0; // счётчик точек маршрута 40 | void loop() { 41 | // здесь происходит движение моторов, вызывать как можно чаще 42 | planner.tick(); 43 | 44 | // если в буфере планировщика есть место 45 | if (planner.available()) { 46 | // добавляем точку маршрута и является ли она точкой остановки (0 - нет) 47 | planner.addTarget(path[count], 0); 48 | if (++count >= sizeof(path) / 8) count = 0; // закольцевать 49 | } 50 | 51 | // асинхронно вывожу в порт графики 52 | static uint32_t tmr; 53 | if (millis() - tmr >= 20) { 54 | tmr = millis(); 55 | Serial.print(stepper1.pos); 56 | Serial.print(','); 57 | Serial.println(stepper2.pos); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner2/PlannerCircle/stepperPlot/stepperPlot.pde: -------------------------------------------------------------------------------- 1 | String port = "COM6"; // имя порта 2 | 3 | import processing.serial.*; 4 | Serial myPort; 5 | 6 | void setup() { 7 | size(500, 500); 8 | myPort = new Serial(this, port, 115200); 9 | fill(0); 10 | noStroke(); 11 | } 12 | 13 | void draw() { 14 | if (myPort.available() > 0) { 15 | String str = myPort.readStringUntil('\n').trim(); 16 | if (str != null) { 17 | String[] pos = split(str, ','); 18 | if (pos.length < 2) return; 19 | int x = int(pos[0]); 20 | int y = int(pos[1]); 21 | fill(10); 22 | circle(x+10, y+10, 4); 23 | fill(200, 2); 24 | rect(0, 0, width, height); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner2/PlannerCircleISR/PlannerCircleISR.ino: -------------------------------------------------------------------------------- 1 | // тож самое, но тик по таймеру 2 | // пример с записанным в памяти маршрутом окружности 3 | // работу можно посмотреть в плоттере, а лучше в приложенном stepperPlot для Processing 4 | 5 | const int pointAm = 30; // количество точек в круге 6 | int radius = 100; // радиус круга 7 | int32_t path[pointAm + 1 + 1][2]; // буфер круга 8 | // +1 на стартовую точку +1 на замыкание круга 9 | 10 | #include "GyverPlanner2.h" 11 | Stepper stepper1(2, 5); 12 | Stepper stepper2(3, 6); 13 | GPlanner2 planner; 14 | 15 | void setup() { 16 | Serial.begin(115200); 17 | // добавляем шаговики на оси 18 | planner.addStepper(0, stepper1); // ось 0 19 | planner.addStepper(1, stepper2); // ось 1 20 | 21 | // устанавливаем ускорение и скорость 22 | planner.setAcceleration(500); 23 | planner.setMaxSpeed(500); 24 | 25 | // начальная точка системы должна совпадать с первой точкой маршрута 26 | planner.setCurrent(path[0]); 27 | 28 | // заполняем буфер 29 | for (int i = 0; i <= pointAm; i++) { 30 | path[i + 1][0] = radius + radius * cos(TWO_PI * i / pointAm); 31 | path[i + 1][1] = radius + radius * sin(TWO_PI * i / pointAm); 32 | } 33 | // 0 - координата 0,0 34 | // 1 - первая координата круга 35 | // итд 36 | 37 | // заводим всё 38 | planner.start(); 39 | initTimer(); 40 | } 41 | 42 | // прерывание таймера 43 | ISR(TIMER1_COMPA_vect) { 44 | // здесь происходит движение моторов 45 | // если мотор должен двигаться (true) - ставим новый период таймеру 46 | if (planner.tickManual()) setPeriod(planner.getPeriod()); 47 | else stopTimer(); 48 | // если нет - останавливаем таймер 49 | } 50 | 51 | int count = 0; // счётчик точек маршрута 52 | void loop() { 53 | // вручную проверяем буфер. Если начался новый отрезок движения 54 | if (planner.checkBuffer()) { 55 | startTimer(); // запускаем таймер 56 | setPeriod(planner.getPeriod()); // устанавливаем новый период 57 | } 58 | 59 | // если в буфере планировщика есть место 60 | if (planner.available()) { 61 | // добавляем точку маршрута и является ли она точкой остановки (0 - нет) 62 | planner.addTarget(path[count], 0); 63 | if (++count >= sizeof(path) / 8) count = 0; // закольцевать 64 | } 65 | 66 | // асинхронно вывожу в порт графики 67 | static uint32_t tmr; 68 | if (millis() - tmr >= 20) { 69 | tmr = millis(); 70 | Serial.print(stepper1.pos); 71 | Serial.print(','); 72 | Serial.println(stepper2.pos); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner2/PlannerCircleISR/stepperPlot/stepperPlot.pde: -------------------------------------------------------------------------------- 1 | String port = "COM6"; // имя порта 2 | 3 | import processing.serial.*; 4 | Serial myPort; 5 | 6 | void setup() { 7 | size(500, 500); 8 | myPort = new Serial(this, port, 115200); 9 | fill(0); 10 | noStroke(); 11 | } 12 | 13 | void draw() { 14 | if (myPort.available() > 0) { 15 | String str = myPort.readStringUntil('\n').trim(); 16 | if (str != null) { 17 | String[] pos = split(str, ','); 18 | if (pos.length < 2) return; 19 | int x = int(pos[0]); 20 | int y = int(pos[1]); 21 | fill(10); 22 | circle(x+10, y+10, 4); 23 | fill(200, 2); 24 | rect(0, 0, width, height); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Planner2/PlannerCircleISR/timer.ino: -------------------------------------------------------------------------------- 1 | // настроить таймер 2 | void initTimer() { 3 | TCCR1A = 0; 4 | // CTC по OCR1A, делитель /64 5 | TCCR1B = bit(WGM12) | 0b011; 6 | } 7 | 8 | // установить период 9 | void setPeriod(uint32_t prd) { 10 | // один тик таймера - 4 мкс (при 16 МГц клоке) 11 | OCR1A = (uint32_t)prd >> 2; 12 | } 13 | 14 | // запустить и сбросить таймер 15 | void startTimer() { 16 | TIMSK1 = bit(OCIE1A); 17 | TCNT1 = 0; 18 | } 19 | 20 | // остановить таймер 21 | void stopTimer() { 22 | TIMSK1 = 0; 23 | TCNT1 = 0; 24 | } 25 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/accelDeccelButton/accelDeccelButton.ino: -------------------------------------------------------------------------------- 1 | // начинаем плавный разгон при удержании кнопки. При отпускании тормозим 2 | 3 | //#define SMOOTH_ALGORITHM 4 | #include 5 | //GStepper stepper(2048, 5, 3, 4, 2); 6 | GStepper stepper(2048, 2, 5); 7 | 8 | 9 | void setup() { 10 | Serial.begin(115200); 11 | pinMode(A0, INPUT_PULLUP); // кнопка на A0 и GND 12 | stepper.enable(); 13 | stepper.autoPower(true); 14 | 15 | // установка ускорения в шагах/сек/сек 16 | stepper.setAcceleration(1200); 17 | stepper.setRunMode(KEEP_SPEED); 18 | } 19 | 20 | bool btnState = false; 21 | void loop() { 22 | stepper.tick(); 23 | 24 | // кнопка нажата 25 | if (!digitalRead(A0) && !btnState) { 26 | btnState = true; 27 | stepper.setSpeed(3000, SMOOTH); 28 | } 29 | 30 | // кнопка отпущена 31 | if (digitalRead(A0) && btnState) { 32 | btnState = false; 33 | stepper.stop(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/demo/demo.ino: -------------------------------------------------------------------------------- 1 | // демо - основные возможности библиотеки 2 | 3 | #include 4 | GStepper stepper(2048, 5, 3, 4, 2); 5 | 6 | // мотор с драйвером ULN2003 подключается по порядку пинов, но крайние нужно поменять местами 7 | // то есть у меня подключено D2-IN1, D3-IN2, D4-IN3, D5-IN4, но в программе поменял 5 и 2 8 | 9 | // создание объекта 10 | // steps - шагов на один оборот вала (для расчётов с градусами) 11 | // step, dir, pin1, pin2, pin3, pin4 - любые GPIO 12 | // en - пин отключения драйвера, любой GPIO 13 | //GStepper stepper(steps, step, dir); // драйвер step-dir 14 | //GStepper stepper(steps, step, dir, en); // драйвер step-dir + пин enable 15 | //GStepper stepper(steps, pin1, pin2, pin3, pin4); // драйвер 4 пин 16 | //GStepper stepper(steps, pin1, pin2, pin3, pin4, en); // драйвер 4 пин + enable 17 | //GStepper stepper(steps, pin1, pin2, pin3, pin4); // драйвер 4 пин полушаг 18 | //GStepper stepper(steps, pin1, pin2, pin3, pin4, en); // драйвер 4 пин полушаг + enable 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | // режим поддержания скорости 23 | stepper.setRunMode(KEEP_SPEED); 24 | 25 | // можно установить скорость 26 | stepper.setSpeed(120); // в шагах/сек 27 | stepper.setSpeedDeg(80); // в градусах/сек 28 | 29 | // режим следования к целевй позиции 30 | stepper.setRunMode(FOLLOW_POS); 31 | 32 | // можно установить позицию 33 | stepper.setTarget(-2024); // в шагах 34 | stepper.setTargetDeg(-360); // в градусах 35 | 36 | // установка макс. скорости в градусах/сек 37 | stepper.setMaxSpeedDeg(400); 38 | 39 | // установка макс. скорости в шагах/сек 40 | stepper.setMaxSpeed(400); 41 | 42 | // установка ускорения в градусах/сек/сек 43 | stepper.setAccelerationDeg(300); 44 | 45 | // установка ускорения в шагах/сек/сек 46 | stepper.setAcceleration(300); 47 | 48 | // отключать мотор при достижении цели 49 | stepper.autoPower(true); 50 | 51 | // включить мотор (если указан пин en) 52 | stepper.enable(); 53 | } 54 | 55 | void loop() { 56 | // просто крутим туды-сюды 57 | if (!stepper.tick()) { 58 | static bool dir; 59 | dir = !dir; 60 | stepper.setTarget(dir ? -1024 : 1024); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/endSwitch/endSwitch.ino: -------------------------------------------------------------------------------- 1 | // пример с концевиком 2 | #include 3 | //GStepper stepper(2048, 5, 3, 4, 2); 4 | GStepper stepper(2048, 2, 5); 5 | 6 | void setup() { 7 | // наша задача - при запуске крутить мотор в сторону до нажатия на кнопку 8 | pinMode(12, INPUT_PULLUP); // кнопка на D12 и GND 9 | 10 | stepper.setRunMode(KEEP_SPEED); 11 | stepper.setSpeedDeg(-10); // медленно крутимся НАЗАД 12 | 13 | // пока кнопка не нажата 14 | while(digitalRead(12)) { 15 | stepper.tick(); 16 | // yield(); // для esp8266 17 | } 18 | // вот тут кнопка нажата, сразу вырубаем мотор. 19 | // Текущее положение также сбрасывается в 0 20 | stepper.reset(); 21 | 22 | // дальше например врубаем FOLLOW_POS 23 | stepper.setRunMode(FOLLOW_POS); 24 | } 25 | 26 | void loop() { 27 | // и качаемся в 20 шагах от кнопки и до 300 28 | static bool dir; 29 | if (!stepper.tick()) { 30 | dir = !dir; 31 | stepper.setTarget(dir ? 20 : 300); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/externalDriver/externalDriver.ino: -------------------------------------------------------------------------------- 1 | // пример с использованием "внешнего" драйвера, который может быть 2 | // подключен к расширителю портов. 3 | 4 | // в качестве примера использую digitalWrite и родные пины 5 | #define PIN_A 2 6 | #define PIN_B 4 7 | #define PIN_C 3 8 | #define PIN_D 5 9 | 10 | #include 11 | GStepper stepper(2048); 12 | 13 | void setup() { 14 | Serial.begin(9600); 15 | // выходы 16 | pinMode(PIN_A, 1); 17 | pinMode(PIN_B, 1); 18 | pinMode(PIN_C, 1); 19 | pinMode(PIN_D, 1); 20 | 21 | stepper.setRunMode(KEEP_SPEED); // режим поддержания скорости 22 | stepper.setSpeedDeg(100); // в градусах/сек 23 | stepper.setAcceleration(500); 24 | 25 | // подключить свою функцию-обработчик шага 26 | stepper.attachStep(step); 27 | 28 | // подключить свою функцию-обработчик для управления питанием 29 | stepper.attachPower(pwr); 30 | 31 | stepper.autoPower(1); // включаем авто выкл питания 32 | } 33 | 34 | // наша функция-обработчик. Будет вызываться на каждом шагу 35 | // у STEPPER4WIRE val содержит состояния обмоток как 0bABCD 36 | // у STEPPER2WIRE val содержит 0 или 1 как DIR, STEP нужно дёрнуть самому 37 | void step(byte val) { 38 | // дёргаем вручную пины 39 | digitalWrite(PIN_D, val & 1); 40 | val >>= 1; 41 | digitalWrite(PIN_C, val & 1); 42 | val >>= 1; 43 | digitalWrite(PIN_B, val & 1); 44 | val >>= 1; 45 | digitalWrite(PIN_A, val & 1); 46 | } 47 | 48 | void pwr(bool val) { 49 | // тут val будет 0 или 1 в зависимости от питания. Подавай на EN 50 | Serial.println(val); 51 | } 52 | 53 | void loop() { 54 | stepper.tick(); 55 | 56 | // разгон и остановка каждые 3 секунды 57 | static uint32_t tmr; 58 | if (millis() - tmr >= 3000) { 59 | tmr = millis(); 60 | static bool dir = 1; 61 | dir = !dir; 62 | if (!dir) stepper.stop(); 63 | else stepper.setSpeedDeg(100); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/multiStepper/multiStepper.ino: -------------------------------------------------------------------------------- 1 | // крутим мотор туда-сюда плавно с ускорением 2 | 3 | #include "GyverStepper.h" 4 | // подключим три мотора 5 | // у первого и второго управление EN не подключаем 6 | GStepper stepper1(100, 2, 3); 7 | GStepper stepper2(100, 4, 5); 8 | GStepper stepper3(100, 6, 7, 8); 9 | 10 | void setup() { 11 | // мотор 1 просто вращается 12 | stepper1.setRunMode(KEEP_SPEED); 13 | stepper1.setSpeed(300); 14 | 15 | // мотор 2 будет делать sweep по проверке tick 16 | stepper2.setRunMode(FOLLOW_POS); 17 | stepper2.setMaxSpeed(1000); 18 | stepper2.setAcceleration(300); 19 | 20 | // мотор 3 будет перемещаться на случайную позицию 21 | stepper3.setRunMode(FOLLOW_POS); 22 | stepper3.setMaxSpeed(1000); 23 | stepper3.setAcceleration(300); 24 | stepper3.autoPower(true); 25 | stepper3.enable(); 26 | } 27 | 28 | void loop() { 29 | // первый мотор 30 | stepper1.tick(); 31 | 32 | // второй крутим туды-сюды (-1000, 1000) 33 | if (!stepper2.tick()) { 34 | static bool dir; 35 | dir = !dir; 36 | stepper2.setTarget(dir ? -1000 : 1000); 37 | } 38 | 39 | // третий по таймеру 40 | // будет отключаться при остановке 41 | stepper3.tick(); 42 | static uint32_t tmr; 43 | if (millis() - tmr > 5000) { // каждые 5 секунд 44 | tmr = millis(); 45 | stepper3.setTarget(random(0, 2000)); // рандом 0-2000 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/potPos/potPos.ino: -------------------------------------------------------------------------------- 1 | // установка позиции потенциометром 2 | 3 | #include 4 | //GStepper stepper(2048, 5, 3, 4, 2); 5 | GStepper stepper(2048, 2, 5); 6 | 7 | void setup() { 8 | Serial.begin(115200); 9 | stepper.setRunMode(FOLLOW_POS); // режим следования к целевй позиции 10 | stepper.setMaxSpeed(400); // установка макс. скорости в шагах/сек 11 | stepper.setAcceleration(500); // установка ускорения в шагах/сек/сек 12 | 13 | // пусть драйвер выключается при достижении позиции 14 | stepper.autoPower(true); 15 | } 16 | 17 | void loop() { 18 | stepper.tick(); 19 | 20 | // сделаем таймер на 20 мс 21 | // будем опрашивать потенциометр и строить графики 22 | static uint32_t tmr2; 23 | if (millis() - tmr2 > 20) { 24 | tmr2 = millis(); 25 | static float val; 26 | // потенциометр на A0 27 | // фильтруем, иначе мотор будет трястись 28 | val += (analogRead(0) - val) * 0.08; 29 | 30 | stepper.setTarget(val); // ставим новую позицию 31 | Serial.print(stepper.getTarget()); 32 | Serial.print(','); 33 | Serial.println(stepper.getCurrent()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/potSpeed/potSpeed.ino: -------------------------------------------------------------------------------- 1 | // установка скорости потенциометром 2 | 3 | #include 4 | //GStepper stepper(2048, 5, 3, 4, 2); 5 | GStepper stepper(2048, 2, 5); 6 | 7 | void setup() { 8 | stepper.setRunMode(KEEP_SPEED); // режим поддержания скорости 9 | stepper.setSpeedDeg(50); // в градусах/сек 10 | } 11 | 12 | void loop() { 13 | stepper.tick(); 14 | 15 | // сделаем таймер на 50 мс и будем опрашивать потенциометр 16 | // менять скорость чаще нет смысла 17 | static uint32_t tmr2; 18 | if (millis() - tmr2 > 50) { 19 | tmr2 = millis(); 20 | 21 | // ставим новую скорость (-512.. 512 шагов в секунду) 22 | // будет крутиться в разные стороны 23 | stepper.setSpeed(512 - analogRead(0)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/smoothAlgorithm/smoothAlgorithm.ino: -------------------------------------------------------------------------------- 1 | // используем более плавный алгоритм движения. Макс. скорость ограничена до 2 | // 7000 шаг/сек, алгоритм использует много процессорного времени! 3 | 4 | // перед подключением библиотеки дефайним 5 | #define SMOOTH_ALGORITHM 6 | 7 | #include 8 | //GStepper stepper(2048, 5, 3, 4, 2); 9 | GStepper stepper(2048, 2, 5); 10 | 11 | void setup() { 12 | Serial.begin(115200); 13 | 14 | // режим следования к целевй позиции 15 | stepper.setRunMode(FOLLOW_POS); 16 | 17 | // установка макс. скорости в шагах/сек 18 | stepper.setMaxSpeed(400); 19 | 20 | // установка ускорения в шагах/сек/сек 21 | stepper.setAcceleration(500); 22 | } 23 | 24 | void loop() { 25 | // просто крутим туды-сюды 26 | if (!stepper.tick()) { 27 | static bool dir; 28 | dir = !dir; 29 | stepper.setTarget(dir ? -400 : 400); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/speed/speed.ino: -------------------------------------------------------------------------------- 1 | // крутимся с заданной скоростью 2 | 3 | #include 4 | //GStepper stepper(2048, 5, 3, 4, 2); 5 | GStepper stepper(2048, 2, 5); 6 | 7 | void setup() { 8 | stepper.setRunMode(KEEP_SPEED); // режим поддержания скорости 9 | stepper.setSpeedDeg(50); // в градусах/сек 10 | } 11 | 12 | void loop() { 13 | stepper.tick(); 14 | } 15 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/speedSerialControl/speedSerialControl.ino: -------------------------------------------------------------------------------- 1 | // управляем скоростью из СОМ порта 2 | // отправь q для тормоза 3 | // отправь w для плавной остановки 4 | // отправь e для скорости 5 град/сек 5 | // отправь r для скорости 100 град/сек 6 | 7 | #include 8 | //GStepper stepper(2048, 5, 3, 4, 2); 9 | GStepper stepper(2048, 2, 5); 10 | 11 | void setup() { 12 | Serial.begin(9600); 13 | stepper.setRunMode(KEEP_SPEED); // режим поддержания скорости 14 | stepper.setSpeedDeg(5); // в градусах/сек 15 | } 16 | 17 | void loop() { 18 | stepper.tick(); 19 | if (Serial.available()) { 20 | char ch = Serial.read(); 21 | if (ch == 'q') stepper.brake(); 22 | if (ch == 'w') stepper.stop(); 23 | if (ch == 'e') stepper.setSpeedDeg(5); 24 | if (ch == 'r') stepper.setSpeedDeg(100); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/stop/stop.ino: -------------------------------------------------------------------------------- 1 | // пример работы stop() 2 | // на графике будет видно, как сместилась установка и мотор к ней затормозил 3 | #include 4 | //GStepper stepper(2048, 5, 3, 4, 2); 5 | GStepper stepper(2048, 2, 5); 6 | 7 | void setup() { 8 | Serial.begin(115200); 9 | stepper.setMaxSpeed(400); 10 | stepper.setAcceleration(300); 11 | stepper.setRunMode(FOLLOW_POS); 12 | 13 | // отправляем мотор подальше 14 | stepper.setTarget(-2024); 15 | } 16 | 17 | void loop() { 18 | stepper.tick(); 19 | 20 | // плавная остановка через 3 секунды 21 | static uint32_t tmr; 22 | static bool flag = false; 23 | if (!flag && millis() > 3000) { 24 | stepper.stop(); 25 | flag = true; 26 | } 27 | 28 | // график установки и текущей позиции 29 | static uint32_t tmr2; 30 | if (millis() - tmr2 > 20) { 31 | tmr2 = millis(); 32 | Serial.print(stepper.getTarget()); 33 | Serial.print(','); 34 | Serial.println(stepper.getCurrent()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/sweep/sweep.ino: -------------------------------------------------------------------------------- 1 | // крутим мотор туда-сюда плавно с ускорением 2 | 3 | #include 4 | //GStepper stepper(2048, 5, 3, 4, 2); 5 | GStepper stepper(2048, 2, 5); 6 | 7 | void setup() { 8 | Serial.begin(115200); 9 | 10 | // режим следования к целевй позиции 11 | stepper.setRunMode(FOLLOW_POS); 12 | 13 | // установка макс. скорости в шагах/сек 14 | stepper.setMaxSpeed(400); 15 | 16 | // установка ускорения в шагах/сек/сек 17 | stepper.setAcceleration(500); 18 | } 19 | 20 | void loop() { 21 | // просто крутим туды-сюды 22 | if (!stepper.tick()) { 23 | static bool dir; 24 | dir = !dir; 25 | stepper.setTarget(dir ? -400 : 400); 26 | } 27 | 28 | // график положения 29 | static uint32_t tmr2; 30 | if (millis() - tmr2 > 20) { 31 | tmr2 = millis(); 32 | Serial.println(stepper.getCurrent()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper/timerISR/timerISR.ino: -------------------------------------------------------------------------------- 1 | // пример с тиком по прерыванию таймера 2 | // используется GyverTimers 3 | 4 | #include 5 | //GStepper stepper(2048, 5, 3, 4, 2); 6 | GStepper stepper(2048, 2, 5); 7 | 8 | #include 9 | 10 | void setup() { 11 | Serial.begin(115200); 12 | 13 | // режим следования к целевй позиции 14 | stepper.setRunMode(FOLLOW_POS); 15 | 16 | // установка макс. скорости в шагах/сек 17 | stepper.setMaxSpeed(400); 18 | 19 | // установка ускорения в шагах/сек/сек 20 | stepper.setAcceleration(500); 21 | 22 | // настраиваем прерывания с периодом, при котором 23 | // система сможет обеспечить максимальную скорость мотора. 24 | // Для большей плавности лучше лучше взять период чуть меньше, например в два раза 25 | Timer2.setPeriod(stepper.getMinPeriod() / 2); 26 | 27 | // взводим прерывание 28 | Timer2.enableISR(); 29 | } 30 | 31 | // обработчик 32 | ISR(TIMER2_A) { 33 | stepper.tick(); // тикаем тут 34 | } 35 | 36 | void loop() { 37 | // просто крутим туды-сюды 38 | if (!stepper.tick()) { // тут всё равно вызываем для смены направления 39 | static bool dir; 40 | dir = !dir; 41 | stepper.setTarget(dir ? -400 : 400); 42 | } 43 | 44 | // график положения 45 | Serial.println(stepper.getCurrent()); 46 | 47 | // задержка, чтобы показать работу степпера в прерывании 48 | delay(100); 49 | } 50 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper2/SpeedControl/SpeedControl.ino: -------------------------------------------------------------------------------- 1 | // крутим мотор. Отправляй в сериал целое число, шаг/сек 2 | 3 | #include "GyverStepper2.h" 4 | //GStepper2 stepper(2048, 5, 3, 4, 2); 5 | GStepper2 stepper(2048, 2, 5); 6 | 7 | void setup() { 8 | Serial.begin(9600); 9 | Serial.setTimeout(10); 10 | } 11 | 12 | void loop() { 13 | // здесь происходит движение моторов, вызывать как можно чаще 14 | stepper.tick(); 15 | 16 | // управляем скоростью 17 | if (Serial.available() > 0) { 18 | int val = Serial.parseInt(); 19 | stepper.setSpeed(val); 20 | } 21 | 22 | static uint32_t tmr; 23 | if (millis() - tmr >= 30) { 24 | tmr = millis(); 25 | Serial.println(stepper.pos); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper2/StepperControl/StepperControl.ino: -------------------------------------------------------------------------------- 1 | // здесь у нас моторы движутся по трём точкам траектории 2 | // можно открыть плоттер, наблюать за этим и отправлять команды: 3 | // s - стоп 4 | // b - тормоз 5 | // p - пауза 6 | // r - продолжить 7 | //#define GS_NO_ACCEL 8 | #include "GyverStepper2.h" 9 | //GStepper2 stepper(2048, 5, 3, 4, 2); 10 | GStepper2 stepper(2048, 2, 5); 11 | 12 | void setup() { 13 | Serial.begin(9600); 14 | 15 | // устанавливаем ускорение и скорость 16 | stepper.setAcceleration(200); 17 | stepper.setMaxSpeed(100); 18 | stepper.setTarget(0); 19 | //stepper.setSpeed(100); 20 | } 21 | 22 | byte count = 0; 23 | int16_t path[] = {0, 200, 100}; 24 | 25 | void loop() { 26 | // здесь происходит движение мотора, вызывать как можно чаще 27 | stepper.tick(); 28 | 29 | // вернёт true, если все моторы доехали 30 | if (stepper.ready()) { 31 | stepper.setTarget(path[count]); // загружаем новую точку (начнётся с 0) 32 | if (++count >= sizeof(path) / 2) count = 0; 33 | } 34 | 35 | // управляем процессом 36 | if (Serial.available() > 0) { 37 | char incoming = Serial.read(); 38 | switch (incoming) { 39 | case 's': stepper.stop(); break; 40 | case 'b': stepper.brake(); break; 41 | case 'r': stepper.resume(); break; 42 | case 'p': stepper.pause(); break; 43 | } 44 | } 45 | 46 | // асинхронно вывожу в порт графики 47 | static uint32_t tmr; 48 | if (millis() - tmr >= 20) { 49 | tmr = millis(); 50 | Serial.print(stepper.getTarget()); 51 | Serial.print(','); 52 | Serial.println(stepper.pos); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper2/homing/homing.ino: -------------------------------------------------------------------------------- 1 | // пример калибровки нуля по концевикам 2 | // концевик на D6 3 | #define LIMSW_X 6 4 | 5 | #include "GyverStepper2.h" 6 | //GStepper2 stepper(2048, 5, 3, 4, 2); 7 | GStepper2 stepper(2048, 2, 5); 8 | 9 | void setup() { 10 | // пуллапим. Кнопки замыкают на GND 11 | pinMode(LIMSW_X, INPUT_PULLUP); 12 | } 13 | 14 | void loop() { 15 | } 16 | 17 | void homing() { 18 | if (digitalRead(LIMSW_X)) { // если концевик X не нажат 19 | stepper.setSpeed(-10); // ось Х, -10 шаг/сек 20 | while (digitalRead(LIMSW_X)) { // пока кнопка не нажата 21 | stepper.tick(); // крутим 22 | } 23 | // кнопка нажалась - покидаем цикл 24 | stepper.brake(); // тормозим, приехали 25 | } 26 | stepper.reset(); // сбрасываем координаты в 0 27 | } 28 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper2/sweep/sweep.ino: -------------------------------------------------------------------------------- 1 | // крутим туда сюда, тикаем в loop 2 | 3 | #include "GyverStepper2.h" 4 | //GStepper2 stepper(2048, 5, 3, 4, 2); 5 | GStepper2 stepper(2048, 2, 5); 6 | 7 | void setup() { 8 | Serial.begin(9600); 9 | //stepper.enable(); 10 | stepper.setMaxSpeed(100); // скорость движения к цели 11 | stepper.setAcceleration(200); // ускорение 12 | stepper.setTarget(300); // цель 13 | } 14 | 15 | bool dir = 1; 16 | void loop() { 17 | stepper.tick(); // мотор асинхронно крутится тут 18 | 19 | // если приехали 20 | if (stepper.ready()) { 21 | dir = !dir; // разворачиваем 22 | stepper.setTarget(dir * 300); // едем в другую сторону 23 | } 24 | 25 | // асинхронный вывод в порт 26 | static uint32_t tmr; 27 | if (millis() - tmr >= 30) { 28 | tmr = millis(); 29 | Serial.println(stepper.pos); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper2/sweepISR/sweepISR.ino: -------------------------------------------------------------------------------- 1 | // крутим туда сюда, прерывание таймера 2 | 3 | #include "GyverStepper2.h" 4 | //GStepper2 stepper(2048, 5, 3, 4, 2); 5 | GStepper2 stepper(2048, 2, 5); 6 | 7 | void setup() { 8 | Serial.begin(9600); 9 | initTimer(); 10 | //stepper.enable(); 11 | stepper.setMaxSpeed(100); // скорость движения к цели 12 | stepper.setAcceleration(200); // ускорение 13 | stepper.setTarget(300); // цель 14 | setPeriod(stepper.getPeriod()); 15 | startTimer(); 16 | } 17 | 18 | // прерывание таймера 19 | ISR(TIMER1_COMPA_vect) { 20 | // здесь происходит движение мотора 21 | // если мотор должен двигаться (true) - ставим новый период таймеру 22 | if (stepper.tickManual()) setPeriod(stepper.getPeriod()); 23 | else stopTimer(); 24 | // если нет - останавливаем таймер 25 | } 26 | 27 | bool dir = 1; 28 | void loop() { 29 | // если приехали 30 | if (stepper.ready()) { 31 | dir = !dir; // разворачиваем 32 | stepper.setTarget(dir * 300); // едем в другую сторону 33 | setPeriod(stepper.getPeriod()); 34 | startTimer(); 35 | } 36 | 37 | // асинхронный вывод в порт 38 | static uint32_t tmr; 39 | if (millis() - tmr >= 30) { 40 | tmr = millis(); 41 | Serial.println(stepper.pos); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper2/sweepISR/timer.ino: -------------------------------------------------------------------------------- 1 | // настроить таймер 2 | void initTimer() { 3 | TCCR1A = 0; 4 | // CTC по OCR1A, делитель /64 5 | TCCR1B = bit(WGM12) | 0b011; 6 | } 7 | 8 | // установить период 9 | void setPeriod(uint32_t prd) { 10 | // один тик таймера - 4 мкс (при 16 МГц клоке) 11 | OCR1A = (uint32_t)prd >> 2; 12 | } 13 | 14 | // запустить и сбросить таймер 15 | void startTimer() { 16 | TIMSK1 = bit(OCIE1A); 17 | TCNT1 = 0; 18 | } 19 | 20 | // остановить таймер 21 | void stopTimer() { 22 | TIMSK1 = 0; 23 | TCNT1 = 0; 24 | } 25 | -------------------------------------------------------------------------------- /libraries/GyverStepper/examples/Stepper2/sweep_FAST_PROFILE/sweep_FAST_PROFILE.ino: -------------------------------------------------------------------------------- 1 | // крутим туда сюда, тикаем в loop 2 | 3 | // включаем быстрый профиль, 10 участков 4 | #define GS_FAST_PROFILE 10 5 | #include "GyverStepper2.h" 6 | //GStepper2 stepper(2048, 5, 3, 4, 2); 7 | GStepper2 stepper(2048, 2, 5); 8 | 9 | uint32_t tar = 60000; 10 | bool dir = 1; 11 | 12 | void setup() { 13 | Serial.begin(9600); 14 | 15 | //stepper.enable(); 16 | stepper.setMaxSpeed(30000); // скорость движения к цели 17 | stepper.setAcceleration(30000); // ускорение 18 | 19 | stepper.setTarget(tar); // цель 20 | } 21 | 22 | void loop() { 23 | while (1) { 24 | stepper.tick(); // мотор асинхронно крутится тут 25 | 26 | // если приехали 27 | if (stepper.ready()) { 28 | dir = !dir; // разворачиваем 29 | stepper.setTarget(dir * tar); // едем в другую сторону 30 | } 31 | 32 | // асинхронный вывод в порт 33 | static uint32_t tmr; 34 | if (millis() - tmr >= 30) { 35 | tmr = millis(); 36 | Serial.println(stepper.pos); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /libraries/GyverStepper/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For GyverStepper 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | GyverStepper KEYWORD1 9 | GyverStepper2 KEYWORD1 10 | GyverPlanner KEYWORD1 11 | GyverPlanner2 KEYWORD1 12 | StepperCore KEYWORD1 13 | 14 | GStepper KEYWORD1 15 | GStepper2 KEYWORD1 16 | GPlanner KEYWORD1 17 | GPlanner2 KEYWORD1 18 | Stepper KEYWORD1 19 | 20 | GS_NO_ACCEL KEYWORD1 21 | GS_FAST_PROFILE KEYWORD1 22 | 23 | ####################################### 24 | # Methods and Functions (KEYWORD2) 25 | ####################################### 26 | tick KEYWORD2 27 | reverse KEYWORD2 28 | invertEn KEYWORD2 29 | setCurrent KEYWORD2 30 | setCurrentDeg KEYWORD2 31 | getCurrent KEYWORD2 32 | getCurrentDeg KEYWORD2 33 | setTarget KEYWORD2 34 | setTargetDeg KEYWORD2 35 | getTarget KEYWORD2 36 | getTargetDeg KEYWORD2 37 | setMaxSpeed KEYWORD2 38 | setMaxSpeedDeg KEYWORD2 39 | setAcceleration KEYWORD2 40 | setAccelerationDeg KEYWORD2 41 | autoPower KEYWORD2 42 | stop KEYWORD2 43 | brake KEYWORD2 44 | reset KEYWORD2 45 | setSpeed KEYWORD2 46 | setSpeedDeg KEYWORD2 47 | getSpeed KEYWORD2 48 | getSpeedDeg KEYWORD2 49 | setRunMode KEYWORD2 50 | enable KEYWORD2 51 | disable KEYWORD2 52 | power KEYWORD2 53 | getState KEYWORD2 54 | home KEYWORD2 55 | getMinPeriod KEYWORD2 56 | stepTime KEYWORD2 57 | degPerMinute KEYWORD2 58 | degPerHour KEYWORD2 59 | attachStep KEYWORD2 60 | attachPower KEYWORD2 61 | setBacklash KEYWORD2 62 | step KEYWORD2 63 | 64 | addStepper KEYWORD2 65 | ready KEYWORD2 66 | pause KEYWORD2 67 | resume KEYWORD2 68 | tickManual KEYWORD2 69 | getPeriod KEYWORD2 70 | getStatus KEYWORD2 71 | 72 | clearBuffer KEYWORD2 73 | checkBuffer KEYWORD2 74 | addTarget KEYWORD2 75 | available KEYWORD2 76 | setDtA KEYWORD2 77 | start KEYWORD2 78 | 79 | ####################################### 80 | # Constants (LITERAL1) 81 | ####################################### 82 | SMOOTH LITERAL1 83 | NO_SMOOTH LITERAL1 84 | ABSOLUTE LITERAL1 85 | RELATIVE LITERAL1 86 | FOLLOW_POS LITERAL1 87 | KEEP_SPEED LITERAL1 88 | STEPPER2WIRE LITERAL1 89 | STEPPER4WIRE LITERAL1 90 | STEPPER4WIRE_HALF LITERAL1 91 | SMOOTH_ALGORITHM LITERAL1 92 | DRIVER_STEP_TIME LITERAL1 93 | STEPPER_PINS LITERAL1 94 | STEPPER_VIRTUAL LITERAL1 -------------------------------------------------------------------------------- /libraries/GyverStepper/library.properties: -------------------------------------------------------------------------------- 1 | name=GyverStepper 2 | version=2.7 3 | author=AlexGyver 4 | maintainer=AlexGyver 5 | sentence=Fast library for stepmotor control and multi-axis planning 6 | paragraph=Fast library for stepmotor control and multi-axis planning 7 | category=Device Control 8 | url=https://github.com/GyverLibs/GyverStepper 9 | architectures=* -------------------------------------------------------------------------------- /libraries/GyverStepper/src/FIFO.h: -------------------------------------------------------------------------------- 1 | // FIFO буфер для планировщика 2 2 | 3 | #ifndef _FIFO_h 4 | #define _FIFO_h 5 | #define FIFO_WIPE 1 6 | 7 | template 8 | class FIFO { 9 | public: 10 | FIFO() { 11 | for (uint16_t i = 0; i < SIZE; i++) buf[i] = 0; 12 | } 13 | // очистить 14 | void clear() { 15 | head = tail = 0; 16 | } 17 | 18 | // элементов в буфере 19 | uint16_t available() { 20 | return (SIZE + head - tail) % SIZE; 21 | } 22 | 23 | // прочитать элемент под номером от начала 24 | T get(int16_t i = 0) { 25 | return buf[(SIZE + tail + i) % SIZE]; 26 | } 27 | 28 | // прочитать крайний элемент буфера 29 | T getLast() { 30 | return buf[(SIZE + head - 1) % SIZE]; 31 | } 32 | 33 | // добавить элемент с конца 34 | void add(T data) { 35 | uint16_t i = (head + 1) % SIZE; 36 | if (i != tail) { 37 | buf[head] = data; 38 | head = i; 39 | } 40 | } 41 | 42 | // установить значение элемента под номером от начала 43 | void set(int16_t i, T data) { 44 | buf[(SIZE + tail + i) % SIZE] = data; 45 | } 46 | 47 | // сдвинуть начало на 1 48 | void next(bool wipe = 0) { 49 | if (wipe) buf[tail] = 0; 50 | tail = (tail + 1) % SIZE; 51 | } 52 | 53 | // доступность для записи (свободное место) 54 | bool availableForWrite() { 55 | return ((head + 1) % SIZE != tail); 56 | } 57 | 58 | private: 59 | T buf[SIZE]; 60 | uint16_t head = 0, tail = 0; 61 | }; 62 | 63 | #endif -------------------------------------------------------------------------------- /libraries/GyverStepper/src/GStypes.h: -------------------------------------------------------------------------------- 1 | #ifndef _GStypes_h 2 | #define _GStypes_h 3 | enum GS_driverType { 4 | STEPPER2WIRE, 5 | STEPPER4WIRE, 6 | STEPPER4WIRE_HALF, 7 | STEPPER_PINS, 8 | STEPPER_VIRTUAL, 9 | }; 10 | 11 | 12 | enum GS_posType { 13 | ABSOLUTE, 14 | RELATIVE, 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Google 3 | AccessModifierOffset: '-2' 4 | AlignAfterOpenBracket: DontAlign 5 | AlignConsecutiveAssignments: 'true' 6 | AlignConsecutiveDeclarations: 'false' 7 | AlignEscapedNewlines: Left 8 | AlignTrailingComments: 'true' 9 | AllowAllParametersOfDeclarationOnNextLine: 'false' 10 | AllowShortBlocksOnASingleLine: 'false' 11 | AllowShortCaseLabelsOnASingleLine: 'false' 12 | AllowShortFunctionsOnASingleLine: InlineOnly 13 | AllowShortIfStatementsOnASingleLine: 'true' 14 | AllowShortLoopsOnASingleLine: 'true' 15 | AlwaysBreakAfterDefinitionReturnType: None 16 | AlwaysBreakAfterReturnType: None 17 | AlwaysBreakBeforeMultilineStrings: 'true' 18 | AlwaysBreakTemplateDeclarations: 'false' 19 | BinPackParameters: 'true' 20 | BreakAfterJavaFieldAnnotations: 'false' 21 | BreakBeforeBinaryOperators: None 22 | BreakBeforeBraces: Attach 23 | BreakBeforeInheritanceComma: 'false' 24 | BreakBeforeTernaryOperators: 'false' 25 | BreakConstructorInitializers: BeforeColon 26 | BreakStringLiterals: 'false' 27 | ColumnLimit: '0' 28 | CompactNamespaces: 'true' 29 | ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' 30 | ConstructorInitializerIndentWidth: '4' 31 | ContinuationIndentWidth: '4' 32 | Cpp11BracedListStyle: 'false' 33 | DerivePointerAlignment: 'false' 34 | FixNamespaceComments: 'true' 35 | IndentCaseLabels: 'true' 36 | IndentWidth: '4' 37 | IndentWrappedFunctionNames: 'false' 38 | JavaScriptQuotes: Single 39 | JavaScriptWrapImports: 'false' 40 | KeepEmptyLinesAtTheStartOfBlocks: 'false' 41 | MaxEmptyLinesToKeep: '1' 42 | NamespaceIndentation: All 43 | ObjCBlockIndentWidth: '4' 44 | ObjCSpaceAfterProperty: 'false' 45 | ObjCSpaceBeforeProtocolList: 'false' 46 | PointerAlignment: Middle 47 | SortIncludes: 'false' 48 | SortUsingDeclarations: 'true' 49 | SpaceAfterCStyleCast: 'false' 50 | SpaceAfterTemplateKeyword: 'false' 51 | SpaceBeforeAssignmentOperators: 'true' 52 | SpaceBeforeParens: Never 53 | SpaceInEmptyParentheses: 'false' 54 | SpacesBeforeTrailingComments: '4' 55 | SpacesInAngles: 'false' 56 | SpacesInCStyleCastParentheses: 'false' 57 | SpacesInContainerLiterals: 'false' 58 | SpacesInParentheses: 'false' 59 | SpacesInSquareBrackets: 'false' 60 | TabWidth: '4' 61 | UseTab: Never 62 | 63 | ... 64 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | /tests/webSocketServer/node_modules 30 | 31 | # IDE 32 | .vscode 33 | .cproject 34 | .project 35 | .settings 36 | *.swp 37 | 38 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | dist: 3 | - xenial 4 | addons: 5 | apt: 6 | packages: 7 | - xvfb 8 | language: bash 9 | os: 10 | - linux 11 | env: 12 | matrix: 13 | - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.13 14 | - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.13 15 | - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.13 16 | - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 17 | - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.9 18 | - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.13 19 | script: 20 | - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 21 | - export DISPLAY=:1.0 22 | - sleep 3 23 | - wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz 24 | - tar xf arduino-$IDE_VERSION-linux64.tar.xz 25 | - mv arduino-$IDE_VERSION $HOME/arduino_ide 26 | - export PATH="$HOME/arduino_ide:$PATH" 27 | - which arduino 28 | - mkdir -p $HOME/Arduino/libraries 29 | 30 | - wget https://github.com/bblanchon/ArduinoJson/archive/6.x.zip 31 | - unzip 6.x.zip 32 | - mv ArduinoJson-6.x $HOME/Arduino/libraries/ArduinoJson 33 | - cp -r $TRAVIS_BUILD_DIR $HOME/Arduino/libraries/arduinoWebSockets 34 | - source $TRAVIS_BUILD_DIR/travis/common.sh 35 | - get_core $CPU 36 | - cd $TRAVIS_BUILD_DIR 37 | - arduino --board $BOARD --save-prefs 38 | - arduino --get-pref sketchbook.path 39 | - arduino --pref update.check=false 40 | - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets/examples/$CPU $CPU 41 | 42 | notifications: 43 | email: 44 | on_success: change 45 | on_failure: change 46 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/README.md: -------------------------------------------------------------------------------- 1 | WebSocket Server and Client for Arduino [![Build Status](https://github.com/Links2004/arduinoWebSockets/workflows/CI/badge.svg?branch=master)](https://github.com/Links2004/arduinoWebSockets/actions?query=workflow%3ACI+branch%3Amaster) 2 | =========================================== 3 | 4 | a WebSocket Server and Client for Arduino based on RFC6455. 5 | 6 | 7 | ##### Supported features of RFC6455 ##### 8 | - text frame 9 | - binary frame 10 | - connection close 11 | - ping 12 | - pong 13 | - continuation frame 14 | 15 | ##### Limitations ##### 16 | - max input length is limited to the ram size and the ```WEBSOCKETS_MAX_DATA_SIZE``` define 17 | - max output length has no limit (the hardware is the limit) 18 | - Client send big frames with mask 0x00000000 (on AVR all frames) 19 | - continuation frame reassembly need to be handled in the application code 20 | 21 | ##### Limitations for Async ##### 22 | - Functions called from within the context of the websocket event might not honor `yield()` and/or `delay()`. See [this issue](https://github.com/Links2004/arduinoWebSockets/issues/58#issuecomment-192376395) for more info and a potential workaround. 23 | - wss / SSL is not possible. 24 | 25 | ##### Supported Hardware ##### 26 | - ESP8266 [Arduino for ESP8266](https://github.com/esp8266/Arduino/) 27 | - ESP32 [Arduino for ESP32](https://github.com/espressif/arduino-esp32) 28 | - ESP31B 29 | - Particle with STM32 ARM Cortex M3 30 | - ATmega328 with Ethernet Shield (ATmega branch) 31 | - ATmega328 with enc28j60 (ATmega branch) 32 | - ATmega2560 with Ethernet Shield (ATmega branch) 33 | - ATmega2560 with enc28j60 (ATmega branch) 34 | 35 | ###### Note: ###### 36 | 37 | version 2.0.0 and up is not compatible with AVR/ATmega, check ATmega branch. 38 | 39 | version 2.3.0 has API changes for the ESP8266 BareSSL (may brakes existing code) 40 | 41 | Arduino for AVR not supports std namespace of c++. 42 | 43 | ### wss / SSL ### 44 | supported for: 45 | - wss client on the ESP8266 46 | - wss / SSL is not natively supported in WebSocketsServer however it is possible to achieve secure websockets 47 | by running the device behind an SSL proxy. See [Nginx](examples/Nginx/esp8266.ssl.reverse.proxy.conf) for a 48 | sample Nginx server configuration file to enable this. 49 | 50 | ### ESP Async TCP ### 51 | 52 | This libary can run in Async TCP mode on the ESP. 53 | 54 | The mode can be activated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). 55 | 56 | [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. 57 | 58 | 59 | ### High Level Client API ### 60 | 61 | - `begin` : Initiate connection sequence to the websocket host. 62 | ```c++ 63 | void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); 64 | void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); 65 | ``` 66 | - `onEvent`: Callback to handle for websocket events 67 | 68 | ```c++ 69 | void onEvent(WebSocketClientEvent cbEvent); 70 | ``` 71 | 72 | - `WebSocketClientEvent`: Handler for websocket events 73 | ```c++ 74 | void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length) 75 | ``` 76 | Where `WStype_t type` is defined as: 77 | ```c++ 78 | typedef enum { 79 | WStype_ERROR, 80 | WStype_DISCONNECTED, 81 | WStype_CONNECTED, 82 | WStype_TEXT, 83 | WStype_BIN, 84 | WStype_FRAGMENT_TEXT_START, 85 | WStype_FRAGMENT_BIN_START, 86 | WStype_FRAGMENT, 87 | WStype_FRAGMENT_FIN, 88 | WStype_PING, 89 | WStype_PONG, 90 | } WStype_t; 91 | ``` 92 | 93 | ### Issues ### 94 | Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues 95 | 96 | [![Join the chat at https://gitter.im/Links2004/arduinoWebSockets](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Links2004/arduinoWebSockets?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 97 | 98 | ### License and credits ### 99 | 100 | The library is licensed under [LGPLv2.1](https://github.com/Links2004/arduinoWebSockets/blob/master/LICENSE) 101 | 102 | [libb64](http://libb64.sourceforge.net/) written by Chris Venter. It is distributed under Public Domain see [LICENSE](https://github.com/Links2004/arduinoWebSockets/blob/master/src/libb64/LICENSE). 103 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/Nginx/esp8266.ssl.reverse.proxy.conf: -------------------------------------------------------------------------------- 1 | # ESP8266 nginx SSL reverse proxy configuration file (tested and working on nginx v1.10.0) 2 | 3 | # proxy cache location 4 | proxy_cache_path /opt/etc/nginx/cache levels=1:2 keys_zone=ESP8266_cache:10m max_size=10g inactive=5m use_temp_path=off; 5 | 6 | # webserver proxy 7 | server { 8 | 9 | # general server parameters 10 | listen 50080; 11 | server_name myDomain.net; 12 | access_log /opt/var/log/nginx/myDomain.net.access.log; 13 | 14 | # SSL configuration 15 | ssl on; 16 | ssl_certificate /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/fullchain.pem; 17 | ssl_certificate_key /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/privkey.pem; 18 | ssl_session_cache builtin:1000 shared:SSL:10m; 19 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 20 | ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; 21 | ssl_prefer_server_ciphers on; 22 | 23 | location / { 24 | 25 | # proxy caching configuration 26 | proxy_cache ESP8266_cache; 27 | proxy_cache_revalidate on; 28 | proxy_cache_min_uses 1; 29 | proxy_cache_use_stale off; 30 | proxy_cache_lock on; 31 | # proxy_cache_bypass $http_cache_control; 32 | # include the sessionId cookie value as part of the cache key - keeps the cache per user 33 | # proxy_cache_key $proxy_host$request_uri$cookie_sessionId; 34 | 35 | # header pass through configuration 36 | proxy_set_header Host $host; 37 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 38 | proxy_set_header X-Forwarded-Proto $scheme; 39 | 40 | # ESP8266 custom headers which identify to the device that it's running through an SSL proxy 41 | proxy_set_header X-SSL On; 42 | proxy_set_header X-SSL-WebserverPort 50080; 43 | proxy_set_header X-SSL-WebsocketPort 50081; 44 | 45 | # extra debug headers 46 | add_header X-Proxy-Cache $upstream_cache_status; 47 | add_header X-Forwarded-For $proxy_add_x_forwarded_for; 48 | 49 | # actual proxying configuration 50 | proxy_ssl_session_reuse on; 51 | # target the IP address of the device with proxy_pass 52 | proxy_pass http://192.168.0.20; 53 | proxy_read_timeout 90; 54 | } 55 | } 56 | 57 | # websocket proxy 58 | server { 59 | 60 | # general server parameters 61 | listen 50081; 62 | server_name myDomain.net; 63 | access_log /opt/var/log/nginx/myDomain.net.wss.access.log; 64 | 65 | # SSL configuration 66 | ssl on; 67 | ssl_certificate /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/fullchain.pem; 68 | ssl_certificate_key /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/privkey.pem; 69 | ssl_session_cache builtin:1000 shared:SSL:10m; 70 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 71 | ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; 72 | ssl_prefer_server_ciphers on; 73 | 74 | location / { 75 | 76 | # websocket upgrade tunnel configuration 77 | proxy_pass http://192.168.0.20:81; 78 | proxy_http_version 1.1; 79 | proxy_set_header Upgrade $http_upgrade; 80 | proxy_set_header Connection "Upgrade"; 81 | proxy_read_timeout 86400; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/avr/WebSocketClientAVR/WebSocketClientAVR.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClientAVR.ino 3 | * 4 | * Created on: 10.12.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | 16 | 17 | // Enter a MAC address for your controller below. 18 | // Newer Ethernet shields have a MAC address printed on a sticker on the shield 19 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 20 | 21 | // Set the static IP address to use if the DHCP fails to assign 22 | IPAddress ip(192, 168, 0, 177); 23 | 24 | WebSocketsClient webSocket; 25 | 26 | 27 | 28 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 29 | 30 | 31 | switch(type) { 32 | case WStype_DISCONNECTED: 33 | Serial.println("[WSc] Disconnected!\n"); 34 | break; 35 | case WStype_CONNECTED: 36 | { 37 | Serial.print("[WSc] Connected to url: "); 38 | Serial.println((char *)payload); 39 | // send message to server when Connected 40 | webSocket.sendTXT("Connected"); 41 | } 42 | break; 43 | case WStype_TEXT: 44 | Serial.print("[WSc] get text: "); 45 | Serial.println((char *)payload); 46 | // send message to server 47 | // webSocket.sendTXT("message here"); 48 | break; 49 | case WStype_BIN: 50 | Serial.print("[WSc] get binary length: "); 51 | Serial.println(length); 52 | // hexdump(payload, length); 53 | 54 | // send data to server 55 | // webSocket.sendBIN(payload, length); 56 | break; 57 | } 58 | 59 | } 60 | 61 | void setup() 62 | { 63 | // Open serial communications and wait for port to open: 64 | Serial.begin(115200); 65 | while (!Serial) {} 66 | 67 | // start the Ethernet connection: 68 | if (Ethernet.begin(mac) == 0) { 69 | Serial.println("Failed to configure Ethernet using DHCP"); 70 | // no point in carrying on, so do nothing forevermore: 71 | // try to congifure using IP address instead of DHCP: 72 | Ethernet.begin(mac, ip); 73 | } 74 | 75 | webSocket.begin("192.168.0.123", 8011); 76 | webSocket.onEvent(webSocketEvent); 77 | 78 | } 79 | 80 | 81 | void loop() 82 | { 83 | webSocket.loop(); 84 | } 85 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp32/WebSocketClient/WebSocketClient.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClient.ino 3 | * 4 | * Created on: 24.05.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | 17 | WiFiMulti WiFiMulti; 18 | WebSocketsClient webSocket; 19 | 20 | #define USE_SERIAL Serial1 21 | 22 | void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { 23 | const uint8_t* src = (const uint8_t*) mem; 24 | USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); 25 | for(uint32_t i = 0; i < len; i++) { 26 | if(i % cols == 0) { 27 | USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); 28 | } 29 | USE_SERIAL.printf("%02X ", *src); 30 | src++; 31 | } 32 | USE_SERIAL.printf("\n"); 33 | } 34 | 35 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 36 | 37 | switch(type) { 38 | case WStype_DISCONNECTED: 39 | USE_SERIAL.printf("[WSc] Disconnected!\n"); 40 | break; 41 | case WStype_CONNECTED: 42 | USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); 43 | 44 | // send message to server when Connected 45 | webSocket.sendTXT("Connected"); 46 | break; 47 | case WStype_TEXT: 48 | USE_SERIAL.printf("[WSc] get text: %s\n", payload); 49 | 50 | // send message to server 51 | // webSocket.sendTXT("message here"); 52 | break; 53 | case WStype_BIN: 54 | USE_SERIAL.printf("[WSc] get binary length: %u\n", length); 55 | hexdump(payload, length); 56 | 57 | // send data to server 58 | // webSocket.sendBIN(payload, length); 59 | break; 60 | case WStype_ERROR: 61 | case WStype_FRAGMENT_TEXT_START: 62 | case WStype_FRAGMENT_BIN_START: 63 | case WStype_FRAGMENT: 64 | case WStype_FRAGMENT_FIN: 65 | break; 66 | } 67 | 68 | } 69 | 70 | void setup() { 71 | // USE_SERIAL.begin(921600); 72 | USE_SERIAL.begin(115200); 73 | 74 | //Serial.setDebugOutput(true); 75 | USE_SERIAL.setDebugOutput(true); 76 | 77 | USE_SERIAL.println(); 78 | USE_SERIAL.println(); 79 | USE_SERIAL.println(); 80 | 81 | for(uint8_t t = 4; t > 0; t--) { 82 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 83 | USE_SERIAL.flush(); 84 | delay(1000); 85 | } 86 | 87 | WiFiMulti.addAP("SSID", "passpasspass"); 88 | 89 | //WiFi.disconnect(); 90 | while(WiFiMulti.run() != WL_CONNECTED) { 91 | delay(100); 92 | } 93 | 94 | // server address, port and URL 95 | webSocket.begin("192.168.0.123", 81, "/"); 96 | 97 | // event handler 98 | webSocket.onEvent(webSocketEvent); 99 | 100 | // use HTTP Basic Authorization this is optional remove if not needed 101 | webSocket.setAuthorization("user", "Password"); 102 | 103 | // try ever 5000 again if connection has failed 104 | webSocket.setReconnectInterval(5000); 105 | 106 | } 107 | 108 | void loop() { 109 | webSocket.loop(); 110 | } 111 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClientSSL.ino 3 | * 4 | * Created on: 10.12.2015 5 | * 6 | * note SSL is only possible with the ESP8266 7 | * 8 | */ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | 19 | WiFiMulti WiFiMulti; 20 | WebSocketsClient webSocket; 21 | 22 | #define USE_SERIAL Serial1 23 | 24 | void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { 25 | const uint8_t* src = (const uint8_t*) mem; 26 | USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); 27 | for(uint32_t i = 0; i < len; i++) { 28 | if(i % cols == 0) { 29 | USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); 30 | } 31 | USE_SERIAL.printf("%02X ", *src); 32 | src++; 33 | } 34 | USE_SERIAL.printf("\n"); 35 | } 36 | 37 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 38 | 39 | 40 | switch(type) { 41 | case WStype_DISCONNECTED: 42 | USE_SERIAL.printf("[WSc] Disconnected!\n"); 43 | break; 44 | case WStype_CONNECTED: 45 | { 46 | USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); 47 | 48 | // send message to server when Connected 49 | webSocket.sendTXT("Connected"); 50 | } 51 | break; 52 | case WStype_TEXT: 53 | USE_SERIAL.printf("[WSc] get text: %s\n", payload); 54 | 55 | // send message to server 56 | // webSocket.sendTXT("message here"); 57 | break; 58 | case WStype_BIN: 59 | USE_SERIAL.printf("[WSc] get binary length: %u\n", length); 60 | hexdump(payload, length); 61 | 62 | // send data to server 63 | // webSocket.sendBIN(payload, length); 64 | break; 65 | case WStype_ERROR: 66 | case WStype_FRAGMENT_TEXT_START: 67 | case WStype_FRAGMENT_BIN_START: 68 | case WStype_FRAGMENT: 69 | case WStype_FRAGMENT_FIN: 70 | break; 71 | } 72 | 73 | } 74 | 75 | void setup() { 76 | // USE_SERIAL.begin(921600); 77 | USE_SERIAL.begin(115200); 78 | 79 | //Serial.setDebugOutput(true); 80 | USE_SERIAL.setDebugOutput(true); 81 | 82 | USE_SERIAL.println(); 83 | USE_SERIAL.println(); 84 | USE_SERIAL.println(); 85 | 86 | for(uint8_t t = 4; t > 0; t--) { 87 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 88 | USE_SERIAL.flush(); 89 | delay(1000); 90 | } 91 | 92 | WiFiMulti.addAP("SSID", "passpasspass"); 93 | 94 | //WiFi.disconnect(); 95 | while(WiFiMulti.run() != WL_CONNECTED) { 96 | delay(100); 97 | } 98 | 99 | webSocket.beginSSL("192.168.0.123", 81); 100 | webSocket.onEvent(webSocketEvent); 101 | 102 | } 103 | 104 | void loop() { 105 | webSocket.loop(); 106 | } 107 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp32/WebSocketServer/WebSocketServer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServer.ino 3 | * 4 | * Created on: 22.05.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | WiFiMulti WiFiMulti; 17 | WebSocketsServer webSocket = WebSocketsServer(81); 18 | 19 | #define USE_SERIAL Serial1 20 | 21 | void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { 22 | const uint8_t* src = (const uint8_t*) mem; 23 | USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); 24 | for(uint32_t i = 0; i < len; i++) { 25 | if(i % cols == 0) { 26 | USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); 27 | } 28 | USE_SERIAL.printf("%02X ", *src); 29 | src++; 30 | } 31 | USE_SERIAL.printf("\n"); 32 | } 33 | 34 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 35 | 36 | switch(type) { 37 | case WStype_DISCONNECTED: 38 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 39 | break; 40 | case WStype_CONNECTED: 41 | { 42 | IPAddress ip = webSocket.remoteIP(num); 43 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 44 | 45 | // send message to client 46 | webSocket.sendTXT(num, "Connected"); 47 | } 48 | break; 49 | case WStype_TEXT: 50 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 51 | 52 | // send message to client 53 | // webSocket.sendTXT(num, "message here"); 54 | 55 | // send data to all connected clients 56 | // webSocket.broadcastTXT("message here"); 57 | break; 58 | case WStype_BIN: 59 | USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); 60 | hexdump(payload, length); 61 | 62 | // send message to client 63 | // webSocket.sendBIN(num, payload, length); 64 | break; 65 | case WStype_ERROR: 66 | case WStype_FRAGMENT_TEXT_START: 67 | case WStype_FRAGMENT_BIN_START: 68 | case WStype_FRAGMENT: 69 | case WStype_FRAGMENT_FIN: 70 | break; 71 | } 72 | 73 | } 74 | 75 | void setup() { 76 | // USE_SERIAL.begin(921600); 77 | USE_SERIAL.begin(115200); 78 | 79 | //Serial.setDebugOutput(true); 80 | USE_SERIAL.setDebugOutput(true); 81 | 82 | USE_SERIAL.println(); 83 | USE_SERIAL.println(); 84 | USE_SERIAL.println(); 85 | 86 | for(uint8_t t = 4; t > 0; t--) { 87 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 88 | USE_SERIAL.flush(); 89 | delay(1000); 90 | } 91 | 92 | WiFiMulti.addAP("SSID", "passpasspass"); 93 | 94 | while(WiFiMulti.run() != WL_CONNECTED) { 95 | delay(100); 96 | } 97 | 98 | webSocket.begin(); 99 | webSocket.onEvent(webSocketEvent); 100 | } 101 | 102 | void loop() { 103 | webSocket.loop(); 104 | } 105 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketClient/WebSocketClient.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClient.ino 3 | * 4 | * Created on: 24.05.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | ESP8266WiFiMulti WiFiMulti; 18 | WebSocketsClient webSocket; 19 | 20 | #define USE_SERIAL Serial1 21 | 22 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 23 | 24 | switch(type) { 25 | case WStype_DISCONNECTED: 26 | USE_SERIAL.printf("[WSc] Disconnected!\n"); 27 | break; 28 | case WStype_CONNECTED: { 29 | USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); 30 | 31 | // send message to server when Connected 32 | webSocket.sendTXT("Connected"); 33 | } 34 | break; 35 | case WStype_TEXT: 36 | USE_SERIAL.printf("[WSc] get text: %s\n", payload); 37 | 38 | // send message to server 39 | // webSocket.sendTXT("message here"); 40 | break; 41 | case WStype_BIN: 42 | USE_SERIAL.printf("[WSc] get binary length: %u\n", length); 43 | hexdump(payload, length); 44 | 45 | // send data to server 46 | // webSocket.sendBIN(payload, length); 47 | break; 48 | case WStype_PING: 49 | // pong will be send automatically 50 | USE_SERIAL.printf("[WSc] get ping\n"); 51 | break; 52 | case WStype_PONG: 53 | // answer to a ping we send 54 | USE_SERIAL.printf("[WSc] get pong\n"); 55 | break; 56 | } 57 | 58 | } 59 | 60 | void setup() { 61 | // USE_SERIAL.begin(921600); 62 | USE_SERIAL.begin(115200); 63 | 64 | //Serial.setDebugOutput(true); 65 | USE_SERIAL.setDebugOutput(true); 66 | 67 | USE_SERIAL.println(); 68 | USE_SERIAL.println(); 69 | USE_SERIAL.println(); 70 | 71 | for(uint8_t t = 4; t > 0; t--) { 72 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 73 | USE_SERIAL.flush(); 74 | delay(1000); 75 | } 76 | 77 | WiFiMulti.addAP("SSID", "passpasspass"); 78 | 79 | //WiFi.disconnect(); 80 | while(WiFiMulti.run() != WL_CONNECTED) { 81 | delay(100); 82 | } 83 | 84 | // server address, port and URL 85 | webSocket.begin("192.168.0.123", 81, "/"); 86 | 87 | // event handler 88 | webSocket.onEvent(webSocketEvent); 89 | 90 | // use HTTP Basic Authorization this is optional remove if not needed 91 | webSocket.setAuthorization("user", "Password"); 92 | 93 | // try ever 5000 again if connection has failed 94 | webSocket.setReconnectInterval(5000); 95 | 96 | // start heartbeat (optional) 97 | // ping server every 15000 ms 98 | // expect pong from server within 3000 ms 99 | // consider connection disconnected if pong is not received 2 times 100 | webSocket.enableHeartbeat(15000, 3000, 2); 101 | 102 | } 103 | 104 | void loop() { 105 | webSocket.loop(); 106 | } 107 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketClientOTA/README.md: -------------------------------------------------------------------------------- 1 | ## Minimal example of WebsocketClientOTA and Python server 2 | 3 | Take this as small example, how achieve OTA update on ESP8266 and ESP32. 4 | 5 | Python server was wrote from train so take it only as bare example. 6 | It's working, but it's not mean to run in production. 7 | 8 | 9 | ### Usage: 10 | 11 | Start server: 12 | ```bash 13 | cd python_ota_server 14 | python3 -m venv .venv 15 | source .venv/bin/activate 16 | pip3 install -r requirements.txt 17 | python3 main.py 18 | ``` 19 | 20 | Flash ESP with example sketch and start it. 21 | 22 | Change version inside example sketch to higher and compile it and save it to bin file. 23 | 24 | Rename it to `mydevice-1.0.1-esp8266.bin` and place it inside new folder firmware (server create it). 25 | 26 | When the ESP connect to server, it check if version flashed is equal to fw in firmware folder. If higher FW version is present, 27 | start the flash process. -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketClientOTA/python_ota_server/requirements.txt: -------------------------------------------------------------------------------- 1 | packaging 2 | websockets -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketClientSSL/WebSocketClientSSL.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClientSSL.ino 3 | * 4 | * Created on: 10.12.2015 5 | * 6 | * note SSL is only possible with the ESP8266 7 | * 8 | */ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | ESP8266WiFiMulti WiFiMulti; 20 | WebSocketsClient webSocket; 21 | 22 | 23 | #define USE_SERIAL Serial1 24 | 25 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 26 | 27 | 28 | switch(type) { 29 | case WStype_DISCONNECTED: 30 | USE_SERIAL.printf("[WSc] Disconnected!\n"); 31 | break; 32 | case WStype_CONNECTED: 33 | { 34 | USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); 35 | 36 | // send message to server when Connected 37 | webSocket.sendTXT("Connected"); 38 | } 39 | break; 40 | case WStype_TEXT: 41 | USE_SERIAL.printf("[WSc] get text: %s\n", payload); 42 | 43 | // send message to server 44 | // webSocket.sendTXT("message here"); 45 | break; 46 | case WStype_BIN: 47 | USE_SERIAL.printf("[WSc] get binary length: %u\n", length); 48 | hexdump(payload, length); 49 | 50 | // send data to server 51 | // webSocket.sendBIN(payload, length); 52 | break; 53 | } 54 | 55 | } 56 | 57 | void setup() { 58 | // USE_SERIAL.begin(921600); 59 | USE_SERIAL.begin(115200); 60 | 61 | //Serial.setDebugOutput(true); 62 | USE_SERIAL.setDebugOutput(true); 63 | 64 | USE_SERIAL.println(); 65 | USE_SERIAL.println(); 66 | USE_SERIAL.println(); 67 | 68 | for(uint8_t t = 4; t > 0; t--) { 69 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 70 | USE_SERIAL.flush(); 71 | delay(1000); 72 | } 73 | 74 | WiFiMulti.addAP("SSID", "passpasspass"); 75 | 76 | //WiFi.disconnect(); 77 | while(WiFiMulti.run() != WL_CONNECTED) { 78 | delay(100); 79 | } 80 | 81 | webSocket.beginSSL("192.168.0.123", 81); 82 | webSocket.onEvent(webSocketEvent); 83 | 84 | } 85 | 86 | void loop() { 87 | webSocket.loop(); 88 | } 89 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClientSSLWithCA.ino 3 | * 4 | * Created on: 27.10.2019 5 | * 6 | * note SSL is only possible with the ESP8266 7 | * 8 | */ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | ESP8266WiFiMulti WiFiMulti; 18 | WebSocketsClient webSocket; 19 | 20 | #define USE_SERIAL Serial1 21 | 22 | 23 | // Can be obtained with: 24 | // openssl s_client -showcerts -connect echo.websocket.org:443 0; t--) { 82 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 83 | USE_SERIAL.flush(); 84 | delay(1000); 85 | } 86 | 87 | WiFiMulti.addAP("SSID", "passpasspass"); 88 | 89 | while(WiFiMulti.run() != WL_CONNECTED) { 90 | delay(100); 91 | } 92 | 93 | //When using BearSSL, client certificate and private key can be set: 94 | //webSocket.setSSLClientCertKey(clientCert, clientPrivateKey); 95 | //clientCert and clientPrivateKey can be of types (const char *, const char *) , or of types (BearSSL::X509List, BearSSL::PrivateKey) 96 | 97 | webSocket.beginSslWithCA("echo.websocket.org", 443, "/", ENDPOINT_CA_CERT); 98 | webSocket.onEvent(webSocketEvent); 99 | } 100 | 101 | void loop() { 102 | webSocket.loop(); 103 | } 104 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClientSocketIO.ino 3 | * 4 | * Created on: 06.06.2016 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | ESP8266WiFiMulti WiFiMulti; 21 | SocketIOclient socketIO; 22 | 23 | #define USE_SERIAL Serial1 24 | 25 | void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) { 26 | switch(type) { 27 | case sIOtype_DISCONNECT: 28 | USE_SERIAL.printf("[IOc] Disconnected!\n"); 29 | break; 30 | case sIOtype_CONNECT: 31 | USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload); 32 | 33 | // join default namespace (no auto join in Socket.IO V3) 34 | socketIO.send(sIOtype_CONNECT, "/"); 35 | break; 36 | case sIOtype_EVENT: 37 | USE_SERIAL.printf("[IOc] get event: %s\n", payload); 38 | break; 39 | case sIOtype_ACK: 40 | USE_SERIAL.printf("[IOc] get ack: %u\n", length); 41 | hexdump(payload, length); 42 | break; 43 | case sIOtype_ERROR: 44 | USE_SERIAL.printf("[IOc] get error: %u\n", length); 45 | hexdump(payload, length); 46 | break; 47 | case sIOtype_BINARY_EVENT: 48 | USE_SERIAL.printf("[IOc] get binary: %u\n", length); 49 | hexdump(payload, length); 50 | break; 51 | case sIOtype_BINARY_ACK: 52 | USE_SERIAL.printf("[IOc] get binary ack: %u\n", length); 53 | hexdump(payload, length); 54 | break; 55 | } 56 | } 57 | 58 | void setup() { 59 | // USE_SERIAL.begin(921600); 60 | USE_SERIAL.begin(115200); 61 | 62 | //Serial.setDebugOutput(true); 63 | USE_SERIAL.setDebugOutput(true); 64 | 65 | USE_SERIAL.println(); 66 | USE_SERIAL.println(); 67 | USE_SERIAL.println(); 68 | 69 | for(uint8_t t = 4; t > 0; t--) { 70 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 71 | USE_SERIAL.flush(); 72 | delay(1000); 73 | } 74 | 75 | // disable AP 76 | if(WiFi.getMode() & WIFI_AP) { 77 | WiFi.softAPdisconnect(true); 78 | } 79 | 80 | WiFiMulti.addAP("SSID", "passpasspass"); 81 | 82 | //WiFi.disconnect(); 83 | while(WiFiMulti.run() != WL_CONNECTED) { 84 | delay(100); 85 | } 86 | 87 | String ip = WiFi.localIP().toString(); 88 | USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str()); 89 | 90 | // server address, port and URL 91 | socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4"); 92 | 93 | // event handler 94 | socketIO.onEvent(socketIOEvent); 95 | } 96 | 97 | unsigned long messageTimestamp = 0; 98 | void loop() { 99 | socketIO.loop(); 100 | 101 | uint64_t now = millis(); 102 | 103 | if(now - messageTimestamp > 2000) { 104 | messageTimestamp = now; 105 | 106 | // creat JSON message for Socket.IO (event) 107 | DynamicJsonDocument doc(1024); 108 | JsonArray array = doc.to(); 109 | 110 | // add evnet name 111 | // Hint: socket.on('event_name', .... 112 | array.add("event_name"); 113 | 114 | // add payload (parameters) for the event 115 | JsonObject param1 = array.createNestedObject(); 116 | param1["now"] = (uint32_t) now; 117 | 118 | // JSON to String (serializion) 119 | String output; 120 | serializeJson(doc, output); 121 | 122 | // Send event 123 | socketIO.sendEVENT(output); 124 | 125 | // Print JSON for debugging 126 | USE_SERIAL.println(output); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketServer/WebSocketServer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServer.ino 3 | * 4 | * Created on: 22.05.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | ESP8266WiFiMulti WiFiMulti; 16 | 17 | WebSocketsServer webSocket = WebSocketsServer(81); 18 | 19 | #define USE_SERIAL Serial1 20 | 21 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 22 | 23 | switch(type) { 24 | case WStype_DISCONNECTED: 25 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 26 | break; 27 | case WStype_CONNECTED: 28 | { 29 | IPAddress ip = webSocket.remoteIP(num); 30 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 31 | 32 | // send message to client 33 | webSocket.sendTXT(num, "Connected"); 34 | } 35 | break; 36 | case WStype_TEXT: 37 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 38 | 39 | // send message to client 40 | // webSocket.sendTXT(num, "message here"); 41 | 42 | // send data to all connected clients 43 | // webSocket.broadcastTXT("message here"); 44 | break; 45 | case WStype_BIN: 46 | USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); 47 | hexdump(payload, length); 48 | 49 | // send message to client 50 | // webSocket.sendBIN(num, payload, length); 51 | break; 52 | } 53 | 54 | } 55 | 56 | void setup() { 57 | // USE_SERIAL.begin(921600); 58 | USE_SERIAL.begin(115200); 59 | 60 | //Serial.setDebugOutput(true); 61 | USE_SERIAL.setDebugOutput(true); 62 | 63 | USE_SERIAL.println(); 64 | USE_SERIAL.println(); 65 | USE_SERIAL.println(); 66 | 67 | for(uint8_t t = 4; t > 0; t--) { 68 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 69 | USE_SERIAL.flush(); 70 | delay(1000); 71 | } 72 | 73 | WiFiMulti.addAP("SSID", "passpasspass"); 74 | 75 | while(WiFiMulti.run() != WL_CONNECTED) { 76 | delay(100); 77 | } 78 | 79 | webSocket.begin(); 80 | webSocket.onEvent(webSocketEvent); 81 | } 82 | 83 | void loop() { 84 | webSocket.loop(); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServerAllFunctionsDemo.ino 3 | * 4 | * Created on: 10.05.2018 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define LED_RED 15 18 | #define LED_GREEN 12 19 | #define LED_BLUE 13 20 | 21 | #define USE_SERIAL Serial 22 | 23 | ESP8266WiFiMulti WiFiMulti; 24 | 25 | ESP8266WebServer server(80); 26 | WebSocketsServer webSocket = WebSocketsServer(81); 27 | 28 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 29 | 30 | switch(type) { 31 | case WStype_DISCONNECTED: 32 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 33 | break; 34 | case WStype_CONNECTED: { 35 | IPAddress ip = webSocket.remoteIP(num); 36 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 37 | 38 | // send message to client 39 | webSocket.sendTXT(num, "Connected"); 40 | } 41 | break; 42 | case WStype_TEXT: 43 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 44 | 45 | if(payload[0] == '#') { 46 | // we get RGB data 47 | 48 | // decode rgb data 49 | uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16); 50 | 51 | analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); 52 | analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); 53 | analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); 54 | } 55 | 56 | break; 57 | } 58 | 59 | } 60 | 61 | void setup() { 62 | //USE_SERIAL.begin(921600); 63 | USE_SERIAL.begin(115200); 64 | 65 | //USE_SERIAL.setDebugOutput(true); 66 | 67 | USE_SERIAL.println(); 68 | USE_SERIAL.println(); 69 | USE_SERIAL.println(); 70 | 71 | for(uint8_t t = 4; t > 0; t--) { 72 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 73 | USE_SERIAL.flush(); 74 | delay(1000); 75 | } 76 | 77 | pinMode(LED_RED, OUTPUT); 78 | pinMode(LED_GREEN, OUTPUT); 79 | pinMode(LED_BLUE, OUTPUT); 80 | 81 | digitalWrite(LED_RED, 1); 82 | digitalWrite(LED_GREEN, 1); 83 | digitalWrite(LED_BLUE, 1); 84 | 85 | WiFiMulti.addAP("SSID", "passpasspass"); 86 | 87 | while(WiFiMulti.run() != WL_CONNECTED) { 88 | delay(100); 89 | } 90 | 91 | // start webSocket server 92 | webSocket.begin(); 93 | webSocket.onEvent(webSocketEvent); 94 | 95 | if(MDNS.begin("esp8266")) { 96 | USE_SERIAL.println("MDNS responder started"); 97 | } 98 | 99 | // handle index 100 | server.on("/", []() { 101 | // send index.html 102 | server.send(200, "text/html", "LED Control:

R:
G:
B:
"); 103 | }); 104 | 105 | server.begin(); 106 | 107 | // Add service to MDNS 108 | MDNS.addService("http", "tcp", 80); 109 | MDNS.addService("ws", "tcp", 81); 110 | 111 | digitalWrite(LED_RED, 0); 112 | digitalWrite(LED_GREEN, 0); 113 | digitalWrite(LED_BLUE, 0); 114 | 115 | } 116 | 117 | unsigned long last_10sec = 0; 118 | unsigned int counter = 0; 119 | 120 | void loop() { 121 | unsigned long t = millis(); 122 | webSocket.loop(); 123 | server.handleClient(); 124 | 125 | if((t - last_10sec) > 10 * 1000) { 126 | counter++; 127 | bool ping = (counter % 2); 128 | int i = webSocket.connectedClients(ping); 129 | USE_SERIAL.printf("%d Connected websocket clients ping: %d\n", i, ping); 130 | last_10sec = millis(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketServerFragmentation/WebSocketServerFragmentation.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServer.ino 3 | * 4 | * Created on: 22.05.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | ESP8266WiFiMulti WiFiMulti; 16 | 17 | WebSocketsServer webSocket = WebSocketsServer(81); 18 | 19 | #define USE_SERIAL Serial 20 | 21 | String fragmentBuffer = ""; 22 | 23 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 24 | 25 | switch(type) { 26 | case WStype_DISCONNECTED: 27 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 28 | break; 29 | case WStype_CONNECTED: { 30 | IPAddress ip = webSocket.remoteIP(num); 31 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 32 | 33 | // send message to client 34 | webSocket.sendTXT(num, "Connected"); 35 | } 36 | break; 37 | case WStype_TEXT: 38 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 39 | break; 40 | case WStype_BIN: 41 | USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); 42 | hexdump(payload, length); 43 | break; 44 | 45 | // Fragmentation / continuation opcode handling 46 | // case WStype_FRAGMENT_BIN_START: 47 | case WStype_FRAGMENT_TEXT_START: 48 | fragmentBuffer = (char*)payload; 49 | USE_SERIAL.printf("[%u] get start start of Textfragment: %s\n", num, payload); 50 | break; 51 | case WStype_FRAGMENT: 52 | fragmentBuffer += (char*)payload; 53 | USE_SERIAL.printf("[%u] get Textfragment : %s\n", num, payload); 54 | break; 55 | case WStype_FRAGMENT_FIN: 56 | fragmentBuffer += (char*)payload; 57 | USE_SERIAL.printf("[%u] get end of Textfragment: %s\n", num, payload); 58 | USE_SERIAL.printf("[%u] full frame: %s\n", num, fragmentBuffer.c_str()); 59 | break; 60 | } 61 | 62 | } 63 | 64 | void setup() { 65 | // USE_SERIAL.begin(921600); 66 | USE_SERIAL.begin(115200); 67 | 68 | //Serial.setDebugOutput(true); 69 | USE_SERIAL.setDebugOutput(true); 70 | 71 | USE_SERIAL.println(); 72 | USE_SERIAL.println(); 73 | USE_SERIAL.println(); 74 | 75 | for(uint8_t t = 4; t > 0; t--) { 76 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 77 | USE_SERIAL.flush(); 78 | delay(1000); 79 | } 80 | 81 | WiFiMulti.addAP("SSID", "passpasspass"); 82 | 83 | while(WiFiMulti.run() != WL_CONNECTED) { 84 | delay(100); 85 | } 86 | 87 | webSocket.begin(); 88 | webSocket.onEvent(webSocketEvent); 89 | } 90 | 91 | void loop() { 92 | webSocket.loop(); 93 | } 94 | 95 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServerHooked.ino 3 | * 4 | * Created on: 22.05.2015 5 | * Hooked on: 28.10.2020 6 | * 7 | */ 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | ESP8266WiFiMulti WiFiMulti; 18 | 19 | ESP8266WebServer server(80); 20 | WebSockets4WebServer webSocket; 21 | 22 | #define USE_SERIAL Serial 23 | 24 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 25 | 26 | switch(type) { 27 | case WStype_DISCONNECTED: 28 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 29 | break; 30 | case WStype_CONNECTED: 31 | { 32 | IPAddress ip = webSocket.remoteIP(num); 33 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 34 | 35 | // send message to client 36 | webSocket.sendTXT(num, "Connected"); 37 | } 38 | break; 39 | case WStype_TEXT: 40 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 41 | 42 | // send message to client 43 | // webSocket.sendTXT(num, "message here"); 44 | 45 | // send data to all connected clients 46 | // webSocket.broadcastTXT("message here"); 47 | break; 48 | case WStype_BIN: 49 | USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); 50 | hexdump(payload, length); 51 | 52 | // send message to client 53 | // webSocket.sendBIN(num, payload, length); 54 | break; 55 | } 56 | 57 | } 58 | 59 | void setup() { 60 | // USE_SERIAL.begin(921600); 61 | USE_SERIAL.begin(115200); 62 | 63 | //Serial.setDebugOutput(true); 64 | USE_SERIAL.setDebugOutput(true); 65 | 66 | USE_SERIAL.println(); 67 | USE_SERIAL.println(); 68 | USE_SERIAL.println(); 69 | 70 | for(uint8_t t = 4; t > 0; t--) { 71 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 72 | USE_SERIAL.flush(); 73 | delay(1000); 74 | } 75 | 76 | WiFiMulti.addAP("SSID", "passpasspass"); 77 | 78 | while(WiFiMulti.run() != WL_CONNECTED) { 79 | delay(100); 80 | } 81 | 82 | server.on("/", []() { 83 | server.send(200, "text/plain", "I am a regular webserver on port 80!\r\n"); 84 | server.send(200, "text/plain", "I am also a websocket server on '/ws' on the same port 80\r\n"); 85 | }); 86 | 87 | server.addHook(webSocket.hookForWebserver("/ws", webSocketEvent)); 88 | 89 | server.begin(); 90 | Serial.println("HTTP server started on port 80"); 91 | Serial.println("WebSocket server started on the same port"); 92 | Serial.printf("my network address is either 'arduinoWebsockets.local' (mDNS) or '%s'\n", WiFi.localIP().toString().c_str()); 93 | 94 | if (!MDNS.begin("arduinoWebsockets")) { 95 | Serial.println("Error setting up MDNS responder!"); 96 | } 97 | } 98 | 99 | void loop() { 100 | server.handleClient(); 101 | webSocket.loop(); 102 | MDNS.update(); 103 | } 104 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketServerHooked/emu: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # linux script to compile&run arduinoWebSockets in a mock environment 4 | 5 | if [ -z "$ESP8266ARDUINO" ]; then 6 | echo "please set ESP8266ARDUINO env-var to where esp8266/arduino sits" 7 | exit 1 8 | fi 9 | 10 | set -e 11 | 12 | where=$(pwd) 13 | 14 | cd $ESP8266ARDUINO/tests/host/ 15 | 16 | make -j FORCE32=0 \ 17 | ULIBDIRS=../../libraries/Hash/:~/dev/proj/arduino/libraries/arduinoWebSockets \ 18 | ${where}/WebSocketServerHooked 19 | 20 | valgrind ./bin/WebSocketServerHooked/WebSocketServerHooked -b "$@" 21 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketServerHooked/ws-testclient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # python websocket client to test with 4 | # emulator: server is at ws://127.0.0.1:9080/ws 5 | # esp8266: server is at ws:///ws 6 | # (uncomment the right line below) 7 | 8 | #uri = "ws://127.0.0.1:9080/ws" 9 | uri = "ws://arduinoWebsockets.local/ws" 10 | 11 | import websocket 12 | try: 13 | import thread 14 | except ImportError: 15 | import _thread as thread 16 | import time 17 | 18 | def on_message(ws, message): 19 | print("message"); 20 | print(message) 21 | 22 | def on_error(ws, error): 23 | print("error") 24 | print(error) 25 | 26 | def on_close(ws): 27 | print("### closed ###") 28 | 29 | def on_open(ws): 30 | print("opened") 31 | def run(*args): 32 | for i in range(3): 33 | time.sleep(1) 34 | ws.send("Hello %d" % i) 35 | time.sleep(1) 36 | ws.close() 37 | print("thread terminating...") 38 | thread.start_new_thread(run, ()) 39 | 40 | 41 | if __name__ == "__main__": 42 | websocket.enableTrace(True) 43 | ws = websocket.WebSocketApp(uri, on_message = on_message, on_error = on_error, on_close = on_close) 44 | ws.on_open = on_open 45 | ws.run_forever() 46 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServerHttpHeaderValidation.ino 3 | * 4 | * Created on: 08.06.2016 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | ESP8266WiFiMulti WiFiMulti; 16 | 17 | WebSocketsServer webSocket = WebSocketsServer(81); 18 | 19 | #define USE_SERIAL Serial1 20 | 21 | const unsigned long int validSessionId = 12345; //some arbitrary value to act as a valid sessionId 22 | 23 | /* 24 | * Returns a bool value as an indicator to describe whether a user is allowed to initiate a websocket upgrade 25 | * based on the value of a cookie. This function expects the rawCookieHeaderValue to look like this "sessionId=|" 26 | */ 27 | bool isCookieValid(String rawCookieHeaderValue) { 28 | 29 | if (rawCookieHeaderValue.indexOf("sessionId") != -1) { 30 | String sessionIdStr = rawCookieHeaderValue.substring(rawCookieHeaderValue.indexOf("sessionId=") + 10, rawCookieHeaderValue.indexOf("|")); 31 | unsigned long int sessionId = strtoul(sessionIdStr.c_str(), NULL, 10); 32 | return sessionId == validSessionId; 33 | } 34 | return false; 35 | } 36 | 37 | /* 38 | * The WebSocketServerHttpHeaderValFunc delegate passed to webSocket.onValidateHttpHeader 39 | */ 40 | bool validateHttpHeader(String headerName, String headerValue) { 41 | 42 | //assume a true response for any headers not handled by this validator 43 | bool valid = true; 44 | 45 | if(headerName.equalsIgnoreCase("Cookie")) { 46 | //if the header passed is the Cookie header, validate it according to the rules in 'isCookieValid' function 47 | valid = isCookieValid(headerValue); 48 | } 49 | 50 | return valid; 51 | } 52 | 53 | void setup() { 54 | // USE_SERIAL.begin(921600); 55 | USE_SERIAL.begin(115200); 56 | 57 | //Serial.setDebugOutput(true); 58 | USE_SERIAL.setDebugOutput(true); 59 | 60 | USE_SERIAL.println(); 61 | USE_SERIAL.println(); 62 | USE_SERIAL.println(); 63 | 64 | for(uint8_t t = 4; t > 0; t--) { 65 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 66 | USE_SERIAL.flush(); 67 | delay(1000); 68 | } 69 | 70 | WiFiMulti.addAP("SSID", "passpasspass"); 71 | 72 | while(WiFiMulti.run() != WL_CONNECTED) { 73 | delay(100); 74 | } 75 | 76 | //connecting clients must supply a valid session cookie at websocket upgrade handshake negotiation time 77 | const char * headerkeys[] = { "Cookie" }; 78 | size_t headerKeyCount = sizeof(headerkeys) / sizeof(char*); 79 | webSocket.onValidateHttpHeader(validateHttpHeader, headerkeys, headerKeyCount); 80 | webSocket.begin(); 81 | } 82 | 83 | void loop() { 84 | webSocket.loop(); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/esp8266/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServer_LEDcontrol.ino 3 | * 4 | * Created on: 26.11.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define LED_RED 15 18 | #define LED_GREEN 12 19 | #define LED_BLUE 13 20 | 21 | #define USE_SERIAL Serial 22 | 23 | 24 | ESP8266WiFiMulti WiFiMulti; 25 | 26 | ESP8266WebServer server(80); 27 | WebSocketsServer webSocket = WebSocketsServer(81); 28 | 29 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 30 | 31 | switch(type) { 32 | case WStype_DISCONNECTED: 33 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 34 | break; 35 | case WStype_CONNECTED: { 36 | IPAddress ip = webSocket.remoteIP(num); 37 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 38 | 39 | // send message to client 40 | webSocket.sendTXT(num, "Connected"); 41 | } 42 | break; 43 | case WStype_TEXT: 44 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 45 | 46 | if(payload[0] == '#') { 47 | // we get RGB data 48 | 49 | // decode rgb data 50 | uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16); 51 | 52 | analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); 53 | analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); 54 | analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); 55 | } 56 | 57 | break; 58 | } 59 | 60 | } 61 | 62 | void setup() { 63 | //USE_SERIAL.begin(921600); 64 | USE_SERIAL.begin(115200); 65 | 66 | //USE_SERIAL.setDebugOutput(true); 67 | 68 | USE_SERIAL.println(); 69 | USE_SERIAL.println(); 70 | USE_SERIAL.println(); 71 | 72 | for(uint8_t t = 4; t > 0; t--) { 73 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 74 | USE_SERIAL.flush(); 75 | delay(1000); 76 | } 77 | 78 | pinMode(LED_RED, OUTPUT); 79 | pinMode(LED_GREEN, OUTPUT); 80 | pinMode(LED_BLUE, OUTPUT); 81 | 82 | digitalWrite(LED_RED, 1); 83 | digitalWrite(LED_GREEN, 1); 84 | digitalWrite(LED_BLUE, 1); 85 | 86 | WiFiMulti.addAP("SSID", "passpasspass"); 87 | 88 | while(WiFiMulti.run() != WL_CONNECTED) { 89 | delay(100); 90 | } 91 | 92 | // start webSocket server 93 | webSocket.begin(); 94 | webSocket.onEvent(webSocketEvent); 95 | 96 | if(MDNS.begin("esp8266")) { 97 | USE_SERIAL.println("MDNS responder started"); 98 | } 99 | 100 | // handle index 101 | server.on("/", []() { 102 | // send index.html 103 | server.send(200, "text/html", "LED Control:

R:
G:
B:
"); 104 | }); 105 | 106 | server.begin(); 107 | 108 | // Add service to MDNS 109 | MDNS.addService("http", "tcp", 80); 110 | MDNS.addService("ws", "tcp", 81); 111 | 112 | digitalWrite(LED_RED, 0); 113 | digitalWrite(LED_GREEN, 0); 114 | digitalWrite(LED_BLUE, 0); 115 | 116 | } 117 | 118 | void loop() { 119 | webSocket.loop(); 120 | server.handleClient(); 121 | } 122 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/examples/particle/ParticleWebSocketClient/application.cpp: -------------------------------------------------------------------------------- 1 | /* To compile using make CLI, create a folder under \firmware\user\applications and copy application.cpp there. 2 | * Then, copy src files under particleWebSocket folder. 3 | */ 4 | 5 | #include "application.h" 6 | #include "particleWebSocket/WebSocketsClient.h" 7 | 8 | WebSocketsClient webSocket; 9 | 10 | void webSocketEvent(WStype_t type, uint8_t* payload, size_t length) 11 | { 12 | switch (type) 13 | { 14 | case WStype_DISCONNECTED: 15 | Serial.printlnf("[WSc] Disconnected!"); 16 | break; 17 | case WStype_CONNECTED: 18 | Serial.printlnf("[WSc] Connected to URL: %s", payload); 19 | webSocket.sendTXT("Connected\r\n"); 20 | break; 21 | case WStype_TEXT: 22 | Serial.printlnf("[WSc] get text: %s", payload); 23 | break; 24 | case WStype_BIN: 25 | Serial.printlnf("[WSc] get binary length: %u", length); 26 | break; 27 | } 28 | } 29 | 30 | void setup() 31 | { 32 | Serial.begin(9600); 33 | 34 | WiFi.setCredentials("[SSID]", "[PASSWORD]", WPA2, WLAN_CIPHER_AES_TKIP); 35 | WiFi.connect(); 36 | 37 | webSocket.begin("192.168.1.153", 85, "/ClientService/?variable=Test1212"); 38 | webSocket.onEvent(webSocketEvent); 39 | } 40 | 41 | void loop() 42 | { 43 | webSocket.sendTXT("Hello world!"); 44 | delay(500); 45 | webSocket.loop(); 46 | } 47 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "maintainer": true, 5 | "name": "Markus Sattler", 6 | "url": "https://github.com/Links2004" 7 | } 8 | ], 9 | "description": "WebSocket Server and Client for Arduino based on RFC6455", 10 | "export": { 11 | "exclude": [ 12 | "tests" 13 | ] 14 | }, 15 | "frameworks": "arduino", 16 | "keywords": "wifi, http, web, server, client, websocket", 17 | "license": "LGPL-2.1", 18 | "name": "WebSockets", 19 | "platforms": "atmelavr, espressif8266, espressif32", 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/Links2004/arduinoWebSockets.git" 23 | }, 24 | "version": "2.3.6" 25 | } -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/library.properties: -------------------------------------------------------------------------------- 1 | name=WebSockets 2 | version=2.3.6 3 | author=Markus Sattler 4 | maintainer=Markus Sattler 5 | sentence=WebSockets for Arduino (Server + Client) 6 | paragraph=use 2.x.x for ESP and 1.3 for AVR 7 | category=Communication 8 | url=https://github.com/Links2004/arduinoWebSockets 9 | architectures=* 10 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/WebSockets4WebServer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file WebSocketsServer.cpp 3 | * @date 28.10.2020 4 | * @author Markus Sattler & esp8266/arduino community 5 | * 6 | * Copyright (c) 2020 Markus Sattler. All rights reserved. 7 | * This file is part of the WebSockets for Arduino. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | */ 24 | 25 | #ifndef __WEBSOCKETS4WEBSERVER_H 26 | #define __WEBSOCKETS4WEBSERVER_H 27 | 28 | #include 29 | #include 30 | 31 | #if WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK 32 | 33 | class WebSockets4WebServer : public WebSocketsServerCore { 34 | public: 35 | WebSockets4WebServer(const String & origin = "", const String & protocol = "arduino") 36 | : WebSocketsServerCore(origin, protocol) { 37 | begin(); 38 | } 39 | 40 | ESP8266WebServer::HookFunction hookForWebserver(const String & wsRootDir, WebSocketServerEvent event) { 41 | onEvent(event); 42 | 43 | return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) { 44 | (void)contentType; 45 | 46 | if(!(method == "GET" && url.indexOf(wsRootDir) == 0)) { 47 | return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; 48 | } 49 | 50 | // allocate a WiFiClient copy (like in WebSocketsServer::handleNewClients()) 51 | WEBSOCKETS_NETWORK_CLASS * newTcpClient = new WEBSOCKETS_NETWORK_CLASS(*tcpClient); 52 | 53 | // Then initialize a new WSclient_t (like in WebSocketsServer::handleNewClient()) 54 | WSclient_t * client = handleNewClient(newTcpClient); 55 | 56 | if(client) { 57 | // give "GET " 58 | String headerLine; 59 | headerLine.reserve(url.length() + 5); 60 | headerLine = "GET "; 61 | headerLine += url; 62 | handleHeader(client, &headerLine); 63 | } 64 | 65 | // tell webserver to not close but forget about this client 66 | return ESP8266WebServer::CLIENT_IS_GIVEN; 67 | }; 68 | } 69 | }; 70 | #else // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK 71 | 72 | #ifndef WEBSERVER_HAS_HOOK 73 | #error Your current Framework / Arduino core version does not support Webserver Hook Functions 74 | #else 75 | #error Your Hardware Platform does not support Webserver Hook Functions 76 | #endif 77 | 78 | #endif // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK 79 | 80 | #endif // __WEBSOCKETS4WEBSERVER_H 81 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/WebSocketsVersion.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file WebSocketsVersion.h 3 | * @date 08.03.2021 4 | * @author Markus Sattler 5 | * 6 | * Copyright (c) 2015 Markus Sattler. All rights reserved. 7 | * This file is part of the WebSockets for Arduino. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | */ 24 | 25 | #ifndef WEBSOCKETSVERSION_H_ 26 | #define WEBSOCKETSVERSION_H_ 27 | 28 | #define WEBSOCKETS_VERSION "2.3.6" 29 | 30 | #define WEBSOCKETS_VERSION_MAJOR 2 31 | #define WEBSOCKETS_VERSION_MINOR 3 32 | #define WEBSOCKETS_VERSION_PATCH 6 33 | 34 | #define WEBSOCKETS_VERSION_INT 2003006 35 | 36 | #endif /* WEBSOCKETSVERSION_H_ */ 37 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/libb64/AUTHORS: -------------------------------------------------------------------------------- 1 | libb64: Base64 Encoding/Decoding Routines 2 | ====================================== 3 | 4 | Authors: 5 | ------- 6 | 7 | Chris Venter chris.venter@gmail.com http://rocketpod.blogspot.com 8 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/libb64/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright-Only Dedication (based on United States law) 2 | or Public Domain Certification 3 | 4 | The person or persons who have associated work with this document (the 5 | "Dedicator" or "Certifier") hereby either (a) certifies that, to the best of 6 | his knowledge, the work of authorship identified is in the public domain of the 7 | country from which the work is published, or (b) hereby dedicates whatever 8 | copyright the dedicators holds in the work of authorship identified below (the 9 | "Work") to the public domain. A certifier, moreover, dedicates any copyright 10 | interest he may have in the associated work, and for these purposes, is 11 | described as a "dedicator" below. 12 | 13 | A certifier has taken reasonable steps to verify the copyright status of this 14 | work. Certifier recognizes that his good faith efforts may not shield him from 15 | liability if in fact the work certified is not in the public domain. 16 | 17 | Dedicator makes this dedication for the benefit of the public at large and to 18 | the detriment of the Dedicator's heirs and successors. Dedicator intends this 19 | dedication to be an overt act of relinquishment in perpetuity of all present 20 | and future rights under copyright law, whether vested or contingent, in the 21 | Work. Dedicator understands that such relinquishment of all rights includes 22 | the relinquishment of all rights to enforce (by lawsuit or otherwise) those 23 | copyrights in the Work. 24 | 25 | Dedicator recognizes that, once placed in the public domain, the Work may be 26 | freely reproduced, distributed, transmitted, used, modified, built upon, or 27 | otherwise exploited by anyone for any purpose, commercial or non-commercial, 28 | and in any way, including by methods that have not yet been invented or 29 | conceived. -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/libb64/cdecode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cdecoder.c - c source to a base64 decoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifdef ESP8266 9 | #include 10 | #endif 11 | 12 | #if defined(ESP32) 13 | #define CORE_HAS_LIBB64 14 | #endif 15 | 16 | #ifndef CORE_HAS_LIBB64 17 | #include "cdecode_inc.h" 18 | 19 | int base64_decode_value(char value_in) 20 | { 21 | static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; 22 | static const char decoding_size = sizeof(decoding); 23 | value_in -= 43; 24 | if (value_in < 0 || value_in > decoding_size) return -1; 25 | return decoding[(int)value_in]; 26 | } 27 | 28 | void base64_init_decodestate(base64_decodestate* state_in) 29 | { 30 | state_in->step = step_a; 31 | state_in->plainchar = 0; 32 | } 33 | 34 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in) 35 | { 36 | const char* codechar = code_in; 37 | char* plainchar = plaintext_out; 38 | char fragment; 39 | 40 | *plainchar = state_in->plainchar; 41 | 42 | switch (state_in->step) 43 | { 44 | while (1) 45 | { 46 | case step_a: 47 | do { 48 | if (codechar == code_in+length_in) 49 | { 50 | state_in->step = step_a; 51 | state_in->plainchar = *plainchar; 52 | return plainchar - plaintext_out; 53 | } 54 | fragment = (char)base64_decode_value(*codechar++); 55 | } while (fragment < 0); 56 | *plainchar = (fragment & 0x03f) << 2; 57 | case step_b: 58 | do { 59 | if (codechar == code_in+length_in) 60 | { 61 | state_in->step = step_b; 62 | state_in->plainchar = *plainchar; 63 | return plainchar - plaintext_out; 64 | } 65 | fragment = (char)base64_decode_value(*codechar++); 66 | } while (fragment < 0); 67 | *plainchar++ |= (fragment & 0x030) >> 4; 68 | *plainchar = (fragment & 0x00f) << 4; 69 | case step_c: 70 | do { 71 | if (codechar == code_in+length_in) 72 | { 73 | state_in->step = step_c; 74 | state_in->plainchar = *plainchar; 75 | return plainchar - plaintext_out; 76 | } 77 | fragment = (char)base64_decode_value(*codechar++); 78 | } while (fragment < 0); 79 | *plainchar++ |= (fragment & 0x03c) >> 2; 80 | *plainchar = (fragment & 0x003) << 6; 81 | case step_d: 82 | do { 83 | if (codechar == code_in+length_in) 84 | { 85 | state_in->step = step_d; 86 | state_in->plainchar = *plainchar; 87 | return plainchar - plaintext_out; 88 | } 89 | fragment = (char)base64_decode_value(*codechar++); 90 | } while (fragment < 0); 91 | *plainchar++ |= (fragment & 0x03f); 92 | } 93 | } 94 | /* control should not reach here */ 95 | return plainchar - plaintext_out; 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/libb64/cdecode_inc.h: -------------------------------------------------------------------------------- 1 | /* 2 | cdecode.h - c header for a base64 decoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CDECODE_H 9 | #define BASE64_CDECODE_H 10 | 11 | typedef enum 12 | { 13 | step_a, step_b, step_c, step_d 14 | } base64_decodestep; 15 | 16 | typedef struct 17 | { 18 | base64_decodestep step; 19 | char plainchar; 20 | } base64_decodestate; 21 | 22 | void base64_init_decodestate(base64_decodestate* state_in); 23 | 24 | int base64_decode_value(char value_in); 25 | 26 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); 27 | 28 | #endif /* BASE64_CDECODE_H */ 29 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/libb64/cencode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cencoder.c - c source to a base64 encoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifdef ESP8266 9 | #include 10 | #endif 11 | 12 | #if defined(ESP32) 13 | #define CORE_HAS_LIBB64 14 | #endif 15 | 16 | #ifndef CORE_HAS_LIBB64 17 | #include "cencode_inc.h" 18 | 19 | const int CHARS_PER_LINE = 72; 20 | 21 | void base64_init_encodestate(base64_encodestate* state_in) 22 | { 23 | state_in->step = step_A; 24 | state_in->result = 0; 25 | state_in->stepcount = 0; 26 | } 27 | 28 | char base64_encode_value(char value_in) 29 | { 30 | static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 31 | if (value_in > 63) return '='; 32 | return encoding[(int)value_in]; 33 | } 34 | 35 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) 36 | { 37 | const char* plainchar = plaintext_in; 38 | const char* const plaintextend = plaintext_in + length_in; 39 | char* codechar = code_out; 40 | char result; 41 | char fragment; 42 | 43 | result = state_in->result; 44 | 45 | switch (state_in->step) 46 | { 47 | while (1) 48 | { 49 | case step_A: 50 | if (plainchar == plaintextend) 51 | { 52 | state_in->result = result; 53 | state_in->step = step_A; 54 | return codechar - code_out; 55 | } 56 | fragment = *plainchar++; 57 | result = (fragment & 0x0fc) >> 2; 58 | *codechar++ = base64_encode_value(result); 59 | result = (fragment & 0x003) << 4; 60 | case step_B: 61 | if (plainchar == plaintextend) 62 | { 63 | state_in->result = result; 64 | state_in->step = step_B; 65 | return codechar - code_out; 66 | } 67 | fragment = *plainchar++; 68 | result |= (fragment & 0x0f0) >> 4; 69 | *codechar++ = base64_encode_value(result); 70 | result = (fragment & 0x00f) << 2; 71 | case step_C: 72 | if (plainchar == plaintextend) 73 | { 74 | state_in->result = result; 75 | state_in->step = step_C; 76 | return codechar - code_out; 77 | } 78 | fragment = *plainchar++; 79 | result |= (fragment & 0x0c0) >> 6; 80 | *codechar++ = base64_encode_value(result); 81 | result = (fragment & 0x03f) >> 0; 82 | *codechar++ = base64_encode_value(result); 83 | 84 | ++(state_in->stepcount); 85 | if (state_in->stepcount == CHARS_PER_LINE/4) 86 | { 87 | *codechar++ = '\n'; 88 | state_in->stepcount = 0; 89 | } 90 | } 91 | } 92 | /* control should not reach here */ 93 | return codechar - code_out; 94 | } 95 | 96 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in) 97 | { 98 | char* codechar = code_out; 99 | 100 | switch (state_in->step) 101 | { 102 | case step_B: 103 | *codechar++ = base64_encode_value(state_in->result); 104 | *codechar++ = '='; 105 | *codechar++ = '='; 106 | break; 107 | case step_C: 108 | *codechar++ = base64_encode_value(state_in->result); 109 | *codechar++ = '='; 110 | break; 111 | case step_A: 112 | break; 113 | } 114 | *codechar++ = 0x00; 115 | 116 | return codechar - code_out; 117 | } 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/libb64/cencode_inc.h: -------------------------------------------------------------------------------- 1 | /* 2 | cencode.h - c header for a base64 encoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CENCODE_H 9 | #define BASE64_CENCODE_H 10 | 11 | typedef enum 12 | { 13 | step_A, step_B, step_C 14 | } base64_encodestep; 15 | 16 | typedef struct 17 | { 18 | base64_encodestep step; 19 | char result; 20 | int stepcount; 21 | } base64_encodestate; 22 | 23 | void base64_init_encodestate(base64_encodestate* state_in); 24 | 25 | char base64_encode_value(char value_in); 26 | 27 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); 28 | 29 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in); 30 | 31 | #endif /* BASE64_CENCODE_H */ 32 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/src/libsha1/libsha1.h: -------------------------------------------------------------------------------- 1 | /* ================ sha1.h ================ */ 2 | /* 3 | SHA-1 in C 4 | By Steve Reid 5 | 100% Public Domain 6 | */ 7 | 8 | #if !defined(ESP8266) && !defined(ESP32) 9 | 10 | typedef struct { 11 | uint32_t state[5]; 12 | uint32_t count[2]; 13 | unsigned char buffer[64]; 14 | } SHA1_CTX; 15 | 16 | void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); 17 | void SHA1Init(SHA1_CTX* context); 18 | void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); 19 | void SHA1Final(unsigned char digest[20], SHA1_CTX* context); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/tests/webSocket.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 40 | 41 | 42 | 43 | LED Control:
44 |
45 | R:
46 | G:
47 | B:
48 | 49 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/tests/webSocketServer/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var WebSocketServer = require('websocket').server; 3 | var http = require('http'); 4 | 5 | var server = http.createServer(function(request, response) { 6 | console.log((new Date()) + ' Received request for ' + request.url); 7 | response.writeHead(404); 8 | response.end(); 9 | }); 10 | server.listen(8011, function() { 11 | console.log((new Date()) + ' Server is listening on port 8011'); 12 | }); 13 | 14 | wsServer = new WebSocketServer({ 15 | httpServer: server, 16 | // You should not use autoAcceptConnections for production 17 | // applications, as it defeats all standard cross-origin protection 18 | // facilities built into the protocol and the browser. You should 19 | // *always* verify the connection's origin and decide whether or not 20 | // to accept it. 21 | autoAcceptConnections: false 22 | }); 23 | 24 | function originIsAllowed(origin) { 25 | // put logic here to detect whether the specified origin is allowed. 26 | return true; 27 | } 28 | 29 | wsServer.on('request', function(request) { 30 | 31 | if (!originIsAllowed(request.origin)) { 32 | // Make sure we only accept requests from an allowed origin 33 | request.reject(); 34 | console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.'); 35 | return; 36 | } 37 | 38 | var connection = request.accept('arduino', request.origin); 39 | console.log((new Date()) + ' Connection accepted.'); 40 | 41 | connection.on('message', function(message) { 42 | if (message.type === 'utf8') { 43 | console.log('Received Message: ' + message.utf8Data); 44 | // connection.sendUTF(message.utf8Data); 45 | } 46 | else if (message.type === 'binary') { 47 | console.log('Received Binary Message of ' + message.binaryData.length + ' bytes'); 48 | //connection.sendBytes(message.binaryData); 49 | } 50 | }); 51 | 52 | connection.on('close', function(reasonCode, description) { 53 | console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.'); 54 | }); 55 | 56 | connection.sendUTF("Hallo Client!"); 57 | }); 58 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/tests/webSocketServer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webSocketServer", 3 | "version": "1.0.0", 4 | "description": "WebSocketServer for testing", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/Links2004/arduinoWebSockets" 12 | }, 13 | "keywords": [ 14 | "esp8266", 15 | "websocket", 16 | "arduino" 17 | ], 18 | "author": "Markus Sattler", 19 | "license": "LGPLv2", 20 | "bugs": { 21 | "url": "https://github.com/Links2004/arduinoWebSockets/issues" 22 | }, 23 | "homepage": "https://github.com/Links2004/arduinoWebSockets", 24 | "dependencies": { 25 | "websocket": "^1.0.18" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /libraries/arduinoWebSockets-2.3.6/travis/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | function build_sketches() 6 | { 7 | local arduino=$1 8 | local srcpath=$2 9 | local platform=$3 10 | local sketches=$(find $srcpath -name *.ino) 11 | for sketch in $sketches; do 12 | local sketchdir=$(dirname $sketch) 13 | if [[ -f "$sketchdir/.$platform.skip" ]]; then 14 | echo -e "\n\n ------------ Skipping $sketch ------------ \n\n"; 15 | continue 16 | fi 17 | echo -e "\n\n ------------ Building $sketch ------------ \n\n"; 18 | $arduino --verify $sketch; 19 | local result=$? 20 | if [ $result -ne 0 ]; then 21 | echo "Build failed ($sketch) build verbose..." 22 | $arduino --verify --verbose --preserve-temp-files $sketch 23 | result=$? 24 | fi 25 | if [ $result -ne 0 ]; then 26 | echo "Build failed ($1) $sketch" 27 | return $result 28 | fi 29 | done 30 | } 31 | 32 | function build_sketch() 33 | { 34 | local arduino=$1 35 | local sketch=$2 36 | $arduino --verify $sketch; 37 | local result=$? 38 | if [ $result -ne 0 ]; then 39 | echo "Build failed ($sketch) build verbose..." 40 | $arduino --verify --verbose --preserve-temp-files $sketch 41 | result=$? 42 | fi 43 | if [ $result -ne 0 ]; then 44 | echo "Build failed ($1) $sketch" 45 | return $result 46 | fi 47 | } 48 | 49 | function get_sketches_json() 50 | { 51 | local arduino=$1 52 | local srcpath=$2 53 | local platform=$3 54 | local sketches=($(find $srcpath -name *.ino)) 55 | echo -en "[" 56 | for sketch in "${sketches[@]}" ; do 57 | local sketchdir=$(dirname $sketch) 58 | if [[ -f "$sketchdir/.$platform.skip" ]]; then 59 | continue 60 | fi 61 | echo -en "\"$sketch\"" 62 | if [[ $sketch != ${sketches[-1]} ]] ; then 63 | echo -en "," 64 | fi 65 | 66 | done 67 | echo -en "]" 68 | } 69 | 70 | function get_sketches_json_matrix() 71 | { 72 | local arduino=$1 73 | local srcpath=$2 74 | local platform=$3 75 | local ideversion=$4 76 | local board=$5 77 | local sketches=($(find $srcpath -name *.ino)) 78 | for sketch in "${sketches[@]}" ; do 79 | local sketchdir=$(dirname $sketch) 80 | local sketchname=$(basename $sketch) 81 | if [[ -f "$sketchdir/.$platform.skip" ]]; then 82 | continue 83 | fi 84 | echo -en "{\"name\":\"$sketchname\",\"board\":\"$board\",\"ideversion\":\"$ideversion\",\"cpu\":\"$platform\",\"sketch\":\"$sketch\"}" 85 | if [[ $sketch != ${sketches[-1]} ]] ; then 86 | echo -en "," 87 | fi 88 | done 89 | } 90 | 91 | function get_core() 92 | { 93 | echo Setup core for $1 94 | 95 | cd $HOME/arduino_ide/hardware 96 | 97 | if [ "$1" = "esp8266" ] ; then 98 | mkdir esp8266com 99 | cd esp8266com 100 | git clone --depth 1 https://github.com/esp8266/Arduino.git esp8266 101 | cd esp8266/ 102 | git submodule update --init 103 | rm -rf .git 104 | cd tools 105 | python get.py 106 | fi 107 | 108 | if [ "$1" = "esp32" ] ; then 109 | mkdir espressif 110 | cd espressif 111 | git clone --depth 1 https://github.com/espressif/arduino-esp32.git esp32 112 | cd esp32/ 113 | rm -rf .git 114 | cd tools 115 | python get.py 116 | fi 117 | 118 | } 119 | 120 | function clone_library() { 121 | local url=$1 122 | echo clone $(basename $url) 123 | mkdir -p $HOME/Arduino/libraries 124 | cd $HOME/Arduino/libraries 125 | git clone --depth 1 $url 126 | rm -rf */.git 127 | rm -rf */.github 128 | rm -rf */examples 129 | } 130 | 131 | function hash_library_names() { 132 | cd $HOME/Arduino/libraries 133 | ls | sha1sum -z | cut -c1-5 134 | } -------------------------------------------------------------------------------- /schemes/scheme1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexGyver/MagicGyver/b515148034cbed1da88869a296a1107ba9b16f12/schemes/scheme1.jpg -------------------------------------------------------------------------------- /schemes/scheme2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexGyver/MagicGyver/b515148034cbed1da88869a296a1107ba9b16f12/schemes/scheme2.png -------------------------------------------------------------------------------- /tracer-test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MagicGyver 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 24 | 25 | 40 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | --------------------------------------------------------------------------------