教程六:官方SDK代码功能补充(ESP8266开发板)

物美智能》系列文章目录

教程一:阿里云使用docker快速部署服务端
教程二:本地配置服务端开发环境
教程三:硬件端-Arduino和ESP8266开发板入门
教程四:使用物联网平台控制硬件端
教程五:物联网平台使用手册
教程六:官方SDK代码功能补充
教程七:APP的使用与场景联动功能
diy:自制作四种智能小电器

前言

在上篇文章中,我们做了物美智能平台远程控制小风扇和获取温湿度数据的测试,但是在官方的代码中,并没有对这类功能的实现,只打印出了串口的调试信息。本片文章来展示此功能性代码的实现。
在这里插入图片描述

注:以下代码为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);
}
posted @ 2022-04-18 09:03  小邱同志~  阅读(149)  评论(0编辑  收藏  举报