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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 14930|回复: 17

[项目] 智能尿液计量仪(物联网版)

[复制链接]
发表于 2019-3-12 22:06 | 显示全部楼层 |阅读模式

图1.1.jpg 图1.2.jpg

  引流袋(如上图)是各大中医院常用的医疗设备之一,主要用来计量患者尿液量,作为医生随时调整治疗方案的重要依据。同时,尿液的计量占用医护人员时间多,计量的时效性和准确性也比较低,高档的引流袋价格也比较高,提高了医院的经营成本和患者就医压力。为解决以上问题,研发物联网版尿液智能计量系统。该系统综合运用传感器、单片机、WIFI、物联网等技术,具备脱机和在线双工作模式,手动和远程遥控双操作模式,实现了自动计量、wifi上传、网络查看和智能预警,达到了尿液计量的信息化、自动化、智能化。
图2.1.jpg 图2.2.jpg
主要材料
  上图是本项目用到的材料。左图上边一排左边是arduino nano,体积小巧性能不弱;旁边是wifi模组ESP8266-01S,体积小使用方便,3.3V供电,它下边是电平转换模块,用于nano与wifi模组间信号电平转换,有的朋友在使用ESP8266-01时没有转换供电和信号电平,也可以运行,但是不稳定有隐患,并且发热会比较严重,毕竟我的目标是希望有一天能投放市场啊(我又开始幻想了。。。);再旁边是聚合物电池芯,选它因为体积小,设备耗电也不大;再旁边是充电和升压板,如果做的东西功耗不大我一般选它们两个,便宜小巧呀;最右边是买的外壳,也就是几元钱。右边图中分别是称重传感器、专用AD转换模组和设备的挂钩,资料里面有对应的文档。下面简单介绍一下硬件制作过程:
图2.3.jpg
用到的工具
图3.png
外壳打孔
图4.png
固定传感器
图5.png
电源模块部分
y1.png
控制板PCB图
图6.png
控制板焊接
图7.png
最终内部图
图8.jpg
成品外观
  本设备使用中国移动的物联网平台:OnetNet,注册登录后界面如下图所示,依次进行添加产品、添加设备、添加数据流模板和应用管理等操作设置,具体参阅平台技术文档和本设备附带的资料,应用发布成功后最终应用界面如下图所示
t1.png
OneNet平台开发者中心界面
t2.png
应用网页
  计量仪外观及尺寸如下图所示。为固定式设计,整体简单明了。电源开关:不管是电池供电或是外部DC5V供电,使用时必须先打开电源开关,加电后设备自动启动,加入热点,与oneNet平台建立TCP链接,然后等待计量命令。计量按键:该键为绿色非自锁按键,8秒内按下并松开则设备在开始计量和停止计量间循环;当按下达8秒后松开则设备自动清除保存的热点参数和oneNet平台接入参数,清除成功指示灯只有告警灯长亮,再次使用前必须使用软件工具写入参数,此功能应用于热点变动需重新加入热点的情况,若清除后设备不能及时接受参数写入,可将设备关机后重新启动,以确保设备牌接受参数写入状态。引流袋挂钩:用于固定引流袋,固定时引流袋不能与其它物品有接触。固定螺孔:用于固定设备,应固定牢固。指示灯:当设备有电源欠压、数据积压(有计量数据未发出)、引流袋即将溢出等情况时红色告警指示灯长亮,否则不亮;当设备已加入热点并与物联网平台建立TCP链接时绿色指示灯长亮,否则不亮;当设备处于计量状态时蓝色指示灯长亮,否则不亮。
图9.png

主要功能流程
  ESP8266-01S初始工作于AP模式,端口115200波特率,开机自动开启热点,热点名称flqjl,密码20181220,自动建立TCP服务器(使用1001端口)。
   y2.png
  启动流程:流程图如上图所示,是否已写入参数判断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为真时平台收到数据后会发回一个接收确认的。
   y4.png
  
游客,如果您要查看本帖隐藏内容请回复
   y6.png
 


重要变量

  
名称
  
所属
作用
备注
measurePeriodNow
arduino
标记操作类型
0无操作,1发心跳,2测量并发数据,3传送积压数据,4干扰测量
runTime
arduino
生成时间片

measurePeriod
oneNet
计量周期
单位小时
measurePeriodTem
oneNet
周期计数用
单位30秒
devID[15]
oneNet
平台验证
设备ID
apiKey[35]
oneNet
平台验证
项目的APIKEY
msg_Id
edpKit
消息编号
上传存储时用,若要平台确认响应,必须使用消息编号,由业务层选择合适方式定期置0,以防溢出
staName[20]
Net_device
热点帐号

staPass[30]
Net_device
热点密码

initStep
Net_device
Wifi初始化
私有变量,标识初始化步骤,如果在第2步失败,下一次直接执行第2步,以提高效率。
measureDataNum
Led
脱机工作
数据积压总数
measureDataIndex
Led
脱机工作
第1个数据的EPPROM地址
preValueProTotal
Led
周期计量
上个计量周期测的总重
menusValueTotal
Led
周期计量
上个计量周期增量
preValuePro
Led
抗干扰处理
上个抗干扰周期测的总重
menusValue
Led
抗干扰处理
上个抗干扰周期增量
库介绍
  
