Stazione meteorologica online

Questo è il codice iniziale, quando accendo il dispositivo non sempre mi da la scritta Display Meteorologico Online, ma mi da una sorta di schermo stellato.

#include <ESP8266WiFi.h>
#include <stdio.h>
#include <ArduinoJson.h>
#include <U8g2lib.h>
#define SUN  0
#define SUN_CLOUD  1
#define CLOUD 2
#define RAIN 3
#define THUNDER 4
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);   // Tutte le schede senza reset del display
//initiate the WifiClient
WiFiClient client;
const char* ssid = "XXXXX"; // Inserire nome rete wifi                         
const char* password = "XXXXXX";                 
unsigned long lastCallTime = 0;                     // Controlla se hai chiamato la funzione updateWeather, in millisecondi
const unsigned long postingInterval = 30L * 1000L;  // Ritardo tra gli aggiornamenti, in millisecondi
String APIKEY = "XXXXXXXXX"; // Inserire la chiave API dal sito home.openweathermap.org
String NameOfCity = "XXXXXXXX"; // Inserisci qui il nome della città per la quale desideri ottenere i dati.  
void setup()
{  
  u8g2.begin();
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawStr(0,20,"Display");
    u8g2.drawStr(28,40,"Meteorologico");
    u8g2.drawStr(56,60,"Online");
  } while ( u8g2.nextPage() );
  u8g2.enableUTF8Print();   // Simbolo del grado
  Serial.begin(115200);
  Serial.println("\n\nDisplay Meteorologico Online\n");
  Serial.println("Connecting to network");
  WiFi.begin(ssid, password);
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) 

Io come prima cosa nel setup metterei un delay di 300

Fatto ma non è cambiato nulla, stesso problema.

