Go Down

Topic: previsioni meteo con rss + esp8266 (Read 1 time) previous topic - next topic

uscrocc

Ciao ragazzi il mio intento è quello di prendere dei valori tramite una pagina xml di un sito meteorologico collegandomi al server grazie al wifi di casa utilizzando l'esp8266. Devo stampare i valori nel monitor seriale.

Il sito dove ho visto l'idea
Ecco il codice originale




uscrocc

Ecco il codice che ho modificato ma mi sono confuso un po:
Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial ESPserial(9, 10); // RX | TX
bool debug = true;

char AP[] = "Hipercom1067118";
char password[] = "gbveeu308812";

#define WEATHER
//#define BIGWEATHER

//----------------------------------------------------------------------------------|
//                                  WEATHER
//----------------------------------------------------------------------------------|
#ifdef WEATHER // http://w1.weather.gov/xml/current_obs/KPDX.xml"
char dataServer[] = "w1.weather.gov";
char dataPage[] = "/xml/current_obs/KPDX.xml";
const char *elements[]  = {"temp_f", "relative_humidity", "pressure_in", "wind_dir", "wind_mph", "<weather"};
char *elementPreLabels[]  = {"", " ", "Pressure: ", "", " @ ", ""};
char *elementPostLabels[]  = {"F ", "% Humidity", "in", "", "MPH", ""};
const char dataEnd = '/';
const byte normalStartBias = 1;
const byte normalEndBias = -1;
const char elementCols[] = {2, 1, 2, 1};
const byte maxDataLength = 21;
char charBuf[50];
long reloadDelay = 60000;
#endif
//----------------------------------------------------------------------------------|
//                                  WEATHER  (BIG FONT)
//----------------------------------------------------------------------------------|
#ifdef BIGWEATHER // http://w1.weather.gov/xml/current_obs/KPDX.xml"
char dataServer[] = "w1.weather.gov";
char dataPage[] = "/xml/current_obs/KPDX.xml";
const char *elements[]  = {"temp_f", "relative_humidity", "wind_mph"};
char *elementPreLabels[]  = {"", "", ""};
char *elementPostLabels[]  = {"F ", "%", "MPH"};
const char dataEnd = '/';
const byte normalStartBias = 1;
const byte normalEndBias = -1;
const char elementCols[] = {2, 1};
#define BIGTEXT
//#define BIGLABELS
const byte maxDataLength = 5;
char charBuf[20];
long reloadDelay = 60000;
#endif
//----------------------------------------------------------------------------------
byte GETdelay = 0;
byte maxLineLength = 100;
long dataTimer;
long bufferTimer;
bool getDataTest = true;
bool startupTest = true;
byte memPos = 0; // Memory offset
const byte elementsArrayLength = sizeof(elements) / sizeof(*elements);
const byte colArrayLength = sizeof(elementCols) / sizeof(*elementCols);
char *elementValues[elementsArrayLength + 1];
byte char_x = 0, char_y = 0;
String serialData;
String lastData;

#ifdef CUSTOMBIAS
const byte customElementsArrayLength = sizeof(customBiasElements) / sizeof(*customBiasElements);
#endif
#ifdef INSTANCENUMBER
byte dataInstance = 0;
#endif

bool IPDflag = false;
byte IPDcheck = 0;

void setup() {
  Serial.begin(115200);                     // fast output helps reduce softserial input overflow
  ESPserial.begin(9600);                    // slow serial keeps things behaving well
  delay(1000);
  sendData("AT+RST\r\n", 2000, true);       // reset the ESP8266
  Serial.println("");
  sendData("AT+CWMODE=1\r\n", 1000, true);  // Set to mode 1 (Station Mode)
  char ATcmd[44];
  ATcmd[0] = 0;
  strcat(ATcmd, "AT+CWJAP=\"");              // make command: "AT+CWJAP=\"access point\",\"password\""
  strcat(ATcmd, AP);
  strcat(ATcmd, "\",\"");
  strcat(ATcmd, password);
  strcat(ATcmd, "\"\r\n");
  Serial.print(F("Set ATcmd[] to: "));
  Serial.println(strlen (ATcmd) + 1);
  sendData(ATcmd, 10000, true);             // Join Wifi network
  sendData("AT+CIFSR\r\n", 1000, true);     // Print IP address
}

continuo il void loop sotto

uscrocc

Code: [Select]

void loop() {
  if (getDataTest) {
    getData();
    if (debug) Serial.print(F("Available RAM: ")); Serial.println(freeRam());
  }

  if (printSerialTest && startupTest) {
    startupTest = false;
    Serial.clear();
  }

  if (!startupTest && printSerialTest) {
    if (debug) Serial.print(F("Available RAM: ")); Serial.println(freeRam());
    printDataToSerial();
  }

  serialBuffer();                   // alwasy look for incoming data
  pageDelayTimer(reloadDelay);      // Re-Load the webpage
}

