Das zwölfte Türchen

Hoy hay de nuevo un Microcontrolador detrás de la pequeña puerta, con la que no solo puede leer varios sensores y actuadores de control, sino también establecer una conexión WLAN. Es otra Breakout Board con el ESP8266.

Además del procesador con memoria flash de 4 MByte, esta Breakout Board tiene un CP2102 USB a Convertidor Serial para que pueda programar fácilmente el módulo. Se sacan la mayoría de los pines de E / S. También hay un regulador de voltaje que suministra el voltaje de suministro de 3.3 V para el ESP8266 desde el voltaje de suministro USB o el voltaje en la conexión Vin. Aquí hay una nota importante. Dado que el ESP8266 funciona con 3,3 V, no se pueden aplicar voltajes superiores a 3,3 V a sus entradas. Otra ventaja de esta placa es que tiene un paso más estrecho y, por lo tanto, cabe en una placa de pruebas simple.


Como muestra la imagen de portada, queremos usar uno de los controladores junto con una pantalla LCD como se presentó en el calendario de Adviento el 4 de diciembre, para construir un lector de feeds RSS que también muestre la fecha y la hora. Con el lector es posible mostrar las noticias actuales de un suministro de noticias como escritura corrida. La fecha y la hora se obtienen de un servidor de hora NTP.
Un feed RSS es un resumen de noticias en formato XML que ofrecen varios servidores de información en Internet. El servidor ARD se utiliza en el programa de ejemplo. Dado que los mensajes se reciben en formato XML, es fácil mostrar solo ciertas partes de la información completa. Con 16 caracteres por línea, el espacio es muy pequeño, por lo que solo mostramos el título de cada mensaje.
Por ejemplo, aquí está el comienzo de dicho feed:



<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/resources/xsl/rdf_xsl.jsp" type="text/xsl"?>
<rss version="2.0">
<!--
* XML-format for teasering tagesschau.de-headlines. Version: 2.0
* Release-Date:2002/02/04, last updated 2006/06/28
*
* Die Nutzung dieser Inhalte ist ausschliesslich nic⸮ht-kommerziellen Internet-
* Angeboten erlaubt, die Nutzung kann jederzeit von tagesschau.de untersagt
* werden. tagesschau.de übernimmt keinen Support, zudem wird keine Verfügbarkeit
* dieser XML-Datei gewährleistet. Die Inhalte dürfen nicht archiviert werden.
//-->
<channel>
<title>tagesschau.de - Die Nachrichten der ARD</title>
<link>https://www.tagesschau.de</link>
<description>tagesschau.de</description>
<language>de</language>
<copyright>tagesschau.de, Norddeutscher Rundfunk</copyright>
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
<ttl>30</ttl>
<item>
<title>Corona-Katastrophenfall: Bayern will Maßnahmen verschärfen</title>
<link>https://www.tagesschau.de/inland/corona-bayern-119.html</link>
<description>Die Neuinfektionen mit dem Corona-Virus bleiben............</description>
<guid>https://www.tagesschau.de/inland/corona-bayern-119.html</guid>
<category>Inland</category>
</item>
<item>
<title>……………………………..




La etiqueta raíz (pronunciada "tegg" = etiqueta, etiqueta, identificación) dentro de esta etiqueta es la etiqueta , que contiene los mensajes individuales con la etiqueta . Estamos interesados ​​en la etiqueta del título del artículo, por lo que la ruta XML debe ser / rss / channel / item / title.

Primero se requiere un poco de trabajo de soldadura. En primer lugar, la placa del microcontrolador debe estar provista de cabezales de pines. Luego, el adaptador I2C debe soldarse a la pantalla. Recomiendo instalar el adaptador I2C en la parte inferior, ya que no será un estorbo si planea instalarlo en una carcasa.

El cableado es muy simple GND y Vcc de la pantalla que conectamos a GND y Vin del controlador. La línea de reloj SCL llega a D1 y la línea de datos SDA a D2.

