I'm tinkering with an ESP32-Wroom-32 on a school IoT project.
The goal is to create a device with an e-ink screen that displays a qr code which url can be changed through a webpage hosted by the esp32 wifi hotspot.
Both functions work separetely : I can manage to display the qr code and connect to wifi on two different arduino sketches.
But when I try to join them and make the display refresh once an user submits the new url to display, nothing changes on the e-ink monitor. I get a confirmation from the Async web server though.
The setup loops initiliazes the display with a predefined url : when placing the block of code aftet hotspot / server init, nothing happens either but when initilizing the display first and then starting the rest, then it works.
I really don't understand the issue.
The display is a 1.54inch model made by HELTEC https://heltec.org/project/154-e-ink/
Librairies used :
- https://github.com/me-no-dev/ESPAsyncWebServer
- https://github.com/me-no-dev/AsyncTCP
- https://github.com/todd-herbert/heltec-eink-modules
- https://github.com/ricmoo/QRCode/tree/master
Here is my code :
Code: Select all
// Pick your panel - https://github.com/todd-herbert/heltec-eink-modules#supported-displays
// ---------------
#define USING_DEPG0150BNS810 // 1.54" V2 - BW - Red Tab
// #define USING_DEPG0154BNS800 // 1.54" V2 - BW - Red Tab
// #define USING_GDEP015OC1 // 1.54" V2 - BW - Blue Tab
// #define USING_DEPG0213RWS800 // 2.13" V2 - BWR - Red Tab
// #define USING_QYEG0213RWS800 // 2.13" V2 - BWR - Red Tab
// #define USING_DEPG0290BNS75A // 2.9" V2 - BW - Red Tab
// #define USING_DEPG0290BNS800 // 2.9" V2 - BW - Red Tab
// #define USING_GDE029A1 // 2.9" V2 - BW - Blue Tab
#define DISPLAY_RES 200
// Find your wiring - https://github.com/todd-herbert/heltec-eink-modules#wiring
// ----------------
#define DC_PIN 2
#define CS_PIN 4
#define BUSY_PIN 5
// (Example automatically picks the correct class, and color palette)
#if defined USING_DEPG0150BNS810
#define PANEL_CLASS DEPG0150BNS810
#endif
// ------------------------------
// IMPORTS
// ------------------------------
// e-ink lib
#include "heltec-eink-modules.h"
// custom qrcode lib
#include "ricmoo_qrcode.h"
// Find your colors
// ----------------
static unsigned int BGCOLOR = WHITE;
static unsigned int ACCENT1 = BLACK;;
static unsigned int ACCENT2 = WHITE;
// ------------------------------
// DISPLAY PROPERTY
// ------------------------------
PANEL_CLASS display(DC_PIN, CS_PIN, BUSY_PIN);
// Shortcut to save typing: Dimension information about fullscreen panel
FullBounds f = display.bounds.full;
// ------------------------------
// DRAW QR CODE
// ------------------------------
// class QRCodeHandler {
// public:
// // ------------------------------
// // GENERATE THE QR CODE FROM URL
// // ------------------------------
// QRCode qrcode;
// int module_size;
// int offset;
// void genQRcode(const char *url) {
// uint8_t qrcodeData[qrcode_getBufferSize(3)];
// qrcode_initText(&qrcode, qrcodeData, 3, 0, url);
// // dynamic qr code module size and centering based on the size provided by qrcode.size
// module_size = DISPLAY_RES / qrcode.size;
// offset = (DISPLAY_RES - (module_size * qrcode.size)) / 2;
// }
// void displayQRcode() {
// // ------------------------------
// // DISPLAY THE QR CODE
// // ------------------------------
// // ONE DRAWING FRAME
// DRAW (display) {
// for (uint8_t y = 0; y < qrcode.size; y++) {
// for (uint8_t x = 0; x < qrcode.size; x++) {
// // a qr code is comprised of an array of modules (x and y), each one is given a filling, either empty or filled
// // we deal with that using a ternary expression
// display.fillRect(offset + x * module_size, offset + y * module_size, module_size, module_size, qrcode_getModule(&qrcode, x, y) ? ACCENT1: ACCENT2);
// }
// }
// }
// }
// };
// ------------------------------
// IMPORTS FOR WIFI AND SERVER
// ------------------------------
// wifi ap + web server libs
#include <DNSServer.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include "ESPAsyncWebServer.h"
// ------------------------------
// WIFI PORTAL CONFIG
// ------------------------------
DNSServer dnsServer;
AsyncWebServer server(80); // server defined on port 80, typical http port
// VARIABLES TO BE UPDATED BY THE USER THROUGH THE SERVER
String user_name;
String proficiency;
bool name_received = false;
bool proficiency_received = false;
// ------------------------------
// HTML TEMPLATE FOR index.html
// ------------------------------
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>Captive Portal Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>
<h3>Captive Portal Demo</h3>
<br><br>
<form action="/get">
<br>
Name: <input type="text" name="name">
<br>
ESP32 Proficiency:
<select name = "proficiency">
<option value=Beginner>Beginner</option>
<option value=Advanced>Advanced</option>
<option value=Pro>Pro</option>
</select>
<input type="submit" value="Submit">
</form>
</body></html>)rawliteral";
// ------------------------------
// REQUEST HANDLERS
// ------------------------------
class CaptiveRequestHandler : public AsyncWebHandler {
public:
CaptiveRequestHandler() {}
virtual ~CaptiveRequestHandler() {}
bool canHandle(AsyncWebServerRequest *request){
//request->addInterestingHeader("ANY");
return true;
}
void handleRequest(AsyncWebServerRequest *request) {
request->send_P(200, "text/html", index_html); // send_P used instead of send because we are fetching a large web page from the Program memory (PROGMEM)
}
};
// ------------------------------
// ASYNC WEB SERVER CONFIG
// to respond to various requests, process the data received and send a response
// ------------------------------
void setupServer(){
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
// Serial.println("Client Connected");
});
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
if (request->hasParam("name")) {
inputMessage = request->getParam("name")->value();
inputParam = "name";
user_name = inputMessage;
// Serial.println(inputMessage);
name_received = true;
}
if (request->hasParam("proficiency")) {
inputMessage = request->getParam("proficiency")->value();
inputParam = "proficiency";
proficiency = inputMessage;
// Serial.println(inputMessage);
proficiency_received = true;
}
// send 200 code : OK, sucess + html code
request->send(200, "text/html", "The values entered by you have been successfully sent to the device <br><a href=\"/\">Return to Home Page</a>");
});
}
// ------------------------------
// INTERRUPTS
// ------------------------------
// void IRAM_ATTR isr() {
// button1.numberKeyPresses++;
// button1.pressed = true;
// updateQRCode();
// }
void setup() {
// ------------------------------
// CONFIGURE THE DISPLAY
// ------------------------------
display.setRotation(4); // Alternatively, PINS_RIGHT
// SET THE BACKGROUND (WHITE IN THIS CASE)
display.setDefaultColor(BGCOLOR);
// QRCode
QRCode qrcode;
uint8_t qrcodeData[qrcode_getBufferSize(3)];
qrcode_initText(&qrcode, qrcodeData, 3, 0, "https://google.fr");
// ONE DRAWING FRAME
int module_size = DISPLAY_RES / qrcode.size;
int offset = (DISPLAY_RES - (module_size * qrcode.size)) / 2;
DRAW (display) {
for (uint8_t y = 0; y < qrcode.size; y++) {
for (uint8_t x = 0; x < qrcode.size; x++) {
// Serial.print(qrcode_getModule(&qrcode, x, y) ? "\u2588\u2588": " ");
display.fillRect(offset + x * module_size, offset + y * module_size, module_size, module_size, qrcode_getModule(&qrcode, x, y) ? ACCENT1: ACCENT2);
}
}
}
// ------------------------------
// WIFI + DNS WEB SERVER SETUP
// ------------------------------
// Serial.begin(115200);
// Serial.println();
// Serial.println("Setting up AP Mode");
// set ap mode
WiFi.mode(WIFI_AP);
// ap name
WiFi.softAP("qr-code");
// Serial.print("AP IP address: ");Serial.println(WiFi.softAPIP());
// Serial.println("Setting up Async WebServer");
// configure the server
setupServer();
// Serial.println("Starting DNS Server");
// start the dns server to redirect all requests to the server
dnsServer.start(53, "*", WiFi.softAPIP());
// add an event handler when a new request arises
server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP
// start the server when everything is ready
server.begin();
// Serial.println("All Done!");
// QRCodeHandler qrhandler;
// // Input the default URL
// qrhandler.genQRcode("https://google.fr");
// // display it
// qrhandler.displayQRcode();
}
void loop(){
// ------------------------------
// HANDLE NEW REQUESTS
// ------------------------------
if(name_received && proficiency_received){
// Serial.print("Hello ");Serial.println(user_name);
// Serial.print("You have stated your proficiency to be ");Serial.println(proficiency);
name_received = false;
proficiency_received = false;
// Serial.println("We'll wait for the next client now");
}
dnsServer.processNextRequest();
}
Kind regards,
William