MS-DTU/Anjiehui7_TTS_ST_V2.4_LOCAL/User/uart_dtu.c

5306 lines
160 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*********************************************************************************************************
* 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();
}
}