智能酒桶-树莓派与Arduino通信
邹振兴的知乎专栏 智能酒桶方案传送门 第一步:arduion驱动lora 本次实验,将实现刷卡取酒的模似功能。流程是这样,刷一次卡,出酒,再刷一次卡,停止出酒并将数据上次到树莓派中。
代码git地址 先看接线图: Arduino接线图 树莓派接线图(仿树莓派板)
使用流程: 1、刷卡 2、吹一下流量计 3、再刷一次卡 4、查看结果,树莓派地址为192.168.1.162,树莓派收到信号后,会自动增加一条记录
关键代码展示:
void loop() {
// 状态0表示空闲状态,可以开始刷卡
if(runstatus == 0) {
cardSerial.listen();
while (cardSerial.available() > 0)
{
sprintf( szTmp, "%02X", (unsigned char) cardSerial.read() );
cardID += szTmp;
delay(2);
}
// 刷卡成功,确认卡的有效性,状态转换为1
if(cardID.length() > 0 && cardID.indexOf("0D0A") != -1) {
Serial.println("Read card process start.....");
impulse = 0;
runstatus = 1;
}
} else if(runstatus == 1) { // 状态1表示正在运行状态
while (cardSerial.available() > 0)
{
sprintf( szTmp, "%02X", (unsigned char) cardSerial.read() );
tempCardID += szTmp;
delay(2);
}
// 再次刷卡结束状态
if(tempCardID.length() > 0 && tempCardID.equals(cardID)) {
Serial.println("Read card process end.....,send message.....");
cardSerial.end();
runstatus = 2;
}
tempCardID = "";
} else if(runstatus == 2) { // 为发送状态
Serial.println("begin send message.....");
String cmd = serverID + "AA3333800001" + cardID + intToHEX(impulse, 4) + myID + "FCFF";
loraSerial.listen();
delay(100);
sendCmd(cmd);
delay(1000);
String resave = "";
while (loraSerial.available() > 0)
{
sprintf( szTmp, "%02X", (unsigned char) loraSerial.read() );
resave += szTmp;
delay(2);
}
Serial.println(resave);
// 前两个FF是模块发送成功的返回,后两个FF是树莓派的返回
if(resave.equals("FFFF")) {
cardID = "";
impulse = 0;
runstatus = 0;
loraSerial.end();
Serial.println("sendMessage OK");
} else {
Serial.println("sendMessage Error, replay.....");
}
}
} ```
```js\n
const SerialPort = require('serialport');
global.serialPort = new SerialPort('/dev/ttyS1', { baudrate: 9600, autoOpen: false, parser: SerialPort.parsers.byteDelimiter([ 0xfc, 0xff ]) });
const protocol24 = require(rootPath.concat('/service/protocol24.js'));
serialPort.open(function (error) {
if (error) {
logger.error('通信串口打开失败', error);
return;
}
logger.error('通信串口打开成功');
serialPort.on('data', (data) => {
// 初步解析数据
const result = util.parseResult(data);
protocol24.parseData(result);
});
serialPort.on('error', (error) => {
logger.error('通信串口报错', error);
});
serialPort.on('disconnect', () => {
logger.error('通信串口报错连接关闭');
global.serialPort = null;
});
serialPort.on('close', () => {
logger.error('通信串口报错连接断开');
global.serialPort = null;
});
});
// 验证并解析数据
exports.parseResult = (data) => {
let recStr = Buffer.from(this.bytes2Str(data)).toString('utf-8');
// logger.info('原始数据:' + recStr);
// 解析数据
const result = {};
// 起始标志数据同步码
result.first = 'protocol24';
// 命令
result.cmd = recStr.substr(8, 4);
// 数据
result.data = recStr.slice(12, recStr.length - 4);
// 全数据
result.fulldata = recStr;
return result;
};
// 解析串口回传数据
exports.parseData = Promise.coroutine(function* (result) {
switch (result.cmd) {
case '0001': {
let obj = {};
obj.cardid = result.data.slice(0, 24);
obj.count = parseInt(result.data.slice(24, 28), 16);
obj.num = parseInt(obj.count * 1000 / 600); // ml
obj.name = result.data.slice(28, 34);
obj.update = util.dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss");
console.log(obj);
if(SocketIO) {
SocketIO.emit("TON_update", obj);
}
serialPort.write(Buffer.from(obj.name + "FF", "hex"));
break;
}
default:
break;
}
});```