Hi, I have a problem that I cant seem to get passed. I'm using an ESP8266-12F to extract temp, wind speed, wind direction, humidity, pressure and weather description from openweathermap.org . After extraction the data is transfered to global variables....so far so good.
All data is displayed and scrolls correctly on my display except the weather description infromation. The serial.prints show the weather description information is correct while the other information is displayed but gets corrupted when the weather desciption passes through line 134
snprintf(scrollText, 30, "%s", weatherOut);
or sprintf(scrollText, "%s", weatherOut); both have the same problem.
The weather description MAY display correctly first time through the loop but later is corrupted by being replaced with squares, at symbols , and other symbols.
Any suggestions? Thanks
//ESP8266 12F & OLED
//TX->IO1
//RX->IO3
//
//SDA - <I02
//SCL - <IO14
#include <Arduino.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <Wire.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, D5, D4 , U8X8_PIN_NONE);
WiFiClient client;
//Globals
float dataVar[5] = {0.00, 0.00, 0.00, 000, 0000.00};
int WId; //weatherID
const char* weatherOut;
const char* terms[] = {"Temperature (C)", "Wind Speed (m/s)", "Wind Direction (deg)", "Humidity (%)", "Pressure (hPa)"};
const unsigned long postingInterval = 10L * 60L * 1000L; // posting interval of 10 minutes (10L *60L*1000L; 10 seconds delay for testing)
unsigned long lastConnectionTime = (millis() - postingInterval);
const char* ssid = "XXXXXXXXXXX";
const char* pass = "XXXXXXXXXXX";
void updateweather()
{
if (client.connect("api.openweathermap.org", 80))
{
client.println("GET /data/2.5/weather?id=XXXXXXX&units=metric&APPID= XXXXXXXXXXXXXXXXXXXXXX HTTP/1.1");
//requires HTTP/1.1 to get correct status
client.println("Host: api.openweathermap.org");
client.println("Connection: close");
client.println();
// Check HTTP status
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
if (strcmp(status + 9, "200 OK") != 0)
{
Serial.print(F("Unexpected response: "));
Serial.println(status);
lastConnectionTime = millis();
return;
}
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!client.find(endOfHeaders))
{
Serial.println(F("Invalid response"));
lastConnectionTime = millis();
return;
}
}
StaticJsonDocument<1024> doc;
// Parse JSON object
DeserializationError error = deserializeJson(doc, client);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
lastConnectionTime = millis();
return;
}
//Disconnect
client.stop();
JsonObject weather_0 = doc["weather"][0];
int weatherId = weather_0 ["id"].as<int>();
const char* weatherNow = weather_0["description"]; // "rain"
JsonObject main = doc["main"];
//transfer weatherNow to global WeatherOut
weatherOut = weatherNow;
WId = weatherId;
dataVar[0] = main["temp"]; // 16.27
dataVar[1] = doc["wind"]["speed"]; // 3.6
dataVar[2] = doc["wind"]["deg"]; // 130
dataVar[3] = main["humidity"]; // 21
dataVar[4] = main["pressure"]; // 1028
//Prints to monitor for checking
Serial.println (dataVar[0]);
Serial.println (dataVar[1]);
Serial.println (dataVar[2]);
Serial.println (dataVar[3]);
Serial.println (dataVar[4]);
Serial.println (weatherNow);
Serial.println ("The end");
Serial.println (weatherOut);
Serial.println (WId);
Serial.println ("The end1");
return;
}
void u8g2_prepare(void)
{
//initialise display
//u8g2.setFont(u8g2_font_6x10_tf);
u8g2.setFont(u8g2_font_ncenB08_tr);
// u8g2.setFont(u8g2_font_logisoso32_tf);
u8g2.setFontRefHeightExtendedText();
u8g2.setDrawColor(1);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
u8g2.enableUTF8Print();
}
// Pause for a 10 minute
void wait()
{
Serial.println("Wait 10 minutes");
lastConnectionTime = millis();
while (millis() - lastConnectionTime < postingInterval)
{
u8g2.clearBuffer(); // clear the internal memory
for (int i = 0; i < 6; i++)
{
char scrollText[32];
if (i < 5)
{
sprintf(scrollText, "%s : %4.1f ", terms[i], dataVar[i]);
}
else
{
snprintf(scrollText, 30, "%s", weatherOut); //not working.Works first time, sometimes
}
Serial.print ("scrollText = ");
Serial.println(scrollText);
Serial.print ("Weather Display = ");
Serial.println(weatherOut);
if (WId == 800) //clear
{
draw(scrollText, SUN, dataVar[0]);
}
else
{
switch (WId / 100)
{
case 2: //Thunderstorm
draw(scrollText, THUNDER, dataVar[0]);
break;
case 3: //Drizzle
case 5: //Rain
draw(scrollText, RAIN, dataVar[0]);
break;
case 7: //Sun with clouds
draw(scrollText, SUN_CLOUD, dataVar[0]);
break;
case 8: //clouds
draw(scrollText, CLOUD, dataVar[0]);
break;
default: //Sun with clouds
draw(scrollText, SUN_CLOUD, dataVar[0]);
break;
}
}
}
}
Serial.println("At the end of ten minute loop");
}
void drawWeatherSymbol(u8g2_uint_t x, u8g2_uint_t y, uint8_t symbol)
{
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);
drawWeatherSymbol(0, 0, symbol);
u8g2.setFont(u8g2_font_logisoso32_tf);
//u8g2.setCursor(48 + 3, 42);
u8g2.setCursor(48 + 5, 5);
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 work for screen with up to 256 pixel width
size_t len;
size_t lencopy;
size_t char_offset = 0;
u8g2_uint_t dx = 0;
size_t visible = 0;
len = strlen(s);
const char* weatherCopy;
weatherCopy = weatherOut;
Serial.print ("s = ");
Serial.println (s);
Serial.print ("weatherOut = ");
Serial.println (weatherOut);
Serial.print ("weatherCopy = ");
Serial.println (weatherCopy);
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);
Serial.println ("buf = ");
Serial.println(buf);
buf[visible] = '\0';
u8g2.setFont(u8g2_font_8x13_mf);
u8g2.drawStr(char_offset * 8 - dx, 50, 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);
Serial.println ("buf = ");
Serial.println(buf);
buf[visible] = '\0';
u8g2.setFont(u8g2_font_8x13_mf);
u8g2.drawStr(-dx, 50, buf);
}
Serial.print ("s out = ");
Serial.println (s);
Serial.print ("weatherOut out = ");
Serial.println (weatherOut);
Serial.print ("weatherCopy out = ");
Serial.println (weatherCopy);
weatherOut = weatherCopy;
}
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();
u8g2.clearBuffer();
do
{
drawWeather(symbol, degree);
drawScrollString(offset, s);
}
while ( u8g2.nextPage() );
delay(20);
offset += 4;
if ( offset > len * 8 + 1 )
break;
}
}
void setup()
{
u8g2.setI2CAddress(120);
Wire.begin(D4, D5); //sda,scl.
Serial.begin(115200);
u8g2.begin();
u8g2_prepare();
u8g2.clear();
Serial.println("Connecting to Network");
WiFi.begin(ssid, pass);
int counter = 0;
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
if (++counter > 100)
ESP.restart();
Serial.print(".");
}
Serial.println("\nWiFi connected");
}
void loop()
{
{
updateweather();// gets weather and update values
wait(); // connection delay and display update.
}
}