上个学期的大作业,最近一直在准备出国的事情,一直没发
一、系统设计
图一:顶层设计框架图
模块准备:
DHT11温湿度模块
NodeMCU模块
MQTT服务器
Apollo服务平台
Android开发平台
图二:MQTT原理图
整体介绍:
整个思路其实非常的简单,简单的说就是NodeMCU通过MQTT协议发送message到Apollo平台,代理服务器再把这个message发给订阅者,即APP,当然,反向传递也是没问题的。
具体联系:
温湿度模块和LED灯珠都是物联网中最基本的模块,其作用就是简单的发光、发亮以及检测温湿度,并将信息传递给NodeMCU开发板。
NodeMCU开发板作为硬件的核心,其主要的功能是,处理接收到的温湿度信息,并将这些信息封装在message中,通过WiFi,MQTT协议发送出去,即作为发布者publish一个topic。
除此之外,NodeMCU还可以作为一个接受者,或者说是订阅者,subscribe一个topic,譬如我们模块中,接受小灯亮灭请求的message,将处理出来的信息,具象化的体现在小灯的亮与灭上。
Apollo则是作为一个代理服务器。我在本地搭建了一个Apollo的服务器,来发送和接受message。从而实现APP和NodeMCU的连接。
APP则是最为一个用户操作级的UI界面,方便用户使用,控制硬件设备。而且前端的设计也非常的重要,唯有美观的界面才能够真正博取人们的眼球。
二、硬件设计
图三:面包板视图
三、软件设计
图四:Aduino代码框架图
arduino的代码,然后这个代码烧录到NodeMCU里面。
主要功能就是连接上局域网,然后接受和发送信息,并控制温湿度和小灯的模块。
https://www.jianshu.com/p/701f4d31029f
这个网站是MQTT--NodeMCU及MQTT接发消息体验的教程
#include
#include
#include
#include
#include
#include
#include
dht11 DHT11;
#define DHT11PIN 2
// If using software SPI (the default case):
#define OLED_MOSI D7
#define OLED_CLK D5
#define OLED_DC D0
#define OLED_CS D8
#define OLED_RESET D3
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
const char* ssid = "sha";//连接的路由器的名字
const char* password = "12345678";//连接的路由器的密码
const char* mqtt_server = "192.168.43.90";//服务器的地址
const int port=61613;//服务器端口号
int ind = 0;
char msg[50];
char msg1[50];
int pinLED = D2;
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {//自动连WIFI接入网络
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print("...");
}
}
void callback(char* topic, byte* payload, unsigned int length) {//用于接收数据
int l=0;
int p=1;
for (int i = length-1; i >=0; i--) {
l+=(int)((char)payload[i]-'0')*p;
p*=10;
}
ind = l;
Serial.println(l);//换行
}
void reconnect() {//等待,直到连接上服务器
while (!client.connected()) {//如果没有连接上
Serial.print("Attempting MQTT connection...");
if (client.connect("light_yzr")) {//接入时的用户名,尽量取一个很不常用的用户名
Serial.println("connected");
client.subscribe("LED");//接收外来的数据时的intopic
} else {
Serial.print("failed, rc=");//连接失败
Serial.print(client.state());//重新连接
Serial.println(" try again in 5 seconds");//延时5秒后重新连接
delay(5000);
}
}
}
void draw(void){
//清屏
display.clearDisplay();
// text display tests
//在0,0这个点,写Humidity的数据,颜色设为白色,大小为1个单位
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("Humdity(%): ");
display.println(DHT11.humidity);
display.setTextSize(1);
display.setTextColor(WHITE);
display.print("Temperature(oC):");
display.println(DHT11.temperature);
//show
display.display();
delay(2000);
}
void setup() {//初始化程序,只运行一遍
Serial.begin(115200);//设置串口波特率(与烧写用波特率不是一个概念)
pinMode(pinLED,OUTPUT);
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC);
// init done
//加了一个清屏就把开机动画去掉
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("Name:");
display.println("yezerui");
display.print("Number:");
display.println("1512190127");
display.display();
setup_wifi();//自动连WIFI接入网络
client.setServer(mqtt_server, port);//端口号
client.setCallback(callback); //用于接收服务器接收的数据
}
void loop() {//主循环
reconnect();//确保连上服务器,否则一直等待。
DHT11.read(DHT11PIN);
//输出在监视器上的。
Serial.print("Humdity(%):");
Serial.println(DHT11.humidity);
Serial.print("Temperature(oC):");
Serial.println(DHT11.temperature);
snprintf (msg, 75, "%ld", DHT11.temperature);
snprintf (msg1, 75, "%ld", DHT11.humidity);
client.publish("Tem", msg);
client.publish("Hum", msg1);
delay(4000);
draw();
client.loop();//MUC接收数据的主循环函数。
if(ind == 1){
digitalWrite(pinLED,LOW);
}else{
digitalWrite(pinLED,HIGH);
}
}
Apollo服务器:
功能:作为一个中间媒介,接受和发送message
可以参考https://www.jianshu.com/p/e11a47f1e53c这个网站的Apollo服务器搭建
APP端的话主要就是API使用的问题,界面的话很简单,而且我自己做得也很粗糙,不想浪费时间
图五:APP端代码结构图
添加这个库:
org.eclipse.paho.client.mqttv3-1.0.2.jar
添加service和权限:
添加receiver:
gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.example.mqtt_test"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
testCompile 'junit:junit:4.12'
}
以及画曲线图的API用的是achartengine
libs中加入achartengine-1.0.0.jar.jar
APP的具体代码放在GitHub中:https://github.com/JerryYZR/MQTT_Hum.git
四、使用说明
1、手机控制小灯亮灭:
第一行输入topic LED,表示控制模块设置为小灯
第二行输入0或者1, 输入0为开灯, 输入1为关灯
2、订阅Temperature和Humidity的信息
当输入Tem为订阅温度模块
当输入Hum为订阅湿度模块
3、按下Update,显示温湿度信息
按下Update按键后,更新温湿度信息
4、点击图标,切换界面:
底部图标可以实现设置界面,与动态图表界面的切换,从而实现更好的UI交互
5、温湿度的动态图表:
订阅了温湿度模块以后,进入到动态图表界面,图表会2秒钟更新一次。
纵坐标为温湿度
横坐标为时间mm:ss(分:秒)