智能尿液计量仪(物联网版)
引流袋(如上图)是各大中医院常用的医疗设备之一,主要用来计量患者尿液量,作为医生随时调整治疗方案的重要依据。同时,尿液的计量占用医护人员时间多,计量的时效性和准确性也比较低,高档的引流袋价格也比较高,提高了医院的经营成本和患者就医压力。为解决以上问题,研发物联网版尿液智能计量系统。该系统综合运用传感器、单片机、WIFI、物联网等技术,具备脱机和在线双工作模式,手动和远程遥控双操作模式,实现了自动计量、wifi上传、网络查看和智能预警,达到了尿液计量的信息化、自动化、智能化。主要材料 上图是本项目用到的材料。左图上边一排左边是arduino nano,体积小巧性能不弱;旁边是wifi模组ESP8266-01S,体积小使用方便,3.3V供电,它下边是电平转换模块,用于nano与wifi模组间信号电平转换,有的朋友在使用ESP8266-01时没有转换供电和信号电平,也可以运行,但是不稳定有隐患,并且发热会比较严重,毕竟我的目标是希望有一天能投放市场啊(我又开始幻想了。。。);再旁边是聚合物电池芯,选它因为体积小,设备耗电也不大;再旁边是充电和升压板,如果做的东西功耗不大我一般选它们两个,便宜小巧呀;最右边是买的外壳,也就是几元钱。右边图中分别是称重传感器、专用AD转换模组和设备的挂钩,资料里面有对应的文档。下面简单介绍一下硬件制作过程: 用到的工具 外壳打孔 固定传感器 电源模块部分控制板PCB图 控制板焊接最终内部图 成品外观 本设备使用中国移动的物联网平台:OnetNet,注册登录后界面如下图所示,依次进行添加产品、添加设备、添加数据流模板和应用管理等操作设置,具体参阅平台技术文档和本设备附带的资料,应用发布成功后最终应用界面如下图所示 OneNet平台开发者中心界面 应用网页 计量仪外观及尺寸如下图所示。为固定式设计,整体简单明了。电源开关:不管是电池供电或是外部DC5V供电,使用时必须先打开电源开关,加电后设备自动启动,加入热点,与oneNet平台建立TCP链接,然后等待计量命令。计量按键:该键为绿色非自锁按键,8秒内按下并松开则设备在开始计量和停止计量间循环;当按下达8秒后松开则设备自动清除保存的热点参数和oneNet平台接入参数,清除成功指示灯只有告警灯长亮,再次使用前必须使用软件工具写入参数,此功能应用于热点变动需重新加入热点的情况,若清除后设备不能及时接受参数写入,可将设备关机后重新启动,以确保设备牌接受参数写入状态。引流袋挂钩:用于固定引流袋,固定时引流袋不能与其它物品有接触。固定螺孔:用于固定设备,应固定牢固。指示灯:当设备有电源欠压、数据积压(有计量数据未发出)、引流袋即将溢出等情况时红色告警指示灯长亮,否则不亮;当设备已加入热点并与物联网平台建立TCP链接时绿色指示灯长亮,否则不亮;当设备处于计量状态时蓝色指示灯长亮,否则不亮。
主要功能流程 ESP8266-01S初始工作于AP模式,端口115200波特率,开机自动开启热点,热点名称flqjl,密码20181220,自动建立TCP服务器(使用1001端口)。 启动流程:流程图如上图所示,是否已写入参数判断EPPROM(1023)即计量周期的值,为0则判断为没有系统参数(wifi帐号和密码,平台的APIKEY和设备ID),非0则判断为已写入参数;4个参数必须全部输入,没有顺序要求,wifi帐号加前缀“name:”,wifi密码加前缀“pass:”,设备ID加前缀“deid:”,APIKEY加前缀“apik:”。目前为生产方便,终端代码中未固化设备ID和APIKEY,产品生产出来后,工厂再利用写入终端将ID和APIKEY写入终端设备存储区。ID和APIKEY写于设备壳体外,或者以二维码的形式贴于壳体外。 系统运行流程图:流程图如上图所示,每15秒一个时间片,每个时间片1次心跳,每20个时间片1次干扰测量,优先级周期计量>干扰测量>发送积压数据>心跳;计量按键为按钮1,复位按键为按钮2,当2个按钮同时按下时响应按钮1,即计量按钮;发送函数的参数msgId_enable为真时平台收到数据后会发回一个接收确认的。 **** Hidden Message *****
重要变量
名称所属作用备注
measurePeriodNowarduino标记操作类型0无操作,1发心跳,2测量并发数据,3传送积压数据,4干扰测量
runTimearduino生成时间片
measurePeriodoneNet计量周期单位小时
measurePeriodTemoneNet周期计数用单位30秒
devIDoneNet平台验证设备ID
apiKeyoneNet平台验证项目的APIKEY
msg_IdedpKit消息编号上传存储时用,若要平台确认响应,必须使用消息编号,由业务层选择合适方式定期置0,以防溢出
staNameNet_device热点帐号
staPassNet_device热点密码
initStepNet_deviceWifi初始化私有变量,标识初始化步骤,如果在第2步失败,下一次直接执行第2步,以提高效率。
measureDataNumLed脱机工作数据积压总数
measureDataIndexLed脱机工作第1个数据的EPPROM地址
preValueProTotalLed周期计量上个计量周期测的总重
menusValueTotalLed周期计量上个计量周期增量
preValueProLed抗干扰处理上个抗干扰周期测的总重
menusValueLed抗干扰处理上个抗干扰周期增量
库介绍
名称作用调用库
edpkitEDP协议的封装与解析#include "net_device.h"#include <stdlib.h>#include <string.h>#include <stdio.h>#include <assert.h>
faultEDP故障处理#include "onenet.h"#include "net_device.h"
led指示灯、称重传感器、按键和EPPROM控制#include <Arduino.h>#include <EEPROM.h>#include <HX711.h>#include "onenet.h"#include "net_device.h"
net_device网络设备ESP8266-01S驱动#include "net_io.h"#include "led.h"
net_io网络设备输入输出#include <Arduino.h>
onenet物联网平台业务处理#include <Arduino.h>#include "fault.h"#include "net_device.h"#include "edpkit.h"#include "led.h"
主要功能模块介绍
名称所属库备注
voidsetup()
系统启动加载程序,主要是初始化
voidloop()
系统主体,主要包括按键响应,物联网平台命令响应,错误处理,时钟响应
voidmyClock()
与物联网平台的交互:心跳、设备状态同步、平台命令响应
uint8*UnpacketPushdata(const uint8* mYdata,uint16* cmdCodeId,uint16* cmdCodeVal)EdpKit解析透传包,即:该包来自于另一设备
uint8 UnpacketSavedataSimpleStringResp(uint8*bufdata)EdpKit解析存储确认包(ack),当向平台发送需存储的数据后,若平台存储成功则返回ACK
int32UnpacketPingResp(uint8* bufdata)EdpKit解析心跳响应包,平台收到心跳后,向心跳来源发响应
UnpacketCmdReq(uint8*bufdata, uint8** msgStr, uint32* msgStr_len)EdpKit解析平台发来的命令包
UnpacketConnectResp(uint8*bufdata) EdpKit解析平台的连接响应包
uint8EdpPacketType(uint8* bufdata)EdpKit检测来自平台的包的类型
uint8*PacketCmdResp2(char* cmdEdpKit) EdpKit对平台命令的响应,将平台命令的消息类型改为响应后其它不变直接发给平台
uint8*PacketSavedataSimpleString(const char* dst_devid, const char* input, boolmsgId_enable) EdpKit保存数据,参数:设备ID,内容,是否带消息编号。ID无效时平台不将数据转给另一个设备
uint8*PacketConnect1(const char* devid, const char* auth_key)EdpKit请求链接平台包
uint8*PacketConnect2(const char* userid, const char* auth_info)EdpKit请求链接平台包
voidFAULT_CLASS::Fault_Process(void)fault错误处理
voidLED_CLASS::Led_Init(void)led初始化灯和称重传感器
voidLED_CLASS::LedB_Set(bool status)led设置蓝色指示灯
voidLED_CLASS::scaleTare(void)led传感器当前设为基准零点
unsignedintLED_CLASS::getUnits(byte times)led将数据按质量单位克转换
voidLED_CLASS::scalePower(bool power)led关闭打开传感器
unsignedint LED_CLASS::scaleMeasure(void)led读取传感器数值
unsignedchar LED_CLASS::KEY_Keyboard(void)led按键消抖
boolLED_CLASS::eppromDataInit(void)led系统启动时读取系统参数
voidLED_CLASS::eppromDataSave(void)led写入系统参数:设备ID,apiKey,WIFI帐号,WIFI密码
voidLED_CLASS::eppromDataWrite(void)led写终端未上传平台积压的数据
unsignedint LED_CLASS::eppromDataRead(void)led读取积压数据
voidLED_CLASS::eppromDataWriteNormal(unsigned int index,unsigned char data)led写普通数据
voidLED_CLASS::eppromRestore(void)led将参数使用标识置零,即系统复位
voidNET_DEVICE_CLASS::NET_DEVICE_IO_Init(void)net_device初始化网络设备IO层
boolNET_DEVICE_CLASS::NET_DEVICE_Init(void)net_device网络设备初始化
boolNET_DEVICE_CLASS::NET_DEVICE_InitSys(void)net_device设备与APP连接,从APP处获取热点的帐号和密码,以及连接平台时的设备ID和APIKEY
voidNET_DEVICE_CLASS::NET_DEVICE_Reset(void)net_device网络设备复位
boolNET_DEVICE_CLASS::NET_DEVICE_ReLink(void)net_device重连物联网平台平台
boolNET_DEVICE_CLASS::NET_DEVICE_SendCmd(char *cmd, char *res,unsigned chartimeOut = 100)net_device向网络设备发送一条命令,并等待正确的响应
voidNET_DEVICE_CLASS::NET_DEVICE_SendData(unsigned char *data, unsigned shortlen)net_device使网络设备发送数据到平台
unsignedchar *NET_DEVICE_CLASS::NET_DEVICE_GetIPD(unsigned short timeOut)net_device获取平台返回的数据
unsignedchar NET_DEVICE_CLASS::NET_DEVICE_Check(void)net_device检查网络设备连接状态
voidNET_DEVICE_CLASS::NET_DEVICE_ReConfig(unsigned char step)net_device设备网络设备初始化的步骤
voidNET_IO_CLASS::NET_IO_Send(unsigned char *str, unsigned short len)net_io发送数据
voidONENET_CLASS::OneNet_DevLink(const char* devid, const char* auth_key)onenet与onenet创建连接
boolONENET_CLASS::OneNet_WorkUnpack(unsigned char* data)onenetEDP协议命令解析
voidONENET_CLASS::OneNet_CmdResp(unsigned char *data)onenet发给平台的命令响应
voidONENET_CLASS::OneNet_SendData(unsigned char sendFlag,bool msgId_enable=false)onenet上传数据到平台
boolONENET_CLASS::OneNet_HeartBeat(void)onenet心跳检测
voidOneNet_Replace(unsigned char *res)onenet替换平台下发命令中的结束符
硬件模块连接
WIFI按钮
RXTXGPIO0VCCGND计量复位
arduinoD1-TXD0-RX 3.3VGNDD8D9
HX117(GDSV)指示灯(红阳绿蓝)
GNDDOUTSCKVCC红绿蓝
arduinoGNDA5A45VD6D7D5
参数存储定义
EPPROM变量含义单位
1023measurePeriod计量周期小时
1022warnValue报警阀值100ml
250myMac设备ID
200netStatusapiKey
150 wifi密码
100 wifi帐号
041measureDataIndex数据下标
040measureDataNum数据总数
000-039dataRetenteNum积压数据对共20对
备注计量值占2个字节,高字节在前
本地端口至热点MAC各参数以@区分,并以@结束
指示灯定义
红(告警)绿(网络)蓝(计量)
灭无告警未接入平台未计量
亮有告警已接入平台正在计量
备注1、 绿灯未亮可能是未加入热点,也可能时未接入平台;2、 未设置WIFI参数,或者是有欠压、溢出告警时皆会亮红灯。
视频链接(部分功能未演示)
本项目资料链接:链接:https://pan.baidu.com/s/1b9wR-1XLJooUvY67_Z9IDg 提取码:2feq 复制这段内容后打开百度网盘手机App,操作更方便哦 或者直接扫描正面的二维码:
主要代码:
//NET_IO_CLASS:串口收发硬件驱动
//功能: 发送数据
voidNET_IO_CLASS::NET_IO_Send(unsigned char *str, unsigned short len)
{ Serial.write(str, len);
Serial.flush();
}
//功能:等待接收完成
boolNET_IO_CLASS::NET_IO_WaitRecive(void)
{ unsigned char count = 0;
NET_IO_CLASS::dataLen = Serial.available();
if(NET_IO_CLASS::dataLen == 0)
return REV_WAIT;
if(NET_IO_CLASS::dataLen ==NET_IO_CLASS::dataLenPre)
{ for(; count < NET_IO_CLASS::dataLen; count++)
NET_IO_CLASS::buf =Serial.read();
NET_IO_CLASS::dataLen = 0;
return REV_OK;
}
NET_IO_CLASS::dataLenPre =NET_IO_CLASS::dataLen;
return REV_WAIT;
}
// NET_DEVICE_CLASS:网络设备esp8266-01s硬件驱动
//功能:向网络设备发送一条命令,并等待正确的响应
boolNET_DEVICE_CLASS::NET_DEVICE_SendCmd(char *cmd, char *res,unsigned char timeOut= 100)
{NET_IO.NET_IO_Send((unsigned char *)cmd,strlen(cmd));
while(timeOut--)
{if(NET_IO.NET_IO_WaitRecive() == REV_OK)
{if(strstr((const char *)NET_IO.buf,res) != NULL)
{NET_IO.NET_IO_ClearRecive();
return 0; }}
delay(10); }
return 1;}
//功能:使网络设备发送数据到平台
voidNET_DEVICE_CLASS::NET_DEVICE_SendData(unsigned char *data, unsigned short len)
{char cmdBuf;
delay(50);
NET_IO.NET_IO_ClearRecive();
sprintf(cmdBuf,"AT+CIPSEND=%d\r\n", len);
if(!NET_DEVICE_SendCmd(cmdBuf,">")){
NET_IO.NET_IO_Send(data, len); }
}
//功能: 获取平台返回的数据
unsignedchar *NET_DEVICE_CLASS::NET_DEVICE_GetIPD(unsigned short timeOut)
{ unsigned char count = 0;
char sByte;
char *ptrIPD;
do
{if(NET_IO.NET_IO_WaitRecive() == REV_OK) {
ptrIPD = strstr((char *)NET_IO.buf,"IPD,");
if(ptrIPD) {
ptrIPD = strstr(ptrIPD,",");ptrIPD++;
while(*ptrIPD != ':') {
sByte = *ptrIPD++;
}
GetIPD_len = (unsignedchar)atoi(sByte);
ptrIPD++;
for(count = 0; count <GetIPD_len; count++){
NET_IO.buf =*ptrIPD++;}
return NET_IO.buf;}}
delay(10);
} while(timeOut--);
return NULL; }
//称重传感器计量
voidLED_CLASS::scaleTest(void)
{
unsigned int measureData=0;
unsigned int menusTem=0;
scale.power_up();
delay(20);
measureData=getUnits(3);
scale.power_down();
menusTem=measureData-preValuePro;
if(fabs(menusTem-menusValue)/menusValue<0.5){//测量合规,更新参数
preValuePro=measureData;//记录当前总重
menusValue=menusTem;//更新单位增量参数
}else{//计量有干扰,使用修正值
preValuePro+=menusValue;
}}
unsignedint LED_CLASS::scaleMeasure(void)
{scaleTest();
menusValueTotal=preValuePro-preValueProTotal;
preValueProTotal=preValuePro;
return preValueProTotal;
}
// EdpPacketClass:EDP协议实现
//功能:打包设备到设备云的EDP协议包,连接设备云的请求包
uint8*EdpPacketClass::PacketConnect1(const char* devid, const char* auth_key)
{
uint32 remainlen;
ClearParameter();
WriteByte(CONNREQ);/* msg type */
remainlen =(2+3)+1+1+2+(2+strlen(devid))+(2+strlen(auth_key));
WriteRemainlen(remainlen);/* remain len */
WriteStr(PROTOCOL_NAME);/* protocol desc */
WriteByte(PROTOCOL_VERSION); /* protocolversion */
WriteByte(0x40);/* connect flag */
WriteUint16(0x0080);/* keep time */
WriteStr(devid);/* DEVID */
WriteStr(auth_key);/* auth key */
return this->data;
}
//功能:打包设备到设备云的EDP协议包,存储数据(数据类型五)
uint8* EdpPacketClass::PacketSavedataSimpleString(constchar* dst_devid, const char* input,bool msgId_enable)
{
uint32 remainlen = 0;
uint32 input_len = 0;
uint16 flag = 0;
ClearParameter();
input_len = strlen(input);
WriteByte(SAVEDATA);
remainlen = 1 + (msgId_enable ? 2:0) +(dst_devid ? (2+strlen(dst_devid)) : 0) + 1 + (2+input_len);
WriteRemainlen(remainlen);
flag |= dst_devid ? 0x80 : 0;
flag |= msgId_enable ? 0x40 : 0;
WriteByte(flag);
if (dst_devid) WriteStr(dst_devid);
if(msgId_enable)WriteUint16(msg_Id++);
WriteByte(kTypeString);
WriteStr(input);
return this->data;
}
//功能: 解包 由设备云到设备的EDP协议包,命令请求消息
int32EdpPacketClass::UnpacketCmdReq(uint8* bufdata, uint8** msgStr, uint32*msgStr_len)
{ uint8*cmdid;
PutData(bufdata);
ReadByte(cmdid);
if (ReadRemainlen(msgStr_len))
return ERR_UNPACK_CMDREQ;
if (ReadStr(&cmdid)) //CMDID部分
return ERR_UNPACK_CMDREQ;
if (ReadUint32(msgStr_len))//读4字节的消息体长度值
return ERR_UNPACK_CMDREQ;
*msgStr = (char*)malloc(sizeof(char) *((*msgStr_len)+1));
strncpy(*msgStr, (const char *)(data +read_pos), *msgStr_len);
return 0;
}
//OneNet_DevLink:业务功能实现
//功能: 与onenet创建连接
voidONENET_CLASS::OneNet_DevLink(const char* devid, const char* auth_key)
{ unsigned char *dataPtr;
EDPKIT.PacketConnect1(devid, auth_key);
NET_DEVICE.NET_DEVICE_SendData(EDPKIT.GetData(), EDPKIT.GetWritepos());
dataPtr =NET_DEVICE.NET_DEVICE_GetIPD(250);
if(dataPtr != NULL)
ONENET_CLASS::netWork= ONENET_CLASS::OneNet_WorkUnpack(dataPtr);
EDPKIT.ClearParameter();
if(ONENET_CLASS::netWork){
ONENET_CLASS::errCount = 0;
NET_DEVICE.NET_DEVICE_Set_DataMode(DEVICE_DATA_MODE);
LED.LedG_Set(true);// 网络指示灯亮
OneNet_SendData(7);
delay(1000);
OneNet_SendData(8);}
else{
if(++ONENET_CLASS::errCount >= 3){
ONENET_CLASS::netWork = 0;
FAULT.faultType = FAULT.faultTypeReport= FAULT_NODEVICE; }
LED.LedG_Set(false);}// 网络指示灯灭
}
//功能: EDP协议命令解析
boolONENET_CLASS::OneNet_WorkUnpack(unsigned char* data)
{ unsigned int tem=0;
unsigned char* msgStr;
unsigned char* msgStr2;
unsigned long msgStr_len=0;
unsigned int cmdCodeId=1;
unsigned int cmdCodeVal=1;
bool reFlag=0;
switch(*data){
case CMDREQ://命令请求0xA0 ,
cmdCodeId=data*255+data;
tem=NET_DEVICE.GetIPD_len-cmdCodeId-8;
msgStr = (char*)malloc(sizeof(char) * tem+1);
memset(msgStr, 0, tem+1);
strncpy(msgStr, (const char *)(data +NET_DEVICE.GetIPD_len-tem), tem);
NET_DEVICE.hexdump(msgStr,tem);//调试打印
cmdCodeId=atoi(msgStr);
msgStr2 = strstr((const char*)msgStr, ":");
if(!msgStr2) return -1;
cmdCodeVal=atoi(msgStr2+1);
if(cmdCodeId==2){
if(cmdCodeVal&&!workStatusM)measurePeriodTem=measurePeriod-1;
measurePeriodTem=measurePeriod*240-1;
workStatusM=cmdCodeVal;
LED.LedB_Set(workStatusM);// 网络指示灯
NET_DEVICE.debugMySerialStr("measure:" + String(cmdCodeVal));}
if(cmdCodeId==3){//修改计量周期命令
if(cmdCodeVal>measurePeriod)measurePeriodTem=measurePeriodTem+(cmdCodeVal-measurePeriod);
if(cmdCodeVal<measurePeriod&& measurePeriodTem>cmdCodeVal)measurePeriodTem=cmdCodeVal;
measurePeriod=cmdCodeVal;
LED.eppromDataWriteNormal(1023,measurePeriod);
NET_DEVICE.debugMySerialStr("period:" +String(measurePeriod)); }
return0;
break;
caseCONNRESP://连接响应0x20
if(data==2 && data==0){
NET_DEVICE.debugMySerialStr("linkok");
return 1;
}else{
NET_DEVICE.debugMySerialStr("linkfail");
return 0;}
break;
caseCONNCLOSE://连接关闭0x40
if(data==1){
netWork=0;
LED.LedG_Set(false);// 网络指示灯灭
NET_DEVICE.debugMySerialStr("netclose:" + String(data));}
return 0;
break;
caseSAVEACK: //存储确认1成功,0失败0x90
reFlag=EDPKIT.UnpacketSavedataSimpleStringResp(data);
if(reFlag==1){
NET_DEVICE.debugMySerialStr("saveok");}
else{
NET_DEVICE.debugMySerialStr("savefail");}
return !reFlag;
break;
case SAVEDATA://转发0x80
cmdCodeId=data*255+data;//设备地址长度
tem=NET_DEVICE.GetIPD_len-cmdCodeId-8;
msgStr = (char*)malloc(sizeof(char)* tem+1);
memset(msgStr, 0, tem+1);
strncpy(msgStr, (const char *)(data+ NET_DEVICE.GetIPD_len-tem), tem);
NET_DEVICE.hexdump(msgStr,tem);//调试打印
cmdCodeId=atoi(msgStr+2);//格式:,;01:1(,;:数据流,值)
msgStr2 = strstr((const char*)(msgStr+1), ",");
if(!msgStr2) return -1;
cmdCodeVal=atoi(msgStr2+1);
NET_DEVICE.debugMySerialStr(String(cmdCodeId));
NET_DEVICE.debugMySerialStr(String(cmdCodeVal));
return 0;
break;
case PUSHDATA://透传0x30
cmdCodeId=data*255+data;
tem=NET_DEVICE.GetIPD_len-cmdCodeId-4;
msgStr = (char*)malloc(sizeof(char)* tem+1);
memset(msgStr, 0, tem+1);
strncpy(msgStr, (const char *)(data+ NET_DEVICE.GetIPD_len-tem), tem);
NET_DEVICE.hexdump(msgStr,tem);//调试打印
cmdCodeId=atoi(msgStr);//格式:01:1(数据流,值)
msgStr2 = strstr((const char*)msgStr, ":");
if(!msgStr2) return -1;
cmdCodeVal=atoi(msgStr2+1);
NET_DEVICE.debugMySerialStr(String(cmdCodeId));
NET_DEVICE.debugMySerialStr(String(cmdCodeVal));
return 0;
break;
default:
return -1;
}
NET_DEVICE.NET_DEVICE_ClrData();
}
//功能: 上传数据到平台
voidONENET_CLASS::OneNet_SendData(unsigned char sendFlag,bool msgId_enable=false)
{ unsigned char *dataPtr;
char send_buf;
if(!ONENET_CLASS::netWork ||NET_DEVICE.NET_DEVICE_Get_DataMode() != DEVICE_DATA_MODE)
return 1;
NET_DEVICE.NET_DEVICE_Set_DataMode(DEVICE_CMD_MODE);
memset(send_buf, 0, sizeof(send_buf));
switch(sendFlag){
case 1://发送开关状态
EDPKIT.msg_Id=1;//防止消息编号溢出
sprintf(send_buf,",;02,%d",workStatusM);
break;
case 2://发送测量数据
sprintf(send_buf,",;01,%d",LED.scaleMeasure());
break;
case 3://发送积压数据
sprintf(send_buf,",;01,%d",LED.eppromDataRead());
return 1;
break;
case 4://发送告警信息:数据积压
sprintf(send_buf, ",;04,%d",2);
break;
case 41://发送告警信息:溢出
sprintf(send_buf,",;04,%d",4);
break;
case 42://发送告警信息:欠压
sprintf(send_buf,",;04,%d",8);
break;
case 5://发送计量周期
sprintf(send_buf,",;03,%d",measurePeriod);
break;
case 6://发送开关
sprintf(send_buf,",;02,%d",workStatusM);
break;
case 7://发送错误的计量周期、开关状态
sprintf(send_buf,",;02,%d",!workStatusM);
break;
case 8://发送计量周期、开关状态
sprintf(send_buf, ",;03,%d;02,%d",measurePeriod,workStatusM);
break;
default:
return 1;
}
EDPKIT.PacketSavedataSimpleString(NULL,send_buf,msgId_enable);
NET_DEVICE.NET_DEVICE_SendData(EDPKIT.GetData(), EDPKIT.GetWritepos());
EDPKIT.ClearParameter();
FAULT.faultTypeReport = FAULT_NONE;
NET_DEVICE.NET_DEVICE_Set_DataMode(DEVICE_DATA_MODE);
return 0;
}
//程序主体控制
voidsetup()
{ bool wifiName=true;
bool wifiPass=true;
bool platId=true;
bool platKey=true;
LED.Led_Init();
NET_DEVICE.NET_DEVICE_IO_Init();
NET_DEVICE.NET_DEVICE_Reset();
NET_DEVICE.NET_DEVICE_Set_DataMode(0);
if(LED.eppromDataInit()){
NET_DEVICE.debugMySerialStr("ap start....");
while(NET_DEVICE.NET_DEVICE_InitSys())delay(1000);
NET_DEVICE.debugMySerialStr("apok....");
do{
dataPtr =NET_DEVICE.NET_DEVICE_GetIPDSys();
if(dataPtr != NULL){
NET_DEVICE.debugMySerialStr(String(dataPtr));
if(strstr(dataPtr,"name:") &&NET_DEVICE.GetIPD_len-5>0){strncpy(NET_DEVICE.staName,dataPtr+5,NET_DEVICE.GetIPD_len-5);wifiName=false;}//收到热点帐号
if(strstr(dataPtr,"pass:") &&NET_DEVICE.GetIPD_len-5>0){strncpy(NET_DEVICE.staPass,dataPtr+5,NET_DEVICE.GetIPD_len-5);wifiPass=false;}//收到热点密码
if(strstr(dataPtr,"deid:") &&NET_DEVICE.GetIPD_len-5>0){strncpy(ONENET.devID,dataPtr+5,NET_DEVICE.GetIPD_len-5);platId=false;}//收到设备ID
if(strstr(dataPtr,"apik:")&&NET_DEVICE.GetIPD_len-5>0){strncpy(ONENET.apiKey,dataPtr+5,NET_DEVICE.GetIPD_len-5);platKey=false;}}//收到平台的KEY
LED.LedR_Set(!LED.ledRSta);//红灯闪烁
delay(500);
}while(wifiName || wifiPass || platId ||platKey);
ONENET.measurePeriod=2;
LED.eppromDataSave();//保存系统参数
NET_DEVICE.debugMySerialStr(NET_DEVICE.staName);
NET_DEVICE.debugMySerialStr(NET_DEVICE.staPass);
NET_DEVICE.debugMySerialStr(ONENET.devID);
NET_DEVICE.debugMySerialStr(ONENET.apiKey);
NET_DEVICE.NET_DEVICE_Reset();
delay(2000);
LED.LedR_Set(false);}//关闭红灯
NET_DEVICE.debugMySerialStr("started...");
}
voidloop()
{{ int keyValue=0;
keyValue=LED.KEY_Keyboard();
if(keyValue==1){//计量开关按键
ONENET.workStatusM=!ONENET.workStatusM;
LED.LedB_Set(ONENET.workStatusM);// 网络指示灯
ONENET.OneNet_SendData(1);//发送:开始/停止计量数据
if(ONENET.workStatusM){
ONENET.measurePeriodTem=ONENET.measurePeriod-1;
runTime=millis();}
}
if(keyValue==2){//恢复系统参数按键
LED.eppromRestore();
while(1)delay(1000); }}
if(ONENET.netWork)//按执行概率由高至低排序
{LED.LedG_Set(true);// 网络指示灯
dataPtr =NET_DEVICE.NET_DEVICE_GetIPD(0);
if(dataPtr != NULL)ONENET.OneNet_WorkUnpack(dataPtr);
}else{
LED.LedG_Set(false);// 网络指示灯灭
NET_DEVICE.debugMySerialStr("initfault:" + String(FAULT.faultType));
if(!NET_DEVICE.NET_DEVICE_Init())
{NET_DEVICE.debugMySerialStr("linking...");
ONENET.OneNet_DevLink(ONENET.devID,ONENET.apiKey);}
delay(100); }
if(FAULT.faultType != FAULT_NONE){
NET_DEVICE.debugMySerialStr("error:"+ String(FAULT.faultType));
delay(2);
FAULT.Fault_Process();}
delay(10);
myClock();}
voidmyClock(){
if(millis()-runTime>15000){
NET_DEVICE.debugMySerialStr(String(ONENET.workStatusM));
runTime=millis();
if(ONENET.netWork)measurePeriodNow=1;//入网才发心跳
if(ONENET.workStatusM){//已开始测量
if (ONENET.measurePeriodTem--<1){//计量周期到
ONENET.measurePeriodTem=ONENET.measurePeriod*240-1;
measurePeriodNow=2;
}else{
if(ONENET.measurePeriodTem %10==0)measurePeriodNow=4;}
}
if(LED.measureDataNum>0 &&measurePeriodNow==1)
measurePeriodNow=3;
switch(measurePeriodNow){
case 1://心跳
NET_DEVICE.debugMySerialStr("heartbeat...");
ONENET.OneNet_HeartBeat();
break;
case 4://抗干扰测量
LED.scaleTest();
break;
case 2://测量发送
LED.scaleTest();
if(ONENET.netWork &&LED.measureDataNum==0){
NET_DEVICE.debugMySerialStr("data...");
ONENET.OneNet_SendData(2,true);}
else{//离线,保存数据
NET_DEVICE.debugMySerialStr("epprom data...");
LED.eppromDataWrite();
}
break;
case 3://积压数据发送
ONENET.OneNet_SendData(3,true);
break;
}
measurePeriodNow=0;
你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。chxyzj@tom.com chxyzj 发表于 2019-3-13 15:45
你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。 ...
不能下载有什么提示呢?我给你发一份 网盘链接提示不存在,请更新。另外请提供演示视频,要求请参考以下链接~
https://www.arduino.cn/thread-82615-1-1.html -3-13 15:45 你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。157403815@qq.com 更新资料链接
链接:https://pan.baidu.com/s/1FQk5NNA5_xdpK6nziWFBcg
提取码:6u77
复制这段内容后打开百度网盘手机App,操作更方便哦
有问题可联系我QQ:2554276567 厉害,你们都是人才,如果精度可以完全可商用 很棒的一个作品!感谢大神分享! 希望能拿个大奖:P
页:
[1]
2