Ahora es el momento de programar con Arduino IDE. Si el soporte de las placas con ESP8266 MCU aún no está instalado, tenemos que hacerlo ahora. En el Arduino IDE vamos a Preferences a través del menú File o simplemente con "Ctrl +;".

En el formulario, hacemos clic en el símbolo a la derecha del campo de entrada debajo del elemento "Additional board manager URLs". Aquí ahora podemos ingresar la URL del ESP8266 board manager:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Una vez guardados los ajustes preestablecidos, llamamos al board manager a través del menú Tools-> Board: -> Board manager. Ingresamos “esp8266” como término de búsqueda. Obtenemos la siguiente entrada, que instalamos.

 
Ahora podemos seleccionar un board en el menú Tools-> Board: ->ESP8266 Boards. Usamos NodeMCU 1.0….

 

Ahora todo está listo para instalar el boceto para el lector de noticias.


#include <ESP8266WiFi.h>  //WLAN Unterstützung

#include <TZ.h>           //Zeitzonen Konstanten

#include <LiquidCrystal_I2C.h> //Bibliothek für das LCD Display
#include <TinyXML.h>         //XML-Interpreter zum Lesen des RSS-Feed

//SSID und PSK vom lokalen WLAN
#define STASSID "*********************"
#define STAPSK  "*********************"

//Zeitzone mit Sommer/Winterzeit Information
#define MYTZ TZ_Europe_Berlin

// Timeout zum Lesen des RSS-Feed in Sekunden
#define READ_TIMEOUT 10

//Verarbeitungsschritte
#define ST_CLEAR 0 //neue Daten vom Server holen
#define ST_START 1 //Meldung anzeigen
#define ST_MOVE  2 //Meldung durchschieben
#define ST_END   3 //Meldungsende anzeigen

#define MAXNEWS 10 //Maximale Anzahl der Meldungen
#define RSS_SERVER "www.tagesschau.de" //Nachrichtenserver
#define RSS_FEED "newsticker.rdf"      //Name des Feeds


// LCD Adresse = 0x27, Anzahl Zeichen 16 Anzahl Zeilen 2
LiquidCrystal_I2C lcd(0x27,16,2); 

//WLAN Client Instanz
WiFiClient client;

//XML Interpreter Instanz
TinyXML xml;

//Deutsche Sonderzeichen
uint8_t font [8][9] {
     {0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00}, // 0 °
     {0x11,0x04,0x0a,0x11,0x1f,0x11,0x11,0x00}, // 1 Ä
     {0x11,0x0e,0x11,0x11,0x11,0x11,0x0e,0x00}, // 2 Ö
     {0x11,0x00,0x11,0x11,0x11,0x11,0x0e,0x00}, // 3 Ü
     {0x0a,0x00,0x1e,0x01,0x0f,0x13,0x0d,0x00}, // 4 ä
     {0x0a,0x00,0x0e,0x11,0x11,0x11,0x0e,0x00}, // 5 ö
     {0x0a,0x00,0x12,0x12,0x12,0x12,0x0f,0x00}, // 6 ü
     {0x0c,0x12,0x12,0x14,0x12,0x12,0x14,0x00}  // 7 ß
};


uint8_t buffer[4000];        //Buffer für XML-Interpreter
uint16_t msglen = 0;         //Länge der aktuellen Nachricht
String msg;                  //aktuelle Nachricht
String news[MAXNEWS];        //Speicher für Nachrichten 
uint8_t newsCnt = 0;         //Anzahl der aktuellen Nachrichten im Speicher
uint8_t curNews = 0;         //Index der gerade angezeigten Nachricht
uint8_t step = 0;            //Aktueller Verarbeitungsschritt
uint16_t pos = 0;            //Startposition zum Durchschieben

//Deutsche Umlaute (UTF8) fürs Display codieren
String extraChar(String text){
  String res = "";
  uint8_t i = 0;
  char c;
  while (i<text.length()) {
    c=text[i];
    if (c==195) { //UTF8 Deutsche Umlaute
      i++;
      switch (text[i]) {
        case 164: c=4; break; //ä
        case 182: c=5; break; //ö
        case 188: c=6; break; //ü
        case 159: c=7; break; //ß
        case 132: c=1; break; //Ä
        case 150: c=2; break; //Ö
        case 156: c=3; break; //Ü
        default: c=0;
      }
    } else if (c == 194) { //UTF8 Sonderzeichen
      i++;
      if (text[i] == 176) c=0xdf; else c=0;
    } else if (c > 128) { //normal characters unchanged
      c=255;
    }
    if (c>0) res.concat(c);
    i++;
  }
  return res;
}


