├── .gitignore ├── LICENSE ├── README.md ├── examples ├── ButtonArray │ └── ButtonArrayDemo │ │ └── ButtonArrayDemo.ino ├── ColorPicker │ └── ColorUpdate │ │ └── ColorUpdate.ino ├── Joystick │ ├── JoystickData │ │ └── JoystickData.ino │ └── JoystickTimer │ │ └── JoystickTimer.ino ├── MotionControl │ ├── MotionData │ │ └── MotionData.ino │ └── MotionTimer │ │ └── MotionTimer.ino ├── SerialMonitor │ └── SerialMonitorDemo │ │ └── SerialMonitorDemo.ino └── Slider │ └── SliderDemo │ └── SliderDemo.ino ├── library.properties └── src ├── ButtonArray.cpp ├── ButtonArray.h ├── ColorData.cpp ├── ColorData.h ├── ColorPicker.cpp ├── ColorPicker.h ├── ControllerData.cpp ├── ControllerData.h ├── InvokController.cpp ├── InvokController.h ├── Joystick.cpp ├── Joystick.h ├── Motion.cpp ├── Motion.h ├── Slider.cpp └── Slider.h /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Thoby Liman Noorhalim 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 | # Invok Controller 2 | 3 | ## What is this library? 4 | 5 | Invok Controller library is a wrapper library based on: 6 | 7 | - [WiFi](https://github.com/arduino-libraries/WiFi) 8 | - [ESPmDNS](https://github.com/espressif/arduino-esp32/tree/master/libraries/ESPmDNS) 9 | - [ESP8266WiFi](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi) 10 | - [ESP8266mDNS](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266mDNS) 11 | - [WebSockets](https://github.com/Links2004/arduinoWebSockets) 12 | - [WiFiManager](https://github.com/tzapu/WiFiManager) 13 | 14 | This library is used for connecting development boards to the [Controller](https://play.google.com/store/apps/details?id=com.invokcontroller.app) app. Controller App is now available on Google Play. 15 | 16 | ## What's new ? 17 | 18 | ## 8 May 2023 19 | 20 | We have added the following: 21 | 22 | - Example sketch for motion control. 23 | 24 | ## 16 December 2021 25 | 26 | We have made the following changes: 27 | 28 | - Option to turn on/off Debug message. Debug message begins with [DEBUG] identifier. 29 | - Remove unused function from previous release. 30 | - Add ability to stop/remove mDNS service when device is connected. 31 | - Add connection status watcher by polling PING message from client. 32 | 33 | ## Disclaimer 34 | 35 | This library is still a work in progress. There may be some breaking changes in the future, which might require you to replace, re-organize, and rearrange functions or variables included in this library. Use this library at your own risk. 36 | 37 | ## Supported Development Board 38 | 39 | - ESP32 Development Board Family (WiFi) 40 | - ESP8266 Development Board Family (WiFi) 41 | 42 | ## Basic Functionality 43 | 44 | - WiFiManager, this awesome library lets you connect you ESP board to WiFi without harcoding the SSID and password. 45 | - Setting ESPs as Websocket Server 46 | - WebSocket PING/PONG heartbeat routine 47 | - Receive control data from Controller app 48 | 49 | ## Quickstart 50 | 51 | - Download the [Controller](https://play.google.com/store/apps/details?id=com.invokcontroller.app) app from Google Play Store. 52 | - Install the following library: 53 | - [WiFi](https://github.com/arduino-libraries/WiFi) 54 | - [ESPmDNS](https://github.com/espressif/arduino-esp32/tree/master/libraries/ESPmDNS) 55 | - [ESP8266WiFi](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi) 56 | - [ESP8266mDNS](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266mDNS) 57 | - [WebSockets](https://github.com/Links2004/arduinoWebSockets) 58 | - [WiFiManager](https://github.com/tzapu/WiFiManager) 59 | - Download/clone this repository, and put it into libraries folder of Arduino directory. Ensure you have downloaded the latest version. 60 | - Compile and upload example sketch. 61 | - With WiFiManager, you can now setup WiFi without hardcoding SSID and password. After uploading the firmware, connect to ESP Wifi, SSID should be something like ESP_XXXX. 62 | - You will then be directed to configuration portal, if you are not redirected automatically, access the portal with this address (1.1.1.1). Internal LED will turn on when in wifi configuration mode. 63 | - Choose SSID you want to connect to, and input the password. 64 | - When connected to network, program will print __IP Address__ on Serial Monitor, take note of this address. 65 | - In Controller app home page, tap Wi-Fi icon on top right corner, this will route you to connection setup page. 66 | - Input the IP Address printed on serial monitor to address field. 67 | - Press __Connect__. 68 | - Status icon on top right corner will turn green when connection is established. 69 | - Test connection by sending message. Server will respond or echo back the same message. 70 | 71 | ## Code Setup 72 | 73 | Create a new arduino sketch, and include InvokController.h 74 | 75 | `#include ` 76 | 77 | Instantiate Controller object as global variable before setup(), and specify controller type, port, and debug mode as argument. 78 | 79 | `Controller myController("websocket", 80, false);` 80 | 81 | In setup(), initiate serial data transmission, 82 | 83 | `Serial.begin(115200);` 84 | 85 | set hostname of your device for mDNS identification, 86 | 87 | `myController.setHostname("myDevice")` 88 | 89 | and continue to call begin method of controller. 90 | 91 | ```c++ 92 | myController.begin(); 93 | ``` 94 | 95 | As soon as you call begin() method, Controller will start a Wi-Fi configuration portal. You can then enter/select your Wi-Fi. If connection is succesfull, the ESP board will start to broadcast a service through mDNS protocol. The controller app will find your ESP device automatically, and you can connect to it without having to check the serial monitor. 96 | 97 | Inside loop(), do not forget to call, 98 | 99 | `myController.loop();` 100 | 101 | `delay()` function use is discouraged, because it blocks the program routine. It might cause the websocket connection to drop. Use `millis()` instead, and create if statement to execute routine every certain time period. 102 | 103 | ## Examples 104 | 105 | Sample sketch are provided to demo the functionality of the App. 106 | 107 | ## Features 108 | 109 | ### Joystick 110 | 111 | In Controller app, Joystick movement will generate 5 data, [x, y, r, theta, intensity]. 112 | 113 | - __x,y__ represent coordinate of the pad in cartesian form. 114 | - __r,theta__ represent coordiate of the pad in polar form, where theta range is [0 - 360°]. 115 | - __intensity__ is the relative distance of pad from center circle to outer circle in percentage out of 100. 116 | 117 | #### Getters 118 | 119 | `ControllerName.joystick.getX()` -> Return x coordinate as __double__. 120 | 121 | `ControllerName.joystick.getY()` -> Return y coordinate as __double__. 122 | 123 | `ControllerName.joystick.getR()` -> Return range value as __double__. 124 | 125 | `ControllerName.joystick.getTheta()` -> Return angle as __double__. 126 | 127 | `ControllerName.joystick.getIntensity()` -> Return intensity as __double__. 128 | 129 | `ControllerName.joystick.getButtonState()` -> Return button state as __bool__. 130 | 131 | All of these datas are sent to the server via WiFi on selected protocol, parsed, and ready to be used. 132 | 133 | There is a small deadzone in the middle of joystick to prevent unwanted control motion. 134 | 135 | ### Color Picker 136 | 137 | Pick any color on color wheel. There are two modes available: 138 | 139 | - Update -> when pressed, app will send color info to the board. 140 | - Continuous -> triggered by long-press the update button, will continously send color data as user pick colors 141 | 142 | #### Color Picker Getters 143 | 144 | `ControllerName.colorPicker.getR()` -> Return Red component of RGB color space as __int__. 145 | 146 | `ControllerName.colorPicker.getG()` -> Return Green component of RGB color space as __int__. 147 | 148 | `ControllerName.colorPicker.getB()` -> Return Blue component of RGB color space as __int__. 149 | 150 | `ControllerName.colorPicker.getH()` -> Return Hue component of HSV color space as __double__. 151 | 152 | `ControllerName.colorPicker.getS()` -> Return Saturation component of HSV color space as __double__. 153 | 154 | `ControllerName.colorPicker.getV()` -> Return Value component of HSV color space as __double__. 155 | 156 | ### Button Array 157 | 158 | Set state of button individually or all button at once. App will send 12 button states as string. The data will then be parsed and processed, and then user can get state of each button pressed in boolean. 159 | 160 | #### Button Array Getters 161 | 162 | `ControllerName.buttonArray.getButtonArrayState(int button)` -> Return button state as __bool__. 163 | User need to specify which button state to get by passing number 0-11 (correspond to button 1 - 12) as parameter to getter function. 164 | 165 | ### Sliders 166 | 167 | Set state of slider individually or all sliders at once with master slider. App will send 6 slider value as string. The data will then be parsed and processed, and then user can get value of each slider in double with single precision (xx.x). 168 | 169 | #### Sliders Getters 170 | 171 | `ControllerName.slider.getSliderData(int slider)` -> Return slider value as __double__. 172 | User need to specify which slider to get by passing number 0-5 (correspond to slider 1 - 6) as parameter to getter function. 173 | 174 | ### Serial Monitor 175 | 176 | Controller serial monitor act just like Arduino serial monitor. It can send, receive and print data between ESP device and Controller app. 177 | 178 | #### Serial Monitor Getters 179 | 180 | `ControllerName.print(std::string stringToPrint)` -> will print 'stringToPrint' in Controller app. 181 | `ControllerName.getIncomingCommand()` -> Return a __std::string__ received from Controller app. 182 | `ControllerName.setIncomingCommand(std::string command)` -> Setter function to set the command when it is received from the app. This setter can also be used to flush the buffer by passing empty string as parameter (""). 183 | 184 | ### Motion Control 185 | 186 | In Controller app, Motion Control will generate 5 data, [x, y, r, theta, intensity]. This control method is very similar to Joystick. In motion control, the pointer move according to the absolute orientation of the phone. 187 | 188 | - __x,y__ represent coordinate of the pointer in cartesian form. 189 | - __r,theta__ represent coordiate of the pointer in polar form, where theta range is [0 - 360°]. 190 | - __intensity__ is the relative distance of pad from center circle to outer circle in percentage out of 100. 191 | 192 | #### Getters 193 | 194 | `ControllerName.motion.getX()` -> Return x coordinate as __double__. 195 | 196 | `ControllerName.motion.getY()` -> Return y coordinate as __double__. 197 | 198 | `ControllerName.motion.getR()` -> Return range value as __double__. 199 | 200 | `ControllerName.motion.getTheta()` -> Return angle as __double__. 201 | 202 | `ControllerName.motion.getIntensity()` -> Return intensity as __double__. 203 | 204 | All of these datas are sent to the server via WiFi on selected protocol, parsed, and ready to be used. 205 | 206 | There is a small deadzone in the middle of the Pad to prevent unwanted control motion. 207 | -------------------------------------------------------------------------------- /examples/ButtonArray/ButtonArrayDemo/ButtonArrayDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Demo sketch for receiving Button State Data from Controller App 3 | Written by Thoby L. Noorhalim 4 | 4 September 2021 5 | */ 6 | 7 | #include 8 | 9 | // Controller Object Instantiation 10 | Controller myController("websocket", 80, false); 11 | 12 | void setup() { 13 | Serial.begin(115200); 14 | 15 | // Controller Setup 16 | myController.setHostname("Button Array"); // mDNS 17 | myController.begin(); 18 | } 19 | 20 | void loop() { 21 | 22 | if (myController.isDataArrived()){ 23 | Serial.printf("Button State [%s] | [%s] | [%s] | [%s] | [%s] | [%s] | [%s] | [%s] | [%s] | [%s] | [%s] | [%s]\n", 24 | myController.buttonArray.getButtonArrayState(0) ? "1" : "0", 25 | myController.buttonArray.getButtonArrayState(1) ? "1" : "0", 26 | myController.buttonArray.getButtonArrayState(2) ? "1" : "0", 27 | myController.buttonArray.getButtonArrayState(3) ? "1" : "0", 28 | myController.buttonArray.getButtonArrayState(4) ? "1" : "0", 29 | myController.buttonArray.getButtonArrayState(5) ? "1" : "0", 30 | myController.buttonArray.getButtonArrayState(6) ? "1" : "0", 31 | myController.buttonArray.getButtonArrayState(7) ? "1" : "0", 32 | myController.buttonArray.getButtonArrayState(8) ? "1" : "0", 33 | myController.buttonArray.getButtonArrayState(9) ? "1" : "0", 34 | myController.buttonArray.getButtonArrayState(10) ? "1" : "0", 35 | myController.buttonArray.getButtonArrayState(11) ? "1" : "0"); 36 | myController.setDataArrived(false); // Flush, reset flag 37 | } 38 | 39 | // Controller Loop 40 | myController.loop(); 41 | } -------------------------------------------------------------------------------- /examples/ColorPicker/ColorUpdate/ColorUpdate.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Demo sketch for receiving Color Data from Controller App 3 | Written by Thoby L. Noorhalim 4 | 4 September 2021 5 | */ 6 | 7 | #include 8 | 9 | // Controller Object Instantiation 10 | Controller myController("websocket", 80, false); 11 | 12 | void setup() { 13 | Serial.begin(115200); 14 | 15 | // Controller Setup 16 | myController.setHostname("Color Update"); // mDNS 17 | myController.begin(); 18 | } 19 | 20 | void loop() { 21 | 22 | if (myController.isDataArrived()){ 23 | Serial.printf("R [%d] G [%d] B [%d] | H [%.1f] S[%.1f] V[%.1f]\n", 24 | myController.colorPicker.getR(), myController.colorPicker.getG(), 25 | myController.colorPicker.getB(), myController.colorPicker.getH(), 26 | myController.colorPicker.getS(), myController.colorPicker.getV()); 27 | myController.setDataArrived(false); // Flush, reset flag 28 | } 29 | 30 | // Controller Loop 31 | myController.loop(); 32 | } -------------------------------------------------------------------------------- /examples/Joystick/JoystickData/JoystickData.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Demo sketch for receiving Joystick Control Data from Controller App 3 | Written by Thoby L. Noorhalim 4 | 4 September 2021 5 | */ 6 | 7 | #include 8 | 9 | // Controller Object Instantiation 10 | Controller myController("websocket", 80, false); 11 | 12 | void setup() { 13 | Serial.begin(115200); 14 | 15 | // Controller Setup 16 | myController.setHostname("Joystick"); // mDNS 17 | myController.begin(); 18 | } 19 | 20 | void loop() { 21 | 22 | if (myController.isDataArrived()){ 23 | Serial.printf("Intensity : [ %.1f ], Theta : [ %.1f ], State : [ %s ]\n", 24 | myController.joystick.getIntensity(), myController.joystick.getTheta(), 25 | myController.joystick.getButtonState() ? "true" : "false"); 26 | myController.setDataArrived(false); // Flush, reset flag 27 | } 28 | 29 | // Controller Loop 30 | myController.loop(); 31 | } -------------------------------------------------------------------------------- /examples/Joystick/JoystickTimer/JoystickTimer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Demo sketch for receiving Joystick Control Data from Controller App, 3 | Printing the data periodically every second without blocking the program 4 | Written by Thoby L. Noorhalim 5 | 4 September 2021 6 | */ 7 | 8 | #include 9 | 10 | // Controller Object Instantiation 11 | Controller myController("websocket", 80, false); 12 | 13 | // Timer 14 | double elapsedTime = 0; 15 | double nowTime = 0; 16 | 17 | void setup() { 18 | Serial.begin(115200); 19 | 20 | // Controller Setup 21 | myController.setHostname("Joystick"); // mDNS 22 | myController.begin(); 23 | } 24 | 25 | void loop() { 26 | 27 | // Print data every second 28 | elapsedTime = millis() - nowTime; 29 | if (elapsedTime > 1000 && myController.isConnected()){ 30 | Serial.printf("Intensity : [ %.1f ], Theta : [ %.1f ], State : [ %s ]\n", 31 | myController.joystick.getIntensity(), myController.joystick.getTheta(), 32 | myController.joystick.getButtonState() ? "true" : "false"); 33 | elapsedTime = 0; 34 | nowTime = millis(); 35 | } 36 | 37 | // Controller Loop 38 | myController.loop(); 39 | } -------------------------------------------------------------------------------- /examples/MotionControl/MotionData/MotionData.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Demo sketch for receiving Motion Control Data from Controller App 3 | Written by Thoby L. Noorhalim 4 | 6 May 2023 5 | */ 6 | 7 | #include 8 | 9 | // Controller Object Instantiation 10 | Controller myController("websocket", 80, false); 11 | 12 | void setup() { 13 | Serial.begin(115200); 14 | 15 | // Controller Setup 16 | myController.setHostname("Motion"); // mDNS 17 | myController.begin(); 18 | } 19 | 20 | void loop() { 21 | 22 | if (myController.isDataArrived()){ 23 | Serial.printf("Intensity : [ %.1f ], Theta : [ %.1f ]\n", 24 | myController.motion.getIntensity(), myController.motion.getTheta(), 25 | myController.setDataArrived(false); // Flush, reset flag 26 | } 27 | 28 | // Controller Loop 29 | myController.loop(); 30 | } -------------------------------------------------------------------------------- /examples/MotionControl/MotionTimer/MotionTimer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Demo sketch for receiving Motion Control Data from Controller App, 3 | Printing the data periodically every second without blocking the program 4 | Written by Thoby L. Noorhalim 5 | 8 May 2023 6 | */ 7 | 8 | #include 9 | 10 | // Controller Object Instantiation 11 | Controller myController("websocket", 80, false); 12 | 13 | // Timer 14 | double elapsedTime = 0; 15 | double nowTime = 0; 16 | 17 | void setup() { 18 | Serial.begin(115200); 19 | 20 | // Controller Setup 21 | myController.setHostname("Motion"); // mDNS 22 | myController.begin(); 23 | } 24 | 25 | void loop() { 26 | 27 | // Print data every second 28 | elapsedTime = millis() - nowTime; 29 | if (elapsedTime > 1000 && myController.isConnected()){ 30 | Serial.printf("Intensity : [ %.1f ], Theta : [ %.1f ]\n", 31 | myController.motion.getIntensity(), myController.motion.getTheta()); 32 | elapsedTime = 0; 33 | nowTime = millis(); 34 | } 35 | 36 | // Controller Loop 37 | myController.loop(); 38 | } -------------------------------------------------------------------------------- /examples/SerialMonitor/SerialMonitorDemo/SerialMonitorDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Demo sketch for Controller app serial monitor 3 | Written by Thoby L. Noorhalim 4 | 13 October 2021 5 | */ 6 | 7 | #include 8 | 9 | // Timer 10 | double elapsedTime = 0; 11 | double capturedTime = 0; 12 | 13 | int variable = 0; 14 | 15 | // Controller Object Instantiation 16 | Controller myController("websocket", 80, false); 17 | 18 | void setup() { 19 | Serial.begin(115200); 20 | 21 | // Controller Setup 22 | myController.setHostname("Serial Monitor"); // mDNS 23 | myController.begin(); 24 | } 25 | 26 | void loop() { 27 | 28 | // Print data every 3 second 29 | elapsedTime = millis() - capturedTime; 30 | if (elapsedTime > 3000 && myController.isConnected()){ 31 | myController.print("Hello " + to_string(variable)); 32 | variable++; 33 | elapsedTime = 0; 34 | capturedTime = millis(); 35 | } 36 | 37 | if(!myController.getIncomingCommand().empty()){ 38 | Serial.printf("Command from client %s\n", myController.getIncomingCommand().c_str()); 39 | // Flush incoming command 40 | myController.setIncomingCommand(""); 41 | } 42 | 43 | // Controller Loop 44 | myController.loop(); 45 | } -------------------------------------------------------------------------------- /examples/Slider/SliderDemo/SliderDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Demo sketch for receiving Slider Data from Controller App 3 | Written by Thoby L. Noorhalim 4 | 28 September 2021 5 | */ 6 | 7 | #include 8 | 9 | // Controller Object Instantiation 10 | Controller myController("websocket", 80, false); 11 | 12 | void setup() { 13 | Serial.begin(115200); 14 | 15 | // Controller Setup 16 | myController.setHostname("Slider"); // mDNS 17 | myController.begin(); 18 | } 19 | 20 | void loop() { 21 | 22 | if (myController.isDataArrived()){ 23 | myController.setDataArrived(false); // Flush, reset flag 24 | Serial.printf("Slider State [%.1f] | [%.1f] | [%.1f] | [%.1f] | [%.1f] | [%.1f]\n", 25 | myController.slider.getSliderData(0), myController.slider.getSliderData(1), 26 | myController.slider.getSliderData(2), myController.slider.getSliderData(3), 27 | myController.slider.getSliderData(4), myController.slider.getSliderData(5) 28 | ); 29 | } 30 | 31 | // Controller Loop 32 | myController.loop(); 33 | } -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Invok Controller 2 | version=1.0.0 3 | author=Thoby L. Noorhalim 4 | maintainer=Thoby L. Noorhalim 5 | sentence=Library for using Controller app 6 | paragraph=Support Joystick controller from app 7 | category=Device Control 8 | url= 9 | architectures=esp8266,esp32 10 | includes=InvokController.h -------------------------------------------------------------------------------- /src/ButtonArray.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Class definition for ButtonArray.h library. 3 | Created by Thoby L. Noorhalim 4 | 3 September 2021 5 | */ 6 | 7 | #include 8 | 9 | // ---------- Constructor ---------- 10 | ButtonArray::ButtonArray(){}; 11 | 12 | void ButtonArray::updateData(std::vector parsedData){ 13 | setButtonArrayState(parsedData); 14 | } 15 | 16 | void ButtonArray::setButtonArrayState(std::vector state){ 17 | for(size_t i = 0; i < sizeof(this->buttonArrayState); i++){ 18 | if(state[i+1].compare("1") == 0){ 19 | this->buttonArrayState[i] = true; 20 | } else { 21 | this->buttonArrayState[i] = false; 22 | } 23 | } 24 | } 25 | 26 | bool ButtonArray::getButtonArrayState(int button){ 27 | return this->buttonArrayState[button]; 28 | } 29 | -------------------------------------------------------------------------------- /src/ButtonArray.h: -------------------------------------------------------------------------------- 1 | /* 2 | ButtonArray.h - Library for storing and 3 | updating Button Array data. 4 | Created by Thoby L. Noorhalim. 5 | 3 September 2021. 6 | */ 7 | 8 | #ifndef BUTTON_ARRAY_H 9 | #define BUTTON_ARRAY_H 10 | 11 | #include 12 | #include 13 | 14 | class ButtonArray { 15 | private: 16 | bool buttonArrayState[12] = {0}; 17 | public: 18 | // ---------- Constructor ---------- 19 | ButtonArray(); 20 | 21 | void updateData(std::vector parsedData); 22 | void setButtonArrayState(std::vector state); 23 | bool getButtonArrayState(int button); 24 | }; 25 | 26 | #endif -------------------------------------------------------------------------------- /src/ColorData.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Class definition for ColorData.h library. 3 | Created by Thoby L. Noorhalim 4 | 1 September 2021 5 | */ 6 | 7 | #include 8 | 9 | // Constructor 10 | ColorData::ColorData(){}; 11 | 12 | // ---------- Setters ---------- 13 | void ColorData::setA(std::string a){ 14 | this->a = stoi(a); 15 | } 16 | 17 | void ColorData::setR(std::string r){ 18 | this->r = stoi(r); 19 | } 20 | 21 | void ColorData::setG(std::string g){ 22 | this->g = stoi(g); 23 | } 24 | 25 | void ColorData::setB(std::string b){ 26 | this->b = stoi(b); 27 | } 28 | 29 | void ColorData::setH(std::string h){ 30 | this->h = stod(h); 31 | } 32 | 33 | void ColorData::setS(std::string s){ 34 | this->s = stod(s); 35 | } 36 | 37 | void ColorData::setV(std::string v){ 38 | this->v = stod(v); 39 | } 40 | 41 | 42 | // ---------- Getters ---------- 43 | int ColorData::getA(){ 44 | return this->a; 45 | } 46 | 47 | int ColorData::getR(){ 48 | return this->r; 49 | } 50 | 51 | int ColorData::getG(){ 52 | return this->g; 53 | } 54 | 55 | int ColorData::getB(){ 56 | return this->b; 57 | } 58 | 59 | double ColorData::getH(){ 60 | return this->h; 61 | } 62 | 63 | double ColorData::getS(){ 64 | return this->s; 65 | } 66 | 67 | double ColorData::getV(){ 68 | return this->v; 69 | } -------------------------------------------------------------------------------- /src/ColorData.h: -------------------------------------------------------------------------------- 1 | /* 2 | ColorData.h - Library for defining and storing 3 | raw values from string, sent by the app. 4 | Created by Thoby L. Noorhalim. 5 | 1 September 2021. 6 | */ 7 | 8 | #ifndef COLOR_DATA_H 9 | #define COLOR_DATA_H 10 | 11 | #include 12 | 13 | class ColorData{ 14 | private: 15 | int a = 0; 16 | int r = 0; 17 | int g = 0; 18 | int b = 0; 19 | double h = 0.0; 20 | double s = 0.0; 21 | double v = 0.0; 22 | 23 | public: 24 | // ---------- Constructor ---------- 25 | ColorData(); 26 | 27 | // ---------- Setters ---------- 28 | void setA(std::string a); 29 | void setR(std::string r); 30 | void setG(std::string g); 31 | void setB(std::string b); 32 | void setH(std::string h); 33 | void setS(std::string s); 34 | void setV(std::string v); 35 | 36 | 37 | // ---------- Getters ---------- 38 | int getA(); 39 | int getR(); 40 | int getG(); 41 | int getB(); 42 | double getH(); 43 | double getS(); 44 | double getV(); 45 | }; 46 | 47 | #endif -------------------------------------------------------------------------------- /src/ColorPicker.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Class definition for ColorPicker.h library. 3 | Created by Thoby L. Noorhalim 4 | 1 September 2021 5 | */ 6 | 7 | #include 8 | 9 | // ---------- Constructor ---------- 10 | ColorPicker::ColorPicker(){}; 11 | 12 | void ColorPicker::updateData(std::vector parsedData){ 13 | setA(parsedData.at(1)); setR(parsedData.at(2)); 14 | setG(parsedData.at(3)); setB(parsedData.at(4)); 15 | setH(parsedData.at(5)); setS(parsedData.at(6)); 16 | setV(parsedData.at(6)); 17 | } -------------------------------------------------------------------------------- /src/ColorPicker.h: -------------------------------------------------------------------------------- 1 | /* 2 | ColorPicker.h - Library for storing and 3 | updating Color data. 4 | Created by Thoby L. Noorhalim. 5 | 1 September 2021. 6 | */ 7 | 8 | #ifndef COLORPICKER_H 9 | #define COLORPICKER_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | class ColorPicker : public ColorData { 16 | public: 17 | // ---------- Constructor ---------- 18 | ColorPicker(); 19 | 20 | void updateData(std::vector parsedData); 21 | }; 22 | 23 | #endif -------------------------------------------------------------------------------- /src/ControllerData.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Class definition for ControllerData.h library. 3 | Created by Thoby L. Noorhalim 4 | 26 August 2021 5 | */ 6 | 7 | #include 8 | 9 | // ---------- Constructor ---------- 10 | ControllerData::ControllerData(){}; 11 | 12 | // ---------- Setters ---------- 13 | void ControllerData::setX(std::string x){ 14 | this->x = stod(x); 15 | } 16 | 17 | void ControllerData::setY(std::string y){ 18 | this->y = stod(y); 19 | } 20 | 21 | void ControllerData::setR(std::string r){ 22 | this->r = stod(r); 23 | } 24 | 25 | void ControllerData::setTheta(std::string theta){ 26 | this->theta = stod(theta); 27 | } 28 | 29 | void ControllerData::setIntensity(std::string intensity){ 30 | this->intensity = stod(intensity); 31 | } 32 | 33 | void ControllerData::setButtonState(std::string state){ 34 | if(state.compare("true") == 0){ 35 | this->buttonState = true; 36 | } else { 37 | this->buttonState = false; 38 | } 39 | } 40 | 41 | 42 | 43 | // ---------- Getters ---------- 44 | double ControllerData::getX(){ 45 | return this->x; 46 | } 47 | 48 | double ControllerData::getY(){ 49 | return this->y; 50 | } 51 | 52 | double ControllerData::getR(){ 53 | return this->r; 54 | } 55 | 56 | double ControllerData::getTheta(){ 57 | return this->theta; 58 | } 59 | 60 | double ControllerData::getIntensity(){ 61 | return this->intensity; 62 | } 63 | 64 | bool ControllerData::getButtonState(){ 65 | return this->buttonState; 66 | } 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/ControllerData.h: -------------------------------------------------------------------------------- 1 | /* 2 | ControllerData.h - Library for defining and storing 3 | raw values from string, sent by the app. 4 | Created by Thoby L. Noorhalim. 5 | 26 August 2021. 6 | Last Update 8 May 2023 7 | */ 8 | 9 | #ifndef CONTROLLER_DATA_H 10 | #define CONTROLLER_DATA_H 11 | 12 | #include 13 | #include 14 | 15 | class ControllerData{ 16 | private: 17 | double r = 0.0; 18 | double theta = 0.0; 19 | double x = 0.0; 20 | double y = 0.0; 21 | double intensity = 0.0; 22 | bool buttonState = false; 23 | 24 | 25 | public: 26 | // ---------- Constructor ---------- 27 | ControllerData(); 28 | 29 | // ---------- Setters ---------- 30 | void setX(std::string x); 31 | void setY(std::string y); 32 | void setR(std::string r); 33 | void setTheta(std::string theta); 34 | void setIntensity(std::string intensity); 35 | void setButtonState(std::string state); 36 | 37 | 38 | // ---------- Getters ---------- 39 | double getX(); 40 | double getY(); 41 | double getR(); 42 | double getTheta(); 43 | double getIntensity(); 44 | bool getButtonState(); 45 | 46 | }; 47 | 48 | #endif -------------------------------------------------------------------------------- /src/InvokController.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Class definition for InvokController.h library. 3 | Created by Thoby L. Noorhalim 4 | 26 August 2021 5 | Last Update 8 May 2023 6 | */ 7 | 8 | #include 9 | 10 | #define WEBSOCKET_POLL 5000 11 | 12 | // LED Blinker Timer 13 | double startTimeLED; 14 | double elapsedTimeLED; 15 | bool ledState = false; 16 | double watchWsTime; 17 | 18 | 19 | // ------------------------------ Constructor ------------------------------ 20 | 21 | /** 22 | *Construct controller object with following parameters: 23 | *- Connection Type, default to websocket 24 | *- Websocket Port, default to 80 25 | *- Debug mode, default to false 26 | */ 27 | Controller::Controller(std::string connectionType, int websocketPort, bool debug){ 28 | this->connectionType = connectionType; 29 | this->websocketPort = websocketPort; 30 | this->debug = debug; 31 | } 32 | 33 | /// Begin Controller routine, setting up Wifi Manager 34 | void Controller::begin(){ 35 | if(this->connectionType == "websocket"){ 36 | // Begin Wifi connection routine 37 | if(debug) Serial.println(F("\n[DEBUG] Starting Controller ...\n")); 38 | 39 | wm.setDebugOutput(debug); 40 | 41 | // Set device as station mode 42 | WiFi.mode(WIFI_STA); 43 | 44 | // Set Internal LED Pin 45 | pinMode(LED_BUILTIN, OUTPUT); 46 | digitalWrite(LED_BUILTIN, LED_ON); 47 | 48 | // Set IP Address 49 | if(debug) Serial.println(F("[DEBUG] Wi-Fi configuration mode, connect to ESP Wi-Fi, and begin setup")); 50 | wm.setAPStaticIPConfig(IPAddress(1,1,1,1), IPAddress(1,1,1,1), IPAddress(255,255,255,0)); 51 | wm.setTimeout(60); 52 | wm.setTitle("ESP Controller"); 53 | bool res = wm.autoConnect(); // auto generated AP name from chipid 54 | 55 | if(!res) { 56 | if(debug) Serial.println(F("[DEBUG] Failed to connect, Entering DEEP SLEEP, Reset to Wake Up")); 57 | ESP.deepSleep(0); 58 | } 59 | else { 60 | //if you get here you have connected to the WiFi 61 | if(debug){ 62 | Serial.printf("[DEBUG] Connected to Wi-Fi, AP [%s], SSID [%s], IP [%s]\n", 63 | wm.getDefaultAPName().c_str(), WiFi.SSID().c_str(), WiFi.localIP().toString().c_str()); 64 | } 65 | 66 | getLocalIP(); 67 | 68 | // Start MDNS Service 69 | mdnsBegin(); 70 | 71 | // Start WebSocket server and assign callback 72 | // Set Websocket server 73 | this->websocket = WebSocketsServer(this->websocketPort); 74 | 75 | // Begin websocket routine 76 | this->websocket.begin(); 77 | this->websocket.onEvent(std::bind(&Controller::onWebSocketEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); 78 | 79 | digitalWrite(LED_BUILTIN, LED_OFF); 80 | startTimeLED = millis(); 81 | } 82 | } 83 | } 84 | 85 | /// Loop routine of controller, Websocket loop executed in this function. 86 | void Controller::loop(){ 87 | if(this->connectionType == "websocket"){ 88 | 89 | // Watch WebSocket Ping 90 | if(millis() - watchWsTime > WEBSOCKET_POLL){ 91 | // No ping detected 92 | if(debug) Serial.print(F("[DEBUG] No Ping detected\n")); 93 | websocket.disconnect(); 94 | watchWsTime = millis(); 95 | } 96 | 97 | this->websocket.loop(); 98 | 99 | } 100 | 101 | // Built in LED blinker 102 | if(!_isConnected){ 103 | #ifdef ESP8266 104 | MDNS.update(); 105 | #endif 106 | elapsedTimeLED = millis() - startTimeLED; 107 | if(elapsedTimeLED > 500){ 108 | ledState = !ledState; 109 | digitalWrite(LED_BUILTIN, ledState); 110 | startTimeLED = millis(); 111 | } 112 | } 113 | 114 | } 115 | 116 | // ------------------------------ Setters ------------------------------ 117 | 118 | void Controller::setWebsocketPort(int port){ 119 | this->websocketPort = port; 120 | } 121 | 122 | void Controller::setDataArrived(bool state){ 123 | this->dataArrived = state; 124 | } 125 | 126 | void Controller::setIncomingCommand(std::string command){ 127 | this->incomingCommand = command; 128 | } 129 | 130 | void Controller::setHostname(std::string name){ 131 | this->hostname = name; 132 | } 133 | 134 | void Controller::setDebugMode(bool state){ 135 | this->debug = state; 136 | } 137 | 138 | // ------------------------------ Getters ------------------------------ 139 | 140 | IPAddress Controller::getLocalIP(){ 141 | this->localIP = WiFi.localIP(); 142 | return WiFi.localIP(); 143 | } 144 | 145 | bool Controller::isConnected(){ 146 | return this->_isConnected; 147 | } 148 | 149 | bool Controller::isDataArrived(){ 150 | return this->dataArrived; 151 | } 152 | 153 | void Controller::print(std::string toPrint){ 154 | if(_isConnected){ 155 | printString = "monitor," + toPrint; 156 | this->websocket.sendTXT(connectedIndex, printString.c_str()); 157 | } 158 | } 159 | 160 | // Return command from controller app serial monitor tool. 161 | std::string Controller::getIncomingCommand(){ 162 | std::string buffer = incomingCommand; 163 | return buffer; 164 | } 165 | 166 | std::string Controller::getHostname(){ 167 | return this->hostname; 168 | } 169 | 170 | // ---------------------------------------- Callback --------------------------------------------- 171 | 172 | /// WebSocket callback routine, any websocket related event will be processed in this function. 173 | void Controller::onWebSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 174 | // Figure out the type of WebSocket event 175 | switch(type) { 176 | 177 | // Client has disconnected 178 | case WStype_DISCONNECTED: 179 | if(debug) Serial.printf("[DEBUG] Client [%u] Disconnected!\n", num); 180 | mdnsBegin(); 181 | this->_isConnected = false; 182 | break; 183 | 184 | // New client has connected 185 | case WStype_CONNECTED: 186 | this->connectedIndex = num; 187 | if(debug){ 188 | IPAddress ip = websocket.remoteIP(num); 189 | Serial.printf("[DEBUG] [%u] Connection from ", num); 190 | Serial.println(ip.toString()); 191 | } 192 | 193 | this->_isConnected = true; 194 | watchWsTime = millis(); 195 | 196 | // Close mDNS 197 | #ifdef ESP8266 198 | MDNS.removeService(getHostname().c_str(), "invc", "tcp"); 199 | #else 200 | mdns_free(); 201 | #endif 202 | 203 | digitalWrite(LED_BUILTIN, LED_OFF); 204 | break; 205 | 206 | // Message Received 207 | case WStype_TEXT: 208 | { 209 | // Cast payload to string 210 | this->message = std::string(reinterpret_cast(const_cast(payload))); 211 | this->dataArrived = true; 212 | 213 | if(debug) Serial.printf("[DEBUG] Message from client: [%s] \n", this->message.c_str()); 214 | 215 | this->parsedDataVector.reserve(10); 216 | this->parsedDataVector = parsecpp(message, ","); 217 | this->command = parsedDataVector[0]; 218 | 219 | if(command.compare("cms") == 0){ 220 | std::string response = "sms," + parsedDataVector[1]; 221 | this->websocket.sendTXT(num, response.c_str()); 222 | response.clear(); 223 | #ifdef DEBUG 224 | onMessageCallback(num, parsedDataVector[1]); 225 | #endif 226 | } else if (command.compare("joystick") == 0){ 227 | // Update Joystick Data 228 | joystick.updateData(parsedDataVector); 229 | } else if (command.compare("cpk") == 0 ){ 230 | // Update Color Data 231 | colorPicker.updateData(parsedDataVector); 232 | } else if (command.compare("bar") == 0 ){ 233 | // Update Button Array Data 234 | buttonArray.updateData(parsedDataVector); 235 | } else if (command.compare("slider") == 0){ 236 | // Update Slider Data 237 | slider.updateData(parsedDataVector); 238 | } else if (command.compare("serial") == 0){ 239 | // Update Incoming Command 240 | if(parsedDataVector[1].compare("initrequest") == 0){ 241 | std::string ip = this->localIP.toString().c_str(); 242 | std::string initResponse = "Connected to Server " + ip; 243 | this->print(initResponse.c_str()); 244 | } else { 245 | setIncomingCommand(message.substr(parsedDataVector[0].length()+1)); 246 | if(getIncomingCommand() == "reset"){ 247 | wm.resetSettings(); 248 | ESP.restart(); 249 | } 250 | } 251 | } else if (command.compare("motion") == 0){ 252 | // Update Motion Data 253 | motion.updateData(parsedDataVector); 254 | } 255 | } 256 | break; 257 | 258 | // For everything else: do nothing 259 | case WStype_PING: 260 | if(debug) Serial.print(F("[DEBUG] Ping from client\n")); 261 | watchWsTime = millis(); 262 | break; 263 | default: 264 | break; 265 | } 266 | } 267 | 268 | void Controller::onMessageCallback(uint8_t num, std::string message){ 269 | if(debug) Serial.printf("[DEBUG] Channel [%d], Message is %s, echoed to client.\n", num, message.c_str()); 270 | } 271 | 272 | void Controller::printIP(){ 273 | Serial.printf("[DEBUG] Connected to Wi-Fi, IP Address: %s\n", getLocalIP().toString().c_str()); 274 | } 275 | 276 | void Controller::setAuthorisation(std::string user, std::string pass){ 277 | this->websocket.setAuthorization(user.c_str(), pass.c_str()); 278 | } 279 | 280 | std::vector Controller::parsecpp(std::string data, std::string delim){ 281 | std::vector myVector{}; 282 | 283 | myVector.reserve(NUM_OF_DATA); 284 | size_t pos = 0; 285 | 286 | while((pos = data.find(delim)) != std::string::npos){ 287 | myVector.push_back(data.substr(0, pos)); 288 | data.erase(0, pos + delim.length()); 289 | } 290 | // Push last substring to vector 291 | myVector.push_back(data.substr(0)); 292 | return myVector; 293 | } 294 | 295 | /// Begin multicast dns service by registering the hostname, and service type to the network. 296 | void Controller::mdnsBegin(){ 297 | if (!MDNS.begin(getHostname().c_str())) { // Start the mDNS responder for esp8266.local 298 | if(debug) Serial.print(F("[DEBUG] Error setting up MDNS responder!\n")); 299 | } 300 | if(debug) Serial.print(F("[DEBUG] mDNS responder started\n")); 301 | MDNS.addService("invc", "tcp", 80); 302 | startTime = millis(); 303 | } 304 | 305 | -------------------------------------------------------------------------------- /src/InvokController.h: -------------------------------------------------------------------------------- 1 | /* 2 | InvokController.h - Wrapper library based on: 3 | - WiFi.h 4 | - ESP8266WiFi.h 5 | - WebSocketsServer.h 6 | Controller library with WiFi and websocket functionality, 7 | to be used for connecting and processing data from Controller app. 8 | Created by Thoby L. Noorhalim. 9 | 26 August 2021. 10 | Last Update 8 May 2023 11 | */ 12 | 13 | #ifndef INVOKCONTROLLER_H 14 | #define INVOKCONTROLLER_H 15 | 16 | #ifdef ESP32 17 | #define LED_ON 0x1 18 | #define LED_OFF 0x0 19 | #include 20 | #define LED_BUILTIN 2 21 | #endif 22 | 23 | #ifdef ESP8266 24 | #define LED_ON 0x0 25 | #define LED_OFF 0x1 26 | #include 27 | #endif 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define NUM_OF_DATA 15 40 | 41 | class Controller{ 42 | private: 43 | int websocketPort; 44 | std::string connectionType; 45 | IPAddress localIP; 46 | bool _isConnected = false; 47 | std::vector parsedDataVector{}; 48 | std::string command; 49 | bool dataArrived = false; 50 | std::string printString; 51 | uint8_t connectedIndex; 52 | std::string incomingCommand; 53 | std::string hostname; 54 | std::string message; 55 | bool debug; 56 | 57 | public: 58 | // ---------- Constructor ---------- 59 | Controller( 60 | std::string connectionType = "websocket", 61 | int websocketPort = 80, 62 | bool debug = false 63 | ); 64 | 65 | void begin(); 66 | void loop(); 67 | 68 | // ---------- Setters ---------- 69 | void setWifiHostname(std::string hostname); 70 | void setWebsocketPort(int port); 71 | void setAuthorisation(std::string user, std::string pass); 72 | void setMessage(std::string data); 73 | void setDataArrived(bool state); 74 | void print(std::string toPrint); // For serial monitor printing 75 | void setIncomingCommand(std::string command); 76 | void setHostname(std::string name); 77 | void setDebugMode(bool state = false); 78 | 79 | // ---------- Getters ---------- 80 | bool isConnected(); 81 | std::string getMessage(); 82 | bool isDataArrived(); 83 | std::string getIncomingCommand(); 84 | void printIP(); 85 | std::string getHostname(); 86 | 87 | // Functions 88 | void mdnsBegin(); 89 | 90 | // ---------- Callback ---------- 91 | void onWebSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length); 92 | void onMessageCallback(uint8_t num, std::string message); 93 | 94 | std::vector parsecpp(std::string data, std::string delim); 95 | IPAddress getLocalIP(); 96 | 97 | // ---------- Object ----------- 98 | WebSocketsServer websocket = WebSocketsServer(80); 99 | Joystick joystick; 100 | ColorPicker colorPicker; 101 | ButtonArray buttonArray; 102 | Slider slider; 103 | Motion motion; 104 | WiFiManager wm; 105 | 106 | // Timer 107 | double startTime; 108 | }; 109 | 110 | #endif -------------------------------------------------------------------------------- /src/Joystick.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Class definition for Joystick.h library. 3 | Created by Thoby L. Noorhalim 4 | 26 August 2021 5 | */ 6 | 7 | #include 8 | 9 | // ---------- Constructor ---------- 10 | Joystick::Joystick(){}; 11 | 12 | void Joystick::updateData(std::vector parsedData){ 13 | setX(parsedData.at(1)); setY(parsedData.at(2)); 14 | setR(parsedData.at(3)); setTheta(parsedData.at(4)); 15 | setIntensity(parsedData.at(5)); 16 | setButtonState(parsedData.at(6)); 17 | } -------------------------------------------------------------------------------- /src/Joystick.h: -------------------------------------------------------------------------------- 1 | /* 2 | Joystick.h - Library for storing and 3 | updating Joystick data. 4 | Created by Thoby L. Noorhalim. 5 | 26 August 2021. 6 | */ 7 | 8 | #ifndef JOYSTICK_H 9 | #define JOYSTICK_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | class Joystick : public ControllerData { 16 | public: 17 | // ---------- Constructor ---------- 18 | Joystick(); 19 | 20 | void updateData(std::vector parsedData); 21 | }; 22 | 23 | #endif -------------------------------------------------------------------------------- /src/Motion.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Class definition for Motion.h library. 3 | Created by Thoby L. Noorhalim 4 | 6 May 2023 5 | */ 6 | 7 | #include 8 | 9 | // ---------- Constructor ---------- 10 | Motion::Motion(){}; 11 | 12 | void Motion::updateData(std::vector parsedData){ 13 | setX(parsedData.at(1)); setY(parsedData.at(2)); 14 | setR(parsedData.at(3)); setTheta(parsedData.at(4)); 15 | setIntensity(parsedData.at(5)); 16 | } -------------------------------------------------------------------------------- /src/Motion.h: -------------------------------------------------------------------------------- 1 | /* 2 | Motion.h - Library for storing and 3 | updating Motion data. 4 | Created by Thoby L. Noorhalim. 5 | 6 May 2023. 6 | */ 7 | 8 | #ifndef MOTION_H 9 | #define MOTION_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | class Motion : public ControllerData { 16 | public: 17 | // ---------- Constructor ---------- 18 | Motion(); 19 | 20 | void updateData(std::vector parsedData); 21 | }; 22 | 23 | #endif -------------------------------------------------------------------------------- /src/Slider.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Class definition for Slider.h library. 3 | Created by Thoby L. Noorhalim 4 | 28 September 2021 5 | */ 6 | 7 | #include 8 | 9 | // ---------- Constructor ---------- 10 | Slider::Slider(){}; 11 | 12 | void Slider::updateData(std::vector parsedData){ 13 | for (size_t i = 0; i < (sizeof(this->sliderData)/sizeof(this->sliderData[0])); i++) 14 | { 15 | this->sliderData[i] = stod(parsedData.at(i+1)); 16 | } 17 | } 18 | 19 | double Slider::getSliderData(int whichSlider){ 20 | return this->sliderData[whichSlider]; 21 | } -------------------------------------------------------------------------------- /src/Slider.h: -------------------------------------------------------------------------------- 1 | /* 2 | Slider.h - Library for storing and 3 | updating Slider data. 4 | Created by Thoby L. Noorhalim. 5 | 28 September 2021. 6 | */ 7 | 8 | #ifndef SLIDER_H 9 | #define SLIDER_H 10 | 11 | #include 12 | #include 13 | 14 | 15 | class Slider { 16 | private: 17 | double sliderData[6] = {0.0}; 18 | 19 | public: 20 | // ---------- Constructor ---------- 21 | Slider(); 22 | 23 | void updateData(std::vector parsedData); 24 | double getSliderData(int whichSlider); 25 | }; 26 | 27 | #endif --------------------------------------------------------------------------------