Skip to content

Commit

Permalink
Add wifimanager and qrcode connect screen
Browse files Browse the repository at this point in the history
  • Loading branch information
kamerat committed Oct 8, 2024
1 parent b794200 commit 6b039a7
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 62 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Weather precipitation graph using Lilygo T5 2.13" ESP32 E-paper screen. This pro
- Search for and install the following libraries:
- Time
- ArduinoJson
- WiFiManager
- QRcodeDisplay

5. Clone this repository or download the `yr-regn-display.ino` file

Expand All @@ -35,8 +37,6 @@ Weather precipitation graph using Lilygo T5 2.13" ESP32 E-paper screen. This pro

8. Customize your configuration:
- In the `config.h` file:
- Replace `"MyWiFiSSID"` with your Wi-Fi SSID
- Replace `"MyWiFiPassword"` with your Wi-Fi password
- Modify the `USER_AGENT` if desired
- Set the `YR_LOCATION` to your desired location ID
- Set `DEBUG` to `true` or `false` as needed
Expand All @@ -50,7 +50,7 @@ Weather precipitation graph using Lilygo T5 2.13" ESP32 E-paper screen. This pro

## Usage

Once uploaded, the device will connect to Wi-Fi, fetch precipitation data from YR.no, and display a graph showing the precipitation forecast for the next 90 minutes.
Once uploaded, the device will prompt you to connect to Wi-Fi. Once connected, it will fetch precipitation data from YR.no, and display a graph showing the precipitation forecast for the next 90 minutes.

## Contributing

Expand Down
4 changes: 0 additions & 4 deletions example.config.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#ifndef CONFIG_H
#define CONFIG_H

// Wi-Fi credentials
#define WIFI_SSID "YOUR_WIFI_SSID"
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"

// User agent for YR.no - If you're using this for your own project, change the user agent to avoid getting blocked by YR.no
#define USER_AGENT_PERSONAL "epaper/1.0 [YOUR_GITHUB_USERNAME]"

Expand Down
33 changes: 33 additions & 0 deletions qrcodeeink.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <Arduino.h>
#include "qrencode.h"
#include "qrcodeeink.h"

QRcodeEink::QRcodeEink(GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> *display) {
this->display = display;
}

void QRcodeEink::init(int x_offset, int y_offset) {
this->screenwidth = display->width();
this->screenheight = display->height();


int min = screenwidth < screenheight ? screenwidth : screenheight;
multiply = min / WD;

offsetsX = (screenwidth-(WD*multiply))/2 + x_offset;
offsetsY = (screenheight-(WD*multiply))/2 + y_offset;
}

void QRcodeEink::screenwhite() {
display->setFullWindow();
display->fillScreen(GxEPD_WHITE);
display->display(false);
}

void QRcodeEink::screenupdate() {
// do nothing
}

void QRcodeEink::drawPixel(int x, int y, int color) {
display->fillRect(x, y, multiply, multiply, color == 1 ? GxEPD_BLACK : GxEPD_WHITE);
}
30 changes: 30 additions & 0 deletions qrcodeeink.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef ESPQRCODEEINK_H
#define ESPQRCODEEINK_H

/* ESP_QRcode. e-ink version
* Import this .h when using some e-ink display
*/

#define EINKDISPLAY

#include <qrcodedisplay.h>
#include <Adafruit_GFX.h>
#include <GxEPD2_BW.h>

#ifndef EINK_MODEL
#define EINK_MODEL 128
#endif

class QRcodeEink : public QRcodeDisplay
{
private:
GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> *display;
void drawPixel(int x, int y, int color);
public:

QRcodeEink(GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> *display);
void init(int x_offset = 0, int y_offset = 0);
void screenwhite();
void screenupdate();
};
#endif
38 changes: 23 additions & 15 deletions wifiView.ino
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
void displayWiFiStatus(DisplayType& display, bool isConnected, IPAddress ipAddress) {
display.setFullWindow();
display.firstPage();
#include "qrcodeeink.h"

void displayWiFiSetup(DisplayType& display, WiFiManager *wifiManager, const char* randomWifiPassword) {
QRcodeEink qrcode(&display);
qrcode.init(-70);
do {
display.fillScreen(GxEPD_WHITE);
// Generate QR code for WiFi configuration
String qrData = "WIFI:S:" + String(wifiManager->getConfigPortalSSID()) + ";T:WPA;P:" + String(randomWifiPassword) + ";;";
qrcode.create(qrData);

display.setFont();
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeSans9pt7b);

display.setCursor(10, 30);
if (isConnected) {
display.print("WiFi connected");
display.setCursor(10, 60);
display.print("IP: ");
display.print(ipAddress);
} else {
display.print("WiFi connection failed");
}
display.setCursor(115, 15);
display.print("WIFI Konfigurasjon");
display.setCursor(115, 49);
display.print("SSID: ");
display.setCursor(115, 79);
display.print("Passord: ");

display.setFont(&FreeSans9pt7b);
display.setCursor(115, 69);
display.print(wifiManager->getConfigPortalSSID());
display.setCursor(115, 101);
display.print(randomWifiPassword);
} while (display.nextPage());
}
}
76 changes: 36 additions & 40 deletions yr-regn-display.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
#include <esp_sleep.h>
#include <sys/time.h>
#include <math.h>
#include <WiFiManager.h>