//Diese Funktion wird vom XML-Interpreter aufgerufen, wenn ein XML-Tag gelesen wurde
//tagName enthält den vollständigen XML-Pfad des Tags, data den Inhalt des Tags
void XML_callback(uint8_t statusflags, char* tagName, uint16_t tagNameLen, char* data, uint16_t dataLen) {
  if (statusflags & STATUS_TAG_TEXT) {
    //Serial.println(tagName);
    //wenn wir einen Titel-Tag finden, und die maximale Anzahl der Meldungen noch
    //nicht erreicht ist, wird die Meldung gespeichert und der Zähler erhöht
    if (strcasecmp(tagName,"/rss/channel/item/title")==0) {
      data[dataLen] = '\0';
      Serial.printf("%i %s\n",newsCnt,data);
      if (newsCnt < MAXNEWS) { 
        news[newsCnt] = data;
        newsCnt++;
      }
    }
  }
}

//Neue Nachrichten vom RSS-Feed lesen
boolean getNews() {
  boolean res = false;
  boolean timedOut = false;
  char c;
  newsCnt = 0;
  //nur wenn wir eine Internetverbindung haben
  if(WiFi.status()== WL_CONNECTED){
    //zuerst mit dem HTTP-Server verbinden
    Serial.println("Mit Server verbinden");
    if(client.connect(RSS_SERVER, 80)) {
      Serial.println("OK\r\nRequesting data...");
      //Nun können wir die XML-Seite mit dem Feed holen
      client.print("GET /");
      client.print(RSS_FEED);
      client.print(" HTTP/1.1\r\nHost: ");
      client.print(RSS_SERVER);
      client.print("\r\nConnection: Close\r\n\r\n");
      client.flush();
      //den XML-Interpreter vorbereiten
      xml.reset();
      newsCnt = 0;
      uint32_t t = millis(); // Startzeit
      while(client.connected()) {
        if((c = client.read()) >= 0) {
          //Solange wir Zeichen vom Webserver erhalten, werden diese
          //zur Interpretation an den XML Interpreter weitergegeben
          xml.processChar(c);
          delay(1); //Verzögerung 1ms sonst kommt der XML Interpreter nicht nach
          t = millis(); // Reset timeout clock
        } else if((millis() - t) >= (READ_TIMEOUT * 1000)) {
          //Im Falle eines Timeouts wird die Interpretation abgebrochen
          Serial.println("---Timeout---");
          timedOut = true;
          break;
        }
      }
      if (timedOut) Serial.println("Timeout");
      if(!timedOut && (newsCnt > 0)) { 
        //Falls Nachrichten empfangen wurden, wird die erste Nachricht angezeigt
        curNews = 0;
      }
    }
    client.stop();
  } else {
    //war keine Internet Verbindung vorhanden
    //wird ein neuer Verbindungsversuch gestartet
    //und eine Fehlermeldung angezeigt
    news[0] = "Keine Internetverbindung!";
    newsCnt = 1;
    curNews = 0;
  }
}

