如何仅花20元成本用arduino平台建立自己的物联网应用
阅读原文时间:2021年04月20日阅读:1

我本是一个天生对硬件不感兴趣的人,但是也不是说软件我就学的多么好。而是我讨厌复杂的电路图,更讨厌焊板子,因为我是一个手残党,再简单的东西让我动手做,我都做得非常糟糕,而对于一个做出来的东西我又在乎美观度,所以干脆就不学习了,尽管我在自动化专业学习了四年,可是我的电路方面的知识几乎为零,所以我更喜欢偏向学软件开发。但是为什么又要研究这个物联网开发呢?凑什么热闹嘛,还不是为了完成我的毕业设计 。

注意:本文是建立在自己初学物联网毕设开发的总结之上,只是希望可能能对未来即将进入物联网领域开发的小白做一个简单的概括,大神请绕道 ,我所说的可能与真理会有一丝不同(当然是我才疏学浅的原因),还请包涵。另:本文是自己搭建MQTT服务消息推送系统的,没有使用其他iot的服务
建立自己的物联网应用,听起来是不是有点高大上的样子,其实,一点都不难。那么我们肯定要学一门单片机技术了啊,学什么呢?就学Arduino把。

一、Arduino

1.1 什么是Arduino

哎,明明自己也不是很懂,也刚开始接触,还在这里一本正经的胡说八道,那我就用自己的语言说了,在我的眼里,他就是块单片机,不过就是相对于51单片机、STM32来说要简单好多好多好多,不过可能对于都学过的同学来讲,都是很简单的吧。
为什么说它简单呢?
因为他的开发风格完全跟C语言一样,单片机知识懂一点就行,只要知道什么是IO口就行,你就可以开发做出一款东西了。
据我所知,它好像有几个版本,刚开始我再某宝上准备买一款支持ArduinoIDE开发方式的开发板,然后在同学的建议下我先买了型号:Arduino mega 2560。这款开发板的特点是IO口超级多,有多少个呢?我上个图吧。

足足有50多个引脚…啥,你问我要这么多引脚干嘛?我…我的毕设是基于语音识别的远程控制系统设计,既然是控制系统了,那我必须IO口多一些,这样做起来以后可以接入好多好多其他模块了,比如led灯、oled显示屏、语音识别模块(虽然我的语音识别是基于Android开发的app),但是我还是想着在硬件上也装个语音识别的模块吧。这样既可以用手机的APP语音控制,也可以近距离直接语音控制了。
废话说这么多,你们会说我,怎么还不开始正题,好了好了,那我开始了。
首先,要知道一个概念。Arduino 只是一个编译器而异,可以用C语音的风格开发硬件。你可以买Arduino平台提供的开发板再加上他们的Arduino IDE进行硬件开发,也可以使用其他支持Arduino IDE的开发板来开发。因为我们要做一个物联网的程序嘛,那肯定要硬件联网啊,这时候就需要用到ESP8266或者ESP32了。其中,ESP32是ESP8266的升级版。
注意:这里有个坑,如果你要购买ESP WIFI通信模块,千万别买ESP-01s,因为这个模块对新手一点都不友好,我调试了几天都不会用,程序老是烧录不进去,等有时间再研究吧,但是它的特点是便宜,只要8块钱左右。
记住,ESP-01s长这个样子,新手千万别买这个。


(图1.ESP-01s)
不买这个那买什么呢?这里我们可以直接买人家封装好的ESP开发板,我也是看大神推荐才买的,NodeMCU-32s,对就买这个没错了,只要二十多人民币,你就可以完成自己的物联网应用了。

二、部署环境

2.1 安装Arduino IDE

购买好开发板之后,我们首先装个ArduinoIDE吧。
官网大家都可以搜到,我这里提供个学习的中文网站吧:Arduino中文社区

2.2 启动Arduino并安装ESP32开发板环境

因为Arduino只是一个编译器,所以你要用什么开发板你就装什么环境就行,因为我买的是NodeMCU-32s,也就是ESP32,那直接装个ESP32环境就行了。
首先找到 文件–首选项–附加开发板管理器网址,如下图:

在这里填入:https://dl.espressif.com/dl/package_esp32_index.json
然后确定就行。
然后按照下图操作打开开发板管理器。

然后搜索esp32,安装后环境就搭建好了。
这里有个要注意 的地方,由于某些原因大家都懂,打开这个开发板管理器有时候会提示出错,不要惊讶,你只要知道这只是你没有科学的上网而已

那么如何解决呢?我这里提供一个方案吧。在Arduino中文社区里下载安装别人封装好的就行了。网址:esp32s
刚开始我安装这个esp32一直找不到,我都快被气死了。后来才知道,我一直在库管理器里面找,能找到才怪…还不是太菜了的原因。Arduino可以安装开发板环境也可以安装我们平时使用的库,比如一些http服务器的库,有了这个,我们就可以把NodeMcu变成一个web服务器。

2.3 学习例程

安装了esp32开发板之后,他会给我们自带好多库,需要什么学什么就行。

三、通信协议

既然要做的是物联网的东西,那么现在我们可以让开发板联网了,但是通信协议如何选取呢?原生的socket、http协议、MQTT协议,到底用哪个好点呢?

  • socket
    这个我不多少,懂得自然懂。socket作为基于TCP/IP 与应用层中间的媒介,也就是说你可以用这个封装你自定义的协议。就不考虑这个了。
  • http协议
    http协议,听起来咋不靠谱呢。emm,因为他是单方面通信协议啊,也就是说只能先是客户端连接服务端,服务端才可以跟客户端通信。太不方便了。
  • MQTT协议
    这个协议简直太适合作为物联网通信协议了。作为基于发布/订阅范式的消息协议,太适合了。

