Story
This is the Arduino code to accompany the video on youtube:
https://youtu.be/1nmMAhbYg0w
Remember to set the WIFI password and SSID where indicated
You can change the feed url to any .txt based feed.
Code:
#include <Arduino.h>
#include "EPD.h"
#include <WiFi.h>
#include <SPI.h>
#include <HTTPClient.h> // Include HTTPClient for making HTTP requests
#define Max_CharNum_PerLine 66 // 792/12 - set max screen characters per line
uint8_t ImageBW[27200]; // Buffer for black and white image data
// Button Pin Definitions
#define BTN_MENU 2 //menu button on IO 2
#define BTN_UP 6 //UP button on IO 6
#define BTN_OK 5 //OK button on IO 5
#define BTN_DOWN 4 //DOWN button on IO 4
#define BTN_EXIT 1 //EXIT button on IO 1
// Text to display for each button
const char* btnMessages[] = {
"Menu Button Pressed", //message 1
"Up Button Pressed", //message 2
"Checking for RSS Feed Info ", //message 3
"Down Button Pressed", //message 4
"Exit Button Pressed" //message 5
};
//-----------------------------------------------------------------------------------------------------------------
const char* ssid = "yourSSID"; //insert your WIFI SSID here between the quotation marks
const char* password = "yourwifipassword"; //same here with password - insert between quotation marks
//-----------------------------------------------------------------------------------------------------------------
int currentLine = 0; // To track which set of 9 lines to display
unsigned long lastUpdate = 0; // For timing the 30-second interval
const unsigned long updateInterval = 30000; // 30 seconds interval
unsigned long lastRSSFeedUpdate = 0; // Last time the RSS feed was fetched
const unsigned long RSSFeedUpdateInterval = 300000; // 5 minutes (in milliseconds)
bool wifiConnected = false; // WiFi connection status
std::vector<String> rssFeed; // Global RSS feed storage
void connectToWiFi() {
WiFi.begin(ssid, password);
Serial.print("Connecting to Wi-Fi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
wifiConnected = true;
Serial.println("\nConnected to Wi-Fi!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
// Function to fetch RSS feed and return a list of lines (ignoring empty lines)
std::vector<String> fetchRSSFeed() {
HTTPClient http;
std::vector<String> lines;
//----------------------------------- data feed retrieveal ----------------------------------------------------------------------
http.begin("https://services.swpc.noaa.gov/text/aurora-nowcast-hemi-power.txt"); //alther the location of the data feed here
int httpCode = http.GET(); // Send HTTP GET request
//------------------------------------ this only seems to work with .txt feeds, not .rss feeds.----------------------------------
if (httpCode == 200) { // Check if the request was successful
String feed = http.getString();
int startIdx = 0;
int endIdx = feed.indexOf("\n", startIdx);
// Parse each line, skipping empty lines
while (endIdx != -1) {
String line = feed.substring(startIdx, endIdx);
if (line.length() > 0) {
lines.push_back(line); // Add line to list if it's not empty
}
startIdx = endIdx + 1;
endIdx = feed.indexOf("\n", startIdx);
}
} else {
Serial.println("Error in HTTP request");
}
http.end(); // Close the connection
return lines;
}
void setup() {
// Screen Power Initialization
pinMode(7, OUTPUT);
digitalWrite(7, HIGH);
connectToWiFi();
// EPD Initialization
EPD_GPIOInit();
Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE);
Paint_Clear(WHITE);
EPD_FastMode1Init(); //set to fast mode?
EPD_Display_Clear(); //clear display
EPD_Update(); //update display buffer
EPD_GPIOInit(); //init general purpose IO
EPD_FastMode1Init(); //set to fast mode?
// Display WiFi Status Message
if (wifiConnected) {
Long_Text_Display(0, 0, "WiFi Connected!", 24, BLACK);
Long_Text_Display(0, 30, "Push OK button to start RSS feed", 24, BLACK);
} else {
Long_Text_Display(0, 0, "WiFi Connection Failed", 24, BLACK);
}
// Initial Message Display
EPD_Display(ImageBW); //set to black and white mode?
EPD_FastUpdate(); //fast update?
EPD_DeepSleep(); //put display to sleep.
// Button Initialization
pinMode(BTN_MENU, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_OK, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_EXIT, INPUT_PULLUP);
// Load initial RSS feed
rssFeed = fetchRSSFeed();
lastRSSFeedUpdate = millis();
}
void loop() {
// Re-check RSS feed every 5 minutes
if (millis() - lastRSSFeedUpdate >= RSSFeedUpdateInterval) {
Serial.println("Re-fetching RSS feed...");
rssFeed = fetchRSSFeed();
lastRSSFeedUpdate = millis(); // Reset the timer
}
// Check Button Presses
if (digitalRead(BTN_OK) == LOW) {
displayButtonMessage(btnMessages[2]);
}
// Check if 30 seconds have passed to update the display
if (millis() - lastUpdate >= updateInterval) {
// Only update the screen if RSS feed is available
int totalLines = rssFeed.size();
if (totalLines > 0) {
// Calculate the starting line based on current position
int startLine = currentLine * 9;
int endLine = startLine + 9;
// Only update the screen if necessary (reducing flicker)
EPD_FastMode1Init(); // Fast mode for partial updates
for (int i = startLine; i < endLine && i < totalLines; i++) {
Long_Text_Display(0, (i - startLine) * 30, rssFeed[i].c_str(), 24, BLACK);
}
// Update the currentLine for the next set of 9 lines
currentLine++;
// If we reach the end of the feed, reset to display from the beginning
if (startLine + 9 >= totalLines) {
currentLine = 0;
}
// Refresh the display (only partial update here)
EPD_Display(ImageBW);
EPD_FastUpdate();
EPD_DeepSleep(); // Put display to sleep after updating
} else {
Serial.println("Failed to fetch RSS content.");
}
// Update the last update time
lastUpdate = millis();
}
delay(200); // Debounce delay
}
// Display button acknowledgment on screen
void displayButtonMessage(const char* message) {
clear_all();
Long_Text_Display(0, 30, message, 24, BLACK);
EPD_Display(ImageBW);
EPD_FastUpdate();
EPD_DeepSleep();
}
void clear_all() {
EPD_FastMode1Init();
EPD_Display_Clear();
EPD_Update();
}
// Display text on screen
void Long_Text_Display(int x, int y, const char* content, int fontSize, int color) {
int length = strlen(content);
int i = 0;
char line[Max_CharNum_PerLine + 1]; // +1 for null terminator
while (i < length) {
int lineLength = 0;
memset(line, 0, sizeof(line)); // Clear line buffer
while (lineLength < Max_CharNum_PerLine && i < length) {
line[lineLength++] = content[i++];
}
EPD_ShowString(x, y, line, fontSize, color);
y += fontSize; // Move to the next line
if (y >= 272) break; // Stop if out of screen space
}
}