diff --git a/.github/workflows/arduino-lint.yml b/.github/workflows/arduino-lint.yml index 258ac58..63b60dd 100644 --- a/.github/workflows/arduino-lint.yml +++ b/.github/workflows/arduino-lint.yml @@ -4,4 +4,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: arduino/arduino-lint-action@v1 \ No newline at end of file + - uses: arduino/arduino-lint-action@v1 + with: + library-manager: update \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d41fe2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +src/.* +.vscode/** \ No newline at end of file diff --git a/blite b/blite new file mode 160000 index 0000000..8b27afd --- /dev/null +++ b/blite @@ -0,0 +1 @@ +Subproject commit 8b27afd245858a26cc0c139a7b03fc9ecd59eca6 diff --git a/examples/08_distance_measuring/08_distance_measuring.ino b/examples/08_distance_measuring/08_distance_measuring.ino index 31b76bb..6a1b10e 100644 --- a/examples/08_distance_measuring/08_distance_measuring.ino +++ b/examples/08_distance_measuring/08_distance_measuring.ino @@ -1,4 +1,4 @@ -#include "blite.h" +#include //define sound velocity in cm/uS #define SOUND_VELOCITY 0.034 diff --git a/examples/13_rgb_web_control/13_rgb_web_control.ino b/examples/13_rgb_web_control/13_rgb_web_control.ino index 94897cd..34065d1 100644 --- a/examples/13_rgb_web_control/13_rgb_web_control.ino +++ b/examples/13_rgb_web_control/13_rgb_web_control.ino @@ -1,150 +1,52 @@ -#include -#include +#include #include -#include +#include +#include "lighting.h" #include - -// Webserver Config -const char *ssid = "ZTE_2.4G_6eZrkS"; -const char *password = "ijF3kXh4"; -ESP8266WebServer server ( 80 ); - // Neopixel Config -#define NeoPIN D4 +#define NeoPIN 2 #define NUM_LEDS 16 + int brightness = 150; Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, NeoPIN, NEO_RGB + NEO_KHZ800); - - +Blite mybot; +ESP8266WebServer wifiRemoteControl(80); +WebSocketsServer webSocket = WebSocketsServer(81); // WebSocket server on port 81 const int led = 13; -void setup ( void ) { - - Serial.begin ( 115200 ); - - // ############## - // NeoPixel start - Serial.println(); - strip.setBrightness(brightness); - strip.begin(); - strip.show(); - delay(50); - Serial.println("NeoPixel started"); - - // ######### - // Webserver - pinMode ( led, OUTPUT ); - digitalWrite ( led, 0 ); - - WiFi.begin ( ssid, password ); - Serial.println ( "" ); - - // Wait for connection - while ( WiFi.status() != WL_CONNECTED ) { - delay ( 500 ); - Serial.print ( "." ); - } - - Serial.println ( "" ); - Serial.print ( "Connected to " ); - Serial.println ( ssid ); - Serial.print ( "IP address: " ); - Serial.println ( WiFi.localIP() ); - - if ( MDNS.begin ( "esp8266" ) ) { - Serial.println ( "MDNS responder started" ); - } - - // what to do with requests - server.on ( "/", handleRoot ); - server.onNotFound ( handleNotFound ); - server.begin(); - - - - Serial.println ( "HTTP server started" ); -} - -void loop ( void ) { - // waiting fo a client - server.handleClient(); +void setup(){ + mybot.setup(); + Serial.begin(115200); + mybot.smartConnectWiFi(); + webSocket.begin(); + webSocket.onEvent(webSocketEvent); + wifiRemoteControl.on("/", HTTP_GET, []() { + Serial.println("Web Server: received a web page request"); + String html = HTML_LIGHT; + wifiRemoteControl.send(200, "text/html", html); + }); + wifiRemoteControl.begin(); + } - -void handleRoot() { - Serial.println("Client connected"); - digitalWrite ( led, 1 ); - - // data from the colorpicker (e.g. #FF00FF) - String color = server.arg("c"); - Serial.println("Color: " + color); - // setting the color to the strip - setNeoColor(color); - - // building a website - char temp[5000]; - int sec = millis() / 1000; - int min = sec / 60; - int hr = min / 60; - char clr [7]; - color.toCharArray(clr, 7); - snprintf ( temp, 5000, - -"\n\n\ - \n\ - wifi pixel\n\ - \n\ - \n\ - \n\ - \n\ -

Buildybee

\n\ -

pick the color!

\n\ - \n\ -
\n\ - \n\ -   \n\ -
\n\ - \n\ - \ -", - - hr, min % 60, sec % 60, clr - ); - server.send ( 200, "text/html", temp ); - digitalWrite ( led, 0 ); +void loop(){ + wifiRemoteControl.handleClient(); + webSocket.loop(); + } -void handleNotFound() { - digitalWrite ( led, 1 ); - String message = "File Not Found\n\n"; - message += "URI: "; - message += server.uri(); - message += "\nMethod: "; - message += ( server.method() == HTTP_GET ) ? "GET" : "POST"; - message += "\nArguments: "; - message += server.args(); - message += "\n"; - - for ( uint8_t i = 0; i < server.args(); i++ ) { - message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n"; - } - - server.send ( 404, "text/plain", message ); - digitalWrite ( led, 0 ); +void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { + String command = String((char*)payload); + Serial.print("command: "); + Serial.println(command); + // setting the color to the strip + setNeoColor(command); } - - void setNeoColor(String value){ Serial.print("Setting Neopixel..."); // converting Hex to Int - int number = (int) strtol( &value[1], NULL, 16); - + int number = (int) strtol( &value[1], NULL, 16); // splitting into three parts int r = number >> 16; int g = number >> 8 & 0xFF; @@ -167,4 +69,4 @@ void setNeoColor(String value){ strip.show(); Serial.println("on."); -} \ No newline at end of file +} diff --git a/examples/13_rgb_web_control/lighting.h b/examples/13_rgb_web_control/lighting.h new file mode 100644 index 0000000..a3a3765 --- /dev/null +++ b/examples/13_rgb_web_control/lighting.h @@ -0,0 +1,75 @@ +const char *HTML_LIGHT = R"=====( + + + + wifi pixel + + + + + +

Buildybee

+

pick the color!

+

+   +

+

+ WebSocket : closed +
+

+ + +)====="; \ No newline at end of file diff --git a/examples/14_blite_rc_car/14_blite_rc_car.ino b/examples/14_blite_rc_car/14_blite_rc_car.ino index 8c70a84..1e71f3f 100644 --- a/examples/14_blite_rc_car/14_blite_rc_car.ino +++ b/examples/14_blite_rc_car/14_blite_rc_car.ino @@ -1,24 +1,97 @@ #include +#include +#include #include "remote.h" -Blite myBot; +#define CMD_BACKWARD 2 +#define CMD_STOP 0 +#define CMD_FORWARD 1 +#define CMD_LEFT 4 +#define CMD_RIGHT 8 +#define CMD_PUSH 5 +#define CMD_SRVCLCK 6 +#define CMD_SRVACLCK 9 + + +Blite mybot; ESP8266WebServer wifiRemoteControl(80); +WebSocketsServer webSocket = WebSocketsServer(81); // WebSocket server on port 81 +void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { + switch (type) { + case WStype_DISCONNECTED: + Serial.printf("[%u] Disconnected!\n", num); + break; + case WStype_CONNECTED: + { + IPAddress ip = webSocket.remoteIP(num); + Serial.printf("[%u] Connected from %d.%d.%d.%d\n", num, ip[0], ip[1], ip[2], ip[3]); + } + break; + case WStype_TEXT: + //Serial.printf("[%u] Received text: %s\n", num, payload); + String angle = String((char*)payload); + int command = angle.toInt(); + Serial.print("command: "); + Serial.println(command); + + switch (command) { + case CMD_STOP: + Serial.println("Stop"); + mybot.stopMotor(); + break; + case CMD_FORWARD: + Serial.println("Move Forward"); + mybot.moveForward(); + break; + case CMD_BACKWARD: + Serial.println("Move Backward"); + mybot.moveBackward(); + break; + case CMD_LEFT: + Serial.println("Turn Left"); + mybot.turnLeft(); + break; + case CMD_RIGHT: + Serial.println("Turn Right"); + mybot.turnRight(); + break; + case CMD_PUSH: + Serial.println("Push button pressed"); + //mybot.push(); + break; + case CMD_SRVCLCK: + Serial.println("Turn servo clockwise"); + //mybot.turnServoClockwise(); + break; + case CMD_SRVACLCK: + Serial.println("Turn servo anti-clockwise"); + //mybot.turnServoAntiClockwise(); + break; + default: + Serial.println("Unknown command"); + } + + break; + } +} + void setup(){ - myBot.setup(); + mybot.setup(); Serial.begin(115200); - myBot.smartConnectWiFi(); + mybot.smartConnectWiFi(); + webSocket.begin(); + webSocket.onEvent(webSocketEvent); wifiRemoteControl.on("/", HTTP_GET, []() { - Serial.println("Web Server: received a web page request"); - String html = REMOTE_HTML_CONTENT; - wifiRemoteControl.send(200, "text/html", html); - }); - wifiRemoteControl.begin(); + Serial.println("Web Server: received a web page request"); + String html = REMOTE_HTML_CONTENT; + wifiRemoteControl.send(200, "text/html", html); + }); + wifiRemoteControl.begin(); + } void loop(){ wifiRemoteControl.handleClient(); - if (myBot.buttonPressed()){ - myBot.blinkLed(2); - } -} + webSocket.loop(); +} diff --git a/examples/14_blite_rc_car/remote.h b/examples/14_blite_rc_car/remote.h index 149a560..bccb1ff 100644 --- a/examples/14_blite_rc_car/remote.h +++ b/examples/14_blite_rc_car/remote.h @@ -8,57 +8,110 @@ const char *REMOTE_HTML_CONTENT = R"=====( - - -

Blite - RC car control

-
-
-
-
-
-
-
-
-
- - - \ No newline at end of file diff --git a/library.properties b/library.properties index ae611e8..580e066 100644 --- a/library.properties +++ b/library.properties @@ -6,4 +6,4 @@ sentence=Dev kit for buildybee blite breakout board paragraph=Develop easily with buildybee devikits url=https://github.com/buildybee/blite.git architectures=esp8266 -depends=WiFiManager \ No newline at end of file +depends=WiFiManager,WebSockets \ No newline at end of file diff --git a/src/blite.cpp b/src/blite.cpp index 8a9d72c..4152789 100644 --- a/src/blite.cpp +++ b/src/blite.cpp @@ -9,6 +9,10 @@ int Blite::getIO(const char * io){ return I2C_SCL; } else if (io == "sda"){ return I2C_SDA; + } else if (io == "io3") { + return I2C_SCL; + } else if (io == "io4"){ + return I2C_SDA; } return -1; @@ -20,28 +24,28 @@ void Blite::reversePolarityM34(){ this->defineM34(false); } void Blite::moveForward(){ - analogWrite(m1,speed); - digitalWrite(m2,LOW); - analogWrite(m4,speed); - digitalWrite(m3,LOW); + analogWrite(this->m1,this->speed); + digitalWrite(this->m2,LOW); + analogWrite(this->m4,this->speed); + digitalWrite(this->m3,LOW); } void Blite::moveBackward(){ - analogWrite(m2,speed); - digitalWrite(m1,LOW); - analogWrite(m3,speed); - digitalWrite(m4,LOW); + analogWrite(this->m2,this->speed); + digitalWrite(this->m1,LOW); + analogWrite(this->m3,this->speed); + digitalWrite(this->m4,LOW); } void Blite::turnRight(){ - digitalWrite(m1,LOW); - digitalWrite(m2,LOW); - analogWrite(m4,speed); - digitalWrite(m3,LOW); + digitalWrite(this->m1,LOW); + digitalWrite(this->m2,LOW); + analogWrite(this->m4,this->speed); + digitalWrite(this->m3,LOW); } void Blite::turnLeft(){ - analogWrite(m1,speed); - digitalWrite(m2,LOW); - digitalWrite(m3,LOW); - digitalWrite(m4,LOW); + analogWrite(this->m1,this->speed); + digitalWrite(this->m2,LOW); + digitalWrite(this->m3,LOW); + digitalWrite(this->m4,LOW); } void Blite::setSpeed(int s){ this->speed = s ; @@ -96,26 +100,19 @@ bool Blite::buttonPressed() { void Blite::setup(){ pinMode(SW1,INPUT_PULLUP); - pinMode(M12_A,OUTPUT); - pinMode(M12_B,OUTPUT); - pinMode(M34_A,OUTPUT); - pinMode(M34_B,OUTPUT); - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, HIGH); + pinMode(M1,OUTPUT); + pinMode(M2,OUTPUT); + pinMode(M3,OUTPUT); + pinMode(M4,OUTPUT); + this->stopMotor(); this->defineM12(true); this->defineM34(true); + this->speed = 100; + String newHostname = "buildybee"; + WiFi.hostname(newHostname.c_str()); WiFi.disconnect(); WiFi.mode(WIFI_OFF); - - -} - -void Blite::glowLed(bool s){ - if (s){ - digitalWrite(LED_BUILTIN, LOW); - } else{ - digitalWrite(LED_BUILTIN, HIGH); - } + this->otaSetup(); } @@ -130,4 +127,72 @@ void Blite::blinkLed(int c){ int Blite::readADC(){ return analogRead(ADC1); -} \ No newline at end of file +} + +void Blite::setupServer(String &html_content) { + this->webServer.on("/", HTTP_GET, [=]() { + this->webServer.send(200, "text/html", html_content); + }); + this->webServer.begin(); + this->serverSetupDone = true; +} + +void Blite::renderServer() { + this->webServer.handleClient(); + this->otaLoop(); +} + +void Blite::smartRenderServer(String &html_content){ + if (!this->serverSetupDone) { + this->setupServer(html_content); + } + this->renderServer(); +} + +void Blite::otaSetup(){ + + ArduinoOTA.onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) { + type = "sketch"; + } else { // U_FS + type = "filesystem"; + } + + // NOTE: if updating FS this would be the place to unmount FS using FS.end() + Serial.println("Start updating " + type); + }); + ArduinoOTA.onEnd([]() { + Serial.println("\nEnd"); + }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + }); + ArduinoOTA.onError([](ota_error_t error) { + Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) { + Serial.println("Auth Failed"); + } else if (error == OTA_BEGIN_ERROR) { + Serial.println("Begin Failed"); + } else if (error == OTA_CONNECT_ERROR) { + Serial.println("Connect Failed"); + } else if (error == OTA_RECEIVE_ERROR) { + Serial.println("Receive Failed"); + } else if (error == OTA_END_ERROR) { + Serial.println("End Failed"); + } + }); + ArduinoOTA.begin(); +} + +void Blite::otaLoop(){ + ArduinoOTA.handle(); +} + +void Blite::stopMotor(){ + digitalWrite(M1,LOW); + digitalWrite(M2,LOW); + digitalWrite(M3,LOW); + digitalWrite(M4,LOW); + +} diff --git a/src/blite.h b/src/blite.h index c781a0d..3eee2d7 100644 --- a/src/blite.h +++ b/src/blite.h @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include class Blite { public: @@ -31,6 +34,7 @@ void moveForward(); void moveBackward(); void turnRight(); void turnLeft(); +void stopMotor(); void setSpeed(int speed); void reversePolarityM12(); @@ -38,12 +42,21 @@ void reversePolarityM34(); int getIO(const char * io); bool buttonPressed(); -void glowLed(bool s); void blinkLed(int c); int readADC(); +void setupServer(String &html_content); +void renderServer(); +void smartRenderServer(String &html_content); + +void otaSetup(); +void otaLoop(); + private: int m1,m2,m3,m4,speed; +ESP8266WebServer webServer = ESP8266WebServer(80); +bool serverSetupDone = false; + void defineM12(bool polarity){ if (polarity){ this->m1 = M1;