// Constants
const char* ssid = WIFI_SSID;
const char* password = WIFI_PASSWORD;
const char* yrApiUrl = "https://www.yr.no/api/v0/locations/" YR_LOCATION "/forecast/now";
const int BUTTON_PIN = 39; // LilyGo T5 integrated button pin
const int UPDATE_INTERVAL = 5 * 60 * 1000000; // 5 minutes in microseconds
Expand All @@ -22,7 +21,6 @@ const int UPDATE_INTERVAL = 5 * 60 * 1000000; // 5 minutes in microseconds
float precipitationData[18]; // Array to store 90 minutes of precipitation data (5-minute intervals)
String responseTime; // String to store the time from the HTTP response
String createdTime; // String to store the time from the YR API response
bool isFirstBoot = true; // Flag to track if it's the first boot
bool radarIsDown = false; // Flag to track if the radar is down

// Display initialization
Expand All @@ -46,7 +44,6 @@ String convertTime(const String& inputTime, const char* inputFormat, bool adjust
return "Failed to parse time";
}


// Main functions
void setup() {
Serial.begin(115200);
Expand All @@ -56,32 +53,49 @@ void setup() {
display.setTextColor(GxEPD_BLACK);

pinMode(BUTTON_PIN, INPUT_PULLUP);
updateAndSleep();

WiFiManager wifiManager;

wifiManager.setConfigPortalTimeout(180);

if (DEBUG) {
wifiManager.resetSettings();
}

const char* randomWifiPassword = generatePassword();

wifiManager.setAPCallback([&](WiFiManager* wifiManager) {
displayWiFiSetup(display, wifiManager, randomWifiPassword);
});

if (wifiManager.autoConnect("regnvarsel", randomWifiPassword)) {
Serial.println("WiFi connected");
updateAndSleep();
} else {
Serial.println("Failed to connect and hit timeout");
ESP.restart();
}
}


void loop() {
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();

if (wakeup_reason == ESP_SLEEP_WAKEUP_EXT0) {
while (digitalRead(BUTTON_PIN) == LOW) {
delay(10);
}
updateAndSleep();
}

updateAndSleep();
}

void updateAndSleep() {
setupWiFi();

if (fetchPrecipitationData()) {
updateDisplayWithNewData();
} else {
Serial.println("Failed to fetch data");
}

isFirstBoot = false;

WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
esp_sleep_enable_timer_wakeup(UPDATE_INTERVAL);
Expand Down Expand Up @@ -118,35 +132,6 @@ void updateDisplayWithNewData() {
}
}

void checkButtonAndUpdate() {
if (digitalRead(BUTTON_PIN) == LOW) { // Button is active LOW
delay(50); // Simple debounce
if (digitalRead(BUTTON_PIN) == LOW) {
updateDisplayWithNewData();
while (digitalRead(BUTTON_PIN) == LOW) {
delay(10); // Wait for button release
}
}
}
}

void setupWiFi() {
WiFi.begin(ssid, password);

int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
attempts++;
}

if (WiFi.status() != WL_CONNECTED) {
displayWiFiError(display);
} else if (DEBUG && isFirstBoot) { // Only display WiFi status on first boot
displayWiFiStatus(display, true, WiFi.localIP());
delay(1000); // Display WiFi status for 1 second
}
}

bool fetchPrecipitationData() {
HTTPClient http;
http.begin(yrApiUrl);
Expand Down Expand Up @@ -201,4 +186,15 @@ bool parsePrecipitationData(const String& payload) {
Serial.println(precipitationData[i]);
}
return true;
}

const char* generatePassword() {
static const char* passwords[] = {
"regnbukse", "paraply", "solskinn", "skybrudd",
"duskregn", "plaskedam", "takrenne", "regnskyll",
"regnbuer", "flomregn", "lynogtorden"
};
int arraySize = sizeof(passwords) / sizeof(passwords[0]);
int randomIndex = random(0, arraySize);
return passwords[randomIndex];
}

0 comments on commit 6b039a7

Please sign in to comment.