名称
  
作用
调用库
edpkit
EDP协议的封装与解析
#include "net_device.h"
  
#include <stdlib.h>
  
#include <string.h>
  
#include <stdio.h>
  
#include <assert.h>
fault
EDP故障处理
#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"
主要功能模块介绍
  
名称
  
所属库
备注
void  setup()

系统启动加载程序,主要是初始化
void  loop()

系统主体,主要包括按键响应,物联网平台命令响应,错误处理,时钟响应
void  myClock()

与物联网平台的交互:心跳、设备状态同步、平台命令响应
uint8*  UnpacketPushdata(const uint8* mYdata,uint16* cmdCodeId,uint16* cmdCodeVal)
EdpKit
解析透传包,即:该包来自于另一设备
uint8 UnpacketSavedataSimpleStringResp(uint8*  bufdata)
EdpKit
解析存储确认包(ack),当向平台发送需存储的数据后,若平台存储成功则返回ACK
int32  UnpacketPingResp(uint8* bufdata)
EdpKit
解析心跳响应包,平台收到心跳后,向心跳来源发响应
UnpacketCmdReq(uint8*  bufdata, uint8** msgStr, uint32* msgStr_len)
EdpKit
解析平台发来的命令包
UnpacketConnectResp(uint8*  bufdata)
EdpKit
解析平台的连接响应包
uint8  EdpPacketType(uint8* bufdata)
EdpKit
检测来自平台的包的类型
uint8*  PacketCmdResp2(char* cmdEdpKit)
EdpKit
对平台命令的响应,将平台命令的消息类型改为响应后其它不变直接发给平台
uint8*  PacketSavedataSimpleString(const char* dst_devid, const char* input, bool  msgId_enable)
EdpKit
保存数据,参数:设备ID,内容,是否带消息编号。ID无效时平台不将数据转给另一个设备
uint8*  PacketConnect1(const char* devid, const char* auth_key)
EdpKit
请求链接平台包
uint8*  PacketConnect2(const char* userid, const char* auth_info)
EdpKit
请求链接平台包
void  FAULT_CLASS::Fault_Process(void)
fault
错误处理
void  LED_CLASS:ed_Init(void)
led
初始化灯和称重传感器
void  LED_CLASS:edB_Set(bool status)
led
设置蓝色指示灯
void  LED_CLASS::scaleTare(void)
led
传感器当前设为基准零点
unsigned  int  LED_CLASS::getUnits(byte times)
led
将数据按质量单位克转换
void  LED_CLASS::scalePower(bool power)
led
关闭打开传感器
unsigned  int LED_CLASS::scaleMeasure(void)
led
读取传感器数值
unsigned  char LED_CLASS::KEY_Keyboard(void)
led
按键消抖
bool  LED_CLASS::eppromDataInit(void)
led
系统启动时读取系统参数
void  LED_CLASS::eppromDataSave(void)
led
写入系统参数:设备ID,apiKey,WIFI帐号,WIFI密码
void  LED_CLASS::eppromDataWrite(void)
led
写终端未上传平台积压的数据
unsigned  int LED_CLASS::eppromDataRead(void)
led
读取积压数据
void  LED_CLASS::eppromDataWriteNormal(unsigned int index,unsigned char data)
led
写普通数据
void  LED_CLASS::eppromRestore(void)
led
将参数使用标识置零,即系统复位
void  NET_DEVICE_CLASS::NET_DEVICE_IO_Init(void)
net_device
初始化网络设备IO层
bool  NET_DEVICE_CLASS::NET_DEVICE_Init(void)
net_device
网络设备初始化
bool  NET_DEVICE_CLASS::NET_DEVICE_InitSys(void)
net_device
设备与APP连接,从APP处获取热点的帐号和密码,以及连接平台时的设备ID和APIKEY
void  NET_DEVICE_CLASS::NET_DEVICE_Reset(void)
net_device
网络设备复位
bool  NET_DEVICE_CLASS::NET_DEVICE_ReLink(void)
net_device
重连物联网平台平台
bool  NET_DEVICE_CLASS::NET_DEVICE_SendCmd(char *cmd, char *res,unsigned char  timeOut = 100)
net_device
向网络设备发送一条命令,并等待正确的响应
void  NET_DEVICE_CLASS::NET_DEVICE_SendData(unsigned char *data, unsigned short  len)
net_device
使网络设备发送数据到平台
unsigned  char *NET_DEVICE_CLASS::NET_DEVICE_GetIPD(unsigned short timeOut)
net_device
获取平台返回的数据
unsigned  char NET_DEVICE_CLASS::NET_DEVICE_Check(void)
net_device
检查网络设备连接状态
void  NET_DEVICE_CLASS::NET_DEVICE_ReConfig(unsigned char step)
net_device
设备网络设备初始化的步骤
void  NET_IO_CLASS::NET_IO_Send(unsigned char *str, unsigned short len)
net_io
发送数据
void  ONENET_CLASS::OneNet_DevLink(const char* devid, const char* auth_key)
onenet
与onenet创建连接
bool  ONENET_CLASS::OneNet_WorkUnpack(unsigned char* data)
onenet
EDP协议命令解析
void  ONENET_CLASS::OneNet_CmdResp(unsigned char *data)
onenet
发给平台的命令响应
void  ONENET_CLASS::OneNet_SendData(unsigned char sendFlag,bool msgId_enable=false)
onenet
上传数据到平台
bool  ONENET_CLASS::OneNet_HeartBeat(void)
onenet
心跳检测
void  OneNet_Replace(unsigned char *res)
onenet
替换平台下发命令中的结束符
硬件模块连接
  
 
  