四、安装MQTT服务

如果想做简单一点的,可以跳过第四、五步看第六步

4.1 安装MQTT服务器

首先我们必须装个支持MQTT协议的消息中间件,我这里用了RabbitMQ作为我的MQTT服务器。RabbitMQ官网:RabbitMQ,稍后几天我会总结一篇使用RabbitMQ的博文。

4.2 给Arduino IDE安装MQTT库

我们需要在Arduino安装个MQTT库,让开发板支持MQTT协议,然后直接连接我们的MQTT服务器。这样只要我们在写个MQTT客户端,就可以使用进行收发数据控制硬件了。这里我推荐使用:pubsubclient,使用起来非常简单。github地址:github-pubsubclient。你可以直接从github下载下来,然后拷贝到如下图的目录里,一般来讲,Arduino自定义安装的库都在这个文件夹下边。或者你也可以直接在Arduino找到库管理器 搜索mqtt,找到pubsubclient,直接安装就行了。

4.3 安装MQTT FX

既然我们使用了MQTT服务,那么其中为了方便调试,我们安装个MQTT客户端即可。提供MQTT FX 下载地址:MQTTFX下载地址

五、编码测试

Arduino端:
我这里直接上传了官方提供的例程并加了注释方便大家理解:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

//要连接的WIFI名称
const char* ssid = "........";
//要连接的 WIFI密码
const char* password = "........";
// MQTT服务器地址
const char* mqtt_server = "broker.mqtt-dashboard.com";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup_wifi() {

  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  // 如果在连接中...
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // 产生一个随机种子 因为要生成MQTT 连接时提供ID
  randomSeed(micros());
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}
//当MQTT推送来消息
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();

  // 如果第一个字节是1,那么关掉灯
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  
  }

}

void reconnect() {
  // 等待连接MQTT服务器成功
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // 创建一个ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // 连接服务器
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // 发布消息
      client.publish("outTopic", "hello world");
      // 订阅消息
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

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

void loop() {
 // 如果断开重新连接
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 50, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

MQTT 客户端:
测试的时候,可以直接使用MQTTFx,进行测试。然后就是对接后端程序了。因为我现在项目还没有完善,所以,本文暂时用MQTTFX 完成对数据的订阅以及发布消息。
首先启动MQTTFX并进行设置,如下图:

5.1.1 读数据

设置好之后,直接Connect,因为esp32烧录了如下代码,client.publish("outTopic", "hello world");。按上述程序逻辑,也就是说,每隔两秒它就会向’outTopic’节点发消息,如果当前有MQTT客户端连接了这个节点,那么将会自动收到来自MQTT服务器推送来的消息。如下图:MQTT服务器连接了’outTopic’节点,所以它收到了服务器推送来的消息。

5.1.2 写数据

由于esp32已经监听了节点‘inTopic’,所以我使用MQTT向节点‘inTopic’发送了一条消息,而单片机的串口端也成功的输出了接收到的信息了。

六、HTTP服务器

也可以直接让esp32作为web服务器端,然后访问esp32设备分配的ip地址即可。然后可以通过传入不同的HTTP参数,来控制硬件的状态,如果想要获得穿透内网的能力,即就是实现外网控制,那么我们只要使用内网穿透服务,这样子就实现了基于单片机的远程控制系统的开发入门了。
这里我就直接拿官方直接给的例程了。这些库在我们装好esp32开发板的时候已经自动给我们装好了,可以直接用。如果有不懂的地方,可以留言哦,仅对小白。

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

const char* ssid = "**";
const char* password = "*****";

WebServer server(80);

const int led = 13;

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/plain", "hello from esp8266!");
  digitalWrite(led, 0);
}

void handleNotFound() {
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

void setup(void) {
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp32")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/inline", []() {
    server.send(200, "text/plain", "this works as well");
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {
  server.handleClient();
}

可以看到,我们 访问如下ip地址就可以控制小灯的状态了,并且网页也输出了相应的文字。以后方便的话我做完了会录个视频总结一下。

七 、总结

回望最近一个多月,经历了多少坎坷,虽然知道是很简单的东西,但我就是能遇到各种问题,好像上帝就是专门要考验我一样,从刚开始使用esp-01s 烧录不进去程序的痛苦,我想了很久,到底是哪里有问题呢?到后来的妥协,因为真的没有时间耗了,所以就买了个nodeMCU,真的一下子方便了好多。感谢这些公司为我们提供的这些模块,才能我让我们再做一件东西的时候不再棘手。其实这个只是一个最最简单的入门博文了,如果有朋友能够看完此文,也一定能对物联网有个新的认识,然而我的毕设肯定没有这么简单,做这样,不然老师得瞪死我把。哎…
未来计划:

  • 完善语音识别APP的开发
  • 完善模块与模块的堆放问题
  • 加入硬件级语音识别模块以及语音合成模块,达成双向语音控制,更加符合毕设题目意图。
  • 加入其它模块eg:温湿度、显示屏…
  • 给esp写一个简单的web服务,可以动态设置esp的MQTT相关的参数。大致思路如下:

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章