#include <qrcode.h>
#include <GxEPD2_BW.h>
#include <U8g2_for_Adafruit_GFX.h>
#include "GxEPD2_display_selection_new_style.h"
#define DEBUG 1
#if DEBUG
#define PRINTS(s) do { Serial.print(F(s)); } while (false)
#define PRINT(s, v) do { Serial.print(F(s)); Serial.print(v); } while (false)
#else
#define PRINTS(s)
#define PRINT(s, v)
#endif
U8G2_FOR_ADAFRUIT_GFX u8g2Fonts;
U8G2_FOR_ADAFRUIT_GFX u8g2;
QRCode QR;
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <WebSerial.h>
#include "data.h"
#define LED 2
AsyncWebServer server(80);
const char* ssid = ""; // Your WiFi SSID
const char* password = "";
const uint16_t MSG_BUF_SIZE = 150;
char mesg[MSG_BUF_SIZE] = { '\0' }; // Serial input message buffer
const uint8_t QR_VERSION = 4;
const uint8_t QR_QUIET_ZONE = 2; // quiet zone all around
const uint8_t LINES_COUNT = 20;
const uint8_t LINE_CONTENT_SIZE = 60;
char individual_labels[LINES_COUNT][LINE_CONTENT_SIZE]={NULL}; // a 2D array to store the splitted lines from the text stored in the header file
struct myStruct { // creating a struct to store the individual words of the label
char number[10];
char id[10];
char type[10];
char description[45];
char sig[10];
char date[25];
};
struct myStruct words;
// String str = "1615 GL
void displayText()
{
display.setRotation(1);
display.setPartialWindow(180, 0, 146, 128);
uint16_t bg = GxEPD_WHITE;
uint16_t fg = GxEPD_BLACK;
u8g2Fonts.setForegroundColor(fg); // apply Adafruit GFX color
u8g2Fonts.setBackgroundColor(bg);
u8g2Fonts.setFont(u8g2_font_nokiafc22_tf);
display.firstPage();
do{
display.fillScreen(GxEPD_WHITE);
u8g2Fonts.setCursor(180,10);
u8g2Fonts.print(String(words.sig));
u8g2Fonts.setCursor(180,20);
u8g2Fonts.print("TEST");
}while (display.nextPage());
}
bool readSerial(void)
{
static char* cp = mesg;
bool gotNewData = false;
while (Serial.available())
{
*cp = (char)Serial.read();
if ((*cp == '\n') || (cp - mesg >= MSG_BUF_SIZE - 2)) // end of message character or full buffer
{
*cp = '\0'; // end the string
// restart the index for next filling spree and
// flag we have a message waiting
cp = mesg;
gotNewData = true;
}
else // move char pointer to next position
cp++;
}
return(gotNewData);
}
void word_grabber(char *arr, struct myStruct words)
{
char * pch; // a pointer to keep track of current location
Serial.printf ("Splitting the string \"%s\" into single words:\n",arr);
// give it a read if you want to more about this function: https://cplusplus.com/reference/cstring/strtok/
pch = strtok (arr," ");
unsigned char rep = 0;
bool date_key = true;
while (pch != NULL)
{
if (rep == 0)
{
strcpy(words.number, pch);
Serial.printf ("Number: %s\n",words.number);
}
else if (rep == 1)
{
strcpy(words.id, pch);
Serial.printf ("ID: %s\n",words.id);
}
else if (rep == 2)
{
strcpy(words.type, pch);
Serial.printf ("Type: %s\n",words.type);
}
else if (rep == 3)
{
strcpy(words.description, pch);
Serial.printf ("Description: %s\n",words.description);
}
else if (rep == 4)
{
strcpy(words.sig, pch);
Serial.printf ("Sig: %s\n",words.sig);
}
else
{
if (date_key) {strcat(words.date, pch);
strcat(words.date, " ");
date_key = false;
}
else {
strcat(words.date, pch);
Serial.printf("Date: %s\n", words.date);
}
}
pch = strtok (NULL, " ");
rep++;
}
}
void recvMsg(uint8_t *data, size_t len){
WebSerial.println("Received Data...");
char web_buffer[MSG_BUF_SIZE]= { '\0' };
for(int i=0; i < len; i++){
web_buffer[i] = char(data[i]);
if (i==len-1) web_buffer[i+1]=='\0';
}
displayQRCode(web_buffer, 0,0);
WebSerial.println(web_buffer);
Serial.printf("The data received from web is: %s\n",web_buffer);
word_grabber(web_buffer,words);
if (!strcmp(web_buffer,"ON")){
digitalWrite(LED, HIGH);
}
if (!strcmp(web_buffer,"OFF")){
digitalWrite(LED, LOW);
}
}
void lines_grabber(String data)
{
uint8_t rep=0;
char saved_data[data.length() + 1];
data.toCharArray(saved_data, saved_string.length() + 1);
char* pch = NULL;
pch = strtok(saved_data, "\r\n");
while (pch != NULL)
{
strcpy(individual_labels[rep],pch);
Serial.printf("%d: %s\n",rep+1, individual_labels[rep]);
pch = strtok(NULL, "\r\n");
rep++;
}
}
void lines_splitter(uint8_t x, uint8_t y)
{
for (uint8_t rep = 0; rep < x ; rep++)
{
if (individual_labels[rep] == NULL) continue;
word_grabber(individual_labels[rep],words);
}
}
void printQRBlock(uint16_t x, uint16_t y, uint16_t size, uint16_t col)
// Draw a square block of size pixels. Drawing individual pixels as this is faster
// that line segments and much faster that a filled rectangle.
{
for (uint16_t i = 0; i < size; i++)
for (uint16_t j = 0; j < size; j++)
display.drawPixel(x + i, y + j, col);
}
void displayQRCode(char *msg, uint16_t x0, uint16_t y0)
// Paged display of the QR code with top left corner at (x0,y0)
// on the display
{
display.setRotation(1);
display.setFullWindow();
uint8_t QRData[qrcode_getBufferSize(QR_VERSION)];
uint8_t blockSize;
uint8_t page = 0;
qrcode_initText(&QR, QRData, QR_VERSION, ECC_LOW, msg);
PRINT("\n\nQR Size: ", QR.size);
PRINT("\nLocation: ", x0);
PRINT(",", y0);
PRINT("\nDisplay Height: ", display.height());
blockSize = (display.height() - (2 * QR_QUIET_ZONE)) / QR.size;
PRINT("\nBlock Size: ", blockSize);
Serial.print(F("\nGenerating QRCode Image - "));
Serial.print(mesg);
display.firstPage();
do
{
page++;
// Space all around
display.fillRect(x0, y0,
x0 + QR.size + (2 * QR_QUIET_ZONE), y0 + QR.size + (2 * QR_QUIET_ZONE),
GxEPD_WHITE);
// For each vertical module
for (uint8_t y = 0; y < QR.size; y++)
{
// Eor each horizontal module
for (uint8_t x = 0; x < QR.size; x++)
{
if (qrcode_getModule(&QR, x, y))
printQRBlock(x0 + (x * blockSize) + QR_QUIET_ZONE,
y0 + (y * blockSize) + QR_QUIET_ZONE,
blockSize,
(qrcode_getModule(&QR, x, y)) ? GxEPD_BLACK : GxEPD_WHITE);
}
}
} while (display.nextPage());
Serial.print(F("\nEnd"));
PRINT(" @ page ", page);
}
void setup()
{
Serial.begin(115200);
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
Serial.print(F("\n QR Code Generator\nEnter Data into Serial Monitor to Generate New QR Code\nEnsure line ending is newline"));
display.init();
delay(200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.printf("WiFi Failed!\n");
return;
}
// WebSerial is accessible at "<IP Address>/webserial" in browser
WebSerial.begin(&server);
WebSerial.msgCallback(recvMsg);
server.begin();
WebSerial.println("Hello!");
u8g2Fonts.begin(display); // connect u8g2 procedures to Adafruit GFX
delay(1000);
SPI.end(); // release standard SPI pins,
//SPI: void begin(int8_t sck=-1, int8_t miso=-1, int8_t mosi=-1, int8_t ss=-1);
SPI.begin(13, 12, 14, 15); // map and init SPI pins SCK(13), MISO(12), MOSI(14), SS(15)
lines_grabber(saved_string);
}
void loop() {
if (readSerial())
{
displayQRCode(individual_labels[0], 0, 0);
word_grabber(individual_labels[0], words);
displayText();
}}
Here is the main code. data.h contains:
String saved_string PROGMEM = R"(
1615 GL Ov Head NW 20 August
1615 GL Ov in NW 20 August
1615 GL Ov Vent NW 20 August
1615 GL Ov Sit NW 20 August
1615 GL Ov Horizo NWO 20 August
1615 GLP02 Ov Horiz NW 20 August
)";
Sorry for not posting this originally. Everything works for me in this code except for this one part for displaying the struct members inside of the displayText(), and I don't know why. Also I moved stuff around a bunch trying different things to make this work so it's not aesthetically pleasing right now to some I'm sure.