OLED Exchange Rate Monitor
Create a real-time currency exchange rate display using an ESP32 and an OLED screen, updated daily with the latest rates from an online API.
Components and supplies
1
Seeed Studio XIAO ESP32C3
1
SSD1306 OLED Display
1
Push Button
1
ESP32 Wroom
Tools and machines
1
Solder Iron
1
cables
1
PCB
1
Breadboard, Plastic
Apps and platforms
1
arduino IDE
Project description
Code
Exchangerates
c
1#include <WiFi.h> 2#include <HTTPClient.h> 3#include <Adafruit_GFX.h> 4#include <Adafruit_SSD1306.h> 5#include <Wire.h> 6 7// OLED display configuration 8#define SCREEN_WIDTH 128 9#define SCREEN_HEIGHT 64 10#define OLED_RESET -1 11#define SCREEN_ADDRESS 0x3C 12 13// WiFi credentials 14#define WIFI_SSID "YOUR-SSID" 15#define WIFI_PASS "YOUR-PASSWORD" 16 17Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 18 19// API URL for exchange rates 20String url = "YOUR-URL"; 21String json; 22String payload; 23const char* ssid = WIFI_SSID; 24const char* password = WIFI_PASS; 25 26// Buttons and timing configuration 27const int button1 = 2; 28const int button2 = 3; 29const long interval = 86400000; // 24 hours 30const unsigned long screenOffTimeout = 5 * 60 * 1000; // 5 minutes 31unsigned long lastButtonPressMillis = 0; 32unsigned long previousMillis = 0; 33unsigned long currentMillis; 34int httpCode; 35int xpos; 36int y = 10; 37int speed = 4; 38int highscrolllimit = 2; 39int downscrolllimit = SCREEN_HEIGHT - 2572; 40int pos; 41int lastNewline; 42int secondLastNewline; 43int lineCount = 0; 44int startIndex = 0; 45int numberoflines = 163; 46bool btn1State; 47bool btn2State; 48 49HTTPClient http; 50 51void setup() { 52 Serial.begin(115200); 53 pinMode(button1, INPUT_PULLUP); 54 pinMode(button2, INPUT_PULLUP); 55 if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { 56 Serial.println(F("SSD1306 allocation failed")); 57 for (;;); 58 } 59 display.setTextSize(1); 60 display.setTextColor(SSD1306_WHITE); 61 display.display(); 62} 63 64void loop() { 65 display.setTextSize(1); 66 btn1State = digitalRead(button1); 67 btn2State = digitalRead(button2); 68 currentMillis = millis(); 69 70 // Update the last button press time if any button is pressed 71 if (btn1State == LOW || btn2State == LOW) { 72 lastButtonPressMillis = currentMillis; 73 } 74 75 // Turn off the display if the screen off timeout is reached 76 if (currentMillis - lastButtonPressMillis >= screenOffTimeout) { 77 display.ssd1306_command(SSD1306_DISPLAYOFF); 78 } else { 79 display.ssd1306_command(SSD1306_DISPLAYON); 80 81 // Scroll up if button1 is pressed and not at the limit 82 if (btn1State == LOW && y < highscrolllimit) { 83 y += speed; 84 } 85 86 // Scroll down if button2 is pressed and not at the limit 87 if (btn2State == LOW && y > downscrolllimit) { 88 y -= speed; 89 } 90 91 // Perform an HTTP request at the specified interval or on the first run 92 if (currentMillis - previousMillis >= interval || previousMillis == 0) { 93 if (httpGETRequest()) { 94 previousMillis = currentMillis; 95 } else { 96 // Display "Retrying..." for HTTP or connection errors 97 Serial.println("Retrying..."); 98 display.clearDisplay(); 99 display.setCursor(0, 0); 100 display.println("Retrying..."); 101 display.display(); 102 delay(1000); 103 } 104 } 105 106 // Display the payload only if httpGETRequest() was successful and no site error occurred 107 if (httpCode > 0 && !isSiteError(payload)) { 108 display.clearDisplay(); 109 display.setCursor(0, y); 110 display.println(payload); 111 display.display(); 112 } 113 } 114} 115 116// Function to connect to WiFi 117void connectToWiFi() { 118 Serial.print("Connecting to WiFi network..."); 119 display.clearDisplay(); 120 display.setCursor(0, 0); 121 display.print("Connecting to WiFi..."); 122 display.display(); 123 124 WiFi.begin(ssid, password); 125 126 xpos = display.getCursorX(); 127 128 // Wait until connected to WiFi 129 while (WiFi.status() != WL_CONNECTED) { 130 display.setCursor(xpos, display.getCursorY()); 131 display.print("."); 132 display.display(); 133 xpos = display.getCursorX(); 134 if (xpos >= display.width() - 7) { 135 int16_t x1, y1; 136 uint16_t w, h; 137 display.getTextBounds(".", 0, 0, &x1, &y1, &w, &h); 138 display.setCursor(0, display.getCursorY() + h); 139 xpos = 0; 140 } 141 delay(1000); 142 } 143 144 Serial.println("Connected to WiFi network\nRequesting HTTP data"); 145 display.clearDisplay(); 146 display.setCursor(0, 0); 147 display.setTextSize(1); 148 display.println("Connected!"); 149 display.println("Requesting HTTP data..."); 150 display.display(); 151} 152 153// Function to perform HTTP GET request 154bool httpGETRequest() { 155 connectToWiFi(); 156 display.setTextSize(1); 157 if (http.begin(url)) { 158 httpCode = http.GET(); 159 160 if (httpCode > 0) { 161 payload = http.getString(); 162 Serial.println(payload); 163 http.end(); 164 165 // Vérifiez si le payload contient une erreur du site 166 if (isSiteError(payload)) { 167 display.clearDisplay(); 168 display.setCursor(0, 0); 169 display.println("Error fetching data!"); 170 display.display(); 171 Serial.println("Error fetching data: Invalid API key or other issue."); 172 delay(1000); 173 http.end(); 174 return false; 175 } 176 177 // Traitement du payload comme précédemment 178 json = payload; 179 180 for (int i = 0; i < 10; i++) { 181 pos = json.indexOf('\n'); 182 if (pos != -1) { 183 json.remove(0, pos + 1); 184 } 185 } 186 187 lastNewline = json.lastIndexOf('\n'); 188 if (lastNewline != -1) { 189 secondLastNewline = json.lastIndexOf('\n', lastNewline - 1); 190 if (secondLastNewline != -1) { 191 json.remove(secondLastNewline); 192 } 193 } 194 195 String lines[numberoflines]; 196 for (int i = 0; i < json.length(); i++) { 197 if (json[i] == '\n') { 198 lines[lineCount] = json.substring(startIndex, i); 199 lines[lineCount].trim(); 200 lineCount++; 201 startIndex = i + 1; 202 } 203 } 204 205 payload = lines[0]; 206 for (int i = 1; i < lineCount; i++) { 207 payload += "\n\n" + lines[i]; 208 } 209 WiFi.disconnect(true); 210 return true; 211 } else { 212 // Handle HTTP request error 213 Serial.println("Error during HTTP request"); 214 display.clearDisplay(); 215 display.setCursor(0, 0); 216 display.println("HTTP request failed!"); 217 display.display(); 218 delay(1000); 219 http.end(); 220 return false; 221 } 222 } else { 223 // Handle server connection error 224 Serial.println("Error connecting to server"); 225 display.clearDisplay(); 226 display.setCursor(0, 0); 227 display.println("Connection to the server failed!"); 228 display.display(); 229 delay(1000); 230 return false; 231 } 232} 233 234// Function to check if the payload contains a site-specific error 235bool isSiteError(const String& payload) { 236 return payload.indexOf("\"result\":\"error\"") != -1; 237}
Downloadable files
Kicad files
Illustrative only, not a complete schematic.
exchangerate.zip
Comments
Only logged in users can leave comments