void setup()
{  
  u8g2.begin();
  u8g2.firstPage();
  do {
    delay(300); // Pausa di 300 ms
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawStr(0,25,"Display");
    u8g2.drawStr(30,45,"Meteo");
    u8g2.drawStr(60,64,"Online");
  } while ( u8g2.nextPage() );
  u8g2.enableUTF8Print();   // Simbolo del grado
  Serial.begin(115200);
  Serial.println("\n\nDisplay Meteorologico Online\n");
  Serial.println("Connecting to network");
  WiFi.begin(ssid, password);

Io dico come "prima cosa" e tu lo metti come terza cosa e dentro ad un ciclo

Cosa intendi che vedi a volte una roba stellata ? Riesci a fare una foto ?
Forse non riesce a inizializzare il display alla partenza. Per questo l'idea di un delay.
Magari come seconda cosa, dopo il u8g2.begin.
Puoi usare la seriale usb ? Sarebbe utile usare il monitor seriale per mettere dei msg di diagnostica

Ma è fisso o si muovono ?
Sposta Serial.begin(115200); come prima cosa, e verifica se su monitor seriale arriva
alla Serial.println("\n\nDisplay Meteorologico Online\n");
Metti anche una Serial.println("inizio"); subito dopo la Serial.begin, per capire dove arriva

I punti sono fissi, mi faresti vedere come riscrivere il codice?

void setup()
{ delay(300);
  Serial.begin(115200);
  Serial.println("avvio...");  
  u8g2.begin();
  Serial.println("u8g begin");
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawStr(0,25,"Display");
    u8g2.drawStr(30,45,"Meteo");
    u8g2.drawStr(60,64,"Online");
  } while ( u8g2.nextPage() );
  Serial.println("u8g logo");
  u8g2.enableUTF8Print();   // Simbolo del grado
  Serial.println("\n\nDisplay Meteorologico Online\n");
...
1 Like

I punti sul display sono aumentatati ma adesso si aggiorna lo schermo.

Sulla seriale cosa vedi ?

Devo controllare l'Hardware, mi sa che il problema non è software!

Ho potuto costatare che il problema è hardware, perché se stacco e riattacco l'alimentazione più volte il software comincia a funzionare, come hardware sto usando un wemos mini 1 e il display un oled da "0.96 comprati su wish

Come alimenti il tutto ?

Normale alimentatore USB da 1 ampere.


Da come vedi il display funziona sempre quando e se parte. A questo punto individuato il problema che è l'hardware passo avanti nel risolvere il problema software, adesso il problema è il fatto che dopo questa schermata non va avanti dovrebbe collegarsi al sito meteo e darmi le info. ti passo il restante codice.

Serial.println("\n\nDisplay Meteo Online\n");
  Serial.println("Connecting to network");
  WiFi.begin(ssid, password);
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);    
    if (++counter > 100) 
      ESP.restart();
    Serial.print( "." );
  }
  Serial.println("\nWiFi connected");
  printWifiStatus();
}
void loop() 
{    
  if (millis() - lastCallTime > postingInterval) 
  {
    updateWeather();
  }
}
void updateWeather()
{     
  // In caso di connessione stabilita
  if (client.connect("api.openweathermap.org", 80)) 
  {
    Serial.println("Connessione al server OpenWeatherMap...");
    // Invia la richiesta HTTP PUT:
    client.println("GET /data/2.5/weather?q=" + NameOfCity + "&units=metric&APPID=" + APIKEY + "HTTP/1.1");
    client.println("Host: api.openweathermap.org");
    client.println("Connection: close");
    client.println();
    // Controlla lo stato HTTP
    char status[32] = {0};
    client.readBytesUntil('\r', status, sizeof(status));
    // Dovrebbe essere "HTTP/1.0 200 OK" o "HTTP/1.1 200 OK"
    if (strcmp(status + 9, "200 OK") != 0) 
    {
      Serial.print(F("Unexpected response: "));
      Serial.println(status);
      return;
    }
    // Skip HTTP headers
    char endOfHeaders[] = "\r\n\r\n";
    if (!client.find(endOfHeaders)) 
    {
      Serial.println(F("Invalid response"));
      return;
    }
    // Allocate the JSON document
    // Use arduinojson.org/v6/assistant to compute the capacity.
    const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + 2*JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(13) + 270;
    DynamicJsonDocument doc(capacity);
    // Parse JSON object
    DeserializationError error = deserializeJson(doc, client);
    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.c_str());
      return;
    }
    int weatherId = doc["weather"][0]["id"].as<int>();
    float weatherTemperature = doc["main"]["temp"].as<float>();
    int weatherHumidity = doc["main"]["humidity"].as<int>();
    //Disconnect
    client.stop();
    Serial.println(F("Response:"));
    Serial.print("Weather: ");
    Serial.println(weatherId);
    Serial.print("Temperature: ");
    Serial.println(weatherTemperature);
    Serial.print("Humidity: ");
    Serial.println(weatherHumidity);
    Serial.println();
    char scrollText[15];
    sprintf(scrollText, "Humidity:%3d%%", weatherHumidity);
    if(weatherId == 800)    //clear
    {
      draw(scrollText, SUN, weatherTemperature);
    }
    else
    {
      switch(weatherId/100)
      {
        case 2:     //Thunderstorm
            draw(scrollText, THUNDER, weatherTemperature);
            break;
    
        case 3:     //Drizzle
        case 5:     //Rain
            draw(scrollText, RAIN, weatherTemperature);
            break;
        case 7:     //Sun with clouds
            draw(scrollText, SUN_CLOUD, weatherTemperature);
            break;
        case 8:     //clouds
            draw(scrollText, CLOUD, weatherTemperature);
            break;
        default:    //Sun with clouds           
            draw(scrollText, SUN_CLOUD, weatherTemperature);
            break;
      }    
    }
  } 
  else 
  {
    // if you couldn't make a connection:
    Serial.println("connection failed");
  }
  // note the time that this function was called
   lastCallTime = millis();
}
void printWifiStatus() 
{
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}
void drawWeatherSymbol(u8g2_uint_t x, u8g2_uint_t y, uint8_t symbol)
{
  // fonts used:
  // u8g2_font_open_iconic_embedded_6x_t
  // u8g2_font_open_iconic_weather_6x_t
  // encoding values, see: https://github.com/olikraus/u8g2/wiki/fntgrpiconic
  switch(symbol)
  {
    case SUN:
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 69);  
      break;
    case SUN_CLOUD:
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 65); 
      break;
    case CLOUD:
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 64); 
      break;
    case RAIN:
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 67); 
      break;
    case THUNDER:
      u8g2.setFont(u8g2_font_open_iconic_embedded_6x_t);
      u8g2.drawGlyph(x, y, 67);
      break;      
  }
}
void drawWeather(uint8_t symbol, int degree)
{
  drawWeatherSymbol(0, 48, symbol);
  u8g2.setFont(u8g2_font_logisoso32_tf);
  u8g2.setCursor(48+3, 42);
  u8g2.print(degree);
  u8g2.print("°C");   // requires enableUTF8Print()
}
/*
  Draw a string with specified pixel offset. 
  The offset can be negative.
  Limitation: The monochrome font with 8 pixel per glyph
*/
void drawScrollString(int16_t offset, const char *s)
{
  static char buf[36];  // should for screen with up to 256 pixel width 
  size_t len;
  size_t char_offset = 0;
  u8g2_uint_t dx = 0;
  size_t visible = 0;
  len = strlen(s);
  if ( offset < 0 )
  {
    char_offset = (-offset)/8;
    dx = offset + char_offset*8;
    if ( char_offset >= u8g2.getDisplayWidth()/8 )
      return;
    visible = u8g2.getDisplayWidth()/8-char_offset+1;
    strncpy(buf, s, visible);
    buf[visible] = '\0';
    u8g2.setFont(u8g2_font_8x13_mf);
    u8g2.drawStr(char_offset*8-dx, 62, buf);
  }
  else
  {
    char_offset = offset / 8;
    if ( char_offset >= len )
      return; // nothing visible
    dx = offset - char_offset*8;
    visible = len - char_offset;
    if ( visible > u8g2.getDisplayWidth()/8+1 )
      visible = u8g2.getDisplayWidth()/8+1;
    strncpy(buf, s+char_offset, visible);
    buf[visible] = '\0';
    u8g2.setFont(u8g2_font_8x13_mf);
    u8g2.drawStr(-dx, 62, buf);
  }
}
void draw(const char *s, uint8_t symbol, int degree)
{
  int16_t offset = -(int16_t)u8g2.getDisplayWidth();
  int16_t len = strlen(s);
  for(;;)
  {
    u8g2.firstPage();
    do {
      drawWeather(symbol, degree);      
      drawScrollString(offset, s);
    } while ( u8g2.nextPage() );
    delay(20);
    offset+=2;
    if ( offset > len*8+1 )
      break;
  }
}

DEVI fare debug usando il monitor seriale. Riempi di Serial.println("dove sono");
ovvero tramite serial monitor vedi i messaggi del codice in base al punto in cui è arrivato.
Ad esempio arriva al msg Serial.println("\nWiFi connected"); ??

Scusa la funzione monitor seriale non la conoscevo ho fatto ricerca su internet per capire di cosa parlavi.
Non andava avanti perché non si connetteva alla rete però mi fa strano che non dava il messaggio sul monitor "Connecting to network". Comunque ho corretto e ho inserito i dati corretti, ma dal monitor seriale mi da questo errore:
Connessione al server OpenWeatherMap...
Unexpected response: {"cod":401, "message": "Invalid

Mi sembra chiaro che "OpenWeatherMap" ti sta dando un messaggio di errore ... se lo riporti completo e non solo un pezzetto ({"cod":401, "message": "Invalid") , vedrai quale è il problema nella tua richiesta al server.

Guglielmo

Mi da solo questo messaggio che si ripete in loop

Ce un'altra cosa che ho notato solo adesso non vedo nel mio programma le assegnazione per le porte da usare per il display.


Ci dovrebbero essere assegnati la D1 e la D2.