void getData() {
  char ATcmd[200];
  ATcmd[0] = 0;
  strcat(ATcmd, "AT+CIPSTART=\"TCP\",\"");        // make command: AT+CPISTART="TCP","www.anyurl.com",80
  strcat(ATcmd, dataServer);
  strcat(ATcmd, "\",80\r\n");
  sendData(ATcmd, 1000, true);
  ATcmd[0] = 0;
  strcat(ATcmd, "GET ");                          // make command: GET /anypage.html HTTP/1.0\r\nHost: www.anyurl.com\r\n\r\n
  strcat(ATcmd, dataPage);
  strcat(ATcmd, " HTTP/1.1\r\nHost: ");
  strcat(ATcmd, dataServer);
  strcat(ATcmd, "\r\nUser-Agent: Mozilla/4.0");   // some servers i.e. weather.gov require this
  strcat(ATcmd, "\r\nConnection: close");
  strcat(ATcmd, "\r\n\r\n");
  sendData("AT+CIPSEND=", 0, true);               // the ESP8266 needs to know the size of the GET request
  ESPserial.print(strlen (ATcmd));
  printSerial();
  sendData("\r\n", 1000, true);                   // wait for the > prompt from the esp8266
  sendData(ATcmd, GETdelay, false);
  ATcmd[0] = 0;
  memPos = 0;
  getDataTest = false;
#ifdef INSTANCENUMBER
  dataInstance = 0;
#endif
}