//Anzeige aktualisieren
void updateDisplay() {
  //erste Zeile Zeit und Datum
  time_t now; //aktuelle Zeit 
  struct tm * s_time; //Zeitstruktur aufgesplittet in Jahr, Monat, Tag, Stunden, Minuten und Sekunden
  char line_buffer[20]; //Buffer für Anzeigenzeile
  now = time(nullptr); //aktuelle Zeit lesen
  s_time = localtime(&now); //für die lokale Zeit in die Zeitstruktur umwandeln
  //Zeilenbuffer mit Uhrzeit und Datum füllen
  strftime(line_buffer,17,"%d.%m.%Y %H:%M",s_time);
  //Uhrzeit auf die serielle Schnittstelle ausgeben
  //Serial.println(line_buffer);
  //Uhrzeit am Display in Zeile 1 anzeigen  
  lcd.setCursor(0,0);
  lcd.print(line_buffer);
  //zweite Zeile Nachrichten
  lcd.setCursor(0,1);
  switch (step) {
    case ST_CLEAR: step = ST_START; //Nächster Schritt
        if (curNews >= newsCnt) {
          lcd.print("Aktualisierung.."); 
          getNews(); //neue Nachrichten holen
          curNews = 0;
        } else {
          curNews++; //nächste Nachricht starten
          lcd.print("                "); 
          if (curNews >= newsCnt) step = ST_END;
        }
        msg = extraChar(news[curNews]);
        msglen = msg.length();
        break;
    case ST_START:lcd.print(msg.substring(0,16));
        pos = 0; //Startposition einnehmen
        step = ST_MOVE;
        break; 
    case ST_MOVE: pos++;
        lcd.print(msg.substring(pos,pos+16));
        //wenn die Nachricht fertig ist, nächste Nachricht
        if (pos > (msglen-17)) step=ST_END;
        break;
    case ST_END: step = ST_CLEAR;
        break;
  }
}

