搭建物联网实验环境(ESP8266 + Arduino + Wifi 2G/3G/4G路由器 + MQTT + 中移动OneNet)

一直从事容灾、云计算、ICT方面的规划、设计、实施和运维工作。近几年则比较看好人工智能和物联网技术。今年国网提出建设“三型两网”(泛在电力物联网),终于可以名正言顺的搞事情了。

物联网涉及诸多技术领域,用“泛在”定义的电力物联网,更是个巨坑。为了分享心得、与同好交流,打算在这里把填坑的点点滴滴记录下来。

这次搞事情的对象选择了中移物联网的OneNet平台,主要原因是支持NB-IoT、灵活的接入方式、支持可视化、可以免费申请开发板(这个才是关键吧,哈哈)。最近还上线了应用编排功能(貌似与华为合作?),有点意思了,虽然只是一点点,但毕竟是向“三流合一”的方向靠近(能源流没有,业务流、数据流可以有)。

盘点了一下手头硬件资源:

  • 攀藤PM2.5、DHT11温湿度、人体红外等传感器,继电器、蜂鸣器等执行器(为什么都是家用产品?因为前几年都是在用Home Assistant之类的自己搭平台玩智能家居呀)
  • ESP8266 01S/NODEMCU
  • 树莓派(摔坏了,出师不利555~~~)
  • HC-05蓝牙模块
  • NB-IOT模块(申请中)
  • 安卓手机
  • Wifi 4G路由器 
  • 笔记本、服务器

嗯,足够搭一个最简单的物联网环境了。

智能终端暂时只能用ESP8266,手头有01S和NODEMCU。NODEMCU自带MicroUSB,程序烧写方便。,而且自带多个GPIO脚,可以设成PWM、I2C、1-Wire,有SPI有UART,能连接各种传感器执行器。编程可以用Arduino,也可以用原厂或第三方的SDK。

中国移动的开放物联网平台OneNet,在三大运营商中算是NO.1了,平台功能也许不能与互联网公司们比,但人家是掌握信道。支持的协议不少,包括私有协议EDP、常见的MQTT、NB的LWM2M等等。功能也勉强够用。接口也比较开放,至少MQTT比较方便移植。自己的设备接入后可以定义数据流,并编辑应用,实现数据的可视化以及对设备下发指令。

新上线的OneNet View和应用开发环境则更进一步,支持对数据流进行编排,支持定制应用。可惜暂时没时间细看,不知道能不能编排应用系统,包括机器学习、深度学习等。

说回信道,这次挺想玩玩NB-IoT的,可惜NB模块还没到货,暂时只能用Wifi了。用ESP8266连接任何能上网的AP都行,我用的是自己手机热点和4G Wifi路由器。通信协议选了MQTT,主要是移植性好,使用TCP支持长连接,日后再试试使用UDP低耗电的NB。

具体实现过程先不说,看看做出来的效果吧(请无视巨大的温差,那不是温湿度传感器采集的数据,只是为了在平台看出明显变化取的随机数)。

链接(刚点了公开,要等审核通过才能看到):https://open.iot.10086.cn/iotbox/appsquare/appview?openid=304a6ec5a16c2d77c638b00437fa6cda

截图:

搭建物联网实验环境(ESP8266 + Arduino + Wifi 2G/3G/4G路由器 + MQTT + 中移动OneNet)_第1张图片

搜集资料期间发现OneNet+MQTT的资料很少,找到的代码要么不全,要么就是有语法和逻辑错误。所以这里直接给出完整代码,Arduino1.8.5编译通过,只要相关库的版本合适,参数配置正确,应该没什么问题。

/*
 * Email:[email protected]
 * WeChat:song641606
 */

#include 
#include 
#include 
#include 

#define wifi_ssid "xxxxxxxxxxx"
#define wifi_password "xxxxxxxxxxx"
#define mqtt_server "183.230.40.39"                         //OneNet-MQTT IP
#define mqtt_port 6002                                      //OneNet-MQTT port
#define mqtt_devid "xxxxxxxx"
#define mqtt_pubid "xxxxxxxx"
#define mqtt_password "xxxxxxxxxxxxxxxxxxxxxxxxxx"          //OneNet-MQTT APIkey
#define pin_led 13

long lastMsg = 0;
char msg_buf[200];
char dataTemplete[] = "{\"dht01\":%d, \"dht02\":%d}";
char msgJson[75];
char debug_buf[200];
unsigned short json_len = 0;
uint8_t debug_buffer_start_index = 0;
int pl_0 = 0;
int temp_r = 0;
int humi_r = 0;

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);
  pinMode(pin_led, OUTPUT);
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);
  WiFi.begin(wifi_ssid, wifi_password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(3000); Serial.print("w?");
  }
  Serial.println("--WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  if ((char)payload[0] == '0') {
    digitalWrite(BUILTIN_LED, HIGH);
  } else {
    digitalWrite(BUILTIN_LED, LOW);
  }

  pl_0 = (int)payload[0] - 48;
  if (pl_0 >= 0 && pl_0 < 10) {
    for (int ii = 0; ii < pl_0; ii++) {
      digitalWrite(pin_led, HIGH); delay(1000);
      digitalWrite(pin_led, LOW); delay(1000);
    }
  }
  else {
    digitalWrite(pin_led, LOW);
  }
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect(mqtt_devid, mqtt_pubid, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5s");
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 10000) {
    lastMsg = now;

    temp_r = random(-20, 40);
    humi_r = random(1, 80);
    snprintf(msgJson, 40, dataTemplete, temp_r, humi_r);
    
    memset(msg_buf, 0, 200);
    json_len = strlen(msgJson);                     //packet length count the end char '\0'
    msg_buf[0] = char(0x03);                        //palyLoad packet byte 1, one_net mqtt Publish packet payload byte 1, type3 , json type2
    msg_buf[1] = char(json_len >> 8);               //high 8 bits of json_len (16bits as short int type)
    msg_buf[2] = char(json_len & 0xff);             //low 8 bits of json_len (16bits as short int type)

    memcpy(msg_buf + 3, msgJson, strlen(msgJson));

    Serial.print("Lngth of published message: ");
    client.publish("$dp", (uint8_t*)msg_buf, 3 + strlen(msgJson));    //// msg_buf as payload length which may have a "0x00"byte
    Serial.println(strlen(msgJson));

    /*
    for (i = 0 ; i < 200; i++)
    {
      sprintf(debug_buf, "0x%02x ", msg_buf[i]);
      Serial.print(debug_buf);
    }
    Serial.println();
    Serial.println(debug_buffer_start_index);
    */
  }
}

ESP8266烧写完成并加电后,每10秒向平台上传温度和湿度两个数据。同时可以接收平台下发的指令,控制板载LED和GPIO外接的LED灯。

代码注释不多,主要是IDE汉字支持的不好,写完注释变乱码了。实在懒得重新写了,有问题就留言吧。还有具体的开发过程和填过哪些坑,后面再一一道来。

你可能感兴趣的:(物联网)