/* ********************************************************************************************************* * IAR Development Kits * on the * * M451 * * Filename : uart_dtu.c * Version : V1.00 * Programmer(s) : Qian Xianghong ********************************************************************************************************* */ #include "includes.h" #include "drv_dtu.h" #include "drv_gps.h" #include "ccs_prediction.h" // 初始唤醒次数(快速发送) #define INITIAL_TRAN_COUNT 6 // 绝对值 #define abs(x) ((x) < 0 ? -(x) : (x)) // GPS上报数据的时间戳,年基数为2010 #define GPS_BASE_YEAR 2010 // Boot-loader地址(在线升级以后重启运行) #define LDROM_BASE 0x100000ul // 1M // GPRS串口接收的循环缓冲 #define DTU_TASKM_DATA_COUNT 200 loopbuff_t DTU_TaskM; uint8_t DTU_TaskM_Data[sizeof(uint8_t) * (DTU_TASKM_DATA_COUNT + 1)] = {0}; // 强制上传数据 volatile uint8_t DTU_dataConn = 0; // 强制连接维护平台 volatile uint8_t DTU_ldmsConn = 0; // 维护平台连接计时 volatile uint32_t DTU_ldmsTime = 0; // 最近一条上传数据的采集时间 volatile uint32_t DTU_dataTime = 0; // 发送成功时间 volatile uint32_t DTU_succTime = 0; // 这个缓冲区比较大,不放在stack里面 char DTU_gpsData[2][DTU_GPSDATA_SIZE] = {0}; // 扩展内存 char DTU_recvBuff[DTU_RECVBUFF_SIZE] = {0}; // 扩展内存 // 一次请求升级包数据大小 #define UPGRADE_DATA_LEN 1024 // DTU_Task任务和服务器之间的收发缓冲 #define TASK_SENDBUFF_SIZE 400 uint8_t Task_sendBuff[TASK_SENDBUFF_SIZE] = {0}; // 扩展内存 #if UPGRADE_DATA_LEN >= SFLASH_ERASE_SIZE #define TASK_RECVBUFF_SIZE (UPGRADE_DATA_LEN + 32) #else #define TASK_RECVBUFF_SIZE (SFLASH_ERASE_SIZE) #endif uint8_t Task_recvBuff[TASK_RECVBUFF_SIZE] = {0}; // 扩展内存 // 信号量,用于通知执行任务 volatile uint8_t DTU_semGPS = 0; volatile uint8_t DTU_semGPRS = 0; volatile uint8_t DTU_semSync = 0; // 用于发送到服务器的数据结构 // 和蓝牙的相应命令一致 #pragma pack(push, 1) typedef struct { uint16_t mark; unsigned ver : 7; unsigned trans : 1; unsigned reserved: 8; uint16_t len; union { uint16_t cmd; struct { uint8_t err; uint8_t cmd_L; }; }; } bluetooth_recv_t; typedef bluetooth_recv_t bluetooth_send_t; typedef struct { unsigned staEPress3 : 2; unsigned staETempr1 : 2; unsigned staETempr2 : 2; unsigned staETempr3 : 2; unsigned staDiff : 2; unsigned staPress : 2; unsigned staEPress1 : 2; unsigned staEPress2 : 2; } bluetooth_sensor_t; typedef struct { unsigned maskStamp : 1; unsigned maskEPress1 : 1; unsigned maskEPress2 : 1; unsigned maskEPress3 : 1; unsigned : 1; unsigned maskLowPower : 1; unsigned maskAbnormal : 1; unsigned maskCharging : 1; unsigned maskRssi : 1; unsigned maskGPS : 1; unsigned maskETempr1 : 1; unsigned maskETempr2 : 1; unsigned maskETempr3 : 1; unsigned maskBattery : 1; unsigned maskFlow : 1; unsigned maskLeak : 1; } bluetooth_mask_t; typedef union { struct { unsigned sec : 6; unsigned min : 6; unsigned hour_L : 4; unsigned hour_H : 1; unsigned day : 5; unsigned mon : 4; unsigned year : 6; }; uint32_t tm; } bluetooth_timestamp_t; typedef union { unsigned long long ll; struct { unsigned long l; unsigned long h; }; } longlong_mask_t; typedef struct { union { struct { unsigned sateCount : 5; // gps可见卫星数量 unsigned posState : 1; // gps定位状态 (0-GPS未定位,1-GPS已定位) unsigned carState : 1; // 车辆是否启动 (0-车辆未启动,1-车辆已启动) unsigned carEvent : 1; // 车辆启动或停止事件(0-启动状态未改变,1-启动状态已改变) }; uint8_t state; }; bluetooth_timestamp_t time; // 时间戳 int32_t latitude; int32_t longitude; uint16_t speed; } gps_data_t; typedef struct // size = 158 { uint32_t sample_time; // 采集时间:自启动以来经过的秒数 data_dtu_t dtuData; // size = 36 data_sample_t sampleData; // size = 118 } gprs_data_t; // 双向通讯的数据结构 typedef struct // size = 120 { uint16_t serverVer; // 服务器参数版本号 uint8_t type; // 储罐类型 uint32_t diameter; // 内径 uint32_t len; // 圆柱体长度 uint32_t lenExtra; // 直边封头长度 uint32_t reserved_1[3]; uint8_t source; // 液源 uint32_t density; // 各液源的比重(kg/m3) uint16_t fullPct; // 满液位百分比 uint16_t priPct; // 关键液位百分比 uint16_t orderPct; // 订货液位百分比 uint16_t emptyPct; // 空液位百分比 uint32_t planMount; // 每日计划用量 uint32_t predictMount; // 每日预测用量 uint16_t warnVolt; // 电压报警低点: 10mV uint16_t warnVoltH; // 电压报警高点: 10mV uint16_t warnPress; // 压力报警低点: KPa uint16_t warnPressH; // 压力报警高点: KPa uint32_t intervalTrans; // 数据上报周期 uint32_t intervalSample; // 数据采集周期 uint32_t intervalGPSTrans; // 位置上报周期 uint32_t intervalGPS; // 位置采集周期 union { struct { char gpsServer[20]; // 远传服务器 (只上传,不修改) int16_t gpsPort; // 远传端口 (只上传,不修改) char pwd1[6]; // 储罐参数修改密码 }; struct { char gprsServer[26]; // praxair:修改数据服务器地址 int16_t gprsPort; // praxair: 修改数据服务器端口 }; }; uint32_t options; // 参数开关 union { uint8_t reserved_2[12]; struct { uint16_t floorLevel; // praxair: 液量报警下限 uint16_t span; // praxair: 液量变化报警门限 uint16_t spanPeriod; // praxair: 液量变化报警时间 unsigned floorLevelAssigned : 1; // praxair: 参数中floorLevel是否有效 unsigned spanAssigned : 1; // praxair: 参数中span是否有效 unsigned spanPeriodAssigned : 1; // praxair: 参数中spanPeriod是否有效 unsigned intervalTransAssigned : 1; // praxair: 参数中intervalTrans是否有效 unsigned gprsServerAssigned : 1; // praxair: 参数中数据服务器地址是否有效 unsigned gprsPortAssigned : 1; // praxair: 参数中数据服务器端口是否有效 unsigned : 2; }; }; uint32_t ts; // 参数时间戳 } param_data_t; // 升级进度信息(存放在FRAM中,可断点续传) typedef struct { uint16_t check; // 标志,固定为0x55AA uint32_t ver; // 固件版本 int32_t fileSize; // 固件总字节数 uint16_t fileCrc; // 固件总的crc int32_t offset; // 本次固件偏移量 int32_t len; // 本次数据长度 uint16_t crc; // 本记录的crc } upgrade_info_t; // 升级包接收记录 typedef struct { uint32_t ver; // 固件版本 int32_t fileSize; // 固件总字节数 uint16_t fileCrc; // 固件总的crc int32_t offset; // 本次固件偏移量 int32_t len; // 本次数据长度 uint8_t data[UPGRADE_DATA_LEN]; // 本次数据 uint16_t crc; // 本次数据的crc } upgrade_frame_t; // 升级文件头 typedef struct // size=12 { unsigned short check; // 数据有效标志, 0x55AA表示有效 unsigned upgrade_request : 1; // 升级请求标志,0-无升级,1-有升级 unsigned upgrade_result : 3; // 升级失败标志,0-成功,1-失败,其余保留 unsigned encrypt_flag : 2; // 加密标志, 0-无加密,其余保留 unsigned compress_flag : 2; // 压缩标志, 0-无压缩,1-有压缩,其余保留 unsigned rerseved1 : 8; // 保留,必须为0xFF unsigned long upgrade_length; // 升级文件长度 unsigned rerseved2 : 8; // 保留,必须为0xFF unsigned rerseved3 : 8; // 保留,必须为0xFF unsigned short crc; // 对前面内容的crc校验 } TUpgradeHeader; // 阿里云密钥记录 typedef struct // size=76 { unsigned short check; // 数据有效标志, 0x55AA表示有效 uint8_t PSN[6]; // 获取密钥所用的PSN(如果PSN改变需重新获取) char product[12]; // 产品代码 char device[21]; // 默认为cPSN char secret[33]; // 设备密钥 unsigned short crc; // 对前面内容的crc校验 } TAliyunSecret; #define ALIYUN_SECRET_SIZE (66) #pragma pack(pop) // 阿里云密钥 TAliyunSecret aliyunSecret = {0}; // 升级包记录 upgrade_info_t upInfo = {0}; // GPS循环缓冲记录 loopbuff_t gpsBuff = {0}; // 存放GPRS记录的循环缓冲 loopbuff_t gprsBuff = {0}; loopbuff_t bd_gprsBuff = {0}; // GPRS记录读写缓冲 gprs_data_t gprsRWBuf; void pack_param_DO23_data(param_data_t *param) { memset(param, 0, sizeof(param_data_t)); param->serverVer = htons(dcBuff.configBottle.serverVer); param->type = dcBuff.configBottle.type; param->diameter = htonl(dcBuff.configBottle.diameter); param->len = htonl(dcBuff.configBottle.len); param->lenExtra = htonl(dcBuff.configBottle.lenExtra); param->source = dcBuff.configBottle.source; param->density = htonl(Config_GetDensity(dcBuff.configBottle.source) * 1000); param->fullPct = htons(dcBuff.configBottle.fullPct); param->priPct = htons(dcBuff.configBottle.priPct); param->orderPct = htons(dcBuff.configBottle.orderPct); param->emptyPct = htons(dcBuff.configBottle.emptyPct); param->planMount = htonl(dcBuff.configBottle.planMount); param->predictMount = htonl(dcBuff.configBottle.predictMount); param->warnVolt = htons(dcBuff.configBottle.warnVolt); param->warnVoltH = htons(dcBuff.configBottle.warnVoltH); param->warnPress = htons(dcBuff.configBottle.warnPress); param->warnPressH = htons(dcBuff.configBottle.warnPressH); param->intervalTrans = htonl(dcBuff.configData.intervalTrans); param->intervalSample = htonl(dcBuff.configData.intervalSample); param->intervalGPSTrans = htonl(dcBuff.configData.intervalGPSTrans); param->intervalGPS = htonl(dcBuff.configData.intervalGPS); if(dcBuff.configBottle.serverVer != 3) { strcpy(param->gpsServer, dcBuff.configData.gpsServer); param->gpsPort = htons(dcBuff.configData.gpsPort); strcpy(param->pwd1, dcBuff.configDisplay.pwd1); } if(dcBuff.configBottle.dispMode == DISP_MODE_ALL) param->options |= 0x0003ul; else if(dcBuff.configBottle.dispMode == DISP_MODE_L) param->options |= 0x0001ul; else if(dcBuff.configBottle.dispMode == DISP_MODE_KG) param->options |= 0x0002ul; param->options = htonl(param->options); param->ts = htonl(dcBuff.configBottle.ts); // praxair memset(param->reserved_2, 0, sizeof(param->reserved_2)); if(dcBuff.configBottle.serverVer == 3) { param->floorLevel = htons(dcBuff.configBottle.floorLevel); param->floorLevelAssigned = 1; param->span = htons(dcBuff.configBottle.span); param->spanAssigned = 1; param->spanPeriod = htons(dcBuff.configBottle.spanPeriod); param->spanPeriodAssigned = 1; param->intervalTransAssigned = 1; strcpy(param->gprsServer, dcBuff.configData.server); param->gprsServerAssigned = 1; param->gprsPort = htons(dcBuff.configData.port); param->gprsPortAssigned = 1; } } void parse_param_D021_data(param_data_t *param) { int serverVer = ntohs(param->serverVer); dcBuff.configBottle.serverVer = serverVer; if(serverVer == 3) // praxair { if(param->floorLevelAssigned) dcBuff.configBottle.floorLevel = ntohs(param->floorLevel); if(param->spanAssigned) dcBuff.configBottle.span = ntohs(param->span); if(param->spanPeriodAssigned) dcBuff.configBottle.spanPeriod = ntohs(param->spanPeriod); if(param->intervalTransAssigned) dcBuff.configData.intervalTrans = ntohl(param->intervalTrans); if(param->gprsServerAssigned) { strcpy(dcBuff.configData.server, param->gprsServer); strcpy(dcBuff.configData.upgServer, param->gprsServer); strcpy(dcBuff.configData.gpsServer, param->gprsServer); } if(param->gprsPortAssigned) { dcBuff.configData.port = ntohs(param->gprsPort); dcBuff.configData.upgPort = dcBuff.configData.port + 1; dcBuff.configData.gpsPort = dcBuff.configData.port + 2; } } else { dcBuff.configBottle.type = param->type; dcBuff.configBottle.diameter = ntohl(param->diameter); dcBuff.configBottle.len = ntohl(param->len); dcBuff.configBottle.lenExtra = ntohl(param->lenExtra); dcBuff.configBottle.source = param->source; Config_SetDensity(dcBuff.configBottle.source, ntohl(param->density) / 1000.0); dcBuff.configBottle.fullPct = ntohs(param->fullPct); dcBuff.configBottle.priPct = ntohs(param->priPct); dcBuff.configBottle.orderPct = ntohs(param->orderPct); dcBuff.configBottle.emptyPct = ntohs(param->emptyPct); dcBuff.configBottle.planMount = ntohl(param->planMount); dcBuff.configBottle.predictMount = ntohl(param->predictMount); dcBuff.configBottle.warnVolt = ntohs(param->warnVolt); dcBuff.configBottle.warnVoltH = ntohs(param->warnVoltH); dcBuff.configBottle.warnPress = ntohs(param->warnPress); dcBuff.configBottle.warnPressH = ntohs(param->warnPressH); dcBuff.configData.intervalTrans = ntohl(param->intervalTrans); dcBuff.configData.intervalSample = ntohl(param->intervalSample); // 以下参数只做上传,不做修改 // dcBuff.configData.intervalGPSTrans = ntohl(param->intervalGPSTrans); // dcBuff.configData.intervalGPS = ntohl(param->intervalGPS); // strcpy(dcBuff.configData.gpsServer, param->gpsServer); // dcBuff.configData.gpsPort = ntohs(param->gpsPort); // strcpy(dcBuff.configDisplay.pwd1, param->pwd1); dcBuff.configBottle.options = ntohl(param->options); if((dcBuff.configBottle.options & 0x0003ul) == 0x0003ul) dcBuff.configBottle.dispMode = DISP_MODE_ALL; else if((dcBuff.configBottle.options & 0x0001ul) == 0x0001ul) dcBuff.configBottle.dispMode = DISP_MODE_L; else if((dcBuff.configBottle.options & 0x0002ul) == 0x0002ul) dcBuff.configBottle.dispMode = DISP_MODE_KG; else dcBuff.configBottle.dispMode = DISP_MODE_DPRESS; dcBuff.configBottle.ts = ntohl(param->ts); } } // 是否GPS定位 volatile uint8_t GPS_Locate = 1; volatile uint8_t GPS_Located = 0; volatile uint32_t GPS_waitTick = 0; volatile uint8_t GPS_Waiting = 0; // GPS定位超时 const uint8_t DTU_tmrLocate = 90; // GPS发送数据 volatile uint32_t GPS_tranTick = 0; // 保存上次数据的时间 bluetooth_timestamp_t GPS_LastTime = {0}; // 是否发送GPRS数据 uint8_t GPRS_Send_Task = 0; uint32_t GPRS_Send_Time = 0; // 是否保存GPRS数据 uint8_t GPRS_Save_Task = 0; uint32_t GPRS_Save_Time = 0; // 计算两个经纬度之间的距离 const double EARTH_RADIUS = 6378.137; double rad(double d) { return d * PI / 180.0; } double GetDistance(int32_t lat1, int32_t lng1, int32_t lat2, int32_t lng2) { double radLat1 = rad(lat1 * 0.000001); double radLat2 = rad(lat2 * 0.000001); double a = radLat1 - radLat2; double b = rad(lng1 * 0.000001) - rad(lng2 * 0.000001); double s = 2 * asin(sqrt(pow(sin(a / 2), 2) + cos(radLat1) * cos(radLat2) * pow(sin(b / 2), 2))); s = s * EARTH_RADIUS; return s; } // 比较新数据的时间,是否晚于老数据的时间 int32_t GPS_IsLateThan(bluetooth_timestamp_t *pNewTime, bluetooth_timestamp_t *pOldTime) { uint8_t newHour = (pNewTime->hour_H << 4) | pNewTime->hour_L; uint8_t oldHour = (pOldTime->hour_H << 4) | pOldTime->hour_L; if(pNewTime->year > pOldTime->year) return TRUE; if(pNewTime->year < pOldTime->year) return FALSE; if(pNewTime->mon > pOldTime->mon) return TRUE; if(pNewTime->mon < pOldTime->mon) return FALSE; if(pNewTime->day > pOldTime->day) return TRUE; if(pNewTime->day < pOldTime->day) return FALSE; if(newHour > oldHour) return TRUE; if(newHour < oldHour) return FALSE; if(pNewTime->min > pOldTime->min) return TRUE; if(pNewTime->min < pOldTime->min) return FALSE; return pNewTime->sec > pOldTime->sec; } // 计算两个时间间隔的秒数 uint32_t GPS_CalcInterval(bluetooth_timestamp_t *pNewTime, bluetooth_timestamp_t *pOldTime) { // 计算从OldYear以来的秒数 uint32_t newSeconds = Calc_SecondsFromYear(GPS_BASE_YEAR + pOldTime->year, pNewTime->year + GPS_BASE_YEAR, pNewTime->mon, pNewTime->day, (pNewTime->hour_H << 4) | pNewTime->hour_L, pNewTime->min, pNewTime->sec); uint32_t oldSeconds = Calc_SecondsFromYear(GPS_BASE_YEAR + pOldTime->year, pOldTime->year + GPS_BASE_YEAR, pOldTime->mon, pOldTime->day, (pOldTime->hour_H << 4) | pOldTime->hour_L, pOldTime->min, pOldTime->sec); return newSeconds - oldSeconds; } // 将一个数据加入队列 void GPS_PutToQueue(gps_data_t *gps) { uint16_t nextPtr; // 如果要添加数据的时间大于上一条数据的时间 if(GPS_LastTime.year == 0 || GPS_IsLateThan(&gps->time, &GPS_LastTime)) { // 移动写指针 nextPtr = LoopBuff_GetNextPtr(&gpsBuff, gpsBuff.info.wtPtr); // 如果队列已满 if(nextPtr == gpsBuff.info.rdPtr) { // 移动读指针(丢弃第一条数据) gpsBuff.info.rdPtr = LoopBuff_GetNextPtr(&gpsBuff, gpsBuff.info.rdPtr); } // 将新数据加到最后 FRAM_BufferWrite(LoopBuff_GetDataPos(&gpsBuff, gpsBuff.info.wtPtr), (uint8_t *) gps, sizeof(gps_data_t)); gpsBuff.info.wtPtr = nextPtr; // 保存到铁电 FRAM_SaveInfo(gpsBuff.info_base, (uint8_t *) &gpsBuff.info, sizeof(gpsBuff.info)); GPS_LastTime = gps->time; } } // 将一个数据加入队列 void GPRS_PutToQueue(loopbuff_t *lpBuff, data_dtu_t *dtuData, data_sample_t *sampleData) { uint16_t nextPtr; S_RTC_TIME_DATA_T sRTC; gprs_data_t *gprs; // 移动写指针 nextPtr = LoopBuff_GetNextPtr(lpBuff, lpBuff->info.wtPtr); // 如果队列已满 if(nextPtr == lpBuff->info.rdPtr) { // 移动读指针(丢弃第一条数据) lpBuff->info.rdPtr = LoopBuff_GetNextPtr(lpBuff, lpBuff->info.rdPtr); } // 将新数据加到最后 gprs = &gprsRWBuf; // 获取当前时间 RTC_GetDateAndTime(&sRTC); // 计算自上次gps定位以来的时间 gprs->sample_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); gprs->dtuData = *dtuData; gprs->sampleData = *sampleData; FRAM_BufferWrite(LoopBuff_GetDataPos(lpBuff, lpBuff->info.wtPtr), (uint8_t *) gprs, sizeof(gprs_data_t)); lpBuff->info.wtPtr = nextPtr; } // 将前面几条数据移出队列 void GPS_MoveFromQueue(uint8_t count) { LoopBuff_RemoveItems(&gpsBuff, count); // 保存到铁电 FRAM_SaveInfo(gpsBuff.info_base, (uint8_t *) &gpsBuff.info, sizeof(gpsBuff.info)); } // 查找队列前面的数据, 找出时间间隔相同的一组,最多max_count条 // 本函数在调用的地方加锁,因为这个函数返回以后接着要取数据 uint8_t GPS_LookData(uint8_t max_count, uint16_t *interval, uint8_t *done) { uint8_t count = 0; uint8_t i; uint16_t gps_count = 0, nextPtr; gps_data_t gps0, gps1; *interval = 0; *done = 1; if(max_count < 1) return 0; // 获取未发送记录条数 gps_count = LoopBuff_GetCount(&gpsBuff); if(gps_count < 2) return gps_count; count = 2; FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, gpsBuff.info.rdPtr), (uint8_t *) &gps0, sizeof(gps_data_t)); nextPtr = LoopBuff_GetNextPtr(&gpsBuff, gpsBuff.info.rdPtr); FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, nextPtr), (uint8_t *) &gps1, sizeof(gps_data_t)); *interval = GPS_CalcInterval(&gps1.time, &gps0.time); for(i = 2; count < max_count && i < gps_count; i++) { // 如果后面的时间间隔不一样 gps0 = gps1; nextPtr = LoopBuff_GetNextPtr(&gpsBuff, nextPtr); FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, nextPtr), (uint8_t *) &gps1, sizeof(gps_data_t)); if(GPS_CalcInterval(&gps1.time, &gps0.time) != *interval) break; count++; } if(i < gps_count) *done = 0; return count; } // 将采集数据中的传感器状态转换为蓝牙协议中的状态 static uint8_t Bluetooth_ConvertStat(sensor_status_t *pStat) { if(pStat->notConnect) return 3; if(pStat->overFlow) return 1; if(pStat->underFlow) return 2; return 0; } // GPS uart void GPS_IRQHandler(USART_Handle *huart) { uint8_t u8DTU = (uint8_t) huart->Instance->RDR; // printf("%c", u8DTU); // 直接处理 DTU_Task0(u8DTU); } // GSM uart void GPRS_IRQHandler(USART_Handle *huart) { uint8_t u8DTU = (uint8_t) huart->Instance->RDR; if(DTU_uartPrint) { // if(u8DTU == '\n') // printf("\\n\n"); // else if(u8DTU == '\r') // printf("\\r"); // else printf("%c", u8DTU); } // 加入缓冲 LoopBuff_PutItem(&DTU_TaskM, &u8DTU); } void DTU_Init() { /* 配置GSM端口 */ LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_9|LL_GPIO_PIN_10; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* 配置GPS端口: GPS和Debug共用一个串口,GPS用到输入,DEBUG用到输出 */ } void DTU_Open() { LL_USART_InitTypeDef USART_InitStruct = {0}; // 分配扩展内存 // DTU_gpsData[0] = (char *) SRAM_Alloc(DTU_GPSDATA_SIZE); // DTU_gpsData[1] = (char *) SRAM_Alloc(DTU_GPSDATA_SIZE); // DTU_recvBuff = (char *) SRAM_Alloc(DTU_RECVBUFF_SIZE); // Task_sendBuff = (uint8_t *) SRAM_Alloc(TASK_SENDBUFF_SIZE); // Task_recvBuff = (uint8_t *) SRAM_Alloc(TASK_RECVBUFF_SIZE); LoopBuff_Create(&gpsBuff, sizeof(gps_data_t), FRAM_GPS_DATA_COUNT, FRAM_GPS_INFO_BASE, FRAM_GPS_DATA_BASE); LoopBuff_Create(&gprsBuff, sizeof(gprs_data_t), FRAM_GPRS_DATA_COUNT, FRAM_GPRS_INFO_BASE, FRAM_GPRS_DATA_BASE); LoopBuff_Create(&bd_gprsBuff, sizeof(gprs_data_t), FRAM_BD_GPRS_DATA_COUNT, FRAM_GPRS_BD_INFO_BASE, FRAM_GPRS_BD_DATA_BASE); LoopBuff_Create(&DTU_TaskM, sizeof(uint8_t), DTU_TASKM_DATA_COUNT, 0, (uint32_t) DTU_TaskM_Data); huart1.RxISR = GPRS_IRQHandler; huart2.RxISR = GPS_IRQHandler; /* Peripheral clock enable */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); /* USART1 interrupt Init */ NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); NVIC_EnableIRQ(USART1_IRQn); USART_InitStruct.BaudRate = 115200; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART1, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART1); SET_BIT(USART1->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); LL_USART_Enable(USART1); /* 打开GPS端口: GPS和Debug共用一个串口,GPS用到输入,DEBUG用到输出 */ } // 任务主体:采集GPS数据 void DTU_Task0(uint8_t c) { static uint16_t RdIdx = 0; static uint8_t bufIdx = 0; static data_dtu_t sample = {0}; static int32_t last_latitude, last_longitude; static uint8_t gps_flag = 0, motion_count = 0, motionless_count = 0; static uint32_t last_time = 0; gps_data_t gpsData; uint32_t time; if(c == '$' || RdIdx >= DTU_GPSDATA_SIZE) RdIdx = 0; if(RdIdx == 0 && c != '$') return; if(c != '\r' && c != '\n') DTU_gpsData[bufIdx][RdIdx++] = c; else { // 收到完整的一行 DTU_gpsData[bufIdx][RdIdx] = 0; RdIdx = 0; // 解析一行数据 if(parse_frame(&bufIdx, DTU_gpsData[bufIdx], &sample)) { if(sample.sateCount > 0) printf("sateCount:\t%d\n", sample.sateCount); if(sample.posState) { time = Calc_SecondsFromYear(INITIAL_YEAR, sample.sysTime.year + 2000, sample.sysTime.month, sample.sysTime.day, sample.sysTime.hour, sample.sysTime.minute, sample.sysTime.second); // 修正时间基准(可显示绝对时间) //if(RTC_offsetSeconds == 0 && time >= DTU_gpsTime) if(time >= DTU_gpsTime) // 每次成功定位都修正时间 RTC_offsetSeconds = time - DTU_gpsTime; if(sample.sateCount >= 4) { if(time >= last_time + dcBuff.configData.intervalGPS) { last_time = time; // 如果没有硬件加速度计,则用软件方式判断 if(dcBuff.configDisplay.op_SEND_GPS_DATA && Accelero_ID != ACCELERO_ID) { if(sample.speed <= 3) { motion_count = 0; if(Motion_Status == 1 && ++motionless_count >= 3) { Motion_Status = 0; printf("\nSoft Motion status = 0\n"); } } else { motionless_count = 0; if(Motion_Status == 0 && ++motion_count >= 3) { Motion_Status = 1; printf("\nSoft Motion status = 1\n"); } } } printf("Latitude:\t%10.6f\n", sample.latitude * 0.000001); printf("Longitude:\t%10.6f\n", sample.longitude * 0.000001); printf("Speed:\t\t%d km/h\n", sample.speed); printf("GPS time:\t%d-%02d-%02d %02d:%02d:%02d\n", sample.sysTime.year + 2000, sample.sysTime.month, sample.sysTime.day, sample.sysTime.hour, sample.sysTime.minute, sample.sysTime.second); // 计算和上次定位之间的距离,或者判断运动状态 if(dcBuff.configDisplay.op_SEND_GPS_DATA && gps_flag == 1 && ( !Motion_Status // || (sample.speed < 5 && GetDistance(last_latitude, last_longitude, sample.latitude, sample.longitude) < 10) )) { printf("\nCalibrate to last position\n"); sample.latitude = last_latitude; sample.longitude = last_longitude; } else { gps_flag = 1; last_latitude = sample.latitude; last_longitude = sample.longitude; } // 写入全局缓冲 dcBuff.dtuData.posState = sample.posState; dcBuff.dtuData.sateCount = sample.sateCount; dcBuff.dtuData.latitude = sample.latitude; dcBuff.dtuData.longitude = sample.longitude; dcBuff.dtuData.speed = sample.speed; dcBuff.dtuData.sysTime = sample.sysTime; // 最近定位成功 dcBuff.dtuData.recentPosState = 1; if(dcBuff.configDisplay.op_SEND_GPS_DATA) { // 加入GPS数据队列,待发送 if(sample.sateCount > 31) gpsData.sateCount = 31; else gpsData.sateCount = sample.sateCount; gpsData.posState = sample.posState; gpsData.carState = VCC_POWER_STATUS() ? 1: 0; gpsData.carEvent = bat_CurrentEvent; bat_CurrentEvent = 0; gpsData.time.year = sample.sysTime.year + 2000 - GPS_BASE_YEAR; gpsData.time.mon = sample.sysTime.month; gpsData.time.day = sample.sysTime.day; gpsData.time.hour_H = sample.sysTime.hour >> 4; gpsData.time.hour_L = sample.sysTime.hour & 0x0F; gpsData.time.min = sample.sysTime.minute; gpsData.time.sec = sample.sysTime.second; gpsData.latitude = sample.latitude; gpsData.longitude = sample.longitude; gpsData.speed = sample.speed; GPS_PutToQueue(&gpsData); } else { GPS_Located = 1; // 停止超时定时器 GPS_Waiting = 0; } } } } // 清除数据 memset(&sample, 0, sizeof(sample)); } } } // 发送奥扬数据 uint16_t pack_aoyang_send_data(gprs_data_t *pGprs, uint32_t totalSeconds) { S_RTC_TIME_DATA_T sRTC; char field[20]; // 打包上报数据(按modbus从机响应的格式) memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); // PSN strcat((char *) Task_sendBuff, "{\"i\":"); sprintf(field, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); strcat((char *) Task_sendBuff, field); // 取数时间 strcat((char *) Task_sendBuff, ",\"t\":"); Wakeup_CalcUTCTime(pGprs->sample_time + RTC_offsetSeconds, &sRTC); sprintf(field, "%04d%02d%02d%02d%02d%02d", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); strcat((char *) Task_sendBuff, field); // 液位高度 strcat((char *) Task_sendBuff, ",\"h\":"); if(pGprs->sampleData.staDPress.status == SENSOR_STATUS_OVERFLOW) { // 短路 sprintf(field, "%d", -1); } else if(pGprs->sampleData.staDPress.status == SENSOR_STATUS_NOCONNECT || pGprs->sampleData.staDPress.status == SENSOR_STATUS_UNDERFLOW) { // 断路 sprintf(field, "%d", -2); } else sprintf(field, "%d", (uint16_t) pGprs->sampleData.height); strcat((char *) Task_sendBuff, field); // 液体体积 strcat((char *) Task_sendBuff, ",\"v\":"); if(pGprs->sampleData.staDPress.status == SENSOR_STATUS_NOCONNECT || pGprs->sampleData.staDPress.status == SENSOR_STATUS_OVERFLOW || pGprs->sampleData.staDPress.status == SENSOR_STATUS_UNDERFLOW) { // 故障 sprintf(field, "%d", -1); } else sprintf(field, "%d", pGprs->sampleData.volume); strcat((char *) Task_sendBuff, field); // 气瓶压力 strcat((char *) Task_sendBuff, ",\"p\":"); if(pGprs->sampleData.staPress.status == SENSOR_STATUS_OVERFLOW) { // 短路 sprintf(field, "%d", -1); } else if(pGprs->sampleData.staPress.status == SENSOR_STATUS_NOCONNECT || pGprs->sampleData.staPress.status == SENSOR_STATUS_UNDERFLOW) { // 断路 sprintf(field, "%d", -2); } else { // 压力:KPa->MPa sprintf(field, "%f", pGprs->sampleData.pressure * 0.001); } strcat((char *) Task_sendBuff, field); // 经度 strcat((char *) Task_sendBuff, ",\"x\":"); if(!pGprs->dtuData.recentPosState || pGprs->dtuData.longitude == 0) sprintf(field, "%d", 200); else sprintf(field, "%.6f", pGprs->dtuData.longitude * 0.000001); strcat((char *) Task_sendBuff, field); // 纬度 strcat((char *) Task_sendBuff, ",\"y\":"); if(!pGprs->dtuData.recentPosState || pGprs->dtuData.latitude == 0) sprintf(field, "%d", 200); else sprintf(field, "%.6f", pGprs->dtuData.latitude * 0.000001); strcat((char *) Task_sendBuff, field); //结束符,多发送一个换行符('\n') strcat((char *) Task_sendBuff, "}\n"); return strlen((char *) Task_sendBuff); } // 发送巴西数据 uint16_t pack_brasil_send_data(gprs_data_t *pGprs, uint32_t totalSeconds) { S_RTC_TIME_DATA_T sRTC; char field[40]; // 打包上报数据(按modbus从机响应的格式) memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); // PSN strcat((char *) Task_sendBuff, "{\"psn\":"); sprintf(field, "\"20%02d%02d%02d%02d%03d\"", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); strcat((char *) Task_sendBuff, field); // 取数时间 strcat((char *) Task_sendBuff, ",\"time\":"); Wakeup_CalcUTCTime(pGprs->sample_time + RTC_offsetSeconds, &sRTC); sprintf(field, "\"%04d%02d%02d%02d%02d%02d\"", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); strcat((char *) Task_sendBuff, field); // 差压 strcat((char *) Task_sendBuff, ",\"dp\":"); if(pGprs->sampleData.staDPress.status == SENSOR_STATUS_NOCONNECT || pGprs->sampleData.staDPress.status == SENSOR_STATUS_OVERFLOW || pGprs->sampleData.staDPress.status == SENSOR_STATUS_UNDERFLOW) { // 故障 sprintf(field, "%d", -300); } else { // mmWC sprintf(field, "%.0f", KPa2mmH2O(pGprs->sampleData.diff)); } strcat((char *) Task_sendBuff, field); // 容积百分比 strcat((char *) Task_sendBuff, ",\"pct\":"); if(pGprs->sampleData.staDPress.status == SENSOR_STATUS_NOCONNECT || pGprs->sampleData.staDPress.status == SENSOR_STATUS_OVERFLOW || pGprs->sampleData.staDPress.status == SENSOR_STATUS_UNDERFLOW) { // 故障 sprintf(field, "%d", 0); } else { // % sprintf(field, "%.1f", pGprs->sampleData.volumePct * 0.01); } strcat((char *) Task_sendBuff, field); // 液体体积 strcat((char *) Task_sendBuff, ",\"v\":"); if(pGprs->sampleData.staDPress.status == SENSOR_STATUS_NOCONNECT || pGprs->sampleData.staDPress.status == SENSOR_STATUS_OVERFLOW || pGprs->sampleData.staDPress.status == SENSOR_STATUS_UNDERFLOW) { // 故障 sprintf(field, "%d", 0); } else { // L sprintf(field, "%d", pGprs->sampleData.volume); } strcat((char *) Task_sendBuff, field); // 压力 strcat((char *) Task_sendBuff, ",\"p\":"); if(pGprs->sampleData.staPress.status == SENSOR_STATUS_NOCONNECT || pGprs->sampleData.staPress.status == SENSOR_STATUS_OVERFLOW || pGprs->sampleData.staPress.status == SENSOR_STATUS_UNDERFLOW) { // 故障 sprintf(field, "%d", -300); } else { // 压力:KPa->MPa sprintf(field, "%.2f", pGprs->sampleData.pressure * 0.001); } strcat((char *) Task_sendBuff, field); // 温度 strcat((char *) Task_sendBuff, ",\"t\":"); if(pGprs->sampleData.staExtTempr[0].status == SENSOR_STATUS_NOCONNECT || pGprs->sampleData.staExtTempr[0].status == SENSOR_STATUS_OVERFLOW || pGprs->sampleData.staExtTempr[0].status == SENSOR_STATUS_UNDERFLOW) { // 故障 sprintf(field, "%d", -300); } else { // 温度:℃ sprintf(field, "%d", pGprs->sampleData.extTempr[0]); } strcat((char *) Task_sendBuff, field); // 经度 strcat((char *) Task_sendBuff, ",\"x\":"); if(!pGprs->dtuData.recentPosState || pGprs->dtuData.longitude == 0) sprintf(field, "%d", -300); else sprintf(field, "%.6f", pGprs->dtuData.longitude * 0.000001); strcat((char *) Task_sendBuff, field); // 纬度 strcat((char *) Task_sendBuff, ",\"y\":"); if(!pGprs->dtuData.recentPosState || pGprs->dtuData.latitude == 0) sprintf(field, "%d", -300); else sprintf(field, "%.6f", pGprs->dtuData.latitude * 0.000001); strcat((char *) Task_sendBuff, field); // APN strcat((char *) Task_sendBuff, ",\"apn\":"); sprintf(field, "\"%s\"", dcBuff.configDisplay.APN); strcat((char *) Task_sendBuff, field); // APN-User strcat((char *) Task_sendBuff, ",\"user\":"); sprintf(field, "\"%s\"", dcBuff.configDisplay.User); strcat((char *) Task_sendBuff, field); // APN-Pwd strcat((char *) Task_sendBuff, ",\"pwd\":"); sprintf(field, "\"%s\"", dcBuff.configDisplay.Pwd); strcat((char *) Task_sendBuff, field); // sim card strcat((char *) Task_sendBuff, ",\"sim\":"); sprintf(field, "\"%s\"", dcBuff.powerInfo.simNumber); strcat((char *) Task_sendBuff, field); // type strcat((char *) Task_sendBuff, ",\"type\":"); sprintf(field, "%d", dcBuff.configBottle.type); strcat((char *) Task_sendBuff, field); // diameter strcat((char *) Task_sendBuff, ",\"dia\":"); sprintf(field, "%d", dcBuff.configBottle.diameter); strcat((char *) Task_sendBuff, field); // len strcat((char *) Task_sendBuff, ",\"len\":"); sprintf(field, "%d", dcBuff.configBottle.len + dcBuff.configBottle.lenExtra); strcat((char *) Task_sendBuff, field); // liquid strcat((char *) Task_sendBuff, ",\"liquid\":"); sprintf(field, "%d", dcBuff.configBottle.source); strcat((char *) Task_sendBuff, field); // density strcat((char *) Task_sendBuff, ",\"density\":"); sprintf(field, "%d", (uint16_t) (Config_GetDensity(dcBuff.configBottle.source) * 1000)); strcat((char *) Task_sendBuff, field); // send strcat((char *) Task_sendBuff, ",\"send\":"); sprintf(field, "%d", dcBuff.configData.intervalTrans); strcat((char *) Task_sendBuff, field); // save strcat((char *) Task_sendBuff, ",\"save\":"); sprintf(field, "%d", dcBuff.configData.intervalSample); strcat((char *) Task_sendBuff, field); // level1 strcat((char *) Task_sendBuff, ",\"level1\":"); sprintf(field, "%.2f", dcBuff.configBottle.priPct * 0.01); strcat((char *) Task_sendBuff, field); // level2 strcat((char *) Task_sendBuff, ",\"level2\":"); sprintf(field, "%.2f", dcBuff.configBottle.orderPct * 0.01); strcat((char *) Task_sendBuff, field); // level3 strcat((char *) Task_sendBuff, ",\"level3\":"); sprintf(field, "%.2f", dcBuff.configBottle.emptyPct * 0.01); strcat((char *) Task_sendBuff, field); // server strcat((char *) Task_sendBuff, ",\"server\":"); sprintf(field, "\"%s\"", dcBuff.configData.server); strcat((char *) Task_sendBuff, field); // port strcat((char *) Task_sendBuff, ",\"port\":"); sprintf(field, "%d", dcBuff.configData.port); strcat((char *) Task_sendBuff, field); //结束符,多发送一个换行符('\n') strcat((char *) Task_sendBuff, "}\n"); return strlen((char *) Task_sendBuff); } // 解析巴西数据 int parse_brasil_recv_data(char *recv, gprs_data_t *pGprs, uint32_t totalSeconds) { char *src = recv; char psn[14], time[15]; S_RTC_TIME_DATA_T sRTC; uint8_t i; uint8_t psnMatch = 0, timeMatch = 0; if(!JSON_Parse_Record(&src)) return 0; for(i = 0; i < JSON_FIELD_COUNT; i++) { if(JSON_Record[i].type == JSON_TYPE_NULL) continue; if(JSON_Record[i].type == JSON_TYPE_INTEGER) printf("%s\t%s\t%ld\n", JSON_Record[i].name, "INTEGER", JSON_Record[i].i); else if(JSON_Record[i].type == JSON_TYPE_FLOAT) printf("%s\t%s\t%f\n", JSON_Record[i].name, "FLOAT", JSON_Record[i].f); else printf("%s\t%s\t%s\n", JSON_Record[i].name, "STRING", JSON_Record[i].s); } // PSN sprintf(psn, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); // 取数时间 Wakeup_CalcUTCTime(pGprs->sample_time + RTC_offsetSeconds, &sRTC); sprintf(time, "%04d%02d%02d%02d%02d%02d", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); // 检查PSN和数据时间 for(int i = 0; i < JSON_FIELD_COUNT; i++) { if(JSON_Record[i].type == JSON_TYPE_NULL) continue; if(strcmp(JSON_Record[i].name, "psn") == 0 && strcmp(psn, JSON_Record[i].s) == 0) { psnMatch = 1; } if(strcmp(JSON_Record[i].name, "time") == 0 && strcmp(time, JSON_Record[i].s) == 0) { timeMatch = 1; } } if(psnMatch && timeMatch) return 1; printf("psn or time NOT matched\n"); return 0; } int save_brasil_issue_parameters() { uint8_t i; int ret = 0; uint16_t f2i; for(i = 0; i < JSON_FIELD_COUNT; i++) { if(JSON_Record[i].type == JSON_TYPE_NULL) continue; if(strcmp(JSON_Record[i].name, "apn") == 0) { if(strlen(JSON_Record[i].s) >= 1 && strlen(JSON_Record[i].s) <= 23 && strcmp(dcBuff.configDisplay.APN, JSON_Record[i].s) != 0) { printf("change apn to: %s\n", JSON_Record[i].s); strcpy(dcBuff.configDisplay.APN, JSON_Record[i].s); ret++; } } else if(strcmp(JSON_Record[i].name, "user") == 0) { if(strlen(JSON_Record[i].s) <= 9 && strcmp(dcBuff.configDisplay.User, JSON_Record[i].s) != 0) { printf("change user to: %s\n", JSON_Record[i].s); strcpy(dcBuff.configDisplay.User, JSON_Record[i].s); ret++; } } else if(strcmp(JSON_Record[i].name, "pwd") == 0) { if(strlen(JSON_Record[i].s) <= 9 && strcmp(dcBuff.configDisplay.Pwd, JSON_Record[i].s) != 0) { printf("change pwd to: %s\n", JSON_Record[i].s); strcpy(dcBuff.configDisplay.Pwd, JSON_Record[i].s); ret++; } } else if(strcmp(JSON_Record[i].name, "type") == 0) { if(JSON_Record[i].i >= 0 && JSON_Record[i].i <= 1 && dcBuff.configBottle.type != JSON_Record[i].i) { printf("change type to: %ld\n", JSON_Record[i].i); dcBuff.configBottle.type = JSON_Record[i].i; ret++; } } else if(strcmp(JSON_Record[i].name, "dia") == 0) { if(JSON_Record[i].i >= 1 && JSON_Record[i].i <= 99999 && dcBuff.configBottle.diameter != JSON_Record[i].i) { printf("change dia to: %ld\n", JSON_Record[i].i); dcBuff.configBottle.diameter = JSON_Record[i].i; ret++; } } else if(strcmp(JSON_Record[i].name, "len") == 0) { if(JSON_Record[i].i >= 1 && JSON_Record[i].i <= 99999 && dcBuff.configBottle.len != JSON_Record[i].i) { printf("change len to: %ld\n", JSON_Record[i].i); dcBuff.configBottle.len = JSON_Record[i].i; dcBuff.configBottle.lenExtra = 0; ret++; } } else if(strcmp(JSON_Record[i].name, "liquid") == 0) { if(JSON_Record[i].i >= 0 && JSON_Record[i].i <= 4 && dcBuff.configBottle.source != JSON_Record[i].i) { printf("change liquid to: %ld\n", JSON_Record[i].i); dcBuff.configBottle.source = JSON_Record[i].i; ret++; } } else if(strcmp(JSON_Record[i].name, "send") == 0) { if(JSON_Record[i].i >= 300 && JSON_Record[i].i <= 86400 && dcBuff.configData.intervalTrans != JSON_Record[i].i) { printf("change send to: %ld\n", JSON_Record[i].i); dcBuff.configData.intervalTrans = JSON_Record[i].i; ret++; } } else if(strcmp(JSON_Record[i].name, "save") == 0) { if(JSON_Record[i].i >= 300 && JSON_Record[i].i <= 86400 && dcBuff.configData.intervalSample != JSON_Record[i].i) { printf("change save to: %ld\n", JSON_Record[i].i); dcBuff.configData.intervalSample = JSON_Record[i].i; ret++; } } else if(strcmp(JSON_Record[i].name, "level1") == 0) { f2i = (uint16_t) (JSON_Record[i].f * 100); if(f2i >= 0 && f2i <= 100 * 100 && dcBuff.configBottle.priPct != f2i) { printf("change level1 to: %f\n", JSON_Record[i].f); dcBuff.configBottle.priPct = f2i; ret++; } } else if(strcmp(JSON_Record[i].name, "level2") == 0) { f2i = (uint16_t) (JSON_Record[i].f * 100); if(f2i >= 0 && f2i <= 100 * 100 && dcBuff.configBottle.orderPct != f2i) { printf("change level2 to: %f\n", JSON_Record[i].f); dcBuff.configBottle.orderPct = f2i; ret++; } } else if(strcmp(JSON_Record[i].name, "level3") == 0) { f2i = (uint16_t) (JSON_Record[i].f * 100); if(f2i >= 0 && f2i <= 100 * 100 && dcBuff.configBottle.emptyPct != f2i) { printf("change level3 to: %f\n", JSON_Record[i].f); dcBuff.configBottle.emptyPct = f2i; ret++; } } else if(strcmp(JSON_Record[i].name, "server") == 0) { if(strlen(JSON_Record[i].s) >= 1 && strlen(JSON_Record[i].s) <= 29 && strcmp(dcBuff.configData.server, JSON_Record[i].s) != 0) { printf("change server to: %s\n", JSON_Record[i].s); strcpy(dcBuff.configData.server, JSON_Record[i].s); ret++; } } else if(strcmp(JSON_Record[i].name, "port") == 0) { if(JSON_Record[i].i >= 0 && JSON_Record[i].i <= 65535 && dcBuff.configData.port != JSON_Record[i].i) { printf("change port to: %ld\n", JSON_Record[i].i); dcBuff.configData.port = JSON_Record[i].i; ret++; } } } // 最后再修改密度(因为要先确定介质) for(i = 0; i < JSON_FIELD_COUNT; i++) { if(JSON_Record[i].type == JSON_TYPE_NULL) continue; if(strcmp(JSON_Record[i].name, "density") == 0) { f2i = (uint16_t) (Config_GetDensity(dcBuff.configBottle.source) * 1000); if(JSON_Record[i].i >= 1 && JSON_Record[i].i <= 9999 && f2i != JSON_Record[i].i) { printf("change density to: %ld\n", JSON_Record[i].i); Config_SetDensity(dcBuff.configBottle.source, JSON_Record[i].i * 0.001); ret++; } } } if(ret > 0) { printf("changed %d parameters\n", ret); return 1; } return 0; } uint8_t pack_gprs_send_data(gprs_data_t *pGprs, uint32_t totalSeconds) { uint8_t i; bluetooth_sensor_t *pSensor; bluetooth_mask_t *pMask; uint32_t relativeTime; S_RTC_TIME_DATA_T sRTC; uint16_t crc; // 打包上报数据(按modbus从机响应的格式) memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = 0; // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); printf("\nSend PSN: 20%02d%02d%02d%02d%03d\n", Task_sendBuff[i], Task_sendBuff[i + 1], Task_sendBuff[i + 2], Task_sendBuff[i+3], (Task_sendBuff[i + 4] << 8) | Task_sendBuff[i + 5]); i += 6; // 功能码 Task_sendBuff[i++] = 0x10; // 数据长度:先预设为0,最后再修改,位置为Task_sendBuff[7] Task_sendBuff[i++] = 0; // 当前差压值 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.diff)); i +=2 ; // 容积百分比 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.volumePct)); i += 2; // 当前容积 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.volume)); i += 4; // 重量 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.weight)); i += 4; // 高度:mmWC if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR && !dcBuff.configDisplay.op_USE_HEIGHT_LEVEL && !dcBuff.configDisplay.op_USE_PCT_LEVEL) Int2ByteS(Task_sendBuff, i, htons((uint16_t) KPa2mmH2O(pGprs->sampleData.diff))); else Int2ByteS(Task_sendBuff, i, htons((uint16_t) pGprs->sampleData.height)); i += 2; // 压力 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.pressure)); i += 2; #if 0 // 温度 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batTempr); #else // 用温度表示自启动以来的时间分钟数,32767分钟 Int2ByteS(Task_sendBuff, i, htons((totalSeconds % 1966080ul) / 60)); #endif i += 2; // 液源 if(dcBuff.configBottle.source >= SOURCE_LNG && dcBuff.configBottle.source <= SOURCE_POPO) Task_sendBuff[i] = dcBuff.configBottle.source; i++; // 储罐类型 if(dcBuff.configBottle.type == BOTTLE_TYPE_STAND) Task_sendBuff[i] = 0; else if(dcBuff.configBottle.type == BOTTLE_TYPE_LYING) Task_sendBuff[i] = 1; else if(dcBuff.configBottle.type == BOTTLE_TYPE_SPHERICAL) Task_sendBuff[i] = 2; i++; // 故障码 pSensor = (bluetooth_sensor_t *) (Task_sendBuff + i); pSensor->staDiff = Bluetooth_ConvertStat(&pGprs->sampleData.staDPress); pSensor->staPress = Bluetooth_ConvertStat(&pGprs->sampleData.staPress); pSensor->staEPress1 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtPress[0]); pSensor->staEPress2 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtPress[1]); pSensor->staEPress3 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtPress[2]); pSensor->staETempr1 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[0]); pSensor->staETempr2 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[1]); pSensor->staETempr3 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[2]); i += 2; // 传感器状态 pMask = (bluetooth_mask_t *) (Task_sendBuff + i); memset(pMask, 0xFF, 2); pMask->maskFlow = 1; pMask->maskLowPower = pGprs->dtuData.batLow; pMask->maskAbnormal = 0; pMask->maskCharging = pGprs->sampleData.charging; i += 2; // 版本号 Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.minor; // rssi Task_sendBuff[i++] = pGprs->dtuData.rssi; if(pMask->maskGPS) { // 经度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.longitude)); i += 4; // 纬度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.latitude)); i += 4; } // 扩展温度 if(pMask->maskETempr1) { Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[0])); i += 2; } if(pMask->maskETempr2) { Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[1])); i += 2; } if(pMask->maskETempr3) { #if 0 // 扩展温度3 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[2])); #else // 用扩展温度3表示硬件配置 Int2ByteS(Task_sendBuff, i, htons(dcBuff.powerInfo.hardVer.major)); #endif i += 2; } // 电池信息 if(pMask->maskBattery) { // 电量百分比 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batPct)); i += 2; // 电池内部温度 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batTempr)); i += 2; // 电池当前电压 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batVoltage / 10)); i += 2; // 电池容量 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batMaxCapa)); i += 2; // 电池当前容量 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batCapa)); i += 2; #if 0 // 充电电流,电流的符号表示充放电状态 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batCurrent)); #else // 用电流的绝对值表示复位原因 // 1-POR, 2-PIN, 4-WDT, 8-LVR, 16-BOD, 32-SYS, 128-CPU, 256-CPULK Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batCurrent > 0 ? SYS_RSTSTS : -SYS_RSTSTS)); #endif i += 2; // 光照强度 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.sunLevel)); i += 2; } // 流量计 if(pMask->maskFlow) { // 天信MODBUS /A1 通信协议 (BCD码) // 标况体积总量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.nM3, 6); i += 6; // 标况流量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.nM3_h, 4); i += 4; // 工况流量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.M3_h, 4); i += 4; // 温度 memmove(Task_sendBuff + i, pGprs->sampleData.flow.tempr, 4); i += 4; // 压力 memmove(Task_sendBuff + i, pGprs->sampleData.flow.pressure, 4); i += 4; } // 泄露报警 if(pMask->maskLeak) { // 类型 Task_sendBuff[i++] = pGprs->sampleData.leak.typeLeak; // 状态、报警浓度 if(pGprs->sampleData.leak.staLeak == LEAK_STATUS_FAULT || pGprs->sampleData.leak.staLeak == LEAK_STATUS_COMM_FAULT) Task_sendBuff[i] = 0x80; else Task_sendBuff[i] = (pGprs->sampleData.leak.concentrations & 0x7F); i++; } if(pMask->maskStamp) { if(dcBuff.powerInfo.protocolVer.minor == 107) { // 获取当前时间 RTC_GetDateAndTime(&sRTC); // 计算自上次gps定位以来的时间 relativeTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time; Int2ByteL(Task_sendBuff, i, htonl(relativeTime)); } // 时间 i += 4; // 年月日 i += 4; } // 扩展压力 if(pMask->maskEPress1) { Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extPressure[0])); i += 2; } if(pMask->maskEPress2) { Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extPressure[1])); i += 2; } if(pMask->maskEPress3) { #if 0 // 扩展压力3 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extPressure[2])); #else // 上传GPS调试信息: 闪断次数*100+卫星数 // 如2105表示闪断21次,卫星数5颗 Int2ByteS(Task_sendBuff, i, htons(GPS_BOD_COUNT * 100 + pGprs->dtuData.sateCount)); printf("\nGPS_DEBUG_VAL: %d\n", ntohs(Byte2IntS(Task_sendBuff, i))); #endif i += 2; } printf("\ndcBuff.powerInfo.hardVer.major = %d, dcBuff.powerInfo.softVer.minor = %d\n", dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.softVer.minor); // 硬件版本 //Task_sendBuff[i++] = ((dcBuff.powerInfo.hardVer.minor / 10) << 4) + dcBuff.powerInfo.hardVer.minor % 10; Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor; // 软件版本 //Task_sendBuff[i++] = ((dcBuff.powerInfo.softVer.minor / 10) << 4) + dcBuff.powerInfo.softVer.minor % 10;; Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor; // 真空传感器1 if(pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_FAULT || pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_COMM_FAULT) Int2ByteS(Task_sendBuff, i, htons(0)); else Int2ByteS(Task_sendBuff, i, htons(1)); i += 2; // 使用年限 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.vacuum[0].lifeVacuum)); i += 2; // 真空度 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.vacuum[0].vacuum * 100)); i += 4; // 漏放气速率 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.vacuum[0].rateVacuum * 100)); i += 4; // 船级社维持时间 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.ccsRemainDay)); i += 2; // 算法版本 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.ccsVer)); i += 4; // 保留 i += 2; // 保留 i += 4; // 气瓶容量 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.volumeTotal)); i += 4; // 储罐封头直边长 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.lenExtra)); i += 2; // 储罐筒长度 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.len)); i += 4; // 储罐直径 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.diameter)); i += 4; // 自动发送频率 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalTrans / 60)); i += 2; // 自动发送短信频率(实际发送采集频率) Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalSample / 60)); i += 2; // 修改数据长度 Task_sendBuff[7] = i - 8; // 校验码 crc = MODBUS_RTU_CRC16((uint8_t *) Task_sendBuff, i); Int2ByteS(Task_sendBuff, i, htons(crc)); i += 2; // 结束符 Task_sendBuff[i++] = 0x0d; Task_sendBuff[i++] = 0x0a; return i; } uint8_t pack_furui_send_data(gprs_data_t *pGprs, uint32_t *relativeTime) { uint8_t i; uint32_t uVal32; S_RTC_TIME_DATA_T sRTC; uint16_t crc; // 打包上报数据(按modbus从机响应的格式) memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = 0; // 起始符 Task_sendBuff[i++] = 0x4C; // 总长度:先预设为0,最后再修改,位置为Task_sendBuff[1] Task_sendBuff[i++] = 0; // 协议版本 Task_sendBuff[i++] = 1; // 硬件版本 Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor; // 软件版本 Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor; // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); printf("\nSend PSN: 20%02d%02d%02d%02d%03d\n", Task_sendBuff[i], Task_sendBuff[i + 1], Task_sendBuff[i + 2], Task_sendBuff[i+3], (Task_sendBuff[i + 4] << 8) | Task_sendBuff[i + 5]); i += 6; // 时间戳 RTC_GetDateAndTime(&sRTC); *relativeTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time; Int2ByteL(Task_sendBuff, i, htonl(*relativeTime)); i += 4; // 传感器状态 uVal32 = 0xFFFFFFFFul; // 连接状态 if(!pGprs->sampleData.staDPress.notConnect) uVal32 &= ~(1ul << 0); if(!pGprs->sampleData.staPress.notConnect) uVal32 &= ~(1ul << 1); if(!pGprs->sampleData.staExtPress[0].notConnect) uVal32 &= ~(1ul << 2); if(!pGprs->sampleData.staExtTempr[0].notConnect) uVal32 &= ~(1ul << 3); if(!pGprs->sampleData.staExtTempr[1].notConnect) uVal32 &= ~(1ul << 4); if(!(pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_COMM_FAULT)) uVal32 &= ~(1ul << 5); if(1) // 流量计 uVal32 &= ~(1ul << 6); if(!(pGprs->sampleData.leak.staLeak == LEAK_STATUS_COMM_FAULT)) uVal32 &= ~(1ul << 7); // 故障状态 if(!(pGprs->sampleData.staDPress.overFlow || pGprs->sampleData.staDPress.underFlow)) uVal32 &= ~(1ul << 8); if(!(pGprs->sampleData.staPress.overFlow || pGprs->sampleData.staPress.underFlow)) uVal32 &= ~(1ul << 9); if(!(pGprs->sampleData.staExtPress[0].overFlow || pGprs->sampleData.staExtPress[0].underFlow)) uVal32 &= ~(1ul << 10); if(!(pGprs->sampleData.staExtTempr[0].overFlow || pGprs->sampleData.staExtTempr[0].underFlow)) uVal32 &= ~(1ul << 11); if(!(pGprs->sampleData.staExtTempr[1].overFlow || pGprs->sampleData.staExtTempr[1].underFlow)) uVal32 &= ~(1ul << 12); if(!(pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_FAULT)) uVal32 &= ~(1ul << 13); if(1) // 流量计 uVal32 &= ~(1ul << 14); if(!(pGprs->sampleData.leak.staLeak == LEAK_STATUS_FAULT)) uVal32 &= ~(1ul << 15); Int2ByteL(Task_sendBuff, i, htonl(uVal32)); i += 4; // 当前差压值:mmWC if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR && !dcBuff.configDisplay.op_USE_HEIGHT_LEVEL && !dcBuff.configDisplay.op_USE_PCT_LEVEL) Int2ByteS(Task_sendBuff, i, htons((uint16_t) KPa2mmH2O(pGprs->sampleData.diff))); else Int2ByteS(Task_sendBuff, i, htons((uint16_t) pGprs->sampleData.height)); i +=2 ; // 容积百分比 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.volumePct)); i += 2; // 当前容积 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.volume)); i += 4; // 重量 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.weight)); i += 4; // 气瓶容量 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.volumeTotal)); i += 4; // 压力1 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.pressure)); i += 2; // 压力2 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extPressure[0])); i += 2; // 温度1 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[0])); i += 2; // 温度2 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[1])); i += 2; // 真空度 Int2ByteS(Task_sendBuff, i, htons((uint16_t) (pGprs->sampleData.vacuum[0].vacuum * 100))); i += 2; // 真空计温度 Int2ByteS(Task_sendBuff, i, htons((int16_t) pGprs->sampleData.vacuum[0].tempr)); i += 2; // 天信MODBUS /A1 通信协议 (BCD码) // 标况体积总量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.nM3, 6); i += 6; // 标况流量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.nM3_h, 4); i += 4; // 工况流量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.M3_h, 4); i += 4; // 流量计温度 memmove(Task_sendBuff + i, pGprs->sampleData.flow.tempr, 4); i += 4; // 流量计压力 memmove(Task_sendBuff + i, pGprs->sampleData.flow.pressure, 4); i += 4; // 泄露状态 Task_sendBuff[i++] = (pGprs->sampleData.leak.staLeak == LEAK_STATUS_A2_ALARM ? 1 : 0); // 经度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.longitude)); i += 4; // 纬度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.latitude)); i += 4; // rssi Task_sendBuff[i++] = pGprs->dtuData.rssi; // 电量百分比 Task_sendBuff[i++] = pGprs->dtuData.batPct; // 电池当前电压 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batVoltage / 10)); i += 2; // 供电状态 Task_sendBuff[i++] = (pGprs->dtuData.batCurrent < 0 ? -1 : 1); // 液源 if(dcBuff.configBottle.source >= SOURCE_LNG && dcBuff.configBottle.source <= SOURCE_POPO) Task_sendBuff[i] = dcBuff.configBottle.source; i++; // 密度 Int2ByteS(Task_sendBuff, i, htons(Config_GetDensity(dcBuff.configBottle.source) * 1000)); i += 2; // 储罐类型 if(dcBuff.configBottle.type == BOTTLE_TYPE_STAND) Task_sendBuff[i] = 0; else if(dcBuff.configBottle.type == BOTTLE_TYPE_LYING) Task_sendBuff[i] = 1; else if(dcBuff.configBottle.type == BOTTLE_TYPE_SPHERICAL) Task_sendBuff[i] = 2; i++; // 储罐直径 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.diameter)); i += 4; // 储罐筒长度 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2)); i += 4; // 采集周期 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalSample)); i += 4; // 发送周期 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalTrans)); i += 4; // 满液位百分比 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.fullPct)); i += 2; // 关键液位百分比 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.priPct)); i += 2; // 订货位百分比 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.orderPct)); i += 2; // 空液位百分比 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.emptyPct)); i += 2; // 压力报警上限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPressH)); i += 2; // 压力报警下限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPress)); i += 2; // 温度报警上限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnTemprH)); i += 2; // 温度报警下限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnTempr)); i += 2; // 真空度报警上限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVacuumH)); i += 2; // 显示控制 Task_sendBuff[i++] = dcBuff.configBottle.dispMode; // 修改数据长度 Task_sendBuff[1] = i - 1 + 2; // 校验码 crc = MODBUS_RTU_CRC16(Task_sendBuff + 1, i - 1); Int2ByteS(Task_sendBuff, i, htons(crc)); i += 2; // 结束符 Task_sendBuff[i++] = 0x53; return i; } uint8_t pack_huida_send_data(gprs_data_t *pGprs, uint32_t *relativeTime) { uint8_t i; uint32_t uVal32; S_RTC_TIME_DATA_T sRTC; uint16_t crc; // 打包上报数据(按modbus从机响应的格式) memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = 0; // 起始符 Task_sendBuff[i++] = 0x4C; // 总长度:先预设为0,最后再修改,位置为Task_sendBuff[1] Task_sendBuff[i++] = 0; // 协议版本 Task_sendBuff[i++] = 1; // 硬件版本 Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor; // 软件版本 Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor; // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); printf("\nSend PSN: 20%02d%02d%02d%02d%03d\n", Task_sendBuff[i], Task_sendBuff[i + 1], Task_sendBuff[i + 2], Task_sendBuff[i+3], (Task_sendBuff[i + 4] << 8) | Task_sendBuff[i + 5]); i += 6; // 时间戳 RTC_GetDateAndTime(&sRTC); *relativeTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time; Int2ByteL(Task_sendBuff, i, htonl(*relativeTime)); i += 4; // 传感器状态 uVal32 = 0xFFFFFFFFul; // 连接状态 if(!pGprs->sampleData.staDPress.notConnect) uVal32 &= ~(1ul << 0); if(!pGprs->sampleData.staPress.notConnect) uVal32 &= ~(1ul << 1); if(!pGprs->sampleData.staExtTempr[0].notConnect) uVal32 &= ~(1ul << 2); if(!pGprs->sampleData.staExtTempr[1].notConnect) uVal32 &= ~(1ul << 3); if(!(pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_COMM_FAULT)) uVal32 &= ~(1ul << 6); if(!(pGprs->sampleData.leak.staLeak == LEAK_STATUS_COMM_FAULT)) uVal32 &= ~(1ul << 7); // 故障状态 if(!(pGprs->sampleData.staDPress.overFlow || pGprs->sampleData.staDPress.underFlow)) uVal32 &= ~(1ul << 8); if(!(pGprs->sampleData.staPress.overFlow || pGprs->sampleData.staPress.underFlow)) uVal32 &= ~(1ul << 9); if(!(pGprs->sampleData.staExtTempr[0].overFlow || pGprs->sampleData.staExtTempr[0].underFlow)) uVal32 &= ~(1ul << 10); if(!(pGprs->sampleData.staExtTempr[1].overFlow || pGprs->sampleData.staExtTempr[1].underFlow)) uVal32 &= ~(1ul << 11); if(!(pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_FAULT)) uVal32 &= ~(1ul << 14); if(!(pGprs->sampleData.leak.staLeak == LEAK_STATUS_FAULT)) uVal32 &= ~(1ul << 15); Int2ByteL(Task_sendBuff, i, htonl(uVal32)); i += 4; // 当前差压值:mmWC if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR && !dcBuff.configDisplay.op_USE_HEIGHT_LEVEL && !dcBuff.configDisplay.op_USE_PCT_LEVEL) Int2ByteS(Task_sendBuff, i, htons((uint16_t) KPa2mmH2O(pGprs->sampleData.diff))); else Int2ByteS(Task_sendBuff, i, htons((uint16_t) pGprs->sampleData.height)); i +=2 ; // 容积百分比 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.volumePct)); i += 2; // 当前容积 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.volume)); i += 4; // 重量 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.weight)); i += 4; // 气瓶容量 Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.volumeTotal)); i += 4; // 压力1 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.pressure)); i += 2; // 温度1 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[0])); i += 2; // 温度2 Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[1])); i += 2; // 温度3 i += 2; // 温度4 i += 2; // 真空度 Int2ByteS(Task_sendBuff, i, htons((uint16_t) (pGprs->sampleData.vacuum[0].vacuum * 100))); i += 2; // 真空计温度 Int2ByteS(Task_sendBuff, i, htons((int16_t) pGprs->sampleData.vacuum[0].tempr)); i += 2; #if 0 // 天信MODBUS /A1 通信协议 (BCD码) // 标况体积总量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.nM3, 6); i += 6; // 标况流量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.nM3_h, 4); i += 4; // 工况流量 memmove(Task_sendBuff + i, pGprs->sampleData.flow.M3_h, 4); i += 4; // 流量计温度 memmove(Task_sendBuff + i, pGprs->sampleData.flow.tempr, 4); i += 4; // 流量计压力 memmove(Task_sendBuff + i, pGprs->sampleData.flow.pressure, 4); i += 4; #endif // 泄露状态 Task_sendBuff[i++] = (pGprs->sampleData.leak.staLeak == LEAK_STATUS_A2_ALARM ? 1 : 0); // 经度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.longitude)); i += 4; // 纬度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.latitude)); i += 4; // rssi Task_sendBuff[i++] = pGprs->dtuData.rssi; // 电量百分比 Task_sendBuff[i++] = pGprs->dtuData.batPct; // 电池当前电压 Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batVoltage / 10)); i += 2; // 供电状态 Task_sendBuff[i++] = (pGprs->dtuData.batCurrent < 0 ? -1 : 1); // 液源 if(dcBuff.configBottle.source >= SOURCE_LNG && dcBuff.configBottle.source <= SOURCE_POPO) Task_sendBuff[i] = dcBuff.configBottle.source; i++; // 密度 Int2ByteS(Task_sendBuff, i, htons(Config_GetDensity(dcBuff.configBottle.source) * 1000)); i += 2; // 储罐类型 if(dcBuff.configBottle.type == BOTTLE_TYPE_STAND) Task_sendBuff[i] = 0; else if(dcBuff.configBottle.type == BOTTLE_TYPE_LYING) Task_sendBuff[i] = 1; else if(dcBuff.configBottle.type == BOTTLE_TYPE_SPHERICAL) Task_sendBuff[i] = 2; i++; // 储罐直径 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.diameter)); i += 4; // 储罐筒长度 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2)); i += 4; // 采集周期 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalSample)); i += 4; // 发送周期 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalTrans)); i += 4; // 满液位百分比 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.fullPct)); i += 2; // 关键液位百分比 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.priPct)); i += 2; // 订货位百分比 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.orderPct)); i += 2; // 空液位百分比 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.emptyPct)); i += 2; // 压力报警上限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPressH)); i += 2; // 压力报警下限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPress)); i += 2; // 温度报警上限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnTemprH)); i += 2; // 温度报警下限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnTempr)); i += 2; // 真空度报警上限 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVacuumH)); i += 2; // 显示控制 Task_sendBuff[i++] = dcBuff.configBottle.dispMode; // 修改数据长度 Task_sendBuff[1] = i - 1 + 2; // 校验码 crc = MODBUS_RTU_CRC16(Task_sendBuff + 1, i - 1); Int2ByteS(Task_sendBuff, i, htons(crc)); i += 2; // 结束符 Task_sendBuff[i++] = 0x53; return i; } uint8_t pack_chaoyang_send_data(gprs_data_t *pGprs, uint32_t *relativeTime) { uint8_t i; uint32_t uVal32; // 打包上报数据(按modbus从机响应的格式) memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = 0; // IMSI memmove(Task_sendBuff + i, dcBuff.powerInfo.simNumber, strlen(dcBuff.powerInfo.simNumber)); i += 15; // 压力状态、压力值 if(pGprs->sampleData.staPress.notConnect || pGprs->sampleData.staPress.underFlow || pGprs->sampleData.staPress.overFlow) { Task_sendBuff[i++] = '0'; sprintf((s8 *) Task_sendBuff + i, "%05d", 0); } else { Task_sendBuff[i++] = '1'; sprintf((s8 *) Task_sendBuff + i, "%05d", pGprs->sampleData.pressure / 10); // 0.1MPa } i += 5; // 液位状态、液量值 if(pGprs->sampleData.staDPress.notConnect || pGprs->sampleData.staDPress.underFlow || pGprs->sampleData.staDPress.overFlow) { Task_sendBuff[i++] = '0'; sprintf((s8 *) Task_sendBuff + i, "%05d", 0); } else { Task_sendBuff[i++] = '1'; sprintf((s8 *) Task_sendBuff + i, "%05d", pGprs->sampleData.volume / 10); // 0.1m3 } i += 5; // 电池电压 Task_sendBuff[i++] = '1'; sprintf((s8 *) Task_sendBuff + i, "%05d", pGprs->dtuData.batVoltage / 10); // 0.1v i += 5; // 充电状态 Task_sendBuff[i++] = '1'; sprintf((s8 *) Task_sendBuff + i, "%05d", VCC_POWER_STATUS() ? 1 * 100 : 0); i += 5; // 结束符 sprintf((s8 *) Task_sendBuff + i, "\r\n"); i += 2; return i; } uint8_t parse_furui_recv_data(uint8_t PSN[6], uint32_t relativeTime, uint16_t recvLen) { uint8_t i, j, len, protocol; uint32_t mask, uVal32; uint16_t uVal16; int16_t val16; uint8_t saveConfig = 0; i = 0; // 检查起始符、结束符 if(Task_recvBuff[i++] != 0x4C || Task_recvBuff[recvLen - 1] != 0x53) return 0; // 检查数据长度和CRC len = Task_recvBuff[i++]; if(len != recvLen - 2 || MODBUS_RTU_CRC16(Task_recvBuff + 1, len) != 0) return 0; // 检查协议版本 protocol = Task_recvBuff[i++]; if(protocol != 1) return 0; // 检查PSN if(memcmp(Task_recvBuff + i, PSN, 6) != 0) return 0; i += 6; // 检查时间戳 if(ntohl(Byte2IntL(Task_recvBuff, i)) != relativeTime) return 0; i += 4; // 参数更新标志 mask = ntohl(Byte2IntL(Task_recvBuff, i)); i += 4; j = 0; // 介质 if(mask & (1ul << (j++))) { printf("modify source\r\n"); if(dcBuff.configBottle.source != Task_recvBuff[i]) { dcBuff.configBottle.source = Task_recvBuff[i]; saveConfig = 1; } } i++; // 密度 if(mask & (1ul << (j++))) { printf("modify density\r\n"); uVal16 = ntohs(Byte2IntS(Task_recvBuff, i)); if(Config_GetDensity(dcBuff.configBottle.source) * 1000 != uVal16) { Config_SetDensity(dcBuff.configBottle.source, uVal16 / 1000.0); saveConfig = 1; } } i += 2; // 储罐类型 if(mask & (1ul << (j++))) { printf("modify type\r\n"); if(dcBuff.configBottle.type != Task_recvBuff[i]) { dcBuff.configBottle.type = Task_recvBuff[i]; saveConfig = 1; } } i++; // 储罐直径 if(mask & (1ul << (j++))) { printf("modify diameter\r\n"); uVal32 = ntohl(Byte2IntL(Task_recvBuff, i)); if(dcBuff.configBottle.diameter != uVal32) { dcBuff.configBottle.diameter = uVal32; saveConfig = 1; } } i += 4; // 储罐筒长度 if(mask & (1ul << (j++))) { printf("modify len\r\n"); uVal32 = ntohl(Byte2IntL(Task_recvBuff, i)); if(dcBuff.configBottle.lenExtra != 0 || dcBuff.configBottle.len != uVal32) { dcBuff.configBottle.lenExtra = 0; dcBuff.configBottle.len = uVal32; saveConfig = 1; } } i += 4; // 采集周期 if(mask & (1ul << (j++))) { printf("modify intervalSample\r\n"); uVal32 = ntohl(Byte2IntL(Task_recvBuff, i)); if(dcBuff.configData.intervalSample != uVal32) { dcBuff.configData.intervalSample = uVal32; saveConfig = 1; } } i += 4; // 发送周期 if(mask & (1ul << (j++))) { printf("modify intervalTrans\r\n"); uVal32 = ntohl(Byte2IntL(Task_recvBuff, i)); if(dcBuff.configData.intervalTrans != uVal32) { dcBuff.configData.intervalTrans = uVal32; saveConfig = 1; } } i += 4; // 满液位百分比 if(mask & (1ul << (j++))) { printf("modify fullPct\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); if(dcBuff.configBottle.fullPct != uVal16) { dcBuff.configBottle.fullPct = uVal16; saveConfig = 1; } } i += 2; // 关键液位百分比 if(mask & (1ul << (j++))) { printf("modify priPct\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); if(dcBuff.configBottle.priPct != uVal16) { dcBuff.configBottle.priPct = uVal16; saveConfig = 1; } } i += 2; // 订货位百分比 if(mask & (1ul << (j++))) { printf("modify orderPct\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); if(dcBuff.configBottle.orderPct != uVal16) { dcBuff.configBottle.orderPct = uVal16; saveConfig = 1; } } i += 2; // 空液位百分比 if(mask & (1ul << (j++))) { printf("modify emptyPct\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); if(dcBuff.configBottle.emptyPct != uVal16) { dcBuff.configBottle.emptyPct = uVal16; saveConfig = 1; } } i += 2; // 压力报警上限 if(mask & (1ul << (j++))) { printf("modify warnPressH\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); if(dcBuff.configBottle.warnPressH != uVal16) { dcBuff.configBottle.warnPressH = uVal16; saveConfig = 1; } } i += 2; // 压力报警下限 if(mask & (1ul << (j++))) { printf("modify warnPress\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); if(dcBuff.configBottle.warnPress != uVal16) { dcBuff.configBottle.warnPress = uVal16; saveConfig = 1; } } i += 2; // 温度报警上限 if(mask & (1ul << (j++))) { printf("modify warnTemprH\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); memmove(&val16, &uVal16, 2); if(dcBuff.configBottle.warnTemprH != val16) { dcBuff.configBottle.warnTemprH = val16; saveConfig = 1; } } i += 2; // 温度报警下限 if(mask & (1ul << (j++))) { printf("modify warnTempr\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); memmove(&val16, &uVal16, 2); if(dcBuff.configBottle.warnTempr != val16) { dcBuff.configBottle.warnTempr = val16; saveConfig = 1; } } i += 2; // 真空度报警上限 if(mask & (1ul << (j++))) { printf("modify warnVacuumH\r\n"); uVal16= ntohs(Byte2IntS(Task_recvBuff, i)); if(dcBuff.configBottle.warnVacuumH != uVal16) { dcBuff.configBottle.warnVacuumH = uVal16; saveConfig = 1; } } i += 2; // 显示控制 if(mask & (1ul << (j++))) { printf("modify dispMode\r\n"); if(dcBuff.configBottle.dispMode != Task_recvBuff[i]) { dcBuff.configBottle.dispMode = Task_recvBuff[i]; saveConfig = 1; } } i++; // 保存参数 if(saveConfig) Config_SaveConfig(); return 1; } uint8_t parse_huida_recv_data(uint8_t PSN[6], uint32_t relativeTime, uint16_t recvLen) { return parse_furui_recv_data(PSN, relativeTime, recvLen); } //////////////////////////////////////////////////////////////////////////////////////// uint8_t pack_rf_send_data(gprs_data_t *pGprs, uint32_t totalSeconds) { uint8_t i; rf_sensor_t *pSensor; S_RTC_TIME_DATA_T sRTC; // 打包上报数据(按modbus从机响应的格式) memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = 0; // PSN printf("\nRf PSN: 20%02d%02d%02d%02d%03d\n", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); // 差压测量:差压值 *100(KPa),称重测量:容积百分比*100,电容测量:液位高度(mm) if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR) { if(dcBuff.configBottle.measureType == 0) Int2ByteS(Task_sendBuff, i, pGprs->sampleData.diff * 100); else Int2ByteS(Task_sendBuff, i, pGprs->sampleData.volumePct); } else Int2ByteS(Task_sendBuff, i, pGprs->sampleData.height); i += 2; // 压力 Int2ByteS(Task_sendBuff, i, pGprs->sampleData.pressure); i += 2; // 温度 Int2ByteS(Task_sendBuff, i, pGprs->sampleData.extTempr[0]); i += 2; // 液源/贮罐类型/故障码/测量方式 pSensor = (rf_sensor_t *) (Task_sendBuff + i); pSensor->staDiff = Bluetooth_ConvertStat(&pGprs->sampleData.staDPress); pSensor->staPress = Bluetooth_ConvertStat(&pGprs->sampleData.staPress); pSensor->staETempr1 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[0]); pSensor->charging = pGprs->sampleData.charging; pSensor->bat_low = pGprs->dtuData.batLow; if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR) pSensor->measure_type = dcBuff.configBottle.measureType; else pSensor->measure_type = 2; pSensor->bottle_type = dcBuff.configBottle.type; pSensor->L_source = dcBuff.configBottle.source; i += 2; // 密度 Int2ByteS(Task_sendBuff, i, Config_GetDensity(dcBuff.configBottle.source) * 1000); i += 2; // 经度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, pGprs->dtuData.longitude); i += 4; // 纬度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, pGprs->dtuData.latitude); i += 4; // 电池当前电压 Int2ByteS(Task_sendBuff, i, pGprs->dtuData.batVoltage / 10); i += 2; // 电量百分比 Task_sendBuff[i++] = pGprs->dtuData.batPct; #if 0 // 充电电流,电流的符号表示充放电状态 if(pGprs->dtuData.batCurrent < -128) Task_sendBuff[i] = -128; else if(pGprs->dtuData.batCurrent > 127) Task_sendBuff[i] = 127; else Task_sendBuff[i] = pGprs->dtuData.batCurrent; #else // 用电流的绝对值表示复位原因 // 1-POR, 2-PIN, 4-WDT, 8-LVR, 16-BOD, 32-SYS Task_sendBuff[i] = SYS_RSTSTS & 0x7F; if(pGprs->dtuData.batCurrent < 0) Task_sendBuff[i] = -Task_sendBuff[i]; #endif i++; // 获取当前时间 RTC_GetDateAndTime(&sRTC); Int2ByteL(Task_sendBuff, i, Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time); i += 4; printf("\ndcBuff.powerInfo.hardVer.major = %d, dcBuff.powerInfo.softVer.minor = %d\n", dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.softVer.minor); // 硬件版本 Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor; // 软件版本 Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor; // 储罐筒长度 Int2ByteL(Task_sendBuff, i, dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2); i += 4; // 储罐直径 Int2ByteL(Task_sendBuff, i, dcBuff.configBottle.diameter); i += 4; // 充装比 Task_sendBuff[i++] = dcBuff.configBottle.chargePct; return i; } //////////////////////////////////////////////////////////////////////////////////////// uint8_t pack_bd_send_data(gprs_data_t *pGprs, uint32_t totalSeconds) { uint8_t i; rf_sensor_t *pSensor; S_RTC_TIME_DATA_T sRTC; // 打包上报数据(按modbus从机响应的格式) memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = 0; // PSN printf("\nBD PSN: 20%02d%02d%02d%02d%03d\n", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); // 差压 Int2ByteS(Task_sendBuff, i, pGprs->sampleData.diff); i += 2; // 容积百分比 Int2ByteS(Task_sendBuff, i, pGprs->sampleData.volumePct); i += 2; // 当前容积 Int2ByteL(Task_sendBuff, i, pGprs->sampleData.volume); i += 4; // 重量 Int2ByteL(Task_sendBuff, i, pGprs->sampleData.weight); i += 4; // 压力 Int2ByteS(Task_sendBuff, i, pGprs->sampleData.pressure); i += 2; // 温度-扩展温度1 Int2ByteS(Task_sendBuff, i, pGprs->sampleData.extTempr[0]); i += 2; // 温度-调试信息:标识北斗短信 Int2ByteS(Task_sendBuff, i, 2); i += 2; // 液源/贮罐类型/故障码/测量方式 pSensor = (rf_sensor_t *) (Task_sendBuff + i); pSensor->staDiff = Bluetooth_ConvertStat(&pGprs->sampleData.staDPress); pSensor->staPress = Bluetooth_ConvertStat(&pGprs->sampleData.staPress); pSensor->staETempr1 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[0]); pSensor->charging = pGprs->sampleData.charging; pSensor->bat_low = pGprs->dtuData.batLow; if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR) pSensor->measure_type = dcBuff.configBottle.measureType; else pSensor->measure_type = 2; pSensor->bottle_type = dcBuff.configBottle.type; pSensor->L_source = dcBuff.configBottle.source; i += 2; // 经度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, pGprs->dtuData.longitude); i += 4; // 纬度 if(pGprs->dtuData.recentPosState) Int2ByteL(Task_sendBuff, i, pGprs->dtuData.latitude); i += 4; // 电池当前电压 Int2ByteS(Task_sendBuff, i, pGprs->dtuData.batVoltage / 10); i += 2; // 电量百分比 Task_sendBuff[i++] = pGprs->dtuData.batPct; #if 0 // 充电电流,电流的符号表示充放电状态 if(pGprs->dtuData.batCurrent < -128) Task_sendBuff[i] = -128; else if(pGprs->dtuData.batCurrent > 127) Task_sendBuff[i] = 127; else Task_sendBuff[i] = pGprs->dtuData.batCurrent; #else // 用电流的绝对值表示复位原因 // 1-POR, 2-PIN, 4-WDT, 8-LVR, 16-BOD, 32-SYS Task_sendBuff[i] = SYS_RSTSTS & 0x7F; if(pGprs->dtuData.batCurrent < 0) Task_sendBuff[i] = -Task_sendBuff[i]; #endif i++; // 获取当前时间 RTC_GetDateAndTime(&sRTC); Int2ByteL(Task_sendBuff, i, Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time); i += 4; printf("\ndcBuff.powerInfo.hardVer.major = %d, dcBuff.powerInfo.softVer.minor = %d\n", dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.softVer.minor); // 硬件版本 Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor; // 软件版本 Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor; // 气瓶容量 Int2ByteL(Task_sendBuff, i, pGprs->sampleData.volumeTotal); i += 4; // 储罐筒长度 Int2ByteL(Task_sendBuff, i, dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2); i += 4; // 储罐直径 Int2ByteL(Task_sendBuff, i, dcBuff.configBottle.diameter); i += 4; return i; } //////////////////////////////////////////////////////////////////////////////////////// uint16_t pack_json_send_data(gprs_data_t *pGprs, uint32_t totalSeconds) { char psn[14], utc[21]; S_RTC_TIME_DATA_T sRTC; #if 0 unsigned long long ll = 0; ll = dcBuff.configBottle.PSN[0] * 1000000000ll + dcBuff.configBottle.PSN[1] * 10000000ll + dcBuff.configBottle.PSN[2] * 100000ll + dcBuff.configBottle.PSN[3] * 1000ll + ((dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); sprintf(psn, "%010llX", ll); #else sprintf(psn, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); #endif Wakeup_CalcUTCTime(pGprs->sample_time + RTC_offsetSeconds, &sRTC); sprintf(utc, "%04d-%02d-%02dT%02d:%02d:%02dZ", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); json_initialize(); json_new_object(); json_new_array("assets"); json_new_object(); json_new_stringValue("customerReference", "PRAXAIR-GOLD-CN-PROD"); json_new_stringValue("assetIntegrationId", "0"); json_new_array("channels"); json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Level"); json_new_stringValue("channelNumber", "1"); json_new_stringValue("scaledUnitName", "mm WC"); json_new_array("readings"); json_new_object(); if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR && !dcBuff.configDisplay.op_USE_HEIGHT_LEVEL && !dcBuff.configDisplay.op_USE_PCT_LEVEL) json_new_doubleValue("scaledMeasurement", KPa2mmH2O(pGprs->sampleData.diff)); else json_new_doubleValue("scaledMeasurement", pGprs->sampleData.height); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object(); if(!dcBuff.configDisplay.op_LEVEL_SENSOR_ONLY){ json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Pressure"); json_new_stringValue("channelNumber", "2"); json_new_stringValue("scaledUnitName", "BAR"); json_new_array("readings"); json_new_object(); json_new_doubleValue("scaledMeasurement", pGprs->sampleData.pressure * 0.01); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object();} if(!dcBuff.configDisplay.op_LEVEL_SENSOR_ONLY && !dcBuff.configDisplay.op_DOL_VER){ json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Temperature"); json_new_stringValue("channelNumber", "3"); json_new_stringValue("scaledUnitName", "Celsius"); json_new_array("readings"); json_new_object(); json_new_intValue("scaledMeasurement", pGprs->sampleData.extTempr[0]); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object();} json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Gps"); json_new_stringValue("channelNumber", "4"); json_new_array("readings"); json_new_object(); json_new_intValue("scaledMeasurement", 0); if(pGprs->dtuData.recentPosState) { json_new_doubleValue("longitude", pGprs->dtuData.longitude * 0.000001); json_new_doubleValue("latitude", pGprs->dtuData.latitude * 0.000001); } else { json_new_doubleValue("longitude", 0); json_new_doubleValue("latitude", 0); } json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object(); json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "BatVoltage"); json_new_stringValue("channelNumber", "5"); json_new_stringValue("scaledUnitName", "V"); json_new_array("readings"); json_new_object(); json_new_doubleValue("scaledMeasurement", pGprs->dtuData.batVoltage * 0.001); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object(); if(0){ json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Diagnostic"); json_new_stringValue("channelNumber", "6"); json_new_array("readings"); json_new_object(); json_new_intValue("scaledMeasurement", dcBuff.powerInfo.hardVer.major); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object();} if(0){ json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Diagnostic"); json_new_stringValue("channelNumber", "7"); json_new_array("readings"); json_new_object(); json_new_intValue("scaledMeasurement", dcBuff.powerInfo.hardVer.minor); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object();} if(0){ json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Diagnostic"); json_new_stringValue("channelNumber", "8"); json_new_array("readings"); json_new_object(); json_new_intValue("scaledMeasurement", dcBuff.powerInfo.softVer.minor); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object();} if(0){ json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Diagnostic"); json_new_stringValue("channelNumber", "9"); json_new_array("readings"); json_new_object(); // 自启动以来的时间分钟数,32767分钟 json_new_intValue("scaledMeasurement", totalSeconds % 1966080ul / 60); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object();} if(0){ json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Diagnostic"); json_new_stringValue("channelNumber", "10"); json_new_array("readings"); json_new_object(); // 启动代码,充放电 json_new_intValue("scaledMeasurement", pGprs->dtuData.batCurrent > 0 ? SYS_RSTSTS : -SYS_RSTSTS); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object();} if(0){ json_new_object(); json_new_stringValue("deviceId", psn); json_new_stringValue("channelType", "Diagnostic"); json_new_stringValue("channelNumber", "11"); json_new_array("readings"); json_new_object(); // 上传GPS调试信息: 闪断次数*100+卫星数, 如2105表示闪断21次,卫星数5颗 json_new_intValue("scaledMeasurement", GPS_BOD_COUNT * 100 + pGprs->dtuData.sateCount); json_new_stringValue("timestamp", utc); json_end_object(); json_end_array(); json_end_object();} json_end_array(); json_end_object(); json_end_array(); json_end_object(); json_finish(); return strlen(JSON_data()); } //////////////////////////////////////////////////////////////////////////////////////// // 填写双向通讯的固定字段 uint16_t fill_biDir_fixFields(uint16_t cmd, uint16_t len) { bluetooth_send_t *pSend = (bluetooth_send_t *) Task_sendBuff; uint16_t crc; pSend->mark = CONFIG_MARK_LS; pSend->ver = htons(dcBuff.powerInfo.protocolVer.major); pSend->trans = 0; pSend->len = htons(len - sizeof(bluetooth_send_t) + 2); pSend->cmd = htons(cmd); crc = MODBUS_RTU_CRC16((uint8_t *) Task_sendBuff, len); Int2ByteS(Task_sendBuff, len, htons(crc)); return len + 2; } uint16_t pack_ldms_info_Ext_data(uint32_t dataTime, uint32_t totalSeconds) { uint16_t i = 0; S_RTC_TIME_DATA_T sRTC; bluetooth_timestamp_t t; memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); // 头信息(最后再填内容) i += sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.major; Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor; Task_sendBuff[i++] = dcBuff.powerInfo.softVer.major; Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor; // 软件日期:yyyymmdd Int2ByteL(Task_sendBuff, i, htonl((2000 + dcBuff.powerInfo.softDate.year) * 10000 + dcBuff.powerInfo.softDate.month * 100 + dcBuff.powerInfo.softDate.day)); i += 4; // Report format Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.major; Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.minor; // Config format Task_sendBuff[i++] = dcBuff.configBottle.header.ver.major; Task_sendBuff[i++] = dcBuff.configBottle.header.ver.minor; // 运行时间:分钟 Int2ByteL(Task_sendBuff, i, htonl(totalSeconds / 60)); i += 4; Int2ByteS(Task_sendBuff, i, htons(SYS_RSTSTS)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.dtuData.batCurrent)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.dtuData.batVoltage / 10)); i += 2; Task_sendBuff[i++] = dcBuff.dtuData.batPct; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.batCapa)); i += 4; if(bat_veryLow) Task_sendBuff[i] = 2; else if(dcBuff.dtuData.batLow) Task_sendBuff[i] = 1; else Task_sendBuff[i] = 0; i++; if(dcBuff.dtuData.posState) Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.latitude)); i += 4; if(dcBuff.dtuData.posState) Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.longitude)); i += 4; // 定位时间 if(dcBuff.dtuData.posState && dcBuff.dtuData.sysTime.year) { t.year = dcBuff.dtuData.sysTime.year + 2000 - 2010; t.mon = dcBuff.dtuData.sysTime.month; t.day = dcBuff.dtuData.sysTime.day; t.hour_H = dcBuff.dtuData.sysTime.hour >> 4; t.hour_L = dcBuff.dtuData.sysTime.hour & 0x0F; t.min = dcBuff.dtuData.sysTime.minute; t.sec = dcBuff.dtuData.sysTime.second; Int2ByteL(Task_sendBuff, i, htonl(t.tm)); } i += 4; // 卫星数量 Task_sendBuff[i++] = dcBuff.dtuData.sateCount; // 数据时间 Wakeup_CalcUTCTime(dataTime + RTC_offsetSeconds, &sRTC); t.year = sRTC.u32Year - 2010; t.mon = sRTC.u32Month; t.day = sRTC.u32Day; t.hour_H = sRTC.u32Hour >> 4; t.hour_L = sRTC.u32Hour & 0x0F; t.min = sRTC.u32Minute; t.sec = sRTC.u32Second; Int2ByteL(Task_sendBuff, i, htonl(t.tm)); i += 4; // 信号强度 Task_sendBuff[i++] = dcBuff.dtuData.rssi; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.gprsSuccCount)); i += 4; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.gprsSendCount - dcBuff.powerInfo.gprsSuccCount)); i += 4; if(dcBuff.powerInfo.gprsSendCount > 0) Task_sendBuff[i] = dcBuff.powerInfo.gprsSuccCount * 100 / dcBuff.powerInfo.gprsSendCount; i++; memmove(Task_sendBuff + i, dcBuff.powerInfo.gprsFailCode, strlen(dcBuff.powerInfo.gprsFailCode)); i += 6; memmove(Task_sendBuff + i, dcBuff.powerInfo.simNumber, strlen(dcBuff.powerInfo.simNumber)); i += 24; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.bdNumber)); i += 4; // 储罐类型 Task_sendBuff[i++] = dcBuff.configBottle.type; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.diameter)); i += 4; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.len)); i += 4; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.lenExtra)); i += 4; Int2ByteL(Task_sendBuff, i, htonl(Theoretical_Param.v)); i += 4; Task_sendBuff[i++] = dcBuff.configBottle.chargePct; Task_sendBuff[i++] = dcBuff.configBottle.source; Int2ByteS(Task_sendBuff, i, htons(Config_GetDensity(dcBuff.configBottle.source) * 1000)); i += 2; Task_sendBuff[i++] = dcBuff.configBottle.dispMode | (dcBuff.configBottle.hideVacu << 2); if(dcBuff.configDisplay.L_Unit == UNIT_KPA) Task_sendBuff[i] = 0; else if(dcBuff.configDisplay.L_Unit == UNIT_KG) Task_sendBuff[i] = 1; else if(dcBuff.configDisplay.L_Unit == UNIT_L) Task_sendBuff[i] = 2; else if(dcBuff.configDisplay.L_Unit == UNIT_MMH2O) Task_sendBuff[i] = 4; else Task_sendBuff[i] = 3; i++; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.serverVer)); i += 2; memmove(Task_sendBuff + i, dcBuff.configData.server, strlen(dcBuff.configData.server)); i += 30; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.port)); i += 2; memmove(Task_sendBuff + i, dcBuff.configData.gpsServer, strlen(dcBuff.configData.gpsServer)); i += 30; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.gpsPort)); i += 2; memmove(Task_sendBuff + i, dcBuff.configData.upgServer, strlen(dcBuff.configData.upgServer)); i += 30; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.upgPort)); i += 2; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalTrans)); i += 4; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalSample)); i += 4; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalGPSTrans)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalGPS)); i += 2; Task_sendBuff[i++] = dcBuff.configData.timeLag; strcpy((char *) Task_sendBuff + i, DTU_DecideAPN()); i += 24; Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configDisplay.bdCommander)); i += 4; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPress)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPressH)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.fullPct)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.priPct)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.orderPct)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.emptyPct)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVolt)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVoltH)); i += 2; strcpy((char *) Task_sendBuff + i, DTU_DecideAPNUser()); i += 10; strcpy((char *) Task_sendBuff + i, DTU_DecideAPNPwd()); i += 10; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.floorLevel)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.span)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.spanPeriod)); i += 2; // 测量方式 Task_sendBuff[i++] = dcBuff.configDisplay.op_USE_CAPACITY_SENSOR ? 2 : dcBuff.configBottle.measureType; Task_sendBuff[i++] = 0; Task_sendBuff[i++] = dcBuff.configDisplay.op_USE_PT100_SENSOR ? 0 : 1; // 差压传感器参数 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.lowRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.highRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.zeroValue)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.fullValue)); i += 2; // 电容传感器参数 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.baseC)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.refC)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.c1ADC)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.c2ADC)); i += 2; Int2ByteS(Task_sendBuff, i, htons(CAP_K_C1)); i += 2; Int2ByteS(Task_sendBuff, i, htons(CAP_K_C2)); i += 2; // 称重传感器参数 // Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.lowRange)); Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adDPress)); i += 4; // Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.highRange)); Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adPress)); i += 4; // Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.zeroValue)); Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adExtTempr[0])); i += 4; // Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.fullValue)); Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adExtTempr[1])); i += 4; // 压力传感器参数 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.lowRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.highRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.zeroValue)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.fullValue)); i += 2; // 扩展压力传感器1参数 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].lowRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].highRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].zeroValue)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].fullValue)); i += 2; if(dcBuff.configDisplay.op_USE_PT100_SENSOR) { // 扩展温度传感器1参数 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].calibrateT)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].calibrateR)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].zeroValue)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].fullValue)); i += 2; // 扩展温度传感器2参数 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].calibrateT)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].calibrateR)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].zeroValue)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].fullValue)); i += 2; } else { // 扩展温度传感器1参数 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[0].lowRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[0].highRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[0].zeroValue)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[0].fullValue)); i += 2; // 扩展温度传感器2参数 Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[1].lowRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[1].highRange)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[1].zeroValue)); i += 2; Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[1].fullValue)); i += 2; } // 填写固定字段 return fill_biDir_fixFields(0xD045, i); } #define D046_PARAM_SIZE (268) uint8_t parse_param_D046_data(uint8_t *param, uint8_t *reset) { longlong_mask_t mask; uint16_t i = 0, shift = 0; // 参数有效标志位(用一个无符号长整数表示, 共63项可选配置(bit 0~62), 最高位(bit 63)代表复位命令) // 网络字节序: 12 34 56 78 90 ab cd ef // h = 0x78563412, l = 0xefcdab90 (网络字节序) // h = 0x12345678, l = 0x90abcdef (本机字节序) // mask = 0x1234567890abcdef mask.h = ntohl(Byte2IntL(param, i)); i += 4; mask.l = ntohl(Byte2IntL(param, i)); i += 4; printf("\nmask = %016llX\n", mask.ll); // 储罐类型 if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.type = param[i]; i++; // 直径 if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.diameter = ntohl(Byte2IntL(param, i)); i += 4; // 长度 if(mask.ll & (1ull << (shift++))) { dcBuff.configBottle.len = ntohl(Byte2IntL(param, i)); dcBuff.configBottle.lenExtra = 0; } i += 4; // 充装比 if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.chargePct = param[i]; i++; // 介质 if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.source = param[i]; i++; // 密度 if(mask.ll & (1ull << (shift++))) Config_SetDensity(dcBuff.configBottle.source, ntohs(Byte2IntS(param, i)) / 1000.0); i += 2; // 显示模式 if(mask.ll & (1ull << (shift++))) { dcBuff.configBottle.dispMode = param[i] & 0x03; dcBuff.configBottle.hideVacu = (param[i] >> 2) & 0x01; dcBuff.configBottle.options &= ~0x0003ul; if(dcBuff.configBottle.dispMode == DISP_MODE_ALL) dcBuff.configBottle.options |= 0x0003ul; else if(dcBuff.configBottle.dispMode == DISP_MODE_L) dcBuff.configBottle.options |= 0x0001ul; else if(dcBuff.configBottle.dispMode == DISP_MODE_KG) dcBuff.configBottle.options |= 0x0002ul; } i++; // 显示单位 if(mask.ll & (1ull << (shift++))) { if(param[i] == 0) dcBuff.configDisplay.L_Unit = UNIT_KPA; else if(param[i] == 1) dcBuff.configDisplay.L_Unit = UNIT_KG; else if(param[i] == 2) dcBuff.configDisplay.L_Unit = UNIT_L; else if(param[i] == 4) dcBuff.configDisplay.L_Unit = UNIT_MMH2O; else dcBuff.configDisplay.L_Unit = UNIT_PCT; } i++; // 服务器版本 if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.serverVer = ntohs(Byte2IntS(param, i)); i += 2; // 远传服务器 if(mask.ll & (1ull << (shift++))) strcpy(dcBuff.configData.server, (char *) param + i); i += 30; // 远传端口 if(mask.ll & (1ull << (shift++))) dcBuff.configData.port = ntohs(Byte2IntS(param, i)); i += 2; // 远传服务器 if(mask.ll & (1ull << (shift++))) strcpy(dcBuff.configData.gpsServer, (char *) param + i); i += 30; // 远传端口 if(mask.ll & (1ull << (shift++))) dcBuff.configData.gpsPort = ntohs(Byte2IntS(param, i)); i += 2; // 远传服务器 if(mask.ll & (1ull << (shift++))) strcpy(dcBuff.configData.upgServer, (char *) param + i); i += 30; // 远传端口 if(mask.ll & (1ull << (shift++))) dcBuff.configData.upgPort = ntohs(Byte2IntS(param, i)); i += 2; // 发送频率 if(mask.ll & (1ull << (shift++))) dcBuff.configData.intervalTrans = ntohl(Byte2IntL(param, i)); i += 4; // 采集频率 if(mask.ll & (1ull << (shift++))) dcBuff.configData.intervalSample = ntohl(Byte2IntL(param, i)); i += 4; // 发送频率 if(mask.ll & (1ull << (shift++))) dcBuff.configData.intervalGPSTrans = ntohs(Byte2IntS(param, i)); i += 2; // 采集频率 if(mask.ll & (1ull << (shift++))) dcBuff.configData.intervalGPS = ntohs(Byte2IntS(param, i)); i += 2; // 时差 if(mask.ll & (1ull << (shift++))) dcBuff.configData.timeLag = param[i]; i++; // APN if(mask.ll & (1ull << (shift++))) strcpy(dcBuff.configDisplay.APN, (char *) param + i); i += 24; // 北斗指挥机卡号 if(mask.ll & (1ull << (shift++))) dcBuff.configDisplay.bdCommander = ntohl(Byte2IntL(param, i)); i += 4; // 压力报警点低: KPa if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.warnPress = ntohs(Byte2IntS(param, i)); i += 2; // 压力报警点高: KPa if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.warnPressH = ntohs(Byte2IntS(param, i)); i += 2; // 满液位报警点: 0.01% if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.fullPct = ntohs(Byte2IntS(param, i)); i += 2; // 关键液位报警点: 0.01% if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.priPct = ntohs(Byte2IntS(param, i)); i += 2; // 订货液位报警点: 0.01% if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.orderPct = ntohs(Byte2IntS(param, i)); i += 2; // 空液位报警点: 0.01% if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.emptyPct = ntohs(Byte2IntS(param, i)); i += 2; // 电压报警低点: mV if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.warnVolt = ntohs(Byte2IntS(param, i)); i += 2; // 电压报警高点: mV if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.warnVoltH = ntohs(Byte2IntS(param, i)); i += 2; // APN-User if(mask.ll & (1ull << (shift++))) strcpy(dcBuff.configDisplay.User, (char *) param + i); i += 10; // APN-Pwd if(mask.ll & (1ull << (shift++))) strcpy(dcBuff.configDisplay.Pwd, (char *) param + i); i += 10; // TTS-空液位报警点: 0.01% if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.floorLevel = ntohs(Byte2IntS(param, i)); i += 2; // TTS-变化量报警点: 0.01% if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.span = ntohs(Byte2IntS(param, i)); i += 2; // TTS-变化量检测时间: 秒 if(mask.ll & (1ull << (shift++))) dcBuff.configBottle.spanPeriod = ntohs(Byte2IntS(param, i)); i += 2; // 差压传感器量程: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorDPress.lowRange = ntohs(Byte2IntS(param, i)); i += 2; // 差压传感器量程: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorDPress.highRange = ntohs(Byte2IntS(param, i)); i += 2; // 差压传感器标定: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorDPress.zeroValue = ntohs(Byte2IntS(param, i)); i += 2; // 差压传感器标定: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorDPress.fullValue = ntohs(Byte2IntS(param, i)); i += 2; // 电容传感器量程: 底电容 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorCap.baseC = ntohs(Byte2IntS(param, i)); i += 2; // 电容传感器量程: 增长电容 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorCap.refC = ntohs(Byte2IntS(param, i)); i += 2; // 电容传感器标定: C1ADC if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorCap.c1ADC = ntohs(Byte2IntS(param, i)); i += 2; // 电容传感器标定: C2ADC if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorCap.c2ADC = ntohs(Byte2IntS(param, i)); i += 2; // 称重传感器量程: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorWeight.lowRange = ntohl(Byte2IntL(param, i)); i += 4; // 称重传感器量程: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorWeight.highRange = ntohl(Byte2IntL(param, i)); i += 4; // 称重传感器标定: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorWeight.zeroValue = ntohl(Byte2IntL(param, i)); i += 4; // 称重传感器标定: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorWeight.fullValue = ntohl(Byte2IntL(param, i)); i += 4; // 压力传感器1量程: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPress.lowRange = ntohs(Byte2IntS(param, i)); i += 2; // 压力传感器1量程: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPress.highRange = ntohs(Byte2IntS(param, i)); i += 2; // 压力传感器1标定: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPress.zeroValue = ntohs(Byte2IntS(param, i)); i += 2; // 压力传感器1标定: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPress.fullValue = ntohs(Byte2IntS(param, i)); i += 2; // 压力传感器2量程: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorEPress[0].lowRange = ntohs(Byte2IntS(param, i)); i += 2; // 压力传感器2量程: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorEPress[0].highRange = ntohs(Byte2IntS(param, i)); i += 2; // 压力传感器2标定: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorEPress[0].zeroValue = ntohs(Byte2IntS(param, i)); i += 2; // 压力传感器2标定: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorEPress[0].fullValue = ntohs(Byte2IntS(param, i)); i += 2; if(dcBuff.configDisplay.op_USE_PT100_SENSOR) { // 温度传感器1量程: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPTempr[0].calibrateT = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器1量程: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPTempr[0].calibrateR = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器1标定: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPTempr[0].zeroValue = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器1标定: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPTempr[0].fullValue = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器2量程: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPTempr[1].calibrateT = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器2量程: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPTempr[1].calibrateR = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器2标定: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPTempr[1].zeroValue = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器2标定: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorPTempr[1].fullValue = ntohs(Byte2IntS(param, i)); i += 2; } else { // 温度传感器1量程: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorMTempr[0].lowRange = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器1量程: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorMTempr[0].highRange = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器1标定: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorMTempr[0].zeroValue = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器1标定: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorMTempr[0].fullValue = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器2量程: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorMTempr[1].lowRange = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器2量程: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorMTempr[1].highRange = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器2标定: 低 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorMTempr[1].zeroValue = ntohs(Byte2IntS(param, i)); i += 2; // 温度传感器2标定: 高 if(mask.ll & (1ull << (shift++))) dcBuff.configSensor.sensorMTempr[1].fullValue = ntohs(Byte2IntS(param, i)); i += 2; } *reset = ((mask.ll & (1ull << shift)) != 0); return ((mask.ll & ~(1ull << shift)) != 0); } #define D048_CONFIG_SIZE (82) uint8_t parse_config_D048_data(uint8_t *param) { uint16_t i = 0; // 服务器版本 dcBuff.configBottle.serverVer = ntohs(Byte2IntS(param, i)); i += 2; // 远传服务器 strcpy(dcBuff.configData.server, (char *) param + i); i += 30; // 远传端口 dcBuff.configData.port = ntohs(Byte2IntS(param, i)); i += 2; // 远传服务器 strcpy(dcBuff.configData.gpsServer, (char *) param + i); i += 30; // 远传端口 dcBuff.configData.gpsPort = ntohs(Byte2IntS(param, i)); i += 2; // 发送频率 dcBuff.configData.intervalTrans = ntohl(Byte2IntL(param, i)); i += 4; // 采集频率 dcBuff.configData.intervalSample = ntohl(Byte2IntL(param, i)); i += 4; // 硬件版本 dcBuff.configDisplay.op_HARDWARE_VER_MAJOR = param[i++]; // 只显示毫米水柱 dcBuff.configDisplay.op_DISP_MMWC_ONLY = param[i++]; // 罐箱版本 dcBuff.configDisplay.op_BOX_VER = param[i++]; // 基站定位、不定位 dcBuff.configDisplay.op_CELL_LOCATION = param[i] & 1; dcBuff.configDisplay.op_NO_LOCATION = (param[i] >> 1) & 1; i++; // 发送轨迹 dcBuff.configDisplay.op_SEND_GPS_DATA = param[i++]; // 通信方式 dcBuff.configDisplay.op_SERVER_PROTOCOL = param[i++]; // URL索引 dcBuff.configDisplay.op_SERVER_INDEX = param[i++]; // 单向通信 dcBuff.configDisplay.op_UNIDIR_COMM = param[i++]; return 1; } // 从服务器获取时间 void DTU_setOffsetSecondsFromServer() { bluetooth_send_t *pRecv = (bluetooth_send_t *) Task_recvBuff; S_RTC_TIME_DATA_T sRTC; uint32_t totalSeconds1, totalSeconds2; int16_t zz; uint16_t i, recvLen; // 从服务器获取当前时间 printf("\nGet time from server ...\n"); // 连接升级服务器 if(DTU_Connect(0, dcBuff.configData.upgServer, dcBuff.configData.upgPort)) { memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // 填写固定字段 i = fill_biDir_fixFields(0xD03B, i); // 发送i个字节到服务器,至少接收10个字节 recvLen = sizeof(bluetooth_recv_t) + 2; if(DTU_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0) { if(recvLen >= sizeof(bluetooth_recv_t) + 11 && pRecv->cmd == ntohs(0x003B) && MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + 11) == 0) { // 获取当前时间 RTC_GetDateAndTime(&sRTC); totalSeconds1 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); // UTC日期 i = sizeof(bluetooth_recv_t); // 年 sRTC.u32Year = ntohs(Byte2IntS(Task_recvBuff, i)); i += 2; // 月 sRTC.u32Month = Task_recvBuff[i++]; // 日 sRTC.u32Day = Task_recvBuff[i++]; // 时 sRTC.u32Hour = Task_recvBuff[i++]; // 分 sRTC.u32Minute = Task_recvBuff[i++]; // 秒 sRTC.u32Second = Task_recvBuff[i++]; // 时差(按1/4小时, 带符号) recvLen = ntohs(Byte2IntS(Task_recvBuff, i)); memmove(&zz, &recvLen, 2); printf("\n%04d-%02d-%02d %02d:%02d:%02d %d\n", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second, zz); totalSeconds2 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); // 将UTC时间转换为GMT时间(时差为0) totalSeconds2 -= zz * 900; // 将GMT时间转换为UTC时间(按配置的时差) totalSeconds2 += dcBuff.configData.timeLag * 3600; if(RTC_offsetSeconds == 0) RTC_offsetSeconds = totalSeconds2 - totalSeconds1; } } } // 关闭和服务器的连接 DTU_Close(0); } } //////////////////////////////////////////////////////////////////////////////////////// // 任务主体:发送运行数据和GPS数据,读取网络信号强度等 void DTU_Task(void *p_arg) { bluetooth_send_t *pSend = (bluetooth_send_t *) Task_sendBuff; bluetooth_send_t *pRecv = (bluetooth_send_t *) Task_recvBuff; uint16_t i, j, k; uint8_t gpsCount, gpsDone; uint16_t gpsInterval; uint32_t totalSeconds; uint32_t relativeTime; S_RTC_TIME_DATA_T sRTC; gprs_data_t *pGprs; uint8_t try_count; uint16_t recvLen; uint8_t upgrade; uint8_t ackUpgrade; uint8_t downloadParam; uint8_t ackParam; uint8_t downloadConfig; uint8_t ackConfig; uint8_t reset = 0; param_data_t *pParam; TUpgradeHeader upHeader; upgrade_frame_t *pFrame; gps_data_t gps; uint16_t nextPtr; uint8_t write_count; uint8_t rf_fail_count = 0; uint8_t semSync, semGPRS, semGPS; uint8_t recentLocate; uint32_t tick; // 从FRAM读取阿里云密钥信息 FRAM_LoadInfo(FRAM_ALIYUN_SECRET_BASE, (uint8_t *) &aliyunSecret, sizeof(aliyunSecret)); // 从FRAM读取GPS信息 FRAM_LoadInfo(gpsBuff.info_base, (uint8_t *) &gpsBuff.info, sizeof(gpsBuff.info)); if(gpsBuff.info.rdPtr > gpsBuff.maxItemCount || gpsBuff.info.wtPtr > gpsBuff.maxItemCount) memset(&gpsBuff.info, 0, sizeof(gpsBuff.info)); // 船级社维持时间算法初始化 //CCS_Init(); // 清除数据 memset(&dcBuff.dtuData, 0, sizeof(dcBuff.dtuData)); // 读取其它板子的配置数据 // 启动定时器 GPS_tranTick = GetDelayTick(dcBuff.configData.intervalGPSTrans * 1000); if(dcBuff.configDisplay.op_BOX_VER) { // 检查是否有BD模块 BD_PowerOn(); BD_PowerOff(); } // // 检查是否有RF模块 // RF_PowerOn(); // RF_PowerOff(); if(RF_initStatus && dcBuff.configDisplay.op_LNG_LORA) RF_PowerOn(); // 打开槽车充液泵 if(dcBuff.configDisplay.op_SEND_GPS_DATA) KZ_PUMP_ON(); // 上电运行一次任务 DTU_semSync = 1; DTU_semGPRS = 1; DTU_semGPS = 1; while(1) { // 获取当前时间 RTC_GetDateAndTime(&sRTC); // 计算自上次gps定位以来的时间 totalSeconds = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); // 刚开始运行的时候,回退到刚启动的时间(忽略系统初始化时间) if(totalSeconds < 10) totalSeconds = 0; // 打开或关闭槽车的RF接收 if(dcBuff.configDisplay.op_SEND_GPS_DATA && RF_initStatus && !dcBuff.configDisplay.op_LNG_LORA) { if(VCC_POWER_STATUS()) RF_PowerOn(); else RF_PowerOff(); } // 槽车充液泵控制 if(dcBuff.configDisplay.op_SEND_GPS_DATA && !IS_PUMP_ON()) { // 等待30分钟,或者离开5分钟 if(totalSeconds >= Pump_Stop_Time + 1800 || (totalSeconds >= Pump_Stop_Time + 300 && rf_is_truck_leave())) KZ_PUMP_ON(); } // 读取信号量 semSync = DTU_semSync; DTU_semSync = 0; semGPRS = DTU_semGPRS; DTU_semGPRS = 0; semGPS = DTU_semGPS; DTU_semGPS = 0; // 本地显示:无4G模块 if(dcBuff.configDisplay.op_LOCAL_DISP) { if(semGPS || semSync) { // 先清除信号量 GPRS_semSampled = 0; // 采集数据 Sample_Notify(); tick = GetDelayTick(3000); while(!GPRS_semSampled && !IsTickOut(tick)) { } } // 休眠 Wakeup_Powerdown(); continue; } // 默认不保存、不发送 GPRS_Send_Task = 0; GPRS_Save_Task = 0; // 是否强制上传 if(DTU_dataConn) { DTU_dataConn = 0; GPRS_Send_Task = 1; } // 是否强制定位 if(GPS_Locate) { GPS_Locate = 0; // 强制定位:保存和发送 GPRS_Send_Task = 1; GPRS_Save_Task = 1; // 设置超时定时器 if(!dcBuff.configDisplay.op_NO_LOCATION) { GPS_waitTick = GetDelayTick(DTU_tmrLocate * 1000); GPS_Waiting = 1; } } // GPS发送周期:检查电池电量 if(semGPS || semSync) { delay_ms(200); // 先清除信号量 GPRS_semSampled = 0; // 采集数据 Sample_Notify(); tick = GetDelayTick(3000); while(!GPRS_semSampled && !IsTickOut(tick)) { } // 根据电量设置工作模式 Wakeup_SetWorkMode(); } // 检测唤醒同步信号 if(semGPRS || semSync) { printf("\n*** dcBuff.sampleData.warnning = %d ***\n", dcBuff.sampleData.warnning); if(dcBuff.sampleData.warnning) { GPRS_Send_Task = 1; dcBuff.sampleData.warnning = 0; } // 判断是否发送周期 // 如果发送时间到了,或者队列中的数据够了,则发送数据(为了工程测试方便,刚开始几次按照不大于5分钟的频率发送) if(dcBuff.configDisplay.op_SEND_GPS_DATA) { // 发送间隔最小值 if(totalSeconds + 3 >= GPRS_Send_Time + (dcBuff.configData.intervalTrans > 300 ? 300 : dcBuff.configData.intervalTrans)) GPRS_Send_Task = 1; } else { if(((SYS_RSTSTS & 0x13) && !(SYS_RSTSTS & 0x04) && // 上电或手动复位, 非看门狗复位 totalSeconds < INITIAL_TRAN_COUNT * (dcBuff.configData.intervalSample > 300 ? 300 : dcBuff.configData.intervalSample)) || totalSeconds + 3 >= GPRS_Send_Time + dcBuff.configData.intervalTrans // || LoopBuff_GetCount(&gprsBuff) >= dcBuff.configData.intervalTrans / dcBuff.configData.intervalSample - 1 ) ////// if(LoopBuff_GetCount(&gprsBuff) >= 11) { // 发送间隔最小值 if(totalSeconds + 3 >= GPRS_Send_Time + (dcBuff.configData.intervalTrans > 300 ? 300 : dcBuff.configData.intervalTrans)) GPRS_Send_Task = 1; } // else if(Config_CheckUpdate(&dcBuff)) // { // GPRS_Send_Task = 1; // } } // 判断是否保存周期 if(GPRS_Send_Task || totalSeconds + 3 >= GPRS_Save_Time + dcBuff.configData.intervalSample) GPRS_Save_Task = 1; if(GPRS_Send_Task && ((dcBuff.configDisplay.op_BOX_VER && (Motion_Detected || Motion_Status)) || (dcBuff.configDisplay.op_SEND_GPS_DATA && Wakeup_GetWorkMode() == WORK_MODE_NORMAL))) { GPS_Located = 0; // 设置超时定时器 if(!dcBuff.configDisplay.op_NO_LOCATION) { GPS_waitTick = GetDelayTick(DTU_tmrLocate * 1000); GPS_Waiting = 1; } } } // 运行数据发送周期:检测信号强度 if(semGPRS || semSync) { if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPRS_Send_Task) { delay_ms(200); // 打开DTU(开始定位) dcBuff.dtuData.networked = 0; if(RF_initStatus && dcBuff.configDisplay.op_BOX_VER && !dcBuff.configDisplay.op_LNG_LORA) { // 打开射频模块 RF_PowerOn(); // 检查中继器是否存在 rf_check_gateway(); // 关闭射频模块 RF_PowerOff(); } if(!rf_has_gateway() || GPS_Waiting || dcBuff.configDisplay.op_SEND_GPS_DATA) { DTU_PowerOn(); // 重新开始定位计时,保证足够定位时间 GPS_waitTick = GetDelayTick(DTU_tmrLocate * 1000); // 采集信号强度和注册信息 Sim808_ReadGPRS(); printf("\ndcBuff.dtuData.networked: %d\n", dcBuff.dtuData.networked); // 如果有GPRS但是信号很弱 if(rf_has_gateway() && dcBuff.dtuData.rssi < 30) dcBuff.dtuData.networked = 0; if(!dcBuff.dtuData.networked) dcBuff.dtuData.rssi = 0; } } // 每小时保存1条数据 if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPRS_Save_Task) { if(GPRS_Send_Task) { // GPRS拨号和GPS定位同时进行,以节省时间 if(dcBuff.dtuData.networked) Sim808_GPRSDial(); // 如果不发送轨迹数据,则等待定位完成再发送运行数据 recentLocate = (!dcBuff.configDisplay.op_SEND_GPS_DATA && Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPS_Waiting); while(!dcBuff.configDisplay.op_SEND_GPS_DATA && Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPS_Waiting) { delay_ms(200); } if(!dcBuff.configDisplay.op_SEND_GPS_DATA) { // 关闭GPS DTU_DisableGPS(); } // 获取基站定位数据 if(recentLocate) { if(DTU_model == DTU_MODEL_LIERDA && Sim808_GetCellLocPosition()) { dcBuff.dtuData.posState = 1; dcBuff.dtuData.recentPosState = 1; // 没有卫星定位或者卫星定位的坐标离基站太远(3000米),直接用基站定位坐标 if(!GPS_Located || GetDistance(dcBuff.dtuData.latitude, dcBuff.dtuData.longitude, DTU_latitude, DTU_longitude) >= 3000) { dcBuff.dtuData.longitude = DTU_longitude; dcBuff.dtuData.latitude = DTU_latitude; } } else if(!GPS_Located) dcBuff.dtuData.recentPosState = 0; } // 本次定位结束 GPS_Located = 1; // 下次有运动才定位(罐箱) Motion_Detected = 0; // 先清除信号量 GPRS_semSampled = 0; // 采集数据 Sample_Notify(); tick = GetDelayTick(3000); while(!GPRS_semSampled && !IsTickOut(tick)) { } // 记录本次发送的时间 GPRS_Send_Time = totalSeconds; } // 船级社维持时间计算 //CCS_Predict(); // 加入队列,待发送 printf("\nPut gprs data to queue...\n"); if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_CHAOYANG) LoopBuff_Clear(&gprsBuff); GPRS_PutToQueue(&gprsBuff, &dcBuff.dtuData, &dcBuff.sampleData); // 每条记录,北斗发送2次 if(BD_initStatus) { GPRS_PutToQueue(&bd_gprsBuff, &dcBuff.dtuData, &dcBuff.sampleData); GPRS_PutToQueue(&bd_gprsBuff, &dcBuff.dtuData, &dcBuff.sampleData); } // 记录本次保存的时间 GPRS_Save_Time = totalSeconds; } } // 用北斗发送数据 if(BD_initStatus && (semGPRS || semSync)) { // 每采集1条就发送1条 if(LoopBuff_GetCount(&bd_gprsBuff) > 0) { if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL) { // 打开北斗模块 BD_PowerOn(); if(BD_initStatus) { FRAM_BufferRead(LoopBuff_GetDataPos(&bd_gprsBuff, bd_gprsBuff.info.rdPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; // 打包上报数据(按北斗精简报文的格式) i = pack_bd_send_data(pGprs, totalSeconds); bd_rf_app_send_data(i, Task_sendBuff); delay_ms(200); } // 关闭北斗模块 BD_PowerOff(); } // 不管是否发送成功,都移除记录(因为1分钟发送一次,没有重发机制) LoopBuff_RemoveItems(&bd_gprsBuff, 1); } } // 优先用射频发送数据 if(rf_has_gateway() && (semGPRS || semSync)) { if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPRS_Send_Task) { // 关闭GPRS DTU_PowerOff(); // 打开射频模块 RF_PowerOn(); k = LoopBuff_GetCount(&gprsBuff); while(k--) { FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, gprsBuff.info.rdPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; // 打包上报数据(按RF精简报文的格式) i = pack_rf_send_data(pGprs, totalSeconds); try_count = 3; while(try_count--) { j = rf_app_send_data(i, Task_sendBuff); if(j == 1) { rf_fail_count = 0; LoopBuff_RemoveItems(&gprsBuff, 1); break; } } if(j == 0) { rf_fail_count++; if(rf_fail_count >= 3) { // 清除网关信息 rf_fail_count = 0; rf_clear_gateway(); } // 下次再来 break; } } // 关闭射频模块 RF_PowerOff(); } } // 如果没有卡,或者没有注册进网络,采集以后休眠 if(!dcBuff.dtuData.networked) { // 检查是否进入掉电模式 Wakeup_Powerdown(); continue; } // 检测发送采集数据的信号 if(semGPRS || semSync) { if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPRS_Send_Task) { // 是否下载参数:数据服务器 downloadParam = 0; ackParam = 0; if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_HTTPS) { try_count = 2; while((try_count--) && LoopBuff_GetCount(&gprsBuff) > 0) { // 第一条记录,连接就开始计数 if(LoopBuff_GetCount(&gprsBuff) > 0) dcBuff.powerInfo.gprsSendCount++; if(Sim808_Connect(1, dcBuff.configData.server, dcBuff.configData.port)) { nextPtr = gprsBuff.info.rdPtr; for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++) { if(k > 0) // 第一条发送计数在连接之前 dcBuff.powerInfo.gprsSendCount++; FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr); // 打包上报数据(按modbus从机响应的格式) i = pack_json_send_data(pGprs, totalSeconds); sprintf((char *) Task_sendBuff, http_header_fmt, SERVER_URLs[dcBuff.configDisplay.op_SERVER_INDEX], dcBuff.configData.server, i); //printf("\n\n%s%s\n", Task_sendBuff, JSON_data()); recvLen = 0; // 发送HTTP头,完了直接返回,不等结果 if(!Sim808_SendAndRecv(1, Task_sendBuff, strlen((char *) Task_sendBuff), &recvLen, Task_recvBuff, sizeof(Task_recvBuff))) break; recvLen = 15; // 发送数据,完了等结果 if(!Sim808_SendAndRecv(1, (uint8_t *) JSON_data(), i, &recvLen, Task_recvBuff, sizeof(Task_recvBuff))) break; printf("\n\n%s\n", Task_recvBuff); if(!strstr((char *) Task_recvBuff, "HTTP/1.1 200 OK")) { strcpy(dcBuff.powerInfo.gprsFailCode, "HTTP"); break; } dcBuff.powerInfo.gprsSuccCount++; // 最近一条上传数据的采集时间 DTU_dataTime = pGprs->sample_time; } // 移除已成功发送的数据 if(k > 0) LoopBuff_RemoveItems(&gprsBuff, k); // 关闭和服务器的连接 DTU_Close(1); } } } else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_MQTT) { // 检查阿里云密钥是否有效,如无效则下载 try_count = 2; while((try_count--) && (aliyunSecret.check != 0x55AA || memcmp(aliyunSecret.PSN, dcBuff.configBottle.PSN, 6) != 0)) { // 连接升级服务器 if(Sim808_Connect(0, dcBuff.configData.upgServer, dcBuff.configData.upgPort)) { printf("\nDownload aliyun secret ...\n"); memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 填写固定字段 i = fill_biDir_fixFields(0xD037, i); // 发送i个字节到服务器,至少接收10个字节 // 如果失败,下次再发送 recvLen = sizeof(bluetooth_recv_t) + 2; if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0) { if(recvLen >= sizeof(bluetooth_recv_t) + ALIYUN_SECRET_SIZE + 2 && pRecv->cmd == ntohs(0x0037) && MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + ALIYUN_SECRET_SIZE + 2) == 0) { // 保存参数 memmove(aliyunSecret.PSN, dcBuff.configBottle.PSN, 6); strcpy(aliyunSecret.product, (char *) Task_recvBuff + sizeof(bluetooth_recv_t)); strcpy(aliyunSecret.device, (char *) Task_recvBuff + sizeof(bluetooth_recv_t) + sizeof(aliyunSecret.product)); strcpy(aliyunSecret.secret, (char *) Task_recvBuff + sizeof(bluetooth_recv_t) + sizeof(aliyunSecret.product) + sizeof(aliyunSecret.device)); FRAM_SaveInfo(FRAM_ALIYUN_SECRET_BASE, (uint8_t *) &aliyunSecret, sizeof(aliyunSecret)); } } } \ // 关闭和服务器的连接 DTU_Close(0); } } try_count = 2; while((try_count--) && aliyunSecret.check == 0x55AA && memcmp(aliyunSecret.PSN, dcBuff.configBottle.PSN, 6) == 0 && LoopBuff_GetCount(&gprsBuff) > 0) { // 第一条记录,连接就开始计数 if(LoopBuff_GetCount(&gprsBuff) > 0) dcBuff.powerInfo.gprsSendCount++; if(Sim808_MqttConnect(SERVER_URLs[dcBuff.configDisplay.op_SERVER_INDEX], dcBuff.configData.port, aliyunSecret.product, aliyunSecret.device, aliyunSecret.secret)) { nextPtr = gprsBuff.info.rdPtr; for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++) { if(k > 0) // 第一条发送计数在连接之前 dcBuff.powerInfo.gprsSendCount++; FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr); // 打包上报数据(按modbus从机响应的格式) i = pack_gprs_send_data(pGprs, totalSeconds); if(!Sim808_MqttPublish(Task_sendBuff, i, aliyunSecret.product, aliyunSecret.device)) break; dcBuff.powerInfo.gprsSuccCount++; // 最近一条上传数据的采集时间 DTU_dataTime = pGprs->sample_time; } // 移除已成功发送的数据 if(k > 0) LoopBuff_RemoveItems(&gprsBuff, k); // 关闭和服务器的连接 MQTT_Close(); } } } else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_TCP) { try_count = 2; while((try_count--) && (LoopBuff_GetCount(&gprsBuff) > 0 // || Config_CheckUpdate(&dcBuff) || downloadParam || ackParam)) { // 第一条记录,连接就开始计数 if(LoopBuff_GetCount(&gprsBuff) > 0) dcBuff.powerInfo.gprsSendCount++; if(Sim808_Connect(0, dcBuff.configData.server, dcBuff.configData.port)) { // 普莱克斯、林德、宝钢的不再上传 if(dcBuff.configBottle.serverVer != 3 && dcBuff.configBottle.serverVer != 4 && dcBuff.configBottle.serverVer != 5 && !dcBuff.configDisplay.op_UNIDIR_COMM && Config_CheckUpdate(&dcBuff)) { printf("\nUpload parameters ...\n"); memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 参数时间戳 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts)); i += 4; // 打包参数 pParam = (param_data_t *) (Task_sendBuff + i); pack_param_DO23_data(pParam); i += sizeof(param_data_t); // 填写固定字段 i = fill_biDir_fixFields(0xD023, i); // 发送i个字节到服务器,至少接收10个字节 // 如果失败,下次再发送 recvLen = sizeof(bluetooth_recv_t) + 2; if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { if(recvLen >= sizeof(bluetooth_recv_t) + 2 && pRecv->cmd == ntohs(0x0023) && MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + 2) == 0) { // 清除更新标志,保存参数 dcBuff.configBottle.updateFlag = 0; Config_SaveConfig(); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi); } } else { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } } nextPtr = gprsBuff.info.rdPtr; for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++) { if(k > 0) // 第一条发送计数在连接之前 dcBuff.powerInfo.gprsSendCount++; FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr); // 打包上报数据(按modbus从机响应的格式) i = pack_gprs_send_data(pGprs, totalSeconds); recvLen = 2; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) break; dcBuff.powerInfo.gprsSuccCount++; // 最近一条上传数据的采集时间 DTU_dataTime = pGprs->sample_time; // 从GPRS切换到RF,需要重新搜索网关 rf_fail_count = 0; rf_clear_gateway(); if(!dcBuff.configDisplay.op_UNIDIR_COMM) { if(recvLen >= 2 && Task_recvBuff[0] == 0xFF && Task_recvBuff[1] == 0x0F) { // 普莱克斯、林德的不再下载 if(dcBuff.configBottle.serverVer != 3 && dcBuff.configBottle.serverVer != 4) downloadParam = 1; } } } // 移除已成功发送的数据 if(k > 0) LoopBuff_RemoveItems(&gprsBuff, k); // 下载参数 if(downloadParam) { printf("\nDownload parameters ...\n"); memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 宝钢版本:用D046替代D021, 因为服务器端没有完整的参数信息,只能修改个别参数 if(dcBuff.configBottle.serverVer == 5) { // 填写固定字段 i = fill_biDir_fixFields(0xD046, i); } else { // 参数时间戳 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts)); i += 4; // 填写固定字段 i = fill_biDir_fixFields(0xD021, i); } // 发送i个字节到服务器,至少接收10个字节 recvLen = sizeof(bluetooth_recv_t) + 2; if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0) { downloadParam = 0; if(recvLen >= sizeof(bluetooth_recv_t) + sizeof(param_data_t) + 2 && pRecv->cmd == ntohs(0x0021) && MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + sizeof(param_data_t) + 2) == 0) { // 解析参数 pParam = (param_data_t *) (Task_recvBuff + sizeof(bluetooth_recv_t)); parse_param_D021_data(pParam); // 清除更新标志, dcBuff.configBottle.updateFlag = 0; } else if(recvLen >= sizeof(bluetooth_recv_t) + D046_PARAM_SIZE + 2 && pRecv->cmd == ntohs(0x0046) && MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + D046_PARAM_SIZE + 2) == 0) { // 保存参数 parse_param_D046_data(Task_recvBuff + sizeof(bluetooth_recv_t), &reset); } // 保存参数 Config_SaveConfig(); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi); ackParam = 1; } } else { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } } // 确认参数 if(ackParam) { printf("\nConfirm download parameters ...\n"); // 发送确认 memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 参数时间戳 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts)); i += 4; // 填写固定字段 i = fill_biDir_fixFields(0xD022, i); // 发送i个字节到服务器,至少接收10个字节 // 如果失败,下次再发送 recvLen = sizeof(bluetooth_recv_t) + 2; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } ackParam = 0; } // 关闭和服务器的连接 DTU_Close(0); } } } else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_AOYANG) { try_count = 2; while((try_count--) && LoopBuff_GetCount(&gprsBuff) > 0) { // 第一条记录,连接就开始计数 if(LoopBuff_GetCount(&gprsBuff) > 0) dcBuff.powerInfo.gprsSendCount++; if(Sim808_Connect(0, dcBuff.configData.server, dcBuff.configData.port)) { nextPtr = gprsBuff.info.rdPtr; for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++) { if(k > 0) // 第一条发送计数在连接之前 dcBuff.powerInfo.gprsSendCount++; FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr); // 打包上报数据(按modbus从机响应的格式) i = pack_aoyang_send_data(pGprs, totalSeconds); printf("\ni=%d:%s\n", i, (char *) Task_sendBuff); recvLen = 7; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) break; dcBuff.powerInfo.gprsSuccCount++; // 最近一条上传数据的采集时间 DTU_dataTime = pGprs->sample_time; // 从GPRS切换到RF,需要重新搜索网关 rf_fail_count = 0; rf_clear_gateway(); } // 移除已成功发送的数据 if(k > 0) LoopBuff_RemoveItems(&gprsBuff, k); // 关闭和服务器的连接 DTU_Close(0); } } } else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_BRASIL) { try_count = 2; while((try_count--) && LoopBuff_GetCount(&gprsBuff) > 0) { // 第一条记录,连接就开始计数 if(LoopBuff_GetCount(&gprsBuff) > 0) dcBuff.powerInfo.gprsSendCount++; if(Sim808_Connect(0, dcBuff.configData.server, dcBuff.configData.port)) { nextPtr = gprsBuff.info.rdPtr; for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++) { if(k > 0) // 第一条发送计数在连接之前 dcBuff.powerInfo.gprsSendCount++; FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr); // 打包上报数据(按modbus从机响应的格式) i = pack_brasil_send_data(pGprs, totalSeconds); printf("\ni=%d:%s\n", i, (char *) Task_sendBuff); recvLen = 47; memset(Task_recvBuff, 0, sizeof(Task_recvBuff)); if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE - 1)) break; if(!parse_brasil_recv_data((char *) Task_recvBuff, pGprs, totalSeconds)) continue; if(save_brasil_issue_parameters()) { // 保存参数 Config_SaveConfig(); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi); } dcBuff.powerInfo.gprsSuccCount++; // 最近一条上传数据的采集时间 DTU_dataTime = pGprs->sample_time; // 从GPRS切换到RF,需要重新搜索网关 rf_fail_count = 0; rf_clear_gateway(); } // 移除已成功发送的数据 if(k > 0) LoopBuff_RemoveItems(&gprsBuff, k); // 关闭和服务器的连接 DTU_Close(0); } } } else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_FURUI || dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_HUIDA) { try_count = 2; while((try_count--) && LoopBuff_GetCount(&gprsBuff) > 0) { // 第一条记录,连接就开始计数 if(LoopBuff_GetCount(&gprsBuff) > 0) dcBuff.powerInfo.gprsSendCount++; if(Sim808_Connect(0, dcBuff.configData.server, dcBuff.configData.port)) { nextPtr = gprsBuff.info.rdPtr; for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++) { if(k > 0) // 第一条发送计数在连接之前 dcBuff.powerInfo.gprsSendCount++; FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr); // 打包上报数据(按modbus从机响应的格式) if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_FURUI) i = pack_furui_send_data(pGprs, &relativeTime); else i = pack_huida_send_data(pGprs, &relativeTime); printf("\nSend %d bytes to server:\n", i); for(j = 0; j < i; j++) printf("%02X ", Task_sendBuff[j]); printf("\n"); recvLen = 6; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) break; if((dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_FURUI && !parse_furui_recv_data(dcBuff.configBottle.PSN, relativeTime, recvLen)) || (dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_HUIDA && !parse_huida_recv_data(dcBuff.configBottle.PSN, relativeTime, recvLen))) { break; } dcBuff.powerInfo.gprsSuccCount++; // 最近一条上传数据的采集时间 DTU_dataTime = pGprs->sample_time; // 从GPRS切换到RF,需要重新搜索网关 rf_fail_count = 0; rf_clear_gateway(); } // 移除已成功发送的数据 if(k > 0) LoopBuff_RemoveItems(&gprsBuff, k); // 关闭和服务器的连接 DTU_Close(0); } } } else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_CHAOYANG) { try_count = 2; while((try_count--) && LoopBuff_GetCount(&gprsBuff) > 0) { // 第一条记录,连接就开始计数 if(LoopBuff_GetCount(&gprsBuff) > 0) dcBuff.powerInfo.gprsSendCount++; if(Sim808_Connect(0, dcBuff.configData.server, dcBuff.configData.port)) { nextPtr = gprsBuff.info.rdPtr; for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++) { if(k > 0) // 第一条发送计数在连接之前 dcBuff.powerInfo.gprsSendCount++; FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t)); pGprs = &gprsRWBuf; nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr); // 打包上报数据(按modbus从机响应的格式) i = pack_chaoyang_send_data(pGprs, &relativeTime); printf("\nSend %d bytes to server:\n", i); for(j = 0; j < i; j++) printf("%c", Task_sendBuff[j]); printf("\n"); recvLen = 0; // 服务器无应答 if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) break; dcBuff.powerInfo.gprsSuccCount++; // 最近一条上传数据的采集时间 DTU_dataTime = pGprs->sample_time; // 从GPRS切换到RF,需要重新搜索网关 rf_fail_count = 0; rf_clear_gateway(); } // 移除已成功发送的数据 if(k > 0) LoopBuff_RemoveItems(&gprsBuff, k); // 关闭和服务器的连接 DTU_Close(0); } } } // 是否连接维护平台:每隔12小时一次(普莱克斯、林德的每次连接) if(dcBuff.configBottle.serverVer == 3 || dcBuff.configBottle.serverVer == 4 || (!dcBuff.configDisplay.op_UNIDIR_COMM && (totalSeconds < INITIAL_TRAN_COUNT * (dcBuff.configData.intervalSample > 300 ? 300 : dcBuff.configData.intervalSample) || totalSeconds + 3 >= DTU_ldmsTime + 43200 || DTU_ldmsConn))) { // 清除强制连接维护平台标志 DTU_ldmsConn = 0; // 保存连接维护平台时间(刚复位时连续上传6次,但只保存第一次) if(totalSeconds >= 3600) DTU_ldmsTime = totalSeconds; // 是否升级或下载参数:维护平台 upgrade = 0; ackUpgrade = 0; downloadParam = 0; ackParam = 0; downloadConfig = 0; ackConfig = 0; reset = 0; k = 1; // 发送1条诊断信息 try_count = 2; while((try_count--) && (k || upgrade || ackUpgrade || downloadParam || ackParam || downloadConfig || ackConfig)) { // 连接升级服务器 if(Sim808_Connect(0, dcBuff.configData.upgServer, dcBuff.configData.upgPort)) { if(k) { // 发送诊断信息,至少接收12个字节 i = pack_ldms_info_Ext_data(DTU_dataTime, totalSeconds); recvLen = sizeof(bluetooth_recv_t) + 2 + 2; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } if(recvLen >= sizeof(bluetooth_recv_t) + 2 + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0 && pRecv->cmd == ntohs(0x0045)) { upgrade = Task_recvBuff[sizeof(bluetooth_recv_t)]; downloadParam = Task_recvBuff[sizeof(bluetooth_recv_t) + 1]; downloadConfig = Task_recvBuff[sizeof(bluetooth_recv_t) + 2]; k--; // 发送成功 } } // 下载参数 if(downloadParam) { printf("\nDownload parameters ...\n"); memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 填写固定字段 i = fill_biDir_fixFields(0xD046, i); // 发送i个字节到服务器,至少接收10个字节 recvLen = sizeof(bluetooth_recv_t) + 2; if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0) { downloadParam = 0; if(recvLen >= sizeof(bluetooth_recv_t) + D046_PARAM_SIZE + 2 && pRecv->cmd == ntohs(0x0046) && MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + D046_PARAM_SIZE + 2) == 0) { // 保存参数 if(parse_param_D046_data(Task_recvBuff + sizeof(bluetooth_recv_t), &reset)) { // 保存参数 Config_SaveConfig(); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DISPLAY_CONFIG, &display_modifi); } ackParam = 1; } } } else { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } } // 确认参数 if(ackParam) { printf("\nConfirm download parameters ...\n"); // 发送确认 memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 参数时间戳 Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts)); i += 4; // 填写固定字段 i = fill_biDir_fixFields(0xD022, i); // 发送i个字节到服务器,至少接收10个字节 // 如果失败,下次再发送 recvLen = sizeof(bluetooth_recv_t) + 2; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } ackParam = 0; } // 下载配置 if(downloadConfig) { printf("\nDownload configuration ...\n"); memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 填写固定字段 i = fill_biDir_fixFields(0xD048, i); // 发送i个字节到服务器,至少接收10个字节 recvLen = sizeof(bluetooth_recv_t) + 2; if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0) { downloadConfig = 0; if(recvLen >= sizeof(bluetooth_recv_t) + D048_CONFIG_SIZE + 2 && pRecv->cmd == ntohs(0x0048) && MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + D048_CONFIG_SIZE + 2) == 0) { // 保存参数 if(parse_config_D048_data(Task_recvBuff + sizeof(bluetooth_recv_t))) { // 保存参数 Config_SaveConfig(); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi); // Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DISPLAY_CONFIG, &display_modifi); } ackConfig = 1; } } } else { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } } // 确认配置 if(ackConfig) { printf("\nConfirm download configuration ...\n"); // 发送确认 memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 填写固定字段 i = fill_biDir_fixFields(0xD039, i); // 发送i个字节到服务器,至少接收10个字节 // 如果失败,下次再发送 recvLen = sizeof(bluetooth_recv_t) + 2; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } ackConfig = 0; // 配置改变,需要复位 reset = 1; } // 升级 if(upgrade) { printf("\nUpgrade software ...\n"); // 从FRAM读取初始进度 FRAM_LoadInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)); if(upInfo.fileSize == 0) { // 从头开始升级 memset(&upInfo, 0, sizeof(upInfo)); // 保存到铁电 for(write_count = 0; write_count < 2; write_count++) { FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)); if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo))) break; printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo)); delay_ms(200); } } // 下载数据 while(upInfo.fileSize == 0 || upInfo.offset < upInfo.fileSize) { memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 当前固件号 Int2ByteL(Task_sendBuff, i, htonl(upInfo.ver)); i += 4; // 文件偏移量 Int2ByteL(Task_sendBuff, i, htonl(upInfo.offset)); i += 4; // 请求数据长度 Int2ByteL(Task_sendBuff, i, htonl(UPGRADE_DATA_LEN)); i += 4; // 填写固定字段 i = fill_biDir_fixFields(0xD0E0, i); // 发送i个字节到服务器,至少接收10个字节 // 如果失败,下次再升级 recvLen = sizeof(bluetooth_recv_t) + 2; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) break; if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0) { if(pRecv->cmd == ntohs(0x00E0)) { pFrame = (upgrade_frame_t *) (Task_recvBuff + sizeof(bluetooth_recv_t)); if(MODBUS_RTU_CRC16(pFrame->data, ntohl(pFrame->len) + 2) == 0) { // 升级内容下载成功,允许继续升级 try_count = 2; // 如果升级包有变化 if(upInfo.fileSize > 0 && (upInfo.fileSize != ntohl(pFrame->fileSize) || upInfo.fileCrc != pFrame->fileCrc || upInfo.offset > ntohl(pFrame->fileSize) || upInfo.ver != ntohl(pFrame->ver))) { // 从头开始升级 memset(&upInfo, 0, sizeof(upInfo)); // 保存到铁电 for(write_count = 0; write_count < 2; write_count++) { FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)); if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo))) break; printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo)); delay_ms(200); } continue; } // 保存下载信息 // 如果只是网络通信失败,会断点续传 upInfo.ver = ntohl(pFrame->ver); upInfo.fileSize = ntohl(pFrame->fileSize); upInfo.offset = ntohl(pFrame->offset); upInfo.len = ntohl(pFrame->len); upInfo.fileCrc = pFrame->fileCrc; printf("\nfileSize = %d, offset = %d, len = %d\n", upInfo.fileSize, upInfo.offset, upInfo.len); // 如果是第一个包,先将升级请求改为0,以免意外重启导致boot-loader解压 // 待全部下载完以后,再改为1 if(upInfo.offset == 0) ((TUpgradeHeader *) pFrame->data)->upgrade_request = 0; #if UPGRADE_DATA_LEN >= SFLASH_ERASE_SIZE // 直接写入flash for(write_count = 0; write_count < 2; write_count++) { SFlash_BufferWrite(SFLASH_UPGRADE_BASE + upInfo.offset, pFrame->data, upInfo.len); if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + upInfo.offset, pFrame->data, upInfo.len)) break; printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + upInfo.offset, upInfo.len); delay_ms(200); } upInfo.offset += upInfo.len; #else // 为了减少flash的多次擦写,又节约收发缓冲 // 先把数据拷到flash页缓冲 for(write_count = 0; write_count < 2; write_count++) { FRAM_BufferWrite(FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, pFrame->data, upInfo.len); if(FRAM_BufferVerify(FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, pFrame->data, upInfo.len)) break; printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, upInfo.len); delay_ms(200); } upInfo.offset += upInfo.len; // 够一页了,或者下载完了就从铁电写入flash if(upInfo.offset % SFLASH_ERASE_SIZE == 0) { FRAM_BufferRead(FRAM_UPGRADE_DATA_BASE, Task_recvBuff, SFLASH_ERASE_SIZE); for(write_count = 0; write_count < 2; write_count++) { SFlash_BufferWrite(SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), Task_recvBuff, SFLASH_ERASE_SIZE); if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), Task_recvBuff, SFLASH_ERASE_SIZE)) break; printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), SFLASH_ERASE_SIZE); delay_ms(200); } } else if(upInfo.offset == upInfo.fileSize) { FRAM_BufferRead(FRAM_UPGRADE_DATA_BASE, Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE); for(write_count = 0; write_count < 2; write_count++) { SFlash_BufferWrite(SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE); if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE)) break; printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), upInfo.offset % SFLASH_ERASE_SIZE); delay_ms(200); } } #endif for(write_count = 0; write_count < 2; write_count++) { // 保存到铁电 FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)); if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo))) break; printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo)); delay_ms(200); } } } else // 命令返回错误 { // 取消本次升级 upInfo.fileSize = 0; // 保存到铁电 for(write_count = 0; write_count < 2; write_count++) { FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)); if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo))) break; printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo)); delay_ms(200); } upgrade = 0; break; } } } if(upInfo.fileSize > 0 && upInfo.offset == upInfo.fileSize) { SFlash_BufferRead(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader)); // 将升级请求改为1 upHeader.upgrade_request = 1; if(upHeader.check == 0x55AA && do_crc_16(0, (uint8_t *) &upHeader, sizeof(upHeader)) == 0 && do_sflash_crc(SFLASH_UPGRADE_BASE + sizeof(upHeader), upHeader.upgrade_length) == 0) { // 校验通过 printf("\nUpgrade package confirm passed\n"); // 发送确认 ackUpgrade = 1; } else { // 校验未通过 printf("\n****** Upgrade package confirm failed\n"); // 从头开始 upInfo.fileSize = 0; // 保存到铁电 for(write_count = 0; write_count < 2; write_count++) { FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)); if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo))) break; printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo)); delay_ms(200); } } } else { // 关闭和服务器的连接 DTU_Close(0); // 继续 continue; } } // 确认升级成功 if(ackUpgrade) { printf("\nConfirm upgrade software ...\n"); // 发送确认 memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 当前固件号 Int2ByteL(Task_sendBuff, i, htonl(upInfo.ver)); i += 4; // 固件的CRC16 Int2ByteS(Task_sendBuff, i, upInfo.fileCrc); i += 2; // 填写固定字段 i = fill_biDir_fixFields(0xD0E1, i); // 发送i个字节到服务器,至少接收10个字节 // 如果失败,下次再发送 recvLen = sizeof(bluetooth_recv_t) + 2; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) { // 关闭和服务器的连接 DTU_Close(0); // 重连 continue; } if(recvLen == sizeof(bluetooth_recv_t) + 2 && pRecv->cmd == ntohs(0x00E1)) { // 将升级请求改为1 SFlash_BufferRead(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader)); upHeader.upgrade_request = 1; for(write_count = 0; write_count < 2; write_count++) { SFlash_BufferWrite(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader)); if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader))) break; printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE, sizeof(upHeader)); delay_ms(200); } // 下次再升级从头开始 upInfo.fileSize = 0; // 保存到铁电 for(write_count = 0; write_count < 2; write_count++) { FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)); if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo))) break; printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo)); delay_ms(200); } // 关闭和服务器的连接 DTU_Close(0); // 关闭DTU电源 VCC_GSM_OFF(); delay_ms(200); // 将LDROM映射到地址0x0 // FMC_Open(); // FMC_SetVectorPageAddr(LDROM_BASE); // FMC_Close(); // 复位以后执行Bootloader,将升级包解压 //WDT_Close(); // 先关看门狗,免得bootloader复位 NVIC_SystemReset(); } } // 关闭和服务器的连接 DTU_Close(0); // 确认参数以后才执行复位命令(避免反复复位) if(reset && !ackParam) { VCC_GSM_OFF(); delay_ms(200); NVIC_SystemReset(); } } } } } // 刚处理完,清除等待的信号。等下一个周期再执行(如果有报警必须立即上传) if(dcBuff.sampleData.warnning == 0) DTU_semGPRS = 0; } // 检测发送GPS定位信号 if(semGPS || semSync) { if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL) { if(dcBuff.configDisplay.op_SEND_GPS_DATA && Sim808_Connect(0, dcBuff.configData.gpsServer, dcBuff.configData.gpsPort)) { // 如果有待发送数据 do { // 根据发送缓冲区的大小,决定一次最多发几条数据 // 每条记录占12个字节,另外有24个字节的固定字段,比如头信息、PSN、crc等 // 如果没有合法的记录,发送一条空记录 gpsCount = GPS_LookData((TASK_SENDBUFF_SIZE - 24) / 12, &gpsInterval, &gpsDone); if(gpsCount > 0) { nextPtr = gpsBuff.info.rdPtr; FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, nextPtr), (uint8_t *) &gps, sizeof(gps_data_t)); } memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE); i = sizeof(bluetooth_send_t); // PSN memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6); i += 6; // 坐标个数 if(gpsCount > 0) Int2ByteS(Task_sendBuff, i, htons(gpsCount)); else Int2ByteS(Task_sendBuff, i, htons(1)); i += 2; // 起始时间戳 if(gpsCount > 0) Int2ByteL(Task_sendBuff, i, htonl(gps.time.tm)); i += 4; // 时间戳增量 if(gpsCount > 0) Int2ByteS(Task_sendBuff, i, htons(gpsInterval)); i += 2; for(j = 0; j < (gpsCount ? gpsCount : 1); j++) { // 状态 if(gpsCount > 0) Task_sendBuff[i] = gps.state; else { // 车辆是否启动(根据充电状态决定) if(VCC_POWER_STATUS()) Task_sendBuff[i] |= (1 << 6); // 车辆启动状态是否改变) Task_sendBuff[i] |= (bat_CurrentEvent << 7); bat_CurrentEvent = 0; } i++; // 保留 i++; // 经度 if(gpsCount > 0) Int2ByteL(Task_sendBuff, i, htonl(gps.longitude)); i += 4; // 纬度 if(gpsCount > 0) Int2ByteL(Task_sendBuff, i, htonl(gps.latitude)); i += 4; // 速度 if(gpsCount > 0) Int2ByteS(Task_sendBuff, i, htons(gps.speed * 100)); i += 2; nextPtr = LoopBuff_GetNextPtr(&gpsBuff, nextPtr); FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, nextPtr), (uint8_t *) &gps, sizeof(gps_data_t)); } // 填写固定字段 i = fill_biDir_fixFields(0xD010, i); // 发送i个字节到服务器,至少接收10个字节 // 如果失败,下次再发送 recvLen = sizeof(bluetooth_recv_t) + 2; if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE)) break; if(gpsCount > 0) { // 将这几条记录移除 GPS_MoveFromQueue(gpsCount); if(gpsDone) { GPS_Located = 1; // 停止超时定时器 GPS_Waiting = 0; } } } while(!gpsDone); } // 无论如何,关闭和服务器的连接 DTU_Close(0); // 刚处理完,清除等待的信号。等下一个周期再执行 DTU_semGPS = 0; } } if(semSync) { // 刚处理完,清除等待的信号。等下一个周期再执行 DTU_semSync = 0; } // 检查是否进入掉电模式 Wakeup_Powerdown(); } }