【智慧楼宇】nodemcu(arduino)连接PZEM-004T上传数据,接收数据、配置网络


一、项目描述

设备将数据上传到阿里云,阿里云下数据到设备


二、使用工具

  • 阿里云物联网平台
  • arduino
  • PZEM-004T
  • nodemcu

三、项目过程

1、设备上传数据到阿里云

①在阿里云物联网平台创建产品

根据阿里云的文档开发
🔗链接

②实物连接,并上云

🔗链接

二、云端下发数据,设备接收数据(实现配网)

这里主要是使用了阿里云的topic实现修改nodemcu的wifi信息。

主要分成两种情况:

  • nodemcu处于掉线模式,需要更换网络

  • nodemcu处于在线模式,需要更换网络

实现方法为:将一个备用网络信息写入nodemcu的flash中(多为自己的手机热点信息),这样即时设备断电,这部分数据也不会丢失。若在掉线模式,设备会先尝试连接原来的网络15次,如果没有连接上,就读出flash中预留的网络配置信息,修改wifi信息,重新尝试连接。若在线,则会修改当前网络信息,并重新执行wifiinit方法。

#include <math.h>
#include "DHT.h"
#include <configdb.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <AliyunIoTSDK.h>
#include <PZEM004Tv30.h>

#define PRODUCT_KEY ""
#define DEVICE_NAME ""
#define DEVICE_SECRET ""
#define REGION_ID "cn-shanghai"
#define DEVICE_KEY ""
#define WIFI_SSID "301"
#define WIFI_PASSWD "13912015808"
#define DHTPIN 3
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);
AliyunIoTSDK iot;
static WiFiClient espClient;
PZEM004Tv30 pzem(D1,D2);
class MyConfiguration
{
  public:
    char *wifiName;
    char *wifiPass;
};
ConfigDB<MyConfiguration> configDB;
unsigned long lastMsMain = 0;
int count = 0;
DynamicJsonDocument doc(1024);

void setup() {
  Serial.begin(115200);
  MyConfiguration defaultCfg = {"301","13912015808"};
  bool isPreviusConfigStored = configDB.storeDefaultIfNotLoad(defaultCfg);
  Serial.println(isPreviusConfigStored);
  while(WiFi.status() != WL_CONNECTED){
    MyConfiguration newCfg = configDB.load();
    String str1= newCfg.wifiName;
    String str2 = newCfg.wifiPass;
    char *wifiName2=(char*)str1.c_str();
    char *wifiPassword2=(char*)str2.c_str();
    wifiInit(wifiName2, wifiPassword2);
  }
    dht.begin(); //DHT开始工作
    AliyunIoTSDK::begin(espClient, PRODUCT_KEY, DEVICE_NAME, 				DEVICE_SECRET, REGION_ID);
    AliyunIoTSDK::bindData("electric",powerCallback);
}

void loop() {
    AliyunIoTSDK::loop();
    if (millis() - lastMsMain >= 3000)
    {
      lastMsMain = millis();
      doc["humi"] = dht.readHumidity();//读湿度
      doc["temp"] = dht.readTemperature();//读温度,默认为摄氏度
      doc["voltage"] = pzem.voltage();
      doc["current"] = pzem.current();
      doc["power"] = pzem.power();
      doc["energy"] = pzem.energy();
      String output;
      serializeJson(doc, output);
      const char *str = output.c_str();
      delay(2000);
      AliyunIoTSDK::send(str); 
    }
}

void wifiInit(char *ssid,char *passphrase)
{
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid,passphrase);
    while(WiFi.status() != WL_CONNECTED){
       count++;
       delay(1000);
       Serial.println(count);
       Serial.println(ssid);
       if(count>15){
          Serial.println(count);
         count=0;
         setWiFiInfo("***","*********");
         break;
       }
       delay(1000);
    }
    Serial.println("Connected to AP");
}
void setWiFiInfo(char *wifiname,char *wifipass){
    MyConfiguration newCfg1 = configDB.load();
    newCfg1.wifiName=wifiname;
    newCfg1.wifiPass=wifipass;
    configDB.save(newCfg1);
}
void powerCallback(JsonVariant p)
{
    String wifiName = p["wifiName"];
    String wifiPassword = p["wifiPassword"];
    char *wifiName1=(char*)wifiName.c_str();
    char *wifiPassword1=(char*)wifiPassword.c_str();
    if(wifiName1&&wifiPassword1){
      setWiFiInfo(wifiName1,wifiPassword1);
      WiFi.disconnect();
    }
    wifiInit(wifiName1,wifiPassword1);  
}

四、遇到问题及解决方法

  • 关于将数据写入nodemcu的flash中
    使用github上的一个库:ConfigDB,里面有一些读取、写入flash的方法。

  • 阿里云的数据json类型转化为char* 类型

String wifiName = p["wifiName"];
char *wifiName1=(char*)wifiName.c_str();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值