1. 程式人生 > 其它 >教程六:官方SDK程式碼功能補充(ESP8266開發板)

教程六:官方SDK程式碼功能補充(ESP8266開發板)

物美智慧》系列文章目錄

前言

在上篇文章中,我們做了物美智慧平臺遠端控制小風扇和獲取溫溼度資料的測試,但是在官方的程式碼中,並沒有對這類功能的實現,只打印出了串列埠的除錯資訊。本片文章來展示此功能性程式碼的實現。

注:以下程式碼為ESP8266開發適用,其他型號開發板未知
官方程式碼文件與平臺可檢視下面gitee連結


https://gitee.com/kerwincui/wumei-smart.git

開關控制程式碼實現(繼電器開關)

1.Help.h補充標頭檔案(包括顯示屏所需標頭檔案、led燈標頭檔案等)

#include "Base64.h"
#include <ESP8266WiFi.h>
#include <Ethernet.h>
#include <ESP8266HTTPClient.h>
#include <PubSubClient.h>      // 版本2.8.0
#include <ArduinoJson.h>       // 版本6.19.1
#include <U8g2lib.h>
#include <Adafruit_NeoPixel.h>  //引入庫檔案

2.Helper.cpp找到開關列印程式碼,新增相應功能函式

if (strcmp(id, "switch") == 0)
    {
      printMsg("開關 switch:" + (String) value);
      loopOC(value);
    }

3.Help.h標頭檔案中定義函式名

void loopOC(const char* value);

4.Help.cpp新增函式實現

void loopOC(const char* value)
{
  printMsg("開關交替");
  pinMode(15, OUTPUT);
  if(*value=='1'){
    digitalWrite(15, HIGH);
    delay(200);
  }else{
    digitalWrite(15, LOW);
    delay(200);
  }
}

顯示屏顯示字串/顯示屏顯示天氣

1.邏輯為當輸入“weather”字串時oled顯示屏中顯示天氣資訊,當輸入其他字串時顯示該字串
2.Help.cpp新增相應功能函式

else if (strcmp(id, "message") == 0)
    {
      printMsg("屏顯訊息 message:" + (String)value);
      pageOled(value);
    }

3.Help.h定義相應函式名

void pageOled(const char* value);

4.Help.cpp中定義全域性變數
通過心知天氣 API 獲取天氣狀態顯示在OLED顯示螢幕上
privateKey 需要自己在心知天氣申請
網站地址: https://www.seniverse.com/dashboard

//自定義配置
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
#define IIC_addr 0x3C //IIC地址預設0x3c
//心知天氣
const char* host = "http://api.seniverse.com";
String privateKey = "請自己去心知天氣官網申請。。。。";
//天氣資料
int temperature = 0;
char *text  = " ";
int code = 0;
int ioccode[] = {241, 223, 259}; //雨 陰 晴
int iocnum = 0;

5.Help.cpp新增函式實現

