2326 views|5 replies

155

Posts

1

Resources
The OP
 

【Beetle ESP32-C3】VII. Network timing and weather request (Arduino) [Copy link]

This article records a case with the following functions: connecting to Wi-Fi, network timing, starting the timer (1s), outputting the time once a minute (whole minute) through the serial port, and outputting real-time weather information every 5 minutes.

1. Request weather

To request weather, users need to register and obtain the api_key through the "Xinzhi Weather" site. I won't go into details about the registration and usage process here. If you are not sure, you can check the official website ( https://www.seniverse.com/ ).

This example only tests the acquisition of real-time weather data. The weather-related data only includes "status (sunny, etc.)" and "temperature". The request interface address is as follows:

https://api.seniverse.com/v3/weather/now.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c

The HTTPClient instance of ESP32-Arduino is used to request the weather. The weather data obtained is in JSON format. Therefore, the ArduinoJson library is loaded in this case. The earlier version installed is 6.18.5. The latest version is 6.19.4 according to the update prompt.

Figure 7-1 Library installation

Figure 7-2 JSON format returned by Xinzhi Weather

2. Weather case code

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

//-----SSID & password
const char *ssid = "yourssid";        //WIFI名称
const char *password = "yourpsw";     //密码

//-----NTP server & timezone offset
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 14400;     //3600*4 for UTC+8
const int  daylightOffset_sec = 14400;
struct tm  t;                         //time struct
void printLocalTime(void);

//-----timer HW per second
#define INMIN     0x60                //in 60s flag
#define ONEMIN    0x61                //one minute flag
hw_timer_t *timer = NULL;             //timer variable
volatile SemaphoreHandle_t timersem;  //timer fire sem
void IRAM_ATTR onTimer(void);         //callback func
void initTimer(void);
static uint8_t timestate = INMIN;     //flag variable

//-----weather server URL & instance for json parsing
DynamicJsonDocument doc(1024);        //json doc instance
const char *url = "https://api.thinkpage.cn/v3/weather/now.json?key=your_api_key&location=tianjin&language=en&unit=c";
void getWeather(void);                //request now weather func               

void setup() { 
  Serial.begin(115200);
//-----connect AP 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
//-----print IP address
  Serial.println(" CONNECTED");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
//-----initialize and get the time then initialize timer(per sec)
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  if(!getLocalTime(&t)){
    Serial.println("Failed to obtain time");
    return;
  } else {
    Serial.println(&t, "%A, %B %d %Y %H:%M:%S");
    initTimer(); //timer init
  }
}

void loop() {  
//-----update time state per second
  if(xSemaphoreTake(timersem, 0) == pdTRUE) {
    if((t.tm_sec)++ >= 59)  timestate = ONEMIN;
  }
//-----print localtime per minute & weather info per 5 minutes
  if(timestate == ONEMIN) {
    timestate = INMIN;
    if(WiFi.status() == WL_CONNECTED) {
      printLocalTime();
      if(t.tm_min%5 == 0) getWeather();
    }   
  }
}

//-----print local time function
void printLocalTime() {
  if(!getLocalTime(&t)) {
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&t, "%F %T %A");
}
//-----second timer callback function
void IRAM_ATTR onTimer() {
  xSemaphoreGiveFromISR(timersem, NULL);
}
//-----intialize timer function
void initTimer() {
  timersem = xSemaphoreCreateBinary();
  //ESP32 sysclk is 80MHz.
  //frequency division factor to 80,
  //then timer clock is 1MHz.
  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmWrite(timer, 1000000, true); //1000000us timer
  timerAlarmEnable(timer);
}
//-----request now weather function
void getWeather() {
  if((WiFi.status() == WL_CONNECTED)) {
    HTTPClient http;           //create HTTPClient instance
    http.begin(url);           //begin HTTP request
    int httpCode = http.GET(); //get response code - normal:200
    if(httpCode > 0) {
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);
      if(httpCode == HTTP_CODE_OK) {
          String payload = http.getString();       
          Serial.println(payload);
          //parse response string  to DynamicJsonDocument instance
          deserializeJson(doc, payload);
          //get top level Json-Object
          JsonObject obj = doc.as<JsonObject>();
          //get "results" property then parse the value to Json-Array
          JsonVariant resultsvar = obj["results"];
          JsonArray resultsarr = resultsvar.as<JsonArray>();
          //get array index 0 which is now weather info
          JsonVariant resultselementvar = resultsarr[0];
          JsonObject resultselementobj = resultselementvar.as<JsonObject>();
          //get city, temp, last_update time
          JsonVariant namevar = resultselementobj["location"]["name"];
          String namestr = namevar.as<String>();
          Serial.println(namestr);
        
          JsonVariant temperaturevar = resultselementobj["now"]["temperature"];
          String temperaturestr = temperaturevar.as<String>();
          Serial.println(temperaturestr);
        
          JsonVariant last_updatevar = resultselementobj["last_update"];
          String last_updatestr = last_updatevar.as<String>();
          Serial.println(last_updatestr);
      }
    } else {
      Serial.printf("[HTTP] GET... failed, error: %s\n", 
      http.errorToString(httpCode).c_str());
    }
    http.end(); //end http connectiong
  }
}

This post is from RF/Wirelessly

Latest reply

I see, I see that pinyin is used. If there are duplicate names, there will be no problem.   Details Published on 2022-8-30 13:09
 

6593

Posts

0

Resources
2
 

The network timing and weather request functions are well evaluated, and I look forward to the follow-up

This post is from RF/Wirelessly
 
 

6787

Posts

2

Resources
3
 

How do I get the region? Do I enter the region information myself?

This post is from RF/Wirelessly

Comments

The address information is in the requested URL  Details Published on 2022-8-29 19:13
 
 
 

6040

Posts

204

Resources
4
 
wangerxian posted on 2022-8-29 10:35 How to get the region? Do you enter the region information yourself?

The address information is in the requested URL

This post is from RF/Wirelessly

Comments

I see, I see that pinyin is used. If there are duplicate names, there will be no problem.  Details Published on 2022-8-30 13:09
 
 
 

6787

Posts

2

Resources
5
 
lcofjp posted on 2022-8-29 19:13 The address information is in the requested URL

I see, I see that pinyin is used. If there are duplicate names, there will be no problem.

This post is from RF/Wirelessly

Comments

It is the URL request parameter. The relevant parameters can be found on the Xinzhi Weather website. The website should have solved the duplicate name problem by itself (personal guess)  Details Published on 2022-9-3 11:24
 
 
 

155

Posts

1

Resources
6
 
wangerxian posted on 2022-8-30 13:09 I see that it is in pinyin. If there are duplicate names, will there be problems?

It is the URL request parameter. The relevant parameters can be found on the Xinzhi Weather website. The website should have solved the duplicate name problem by itself (personal guess)

This post is from RF/Wirelessly
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

快速回复 返回顶部 Return list