WIFI
按钮
 
RX
TX
GPIO0
VCC
GND
计量
复位
 
 
 
 
 
 
 
 
arduino
D1-TX
D0-RX
 
3.3V
GND
D8
D9
 
HX117(GDSV)
指示灯(红阳绿蓝)
 
GND
DOUT
SCK
VCC
绿
arduino
GND
A5
A4
5V
D6
D7
D5
参数存储定义
  
EPPROM
  
变量
含义
单位
1023
measurePeriod
计量周期
小时
1022
warnValue
报警阀值
100ml
250
myMac
设备ID
 
200
netStatus
apiKey
 
150
 
wifi密码
 
100
 
wifi帐号
 
041
measureDataIndex
数据下标
 
040
measureDataNum
数据总数
 
000-039
dataRetenteNum
积压数据对
共20对
备注
计量值占2个字节,高字节在前
  本地端口至热点MAC各参数以@区分,并以@结束
指示灯定义
  
 
  
红(告警)
绿(网络)
蓝(计量)
无告警
未接入平台
未计量
有告警
已接入平台
正在计量
备注
1、   绿灯未亮可能是未加入热点,也可能时未接入平台;
  
2、   未设置WIFI参数,或者是有欠压、溢出告警时皆会亮红灯。


  视频链接(部分功能未演示)

  本项目资料链接:链接:https://pan.baidu.com/s/1b9wR-1XLJooUvY67_Z9IDg
提取码:2feq
复制这段内容后打开百度网盘手机App,操作更方便哦
  或者直接扫描正面的二维码:
百度网盘链接及提取码.png

t1.jpg
 楼主| 发表于 2019-3-12 22:55 | 显示全部楼层
[mw_shl_code=arduino,true]主要代码:
//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[count] =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[30];
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[5];
    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[count++] = *ptrIPD++;
                }
                GetIPD_len = (unsignedchar)atoi(sByte);
                ptrIPD++;
                for(count = 0; count <GetIPD_len; count++){
                    NET_IO.buf[count] =*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:acketConnect1(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:acketSavedataSimpleString(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[2]*255+data[3];
          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[1]==2 && data[3]==0){               
       NET_DEVICE.debugMySerialStr("linkok");
       return 1;
   }else{
       NET_DEVICE.debugMySerialStr("linkfail");
       return 0;}
   break;
caseCONNCLOSE://连接关闭0x40
   if(data[1]==1){
      netWork=0;
      LED.LedG_Set(false);// 网络指示灯灭
      NET_DEVICE.debugMySerialStr("netclose:" + String(data[2]));}
   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[3]*255+data[4];//设备地址长度
           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[2]*255+data[3];
           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[256];
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[0]));
           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;     
[/mw_shl_code]
发表于 2019-3-13 15:45 | 显示全部楼层
你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。chxyzj@tom.com
 楼主| 发表于 2019-3-13 22:33 | 显示全部楼层
chxyzj 发表于 2019-3-13 15:45
你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。 ...

不能下载有什么提示呢?我给你发一份
发表于 2019-4-7 22:16 | 显示全部楼层
网盘链接提示不存在,请更新。另外请提供演示视频,要求请参考以下链接~
https://www.arduino.cn/thread-82615-1-1.html
发表于 2019-4-10 04:58 来自手机 | 显示全部楼层
-3-13 15:45 你好,资料不能下载啊,希望能够好好学习,拜读一下你的大作,能不能发一份资料给我。157403815@qq.com
 楼主| 发表于 2019-4-25 23:02 | 显示全部楼层
更新资料链接
链接:https://pan.baidu.com/s/1FQk5NNA5_xdpK6nziWFBcg
提取码:6u77
复制这段内容后打开百度网盘手机App,操作更方便哦
有问题可联系我QQ:2554276567
发表于 2019-5-31 01:13 | 显示全部楼层
厉害,你们都是人才,如果精度可以完全可商用
发表于 2019-5-31 06:40 来自手机 | 显示全部楼层
很棒的一个作品!感谢大神分享!
 楼主| 发表于 2019-6-13 18:57 | 显示全部楼层
希望能拿个大奖
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-9-20 22:28 , Processed in 0.090658 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表