智能尿液计量仪(物联网版)-Arduino中文社区 - Powered by Discuz! Archiver

flqqjl 发表于 2019-3-12 22:06

智能尿液计量仪(物联网版)



  引流袋(如上图)是各大中医院常用的医疗设备之一,主要用来计量患者尿液量,作为医生随时调整治疗方案的重要依据。同时,尿液的计量占用医护人员时间多,计量的时效性和准确性也比较低,高档的引流袋价格也比较高,提高了医院的经营成本和患者就医压力。为解决以上问题,研发物联网版尿液智能计量系统。该系统综合运用传感器、单片机、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,操作更方便哦  或者直接扫描正面的二维码:

flqqjl 发表于 2019-3-12 22:55

主要代码:
//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 发表于 2019-3-13 15:45

你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。chxyzj@tom.com

flqqjl 发表于 2019-3-13 22:33

chxyzj 发表于 2019-3-13 15:45
你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。 ...

不能下载有什么提示呢?我给你发一份

syl312 发表于 2019-4-7 22:16

网盘链接提示不存在,请更新。另外请提供演示视频,要求请参考以下链接~
https://www.arduino.cn/thread-82615-1-1.html

jinfangyi 发表于 2019-4-10 04:58

-3-13 15:45 你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。157403815@qq.com

flqqjl 发表于 2019-4-25 23:02

更新资料链接
链接:https://pan.baidu.com/s/1FQk5NNA5_xdpK6nziWFBcg
提取码:6u77
复制这段内容后打开百度网盘手机App,操作更方便哦
有问题可联系我QQ:2554276567

godisme44 发表于 2019-5-31 01:13

厉害,你们都是人才,如果精度可以完全可商用

mlkxm 发表于 2019-5-31 06:40

很棒的一个作品!感谢大神分享!

flqqjl 发表于 2019-6-13 18:57

希望能拿个大奖:P
页: [1] 2
查看完整版本: 智能尿液计量仪(物联网版)