void serialBuffer() {
  byte instanceElement;

  while (ESPserial.available() > 0) {
    SerialTimer = millis();                  // don't refresh the Serial if we are downloading data

#ifdef INSTANCENUMBER
    if (dataInstance == INSTANCENUMBER) {
      ESPserial.read();
      break;
    }
#endif

    char received = ESPserial.read();

    if (serialData.length() < maxLineLength || received == '\n') {
      serialData += received;
    }

#ifdef CUSTNEWLINECHAR
    if (received == '\n' || received == CUSTNEWLINECHAR)    {        // Process message when new line character is received
      if (received == CUSTNEWLINECHAR && debug)Serial.println("");
#else
    if (received == '\n') {
#endif

      if (serialData.indexOf("OK") == 0) {                         //  remove +IPD messages
        IPDflag = true;
        IPDcheck = 3;
        if (debug) Serial.println(F("--FOUND OK"));
      }
      if (IPDcheck > 0) {
        IPDcheck--;
      }
      if (IPDcheck == 0)IPDflag = false;                           // Found "OK" but not "+IPD" so reset for next one
      if (serialData.indexOf("+IPD,") == 0) {
        byte ipdEnd = serialData.indexOf(':');
        byte newLine = lastData.indexOf('\n');
        serialData = serialData.substring(ipdEnd + 1);
        lastData = lastData.substring(0, newLine - 1);
        serialData = lastData + serialData;
        IPDflag = false;
        if (debug) Serial.println(F("--FOUND +IPD: Reprinting last line "));
      }

      if (!IPDflag) {
        lastData = serialData;                // save this line of data in case of IPD+ Event
      }

      if (debug)Serial.print(F("Arduino Received "));               // print webpage to serial monitor
      if (debug)Serial.print(serialData);

      int elementPos;
      byte elementLength;
      byte endElement;
      char startBias, endBias;

      for (byte i = 0; i < elementsArrayLength; i++) {
        elementLength = strlen (elements[i]);
        elementPos = serialData.indexOf(elements[i]);
        endElement = serialData.indexOf(dataEnd);

        if (elementPos > -1)  {                                       // Found the element!!!
          ////!!!!!!! TODO: if don't find end element

#ifdef INSTANCENUMBER
          dataInstance++;
#endif

#ifdef CUSTOMBIAS                                  // Check for custom bias
          bool customFlag = false;
          for (byte k = 0; k < customElementsArrayLength; k++) {
            if (elements[i] == customBiasElements[k]) {
              startBias = customStartBias;
              endBias = customEndBias;
              customFlag = true;
              break;
            }
          }
          if (!customFlag) {
            startBias = normalStartBias;
            endBias = normalEndBias;
          }
#else
          startBias = normalStartBias;
          endBias = normalEndBias;
#endif

          serialData = serialData.substring(elementPos + elementLength + startBias, endElement + endBias);
          if (serialData == "")serialData = "-";        // if no value, replace with a dash
          serialData.toCharArray(charBuf + memPos, maxDataLength);
          elementValues[i] = charBuf + memPos;
          // if (!memPosIPDflag)memPos = memPos + serialData.length() + 1;  //!!! TODO if IPD flag don't increment memPos
          memPos = memPos + serialData.length() + 1;

          //  memPosIPDflag = false;
          if (debug) {

#ifdef CUSTNEWLINECHAR
            if (received == CUSTNEWLINECHAR) Serial.println("");
#endif
            Serial.print(F("FOUND "));
            Serial.print(elements[i]);
            Serial.print(F("  VALUE="));
            Serial.print(elementValues[i]);
            Serial.print(F("  MEMORY BUF From "));
            Serial.print(memPos - serialData.length() - 1);
            Serial.print(F(" To "));
            Serial.println(memPos);
          }
          break;  // no need to keep searching for a match
        }
      }
      serialData = ""; // to flush the value.
      if (ESPserial.overflow()) Serial.println(F("<----! SoftwareSerial overflow !---->"));
    }
  }
}
void sendData(char command[], int wait, bool printSer) {
  ESPserial.print(command);
  delay(wait);
  if (printSer)printSerial();
}

void printSerial() {
  while (ESPserial.available() > 0)
  {
    char a = ESPserial.read();
    if (a == '\0')
      continue;
    if (a != '\r' && a != '\n' && (a < 32))
      continue;
    Serial.print(a);
    if (ESPserial.overflow()) Serial.println(F("<----! SoftwareSerial overflow !---->"));
  }
}

void pageDelayTimer(long delayTime) {
  if (dataTimer + delayTime < millis()) {
    dataTimer = millis();
    getDataTest = true;
  }
}

int freeRam ()  // from: https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory
{
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

uscrocc

L'errore che mi da:
Code: [Select]
Arduino:1.6.7 (Windows 7), Scheda:"Arduino/Genuino Uno"

previsioni_meteo_esp8266:309: error: stray '\302' in program

 Â© 2016 GitHub, Inc. Terms Privacy Security Contact Help

 ^

previsioni_meteo_esp8266:309: error: stray '\251' in program

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:18:66: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

 char *elementPreLabels[]  = {"", " ", "Pressure: ", "", " @ ", ""};

                                                                  ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:18:66: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:18:66: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:18:66: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:18:66: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:18:66: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:19:70: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

 char *elementPostLabels[]  = {"F ", "% Humidity", "in", "", "MPH", ""};

                                                                      ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:19:70: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:19:70: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:19:70: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:19:70: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:19:70: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino: In function 'void setup()':

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:76:36: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

   sendData("AT+RST\r\n", 2000, true);       // reset the ESP8266

                                    ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:78:41: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

   sendData("AT+CWMODE=1\r\n", 1000, true);  // Set to mode 1 (Station Mode)

                                         ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:89:38: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

   sendData("AT+CIFSR\r\n", 1000, true);     // Print IP address

                                      ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino: In function 'void loop()':

previsioni_meteo_esp8266:98: error: 'printSerialTest' was not declared in this scope

   if (printSerialTest && startupTest) {

       ^

previsioni_meteo_esp8266:100: error: 'class HardwareSerial' has no member named 'clear'

     Serial.clear();

            ^

previsioni_meteo_esp8266:103: error: 'printSerialTest' was not declared in this scope

   if (!startupTest && printSerialTest) {

                       ^

previsioni_meteo_esp8266:105: error: 'printDataToSerial' was not declared in this scope

     printDataToSerial();

                       ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino: In function 'void getData()':

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:127:34: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

   sendData("AT+CIPSEND=", 0, true);               // the ESP8266 needs to know the size of the GET request

                                  ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino:130:30: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

   sendData("\r\n", 1000, true);                   // wait for the > prompt from the esp8266

                              ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino: In function 'void serialBuffer()':

previsioni_meteo_esp8266:145: error: 'SerialTimer' was not declared in this scope

     SerialTimer = millis();                  // don't refresh the Serial if we are downloading data

     ^

C:\Users\marco\Documents\Arduino\previsioni_meteo_esp8266\previsioni_meteo_esp8266.ino: At global scope:

previsioni_meteo_esp8266:306: error: expected declaration before '}' token

 }}

 ^

exit status 1
stray '\302' in program

  Questo report potrebbe essere più ricco di informazioni con
  "Mostra un output dettagliato durante la compilazione"
  abilitato in "File > Impostazioni"

gpb01

#4
Jun 01, 2016, 10:21 pm Last Edit: Jun 01, 2016, 10:22 pm by gpb01
Ho la vaga idea che hai fatto dei copia/incolla e, in questi passaggi, hai copiato o da pagine HTML o da testo comunque "formattato" e ... ti sei portato dietro caratteri invisibili di formattazione ('\302') ...
... è successo anche a me a volte copiando da un editor che usava RTF.

Guglielmo

Search is Your friend ... or I am Your enemy !

Enzo--

Forse dovresti includere la libreria wifyEsp.
Ma aspettiamo  risposta dai più esperti.

zoomx

#6
Jun 10, 2016, 10:27 am Last Edit: Jun 10, 2016, 10:31 am by zoomx
A me non da nessun errore.
Però per copiare il codice dalla pagina su github ho prima premuto su raw nella riga sopa il codice a destra.


Edit:
leggo che bisogna incrementare il buffer di ricezione a 256 byte. L'autore propone di modificare la libreria, io propongo di copiare la libreria nella stessa cartella dello sketch, rinominarla, modificarla e referenziare quella modificata.
Modificare una libreria magari usata in altri progetti solo per uno sketch non mi sembra una buona idea.

Go Up