//Setup Funktion
void setup() {
  Serial.begin(115200); //Serielle Schnittstelle initialisieren
  //XML-Interpreter initialisieren
  xml.init((uint8_t *)buffer, sizeof(buffer), &XML_callback);
  //Display initialisieren und Beleuchtung ein
  lcd.init(); //bei älteren Versionen der Bibliothek muss der Aufruf lcd.begin(); heißen  
lcd.backlight();  //Deutsche Umlaute erzeugen  for (uint8_t i = 0; i<8; i++) lcd.createChar(i, font[i]);  //Display löschen und Startmeldung anzeigen  lcd.clear();  lcd.setCursor(0,0);  lcd.print("AZ-Delivery");  lcd.setCursor(0,1);  lcd.print("Einen Moment....");  //Interne Uhr konfigurieren  configTime(MYTZ, "pool.ntp.org");  //WLAN initialisieren und mit dem WLAN verbinden  WiFi.persistent(false);  WiFi.mode(WIFI_STA);  WiFi.begin(STASSID, STAPSK);  uint8_t cnt = 0;  //warten bis Verbindung hergestellt wurde  while ((WiFi.status() != WL_CONNECTED) && (cnt<10)) {    Serial.println(WiFi.status());    cnt++;    delay(500);  }  newsCnt = 0;  step = ST_CLEAR; } //Hauptschleife void loop() {  //Zeit anzeigen  updateDisplay();  //Verzögerung fürs Durchschieben  delay(500); }

 Descargar boceto

Casi todo lo que necesitamos está incluido en el paquete ESP8266. Solo faltan las bibliotecas para la pantalla LCD y para evaluar los datos XML. Se pueden instalar a través de library manager en el Arduino IDE.

Ingresamos “I2C LCD” como término de búsqueda y encontramos la biblioteca deseada un poco más abajo en la lista.

 

Luego ingresamos “Tiny XML” como término de búsqueda y obtenemos la biblioteca deseada.

 

Antes de compilar el boceto, debemos ingresar los datos de acceso para la WLAN en lugar de los asteriscos.

Es posible que también desee seleccionar un servidor de noticias diferente, una fuente diferente en este servidor y / o una cantidad diferente de mensajes. Luego tiene que cambiar las entradas #define correspondientes. El número de mensajes no debe ser superior a 10.

No se sorprenda si recibe la siguiente advertencia durante la compilación.

ADVERTENCIA: La biblioteca LiquidCrystal_I2C afirma que se ejecuta en arquitectura (s) avr y puede ser incompatible con su placa actual que se ejecuta en arquitectura (s) esp8266.

Esta advertencia proviene del hecho de que se realizó una entrada incorrecta en las especificaciones de la biblioteca. La biblioteca funciona bien con ESP8266 MCUs.

Después de que se hayan mostrado todos los mensajes del servidor de noticias, los mensajes se obtienen del servidor nuevamente. La hora se actualiza continuamente. Cambia automáticamente entre el horario de verano y el de invierno.

Diviértase con la réplica de este proyecto. 

MuestraPrecipitador electrostático - 8266Specials

6 comentarios

Hans-Jürgen Pollmer

Hans-Jürgen Pollmer

Hallo,
mit den Änderungen von Paul läuft der Sketch problemlos.
Ich würde aber gern das liquidcrystal_i2c-Display durch Matrixmodule max7219 ersetzen.
Wie ist der Sketch zu ändern, oder gibt es schon fertige Projekte damit?
Vielen Dank für evtl. Lösungen.

Paul

Paul

Vielen Dank für diese Idee. So, wie ihr sie vorgestellt habt, funktioniert sie leider nicht, da tagesschau.de Daten nur über einen https-Request ausgibt. Aber mit einem kleinen Umbau des Sketches läßt sich der Server überreden, doch Daten zu senden.

1. Erweiterung der Einbindung von Bibliotheken um die SlientSecure-Bibliothek:
#include

2. Die WLAN-Client Instanz ändern auf
WiFiClientSecure client;

3. in der boolean-Routine getNews() den Server-Port für die Client-Verbindung zum Server ändern von 80 auf 443

4. Im Setup vor dem Befehl WiFi.begin folgende Zeile hinzufügen:

client.setInsecure();

Mit diesem kleinen Umbau funktioniert der Sketch und damit auch der RSS-Reader problemlos und zeigt die Titel auf dem LC-Display an.

Der Befehl “client.setInsecure()” ermöglicht das Abfragen von Daten vom HTTPS-Server, ohne den FIngerprint senden zu müssen, der sonst vorhanden sein müsste, sich aber in einem bestimmten Interval immer wieder ändert.

Harry

Harry

Der Tagesschau Feed kann nicht mehr geladen werden da die Server nur noch verschlüsselte Verbindungen beantworten.
Also entweder das Programm reparieren oder auf einen unverschlüsselten Feed ausweichen. z.B.
#define RSS_SERVER “newsfeed.zeit.de” //Nachrichtenserver
#define RSS_FEED “index” //Name des Feeds

Wominator

Wominator

Sehr geehrter Herr Lechner,
ich habe dieses Projekt nachgebaut, mit einem LCD 20×4 und einem D1Mini. Display, WiFi usw. funktioniert, aber der RSS-Feed wird nicht abgerufen. Auf dem Display erscheint das aktuelle Datum, die Uhrzeit und “Aktualisierung..” Dann passiert nichts mehr.
Im Seriellen Monitor wird angezeigt:
01:13:08.880 → Mit Server verbinden
01:13:08.880 → OK
01:13:08.880 → Requesting data…
01:13:11.088 → Mit Server verbinden
01:13:11.088 → OK
01:13:11.088 → Requesting data…
01:13:13.296 → Mit Server verbinden
01:13:13.343 → OK
01:13:13.343 → Requesting data…
01:13:15.535 → Mit Server verbinden
01:13:15.582 → OK
01:13:15.582 → Requesting data…
01:13:17.758 → Mit Server verbinden
01:13:17.812 → OK
Egal, ob ich den RSS-Feed von der tagesschau oder von Heise eingebe, immer das selbe Ergebnis. Haben Sie eine Idee, warum der Feed nicht geladen und angezeigt wird?
Danke im Voraus!
Womi

Bernd-Steffen Großmann

Bernd-Steffen Großmann

Hi Anthony, I have this problem (the first two letters are not readable) too, but only with iOS (Safari). It works properly with Chrome, Firefox, and other browsers on Windows or Android. Sincerely Bernd-Steffen

Anthony Goodhew

Anthony Goodhew

Formatting of this blog not working properly.

Deja un comentario

Todos los comentarios son moderados antes de ser publicados

Artículos de blog

  1. Ahora instalamos el esp32 a través de la administración.
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. Transporte Aéreo - programación de ESP mediante redes locales inalámbricas