概述
本项目将axl345采集的角度变化传送到巴法云或者本地mqtt服务并在web页面实时显示变化。包含axl345和esp8266的IIC,mqtt本地服务,基于vue2的web编程。
使用环境和开发板
Ariduino IDE -- esp8266编程环境
Node.js -- vue2 aedes
NodeMCU1.0 -- esp8266开发板型号
axl345 -- 传感器
axl345和esp8266
接线
IIC是I一种串行总线,一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。需要将SDA和SCL接在开发板对应的时钟线和数据线接口上。我所使用开发板是D1 (SCL)和D2(SDA)。然后是是给传感器通上电,vcc接到3.3v/5v,GND接GND。
代码
将axl345作为从机,给它分配一个寄存器地址,通过esp8266的write.h实现。
定义:
// ADXL345 分配的地址
#define Addr 0x53
// 数据线和时钟线
const uint8_t scl = D1; //D1
const uint8_t sda = D2; //D2
初始化(setup函数)
// 初始化I2C通信作为主机
Wire.begin(sda, scl);
采集和IIC
unsigned int data[6];
// 启动I2C传输
Wire.beginTransmission(Addr);
// 选择带宽速率寄存器
Wire.write(0x2C);
// Normal mode, Output data rate = 100 Hz
Wire.write(0x0A);
// 停止I2C传输
Wire.endTransmission();
// 启动I2C传输
Wire.beginTransmission(Addr);
// 选择功率控制寄存器
Wire.write(0x2D);
// Auto-sleep disable
Wire.write(0x08);
// 停止I2C传输
Wire.endTransmission();
// 启动I2C传输
Wire.beginTransmission(Addr);
// 选择数据格式寄存器
Wire.write(0x31);
// Self test disabled, 4-wire interface, Full resolution, Range = +/-2g
Wire.write(0x08);
// 停止I2C传输
Wire.endTransmission();
delay(300);
for (int i = 0; i < 6; i++)
{
// 启动I2C传输
Wire.beginTransmission(Addr);
// 选择数据寄存器
Wire.write((50 + i));
// //停止I2C传输
Wire.endTransmission();
// 读取1字节数据
Wire.requestFrom(Addr, 1);
// 读取6字节数据
// xAccl lsb, xAccl msb, yAccl lsb, yAccl msb, zAccl lsb, zAccl msb
if (Wire.available() == 1)
{
data[i] = Wire.read();
}
}
// 将数据转换为10位
int xAccl = (((data[1] & 0x03) * 256) + data[0]);
if (xAccl > 511)
{
xAccl -= 1024;
}
int yAccl = (((data[3] & 0x03) * 256) + data[2]);
if (yAccl > 511)
{
yAccl -= 1024;
}
int zAccl = (((data[5] & 0x03) * 256) + data[4]);
if (zAccl > 511)
{
zAccl -= 1024;
}
可以获取到传感器的数据。
代码是参考了这篇文章:ESP8266无线+ADXL345加速度传感器
数据上传
获取数据后就是数据上传。这里使用了两种方案,第一种是通过巴法云,但是这个好像有4-5s的延时,第二种方案是使用本地的mqtt服务,延时还是很可观的。
巴法云(tcp)
使用巴法云物联网平台。这个平台良心啊,免费还有文档还写的很好,也有mqtt的。这是我之前使用的一些经验可以参考一下:呵呵 发送数据:
String tcpTemp = "cmd=2&uid=" + UID + "&topic=" + TOPIC + "&msg=#X#"+String(xAccl) +"#y#"+String(yAccl)+"#z#"+String(zAccl)+ "#\r\n";; //构建发布指令
sendtoTCPServer(tcpTemp); //发送订阅指令
tcpTemp = ""; //清空
注意: 要记得清空之前的发送的指令和数据,数据包裹的格式可以自己定义,但要方便我们在前端展示时候拆装。
前端:
配置
user:{
uid: '***', // uid
topic: 'AXL345', //订阅主题AXL345
type: '3' // 选择tcp 文档里有 1位mqtt
},
发送网页请求(ajax):(这里使用了axios封装)
// 巴法云获取接口
// 将user的配置传过去
export const getBcloud = (params) => {
return ajax.request({
url: 'https://apis.bemfa.com/va/getmsg',
method:'get',
params
})
效果:
本地的mqtt
使用本地的mqtt,需要自己搭建一个本地的mqtt服务。有node.js的一点点经验所以选择了这语言,其他的后端语言也可以实现。这里使用了aceds。需要注意的是,因为前端使用到了web,而web是通过webstock进行通信的,和stock是有区别的,需要给一个专门的端口给web端订阅。本地开启的mqtt服务是在本地的ip或是你连接的路由器分配的ipv4。可以看这位大佬的这篇文章。
这里需要安装aedes 和 websocket-stream两个包
服务端代码:
const aedes=require('aedes')();
const broker = require('net').createServer(aedes.handle);
const httpServer = require('http').createServer();
const ws = require('websocket-stream');
const port = 1883; // mqtt
const wsPort = 8888; // web
broker.listen(port, function () {
console.log('broker listening on port', port)
});
ws.createServer({
server: httpServer
}, aedes.handle);
httpServer.listen(wsPort, function () {
console.log('websocket server listening on port', wsPort)
});
//身份验证
aedes.authenticate = function (client, username, password, callback) {
callback(null, (username === 'user' && password.toString() === '123456'));
};
// 客户端连接
aedes.on('client', function (client) {
console.log('Client Connected: \x1b[33m' + (client ? client.id : client) );
});
// 客户端断开
aedes.on('clientDisconnect', function (client) {
console.log('Client Disconnected: \x1b[31m' + (client ? client.id : client) );
});
前端:
import * as mqtt from 'mqtt'
// 在method里
connectMqtt() {
let that = this // 这里接住这个这个app的实例的this,
// 否则里面的作用域会变,就接不到数据到页面
const client = mqtt.connect('ws://ip:8888', this.option)
// 注意这里的ip和端口要使用你开启ws的端口
client.on("connect", () => {
console.log("服务器连接成功")
console.log(client.options.clientId);
client.subscribe("test/mqtt", { qos: 1 });
});
client.on('reconnect', () => {
console.log('重新链接')
})
client.on('error',(err) => {
console.log(err)
console.log('链接失败')
})
client.on("message", function(top, message) {
console.log("当前topic:", top)
console.log("当前数据:", message.toString())
that.data = message.toString().split('#')
})
},
// 在created生命周期里面调用就好
this.connectMqtt()
效果: