[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]