@@ -23,40 +23,62 @@ SOFTWARE.
2323See more at http://blog.squix.ch
2424*/
2525
26-
27- #include < JsonListener.h>
2826#include < ESP8266WiFi.h>
27+ #include < Ticker.h>
28+ #include < JsonListener.h>
2929#include " SSD1306.h"
3030#include " SSD1306Ui.h"
3131#include " Wire.h"
3232#include " WundergroundClient.h"
3333#include " WeatherStationFonts.h" ;
34- #include < Ticker.h >
34+ #include " WeatherStationImages.h " ;
3535#include " TimeClient.h"
3636#include " ThingspeakClient.h"
3737
38+ /* **************************
39+ * Begin Settings
40+ **************************/
41+ // WIFI
42+ const char * WIFI_SSID = " yourssid" ;
43+ const char * WIFI_PWD = " yourpassw0rd" ;
44+
45+ // Display Settings
46+ const int I2C_DISPLAY_ADDRESS = 0x3c ;
47+ const int SDA_PIN = D3;
48+ const int SDC_PIN = D4;
49+
50+ // TimeClient settings
51+ const float UTC_OFFSET = 1 ;
52+
53+ // Wunderground Settings
54+ const boolean IS_METRIC = true ;
55+ const String WUNDERGRROUND_API_KEY = " WUNDERGROUND_API_KEY" ;
56+ const String WUNDERGROUND_COUNTRY = " CH" ;
57+ const String WUNDERGROUND_CITY = " Zurich" ;
58+
59+ // Thingspeak Settings
60+ const String THINGSPEAK_CHANNEL_ID = " 67284" ;
61+ const String THINGSPEAK_API_READ_KEY = " L2VIW20QVNZJBLAK" ;
62+
3863// Initialize the oled display for address 0x3c
3964// sda-pin=14 and sdc-pin=12
40- SSD1306 display (0x3c , D6, D5 );
41- // SSD1306 display(0x3c, 0, 2 );
65+ SSD1306 display (I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN );
66+ SSD1306Ui ui ( &display );
4267
43- // Set to false, if you prefere imperial/inches, Fahrenheit
44- WundergroundClient wunderground (true );
68+ /* **************************
69+ * End Settings
70+ **************************/
4571
46- float utcOffset = 1 ;
47- TimeClient timeClient (utcOffset);
72+ TimeClient timeClient (UTC_OFFSET);
4873
49- // Add your wounderground api key here
50- String apiKey = " 0c99d927fea78b32" ;
51- String country = " CH" ;
52- String city = " Zurich" ;
74+ // Set to false, if you prefere imperial/inches, Fahrenheit
75+ WundergroundClient wunderground (IS_METRIC);
5376
5477ThingspeakClient thingspeak;
5578
5679// this array keeps function pointers to all frames
5780// frames are the single views that slide from right to left
58- void (*frameCallbacks[])(int x, int y) = {drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5};
59-
81+ bool (*frames[])(SSD1306 *display, SSD1306UiState* state, int x, int y) = { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5 };
6082int numberOfFrames = 5 ;
6183
6284// flag changed in the ticker function every 10 minutes
@@ -75,160 +97,171 @@ void setup() {
7597 display.init ();
7698 display.clear ();
7799 display.display ();
78- WiFi.begin (" yourssid" , " yourpassw0rd" );
79100
101+ // display.flipScreenVertically();
102+ display.setFont (ArialMT_Plain_10);
103+ display.setTextAlignment (TEXT_ALIGN_CENTER);
104+ display.setContrast (255 );
105+
106+ WiFi.begin (WIFI_SSID, WIFI_PWD);
107+
80108 int counter = 0 ;
81109 while (WiFi.status () != WL_CONNECTED) {
82110 delay (500 );
83111 Serial.print (" ." );
84- drawProgress (counter * 10 % 100 , " Connecting Wifi..." , true );
112+ display.clear ();
113+ display.drawString (64 , 10 , " Connecting to WiFi" );
114+ display.drawXbm (46 , 30 , 8 , 8 , counter % 3 == 0 ? activeSymbole : inactiveSymbole);
115+ display.drawXbm (60 , 30 , 8 , 8 , counter % 3 == 1 ? activeSymbole : inactiveSymbole);
116+ display.drawXbm (74 , 30 , 8 , 8 , counter % 3 == 2 ? activeSymbole : inactiveSymbole);
117+ display.display ();
118+
85119 counter++;
86120 }
87121
88- display.setFrameCallbacks (numberOfFrames, frameCallbacks);
89- // how many ticks does a slide of frame take?
90- display.setFrameTransitionTicks (10 );
91- // how many ticks should we wait until the next transition begins?
92- display.setFrameWaitTicks (150 );
122+ ui.setTargetFPS (30 );
123+
124+ ui.setActiveSymbole (activeSymbole);
125+ ui.setInactiveSymbole (inactiveSymbole);
126+
127+ // You can change this to
128+ // TOP, LEFT, BOTTOM, RIGHT
129+ ui.setIndicatorPosition (BOTTOM);
130+
131+ // Defines where the first frame is located in the bar.
132+ ui.setIndicatorDirection (LEFT_RIGHT);
133+
134+ // You can change the transition that is used
135+ // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
136+ ui.setFrameAnimation (SLIDE_LEFT);
137+
138+ // Add frames
139+ ui.setFrames (frames, numberOfFrames);
140+
141+ // Inital UI takes care of initalising the display too.
142+ ui.init ();
93143
94144 Serial.println (" " );
95145
96- updateData ();
146+ updateData (&display );
97147
98- ticker.attach (10 * 60 , setReadyForWeatherUpdate);
148+ ticker.attach (10 * 60 * 10 , setReadyForWeatherUpdate);
99149
100150}
101151
102152void loop () {
103- if (readyForWeatherUpdate && display.getFrameState () == display.FRAME_STATE_FIX ) {
104- updateData ();
105- }
106153
107- // display.clear();
154+ if (readyForWeatherUpdate && ui.getUiState ().frameState == FIXED) {
155+ updateData (&display);
156+ }
108157
109- display.clear ();
110- display.nextFrameTick ();
111- display.display ();
158+ int remainingTimeBudget = ui.update ();
112159
113- // delay(1000);
160+ if (remainingTimeBudget > 0 ) {
161+ // You can do some work here
162+ // Don't do stuff if you are below your
163+ // time budget.
164+ delay (remainingTimeBudget);
165+ }
114166
115167}
116168
117- void updateData () {
118- drawProgress (10 , " Updating time..." , false );
169+ void updateData (SSD1306 *display ) {
170+ drawProgress (display, 10 , " Updating time..." );
119171 timeClient.updateTime ();
120- drawProgress (30 , " Updating conditions..." , false );
121- wunderground.updateConditions (apiKey, country, city );
122- drawProgress (50 , " Updating forecasts..." , false );
123- wunderground.updateForecast (apiKey, country, city );
124- drawProgress (70 , " Updating Thingspeak ..." , false );
125- thingspeak.getLastChannelItem (" 67284 " , " L2VIW20QVNZJBLAK " );
172+ drawProgress (display, 30 , " Updating conditions..." );
173+ wunderground.updateConditions (WUNDERGRROUND_API_KEY, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY );
174+ drawProgress (display, 50 , " Updating forecasts..." );
175+ wunderground.updateForecast (WUNDERGRROUND_API_KEY, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY );
176+ drawProgress (display, 80 , " Updating thingspeak ..." );
177+ thingspeak.getLastChannelItem (THINGSPEAK_CHANNEL_ID, THINGSPEAK_API_READ_KEY );
126178 lastUpdate = timeClient.getFormattedTime ();
127179 readyForWeatherUpdate = false ;
180+ drawProgress (display, 100 , " Done..." );
181+ delay (1000 );
128182}
129183
130- void drawProgress (int percentage, String label, boolean isSpinner) {
131- display.clear ();
132- display.setTextAlignment (TEXT_ALIGN_CENTER);
133- display.setFont (ArialMT_Plain_10);
134- display.drawString (64 , 32 , label);
135- display.drawRect (10 , 50 , 108 , 12 );
136-
137-
138- if (isSpinner) {
139- int blockWidth = 20 ;
140- int startX = (104 - blockWidth) * percentage / 100 ;
141- display.fillRect (startX, 52 , startX + blockWidth , 8 );
142- } else {
143- display.fillRect (12 , 52 , 104 * percentage / 100 , 8 );
144- }
145- display.display ();
184+ void drawProgress (SSD1306 *display, int percentage, String label) {
185+ display->clear ();
186+ display->setTextAlignment (TEXT_ALIGN_CENTER);
187+ display->setFont (ArialMT_Plain_10);
188+ display->drawString (64 , 10 , label);
189+ display->drawRect (10 , 28 , 108 , 12 );
190+ display->fillRect (12 , 30 , 104 * percentage / 100 , 9 );
191+ display->display ();
146192}
147193
148- void drawFrame0 (int x, int y) {
149- display.setTextAlignment (TEXT_ALIGN_LEFT);
150- display.setFont (ArialMT_Plain_16);
151- display.drawStringMaxWidth (x,0 ,128 , " äöü ÄÖÜ éàè °§€@ $£" );
152- }
153194
154- void drawFrame1 (int x, int y) {
155- display. setTextAlignment (TEXT_ALIGN_CENTER);
156- display. setFont (ArialMT_Plain_10);
195+ bool drawFrame1 (SSD1306 *display, SSD1306UiState* state, int x, int y) {
196+ display-> setTextAlignment (TEXT_ALIGN_CENTER);
197+ display-> setFont (ArialMT_Plain_10);
157198 String date = wunderground.getDate ();
158- int textWidth = display. getStringWidth (date);
159- display. drawString (64 + x, 10 + y, date);
160- display. setFont (ArialMT_Plain_24);
199+ int textWidth = display-> getStringWidth (date);
200+ display-> drawString (64 + x, 10 + y, date);
201+ display-> setFont (ArialMT_Plain_24);
161202 String time = timeClient.getFormattedTime ();
162- textWidth = display. getStringWidth (time);
163- display. drawString (64 + x, 20 + y, time);
164- display. setTextAlignment (TEXT_ALIGN_LEFT);
203+ textWidth = display-> getStringWidth (time);
204+ display-> drawString (64 + x, 20 + y, time);
205+ display-> setTextAlignment (TEXT_ALIGN_LEFT);
165206}
166207
167- void drawFrame2 (int x, int y) {
168- display. setFont (ArialMT_Plain_10);
169- display. drawString (60 + x, 10 + y, wunderground.getWeatherText ());
208+ bool drawFrame2 (SSD1306 *display, SSD1306UiState* state, int x, int y) {
209+ display-> setFont (ArialMT_Plain_10);
210+ display-> drawString (60 + x, 10 + y, wunderground.getWeatherText ());
170211
171- display. setFont (ArialMT_Plain_24);
212+ display-> setFont (ArialMT_Plain_24);
172213 String temp = wunderground.getCurrentTemp () + " °C" ;
173- display. drawString (60 + x, 20 + y, temp);
174- int tempWidth = display. getStringWidth (temp);
214+ display-> drawString (60 + x, 20 + y, temp);
215+ int tempWidth = display-> getStringWidth (temp);
175216
176- display. setFont (Meteocons_0_42);
217+ display-> setFont (Meteocons_0_42);
177218 String weatherIcon = wunderground.getTodayIcon ();
178- int weatherIconWidth = display. getStringWidth (weatherIcon);
179- display. drawString (32 + x - weatherIconWidth / 2 , 10 + y, weatherIcon);
219+ int weatherIconWidth = display-> getStringWidth (weatherIcon);
220+ display-> drawString (32 + x - weatherIconWidth / 2 , 10 + y, weatherIcon);
180221}
181222
182- void drawFrame3 (int x, int y) {
183- display.setTextAlignment (TEXT_ALIGN_CENTER);
184- display.setFont (ArialMT_Plain_10);
185- display.drawString (32 + x, 0 + y, " Humidity" );
186- display.drawString (96 + x, 0 + y, " Pressure" );
187- display.drawString (32 + x, 28 + y, " Precipit." );
188-
189- display.setFont (ArialMT_Plain_16);
190- display.drawString (32 + x, 10 + y, wunderground.getHumidity ());
191- display.drawString (96 + x, 10 + y, wunderground.getPressure ());
192- display.drawString (32 + x, 38 + y, wunderground.getPrecipitationToday ());
193- }
194-
195- void drawFrame4 (int x, int y) {
196- drawForecast (x, y, 0 );
197- drawForecast (x + 44 , y, 2 );
198- drawForecast (x + 88 , y, 4 );
223+ bool drawFrame3 (SSD1306 *display, SSD1306UiState* state, int x, int y) {
224+ display->setTextAlignment (TEXT_ALIGN_CENTER);
225+ display->setFont (ArialMT_Plain_10);
226+ display->drawString (32 + x, 0 + y, " Humidity" );
227+ display->drawString (96 + x, 0 + y, " Pressure" );
228+ display->drawString (32 + x, 28 + y, " Precipit." );
229+
230+ display->setFont (ArialMT_Plain_16);
231+ display->drawString (32 + x, 10 + y, wunderground.getHumidity ());
232+ display->drawString (96 + x, 10 + y, wunderground.getPressure ());
233+ display->drawString (32 + x, 38 + y, wunderground.getPrecipitationToday ());
199234}
200235
201- void drawFrame5 (int x, int y) {
202- display.setTextAlignment (TEXT_ALIGN_CENTER);
203- display.setFont (ArialMT_Plain_10);
204- display.drawString (64 + x, 0 + y, " Outdooräöüàé" );
205- display.setFont (ArialMT_Plain_24);
206- display.drawString (64 + x, 10 + y, thingspeak.getFieldValue (0 ) + " °C" );
207- display.drawString (64 + x, 30 + y, thingspeak.getFieldValue (1 ) + " %" );
236+ bool drawFrame4 (SSD1306 *display, SSD1306UiState* state, int x, int y) {
237+ drawForecast (display, x, y, 0 );
238+ drawForecast (display, x + 44 , y, 2 );
239+ drawForecast (display, x + 88 , y, 4 );
208240}
209241
210- void drawFrame6 (int x, int y) {
211- drawForecast (x, y, 4 );
242+ bool drawFrame5 (SSD1306 *display, SSD1306UiState* state, int x, int y) {
243+ display->setTextAlignment (TEXT_ALIGN_CENTER);
244+ display->setFont (ArialMT_Plain_10);
245+ display->drawString (64 + x, 0 + y, " Outdoor" );
246+ display->setFont (ArialMT_Plain_24);
247+ display->drawString (64 + x, 10 + y, thingspeak.getFieldValue (0 ) + " °C" );
248+ display->drawString (64 + x, 30 + y, thingspeak.getFieldValue (1 ) + " %" );
212249}
213250
214- void drawForecast (int x, int y, int dayIndex) {
215- display. setTextAlignment (TEXT_ALIGN_CENTER);
216- display. setFont (ArialMT_Plain_10);
251+ void drawForecast (SSD1306 *display, int x, int y, int dayIndex) {
252+ display-> setTextAlignment (TEXT_ALIGN_CENTER);
253+ display-> setFont (ArialMT_Plain_10);
217254 String day = wunderground.getForecastTitle (dayIndex).substring (0 , 3 );
218255 day.toUpperCase ();
219- display. drawString (x + 20 , y, day);
220-
221- display. setFont (Meteocons_0_21);
222- display. drawString (x + 20 , y + 15 , wunderground.getForecastIcon (dayIndex));
256+ display-> drawString (x + 20 , y, day);
257+
258+ display-> setFont (Meteocons_0_21);
259+ display-> drawString (x + 20 , y + 15 , wunderground.getForecastIcon (dayIndex));
223260
224- display. setFont (ArialMT_Plain_16);
225- display. drawString (x + 20 , y + 37 , wunderground.getForecastLowTemp (dayIndex) + " /" + wunderground.getForecastHighTemp (dayIndex) + String (( char ) 176 ));
261+ display-> setFont (ArialMT_Plain_16);
262+ display-> drawString (x + 20 , y + 37 , wunderground.getForecastLowTemp (dayIndex) + " /" + wunderground.getForecastHighTemp (dayIndex));
226263 // display.drawString(x + 20, y + 51, );
227- display.setTextAlignment (TEXT_ALIGN_LEFT);
228- }
229-
230- void drawFrame7 (int x, int y) {
231-
264+ display->setTextAlignment (TEXT_ALIGN_LEFT);
232265}
233266
234267void setReadyForWeatherUpdate () {
@@ -237,4 +270,3 @@ void setReadyForWeatherUpdate() {
237270}
238271
239272
240-
0 commit comments