//自測螢幕顯示
void pageOled(const char* value)
{
  const char* cloud="weather";
  if(strcmp(value,cloud)!=0){
    u8g2.setI2CAddress(IIC_addr * 2); //設定顯示屏地址
    u8g2.begin(); //U8G2開始 U8g2建構函式
    u8g2.firstPage();
    do{
      u8g2.setFont(u8g2_font_timR10_tf);  //設定顯示字型
      u8g2.setFontPosTop(); //設定字型左上角位參考點
      u8g2.setCursor(0, 20); //設定顯示位置
      u8g2.print(value); //寫入顯示字串
    }while(u8g2.nextPage());
    delay(100);
  }else{
    int httpCode = 0;
    String httpData;
    WiFiClient client;
    //傳送http請求
    HTTPClient http;
    http.begin(client, "http://api.seniverse.com/v3/weather/now.json?key=" + privateKey + "&location=ip&language=en&unit=c");
    httpCode = http.GET();
    //若是有返回就接收資料
    if ( httpCode >= 0)
    {
      Serial.println("startedRequest ok");
      httpData = http.getString();  //api 獲取的json資料 可以檢視獲取資料規則 
      Serial.println(httpData);
      //提取出關於天氣的那一段字串
      String  data = httpData.substring((httpData.indexOf("\"now\":") + 6), httpData.indexOf(",\"last"));
      //通過json庫解析出相應的資料
      StaticJsonDocument<1024> doc; //1024位元組記憶體池容量
      //解析JSON
      DeserializationError error = deserializeJson(doc, data);
      if (error)
      {
        Serial.print(F("deserializeJson() failed: "));
        // Serial.println(error);
        return;
      }
      temperature = doc["temperature"];
      const char *text = doc["text"];
      code = doc["code"];
      Serial.print("temperature is :");
      Serial.println(temperature);
      Serial.println((String)text);
      Serial.println(code);
      if (code > 9) { //
        iocnum = 0;
      }
      else if (code == 9 || code == 8 || code == 6 || code == 4 || code == 3 || code == 1) {
        iocnum = 1;
      } else iocnum = 2;
      u8g2.firstPage();
    do
      {
        u8g2.setFont(u8g2_font_open_iconic_all_4x_t);
        u8g2.drawGlyph(15, 5, ioccode[iocnum]); //內建圖示庫
        u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
        u8g2.drawGlyph(110, 5, 247); //訊號圖示
        u8g2.setFont(u8g2_font_timR10_tf);  //設定顯示字型
        u8g2.setFontPosTop(); //設定字型左上角位參考點
        u8g2.setCursor(10, 50); //設定顯示位置
        u8g2.print((String)text); //寫入顯示字串
        u8g2.setCursor(80, 45); //設定顯示位置
        u8g2.print("T:"); //寫入顯示溫度
        u8g2.setCursor(98, 45); //設定顯示位置
        u8g2.print(temperature); //寫入顯示溫度
        u8g2.setCursor(115, 45); //設定顯示位置
        u8g2.print("C'"); //寫入顯示溫度
  
      } while (u8g2.nextPage()); //將快取資料輸出到顯示屏顯示 迴圈重新整理顯示
    }else{
      Serial.print("Connect failed");
      delay(50000);
    }
  }
}

led燈光控制

1.邏輯為當在官網中輸入三個引數字串時,led燈做出相應變化,當資料為(0,0,0)時,led燈預設熄滅
2.Help.cpp新增相應功能函式

    else if (strcmp(id, "light_color") == 0)
    {
      printMsg("燈光顏色 light_color:" + (String)value);
      lightColor(value);
    }

3.Help.h定義相應函式名

void lightColor(const char* value);

4.Help.cpp中定義全域性變數

//自定義配置
//led燈配置
#define rgb_num 3  //定義燈珠數量
#define rgb_pin 13  //定義燈珠使用引腳
//新建一個物件並設定引腳和燈珠數量
Adafruit_NeoPixel rgb_display_13 = Adafruit_NeoPixel(3, 13, NEO_GRB + NEO_KHZ800);

5.Help.cpp新增函式實現

//自測led燈
void lightColor(const char* value){
  char buf[256], *p=NULL, **array=NULL;
  int cnt = 0, i=0;
  strcpy(buf,value); //考慮到ptr指向常量,所以用buf來複制常量內容
  p = strtok(buf, ",");
  while (p!=NULL) {
        if (cnt==0) {
            array = (char**)malloc(sizeof(char*));//動態給array申請記憶體
        } else {
            array = (char**)realloc(array, sizeof(char*)*(cnt+1)); //沒找到一個分割字元就重新修改array的長度,並儲存分割後的字串
        }
        array[cnt++] = p;
        p = strtok(NULL, ",");
  }
  if(cnt==3){
    int light1=atoi(array[0]);
    int light2=atoi(array[1]);
    int light3=atoi(array[2]);
    rgb_display_13.begin();  //初始化燈珠
    for (int i = 0; i < rgb_num; i++) {  //迴圈rgb_num次 點亮所有燈
      rgb_display_13.setPixelColor(i, rgb_display_13.Color(light1,light2,light3)); //將資料寫入快取 分別對應RGB 顏色值改變值就能改變顏色了
      rgb_display_13.show(); //rgb資料輸出 RGB開始點亮
      delay(1000); //延時1s
    }
  }
  free(array);
}