fix(board): add APOTA to senseBox Eye
This commit is contained in:
parent
6a33f0bfc1
commit
76210797ed
4 changed files with 343 additions and 11 deletions
|
|
@ -41448,7 +41448,7 @@ sensebox_eye.menu.PartitionScheme.tinyuf2=TinyUF2 Compatibility (2MB APP/12MB FF
|
||||||
sensebox_eye.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader_tinyuf2
|
sensebox_eye.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader_tinyuf2
|
||||||
sensebox_eye.menu.PartitionScheme.tinyuf2.build.custom_partitions=partitions_tinyuf2
|
sensebox_eye.menu.PartitionScheme.tinyuf2.build.custom_partitions=partitions_tinyuf2
|
||||||
sensebox_eye.menu.PartitionScheme.tinyuf2.upload.maximum_size=2097152
|
sensebox_eye.menu.PartitionScheme.tinyuf2.upload.maximum_size=2097152
|
||||||
sensebox_eye.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x410000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin"
|
sensebox_eye.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x410000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" 0x210000 "{runtime.platform.path}/variants/{build.variant}/APOTA.bin"
|
||||||
sensebox_eye.menu.PartitionScheme.gen4esp32scheme4=Huge App (16MB APP)
|
sensebox_eye.menu.PartitionScheme.gen4esp32scheme4=Huge App (16MB APP)
|
||||||
sensebox_eye.menu.PartitionScheme.gen4esp32scheme4.build.custom_partitions=gen4esp32_16MBapp
|
sensebox_eye.menu.PartitionScheme.gen4esp32scheme4.build.custom_partitions=gen4esp32_16MBapp
|
||||||
sensebox_eye.menu.PartitionScheme.gen4esp32scheme4.upload.maximum_size=16646144
|
sensebox_eye.menu.PartitionScheme.gen4esp32scheme4.upload.maximum_size=16646144
|
||||||
|
|
|
||||||
BIN
variants/sensebox_eye/APOTA.bin
Normal file
BIN
variants/sensebox_eye/APOTA.bin
Normal file
Binary file not shown.
287
variants/sensebox_eye/APOTA.ino
Normal file
287
variants/sensebox_eye/APOTA.ino
Normal file
|
|
@ -0,0 +1,287 @@
|
||||||
|
// APOTA is a arduino fallback sketch that is written to OTA1_Partition.
|
||||||
|
// APOTA opens an access point which waits to receive a .binfile on /sketch.
|
||||||
|
// After succesful upload, the file is written to OTA0_Partition and the microcontroller reboots to the newly uploaded sketch.
|
||||||
|
|
||||||
|
#define DISPLAY_ENABLED
|
||||||
|
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <WebServer.h>
|
||||||
|
#include <ESPmDNS.h>
|
||||||
|
#include <WiFiAP.h>
|
||||||
|
#include <Update.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#ifdef DISPLAY_ENABLED
|
||||||
|
#define SCREEN_WIDTH 128
|
||||||
|
#define SCREEN_HEIGHT 64
|
||||||
|
#define OLED_RESET -1
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <Adafruit_SSD1306.h>
|
||||||
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||||
|
#include <Adafruit_NeoPixel.h>
|
||||||
|
Adafruit_NeoPixel rgb_led_1 = Adafruit_NeoPixel(1, 1, NEO_GRB + NEO_KHZ800);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#include "esp_partition.h"
|
||||||
|
#include "esp_ota_ops.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
|
||||||
|
String ssid;
|
||||||
|
uint8_t mac[6];
|
||||||
|
|
||||||
|
// Create an instance of the server
|
||||||
|
WebServer server(80);
|
||||||
|
bool displayEnabled;
|
||||||
|
|
||||||
|
const int BUTTON_PIN = 0; // GPIO for the button
|
||||||
|
volatile unsigned long lastPressTime = 0; // Time of last button press
|
||||||
|
volatile bool doublePressDetected = false; // Flag for double press
|
||||||
|
const unsigned long doublePressInterval = 500; // Max. time (in ms) between two presses for double press
|
||||||
|
volatile int pressCount = 0; // Counts the button presses
|
||||||
|
|
||||||
|
const unsigned char epd_bitmap_wifi[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0xff, 0x00, 0x00,
|
||||||
|
0x00, 0x3f, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x7c, 0x00, 0x03, 0xe0, 0x00, 0x00, 0xf0, 0x00, 0x01, 0xf0, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x78, 0x00,
|
||||||
|
0x03, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x07, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x7f, 0xe0, 0x0e, 0x00,
|
||||||
|
0x0c, 0x01, 0xff, 0xf0, 0x06, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x02, 0x00, 0x00, 0x0f, 0x80, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x0f, 0x00, 0x00,
|
||||||
|
0x00, 0x1c, 0x00, 0x07, 0x80, 0x00, 0x00, 0x38, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x70, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x70, 0x00, 0x00, 0xc0, 0x00,
|
||||||
|
0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x78, 0x00, 0x00, 0x00, 0x03, 0x80, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
// 'checkmark', 44x44px
|
||||||
|
const unsigned char epd_bitmap_checkmark[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x00,
|
||||||
|
0x00, 0x0f, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x07, 0xc7, 0x80, 0x00, 0x00, 0x00, 0x03, 0xef, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
void IRAM_ATTR handleButtonPress() {
|
||||||
|
unsigned long currentTime = millis(); // Get current time
|
||||||
|
|
||||||
|
// Debounce: If the current press is too close to the last one, ignore it
|
||||||
|
if (currentTime - lastPressTime > 50) {
|
||||||
|
pressCount++; // Count the button press
|
||||||
|
|
||||||
|
// Check if this is the second press within the double-press interval
|
||||||
|
if (pressCount == 2 && (currentTime - lastPressTime <= doublePressInterval)) {
|
||||||
|
doublePressDetected = true; // Double press detected
|
||||||
|
pressCount = 0; // Reset counter
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPressTime = currentTime; // Update the time of the last press
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to switch the boot partition to OTA1
|
||||||
|
void setBootPartitionToOTA0() {
|
||||||
|
const esp_partition_t *ota0_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL);
|
||||||
|
|
||||||
|
if (ota0_partition) {
|
||||||
|
// Set OTA1 as new boot partition
|
||||||
|
esp_ota_set_boot_partition(ota0_partition);
|
||||||
|
Serial.println("Boot partition changed to OTA0. Restarting...");
|
||||||
|
|
||||||
|
// Restart to boot from the new partition
|
||||||
|
esp_restart();
|
||||||
|
} else {
|
||||||
|
Serial.println("OTA1 partition not found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupDisplay() {
|
||||||
|
displayEnabled = display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
|
||||||
|
if (displayEnabled) {
|
||||||
|
display.display();
|
||||||
|
delay(100);
|
||||||
|
display.clearDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayStatusBar(int progress) {
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setCursor(24, 8);
|
||||||
|
display.println("Sketch wird");
|
||||||
|
display.setCursor(22, 22);
|
||||||
|
display.println("hochgeladen!");
|
||||||
|
|
||||||
|
display.fillRect(0, SCREEN_HEIGHT - 24, SCREEN_WIDTH - 4, 8, BLACK); // Clear status bar area
|
||||||
|
display.drawRect(0, SCREEN_HEIGHT - 24, SCREEN_WIDTH - 4, 8, WHITE); // Draw border
|
||||||
|
int filledWidth = (progress * SCREEN_WIDTH - 4) / 100; // Calculate progress width
|
||||||
|
display.fillRect(1, SCREEN_HEIGHT - 23, filledWidth - 4, 6, WHITE); // Fill progress bar
|
||||||
|
|
||||||
|
display.setCursor((SCREEN_WIDTH / 2) - 12, SCREEN_HEIGHT - 10);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
display.print(progress);
|
||||||
|
display.println(" %");
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayWelcomeScreen() {
|
||||||
|
display.clearDisplay();
|
||||||
|
|
||||||
|
// Draw WiFi symbol
|
||||||
|
display.drawBitmap(0, 12, epd_bitmap_wifi, 44, 44, WHITE);
|
||||||
|
|
||||||
|
// Display SSID text
|
||||||
|
display.setCursor(40, 13);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
display.println("Verbinde dich"); // "Connect"
|
||||||
|
display.setCursor(60, 27);
|
||||||
|
display.println("mit:"); // "with"
|
||||||
|
|
||||||
|
// Display SSID
|
||||||
|
display.setCursor(40, 43);
|
||||||
|
display.setTextSize(1); // Larger text for SSID
|
||||||
|
display.print(ssid);
|
||||||
|
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void displaySuccessScreen() {
|
||||||
|
display.clearDisplay();
|
||||||
|
|
||||||
|
// Draw WiFi symbol
|
||||||
|
display.drawBitmap(0, 12, epd_bitmap_checkmark, 44, 44, WHITE);
|
||||||
|
|
||||||
|
// Display SSID text
|
||||||
|
display.setCursor(48, 22);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
display.println("Erfolgreich"); // "Successfully"
|
||||||
|
display.setCursor(48, 36);
|
||||||
|
display.println("hochgeladen!"); // "uploaded!"
|
||||||
|
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wipeDisplay() {
|
||||||
|
display.clearDisplay();
|
||||||
|
display.println("");
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupWiFi() {
|
||||||
|
WiFi.macAddress(mac);
|
||||||
|
char macLastFour[5];
|
||||||
|
snprintf(macLastFour, sizeof(macLastFour), "%02X%02X", mac[4], mac[5]);
|
||||||
|
ssid = "senseBox:" + String(macLastFour);
|
||||||
|
|
||||||
|
// Define the IP address, gateway, and subnet mask
|
||||||
|
IPAddress local_IP(192, 168, 1, 1); // The new IP address
|
||||||
|
IPAddress gateway(192, 168, 1, 1); // Gateway address (can be the same as the AP's IP)
|
||||||
|
IPAddress subnet(255, 255, 255, 0); // Subnet mask
|
||||||
|
|
||||||
|
// Set the IP address, gateway, and subnet mask of the access point
|
||||||
|
WiFi.softAPConfig(local_IP, gateway, subnet);
|
||||||
|
|
||||||
|
// Start the access point
|
||||||
|
WiFi.softAP(ssid.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupOTA() {
|
||||||
|
// Handle updating process
|
||||||
|
server.on(
|
||||||
|
"/sketch", HTTP_POST,
|
||||||
|
[]() {
|
||||||
|
server.sendHeader("Connection", "close");
|
||||||
|
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
|
||||||
|
ESP.restart();
|
||||||
|
},
|
||||||
|
[]() {
|
||||||
|
HTTPUpload &upload = server.upload();
|
||||||
|
|
||||||
|
if (upload.status == UPLOAD_FILE_START) {
|
||||||
|
Serial.setDebugOutput(true);
|
||||||
|
size_t fsize = UPDATE_SIZE_UNKNOWN;
|
||||||
|
if (server.clientContentLength() > 0) {
|
||||||
|
fsize = server.clientContentLength();
|
||||||
|
}
|
||||||
|
Serial.printf("Receiving Update: %s, Size: %d\n", upload.filename.c_str(), fsize);
|
||||||
|
|
||||||
|
Serial.printf("Update: %s\n", upload.filename.c_str());
|
||||||
|
if (!Update.begin(fsize)) { //start with max available size
|
||||||
|
Update.printError(Serial);
|
||||||
|
}
|
||||||
|
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
||||||
|
/* flashing firmware to ESP*/
|
||||||
|
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
||||||
|
Update.printError(Serial);
|
||||||
|
} else {
|
||||||
|
int progress = (Update.progress() * 100) / Update.size();
|
||||||
|
displayStatusBar(progress); // Update progress on status bar
|
||||||
|
}
|
||||||
|
} else if (upload.status == UPLOAD_FILE_END) {
|
||||||
|
if (Update.end(true)) { //true to set the size to the current progress
|
||||||
|
displaySuccessScreen();
|
||||||
|
delay(3000);
|
||||||
|
wipeDisplay();
|
||||||
|
} else {
|
||||||
|
Update.printError(Serial);
|
||||||
|
}
|
||||||
|
Serial.setDebugOutput(false);
|
||||||
|
}
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Start Serial communication
|
||||||
|
Serial.begin(115200);
|
||||||
|
rgb_led_1.begin();
|
||||||
|
rgb_led_1.setBrightness(30);
|
||||||
|
rgb_led_1.setPixelColor(0, rgb_led_1.Color(51, 51, 255));
|
||||||
|
rgb_led_1.show();
|
||||||
|
|
||||||
|
// Configure button pin as input
|
||||||
|
pinMode(BUTTON_PIN, INPUT_PULLUP);
|
||||||
|
|
||||||
|
// Interrupt for the button
|
||||||
|
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleButtonPress, FALLING);
|
||||||
|
|
||||||
|
#ifdef DISPLAY_ENABLED
|
||||||
|
setupDisplay();
|
||||||
|
#endif
|
||||||
|
setupWiFi();
|
||||||
|
// Set the ESP32 as an access point
|
||||||
|
setupOTA();
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Handle client requests
|
||||||
|
server.handleClient();
|
||||||
|
|
||||||
|
#ifdef DISPLAY_ENABLED
|
||||||
|
displayWelcomeScreen();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (doublePressDetected) {
|
||||||
|
Serial.println("Doppeldruck erkannt!"); // "Double press detected!"
|
||||||
|
setBootPartitionToOTA0();
|
||||||
|
#ifdef DISPLAY_ENABLED
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
display.println("");
|
||||||
|
display.display();
|
||||||
|
delay(50);
|
||||||
|
#endif
|
||||||
|
// Restart to boot from the new partition
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,9 +26,25 @@
|
||||||
#include "pins_arduino.h"
|
#include "pins_arduino.h"
|
||||||
#include "driver/rmt_tx.h"
|
#include "driver/rmt_tx.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "esp_partition.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_ota_ops.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
void blinkLED(uint8_t color[3], rmt_channel_handle_t led_chan, rmt_encoder_handle_t ws2812_encoder, rmt_transmit_config_t tx_config) {
|
||||||
|
ESP_ERROR_CHECK(rmt_transmit(led_chan, ws2812_encoder, color, sizeof(color), &tx_config));
|
||||||
|
rmt_tx_wait_all_done(led_chan, portMAX_DELAY);
|
||||||
|
|
||||||
|
// Wait a moment
|
||||||
|
delay(50);
|
||||||
|
|
||||||
|
// Turn LED off
|
||||||
|
uint8_t pixel_off[3] = { 0x00, 0x00, 0x00 };
|
||||||
|
ESP_ERROR_CHECK(rmt_transmit(led_chan, ws2812_encoder, pixel_off, sizeof(pixel_off), &tx_config));
|
||||||
|
rmt_tx_wait_all_done(led_chan, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
void initVariant(void) {
|
void initVariant(void) {
|
||||||
rmt_channel_handle_t led_chan = NULL;
|
rmt_channel_handle_t led_chan = NULL;
|
||||||
rmt_tx_channel_config_t tx_chan_config = {};
|
rmt_tx_channel_config_t tx_chan_config = {};
|
||||||
|
|
@ -52,20 +68,49 @@ void initVariant(void) {
|
||||||
|
|
||||||
ESP_ERROR_CHECK(rmt_enable(led_chan));
|
ESP_ERROR_CHECK(rmt_enable(led_chan));
|
||||||
|
|
||||||
// WS2812 GRB data (green pixel)
|
|
||||||
uint8_t pixel[3] = { 0x10, 0x00, 0x00 }; // green
|
|
||||||
rmt_transmit_config_t tx_config = {
|
rmt_transmit_config_t tx_config = {
|
||||||
.loop_count = 0
|
.loop_count = 0
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(rmt_transmit(led_chan, ws2812_encoder, pixel, sizeof(pixel), &tx_config));
|
|
||||||
rmt_tx_wait_all_done(led_chan, portMAX_DELAY);
|
|
||||||
|
|
||||||
// Wait a moment
|
uint8_t pixel[3] = { 0x10, 0x00, 0x00 }; // green
|
||||||
delay(50);
|
blinkLED(pixel, led_chan, ws2812_encoder, tx_config);
|
||||||
|
|
||||||
// Turn LED off
|
// define button pin
|
||||||
uint8_t pixel_off[3] = { 0x00, 0x00, 0x00 };
|
pinMode(0, INPUT_PULLUP);
|
||||||
ESP_ERROR_CHECK(rmt_transmit(led_chan, ws2812_encoder, pixel_off, sizeof(pixel_off), &tx_config));
|
|
||||||
rmt_tx_wait_all_done(led_chan, portMAX_DELAY);
|
// keep button pressed
|
||||||
|
unsigned long pressStartTime = 0;
|
||||||
|
bool buttonPressed = false;
|
||||||
|
|
||||||
|
// Wait 3.5 seconds for the button to be pressed
|
||||||
|
unsigned long startTime = millis();
|
||||||
|
|
||||||
|
// Check if button is pressed
|
||||||
|
while (millis() - startTime < 3500) {
|
||||||
|
if (digitalRead(0) == LOW) {
|
||||||
|
if (!buttonPressed) {
|
||||||
|
// The button was pressed
|
||||||
|
buttonPressed = true;
|
||||||
|
}
|
||||||
|
} else if (buttonPressed) {
|
||||||
|
// When the button is pressed and then released, boot into the OTA1 partition
|
||||||
|
const esp_partition_t *ota1_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL);
|
||||||
|
|
||||||
|
if (ota1_partition) {
|
||||||
|
esp_err_t err = esp_ota_set_boot_partition(ota1_partition);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
uint8_t pixel[3] = { 0x00, 0x00, 0x10 }; // blue
|
||||||
|
blinkLED(pixel, led_chan, ws2812_encoder, tx_config);
|
||||||
|
esp_restart(); // restart, to boot OTA1 partition
|
||||||
|
} else {
|
||||||
|
uint8_t pixel[3] = { 0x00, 0x10, 0x00 }; // red
|
||||||
|
blinkLED(pixel, led_chan, ws2812_encoder, tx_config);
|
||||||
|
ESP_LOGE("OTA", "Error setting OTA1 partition: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Abort after releasing the button
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue