Hallo zusammen,
jeden 3. Freitag im Monat findet in der Stadtbibliothek in Minden das Treffen des MakerSPace statt.
Von 15:00 bis 18:00 Uhr basteln, grübeln und lachen wir gemeinsam.
Hallo zusammen,
jeden 3. Freitag im Monat findet in der Stadtbibliothek in Minden das Treffen des MakerSPace statt.
Von 15:00 bis 18:00 Uhr basteln, grübeln und lachen wir gemeinsam.
Science Slam 2018 Vorrunde am 07.06.2018 in der UNI KASSEL
Schreibt einen Kommentar …
Hallo Ihr Lieben …
Der MakerSpace-Minden sucht neue Räume.
Doch leider geht es in unserer Stadt nicht so richtig weiter.
Die StaBi hat uns bis jetzt als erster Anlaufpunkt gedient, kann aber nicht die Möglichkeiten bieten die wir uns wünschen. Aus diesem Grund suchen wir nach neuen Möglichkeiten.
Ideal wären Räume die in Verbindung mit Key-Usern 24/7 zugänglich sind. Aber es muss ja nicht immer gleich perfekt sein. 🙂
Solltet Ihr Ideen oder Anregungen haben, würden wir uns sehr freuen von Euch zu hören.
Es ist geplant sich in der nächsten Zeit mit “Aktoren” der Stadt Minden und der hier ansässigen Firmen zu treffen und ggf. über Möglichkeiten zu diskutieren.
Wer sich an der Suche beteiligen mag, kann ganz formlos mit uns in Kontakt treten unter: info@promoscout.de
In dem Sinne …
Thomas Utpatel
What’s the MATRIX Voice?
http://esp-idf.readthedocs.io/en/latest/api-reference/index.html
https://www.espressif.com/en/products/hardware/esp32/resources
https://www.bluetooth.com/specifications/gatt/services
https://www.instructables.com/id/ESP32ESP8266-Weather-ForecasterPredictor/
https://www.instructables.com/id/IOT-Made-Simple-Playing-With-the-ESP32-on-Arduino-/
/* Last udpate: Added enumerated weather types, improved efficiency
* Last update: 25-March-2018, with improved forecast rules *
* ESP32 and BMP180 or BME280 and OLED SH1106 or SSD1306 display Weather Forecaster
* Using air pressure changes to predict weather based on an advanced set of forecasting rules.
* The ‘MIT License (MIT) Copyright (c) 2016 by David Bird’. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
* following conditions:
* The above copyright (‘as annotated’) notice and this permission notice shall be included in all copies or substantial portions of the Software and where the
* software use is visible to an end-user.
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* See more at http://dsbird.org.uk*/
#include “SSD1306.h” // Version 4 or higher
#include “OLEDDisplayUi.h” // Version 4 or higher#include <WiFi.h>
#include “time.h”
#include <Wire.h>//
#include <Adafruit_BME280.h>
#include <Adafruit_BMP085.h> // If using BMP180 or BMP085 and update line: 173/174 accordingly e.g. BME and BME or BMP and BMP
#define icon_width 40#
define icon_height 40 // Define each of the *icons for displayconst uint8_t rain_icon[] PROGMEM = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x3F, 0x04, 0xFE, 0xFF, 0xFF, 0xDF, 0xF0, 0xFC, 0xFF, 0xFF, 0xE7, 0xFF, 0xFB, 0xFF, 0xFF, 0xFB, 0xFF, 0xF3, 0xFF, 0xFF, 0xFD, 0xFF, 0xE7, 0xFF, 0xFF, 0xFD, 0xFF, 0x0F, 0xFE, 0x0F, 0xF8, 0xFF, 0x8F, 0xFC, 0xE7, 0xFB, 0xFF, 0xC7, 0xF9, 0xF7, 0xE3, 0xFF, 0xC3, 0xF3, 0xF3, 0xDF, 0xFF, 0xE8, 0xE7, 0xF9, 0xFF, 0xFF, 0xFE, 0xEF, 0xFD, 0xFF, 0xFF, 0xFF, 0xE7, 0xF9, 0xFF, 0xFF, 0xFF, 0xF7, 0xFB, 0xFF, 0xFF, 0xFF, 0xF3, 0xFB, 0xFF, 0xFF, 0xFF, 0xF9, 0xF7, 0xFF, 0xFF, 0xFF, 0xFC, 0xCF, 0xFF, 0xFF, 0x3F, 0xFE, 0x3F, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x7D, 0xBF, 0xEF, 0xFF, 0xFF, 0xBE, 0xDF, 0xF7, 0xFF, 0x7F, 0xDF, 0xEF, 0xFB, 0xFF, 0xBF, 0xEF, 0xF7, 0xFD, 0xFF, 0xDF, 0xF7, 0xFB, 0xFE, 0xFF, 0xEF, 0xFB, 0x7D, 0xFF, 0xFF, 0xF7, 0xFD, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };const uint8_t sunny_icon[] PROGMEM = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFD, 0xDF, 0xFF, 0xE3, 0xFF, 0xF8, 0x8F, 0xFF, 0xE3, 0x7F, 0xF0, 0x07, 0xFF, 0xE3, 0x3F, 0xF8, 0x0F, 0xFE, 0xFF, 0x1F, 0xFC, 0x1F, 0x7C, 0x00, 0x0E, 0xFE, 0x3F, 0x18, 0x00, 0x1C, 0xFF, 0x7F, 0xCC, 0xFF, 0xB1, 0xFF, 0xFF, 0xE6, 0xFF, 0xE7, 0xFF, 0xFF, 0xF3, 0xFF, 0xCF, 0xFF, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0xFF, 0xF9, 0xFF, 0x9F, 0xFF, 0xFF, 0xF9, 0xFF, 0x9F, 0xFF, 0xFF, 0xF9, 0xFF, 0x9F, 0xFF, 0x01, 0xF9, 0xFF, 0x9F, 0x80, 0x01, 0xF9, 0xFF, 0x9F, 0x80, 0x01, 0xF9, 0xFF, 0x9F, 0x80, 0xFF, 0xF9, 0xFF, 0x9F, 0xFF, 0xFF, 0xF1, 0xFF, 0x8F, 0xFF, 0xFF, 0xF1, 0xFF, 0x8F, 0xFF, 0xFF, 0xE3, 0xFF, 0xE7, 0xFF, 0xFF, 0xC7, 0xFF, 0xF3, 0xFF, 0xFF, 0x8D, 0xFF, 0xD8, 0xFF, 0xFF, 0x38, 0x00, 0x8C, 0xFF, 0x7F, 0x70, 0x00, 0x07, 0xFF, 0x3F, 0xF8, 0xFF, 0x0F, 0xFE, 0x1F, 0xFC, 0xE3, 0x1F, 0xFC, 0x0F, 0xFE, 0xE3, 0x3F, 0xF8, 0x07, 0xFF, 0xE3, 0x7F, 0xF0, 0x8F, 0xFF, 0xE3, 0xFF, 0xF8, 0xDF, 0xFF, 0xE3, 0xFF, 0xFD, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };const uint8_t mostlysunny_icon[] PROGMEM = { 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFD, 0x7E, 0xFF, 0xFF, 0xFF, 0xFB, 0xBF, 0xEF, 0xFF, 0xFF, 0x17, 0xE0, 0xF7, 0xFF, 0xFF, 0xCF, 0x9F, 0xF9, 0xFF, 0xFF, 0xE6, 0x3F, 0xFD, 0xFF, 0xFF, 0xF5, 0x7F, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFE, 0xFF, 0xFF, 0xF9, 0xFF, 0x00, 0xFF, 0xFF, 0xFD, 0x7F, 0x08, 0xFC, 0xFF, 0xFD, 0xBF, 0xE1, 0xF9, 0xFF, 0xFD, 0xCF, 0xFF, 0xF7, 0xFF, 0xFD, 0xF7, 0xFF, 0xE7, 0xFF, 0xF9, 0xFB, 0xFF, 0xCF, 0xFF, 0xF3, 0xFB, 0xFF, 0x1F, 0xFC, 0x17, 0xF0, 0xFF, 0x1F, 0xF9, 0xC7, 0xF7, 0xFF, 0x8F, 0xF3, 0xEF, 0xC7, 0xFF, 0x87, 0xE7, 0xE7, 0xBF, 0xFF, 0xD1, 0xCF, 0xF3, 0xFF, 0xFF, 0xFD, 0xDF, 0xFB, 0xFF, 0xFF, 0xFF, 0xCF, 0xF3, 0xFF, 0xFF, 0xFF, 0xEF, 0xF7, 0xFF, 0xFF, 0xFF, 0xE7, 0xF7, 0xFF, 0xFF, 0xFF, 0xF3, 0xEF, 0xFF, 0xFF, 0xFF, 0xF9, 0x9F, 0xFF, 0xFF, 0x7F, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; const uint8_t cloudy_icon[] PROGMEM = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x7F, 0x78, 0xFC, 0xFF, 0xFF, 0xBF, 0xFF, 0xF9, 0xFF, 0xFF, 0xCF, 0xFF, 0xF7, 0xFF, 0xFF, 0xF7, 0xFF, 0xE7, 0xFF, 0xFF, 0xFB, 0xFF, 0xCF, 0xFF, 0xFF, 0xFB, 0xFF, 0x1F, 0xFC, 0x3F, 0xF0, 0xFF, 0xE7, 0xFB, 0xCF, 0xF7, 0xFF, 0xF3, 0xF7, 0xEF, 0xCF, 0xFF, 0xF9, 0xEF, 0xF7, 0xBF, 0xFF, 0xFD, 0xCF, 0xF3, 0xFF, 0xFF, 0xFD, 0xDF, 0xFB, 0xFF, 0xFF, 0xFF, 0xDF, 0xFB, 0xFF, 0xFF, 0xFF, 0xEF, 0xF7, 0xFF, 0xFF, 0xFF, 0xE7, 0xF7, 0xFF, 0xFF, 0xFF, 0xF3, 0xEF, 0xFF, 0xFF, 0xFF, 0xF9, 0x9F, 0xFF, 0xFF, 0x7F, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };const uint8_t tstorms_icon[] PROGMEM = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x3F, 0x04, 0xFE, 0xFF, 0xFF, 0xDF, 0xF0, 0xFC, 0xFF, 0xFF, 0xE7, 0xFF, 0xFB, 0xFF, 0xFF, 0xFB, 0xFF, 0xF3, 0xFF, 0xFF, 0xFD, 0xFF, 0xE7, 0xFF, 0xFF, 0xFD, 0xFF, 0x0F, 0xFE, 0x0F, 0xF8, 0xFF, 0x8F, 0xFC, 0xE7, 0xFB, 0xFF, 0xC7, 0xF9, 0xF7, 0xE3, 0xFF, 0xC3, 0xF3, 0xF3, 0xDF, 0xFF, 0xE8, 0xE7, 0xF9, 0xFF, 0xFF, 0xFE, 0xEF, 0xFD, 0xFF, 0xFF, 0xFF, 0xE7, 0xF9, 0xFF, 0xFF, 0xFF, 0xF7, 0xFB, 0xFF, 0xFF, 0xFF, 0xF3, 0xFB, 0xFF, 0xFF, 0xFF, 0xF9, 0xF7, 0xFF, 0xFF, 0xFF, 0xFC, 0xCF, 0xFF, 0xFF, 0x3F, 0xFE, 0x3F, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xBF, 0xBF, 0xFF, 0xFF, 0xFF, 0xDF, 0x8F, 0xFF, 0xFF, 0xFF, 0xEF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7, 0xFB, 0xFF, 0xFF, 0xFF, 0x4F, 0xF7, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xFF, 0xFF, 0xDF, 0xF1, 0xFF, 0xFF, 0xFF, 0xDF, 0xFE, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; String time_str, weather_text, weather_extra_text;int last_reading_hour, reading_hour, hr_cnt;const char* ssid = “UT-VNet”;const char* password = “43246641485350293845”;enum image_names { // enumerated table used to point to images rain_img, sunny_img, mostlysunny_img, cloudy_img, tstorms_img, } image;// Define and enumerated type and assign values to expected weather types.// These values help to determine the average weather preceeding a ‘no-change’ forecast e.g. rain, rain then mostlysun = -1 (-1 + -1 + 1) resulting on balance = more rainenum weather_type {unknown = 4, sunny = 2, mostlysunny = 1, cloudy = 0, rain = -1, tstorms = -2 };enum weather_description {GoodClearWeather, BecomingClearer, NoChange, ClearSpells, ClearingWithin12hrs, ClearingAndColder, GettingWarmer, WarmerIn2daysRainLikely, ExpectRain, WarmerRainWithin36hrs, RainIn18hrs, RainHighWindsClearAndCool, GalesHeavyRainSnowInWinter };weather_type current_wx; // Enable the current wx to be recordedconst uint8_t* image_table[] PROGMEM = {rain_icon, sunny_icon, mostlysunny_icon, cloudy_icon, tstorms_icon}; // An array of image icons// An array structure to record pressure, temperaturre, humidity and weather statetypedef struct { float pressure; // air pressure at the designated hour float temperature; // temperature at the designated hour float humidity; // humidity at the designated hour weather_type wx_state_1hr; // weather state at 1-hour weather_type wx_state_3hr; // weather state at 3-hour point} wx_record_type;wx_record_type reading[24]; // An array covering 24-hours to enable P, T, % and Wx state to be recorded for every hourint wx_average_1hr, wx_average_3hr; // Indicators of average weatherbool look_3hr = true;bool look_1hr = false; SSD1306 display(0x3c, 5,4); // OLED display object definition (address, SDA, SCL)OLEDDisplayUi ui ( &display );//Adafruit_BME280 bme;Adafruit_BMP085 bme; // If using BMP180 or BMP085WiFiClient client; // wifi client object#define pressure_offset 3.3 // Used to adjust sensor reading to correct pressure for your location/////////////////////////////////////////////////////////////////////////// What’s displayed along the top linevoid msOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { display->setTextAlignment(TEXT_ALIGN_LEFT); display->drawString(0,0, time_str.substring(0,8)); //HH:MM:SS Sat 05-07-17 display->setTextAlignment(TEXT_ALIGN_RIGHT); display->drawString(128,0, time_str.substring(9)); display->setTextAlignment(TEXT_ALIGN_LEFT);}// This frame draws a weather icon based on 3-hours of data for the predictionvoid drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { float trend = reading[23].pressure – reading[20].pressure; // Trend over the last 3-hours ForecastToImgTxt(get_forecast_text(reading[23].pressure, trend, look_3hr)); // From forecast and trend determine what image to display display->drawXbm(x+0,y+15, icon_width, icon_height, image_table[image]); // Display corresponding image display->drawStringMaxWidth(x+45,y+12,90,String(reading[23].pressure,1)+” hPA”); // Show current air pressure display->drawStringMaxWidth(x+45,y+25,90,String(trend,1)+” “+get_trend_text(trend)); // and pressure trend}// This frame shows a weather description based on 3-hours of data for the predictionvoid drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { float trend = reading[23].pressure – reading[20].pressure; // Get current trend over last 3-hours weather_description wx_text = get_forecast_text(reading[23].pressure, trend, look_3hr); // Convert to forecast text based on 3-hours ForecastToImgTxt(wx_text); // Display corresponding text display->setFont(ArialMT_Plain_16); display->drawStringMaxWidth(x+0,y+10,127,weather_text); display->setFont(ArialMT_Plain_10);}// This frame draws a graph of pressure (delta) change for the last 24-hours, see Annex* for more detailsvoid drawFrame3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { int gwidth = 75; // Graph width in pixels int gscale = 30; // Graph height in pixels int num_bars = 8; // Number of bars to display #define yscale 8 // Graph +/- y-axis scale e.g. 8 displays +/-8 and scales data accordingly float bar_width = gwidth / (num_bars+1); // Determine bar width based on graph width x = 30; // Sets position of graph on screen y = 15; // Sets position of graph on screen display->drawVerticalLine(x, y, gscale+1); display->drawString(x-18,y-6,”>+”+String(yscale)); display->drawString(x-8,y+gscale/2-6,”0″); display->drawString(x-15,y+gscale-6,”<-“+String(yscale)); display->drawString(x-30,y+gscale/2-6,String(hr_cnt%24)); display->drawString(x+2+(bar_width+3)*0, y+gscale,”-24″); // 24hr marker at bar 0 display->drawString(x+2+(bar_width+3)*2, y+gscale,”-12″); // 12hr marker at bar 2 display->drawString(x+2+(bar_width+3)*5, y+gscale,”-2″); // 2hr marker at bar 5 display->drawString(x+2+(bar_width+3)*7, y+gscale,”0″); // 0hr marker at bar 7 int display_points [8] = {0,5,11,17,20,21,22,23}; // Only display time for hours 0,5,11,17,20,21,22,23 float value; for (int bar_num = 0; bar_num < num_bars; bar_num++){ // Now display a bar at each hour position -24, -18, -12, -6, -3, -2, -1 and 0 hour value = map(reading[display_points[bar_num]].pressure, reading[23].pressure-yscale, reading[23].pressure+yscale, gscale, 0); if (value > gscale) value = gscale; // Screen scale is 0 to e.g. 40pixels, this stops drawing beyond graph bounds if (value < 0 ) value = 0; // 0 is top of graph, this stops drawing beyond graph bounds display->drawHorizontalLine(x+bar_num*(bar_width+3)+2, y+value, bar_width); for (int yplus=gscale; yplus > value; yplus = yplus – 1) { display->drawHorizontalLine(x+bar_num*(bar_width+3)+2, y + yplus, bar_width); } }}// This frame draws a weather icon based on 1-hour of data for the predictionvoid drawFrame4(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { reading[23].pressure = (reading[23].pressure + read_pressure())/2; // Update rolling average, gets reset on the hour transition float trend = reading[23].pressure – reading[22].pressure; // Get short-term trend for the last 1-hour weather_description wx_text = get_forecast_text(read_pressure(), trend, look_1hr); // Convert to forecast text based on 1-hours ForecastToImgTxt(wx_text); display->drawXbm(x+0,y+15, 40, 40, image_table[image]); // Display corresponding image display->drawStringMaxWidth(x+45,y+12,90,”1-Hr forecast”); display->drawStringMaxWidth(x+45,y+22,90,String(read_pressure(),1)+” hPA”); display->drawStringMaxWidth(x+47,y+32,90,String(trend,1)+” “+get_trend_text(trend));}// This frame shows a weather description based on 1-hour of data for the predictionvoid drawFrame5(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { reading[23].pressure = (reading[23].pressure + read_pressure())/2; // Update rolling average float trend = reading[23].pressure – reading[22].pressure; // Get short-term trend weather_description wx_text = get_forecast_text(read_pressure(), trend, look_1hr); // Convert to forecast text based on 1-hours ForecastToImgTxt(wx_text); display->drawString(x+0,y+10,”Short-term forecast:”); display->setFont(ArialMT_Plain_16); display->drawStringMaxWidth(x+0,y+18,127,weather_text); display->setFont(ArialMT_Plain_10);}float read_pressure(){ int reading = (bme.readPressure()/100.0F+pressure_offset)*10; // Rounded result to 1-decimal place return (float)reading/10;}// Convert pressure trend to textString get_trend_text(float trend){ String trend_str = “Steady”; // Default weather state if (trend > 3.5) { trend_str = “Rising fast”; } else if (trend > 1.5 && trend <= 3.5) { trend_str = “Rising”; } else if (trend > 0.25 && trend <= 1.5) { trend_str = “Rising slow”; } else if (trend > -0.25 && trend < 0.25) { trend_str = “Steady”; } else if (trend >= -1.5 && trend < -0.25) { trend_str = “Falling slow”; } else if (trend >= -3.5 && trend < -1.5) { trend_str = “Falling”; } else if (trend <= -3.5) { trend_str = “Falling fast”; } return trend_str;}// Convert forecast text to a corresponding image for display together with a record of the current weathervoid ForecastToImgTxt(weather_description wx_text){ if (wx_text == GoodClearWeather) {image = sunny_img; current_wx = sunny; weather_text = “Good clear weather”;} else if (wx_text == BecomingClearer) {image = mostlysunny_img; current_wx = mostlysunny; weather_text = “Becoming clearer”;} else if (wx_text == NoChange) {image = cloudy_img; current_wx = cloudy; weather_text = “No change, clearing”;} else if (wx_text == ClearSpells) {image = mostlysunny_img; current_wx = mostlysunny; weather_text = “Clear spells”;} else if (wx_text == ClearingWithin12hrs) {image = mostlysunny_img; current_wx = mostlysunny; weather_text = “Clearing within 12-hrs”;} else if (wx_text == ClearingAndColder) {image = mostlysunny_img; current_wx = mostlysunny; weather_text = “Clearing and colder”;} else if (wx_text == GettingWarmer) {image = mostlysunny_img; current_wx = mostlysunny; weather_text = “Getting warmer”;} else if (wx_text == WarmerIn2daysRainLikely) {image = rain_img; current_wx = rain; weather_text = “Warmer in 2-days, rain likely”;} else if (wx_text == ExpectRain) {image = rain_img; current_wx = rain; weather_text = “Expect rain”;} else if (wx_text == WarmerRainWithin36hrs) {image = rain_img; current_wx = rain; weather_text = “Warmer, rain within 36-hrs”;} else if (wx_text == RainIn18hrs) {image = rain_img; current_wx = rain; weather_text = “Rain in 18-hrs”;} else if (wx_text == RainHighWindsClearAndCool) {image = rain_img; current_wx = rain; weather_text = “Rain, high winds, clear and cool”;} else if (wx_text == GalesHeavyRainSnowInWinter) {image = tstorms_img; current_wx = tstorms; weather_text = “Gales, heavy rain, in winter snow”;}}// Convert pressure and trend to a weather description either for 1 or 3 hours with the boolean true/false switchweather_description get_forecast_text(float pressure_now, float trend, bool range) { String trend_str = get_trend_text(trend); weather_description wx_text = NoChange; //As a default forecast image = cloudy_img; // Generally when there is ‘no change’ then cloudy is the conditions if (pressure_now >= 1022.68 ) {wx_text = GoodClearWeather;} if (pressure_now >= 1022.7 && trend_str == “Falling fast”) {wx_text = WarmerRainWithin36hrs;} if (pressure_now >= 1013.2 && pressure_now <= 1022.68 && (trend_str == “Steady” || trend_str == “Rising slow”)) {wx_text = NoChange; (range?wx_history_3hr():wx_history_1hr()); } if (pressure_now >= 1013.2 && pressure_now <= 1022.68 && (trend_str == “Rising” || trend_str == “Rising fast”)) {wx_text = GettingWarmer;} if (pressure_now >= 1013.2 && pressure_now <= 1022.68 && trend_str == “Rising slow”) {wx_text = BecomingClearer;} if (pressure_now >= 1013.2 && pressure_now <= 1022.68 && (trend_str == “Falling slow” || trend_str == “Falling fast”)) {wx_text = ExpectRain;} if (pressure_now >= 1013.2 && pressure_now <= 1022.68 && trend_str == “Steady”) {wx_text = ClearSpells; (range?wx_history_3hr():wx_history_1hr());}; if (pressure_now <= 1013.2 && (trend_str == “Falling slow” || trend_str == “Falling”)) {wx_text = RainIn18hrs;} if (pressure_now <= 1013.2 && trend_str == “Falling fast”) {wx_text = RainHighWindsClearAndCool;} if (pressure_now <= 1013.2 && (trend_str == “Rising” || trend_str==”Rising slow”||trend_str==”Rising fast”)) {wx_text = ClearingWithin12hrs;} if (pressure_now <= 1009.14 && trend_str == “Falling fast”) {wx_text = GalesHeavyRainSnowInWinter;} if (pressure_now <= 1009.14 && trend_str == “Rising fast”) {wx_text = ClearingAndColder;} return wx_text;}// Convert 1-hr weather history to textvoid wx_history_1hr() { if (wx_average_1hr > 0) weather_extra_text = “, expect sun”; else if (wx_average_1hr == 0) weather_extra_text = “, mainly cloudy”; else if (wx_average_1hr < 0) weather_extra_text = “, expect rain”; else weather_extra_text = “”;}// Convert 3-hr weather history to textvoid wx_history_3hr() { if (wx_average_3hr > 0) weather_extra_text = “, expect sun”; else if (wx_average_3hr == 0) weather_extra_text = “, mainly cloudy”; else if (wx_average_3hr < 0) weather_extra_text = “, expect rain”; else weather_extra_text = “”;}///////////////////////////////////////////////////////////////////////////////////////////////////////// This array keeps function pointers to all frames// frames are the single views that slide inFrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5};// how many frames are there?int frameCount = 5;// Overlays are statically drawn on top of a frame eg. a clockOverlayCallback overlays[] = { msOverlay };int overlaysCount = 1;void setup() { float p,t; Serial.begin(115200); Wire.begin(5,4); if (!StartWiFi(ssid,password)) Serial.println(“Failed to start WiFi Service after 20 attempts”);; configTime(1, 3600, “pool.ntp.org”); if (!bme.begin()) { Serial.println(“Could not find a sensor, check wiring!”);} else { Serial.println(“Found a sensor continuing”); while (isnan(bme.readPressure())) { Serial.println(bme.readPressure()); } } while (!update_time()); //Get the latest time for (int i = 0; i <= 23; i++){ // At the start all array values are the same as a baseline reading[i].pressure = read_pressure(); // A rounded to 1-decimal place version of pressure reading[i].temperature = bme.readTemperature(); // Although not used, but avialable reading[i].humidity = bme.readAltitude(); // Although not used, but avialable reading[i].wx_state_1hr = unknown; // To begin with reading[i].wx_state_3hr = unknown; // To begin with } // Note that only 0,5,11,17,20,21,22,23 are used as display positions last_reading_hour = reading_hour; wx_average_1hr = 0; // Until we get a better idea wx_average_3hr = 0; // Until we get a better idea // An ESP is capable of rendering 60fps in 80Mhz mode but leaves little time for anything else, run at 160Mhz mode or just set it to about 30 fps ui.setTargetFPS(20); ui.setIndicatorPosition(BOTTOM); // You can change this to TOP, LEFT, BOTTOM, RIGHT ui.setIndicatorDirection(LEFT_RIGHT); // Defines where the first frame is located in the bar ui.setFrameAnimation(SLIDE_LEFT); // You can change the transition that is used SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN ui.setFrames(frames, frameCount); // Add frames ui.setOverlays(overlays, overlaysCount); // Add overlays ui.init(); // Initialising the UI will init the display too. display.flipScreenVertically(); display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_LEFT);}void loop() { int remainingTimeBudget = ui.update(); update_time_and_data(); if (remainingTimeBudget > 0) { // Do some work here if required //for (int i = 0; i < 24;i++){ // Serial.println(String(i)+” “+String(reading[pressure][i])); //} delay(remainingTimeBudget); }}void update_time_and_data(){ while (!update_time()); if (reading_hour != last_reading_hour) { // If the hour has advanced, then shift readings left and record new values at array element [23] for (int i = 0; i < 23;i++){ reading[i].pressure = reading[i+1].pressure; reading[i].temperature = reading[i+1].temperature; reading[i].wx_state_1hr = reading[i+1].wx_state_1hr; reading[i].wx_state_3hr = reading[i+1].wx_state_3hr; } reading[23].pressure = read_pressure(); // Update time=now with current value of pressure reading[23].wx_state_1hr = current_wx; reading[23].wx_state_3hr = current_wx; last_reading_hour = reading_hour; hr_cnt++; wx_average_1hr = reading[22].wx_state_1hr + current_wx; // Used to predict 1-hour forecast extra text wx_average_3hr = 0; for (int i=23;i >= 21; i–){ // Used to predict 3-hour forecast extra text wx_average_3hr = wx_average_3hr + (int)reading[i].wx_state_3hr; // On average the last 3-hours of weather is used for the ‘no change’ forecast – e.g. more of the same? } } }bool update_time(){ struct tm timeinfo; if(!getLocalTime(&timeinfo)){ Serial.println(“Failed to obtain time”); return false; } //See http://www.cplusplus.com/reference/ctime/strftime/ Serial.println(&timeinfo, “%A, %d %B %y %H:%M:%S”); // Displays: Saturday, 24 June 17 14:05:49 char strftime_buf[64]; strftime(strftime_buf, sizeof(strftime_buf), “%R:%S %a %d-%m-%y”, &timeinfo); time_str = strftime_buf; // Now is this format HH:MM:SS Sat 05-07-17 reading_hour = time_str.substring(0,2).toInt(); return true;}int StartWiFi(const char* ssid, const char* password){ int connAttempts = 0; Serial.println(“rnConnecting to: “+String(ssid)); WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED ) {delay(500);Serial.print(“.”); if(connAttempts > 20) return false;connAttempts++;}Serial.print(“WiFi connectedrnIP address: “);
Serial.println(WiFi.localIP()); return true;}/*FRAME-3 description // This frame draws a graph of pressure (delata) change for the last 24-hours, see Annex* for more details// Draws a ‘relative value’ chart using reading[23] as the baseline// +8 |// +7 |– // : // +1 |– — — — — — — // 0 +-24+-18+-12+-8-+-3-+-2-+-1-+-0-+// -1 | // -2 |// The ‘reading’ array holds values for Pressure, Temperature, Humidity and Wx State for the last 24-hours// [00][01][02][03][04][05][06][07][08][09][10][11][12][13][14][15][16][17][18][19][20][21][22][23] Values are shifted left <– each hour// ^-23Hr ^-18Hr ^-12Hr ^-6Hr ^-3 ^-2 ^-1 ^0Hr// P ~ readings in each array position// T ~ readings in each array position// % ~ readings in each array position// Wx ~ readings in each array position
// Forecast basics:// Look at the pressure change over3 hours// If pressure is descending, then a low pressure area is approaching // If pressure is ascending , then a low is passing or a high pressure is coming// When pressure is changing rapidly (>6hPa/3 hours), it will be windy (or potentially windy)
// More detailed:// Pressure falling slowly (0.5 – 3 hPa in 3h): low is weak, dying or moving slowly. You might get some rain but typically no high winds.// Pressure falling moderately (3-6 hPa/3h): rapid movement or deepening low. Moderate winds and rain and a warm front. : the low is passing fast, the day after tomorrow will typically be fine. // Pressure falling fast (6-12 hPa/3h) : Storm conditions highly likely.// Pressure rises are connected with gradually drier weather
*/
Der neue MicroShip der von der Firma Espressif Systems entwickelt wurde, ist seit einigen Monaten am Markt und bringt eine Menge neue Futures mit.
Eine der angenehmeren Möglichkeiten mit dem [wiki]ESP32[/wiki] ein Projekt umzusetzen, ist das verwenden von “MicroPython”. In Verbindung mit dem “Atom” Editor und dem “pymakr” PlugIn.
SS – CS – 05
SCK – CLK – 18
DO – MISO – 19
DI – MOSI – 23
LCD_RST – LCD_Reset – 36
LCD_CS – ChipSelect – 34
LCD_RS – (RegisterSelect) – 35
LCD_WR – (WRite data) – 04
LCD_RD – (ReaD data) – 02
LCD_D0 – 12
LCD_D1 – 13
LCD_D2 – 26
LCD_D3 – 25
LCD_D4 – 17
LCD_D5 – 16
LCD_D6 – 27
LCD_D7 – 14
WiKi / Infos zum Shield: 2.6″ / 2.8″ TFT_LCD
>>> import gc
>>> gc.collect()
>>> gc.mem_free()
90208
>>> import uos
>> uos.uname()
(sysname=‘esp32’, nodename=‘esp32’, release=‘1.9.3’, version=‘v1.9.3-240-ga275cb0f on 2018-01-27’, machine=‘ESP32 module with ESP32’)
>>>
… ist ein Protokoll um zwischen 2 Geräten Daten in beide Richtungen zu senden.
Als Beispiel: Ein LED-Controller bekommt Informationen/Daten gesendet um zu wissen was er tun soll. Hingegen ein Temperatursensor schickt Daten an den Microkontroller.
Und so läuft das Spiel: