#include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include #include "GPIOControl.h" #include "SerialComm.h" #include #include #include "AndroidHelper.h" #include "SensorsProtocol.h" //#include "Eint.h" #include pthread_mutex_t serial_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁 pthread_mutex_t camera_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁 pthread_mutex_t bd_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁 SIO_PARAM_SERIAL_DEF serialport[MAX_SERIAL_PORT_NUM]; SERIAL_PARAM devparam[MAX_SERIAL_DEV_NUM]; SRDT_DEF srdt; AI_DEF weatherpntmsg[WEATHER_DATA_NUM]; AI_DEF rallypntmsg[6][RALLY_DATA_NUM]; AI_DEF slantpntmsg[6][SLANTANGLE_DATA_NUM]; char logPath[512]; extern int Gm_SetSerialPortParam(int commid); static speed_t getBaudrate(unsigned int baudrate) { switch (baudrate) { case 0: return B0; case 50: return B50; case 75: return B75; case 110: return B110; case 134: return B134; case 150: return B150; case 200: return B200; case 300: return B300; case 600: return B600; case 1200: return B1200; case 1800: return B1800; case 2400: return B2400; case 4800: return B4800; case 9600: return B9600; case 19200: return B19200; case 38400: return B38400; case 57600: return B57600; case 115200: return B115200; case 230400: return B230400; case 460800: return B460800; case 500000: return B500000; case 576000: return B576000; case 921600: return B921600; case 1000000: return B1000000; case 1152000: return B1152000; case 1500000: return B1500000; case 2000000: return B2000000; case 2500000: return B2500000; case 3000000: return B3000000; case 3500000: return B3500000; case 4000000: return B4000000; default: return B9600; } } static int64_t get_msec() { struct timeval tv; int64_t time_in_msec = 0; gettimeofday(&tv, NULL); time_in_msec = tv.tv_sec; time_in_msec *= 1000; time_in_msec += tv.tv_usec / 1000; return time_in_msec; } /* 打开串口电源 */ void Gm_OpenSerialPower() { /*由传送的主站的地方来控制串口电源,这里不实现*/; } // 关闭串口电源 void Gm_CloseSerialPower() { } // 关闭传感器电源 void Gm_CloseSensorsPower() { //char iIoNo; //char szbuf[128]; int igpio; //sprintf(szbuf, "Close Sensors port %d Power!", port); /* 关闭电源*/ //switch(port) /* 根据硬件具体布置最后调整,目前是微拍板子的来控制*/ } // 打开传感器电源 void Gm_OpenSensorsPower() { } // 查询传感器电源状态 char Gm_GetSensorsPowerState(int port) { char iIoNo, cstate = 0; //char szbuf[128]; /* 查询电源状态*/ //switch(port) return cstate; } void BytestreamLOG(int commid, char* describe, u_char* buf, int len, char flag) { int i; char szbuf[8192]; memset(szbuf, 0, sizeof(szbuf)); if (NULL != describe) strncpy(szbuf, describe, strlen(describe)); for (i = 0; i < len; i++) { ::sprintf(szbuf, "%s %02X", szbuf, buf[i]); } SaveLogTofile(commid, szbuf); switch (flag) { case 'E': ALOGE("%s", szbuf); break; case 'I': ALOGI("%s", szbuf); break; case 'D': ALOGD("%s", szbuf); break; case 'V': ALOGI("%s", szbuf); break; case 'W': ALOGW("%s", szbuf); break; default: ALOGI("%s", szbuf); break; } } // 打开串口通讯 void Gm_OpenSerialPort(int devidx) { int fd = -1; char szbuf[512]; if ((devidx < 0) || (devidx >= MAX_SERIAL_DEV_NUM)) return; memset(szbuf, 0, sizeof(szbuf)); if (serialport[devparam[devidx].commid].fd <= 0) { fd = ::open(devparam[devidx].pathname, O_RDWR | O_NDELAY); if (fd < 0) { sprintf(szbuf, "装置%d 打开串口%d %s失败!fd=%d", devidx+1, devparam[devidx].commid+1, devparam[devidx].pathname, fd); DebugLog(devparam[devidx].commid, szbuf, 'E'); return; } sprintf(szbuf, "装置%d 打开串口%d %s成功!fd=%d", devidx + 1, devparam[devidx].commid + 1, devparam[devidx].pathname, fd); DebugLog(devparam[devidx].commid, szbuf, 'I'); serialport[devparam[devidx].commid].fd = fd; Gm_SetSerialPortParam(devparam[devidx].commid); return; } sprintf(szbuf, "装置%d 串口%d %s已经打开!fd=%d", devidx + 1, devparam[devidx].commid + 1, devparam[devidx].pathname, serialport[devparam[devidx].commid].fd); DebugLog(devparam[devidx].commid, szbuf, 'I'); } // 关闭串口通讯 void Gm_CloseSerialPort() { int i; for (i = 1; i < MAX_SERIAL_PORT_NUM; i++) { if (serialport[i].fd > 0) { close(serialport[i].fd); serialport[i].fd = -1; } } } /******************************************************************************* 函数名称: int GM_SerialComSend(const uint8_t * cSendBuf, uint32_t nSendLen, int commid) 功能说明:串口发送数据 返回实际发送的字节数 输入参数: 输出参数: 其它说明: *********************************************************************************/ int GM_SerialComSend(unsigned char * cSendBuf, size_t nSendLen, int commid) { int i, len; char szbuf[512]; memset(szbuf, 0, sizeof(szbuf)); len = write(serialport[commid].fd, cSendBuf, (size_t)nSendLen);/* 向串囗发送字符串 */ //serialport[commid].RevCmdFlag = 0; //LOGE("发送命令时间差%ld毫秒", get_msec() - isendtime); //isendtime = time(NULL); //isendtime = get_msec(); if (len < 0) { sprintf(szbuf, "write data error "); DebugLog(commid, szbuf, 'E'); return -1; } else if (len > 0) { ; } return len; } int Gm_SetSerialPortParam(int commid) { int ret; char szbuf[128]; SERIAL_PARAM *pPortParam = NULL; pPortParam = &devparam[srdt.curdevidx[commid]]; ret = set_port_attr(serialport[commid].fd, pPortParam->baudrate, pPortParam->databit, pPortParam->stopbit, pPortParam->parity, 0, 0);/*9600 8n1 */ if (ret < 0) { memset(szbuf, 0, sizeof(szbuf)); sprintf(szbuf, "串口%d 波特率等参数设置错误!", commid + 1); DebugLog(commid, szbuf, 'E'); return -1; } return ret; } void Gm_InitSerialComm_Test() { int i, j; SENSOR_PARAM sensorParam[MAX_SERIAL_DEV_NUM]; #if 0 srdt.PtzCmdType = Cmd_Cancel; // 云台指令类型 for (i = 0; i < MAX_SERIAL_PORT_NUM; i++) { //***************** 串行端口信息 ************************ //g_serialparam[i].Baud = 1200; //g_serialparam[i].dataBits = 8; //g_serialparam[i].stopBits = 1; //g_serialparam[i].parity = 0; //******************** Poll Cmd **************************** serialport[i].Retry = 0; //serialport[i].RetryTime = 500/TIMER_CNT; j = TIMER_CNT; serialport[i].RetryTime = 300 / TIMER_CNT; j = 1500 / TIMER_CNT; serialport[i].WaitTime = 0; memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 ClearCmdFormPollCmdBuf(i); } //g_serialparam[1].Baud = 1200; for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) devparam[i].IsNoInsta = 0; #endif //if(NULL == sensorParam) // return; memset(sensorParam, 0, sizeof(sensorParam)); //#if COLLECT_DATA sensorParam[0].SensorsType = WEATHER_PROTOCOL; sensorParam[0].baudrate = 9600; sensorParam[0].databit = 8; //memset(devparam[0].stopbit, 0, sizeof(devparam[0].stopbit)); //sprintf(devparam[0].stopbit, "1"); sensorParam[0].stopbit = 1; sensorParam[0].parity = 'n'; sensorParam[0].IsNoInsta = 1; sensorParam[0].devaddr = 4; memset(sensorParam[0].pathname, 0, sizeof(sensorParam[0].pathname)); strcpy(sensorParam[0].pathname, "/dev/ttysWK3"); sensorParam[1].SensorsType = WEATHER_PROTOCOL; sensorParam[1].baudrate = 9600; sensorParam[1].databit = 8; //memset(devparam[1].stopbit, 0, sizeof(devparam[1].stopbit)); //sprintf(devparam[1].stopbit, "1"); sensorParam[1].stopbit = 1; sensorParam[1].parity = 0; sensorParam[1].IsNoInsta = 1; sensorParam[1].devaddr = 1; memset(sensorParam[1].pathname, 0, sizeof(sensorParam[1].pathname)); strcpy(sensorParam[1].pathname, "/dev/ttysWK3"); sensorParam[2].SensorsType = RALLY_PROTOCOL; sensorParam[2].baudrate = 9600; sensorParam[2].databit = 8; //memset(devparam[2].stopbit, 0, sizeof(devparam[2].stopbit)); //sprintf(devparam[2].stopbit, "1"); sensorParam[2].stopbit = 1; sensorParam[2].parity = 0; sensorParam[2].IsNoInsta = 1; //sensorParam[2].PowerPort = 3; //sensorParam[2].devaddr = 13; sensorParam[2].devaddr = 13; memset(sensorParam[2].pathname, 0, sizeof(sensorParam[2].pathname)); strcpy(sensorParam[2].pathname, "/dev/ttysWK1"); sensorParam[5].SensorsType = RALLY_PROTOCOL; sensorParam[5].baudrate = 9600; sensorParam[5].databit = 8; //memset(devparam[2].stopbit, 0, sizeof(devparam[2].stopbit)); //sprintf(devparam[2].stopbit, "1"); sensorParam[5].stopbit = 1; sensorParam[5].parity = 0; sensorParam[5].IsNoInsta = 1; sensorParam[5].devaddr = 10; memset(sensorParam[5].pathname, 0, sizeof(sensorParam[3].pathname)); strcpy(sensorParam[5].pathname, "/dev/ttysWK1"); sensorParam[4].SensorsType = RALLY_PROTOCOL; sensorParam[4].baudrate = 9600; sensorParam[4].databit = 8; //memset(devparam[2].stopbit, 0, sizeof(devparam[2].stopbit)); //sprintf(devparam[2].stopbit, "1"); sensorParam[4].stopbit = 1; sensorParam[4].parity = 0; sensorParam[4].IsNoInsta = 1; //sensorParam[2].PowerPort = 3; //sensorParam[2].devaddr = 13; sensorParam[4].devaddr = 12; memset(sensorParam[4].pathname, 0, sizeof(sensorParam[4].pathname)); strcpy(sensorParam[4].pathname, "/dev/ttysWK1"); sensorParam[6].SensorsType = SLANT_PROTOCOL; sensorParam[6].baudrate = 9600; sensorParam[6].databit = 8; //memset(devparam[13].stopbit, 0, sizeof(devparam[13].stopbit)); //sprintf(devparam[13].stopbit, "1"); sensorParam[6].stopbit = 1; sensorParam[6].parity = 0; //devparam[13].PowerPort = 4; sensorParam[6].IsNoInsta = 1; sensorParam[6].devaddr = 2; memset(sensorParam[6].pathname, 0, sizeof(sensorParam[6].pathname)); strcpy(sensorParam[6].pathname, "/dev/ttysWK0"); sensorParam[7].SensorsType = SLANT_PROTOCOL; sensorParam[7].baudrate = 9600; sensorParam[7].databit = 8; //memset(devparam[13].stopbit, 0, sizeof(devparam[13].stopbit)); //sprintf(devparam[13].stopbit, "1"); sensorParam[7].stopbit = 1; sensorParam[7].parity = 0; //devparam[13].PowerPort = 4; sensorParam[7].IsNoInsta = 1; sensorParam[7].devaddr = 3; memset(sensorParam[7].pathname, 0, sizeof(sensorParam[7].pathname)); strcpy(sensorParam[7].pathname, "/dev/ttysWK0"); sensorParam[13].SensorsType = SLANT_PROTOCOL; sensorParam[13].baudrate = 9600; sensorParam[13].databit = 8; //memset(devparam[13].stopbit, 0, sizeof(devparam[13].stopbit)); //sprintf(devparam[13].stopbit, "1"); sensorParam[13].stopbit = 1; sensorParam[13].parity = 0; //devparam[13].PowerPort = 4; sensorParam[13].IsNoInsta = 1; sensorParam[13].devaddr = 5; memset(sensorParam[13].pathname, 0, sizeof(sensorParam[13].pathname)); strcpy(sensorParam[13].pathname, "/dev/ttysWK0"); #if 0 devparam[14].ProtocolIdx = SLANT_PROTOCOL; devparam[14].baudrate = 1200; devparam[14].databit = 8; devparam[14].stopbit = 1; devparam[14].parity = 0; devparam[14].IsNoInsta = 1; //devparam[14].PowerPort = 2; devparam[14].devaddr = 3; devparam[15].ProtocolIdx = LEIRALLY_PROTOCOL; //#endif devparam[15].ProtocolIdx = WIND_PROTOCOL; devparam[15].baudrate = 9600; devparam[15].databit = 8; devparam[15].stopbit = 1; devparam[15].parity = 0; devparam[15].IsNoInsta = 1; devparam[15].PowerPort = 14; devparam[15].devaddr = 1; #endif //#else sensorParam[3].SensorsType = PELCO_D_PROTOCOL; sensorParam[3].baudrate = 38400; sensorParam[3].databit = 8; sensorParam[3].stopbit = 1; sensorParam[3].parity = 0; sensorParam[3].IsNoInsta = 1; //devparam[3].PowerPort = 15; sensorParam[3].CameraChannel = 1; sensorParam[3].devaddr = 0; memset(sensorParam[3].pathname, 0, sizeof(sensorParam[3].pathname)); strcpy(sensorParam[3].pathname, "/dev/ttyS1"); //#endif Gm_InitSerialComm(sensorParam, "/sdcard/photo/",logPath); } uint8_t getdevtype(int devno) { return devparam[devno].ProtocolIdx; } // 初始化所有串口及所接传感器的配置 void Gm_InitSerialComm(SENSOR_PARAM *sensorParam, const char *filedir,const char *log) { int i; char szbuf[128]; memset(logPath,0, sizeof(logPath)); strcpy(logPath, log); for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) { memset(&devparam[i], 0, sizeof(SERIAL_PARAM)); memset(&srdt, 0, sizeof(srdt)); srdt.camerauseserial = -1; } for (i = 0; i < MAX_SERIAL_PORT_NUM; i++) { memset(&serialport[i], 0, sizeof(SIO_PARAM_SERIAL_DEF)); serialport[i].fd = -1; serialport[i].lsendtime = get_msec(); } if (NULL == sensorParam) return; //memset(sensorParam, 0, sizeof(sensorParam)); //Gm_InitSerialComm_Test(sensorParam); for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) { devparam[i].IsNoInsta = sensorParam[i].IsNoInsta; if (0 == sensorParam[i].IsNoInsta) continue; devparam[i].ProtocolIdx = sensorParam[i].SensorsType; devparam[i].devaddr = sensorParam[i].devaddr; devparam[i].baudrate = getBaudrate(sensorParam[i].baudrate); memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname)); memmove(devparam[i].pathname, sensorParam[i].pathname, sizeof(devparam[i].pathname)); devparam[i].databit = sensorParam[i].databit; devparam[i].stopbit = (int)(sensorParam[i].stopbit * 10); devparam[i].CameraChannel = sensorParam[i].CameraChannel; devparam[i].Phase = sensorParam[i].Phase; } #if 1 //******************** 端口基本信息 ************************ for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) { memset(szbuf, 0, sizeof(szbuf)); switch (sensorParam[i].SensorsType) { case 0: sprintf(szbuf, "传感器%d没有接!", i + 1); break; case WEATHER_PROTOCOL: sprintf(szbuf, "传感器%d接的是气象传感器!", i + 1); break; case SERIALCAMERA_PROTOCOL: sprintf(szbuf, "传感器%d接的是串口摄像机!", i + 1); break; case PELCO_P_PROTOCOL: sprintf(szbuf, "传感器%d接的是PELCO_P摄像机!", i + 1); break; case SLANT_PROTOCOL: sprintf(szbuf, "传感器%d接的是倾角!", i + 1); break; case WIND_PROTOCOL: sprintf(szbuf, "传感器%d接的是风速风向传感器", i + 1); break; case RALLY_PROTOCOL: sprintf(szbuf, "传感器%d接的是拉力!", i + 1); break; case PELCO_D_PROTOCOL: sprintf(szbuf, "传感器%d接的是PELCO_D摄像机!", i + 1); break; case RESERVE5_PROTOCOL: sprintf(szbuf, "传感器%d接的是加密芯片", i + 1); break; case MUTIWEATHER_PROTOCOL: sprintf(szbuf, "传感器%d接的是多合一气象传感器", i + 1); break; default: sprintf(szbuf, "传感器%d没有接!", i + 1); break; } sprintf(szbuf, "%s 地址%d!;", szbuf, sensorParam[i].devaddr); if (0 == sensorParam[i].IsNoInsta) sprintf(szbuf, "%s", "没有启用!;"); else { sprintf(szbuf, "%s 已启用!;", szbuf); DebugLog(8, szbuf, 'I'); } } if (NULL == filedir) return; memset(srdt.filedir, 0, sizeof(srdt.filedir)); memmove(srdt.filedir, filedir, std::min(sizeof(srdt.filedir), strlen(filedir))); FindDevUseSerialCommNo(); #if 0 //Collect_sensor_data(); //#else for (;;) { CameraPhotoCmd(sensorParam, 1, 0, 6, 1); sleep(5); //CameraPhotoCmd(sensorParam, 1, 10017, 0, 1); //sleep(5); //CameraPhotoCmd(sensorParam, 1, MOVE_LEFT, 0, 0); //sleep(5); //CameraPhotoCmd(sensorParam, 1, MOVE_DOWN, 0, 0); //sleep(5); //CameraPhotoCmd(sensorParam, 1, MOVE_RIGHT, 0, 0); //sleep(5); //CameraPhotoCmd(sensorParam, 1, MOVE_UP, 0, 0); //sleep(5); //CameraPhotoCmd(sensorParam, 1, 10017, 0, 2); //sleep(5); //CameraPhotoCmd(sensorParam, 1, ZOOM_TELE, 0, 0); //sleep(5); //CameraPhotoCmd(sensorParam, 1, ZOOM_WIDE, 0, 0); //sleep(5); } #endif #endif } void testComm() { int i; char szbuf[128]; //SENSOR_PARAM sensorParam[MAX_SERIAL_DEV_NUM]; //memset(sensorParam, 0, sizeof(sensorParam)); Gm_InitSerialComm_Test(); for (;;) { #if COLLECT_DATA Collect_sensor_data(); #else sleep(15); CameraPhotoCmd(time(NULL), 1, 0, 6, 1, "/dev/ttyS0",38400, 1); sleep(5); CameraPhotoCmd(time(NULL), 1, MOVE_PRESETNO, 0, 2, "/dev/ttyS1",38400, 1); sleep(5); CameraPhotoCmd(0, 1, MOVE_LEFT, 0, 0, "/dev/ttyS1",38400, 1); sleep(5); CameraPhotoCmd(0, 1, MOVE_DOWN, 0, 0, "/dev/ttyS1",38400, 1); sleep(5); CameraPhotoCmd(0, 1, MOVE_RIGHT, 0, 0, "/dev/ttyS1",38400, 1); sleep(5); CameraPhotoCmd(0, 1, MOVE_UP, 0, 0, "/dev/ttyS1",38400, 1); sleep(5); CameraPhotoCmd(0, 1, MOVE_PRESETNO, 0, 1, "/dev/ttyS1",38400, 1); sleep(5); sleep(5); //CameraPhotoCmd(0, 1, ZOOM_WIDE, 0, 0); //sleep(5); //CameraPhotoCmd(time(NULL), 1, 0, 6, 2); //sleep(5); #endif } #if 1 //******************** 端口基本信息 ************************ /*for(i=0; i*/ //sprintf(devparam[i].pathname, "/dev/swk3"); devparam[i].commid = 3; break; case SLANT_PROTOCOL: //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname)); /* 目前还不确定具体串口分配,暂时默认使用串口1*/ //sprintf(devparam[i].pathname, "/dev/swk2"); devparam[i].commid = 2; break; case RALLY_PROTOCOL: //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname)); /* 目前还不确定具体串口分配,暂时默认使用串口1*/ //sprintf(devparam[i].pathname, "/dev/swk1"); devparam[i].commid = 1; break; case PELCO_D_PROTOCOL: /* 摄像机协议*/ case PELCO_P_PROTOCOL: /* 摄像机协议*/ case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/ //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname)); /* 目前还不确定//具体串口分配,暂时默认使用串口1*/ //sprintf(devparam[i].pathname, "/dev/ttyS1"); devparam[i].commid = 0; srdt.camerauseserial = 0; break; default: devparam[i].IsNoInsta = 0; break; } } } void GM_StartSerialComm() { int i, j, commid; char szbuf[64], logbuf[128]; //int64_t polltime=0; // 此处不能对轮询设备标识清零,否则如果先起摄像机,就会导致poll乱掉 //memset((void*)srdt.curdevidx, 0, sizeof(srdt.curdevidx)); //Gm_OpenSerialPower(); /* 不在这使用*/ //FindDevUseSerialCommNo(); // 初始化串口使用状态(需要考虑不同时间启用了摄像机使用) for (i = 0; i < MAX_SERIAL_PORT_NUM; i++) { if (i == srdt.camerauseserial) continue; serialport[i].Retry = 0; serialport[i].RetryTime = 800; serialport[i].WaitTime = 20; serialport[i].m_iRevStatus = 0; serialport[i].m_iRecvLen = 0; serialport[i].m_iNeedRevLength = 0; serialport[i].fd = -1; memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 ClearCmdFormPollCmdBuf(i); } #if 0/* 简化插入使用摄像机过程,摄像机使用单独的串口*/ else { for (i = 0; i < MAX_SERIAL_PORT_NUM; i++) { for (j = 0; j < MAX_SERIAL_DEV_NUM; j++) { if (((PELCO_D_PROTOCOL == devparam[i].ProtocolIdx) || (PELCO_P_PROTOCOL == devparam[i].ProtocolIdx)\ || (SERIALCAMERA_PROTOCOL == devparam[i].ProtocolIdx)) && (1 == devparam[i].IsNoInsta)) break; } if (j < MAX_SERIAL_DEV_NUM) continue; serialport[i].m_iRevStatus = 0; serialport[i].m_iRecvLen = 0; serialport[i].m_iNeedRevLength = 0; serialport[i].fd = -1; ClearCmdAllFlag(i); } } #endif for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) { memset(srdt.ms_dev[i].aiValue, 0, sizeof(AI_DEF)*MAX_DEV_VALUE_NUM); if (0 == devparam[i].IsNoInsta) { srdt.ms_dev[i].IsNeedSerial = 0; continue; } switch (devparam[i].ProtocolIdx) { case WEATHER_PROTOCOL: // 气象 case MUTIWEATHER_PROTOCOL: memset(weatherpntmsg, 0, sizeof(AI_DEF)*WEATHER_DATA_NUM); memset(szbuf, 0, sizeof(szbuf)); sprintf(szbuf, "%s", "气象"); srdt.ms_dev[i].IsNeedSerial = 1; srdt.ms_dev[i].FirstCmdTimeCnt = get_msec(); srdt.ms_dev[i].recvdatacnt = 0; for (j = 0; j < WEATHER_DATA_NUM; j++) { srdt.ms_dev[i].aiValue[j].AiState = SER_STARTSAMPLE; weatherpntmsg[j].AiState = SER_STARTSAMPLE; sprintf(logbuf, "init weather_state%d=%d", j, weatherpntmsg[j].AiState); DebugLog(8, logbuf, 'I'); } break; case RALLY_PROTOCOL: /* 拉力*/ sprintf(szbuf, "%s", "拉力"); srdt.ms_dev[i].IsNeedSerial = 1; srdt.ms_dev[i].FirstCmdTimeCnt = get_msec(); srdt.ms_dev[i].recvdatacnt = 0; for (j = 0; j < RALLY_DATA_NUM; j++) srdt.ms_dev[i].aiValue[j].AiState = SER_STARTSAMPLE; break; case WIND_PROTOCOL: /* 风速风向*/ memset(weatherpntmsg, 0, sizeof(AI_DEF)*WEATHER_DATA_NUM); memset(szbuf, 0, sizeof(szbuf)); sprintf(szbuf, "%s", "风速风向"); srdt.ms_dev[i].IsNeedSerial = 1; srdt.ms_dev[i].FirstCmdTimeCnt = get_msec(); for (j = 0; j < WEATHER_DATA_NUM; j++) { srdt.ms_dev[i].aiValue[j].AiState = SER_STARTSAMPLE; weatherpntmsg[j].AiState = SER_STARTSAMPLE; sprintf(logbuf, "init weather_state%d=%d", j, weatherpntmsg[j].AiState); DebugLog(8, logbuf, 'I'); } break; case SLANT_PROTOCOL: /* 倾角*/ sprintf(szbuf, "%s", "倾角"); srdt.ms_dev[i].IsNeedSerial = 1; srdt.ms_dev[i].FirstCmdTimeCnt = get_msec(); srdt.ms_dev[i].recvdatacnt = 0; for (j = 0; j < SLANTANGLE_DATA_NUM; j++) srdt.ms_dev[i].aiValue[j].AiState = SER_STARTSAMPLE; break; case PELCO_D_PROTOCOL: /* 摄像机协议*/ case PELCO_P_PROTOCOL: /* 摄像机协议*/ case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/ sprintf(szbuf, "%s", "摄像机"); srdt.ms_dev[i].IsNeedSerial = 0; break; default: srdt.ms_dev[i].IsNeedSerial = 0; sprintf(szbuf, "%s", "无效传感器"); break; } // 测试查询传感器电源状态 // 打开传感器电源 // 打开对应的485电源 // 打开串口通讯 memset(logbuf, 0, sizeof(logbuf)); if (1 == srdt.ms_dev[i].IsNeedSerial) { sprintf(logbuf, "装置%d, IsNoInsta=%d, 类型:%s", i + 1, devparam[i].IsNoInsta, szbuf); DebugLog(8, logbuf, 'I'); Gm_OpenSensorsPower(); Gm_OpenSerialPort(i); } } DebugLog(8, "启动数据采样!", 'I'); /* 直接使用循环进行采样处理*/ //polltime = get_msec(); for (;;) { usleep(10); //LOGW("polltime=%ldms", get_msec()-polltime); //polltime = get_msec(); if (GM_SerialTimer() < 0) { DebugLog(8, "退出采样流程!", 'V'); sleep(5); //GM_StartSerialComm(); break; } } return; } int GM_SerialTimer(void) { int flag = -1; GM_AllSerialComRecv(); GM_IsCloseSensors(); Gm_FindAllSensorsCommand(); GM_AllSerialComRecv(); flag = GM_CloseTimer(); return flag; } /******************************************************************************** 函数名称: void Gm_FindAllSensorsCommand() 功能说明:轮询所有串口和传感器是否需要生成下发命令 输入参数: 输出参数: 其它说明: *********************************************************************************/ void Gm_FindAllSensorsCommand() { int i, j, curidx, flag; //Gm_CheckSensorsPower(); /* 暂时不考虑电源控制*/ for (j = 1; j < MAX_SERIAL_PORT_NUM; j++) { // 发送缓冲区中命令 接收到了应答报文,紧接着进行缓冲区清理 SendCmdFormPollCmdBuf(j); // 串口已经被占用则直接跳过 curidx = srdt.curdevidx[j]; for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) { curidx = (curidx + 1) % MAX_SERIAL_DEV_NUM; if (j != devparam[curidx].commid) continue; if (srdt.ms_dev[curidx].IsNeedSerial == 0) continue; if (serialport[devparam[curidx].commid].fd < 0) Gm_OpenSerialPort(curidx); if (serialport[devparam[curidx].commid].cmdlen > 0) break; flag = -1; switch (devparam[curidx].ProtocolIdx) { case WEATHER_PROTOCOL: /* 温湿度气压*/ case RALLY_PROTOCOL: /* 拉力*/ case WIND_PROTOCOL: /* 风速风向*/ case SLANT_PROTOCOL: /* 倾角*/ case MUTIWEATHER_PROTOCOL: flag = FindNextShxyProtocolCommand(curidx); break; case RESERVE2_PROTOCOL: break; case RESERVE5_PROTOCOL: break; case PELCO_D_PROTOCOL: /* 摄像机协议*/ case PELCO_P_PROTOCOL: /* 摄像机协议*/ case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/ break; default: break; } if (flag == -1) continue; srdt.curdevidx[j] = curidx; break; } // 发送缓冲区中命令 生成了命令之后紧接着进行命令发送 SendCmdFormPollCmdBuf(j); } } /******************************************************************************** 函数名称: void GM_IsCloseSensors() 功能说明:检查所有传感器是否采集完毕,采集完毕的关闭传感器电源 输入参数: 输出参数: 其它说明: *********************************************************************************/ void GM_IsCloseSensors() { int i, j; char buf[256]; int64_t lctime; lctime = get_msec(); for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) { if (srdt.ms_dev[i].IsNeedSerial == 0) continue; memset(buf, 0, sizeof(buf)); switch (devparam[i].ProtocolIdx) { case WEATHER_PROTOCOL: /* 气象*/ case RALLY_PROTOCOL: /* 拉力*/ case WIND_PROTOCOL: /* 风速风向*/ case SLANT_PROTOCOL: /* 倾角*/ case MUTIWEATHER_PROTOCOL: if ((lctime - srdt.ms_dev[i].FirstCmdTimeCnt > 50 * 1000) || (lctime - srdt.ms_dev[i].FirstCmdTimeCnt < 0)) { srdt.ms_dev[i].FirstCmdTimeCnt = lctime; break; } if (lctime - srdt.ms_dev[i].FirstCmdTimeCnt > 15 * 1000) { srdt.ms_dev[i].IsNeedSerial = 0; // 关闭传感器电源 sprintf(buf, "读取装置%d数据%0.3f秒,关闭装置%d电源!", i + 1, (get_msec() - srdt.ms_dev[i].FirstCmdTimeCnt) / 1000.0, i + 1); DebugLog(devparam[i].commid, buf, 'I'); for (j = 0; j < MAX_DEV_VALUE_NUM; j++) { if (SER_STARTSAMPLE == srdt.ms_dev[i].aiValue[j].AiState) srdt.ms_dev[i].aiValue[j].AiState = SER_SAMPLEFAIL; else if (SER_SAMPLE == srdt.ms_dev[i].aiValue[j].AiState) srdt.ms_dev[i].aiValue[j].AiState = SAMPLINGSUCCESS; } if((devparam[i].ProtocolIdx == WIND_PROTOCOL) || (WEATHER_PROTOCOL == devparam[i].ProtocolIdx)|| (MUTIWEATHER_PROTOCOL == devparam[i].ProtocolIdx)) { for (j = 0; j < WEATHER_DATA_NUM; j++) { if (SER_STARTSAMPLE == weatherpntmsg[j].AiState) weatherpntmsg[j].AiState = SER_SAMPLEFAIL; else if (SER_SAMPLE == weatherpntmsg[j].AiState) weatherpntmsg[j].AiState = SAMPLINGSUCCESS; sprintf(buf, "over weather_state%d=%d", j, weatherpntmsg[j].AiState); DebugLog(8, buf, 'I'); } } } break; case PELCO_D_PROTOCOL: /* 摄像机类型*/ case PELCO_P_PROTOCOL: /* 摄像机类型*/ case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/ if (-1 == srdt.ms_dev[i].SerialCmdidx) { if ((SER_STARTSAMPLE == srdt.ms_dev[i].image.state) || (SER_SAMPLE == srdt.ms_dev[i].image.state)) srdt.ms_dev[i].image.state = SER_SAMPLEFAIL; else if (PHOTO_SAVE_SUCC == srdt.ms_dev[i].image.state) srdt.ms_dev[i].image.state = SAMPLINGSUCCESS; srdt.ms_dev[i].IsNeedSerial = 0; sprintf(buf, "通道%d摄像机使用完毕!可以关闭摄像机电源!", devparam[i].CameraChannel); DebugLog(devparam[i].commid, buf, 'I'); } break; } } } /******************************************************************************** 函数名称: void GM_AllSerialComRecv() 功能说明:检查所有串口是否有数据接收,有则启动接收 输入参数: 输出参数: 其它说明: *********************************************************************************/ void GM_AllSerialComRecv() { int i, j, recvlen; u_char recvbuf[RECVDATA_MAXLENTH]; char buf[256]; for (j = 0; j < MAX_SERIAL_PORT_NUM; j++) { memset(recvbuf, 0, sizeof(recvbuf)); if (serialport[j].fd <= 0) continue; //for(;;) recvlen = read(serialport[j].fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */ if (recvlen < 1) continue; #if 1 sprintf(buf, "收到串口%d, %d字节数据:", j + 1, recvlen); BytestreamLOG(j, buf, recvbuf, recvlen, 'I'); #endif SerialDataProcess(srdt.curdevidx[j], recvbuf, recvlen); } } /******************************************************************************** 函数名称: int GM_CloseTimer() 功能说明: 输入参数: 输出参数: 其它说明: *********************************************************************************/ int GM_CloseTimer() { int i, j, iretime; char buf[256]; for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) { if ((srdt.ms_dev[i].IsNeedSerial == 1) && ((0 < devparam[i].ProtocolIdx) && (INVALID_PROTOCOL > devparam[i].ProtocolIdx))) break; } if (i < MAX_SERIAL_DEV_NUM) { return 1; // 寻找 } else // 关闭所有串口及电源 { Gm_CloseSerialPort(); //for (j = 0; j < MAX_SERIAL_DEV_NUM; j++) //Gm_CloseSensorsPower(); for (j = 1; j < MAX_SERIAL_PORT_NUM; j++) ClearCmdFormPollCmdBuf(j); sprintf(buf, "%s", "关闭串口定时器!"); DebugLog(8, buf, 'I'); return -1; } } void SerialDataProcess(int devidx, u_char *buf, int len) { switch (devparam[devidx].ProtocolIdx) { case WEATHER_PROTOCOL: /* 气象*/ case RALLY_PROTOCOL: /* 拉力*/ case WIND_PROTOCOL: /* 风速风向*/ case SLANT_PROTOCOL: /* 倾角*/ case MUTIWEATHER_PROTOCOL: ShxyProtocolRecvData(devidx, buf, len); break; case RESERVE2_PROTOCOL: /* 意科电池电量读取协议*/ break; case PELCO_D_PROTOCOL: /* 摄像机协议*/ case PELCO_P_PROTOCOL: /* 摄像机协议*/ case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/ break; } } void DebugLog(int commid, const char *szbuf, char flag) { if (NULL == szbuf) return; SaveLogTofile(commid, szbuf); switch (flag) { case 'E': ALOGE("%s", szbuf); break; case 'I': ALOGI("%s", szbuf); break; case 'D': ALOGD("%s", szbuf); break; case 'V': ALOGI("%s", szbuf); break; case 'W': ALOGW("%s", szbuf); break; default: ALOGI("%s", szbuf); break; } } int SaveLogTofile(int commid, const char *szbuf) { int status; time_t now; char filename[512], filedir[512], buf[128]; FILE *fp = NULL; struct tm t0; struct timeval tv; if (NULL == szbuf) return -1; now = time(NULL); localtime_r(&now, &t0); gettimeofday(&tv, NULL); memset(filedir, 0, sizeof(filedir)); if(logPath != NULL) strcpy(filedir, logPath); if (access(filedir, 0) == 0) ;//LOGI("文件路径已经存在!"); else { status = mkdir(filedir, S_IRWXU | S_IRWXG | S_IRWXO); if (status < 0) return -1; } // 写入文件到sdcard memset(filename, 0, sizeof(filename)); sprintf(filename, "%sCOM%dlog-%04d-%02d-%02d.txt", filedir, commid + 1, t0.tm_year + 1900, t0.tm_mon + 1, t0.tm_mday); fp = fopen(filename, "a+"); if (NULL == fp) return -1; memset(buf, 0, sizeof(buf)); sprintf(buf, "%d-%d-%d %d:%d:%d-%d ", t0.tm_year + 1900, t0.tm_mon + 1, t0.tm_mday, t0.tm_hour, t0.tm_min, t0.tm_sec, (int)(tv.tv_usec / 1000)); fwrite(buf, 1, strlen(buf), fp); fwrite(szbuf, 1, strlen(szbuf), fp); memset(buf, 0, sizeof(buf)); strcpy(buf, "\n"); fwrite(buf, 1, strlen(buf), fp); fclose(fp); return 1; } int SaveImageDataTofile(SIO_PARAM_SERIAL_DEF *curserial) { u_char *image = NULL, *tempphoto = NULL; int i, status; size_t len; char filename[512]/*, filedir[512]*/, szbuf[128]; FILE *fp = NULL; image = (u_char*)malloc(curserial->image.imagelen); if (NULL == image) return -1; tempphoto = image; for (i = 0; i < curserial->image.imagenum; ++i) { memmove(tempphoto, &curserial->image.buf[i], (size_t)curserial->image.ilen[i]); tempphoto += (size_t)curserial->image.ilen[i]; } memset(szbuf, 0, sizeof(szbuf)); //memset(filedir, 0, sizeof(filedir)); //sprintf(filedir, "/sdcard/photo/"); if (access(srdt.filedir, 0) == 0) { sprintf(szbuf, "文件路径%s已经存在!", srdt.filedir); DebugLog(0, szbuf, 'I'); } else { status = mkdir(srdt.filedir, S_IRWXU | S_IRWXG | S_IRWXO); if (status < 0) return -1; } // 写入文件到sdcard memset(curserial->image.photoname, 0, sizeof(curserial->image.photoname)); sprintf(curserial->image.photoname, "%s1-%d-%d.jpg", srdt.filedir, curserial->image.presetno, curserial->image.phototime); fp = fopen(curserial->image.photoname, "wb+"); if (NULL == fp) return -1; len = fwrite(image, 1, curserial->image.imagelen, fp); fclose(fp); free(image); image = NULL; if (len < curserial->image.imagelen) return -1; else { memset(szbuf, 0, sizeof(szbuf)); sprintf(szbuf, "写入图片文件%s成功!", curserial->image.photoname); DebugLog(0, szbuf, 'I'); return 1; } } /******************************************************************* * 读 摄像机 数据 * *******************************************************************/ void CameraRecvData(SIO_PARAM_SERIAL_DEF *pPortParam, u_char *buf, int len) { int i; for (i = 0; i < len; i++) { switch (pPortParam->m_iRevStatus) { case 0: // 0x68 pPortParam->m_iRecvLen = 0; pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (0x68 == buf[i]) pPortParam->m_iRevStatus++; else pPortParam->m_iRevStatus = 18; break; case 1: // len1 pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_iRevStatus++; break; case 2: // len2 pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_iRevStatus++; pPortParam->m_iNeedRevLength = pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2] * 256 + buf[i] + 5; break; case 3: // 0x68 pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_iNeedRevLength--; if (0x68 == buf[i]) pPortParam->m_iRevStatus++; else pPortParam->m_iRevStatus = 18; break; case 4: // 正确接收数据 pPortParam->m_iNeedRevLength--; pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (pPortParam->m_iNeedRevLength > 0) break; if (buf[i] != 0x16) { pPortParam->m_iRevStatus = 18; break; } if (pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2] == CalLpc(&pPortParam->m_au8RecvBuf[4], pPortParam->m_iRecvLen - 6)) { CameraPhotoPortDataProcess(pPortParam); pPortParam->m_iRevStatus = 0; pPortParam->RevCmdFlag = 1; } else { pPortParam->m_iRevStatus = 0; } pPortParam->m_iRecvLen = 0; break; case 255:// 错误接收数据 default: if (buf[i] == 0x68) { pPortParam->m_iRevStatus = 1; pPortParam->m_iRecvLen = 1; pPortParam->m_au8RecvBuf[0] = buf[i]; } else if (buf[i] == 0x16) { pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_iRevStatus = 0; pPortParam->m_iRecvLen = 0; } else { pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (pPortParam->m_iRecvLen > 200) { pPortParam->m_iRecvLen = 0; } } break; } } } /********************************************************************************* CameraPhoto 端口数据处理 **********************************************************************************/ void CameraPhotoPortDataProcess(SIO_PARAM_SERIAL_DEF *curserial) { RTUMSG rtumsg; int img_file_size, packetnum, iNo, packsize, i = 0, j = 0, presetno, iphototime, pidx; int datanum; float fvalue; char szbuf[128]; uint16_t uDevAddr, datalen=0; uint8_t cmdidx, recvend; memset((void*)rtumsg.MsgData, 0, sizeof(rtumsg.MsgData)); memcpy((void*)rtumsg.MsgData, (void*)curserial->m_au8RecvBuf, curserial->m_iRecvLen); rtumsg.MsgLen = curserial->m_iRecvLen; //rtumsg.PortIdx = devparam[devno].commid; cmdidx = curserial->m_au8RecvBuf[5]; uDevAddr = curserial->m_au8RecvBuf[4]; //sprintf(szbuf, "摄像机地址%d,命令%02X!", uDevAddr, cmdidx); //DebugStringPrintf(szbuf, strlen(szbuf), 1); datalen = rtumsg.MsgData[1]*256+rtumsg.MsgData[2]; if (uDevAddr != curserial->cameraaddr) return; memset(szbuf, 0, sizeof(szbuf)); switch (cmdidx) { case 0x10: /* 拍照应答*/ if (0xFF == rtumsg.MsgData[6]) { srdt.RephotographCnt++; if (srdt.RephotographCnt > 2) { curserial->SerialCmdidx = -1; sprintf(szbuf, "因摄像机重拍%d次均未成功!结束拍照!", srdt.RephotographCnt); DebugLog(0, szbuf, 'E'); } break; } i = 6; memset(&curserial->image, 0, sizeof(curserial->image)); iphototime = rtumsg.MsgData[i + 3] + (rtumsg.MsgData[i + 2] << 8) + (rtumsg.MsgData[i + 1] << 16) + (rtumsg.MsgData[i] << 24); srdt.photographtime = iphototime; curserial->image.phototime = iphototime; i = 10; img_file_size = rtumsg.MsgData[i + 3] + (rtumsg.MsgData[i + 2] << 8) + (rtumsg.MsgData[i + 1] << 16) + (rtumsg.MsgData[i] << 24); packetnum = rtumsg.MsgData[i + 5] + (rtumsg.MsgData[i + 4] << 8); curserial->image.imagelen = img_file_size; curserial->image.imagenum = packetnum; srdt.historyimagenum[0] = rtumsg.MsgData[i + 7] + (rtumsg.MsgData[i + 6] << 8); sprintf(szbuf, "有%d张历史图片!", srdt.historyimagenum[0]); DebugLog(0, szbuf, 'V'); presetno = (int)rtumsg.MsgData[i + 8]; curserial->image.presetno = presetno; curserial->image.state = SER_SAMPLE; curserial->RevCmdFlag = 1; curserial->SerialCmdidx = 1; srdt.sendphotocmdcnt = 0; break; case 0x11: /* 图片数据包*/ i = 6; iNo = rtumsg.MsgData[i + 1] + rtumsg.MsgData[i] * 256; if((0xFF == rtumsg.MsgData[i+2]) && (3 == datalen)) { curserial->SerialCmdidx = iNo; break; } packsize = rtumsg.MsgData[i + 3] + rtumsg.MsgData[i + 2] * 256; memmove(&curserial->image.buf[iNo - 1], &rtumsg.MsgData[i + 4], packsize); curserial->image.ilen[iNo - 1] = packsize; sprintf(szbuf, "收到第%d(总%d包)包长=%d", iNo, curserial->image.imagenum, packsize); DebugLog(0, szbuf, 'V'); curserial->RevCmdFlag = 1; curserial->FirstCmdTimeCnt = get_msec(); if (iNo == curserial->SerialCmdidx) { if (iNo == curserial->image.imagenum) { /* 检查是否有漏包*/ for (pidx = 0; pidx < curserial->image.imagenum; pidx++) { if (curserial->image.ilen[pidx] < 1) break; } if (pidx < curserial->image.imagenum) { iNo = pidx; recvend = 0; } else { if ((1 == SaveImageDataTofile(curserial)) && (SER_SAMPLE == curserial->image.state)) { curserial->image.state = PHOTO_SAVE_SUCC; } recvend = 1; } } else recvend = 0; if (packsize > MAX_PHOTO_FRAME_LEN) recvend = 0xFF; if (1 == recvend) { curserial->SerialCmdidx = 10002;/* 图片读取完成*/ } else if (0xFF == recvend) { curserial->SerialCmdidx = -1; } else { if ((iNo > curserial->image.imagenum) || (0 >= curserial->image.imagenum)) { curserial->SerialCmdidx = -1; } else curserial->SerialCmdidx = iNo + 1; } srdt.errorPhotoNoCnt = 0; break; } srdt.errorPhotoNoCnt++; sprintf(szbuf, "问询第%d包图片摄像机应答第%d包,连续错误%d次!", curserial->SerialCmdidx, iNo, srdt.errorPhotoNoCnt); DebugLog(0, szbuf, 'E'); if (srdt.errorPhotoNoCnt > 5) { curserial->SerialCmdidx = 0; srdt.RephotographCnt++; if (srdt.RephotographCnt > 2) { curserial->SerialCmdidx = -1; sprintf(szbuf, "因摄像机重拍%d次均未成功!结束拍照!", srdt.RephotographCnt); DebugLog(0, szbuf, 'E'); } } break; case 0x03: //sprintf(szbuf, "设置波特率%d成功", curserial->baud); //DebugLog(devparam[devno].commid, szbuf, 'D'); curserial->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; curserial->RevCmdFlag = 1; curserial->FirstCmdTimeCnt = get_msec(); break; case 0xA0: sprintf(szbuf, "云台收到关电通知响应!"); DebugLog(0, szbuf, 'I'); curserial->SerialCmdidx = -1; break; case 0x08: datanum = curserial->m_au8RecvBuf[6]; memset(szbuf, 0, sizeof(szbuf)); for (i = 0, j = 7; (i < datanum) && (j < 6 + datalen); i++, j += 5) { fvalue = (curserial->m_au8RecvBuf[j + 1] << 24) + (curserial->m_au8RecvBuf[j + 2] << 16) + (curserial->m_au8RecvBuf[j + 3] << 8) + curserial->m_au8RecvBuf[j + 4]; switch (curserial->m_au8RecvBuf[j]) { case 200: /* 云台状态*/ curserial->ptz_state.ptz_process = curserial->m_au8RecvBuf[j + 1]; curserial->ptz_state.ptz_status = curserial->m_au8RecvBuf[j+4]; switch (curserial->ptz_state.ptz_process) { case 1: // 自检 if (0 == curserial->ptz_state.ptz_status) sprintf(szbuf, "云台自检结束!"); else if (0 < curserial->ptz_state.ptz_status) sprintf(szbuf, "云台正在自检!"); else sprintf(szbuf, "云台自检发生错误!"); DebugLog(0, szbuf, 'I'); break; case 2: // 调用预置点 if (0 == curserial->ptz_state.ptz_status) sprintf(szbuf, "调用预置位结束,云台处于所调预置位!"); else if (0 < curserial->ptz_state.ptz_status) sprintf(szbuf, "调用预置位,云台正在前往所调预置位位置!"); else if (2 == (curserial->ptz_state.ptz_status & 0x0f)) sprintf(szbuf, "调用预置位时,机芯电源未打开!"); else sprintf(szbuf, "调用预置位时,发生了错误,未正确执行!"); DebugLog(0, szbuf, 'I'); break; case 3: // 一般状态 if (0 == curserial->ptz_state.ptz_status) sprintf(szbuf, "云台处于静止状态!"); else if (0 < curserial->ptz_state.ptz_status) sprintf(szbuf, "云台正在运动!"); else sprintf(szbuf, "云台发生错误!"); DebugLog(0, szbuf, 'I'); break; default: sprintf(szbuf, "未知错误,云台应答错误!"); DebugLog(0, szbuf, 'I'); break; } break; case 201: /* 云台预置点*/ curserial->ptz_state.presetno = (curserial->m_au8RecvBuf[j + 3] << 8) + curserial->m_au8RecvBuf[j + 4]; sprintf(szbuf, "云台预置点号=%d", curserial->ptz_state.presetno); DebugLog(0, szbuf, 'I'); break; case 202: /* 云台坐标*/ fvalue = (uint16_t)((curserial->m_au8RecvBuf[j + 1] << 8) + (curserial->m_au8RecvBuf[j + 2])); fvalue /=100.0; curserial->ptz_state.x_coordinate = fvalue; fvalue = (uint16_t)((curserial->m_au8RecvBuf[j + 3] << 8) + (curserial->m_au8RecvBuf[j + 4])); fvalue /=100.0; #if 0 if(fvalue < 180) fvalue *= -1; else fvalue = 360-fvalue; #endif if(fvalue > 180) fvalue -= 360; curserial->ptz_state.y_coordinate = fvalue; sprintf(szbuf, "云台坐标水平(X)=%0.2f°, 垂直(Y)=%0.2f°", curserial->ptz_state.x_coordinate, curserial->ptz_state.y_coordinate); DebugLog(0, szbuf, 'I'); break; } } curserial->SerialCmdidx = -1; break; case 0x15: if (0xFF == rtumsg.MsgData[6]) { curserial->SerialCmdidx = -1; strcpy(szbuf, "没有历史图片!结束读取图片!"); DebugLog(0, szbuf, 'I'); break; } i = 6; iphototime = rtumsg.MsgData[i + 3] + (rtumsg.MsgData[i + 2] << 8) + (rtumsg.MsgData[i + 1] << 16) + (rtumsg.MsgData[i] << 24); srdt.photographtime = iphototime; curserial->image.phototime = iphototime; i = 10; img_file_size = rtumsg.MsgData[i + 3] + (rtumsg.MsgData[i + 2] << 8) + (rtumsg.MsgData[i + 1] << 16) + (rtumsg.MsgData[i] << 24); packetnum = rtumsg.MsgData[i + 5] + (rtumsg.MsgData[i + 4] << 8); curserial->image.imagelen = img_file_size; curserial->image.imagenum = packetnum; //srdt.imagepacketnum = packetnum; srdt.historyimagenum[0] = rtumsg.MsgData[i + 7] + (rtumsg.MsgData[i + 6] << 8); presetno = rtumsg.MsgData[i + 8]; curserial->image.presetno = presetno; sprintf(szbuf, "读取历史图片,还有%d张历史图片!", srdt.historyimagenum[0]); DebugLog(0, szbuf, 'I'); curserial->RevCmdFlag = 1; curserial->SerialCmdidx = 1; srdt.sendphotocmdcnt = 0; break; case 0x16: if (0xFF == rtumsg.MsgData[10]) { curserial->SerialCmdidx = -1; strcpy(szbuf, "摄像机图片保存失败!"); DebugLog(0, szbuf, 'E'); } curserial->SerialCmdidx = -1; if (0 == rtumsg.MsgData[10]) { if (0 == srdt.historyimagenum[0]) { ; } else { curserial->SerialCmdidx = 10003;/* 暂时不实现*/ } } curserial->FirstCmdTimeCnt = get_msec(); curserial->RevCmdFlag = 1; break; default: curserial->RevCmdFlag = 1; break; } } /********************************************************************************* 发送命令 **********************************************************************************/ void SendCmdFormPollCmdBuf(int port) { char buf[128]; int len, ret; int64_t lctime; SIO_PARAM_SERIAL_DEF *pPortParam; if(port < 1) return; pPortParam = &serialport[port]; memset(buf, 0, sizeof(buf)); lctime = get_msec(); if (pPortParam->ForceWaitFlag && pPortParam->ForceWaitCnt) { pPortParam->ForceWaitCnt--; return; } if (pPortParam->SendCmdFlag && (pPortParam->RevCmdFlag == 0)) { //pPortParam->RetryTimeCnt++; if ((lctime - pPortParam->RetryTimeCnt > 3 * pPortParam->RetryTime) || (lctime - pPortParam->RetryTimeCnt < 0)) { pPortParam->RetryTimeCnt = lctime; return; } if (lctime - pPortParam->RetryTimeCnt < pPortParam->RetryTime) //if(pPortParam->RetryTimeCnt < pPortParam->RetryTime) { return; } pPortParam->RetryTimeCnt = lctime; pPortParam->RetryCnt++; if (pPortParam->RetryCnt > pPortParam->Retry) { ClearCmdFormPollCmdBuf(port); } else { pPortParam->SendCmdFlag = 0; pPortParam->RevCmdFlag = 0; pPortParam->ReSendCmdFlag = 1; } } if (pPortParam->SendCmdFlag && pPortParam->RevCmdFlag) { // 清除当前命令 ClearCmdFormPollCmdBuf(port); } if (pPortParam->WaitTime > 0) { if ((lctime - pPortParam->WaitTimeCnt > 30 * pPortParam->WaitTime) || (lctime - pPortParam->WaitTimeCnt < 0)) { pPortParam->WaitTimeCnt = lctime; return; } if (lctime - pPortParam->WaitTimeCnt < pPortParam->WaitTime) { return; } } pPortParam->WaitTimeCnt = lctime; if (pPortParam->ReSendCmdFlag) len = pPortParam->cmdlen; else { len = pPortParam->cmdlen; pPortParam->RetryCnt = 0; } if (len == 0) return; serialport[devparam[srdt.curdevidx[port]].commid].m_iRecvLen = 0; // 当发送一条新指令时,清除接收状态 serialport[devparam[srdt.curdevidx[port]].commid].m_iRevStatus = 0; if (serialport[port].fd < 0) return; ret = Gm_SetSerialPortParam(port); if (ret < 0) return; len = GM_SerialComSend(&pPortParam->PollCmd[2], pPortParam->cmdlen - 2, port); if (len < 1) { sprintf(buf, "串口%d, 发送命令失败! fd = %d", port + 1, serialport[port].fd); DebugLog(port, buf, 'E'); } else { sprintf(buf, "发送串口%d 装置%d命令:", port + 1, srdt.curdevidx[port] + 1); BytestreamLOG(port, buf, &pPortParam->PollCmd[2], len, 'D'); sprintf(buf, "sendtimeconst= %lld", lctime - pPortParam->lsendtime); DebugLog(port, buf, 'W'); pPortParam->lsendtime = lctime; } pPortParam->SendCmdFlag = 1; pPortParam->ReSendCmdFlag = 0; pPortParam->RevCmdFlag = 0; pPortParam->RetryTimeCnt = lctime; pPortParam->ForceWaitCnt = pPortParam->PollCmd[0] * 256 + pPortParam->PollCmd[1] + TIMER_CNT - 1; pPortParam->ForceWaitCnt /= TIMER_CNT; if (pPortParam->ForceWaitCnt) { pPortParam->ForceWaitFlag = 1; } } void ClearCmdAllFlag(int commid) { if ((commid < 0) || (commid >= MAX_SERIAL_PORT_NUM)) return; serialport[commid].RetryCnt = 0; serialport[commid].RetryTimeCnt = get_msec(); serialport[commid].WaitTimeCnt = get_msec(); serialport[commid].ForceWaitFlag = 0; serialport[commid].ForceWaitCnt = 0; serialport[commid].SendCmdFlag = 0; serialport[commid].RevCmdFlag = 0; serialport[commid].ReSendCmdFlag = 0; } void ClearCmdFormPollCmdBuf(int port) { //int len, idx; SIO_PARAM_SERIAL_DEF *pPortParam; if ((port < 0) || (port >= MAX_SERIAL_PORT_NUM)) return; pPortParam = &serialport[port]; pPortParam->cmdlen = 0; memset(pPortParam->PollCmd, 0, sizeof(pPortParam->PollCmd)); srdt.serialstatus[port] = 0; // 清除指令下发标识 ClearCmdAllFlag(port); } void ClearCameraCmdFormPollCmdBuf(SIO_PARAM_SERIAL_DEF *pPortParam) { pPortParam->cmdlen = 0; memset(pPortParam->PollCmd, 0, sizeof(pPortParam->PollCmd)); //srdt.serialstatus[port] = 0; // 清除指令下发标识 ClearCameraCmdAllFlag(pPortParam); } void ClearCameraCmdAllFlag(SIO_PARAM_SERIAL_DEF *pPortParam) { pPortParam->RetryCnt = 0; pPortParam->RetryTimeCnt = get_msec(); pPortParam->WaitTimeCnt = get_msec(); pPortParam->ForceWaitFlag = 0; pPortParam->ForceWaitCnt = 0; pPortParam->SendCmdFlag = 0; pPortParam->RevCmdFlag = 0; pPortParam->ReSendCmdFlag = 0; } // 下发串口拍照指令控制 int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) { int imagesize = 3, cmdno; uint8_t channel, imagequality = 90, presetno; uint16_t packetsize; int64_t lcurtime; uint8_t cmdidx = 0x10; char szbuf[128]; //如果命令缓冲区仍有命令,则退出本函数 if (-1 == pPortParam->SerialCmdidx)/* 下发拍照指令*/ return -1; channel = 1; cmdno = pPortParam->SerialCmdidx; lcurtime = get_msec(); if ((1 > cmdno) || (10000 <= cmdno)) { if (lcurtime - pPortParam->FirstCmdTimeCnt < 300) return -1; } switch (cmdno) { case TAKE_PHOTO:/* 下发拍照指令*/ if (lcurtime - pPortParam->FirstCmdTimeCnt < 3800) return -1; if ((lcurtime - pPortParam->FirstCmdTimeCnt > 3 * 35 * 1000) || (lcurtime - pPortParam->FirstCmdTimeCnt < 0)) { pPortParam->FirstCmdTimeCnt = lcurtime; return -1; } if (lcurtime - pPortParam->FirstCmdTimeCnt > 35 * 1000) { pPortParam->SerialCmdidx = -1; strcpy(szbuf, "串口摄像机未接或故障!结束拍照!"); DebugLog(0, szbuf, 'I'); return -1; } memset(szbuf, 0, sizeof(szbuf)); sprintf(szbuf, "time=%lldms", lcurtime - pPortParam->FirstCmdTimeCnt); DebugLog(0, szbuf, 'I'); packetsize = (uint16_t)MAX_PHOTO_FRAME_LEN; srdt.sendphotocmdcnt++; srdt.imagepacketnum = 0; srdt.errorPhotoNoCnt = 0; cmdidx = 0x10; imagesize = srdt.bImageSize; break; case SET_BAUD: /* 下发设置串口波特率命令*/ #if 0 switch (devparam[devidx].baudrate) { case B9600: imagesize = 0x07; break; case B19200: imagesize = 0x08; break; case B38400: imagesize = 0x09; break; default: sprintf(szbuf, "设置串口摄像机参数时,配置参数错误!退出设置!"); DebugLog(devparam[devidx].commid, szbuf, 'I'); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return -1; } if (lcurtime - pPortParam->FirstCmdTimeCnt > 15 * 1000) { pPortParam->SerialCmdidx = -1; sprintf(szbuf, "设置串口摄像机参数时,15秒未收到摄像机应答!退出设置!"); DebugLog(devparam[devidx].commid, szbuf, 'I'); return -1; } cmdidx = 0x03; packetsize = 0xFFFF; #endif break; case 10001: /* 通知摄像机图片读取完成或存储(16H)*/ case 10002: cmdidx = 0x16; if (10001 == cmdno) packetsize = 1; else packetsize = 0; imagesize = srdt.photographtime; /* 需要保存或删除的图片拍摄时间*/ break; case 10003: /* 读取历史图片(15H)*/ cmdidx = 0x15; packetsize = (uint16_t)MAX_PHOTO_FRAME_LEN; break; case STOP_CMD: /* 关闭功能*/ //Gm_CtrlPtzCmd(1, P_MOVE_LEFT); //sleep(2); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; //sleep(20); return 1; case AUTO_SCAN: /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ Gm_CtrlPtzCmd(pPortParam, P_Auto_Scan); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case IRIS_CLOSE: /* 光圈缩小(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_IRIS_CLOSE); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case IRIS_OPEN: /* 光圈放大(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_IRIS_OPEN); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case FOCUS_NEAR: /* 近距离聚焦(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_FOCUS_NEAR); usleep(500000); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case FOCUS_FAR: /* 远距离聚焦(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_FOCUS_FAR); usleep(500000); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case ZOOM_WIDE: /* 远离物体(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_ZOOM_WIDE); usleep(500000); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case ZOOM_TELE: /* 接近物体(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_ZOOM_TELE); usleep(500000); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case MOVE_DOWN: /* 向下移动镜头(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_MOVE_DOWN); sleep(1); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case MOVE_UP: /* 向上移动镜头(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_MOVE_UP); sleep(1); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case MOVE_LEFT: /* 向左移动镜头(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_MOVE_LEFT); sleep(1); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case MOVE_RIGHT: /* 向右移动镜头(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_MOVE_RIGHT); sleep(1); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case MOVE_PRESETNO: /* 调用预置点*/ //srdt.presetno = 2; Gm_CtrlPtzCmd(pPortParam, MOVE_TO_PRESETNO + srdt.presetno); #if 0 sleep(2); if (0 == srdt.IsSleep) { pPortParam->SerialCmdidx = MOVE_PRESETNO; srdt.IsSleep++; return 1; } #endif pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; srdt.IsSleep = 0; return 1; case SAVE_PRESETNO: /* 设置预置点*/ Gm_CtrlPtzCmd(pPortParam, SET_PRESETNO + srdt.presetno); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; case NOTIFY_PTZ_CLOSE: /* 通知云台关闭电源*/ if (pPortParam->sendptzstatecmd == 0) { cmdidx = 0xA0; pPortParam->sendptzstatecmd++; } else { pPortParam->SerialCmdidx = -2; pPortParam->sendptzstatecmd = 0; strcpy(szbuf, "云台未接或故障!结束通知!"); DebugLog(0, szbuf, 'I'); return -1; } MakePtzStateQueryCommand(pPortParam, cmdidx); return 1; case QUERY_PTZ_STATE: /* 查询云台状态信息*/ //::memset(szbuf, 0, sizeof(szbuf)); //sprintf(szbuf, "下发命令sendptzstatecmd=%d!", pPortParam->sendptzstatecmd); //DebugLog(0, szbuf, 'I'); //if (pPortParam->sendptzstatecmd > 0) #if 1 if (pPortParam->sendptzstatecmd == 0) { pPortParam->sendptzstatecmd++; cmdidx = 0x08; //::memset(szbuf, 0, sizeof(szbuf)); //sprintf(szbuf, "下发命令sendptzstatecmd=%d!", pPortParam->sendptzstatecmd); //DebugLog(0, szbuf, 'I'); } else #endif { pPortParam->SerialCmdidx = -2; pPortParam->sendptzstatecmd = 0; strcpy(szbuf, "云台未接或故障!结束查询!"); DebugLog(0, szbuf, 'I'); return -1; } //pPortParam->sendptzstatecmd++; //cmdidx = 0x08; MakePtzStateQueryCommand(pPortParam, cmdidx); return 1; default: imagesize = 0xFF; packetsize = (uint16_t)pPortParam->SerialCmdidx; cmdidx = 0x11; #if 0 if (0 == srdt.IsSleep) { srdt.IsSleep++; testComm(); } #endif if (lcurtime - pPortParam->FirstCmdTimeCnt > 35 * 1000) { pPortParam->SerialCmdidx = -1; sprintf(szbuf, "读取第%d包图片数据35秒未收到!结束拍照!", packetsize); DebugLog(0, szbuf, 'I'); return -1; } break; } //::memset(szbuf, 0, sizeof(szbuf)); //strcpy(szbuf, "make:sendptzstatecmd"); //DebugLog(0, szbuf, 'I'); MakeCameraPhotoCommand(pPortParam, cmdidx, imagesize, packetsize, imagequality, srdt.sendphototime); return 1; } /********************************************************************************* 生成 CameraPhoto命令 **********************************************************************************/ void MakeCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam, uint8_t cmdidx, int OneParam, uint16_t TwoParam, uint8_t Threep, int phototime) { int i, icurtime; u_char *sendbuf; char szbuf[128]; sendbuf = pPortParam->PollCmd; ::memset(szbuf, 0, sizeof(szbuf)); strcpy(szbuf, "make:sendptzstatecmd start!"); DebugLog(0, szbuf, 'I'); //return; icurtime = phototime; i = 0; sendbuf[i++] = 0x00; /* 强制等待时间*/ sendbuf[i++] = 0x00; /* 强制等待时间*/ sendbuf[i++] = 0x68; /* 起始字符*/ sendbuf[i++] = (uint8_t)0x00; /* length */ sendbuf[i++] = (uint8_t)0x00; /* length */ sendbuf[i++] = 0x68; /* 起始字符*/ sendbuf[i++] = (uint8_t)pPortParam->cameraaddr;/* 传感器地址*/ sendbuf[i++] = cmdidx; /* 命令字*/ switch (cmdidx) { case 0x02: /* */ sendbuf[i - 2] = 0xFF; break; case 0x03: /*设置传感器通讯参数(03H)*/ sendbuf[i++] = 0x00; /* 波特率*/ sendbuf[i++] = 0x00; sendbuf[i++] = 0x00; sendbuf[i++] = (uint8_t)OneParam; sendbuf[i++] = 0x08; /* 数据位*/ sendbuf[i++] = 0x00; /* 校验位*/ sendbuf[i++] = 0x01; /* 停止位*/ break; case 0x010: /* 拍摄图片并指定大小分包(10H)*/ sendbuf[i++] = OneParam; /* 图片大小(Resolution)*/ sendbuf[i++] = HIBYTE(TwoParam);/*包大小(PackageSize)*/ sendbuf[i++] = LOBYTE(TwoParam); sendbuf[i++] = HIBYTE(HIWORD(icurtime + 8 * 60 * 60));/* 请求拍摄图片时间(PhotoTime)*/ sendbuf[i++] = LOBYTE(HIWORD(icurtime + 8 * 60 * 60)); sendbuf[i++] = HIBYTE(LOWORD(icurtime + 8 * 60 * 60)); sendbuf[i++] = LOBYTE(LOWORD(icurtime + 8 * 60 * 60)); sendbuf[i++] = Threep;/*图像质量(ImageQuality)*/ sendbuf[i++] = srdt.presetno;//netportparam.CurPresetno[srdt.ms_dev[portno].CameraChannel-1];/*拍照预置点(PresetNo)*/ break; case 0x11: /* 获取指定包数据(11H)*/ sendbuf[i++] = HIBYTE(TwoParam);/*图片包号:(PackageNo)*/ sendbuf[i++] = LOBYTE(TwoParam); break; case 0x15: /* 读取历史图片(15H)*/ sendbuf[i++] = HIBYTE(TwoParam);/*包大小(PackageSize)*/ sendbuf[i++] = LOBYTE(TwoParam); break; case 0x16: /* 通知摄像机图片读取完成或存储(16H)*/ sendbuf[i++] = HIBYTE(HIWORD(OneParam));/* 需要保存或删除的图片拍摄时间*/ sendbuf[i++] = LOBYTE(HIWORD(OneParam)); sendbuf[i++] = HIBYTE(LOWORD(OneParam)); sendbuf[i++] = LOBYTE(LOWORD(OneParam)); sendbuf[i++] = (uint8_t)TwoParam; /* 是否需要保存*/ break; default: break; } sendbuf[i] = CalLpc((u_char *)&sendbuf[6], i - 6); i += 1; sendbuf[i++] = 0x16; /* 信息尾*/ sendbuf[3] = (uint8_t)((i - 10) >> 8); sendbuf[4] = (uint8_t)(i - 10); pPortParam->cmdlen = i; #if 1 //::memset(szbuf, 0, sizeof(szbuf)); //strcpy(szbuf, "make over!"); //DebugLog(0, szbuf, 'I'); if(0x08 == cmdidx) { ::memset(szbuf, 0, sizeof(szbuf)); strcpy(szbuf, "生成查询云台位置命令!"); DebugLog(0, szbuf, 'I'); } #endif //return; } /********************************************************************************* 生成 QueryPtzState命令 **********************************************************************************/ void MakePtzStateQueryCommand(SIO_PARAM_SERIAL_DEF *pPortParam, uint8_t cmdidx) { int i, icurtime; u_char *sendbuf; //char szbuf[128]; sendbuf = pPortParam->PollCmd; //::memset(szbuf, 0, sizeof(szbuf)); //strcpy(szbuf, "make:sendptzstatecmd start!"); //DebugLog(0, szbuf, 'I'); i = 0; sendbuf[i++] = 0x00; /* 强制等待时间*/ sendbuf[i++] = 0x00; /* 强制等待时间*/ sendbuf[i++] = 0x68; /* 起始字符*/ sendbuf[i++] = (uint8_t)0x00; /* length */ sendbuf[i++] = (uint8_t)0x00; /* length */ sendbuf[i++] = 0x68; /* 起始字符*/ sendbuf[i++] = (uint8_t)pPortParam->cameraaddr;/* 传感器地址*/ sendbuf[i++] = cmdidx; /* 命令字*/ sendbuf[i] = CalLpc((u_char *)&sendbuf[6], i - 6); i += 1; sendbuf[i++] = 0x16; /* 信息尾*/ sendbuf[3] = (uint8_t)((i - 10) >> 8); sendbuf[4] = (uint8_t)(i - 10); pPortParam->cmdlen = i; #if 0 //::memset(szbuf, 0, sizeof(szbuf)); //strcpy(szbuf, "make over!"); //DebugLog(0, szbuf, 'I'); if(0x08 == cmdidx) { ::memset(szbuf, 0, sizeof(szbuf)); strcpy(szbuf, "生成查询云台位置命令!"); DebugLog(0, szbuf, 'I'); } #endif //return; } // 准备发送云台指令 int Gm_CtrlPtzCmd(SIO_PARAM_SERIAL_DEF *pPortParam, uint32_t ptzcmd) { switch (ptzcmd) { case P_Auto_Scan: srdt.PtzCmdType = D_Auto_Scan; break; case P_IRIS_CLOSE: srdt.PtzCmdType = D_IRIS_CLOSE; break; case P_IRIS_OPEN: srdt.PtzCmdType = D_IRIS_OPEN; break; case P_FOCUS_NEAR: srdt.PtzCmdType = D_FOCUS_NEAR; break; case P_FOCUS_FAR: srdt.PtzCmdType = D_FOCUS_FAR; break; case P_ZOOM_WIDE: srdt.PtzCmdType = D_ZOOM_WIDE; break; case P_ZOOM_TELE: srdt.PtzCmdType = D_ZOOM_TELE; break; case P_MOVE_DOWN: srdt.PtzCmdType = D_MOVE_DOWN; break; case P_MOVE_UP: srdt.PtzCmdType = D_MOVE_UP; break; case P_MOVE_LEFT: srdt.PtzCmdType = D_MOVE_LEFT; break; case P_MOVE_RIGHT: srdt.PtzCmdType = D_MOVE_RIGHT; break; } if (serialport[srdt.camerauseserial].cmdlen > 0) return -1; Gm_SendPelco_DCommand(pPortParam,ptzcmd); return 1; } // 发送转动摄像机云台命令定时器 #if 0 int Gm_Camera_Timer() { char szbuf[128]; if (PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx) { switch (srdt.PtzCmdType) { case P_Auto_Scan: srdt.PtzCmdType = D_Auto_Scan; break; case P_IRIS_CLOSE: srdt.PtzCmdType = D_IRIS_CLOSE; break; case P_IRIS_OPEN: srdt.PtzCmdType = D_IRIS_OPEN; break; case P_FOCUS_NEAR: srdt.PtzCmdType = D_FOCUS_NEAR; break; case P_FOCUS_FAR: srdt.PtzCmdType = D_FOCUS_FAR; break; case P_ZOOM_WIDE: srdt.PtzCmdType = D_ZOOM_WIDE; break; case P_ZOOM_TELE: srdt.PtzCmdType = D_ZOOM_TELE; break; case P_MOVE_DOWN: srdt.PtzCmdType = D_MOVE_DOWN; break; case P_MOVE_UP: srdt.PtzCmdType = D_MOVE_UP; break; case P_MOVE_LEFT: srdt.PtzCmdType = D_MOVE_LEFT; break; case P_MOVE_RIGHT: srdt.PtzCmdType = D_MOVE_RIGHT; break; } } if (srdt.SendStopPtzCmdTimeCnt == -1) { if (serialport[srdt.camerauseserial].cmdlen > 0) return -1; if (PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx) Gm_SendPelco_DCommand(srdt.PtzCmdType); else Gm_SendPelco_pCommand(srdt.PtzCmdType); if ((SET_PRESETNO == (srdt.PtzCmdType & 0xFFFF0000)) || (MOVE_TO_PRESETNO == (srdt.PtzCmdType & 0xFFFF0000))) { //srdt.sampling &= 0xFD; return 1; } srdt.PtzCmdType = Cmd_Cancel; srdt.SendStopPtzCmdTimeCnt = 0; } return 1; #if 0 //if(srdt.SendStopPtzCmdTimeCnt > PTZ_MOVETIME*1000/TIMER_CNT) { if (serialport[srdt.camerauseserial].cmdlen > 0) return -1; if (PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx) Gm_SendPelco_DCommand(srdt.PtzCmdType); else Gm_SendPelco_pCommand(srdt.PtzCmdType); srdt.SendStopPtzCmdTimeCnt = -1; //srdt.sampling &= 0xFD; return 1; } //else // srdt.SendStopPtzCmdTimeCnt ++; //return -1; #endif } #endif /******************************************************************************** * 生成 PELCO_P 命令 * *********************************************************************************/ void Gm_SendPelco_pCommand(uint32_t cmdtype) { int len; uint8_t commandbuf[32]; char buf[128]; len = 0; commandbuf[len++] = (uint8_t)0xA0; commandbuf[len++] = (uint8_t)devparam[srdt.usecameradevidx].devaddr; commandbuf[len++] = (uint8_t)(cmdtype >> 24); commandbuf[len++] = (uint8_t)(cmdtype >> 16); commandbuf[len++] = (uint8_t)(cmdtype >> 8); commandbuf[len++] = (uint8_t)(cmdtype); commandbuf[len++] = (uint8_t)0xAF; commandbuf[len] = (uint8_t)Gm_Pelco_pXORCheck(commandbuf, len); len++; serialport[srdt.camerauseserial].cmdlen = len; //Gm_SetSerialPortParam(srdt.camerauseserial); //unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x0ff,0x02,0x01,0x16}; //len = GM_SerialComSend(sendbuf, sizeof(sendbuf), srdt.camerauseserial); len = GM_SerialComSend(commandbuf, len, srdt.camerauseserial); if (len < 1) { DebugLog(srdt.camerauseserial, "发送Pelco_p命令失败", 'E'); } else { sprintf(buf, "发送串口%d 像机通道%d Pelco_P命令:", srdt.camerauseserial + 1, devparam[srdt.usecameradevidx].CameraChannel); BytestreamLOG(srdt.camerauseserial, buf, commandbuf, len, 'D'); } ClearCmdFormPollCmdBuf(srdt.camerauseserial); } uint8_t Gm_Pelco_pXORCheck(uint8_t *msg, int len) { int i; uint8_t checkvalue = 0; if (len <= 0) return checkvalue; checkvalue = msg[0]; for (i = 1; i < len; i++) checkvalue ^= msg[i]; return checkvalue; } /******************************************************************************** * 生成 PELCO_D 命令 * *********************************************************************************/ void Gm_SendPelco_DCommand(SIO_PARAM_SERIAL_DEF *pPortParam, uint32_t cmdtype) { int len; uint8_t commandbuf[32]; char buf[128]; len = 0; #if 1 /* Pelco_D*/ commandbuf[len++] = (uint8_t)0xFF; commandbuf[len++] = (uint8_t)pPortParam->cameraaddr; commandbuf[len++] = (uint8_t)(cmdtype >> 24); commandbuf[len++] = (uint8_t)(cmdtype >> 16); commandbuf[len++] = (uint8_t)(cmdtype >> 8); commandbuf[len++] = (uint8_t)(cmdtype); commandbuf[len] = (uint8_t)Gm_Pelco_DCheck(commandbuf, len); #endif len++; pPortParam->cmdlen = len; //Gm_SetSerialPortParam(srdt.camerauseserial); len = GM_CameraComSend(commandbuf, len, pPortParam->fd); if (len < 1) { DebugLog(0, "发送Pelco_D命令失败", 'E'); } else { strcpy(buf, "发送像机Pelco_D命令:"); BytestreamLOG(0, buf, commandbuf, len, 'D'); } ClearCameraCmdFormPollCmdBuf(pPortParam); } // 计算Pelco_D校验 uint8_t Gm_Pelco_DCheck(uint8_t *msg, int len) { int i; uint8_t checkvalue = 0; if (len <= 0) return checkvalue; checkvalue = 0; for (i = 1; i < len; i++) checkvalue += msg[i]; return checkvalue; } /********************************************************************************* 寻找并生成下一条倾角命令 **********************************************************************************/ int FindNextShxyProtocolCommand(int devidx) { int cmdno = 0; //如果命令缓冲区仍有命令,则退出本函数 if ((devparam[devidx].commid + 1 < 1) || (devparam[devidx].commid + 1 > MAX_SERIAL_PORT_NUM)) return -1; if (get_msec() - srdt.ms_dev[devidx].FirstCmdTimeCnt < 3 * 1000) { return -1; } //if(SLANT_PROTOCOL == devparam[devidx].ProtocolIdx) // return -1; switch (cmdno) { case 0: /* 正常采集数据*/ MakeShxyProtocolPollCommand(devidx, 0x09); srdt.curdevidx[devparam[devidx].commid] = devidx; return 1; case 1: /* 测试读取地址*/ MakeShxyProtocolPollCommand(devidx, 0x02); srdt.curdevidx[devparam[devidx].commid] = devidx; return 1; default: break; } return -1; } /********************************************************************************* 生成下发命令 **********************************************************************************/ void MakeShxyProtocolPollCommand(int portno, uint8_t cmdidx) { int i, length = 0; int newaddr = 9, baud = 9600, stopbit = 1, parity = 0; //char buf[128]; u_char *sendbuf; sendbuf = serialport[devparam[portno].commid].PollCmd; /* 测试变量*/ cmdidx = cmdidx; i = 0; sendbuf[i++] = 0x00; // 强制等待时间 sendbuf[i++] = 0x00; // sendbuf[i++] = 0x68; // 起始字符 sendbuf[i++] = (uint8_t)0x00; // length sendbuf[i++] = (uint8_t)0x00; // length sendbuf[i++] = 0x68; sendbuf[i++] = (uint8_t)devparam[portno].devaddr; // 传感器地址 sendbuf[i++] = cmdidx; // 命令信息0x06 switch (cmdidx) { case 1: /* 设置传感器新地址*/ sendbuf[i++] = newaddr; length = 1; break; case 2: /* 广播读地址*/ sendbuf[6] = 0xFF; break; case 3: /* 设置串口参数*/ sendbuf[i++] = (u_char)(baud >> 24); sendbuf[i++] = (u_char)(baud >> 16); sendbuf[i++] = (u_char)(baud >> 8); sendbuf[i++] = (u_char)baud; sendbuf[i++] = 8; sendbuf[i++] = parity; sendbuf[i++] = stopbit; length = 7; break; default: break; } sendbuf[i] = CalLpc((u_char *)&sendbuf[6], i - 6); i += 1; sendbuf[3] = length; sendbuf[4] = length; sendbuf[i++] = 0x16; // 信息尾 serialport[devparam[portno].commid].cmdlen = i; } unsigned char CalLpc(unsigned char *msg, int len) { int i; unsigned char retval = 0; for (i = 0; i < len; i++) retval += msg[i]; return retval; } unsigned char BDXorCheck(unsigned char *msg, int len) { int i; unsigned char retval = 0; for (i = 0; i < len; i++) retval ^= msg[i]; return retval; } /*************************************************************** * 读上海欣影传感器协议数据 * ***************************************************************/ void ShxyProtocolRecvData(int devno, u_char *buf, int len)// 规约读数据处理 { int i, ictime; //uint16_t crc, check; //SERIAL_DEV_DEF *pPortParam; SIO_PARAM_SERIAL_DEF *pPortParam; if ((devno < 0) || (devno > MAX_SERIAL_DEV_NUM)) { return; } pPortParam = &serialport[devparam[devno].commid]; for (i = 0; i < len; i++) { switch (pPortParam->m_iRevStatus) { case 0: // 0x68 pPortParam->m_iRecvLen = 0; pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (0x68 == buf[i]) pPortParam->m_iRevStatus++; else pPortParam->m_iRevStatus = 18; break; case 1: // len1 pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_iRevStatus++; break; case 2: // len2 pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2]) { pPortParam->m_iRevStatus++; pPortParam->m_iNeedRevLength = buf[i] + 5; } else pPortParam->m_iRevStatus = 18; break; case 3: // 0x68 pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_iNeedRevLength--; if (0x68 == buf[i]) pPortParam->m_iRevStatus++; else pPortParam->m_iRevStatus = 18; break; case 4: // 正确接收数据 pPortParam->m_iNeedRevLength--; pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (pPortParam->m_iNeedRevLength > 0) break; if (buf[i] != 0x16) { pPortParam->m_iRevStatus = 18; break; } if (CheckShxyProtocolLpcError(pPortParam->m_au8RecvBuf, pPortParam->m_iRecvLen) == 1) { ShxyProtocolDataProcess(devno); pPortParam->m_iRevStatus = 0; pPortParam->RevCmdFlag = 1; } else { pPortParam->m_iRevStatus = 0; } pPortParam->m_iRecvLen = 0; break; case 255:// 错误接收数据 default: if (buf[i] == 0x68) { pPortParam->m_iRevStatus = 1; pPortParam->m_iRecvLen = 1; pPortParam->m_au8RecvBuf[0] = buf[i]; } else if (buf[i] == 0x16) { pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_iRevStatus = 0; pPortParam->m_iRecvLen = 0; } else { pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (pPortParam->m_iRecvLen > 200) { pPortParam->m_iRecvLen = 0; } } break; } } } //******************************************************************************** // 检查检验和是否正确 //******************************************************************************** int CheckShxyProtocolLpcError(u_char* msg, int len) { int bRetval = 0; int iCheckLen; if (0x68 == msg[0]) { if (msg[0] != msg[3]) return bRetval; if (msg[len - 1] != 0x16) return bRetval; if (msg[1] != msg[2]) return bRetval; iCheckLen = msg[1]; if (CalLpc(&msg[4], iCheckLen + 2) != msg[len - 2]) return bRetval; bRetval = 1; } return bRetval; } /********************************************************************************* 上海欣影传感器协议数据处理 **********************************************************************************/ void ShxyProtocolDataProcess(int devno) { float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/; uint16_t uDevAddr; uint8_t cmdidx; int i, j, aipnt, datanum; SERIAL_DEV_DEF *pPortParam; SIO_PARAM_SERIAL_DEF *curserial; char szbuf[128]; pPortParam = &srdt.ms_dev[devno]; curserial = &serialport[devparam[devno].commid]; //取出装置地址,开始处理地址+++ if (0x02 == curserial->m_au8RecvBuf[5]) { devparam[devno].devaddr = curserial->m_au8RecvBuf[4]; return; } cmdidx = curserial->m_au8RecvBuf[5]; aipnt = pPortParam->SameTypeDevIdx; uDevAddr = curserial->m_au8RecvBuf[4]; fvalua = &fvalue; memset(szbuf, 0, sizeof(szbuf)); if (0x06 == cmdidx) { if (0x08 != curserial->m_au8RecvBuf[1]) return; pPortParam->recvdatacnt++; if (pPortParam->recvdatacnt < 2) return; // ++++++++++++++++++++++++++++ //g_SelfTest.SensorsFault |= (0x800<m_au8RecvBuf[9]; *((uint8_t*)fvalua + 1) = curserial->m_au8RecvBuf[8]; *((uint8_t*)fvalua + 2) = curserial->m_au8RecvBuf[7]; *((uint8_t*)fvalua + 3) = curserial->m_au8RecvBuf[6]; if ((fvalue < -59) || (fvalue > 59)) { frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0; pPortParam->aiValue[0].EuValue *= (1 + frnb); } else pPortParam->aiValue[0].EuValue = fvalue; pPortParam->aiValue[0].AiState = SER_SAMPLE; //slantpntmsg[aipnt][0].EuValue = fvalue*slantpntmsg[aipnt][0].AiParam.fFactor\ // +slantpntmsg[aipnt][0].AiParam.EuValueDelta; //slantpntmsg[aipnt][0].AiState = 1; //if ((gDisSunRain & 0x20) == 0x20) { sprintf(szbuf, "倾角ID:%d slantangle X=%0.3f ", devparam[devno].devaddr, fvalue); //DebugLog(devparam[devno].commid, szbuf, 'V'); } //XslantSec[aipnt][srdt.SectimesamplingCnt[0]] = (short)slantpntmsg[aipnt][0].EuValue; //srdt.SectimesamplingCnt[0] += 1; *(uint8_t*)fvalua = curserial->m_au8RecvBuf[13]; *((uint8_t*)fvalua + 1) = curserial->m_au8RecvBuf[12]; *((uint8_t*)fvalua + 2) = curserial->m_au8RecvBuf[11]; *((uint8_t*)fvalua + 3) = curserial->m_au8RecvBuf[10]; //if ((gDisSunRain & 0x20) == 0x20) { sprintf(szbuf, "%sY =%0.3f ", szbuf, fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); } if ((fvalue < -59) || (fvalue > 59)) { frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0; pPortParam->aiValue[1].EuValue *= (1 + frnb); //slantpntmsg[aipnt][1].EuValue *= (1+frnb); } else pPortParam->aiValue[1].EuValue = fvalue; pPortParam->aiValue[1].AiState = SER_SAMPLE; /*slantpntmsg[aipnt][1].EuValue = fvalue*slantpntmsg[aipnt][1].AiParam.fFactor\ +slantpntmsg[aipnt][1].AiParam.EuValueDelta; slantpntmsg[aipnt][1].AiState = 1;*/ //YslantSec[aipnt][srdt.SectimesamplingCnt[1]] = (short)slantpntmsg[aipnt][1].EuValue; srdt.SectimesamplingCnt[1] += 1; } datanum = curserial->m_au8RecvBuf[6]; if ((0x08 != cmdidx) && (0x09 != cmdidx)) return; for (i = 0, j = 7; (i < datanum) && (j < 6 + curserial->m_au8RecvBuf[1]); i++, j += 5) { if (0x08 == cmdidx) fvalue = (curserial->m_au8RecvBuf[j + 1] << 24) + (curserial->m_au8RecvBuf[j + 2] << 16) + (curserial->m_au8RecvBuf[j + 3] << 8) + curserial->m_au8RecvBuf[j + 4]; else { *(uint8_t*)fvalua = curserial->m_au8RecvBuf[j + 4]; *((uint8_t*)fvalua + 1) = curserial->m_au8RecvBuf[j + 3]; *((uint8_t*)fvalua + 2) = curserial->m_au8RecvBuf[j + 2]; *((uint8_t*)fvalua + 3) = curserial->m_au8RecvBuf[j + 1]; } switch (curserial->m_au8RecvBuf[j]) { case 1: /*温度*/ if(devparam[devno].ProtocolIdx == WIND_PROTOCOL) break; if ((fvalue < -60) || (fvalue > 100)) { frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0; pPortParam->aiValue[AirTempNo].EuValue *= (1 + frnb); weatherpntmsg[AirTempNo].EuValue *= (1 + frnb); //weatherpntmsg[AirTempNo].AiState = SER_SAMPLE; } else { pPortParam->aiValue[AirTempNo].EuValue = fvalue; weatherpntmsg[AirTempNo].EuValue = fvalue; } pPortParam->aiValue[AirTempNo].AiState = SER_SAMPLE; weatherpntmsg[AirTempNo].AiState = SER_SAMPLE; //g_SelfTest.SensorsFault |= (0x01); //if ((gDisSunRain & 0x80) == 0x80) { sprintf(szbuf, "ID:%d 温度:%0.3f ", devparam[devno].devaddr, fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 2: /*气压*/ if(devparam[devno].ProtocolIdx == WIND_PROTOCOL) break; if ((fvalue < 550) || (fvalue > 1060)) { frnb = (GeneratingRandomNumber() % 41 - 20) / 10000.0; pPortParam->aiValue[AtmosNo].EuValue *= (1 + frnb); weatherpntmsg[AtmosNo].EuValue *= (1 + frnb); } else { pPortParam->aiValue[AtmosNo].EuValue = fvalue; weatherpntmsg[AtmosNo].EuValue = fvalue; } pPortParam->aiValue[AtmosNo].AiState = SER_SAMPLE; weatherpntmsg[AtmosNo].AiState = SER_SAMPLE; //g_SelfTest.SensorsFault |= (0x10); //if ((gDisSunRain & 0x80) == 0x80) { sprintf(szbuf, "气压:%0.3f ", fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 3: /*湿度*/ if(devparam[devno].ProtocolIdx == WIND_PROTOCOL) break; if ((fvalue < 0) || (fvalue > 100)) { frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0; pPortParam->aiValue[HumidityNo].EuValue *= (1 + frnb); weatherpntmsg[HumidityNo].EuValue *= (1 + frnb); } else { pPortParam->aiValue[HumidityNo].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor + pPortParam->aiValue[1].AiParam.EuValueDelta;*/ weatherpntmsg[HumidityNo].EuValue = fvalue;/*weatherpntmsg[HumidityNo].AiParam.fFactor + weatherpntmsg[HumidityNo].AiParam.EuValueDelta;*/ } pPortParam->aiValue[HumidityNo].AiState = SER_SAMPLE; weatherpntmsg[HumidityNo].AiState = SER_SAMPLE; //g_SelfTest.SensorsFault |= (0x02); //if ((gDisSunRain & 0x80) == 0x80) { sprintf(szbuf, "湿度:%0.3f ", fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 4: /*雨量*/ if ((fvalue < 0) || (fvalue > 10000)) { frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0; pPortParam->aiValue[RainfallNo].EuValue *= (1 + frnb); weatherpntmsg[RainfallNo].EuValue *= (1 + frnb); } else { pPortParam->aiValue[RainfallNo].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor + pPortParam->aiValue[1].AiParam.EuValueDelta;*/ weatherpntmsg[RainfallNo].EuValue = fvalue;/*weatherpntmsg[HumidityNo].AiParam.fFactor + weatherpntmsg[HumidityNo].AiParam.EuValueDelta;*/ } pPortParam->aiValue[RainfallNo].AiState = SER_SAMPLE; weatherpntmsg[RainfallNo].AiState = SER_SAMPLE; //g_SelfTest.SensorsFault |= (0x02); //if ((gDisSunRain & 0x80) == 0x80) { sprintf(szbuf, "雨量:%0.3f ", fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 5: /*日照*/ if ((fvalue < 0) || (fvalue > 10000)) { frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0; pPortParam->aiValue[OpticalRadiationNo].EuValue *= (1 + frnb); weatherpntmsg[OpticalRadiationNo].EuValue *= (1 + frnb); } else { pPortParam->aiValue[OpticalRadiationNo].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor + pPortParam->aiValue[1].AiParam.EuValueDelta;*/ weatherpntmsg[OpticalRadiationNo].EuValue = fvalue;/*weatherpntmsg[HumidityNo].AiParam.fFactor + weatherpntmsg[HumidityNo].AiParam.EuValueDelta;*/ } pPortParam->aiValue[OpticalRadiationNo].AiState = SER_SAMPLE; weatherpntmsg[OpticalRadiationNo].AiState = SER_SAMPLE; { sprintf(szbuf, "日照:%0.3f ", fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 6: /*风速*/ if ((fvalue < 0) || (fvalue > 80)) { frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0; pPortParam->aiValue[WindSpeedNo].EuValue *= (1 + frnb); weatherpntmsg[WindSpeedNo].EuValue *= (1 + frnb); } else { pPortParam->aiValue[WindSpeedNo].EuValue = fvalue;/*pPortParam->aiValue[2].AiParam.fFactor + pPortParam->aiValue[2].AiParam.EuValueDelta;*/ weatherpntmsg[WindSpeedNo].EuValue = fvalue;/*weatherpntmsg[WindSpeedNo].AiParam.fFactor + weatherpntmsg[WindSpeedNo].AiParam.EuValueDelta;*/ } pPortParam->aiValue[WindSpeedNo].AiState = SER_SAMPLE; weatherpntmsg[WindSpeedNo].AiState = SER_SAMPLE; //g_SelfTest.SensorsFault |= (0x04); //if ((gDisSunRain & 0x10) == 0x10) { //fwind = fvalue/1000*0.95; //if(fvalue/1000 > 25) // fwind -= 1.2; //sprintf(szbuf, "风速:%0.3f ", fwind); sprintf(szbuf, "ID:%d 风速:%0.3f ", devparam[devno].devaddr, fvalue); } break; case 7: /*风向*/ if ((fvalue / 1000 < 0) || (fvalue / 1000 > 359.99)) { frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0; pPortParam->aiValue[WindDirectionNo].EuValue *= (1 + frnb); weatherpntmsg[WindDirectionNo].EuValue *= (1 + frnb); } else { pPortParam->aiValue[WindDirectionNo].EuValue = fvalue;/*pPortParam->aiValue[3].AiParam.fFactor + pPortParam->aiValue[3].AiParam.EuValueDelta;*/ weatherpntmsg[WindDirectionNo].EuValue = fvalue;/*weatherpntmsg[WindDirectionNo].AiParam.fFactor + weatherpntmsg[WindDirectionNo].AiParam.EuValueDelta;*/ } pPortParam->aiValue[WindDirectionNo].AiState = SER_SAMPLE; weatherpntmsg[WindDirectionNo].AiState = SER_SAMPLE; //g_SelfTest.SensorsFault |= (0x08); //if ((gDisSunRain & 0x10) == 0x10) { sprintf(szbuf, "%s 风向:%0.3f ", szbuf, fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 8: /*拉力*/ pPortParam->recvdatacnt++; if (pPortParam->recvdatacnt < 2) break; pPortParam->aiValue[0].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor\ +pPortParam->aiValue[0].AiParam.EuValueDelta;*/ //rallypntmsg[aipnt][0].EuValue = fvalue*rallypntmsg[aipnt][0].AiParam.fFactor\ // +rallypntmsg[aipnt][0].AiParam.EuValueDelta; pPortParam->aiValue[0].AiState = SER_SAMPLE; //rallypntmsg[aipnt][0].AiState = 1; sprintf(szbuf, "地址%d拉力:%0.3fKg ", devparam[devno].devaddr, fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); //} break; case 9: /*倾角传感器X轴倾角*/ if ((fvalue < -59) || (fvalue > 59)) { frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0; pPortParam->aiValue[0].EuValue *= (1 + frnb); //slantpntmsg[aipnt][0].EuValue *= (1+frnb); } else { pPortParam->aiValue[0].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor\ +pPortParam->aiValue[0].AiParam.EuValueDelta;*/ //slantpntmsg[aipnt][0].EuValue = fvalue*slantpntmsg[aipnt][0].AiParam.fFactor\ //+slantpntmsg[aipnt][0].AiParam.EuValueDelta; } pPortParam->aiValue[0].AiState = SER_SAMPLE; //slantpntmsg[aipnt][0].AiState = 1; sprintf(szbuf, "倾角ID:%d slantangle X=%0.3f ", devparam[devno].devaddr, fvalue); break; case 10: /*倾角传感器Y轴倾角*/ sprintf(szbuf, "%s Y =%0.3f ", szbuf, fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); if ((fvalue < -59) || (fvalue > 59)) { frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0; pPortParam->aiValue[1].EuValue *= (1 + frnb); } else { pPortParam->aiValue[1].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor\ +pPortParam->aiValue[1].AiParam.EuValueDelta;*/ } pPortParam->aiValue[1].AiState = SER_SAMPLE; //slantpntmsg[aipnt][1].AiState = 1; break; } } } void delete_old_files(const char *path, int days) { struct stat file_stat; struct tm *file_tm; time_t now = time(NULL); DIR *dir = opendir(path); struct dirent *entry; char szbuf[1024]; char fullpath[256]; memset(szbuf, 0, sizeof(szbuf)); if (!dir) { sprintf(szbuf, "delete_old_files opendir %s error ", path); DebugLog(8, szbuf, 'E'); return; } while ((entry = readdir(dir))) { memset(szbuf, 0, sizeof(szbuf)); if (entry->d_type == DT_REG) { // 只处理普通文件 snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name); if (stat(fullpath, &file_stat) == -1) { perror("stat"); strcpy(szbuf, "stat"); DebugLog(8, szbuf, 'E'); continue; } localtime_r(&(file_stat.st_mtime), file_tm); //file_tm = localtime(&(file_stat.st_mtime)); if (difftime(now, mktime(file_tm)) > days * 24 * 60 * 60) { if (unlink(fullpath) == -1) { // 删除文件 perror("unlink"); } } } } closedir(dir); } /********************************************************************************* 把16进制和10进制ASCII字符串转换成int整数 *********************************************************************************/ int ATOI(char *buf) { int i, ilen, iRetVal; if (NULL == buf) return 0; ilen = strlen(buf); if (ilen > 2) { if ((buf[0] == '0') && ((buf[1] == 'x') || (buf[1] == 'X'))) { iRetVal = 0; for (i = 2; i < ilen; i++) { iRetVal = (iRetVal << 4) + HexCharToInt(buf[i]); } } else { iRetVal = atoi(buf); } } else { iRetVal = atoi(buf); } return iRetVal; } #if 0 // 控制关闭传感器电源 void Gm_CtrlCloseSensorsPower(int devidx) { if ((devidx < 0) || (devidx > MAX_SERIAL_DEV_NUM - 1)) return; srdt.ms_dev[devidx].uOpenPowerFlag = CLOSEPOWER; } // 检查传感器电源是否应该关闭或打开 void Gm_CheckSensorsPower(void) { int i, j; for (i = 0; i < MAX_SERIAL_DEV_NUM - 2; i++) { if ((1 > srdt.ms_dev[i].ProtocolIdx) || (INVALID_PROTOCOL <= srdt.ms_dev[i].ProtocolIdx)) continue; if ((PELCO_P_PROTOCOL == srdt.ms_dev[i].ProtocolIdx) || (PELCO_D_PROTOCOL == srdt.ms_dev[i].ProtocolIdx) || (SERIALCAMERA_PROTOCOL == srdt.ms_dev[i].ProtocolIdx)) continue; // 需要传感器处于上电状态 for (j = 0; j < MAX_SERIAL_DEV_NUM - 2; j++) { if ((srdt.ms_dev[i].PowerPort == srdt.ms_dev[j].PowerPort) && (srdt.ms_dev[j].uOpenPowerFlag == OPENPOWER)) break; } if (j < MAX_SERIAL_DEV_NUM - 2) continue; } } #endif int GeneratingRandomNumber(void) { int ictime, randomdate; /* 生成随机数n-m -> rand()%(m-n+1)+n*/ ictime = (int)time(NULL); srand((uint32_t)ictime); randomdate = rand(); return randomdate; } /* 串口启动接口函数 开始*/ void Collect_sensor_data() { #if 0 int i; for (i = 0; i < MAX_SERIAL_DEV_NUM; i++) { devparam[i].IsNoInsta = sensorParam[i].IsNoInsta; if (0 == sensorParam[i].IsNoInsta) continue; devparam[i].ProtocolIdx = sensorParam[i].SensorsType; devparam[i].devaddr = sensorParam[i].devaddr; devparam[i].baudrate = getBaudrate(sensorParam[i].baudrate); memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname)); memmove(devparam[i].pathname, sensorParam[i].pathname, sizeof(devparam[i].pathname)); devparam[i].databit = sensorParam[i].databit; devparam[i].stopbit = (int)(sensorParam[i].stopbit * 10); devparam[i].CameraChannel = sensorParam[i].CameraChannel; devparam[i].Phase = sensorParam[i].Phase; } #endif #if 1 pthread_mutex_lock(&serial_mutex); // 加锁 static int ideletefile = 0; char logbuf[64]; time_t now; struct tm t0; // const char *path = logPath; // 指定目录路径 // int days = 15; // 删除15天前的log文件 sprintf(logbuf, "进入程序时间:%lld, ideletefile=%d", get_msec(), ideletefile); DebugLog(8, logbuf, 'I'); // now = time(NULL); // localtime_r(&now, &t0); // if ((0 == t0.tm_hour) && (0 == ideletefile)) // { // delete_old_files(path, days); // ideletefile++; // } // if (0 < t0.tm_hour) // ideletefile = 0; #endif GM_StartSerialComm(); pthread_mutex_unlock(&serial_mutex); // 解锁 } int Gm_SetCameraSerialPortParam(int fd, unsigned int baud) { int ret; char szbuf[128]; ret = set_port_attr(fd, baud, 8, 1, 'n', 0, 0);/*9600 8n1 */ if (ret < 0) { memset(szbuf, 0, sizeof(szbuf)); strcpy(szbuf, "摄像机串口波特率等参数设置错误!"); DebugLog(0, szbuf, 'E'); return -1; } return ret; } int Gm_OpenCameraSerial(SIO_PARAM_SERIAL_DEF *pPortParam, const char *serfile, unsigned int baud) { int fd = -1; char szbuf[512]; unsigned int serbaud; memset(szbuf, 0, sizeof(szbuf)); if (pPortParam->fd <= 0) { fd = ::open(serfile, O_RDWR | O_NDELAY); if (fd < 0) { sprintf(szbuf, "摄像机串口%s打开失败!fd=%d", serfile, fd); DebugLog(0, szbuf, 'E'); return -1; } sprintf(szbuf, "摄像机打开串口%s成功!fd=%d 波特率:%d", serfile, fd, baud); DebugLog(0, szbuf, 'I'); pPortParam->fd = fd; serbaud = getBaudrate(baud); Gm_SetCameraSerialPortParam(fd, serbaud); return 0; } sprintf(szbuf, "摄像机串口%s已经打开!fd=%d", serfile, pPortParam->fd); DebugLog(0, szbuf, 'I'); return 0; } int GM_CameraComSend(unsigned char * cSendBuf, size_t nSendLen, int fd) { int i, len; char szbuf[512]; memset(szbuf, 0, sizeof(szbuf)); len = write(fd, cSendBuf, (size_t)nSendLen);/* 向串囗发送字符串 */ if (len < 0) { strcpy(szbuf, "write data error "); DebugLog(0, szbuf, 'E'); return -1; } else if (len > 0) { ; } return len; } void SendCameraCmdFormPollCmdBuf(SIO_PARAM_SERIAL_DEF *pPortParam) { char buf[128]; int len, ret; int64_t lctime; //char szbuf[512]; memset(buf, 0, sizeof(buf)); lctime = get_msec(); if (pPortParam->ForceWaitFlag && pPortParam->ForceWaitCnt) { pPortParam->ForceWaitCnt--; return; } if (pPortParam->SendCmdFlag && (pPortParam->RevCmdFlag == 0)) { //pPortParam->RetryTimeCnt++; //strcpy(szbuf, "1-send"); //DebugLog(0, szbuf, 'E'); if ((lctime - pPortParam->RetryTimeCnt > 3 * pPortParam->RetryTime) || (lctime - pPortParam->RetryTimeCnt < 0)) { pPortParam->RetryTimeCnt = lctime; return; } if (lctime - pPortParam->RetryTimeCnt < pPortParam->RetryTime) { return; } pPortParam->RetryTimeCnt = lctime; pPortParam->RetryCnt++; if (pPortParam->RetryCnt > pPortParam->Retry) { ClearCameraCmdFormPollCmdBuf(pPortParam); } else { pPortParam->SendCmdFlag = 0; pPortParam->RevCmdFlag = 0; pPortParam->ReSendCmdFlag = 1; } } if (pPortParam->SendCmdFlag && pPortParam->RevCmdFlag) { //strcpy(szbuf, "2-send"); //DebugLog(0, szbuf, 'E'); // 清除当前命令 ClearCameraCmdFormPollCmdBuf(pPortParam); } if (pPortParam->WaitTime > 0) { if ((lctime - pPortParam->WaitTimeCnt > 30 * pPortParam->WaitTime) || (lctime - pPortParam->WaitTimeCnt < 0)) { pPortParam->WaitTimeCnt = lctime; return; } if (lctime - pPortParam->WaitTimeCnt < pPortParam->WaitTime) { return; } } pPortParam->WaitTimeCnt = lctime; if (pPortParam->ReSendCmdFlag) len = pPortParam->cmdlen; else { len = pPortParam->cmdlen; pPortParam->RetryCnt = 0; } if (len == 0) return; pPortParam->m_iRecvLen = 0; // 当发送一条新指令时,清除接收状态 pPortParam->m_iRevStatus = 0; if (pPortParam->fd < 0) return; len = GM_CameraComSend(&pPortParam->PollCmd[2], pPortParam->cmdlen - 2, pPortParam->fd); if (len < 1) { strcpy(buf, "摄像机串口, 发送命令失败!"); DebugLog(0, buf, 'E'); } else { strcpy(buf, "摄像机串口命令:"); BytestreamLOG(0, buf, &pPortParam->PollCmd[2], len, 'D'); sprintf(buf, "sendtimeconst= %lld", (long long)(lctime - pPortParam->lsendtime)); DebugLog(0, buf, 'W'); pPortParam->lsendtime = lctime; } pPortParam->SendCmdFlag = 1; pPortParam->ReSendCmdFlag = 0; pPortParam->RevCmdFlag = 0; pPortParam->RetryTimeCnt = lctime; pPortParam->ForceWaitCnt = pPortParam->PollCmd[0] * 256 + pPortParam->PollCmd[1] + TIMER_CNT - 1; pPortParam->ForceWaitCnt /= TIMER_CNT; if (pPortParam->ForceWaitCnt) { pPortParam->ForceWaitFlag = 1; } } void Gm_FindCameraCommand(SIO_PARAM_SERIAL_DEF *pPortParam) { int flag; // 发送缓冲区中命令 接收到了应答报文,紧接着进行缓冲区清理 SendCameraCmdFormPollCmdBuf(pPortParam); // 串口已经被占用则直接跳过 if (pPortParam->cmdlen > 0) return; flag = -1; flag = FindNextCameraPhotoCommand(pPortParam); if (flag == -1) return; // 发送缓冲区中命令 生成了命令之后紧接着进行命令发送 SendCameraCmdFormPollCmdBuf(pPortParam); } int GM_IsCloseCamera(SIO_PARAM_SERIAL_DEF *pPortParam) { int i, j; char buf[256]; int64_t lctime; lctime = get_msec(); memset(buf, 0, sizeof(buf)); if (0 > pPortParam->SerialCmdidx) { if ((SER_STARTSAMPLE == pPortParam->image.state) || (SER_SAMPLE == pPortParam->image.state)) pPortParam->image.state = SER_SAMPLEFAIL; else if (PHOTO_SAVE_SUCC == pPortParam->image.state) pPortParam->image.state = PHOTO_SAVE_SUCC; strcpy(buf, "摄像机使用完毕!可以关闭摄像机电源!"); DebugLog(0, buf, 'I'); memset(&serialport[0].image, 0, sizeof(PHOTO_DEF)); memmove((void *)&serialport[0].image, (void*)&pPortParam->image, sizeof(PHOTO_DEF)); if(pPortParam->fd >= 0) { close(pPortParam->fd); pPortParam->fd = -1; } } return pPortParam->SerialCmdidx; } void GM_CameraSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam) { int i, recvlen; u_char recvbuf[RECVDATA_MAXLENTH]; char buf[256]; int64_t t0, t1; t0 = get_msec(); memset(recvbuf, 0, sizeof(recvbuf)); if (pPortParam->fd <= 0) return; i=0; recvlen = 0; for(;;) { i += recvlen; recvlen = read(pPortParam->fd, &recvbuf[i], sizeof(recvbuf)-i);/* 在串口读取字符串 */ t1 = get_msec(); if(t1-t0 >= 350) { i += recvlen; break; } } recvlen = i; if (recvlen < 1) return; #if 1 sprintf(buf, "收到BD, %d字节数据:", recvlen); BytestreamLOG(0, buf, recvbuf, recvlen, 'I'); #endif CameraRecvData(pPortParam, recvbuf, recvlen); } int GM_CameraSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam) { int flag = -1; //GM_CameraSerialComRecv(pPortParam); Gm_FindCameraCommand(pPortParam); GM_CameraSerialComRecv(pPortParam); flag = GM_IsCloseCamera(pPortParam); return flag; } #if 1 // 启动使用串口拍照 int GM_StartSerialCameraPhoto(int phototime, unsigned char channel, int cmdidx, unsigned char bImageSize, unsigned char presetno, const char *serfile, unsigned int baud, int addr) { int flag = 0; char szbuf[128], logbuf[128]; SIO_PARAM_SERIAL_DEF *cameraport; cameraport = (SIO_PARAM_SERIAL_DEF*)malloc(sizeof(SIO_PARAM_SERIAL_DEF)); srdt.RephotographCnt = 0; cameraport->cameraaddr = addr; cameraport->Retry = 0; cameraport->RetryTime = 2000; cameraport->WaitTime = 0; cameraport->m_iRevStatus = 0; cameraport->m_iRecvLen = 0; cameraport->m_iNeedRevLength = 0; cameraport->fd = -1; memset(cameraport->m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 ClearCameraCmdFormPollCmdBuf(cameraport); flag = Gm_OpenCameraSerial(cameraport, serfile, baud); #if 1 memset(szbuf, 0, sizeof(szbuf)); srdt.iLastGetPhotoNo = -1; if (TAKE_PHOTO == cmdidx) cameraport->image.state = SER_STARTSAMPLE; if ((TAKE_PHOTO == cmdidx) && (srdt.presetno > 0)) { cameraport->SerialCmdidx = MOVE_PRESETNO; srdt.iLastGetPhotoNo = cmdidx; } else cameraport->SerialCmdidx = cmdidx; cameraport->FirstCmdTimeCnt = get_msec(); srdt.sendphotocmdcnt = 0; //sprintf(szbuf, "摄像机"); //flag = 1; //if (1 == srdt.ms_dev[i].IsNeedSerial) //{ //sprintf(logbuf, "装置%d, IsNoInsta=%d, 类型:%s", i + 1, devparam[i].IsNoInsta, szbuf); //DebugLog(8, logbuf, 'I'); //Gm_OpenSensorsPower(); //Gm_OpenCameraSerial(&cameraport); //} #endif if(-1 == flag) { if(NULL != cameraport) { free(cameraport); cameraport = NULL; } return -1; } if (0x00 == flag) { sprintf(szbuf, "摄像机启动串口定时器!"); DebugLog(8, szbuf, 'I'); for (;;) { usleep(10); //LOGW("polltime=%ldms", get_msec()-polltime); //polltime = get_msec(); if (GM_CameraSerialTimer(cameraport) < 0) { DebugLog(8, "退出操作摄像机流程!", 'V'); //sleep(3); break; } } } if(NULL != cameraport) { free(cameraport); cameraport = NULL; } return 0; } #endif int CameraPhotoCmd(int phototime, unsigned char channel, int cmdidx, unsigned char bImageSize, unsigned char presetno, const char *serfile, unsigned int baud, int addr) { pthread_mutex_lock(&camera_mutex); int flag = 0; srdt.bImageSize = bImageSize; srdt.presetno = presetno; srdt.sendphototime = phototime; flag = GM_StartSerialCameraPhoto(phototime, channel, cmdidx, bImageSize, presetno, serfile, baud, addr); pthread_mutex_unlock(&camera_mutex); // 解锁 return flag; } int QueryPtzState(PTZ_STATE *ptz_state, int cmdidx, const char *serfile, unsigned int baud, int addr) { pthread_mutex_lock(&camera_mutex); int flag = 0; char szbuf[128], logbuf[128]; SIO_PARAM_SERIAL_DEF *cameraport=NULL; if(NULL == ptz_state) return -1; if((NOTIFY_PTZ_CLOSE == cmdidx) || (QUERY_PTZ_STATE == cmdidx)) ; else return -1; cameraport = (SIO_PARAM_SERIAL_DEF*)malloc(sizeof(SIO_PARAM_SERIAL_DEF)); cameraport->cameraaddr = addr; cameraport->Retry = 0; cameraport->RetryTime = 1000; cameraport->WaitTime = 0; cameraport->m_iRevStatus = 0; cameraport->m_iRecvLen = 0; cameraport->m_iNeedRevLength = 0; cameraport->fd = -1; memset(cameraport->m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 ClearCameraCmdFormPollCmdBuf(cameraport); flag = Gm_OpenCameraSerial(cameraport, serfile, baud); #if 1 memset(szbuf, 0, sizeof(szbuf)); srdt.iLastGetPhotoNo = -1; cameraport->SerialCmdidx = cmdidx; cameraport->FirstCmdTimeCnt = get_msec(); cameraport->sendptzstatecmd = 0; #endif if(-1 == flag) { if(NULL != cameraport) { free(cameraport); cameraport = NULL; } return -1; } if (0x00 == flag) { ::memset(szbuf, 0, sizeof(szbuf)); strcpy(szbuf, "云台状态查询启动串口定时器!"); DebugLog(8, szbuf, 'I'); //sprintf(szbuf, "下发命令sendptzstatecmd=%d!", cameraport->sendptzstatecmd); //DebugLog(0, szbuf, 'I'); for (;;) { usleep(10); //LOGW("polltime=%ldms", get_msec()-polltime); //polltime = get_msec(); flag = GM_CameraSerialTimer(cameraport); if (flag < 0) { DebugLog(8, "退出查询云台状态流程!", 'V'); memmove((void*)ptz_state, &cameraport->ptz_state, sizeof(PTZ_STATE)); if(flag == -2) flag = -1; else flag = 0; //sleep(3); break; } } } if(NULL != cameraport) { free(cameraport); cameraport = NULL; } pthread_mutex_unlock(&camera_mutex); // 解锁 return flag; } int Query_BDGNSS_Data(BD_GNSS_DATA *BD_data, int samptime, const char *serfile, unsigned int baud) { pthread_mutex_lock(&bd_mutex); int flag = 0; char szbuf[128], logbuf[128]; SIO_PARAM_SERIAL_DEF *cameraport=NULL; if(NULL == BD_data) return -1; if(samptime < 5) samptime = 5; cameraport = (SIO_PARAM_SERIAL_DEF*)malloc(sizeof(SIO_PARAM_SERIAL_DEF)); cameraport->Retry = 0; cameraport->RetryTime = 1000; cameraport->WaitTime = 0; cameraport->m_iRevStatus = 0; cameraport->m_iRecvLen = 0; cameraport->m_iNeedRevLength = 0; cameraport->fd = -1; memset(cameraport->m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 ClearCameraCmdFormPollCmdBuf(cameraport); flag = Gm_OpenCameraSerial(cameraport, serfile, baud); #if 1 memset(szbuf, 0, sizeof(szbuf)); srdt.iLastGetPhotoNo = -1; cameraport->SerialCmdidx = -1; cameraport->FirstCmdTimeCnt = get_msec(); #endif if(-1 == flag) { if(NULL != cameraport) { free(cameraport); cameraport = NULL; } return -1; } if (0x00 == flag) { sprintf(szbuf, "北斗定位数据查询启动串口定时器!"); DebugLog(8, szbuf, 'I'); for (;;) { usleep(10); //LOGW("polltime=%ldms", get_msec()-polltime); //polltime = get_msec(); flag = GM_BdSerialTimer(cameraport); if(get_msec() - cameraport->FirstCmdTimeCnt > samptime*1000) { DebugLog(8, "退出查询北斗定位数据流程!", 'V'); memmove((void*)BD_data, &cameraport->bd_data, sizeof(BD_GNSS_DATA)); break; } } } if(NULL != cameraport) { free(cameraport); cameraport = NULL; } pthread_mutex_unlock(&bd_mutex); // 解锁 return flag; } int GM_BdSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam) { int flag = 0; GM_BdSerialComRecv(pPortParam); return flag; } void GM_BdSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam) { int i, recvlen; u_char recvbuf[RECVDATA_MAXLENTH]; char buf[RECVDATA_MAXLENTH+256]; int64_t t0, t1; t0 = get_msec(); memset(recvbuf, 0, sizeof(recvbuf)); if (pPortParam->fd <= 0) return; i=0; recvlen = 0; memset(recvbuf, 0, sizeof(recvbuf)); for(;;) { i += recvlen; recvlen = read(pPortParam->fd, &recvbuf[i], sizeof(recvbuf)-i);/* 在串口读取字符串 */ t1 = get_msec(); if(t1-t0 >= 350) break; } recvlen = i; if (recvlen < 1) return; #if 1 sprintf(buf, "收到BD, %d字节数据:%s", recvlen, recvbuf); DebugLog(0, (char*)recvbuf, 'I'); #endif BdRecvData(pPortParam, recvbuf, recvlen); } void BdRecvData(SIO_PARAM_SERIAL_DEF *pPortParam, u_char *buf, int len) { int i; unsigned char bdxor=0, srcxor=0; for (i = 0; i < len; i++) { switch (pPortParam->m_iRevStatus) { case 0: // 搜索起始符 '$' pPortParam->m_iRecvLen = 0; memset(pPortParam->m_au8RecvBuf, 0,sizeof(pPortParam->m_au8RecvBuf)); if ('$' == buf[i]) { pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_iRevStatus = 1; // 进入数据接收状态 } break; case 1: // 接收数据直到 '*' if (pPortParam->m_iRecvLen >= RECVDATA_MAXLENTH) { // 缓冲区溢出,重置状态 pPortParam->m_iRevStatus = 0; pPortParam->m_iRecvLen = 0; break; } pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (buf[i] == '*') { pPortParam->m_iRevStatus = 2; // 进入校验码接收状态 } break; case 2: // 接收校验码(2字节十六进制)和 if (pPortParam->m_iRecvLen >= RECVDATA_MAXLENTH) { // 缓冲区溢出,重置状态 pPortParam->m_iRevStatus = 0; pPortParam->m_iRecvLen = 0; break; } pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; // 检测到换行符(0x0A),检查前一个字符是否为回车符(0x0D) if (buf[i] == 0x0A) { if (pPortParam->m_iRecvLen >= 5 && pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2] == 0x0D) { // 提取校验码(*后的两个字符) char hex_str[3] = { (char)pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 4], (char)pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 3], '\0' }; srcxor = (uint8_t)strtol(hex_str, NULL, 16); // 计算校验值(从$后的第一个字符到*前的字符) uint8_t calc_xor = BDXorCheck(&pPortParam->m_au8RecvBuf[1],pPortParam->m_iRecvLen - 6);// 长度 = 总长度 - ($ + *HH + \r\n) if (srcxor == calc_xor) { BD_NMEA0183_PortDataProcess(pPortParam); pPortParam->RevCmdFlag = 1; } // 重置状态,准备接收下一帧 pPortParam->m_iRevStatus = 0; pPortParam->m_iRecvLen = 0; } else { // 格式错误,丢弃数据 pPortParam->m_iRevStatus = 0; pPortParam->m_iRecvLen = 0; } } break; case 255:// 错误接收数据 default: if (buf[i] == '$') { pPortParam->m_iRevStatus = 1; pPortParam->m_iRecvLen = 1; pPortParam->m_au8RecvBuf[0] = buf[i]; } else { pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if (pPortParam->m_iRecvLen > 200) { pPortParam->m_iRecvLen = 0; } } break; } } } /* $BDRMC,023656.00,A,2240.61563,N,11359.86512,E,0.16,,140324,,,A,V*2C $BDVTG,,,,,0.16,N,0.30,K,A*2F $BDGGA,023656.00,2240.61563,N,11359.86512,E,1,23,0.7,96.53,M,-3.52,M,,*5B $BDGSA,A,3,01,02,03,04,05,06,07,09,10,16,19,20,1.0,0.7,0.8,4*30 $BDGSV,6,1,23,01,45,125,38,02,46,235,40,03,61,189,46,04,32,112,37,1*7B $BDGLL,2240.61563,N,11359.86512,E,023656.00,A,A*78 $BDZDA,023656.00,14,03,2024,00,00*71 $GPTXT,01,01,01,ANTENNA OPEN*25 GLL:经度、纬度、UTC 时间 GSA:北斗接收机操作模式,定位使用的卫星,DOP 值 GSV:可见北斗卫星信息、仰角、方位角、信噪比(SNR) RMC:时间、日期、位置、速度 VTG:地面速度信息 ZDA: 时间、日期 TXT:用于天线状态检测 */ void BD_NMEA0183_PortDataProcess(SIO_PARAM_SERIAL_DEF *curserial) { BD_NMEA0183_PROC_FUNC bd_nmea0183_call[] = { {"$BDRMC",BD_get_BDRMC_data},/* 时间、日期、位置、速度*/ {"$BDVTG",NULL},/* 地面速度信息*/ {"$BDGGA",NULL},/* 时间、位置、定位类型*/ {"$BDGSA",NULL},/* 北斗接收机操作模式,定位使用的卫星,DOP 值 */ {"$BDGSV",NULL},/* 可见北斗卫星信息、仰角、方位角、信噪比(SNR)*/ {"$BDGLL",NULL},/* 经度、纬度、UTC 时间*/ {"$BDZDA",NULL},/* 时间、日期 */ {"$GPTXT",NULL},/* 用于天线状态检测*/ };/* irows*/ int i=0, irows; char szbuf[512]; //char *cmd=NULL, *sourestr=NULL; //RTUMSG rtumsg; if(NULL == curserial) return; irows = sizeof(bd_nmea0183_call)/sizeof(BD_NMEA0183_PROC_FUNC); memset(szbuf, 0, sizeof(szbuf)); //sprintf(szbuf, "rows = %d", irows); DebugLog(0, (char*)curserial->m_au8RecvBuf, 'I'); #if 0 memset((void*)rtumsg.MsgData, 0, sizeof(rtumsg.MsgData)); memcpy((void*)rtumsg.MsgData, (void*)curserial->m_au8RecvBuf, curserial->m_iRecvLen); rtumsg.MsgLen = curserial->m_iRecvLen; /* 析出关键字符串*/ cmd = (char *)rtumsg.MsgData; sourestr = strstr((char *)rtumsg.MsgData, ","); *sourestr = 0; sprintf(szbuf, "cmd_len = %d, cmd:%s", strlen(cmd), cmd); DebugLog(0, szbuf, 'I'); #endif for(i=0; im_au8RecvBuf, bd_nmea0183_call[i].cmd_name)) { sprintf(szbuf, "cmd_name[%d]:%s", i, bd_nmea0183_call[i].cmd_name); DebugLog(0, szbuf, 'I'); if(NULL != bd_nmea0183_call[i].recv_process) bd_nmea0183_call[i].recv_process(curserial); break; } } if(i >= irows) return; } int BD_get_BDRMC_data(SIO_PARAM_SERIAL_DEF *curserial) { const int UTC_TIME = 1; const int STATUS = 2; const int LAT = 3; const int ULAT = 4; const int LON = 5; const int ULON = 6; const int DATE = 9; double dvalue; int total_fields=0, ivalue; char **result = NULL; char buffer[128]; // 存储格式化时间的缓冲区 if(NULL == curserial) return -1; /* 1 $--RMC 字符串 消息 ID,RMC 语句头,’--‘为系统标识 2 UTCtime hhmmss.ss 当前定位的 UTC 时间 3 status 字符串 位置有效标志。 V=接收机警告,数据无效 A=数据有效 4 lat ddmm.mmmmm 纬度,前 2 字符表示度,后面的字符表示分 5 uLat 字符 纬度方向:N-北,S-南 6 lon dddmm.mmmmm 经度,前 3 字符表示度,后面的字符表示分 7 uLon 字符 经度方向:E-东,W-西 8 spd 数值 对地速度,单位为节 9 cog 数值 对地真航向,单位为度 10 date ddmmyy 日期(dd 为日,mm 为月,yy 为年) 11 mv 数值 磁偏角,单位为度。固定为空 12 mvE 字符 磁偏角方向:E-东,W-西。固定为空 13 mode 字符 定位模式标志(备注[1]) 14 navStatus 字符 导航状态标示符(V 表示系统不输出导航状态信息) 仅 NMEA 4.1 及以上版本有效 15 CS 16 进制数值 校验和,$和*之间(不包括$和*)所有字符的异或结果 16 字符 回车与换行符*/ result = BD_NMEA0183_SplitString((char *)curserial->m_au8RecvBuf, &total_fields); if(NULL == result) return -1; dvalue = ::atof(result[UTC_TIME]); curserial->bd_data.UTC_time.tm_sec = (int)dvalue%100; curserial->bd_data.UTC_time.tm_min = (int)dvalue/100%100; curserial->bd_data.UTC_time.tm_hour = (int)dvalue/10000; curserial->bd_data.ms_time = (dvalue - ((int)dvalue/1))*1000; curserial->bd_data.status = result[STATUS][0]; dvalue = ::atof(result[LAT]); curserial->bd_data.lat = ((int)dvalue/100)+(dvalue - ((int)dvalue/100*100))/60; curserial->bd_data.uLat = result[ULAT][0]; dvalue = ::atof(result[LON]); curserial->bd_data.lon = ((int)dvalue/100)+(dvalue - ((int)dvalue/100*100))/60; curserial->bd_data.uLon = result[ULON][0]; ivalue = ::atoi(result[DATE]); ALOGD("%d", ivalue); curserial->bd_data.UTC_time.tm_mday = ivalue/10000; ALOGD("D:%d", curserial->bd_data.UTC_time.tm_mday); curserial->bd_data.UTC_time.tm_mon = ivalue/100%100-1; ALOGD("M:%d", curserial->bd_data.UTC_time.tm_mon); curserial->bd_data.UTC_time.tm_year = ivalue%100+100; ALOGD("Y:%d", curserial->bd_data.UTC_time.tm_year); ::memset(buffer, 0, sizeof(buffer)); // 使用 strftime 格式化时间 strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &curserial->bd_data.UTC_time); DebugLog(0, (char*)buffer, 'I'); ::sprintf(buffer, "ms:%d lat=%f ulat=%c", curserial->bd_data.ms_time, curserial->bd_data.lat, curserial->bd_data.uLat); DebugLog(0, (char*)buffer, 'I'); ::sprintf(buffer, "lon=%f ulon=%c, status=%c", curserial->bd_data.lon, curserial->bd_data.uLon, curserial->bd_data.status); DebugLog(0, (char*)buffer, 'I'); // 释放内存 for (int i = 0; i < total_fields; ++i) free(result[i]); free(result); return 0; } char** BD_NMEA0183_SplitString(char *str, int *total_fields) { int max_fields, field_count = 0; char **fields = NULL, **new_fields = NULL, **result = NULL; char *copy = NULL, *p = NULL; char szbuf[128]; if(NULL == str) return NULL; if(NULL == total_fields) return NULL; // 创建可修改的副本 copy = strdup(str); memset(szbuf, 0, sizeof(szbuf)); if (!copy) { sprintf(szbuf, "内存分配失败\n"); DebugLog(0, szbuf, 'E'); return NULL; } // 初始字段数组大小 max_fields = MAX_FIELDS_NUM; fields = (char**)malloc(max_fields * sizeof(char *)); if (!fields) { free(copy); sprintf(szbuf, "fields 内存分配失败\n"); DebugLog(0, szbuf, 'E'); return NULL; } field_count = 0; fields[field_count] = copy; // 第一个字段起始 // 遍历字符串分割字段 for (p = copy; *p; ++p) { if (*p == ',') { *p = '\0'; // 结束当前字段 field_count++; // 动态扩展数组 if (field_count >= max_fields) { max_fields *= 2; new_fields = (char**)realloc(fields, max_fields * sizeof(char *)); if (!new_fields) { free(fields); free(copy); sprintf(szbuf, "new_fields 内存分配失败\n"); DebugLog(0, szbuf, 'E'); return NULL; } fields = new_fields; } fields[field_count] = p + 1; // 下一字段起始 } } *total_fields = field_count + 1; // 总字段数 // 复制字段到独立内存 result = (char **)malloc((*total_fields) * sizeof(char *)); if (!result) { free(fields); free(copy); sprintf(szbuf, "result 内存分配失败\n"); DebugLog(0, szbuf, 'E'); return NULL; } for (int i = 0; i < *total_fields; ++i) { result[i] = strdup(fields[i]); if (!result[i]) { // 释放已分配内存 for (int j = 0; j < i; ++j) free(result[j]); free(result); free(fields); free(copy); sprintf(szbuf, "result 字段复制失败\n"); DebugLog(0, szbuf, 'E'); return NULL; } } // 输出结果到日志 for (int i = 0; i < *total_fields; ++i) { sprintf(szbuf, "字段 %2d: %s\n", i + 1, result[i]); DebugLog(0, szbuf, 'I'); } // 释放内存 //for (int i = 0; i < total_fields; ++i) free(result[i]); //free(result); free(fields); free(copy); return result; } /* 串口启动接口函数 结束*/ /* 数据和图片采集数据返回函数 开始*/ int GetWeatherData(Data_DEF *data, int datano) { int i; char logbuf[512], szbuf[128]; if (NULL == data) return -1; if ((AirTempNo > datano) || (datano > OpticalRadiationNo)) return -1; data->EuValue = weatherpntmsg[datano].EuValue; data->AiState = weatherpntmsg[datano].AiState; memset(szbuf, 0, sizeof(szbuf)); switch (datano) { case AirTempNo: sprintf(szbuf, "温度"); break; case HumidityNo: sprintf(szbuf, "湿度"); break; case WindSpeedNo: sprintf(szbuf, "风速"); break; case WindDirectionNo: sprintf(szbuf, "风向"); break; case RainfallNo: sprintf(szbuf, "雨量"); break; case AtmosNo: sprintf(szbuf, "大气压"); break; case OpticalRadiationNo: sprintf(szbuf, "日照"); break; default: sprintf(szbuf, "未知"); break; } sprintf(logbuf, "data_state=%d, %svalue=%0.3f", data->AiState, szbuf,data->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == data->AiState) || (SAMPLINGSUCCESS == data->AiState)) { weatherpntmsg[datano].AiState = SER_IDLE; return 2; } return 1; } int GetAirTempData(Data_DEF *airt) { char logbuf[512]; if (NULL == airt) return -1; airt->EuValue = weatherpntmsg[AirTempNo].EuValue; airt->AiState = weatherpntmsg[AirTempNo].AiState; sprintf(logbuf, "data_state=%d, 温度value=%0.3f", airt->AiState, airt->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState)) { weatherpntmsg[AirTempNo].AiState = SER_IDLE; return 2; } return 1; } int GetHumidityData(Data_DEF *airt) { char logbuf[512]; if (NULL == airt) return -1; airt->EuValue = weatherpntmsg[HumidityNo].EuValue; airt->AiState = weatherpntmsg[HumidityNo].AiState; sprintf(logbuf, "data_state=%d, 湿度value=%0.3f", airt->AiState, airt->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState)) { weatherpntmsg[HumidityNo].AiState = SER_IDLE; return 2; } return 1; } int GetWindSpeedData(Data_DEF *airt) { char logbuf[512]; if (NULL == airt) return -1; airt->EuValue = weatherpntmsg[WindSpeedNo].EuValue; airt->AiState = weatherpntmsg[WindSpeedNo].AiState; sprintf(logbuf, "data_state=%d, 风速value=%0.3f", airt->AiState, airt->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState)) { weatherpntmsg[WindSpeedNo].AiState = SER_IDLE; return 2; } return 1; } int GetWindDirectionData(Data_DEF *airt) { char logbuf[512]; if (NULL == airt) return -1; airt->EuValue = weatherpntmsg[WindDirectionNo].EuValue; airt->AiState = weatherpntmsg[WindDirectionNo].AiState; sprintf(logbuf, "data_state=%d, 风向value=%0.3f", airt->AiState, airt->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState)) { weatherpntmsg[WindDirectionNo].AiState = SER_IDLE; return 2; } return 1; } int GetRainfallData(Data_DEF *airt) { char logbuf[512]; if (NULL == airt) return -1; airt->EuValue = weatherpntmsg[RainfallNo].EuValue; airt->AiState = weatherpntmsg[RainfallNo].AiState; sprintf(logbuf, "data_state=%d, 雨量value=%0.3f", airt->AiState, airt->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState)) { weatherpntmsg[RainfallNo].AiState = SER_IDLE; return 2; } return 1; } int GetAtmosData(Data_DEF *airt) { char logbuf[512]; if (NULL == airt) return -1; airt->EuValue = weatherpntmsg[AtmosNo].EuValue; airt->AiState = weatherpntmsg[AtmosNo].AiState; sprintf(logbuf, "data_state=%d, 大气压value=%0.3f", airt->AiState, airt->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState)) { weatherpntmsg[AtmosNo].AiState = SER_IDLE; return 2; } return 1; } int GetOpticalRadiationData(Data_DEF *airt) { char logbuf[512]; if (NULL == airt) return -1; airt->EuValue = weatherpntmsg[OpticalRadiationNo].EuValue; airt->AiState = weatherpntmsg[OpticalRadiationNo].AiState; sprintf(logbuf, "data_state=%d, 日照value=%0.3f", airt->AiState, airt->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState)) { weatherpntmsg[OpticalRadiationNo].AiState = SER_IDLE; return 2; } return 1; } int GetPullValue(int devno, Data_DEF *data) { char logbuf[512]; if (NULL == data) return -1; if ((0 > devno) || (MAX_SERIAL_DEV_NUM < devno)) return -1; if (RALLY_PROTOCOL != devparam[devno].ProtocolIdx) return -1; data->EuValue = srdt.ms_dev[devno].aiValue[0].EuValue; data->AiState = srdt.ms_dev[devno].aiValue[0].AiState; sprintf(logbuf, "装置%d, ID=%d, data_state=%d, 拉力value=%0.3f", devno + 1, devparam[devno].devaddr, data->AiState, data->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == data->AiState) || (SAMPLINGSUCCESS == data->AiState)) { srdt.ms_dev[devno].aiValue[0].AiState = SER_IDLE; return 2; } return 1; } int GetAngleValue(int devno, Data_DEF *data, int Xy) { char logbuf[512]; if (NULL == data) return -1; if ((0 > devno) || (MAX_SERIAL_DEV_NUM < devno)) return -1; if (SLANT_PROTOCOL != devparam[devno].ProtocolIdx) return -1; if ((0 > Xy) || (1 < Xy)) return -1; data->EuValue = srdt.ms_dev[devno].aiValue[Xy].EuValue; data->AiState = srdt.ms_dev[devno].aiValue[Xy].AiState; sprintf(logbuf, "装置%d, ID=%d, data_state=%d, 倾角value[%d]=%0.3f", devno + 1, devparam[devno].devaddr, data->AiState, Xy, data->EuValue); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == data->AiState) || (SAMPLINGSUCCESS == data->AiState)) { srdt.ms_dev[devno].aiValue[Xy].AiState = SER_IDLE; return 2; } return 1; } int GetImage(int devno, IMAGE_DEF *photo) { char logbuf[512]; if (NULL == photo) return -1; photo->presetno = serialport[0].image.presetno; photo->phototime = serialport[0].image.phototime; memset(photo->photoname, 0, sizeof(photo->photoname)); memmove(photo->photoname, serialport[0].image.photoname, sizeof(photo->photoname)); photo->imagelen = serialport[0].image.imagelen; photo->state = serialport[0].image.state; sprintf(logbuf, "装置%d, image_state=%d, 预置点:%d,拍照时间:%d, pic_name:%s", devno + 1, photo->state, photo->presetno, photo->phototime, photo->photoname); DebugLog(8, logbuf, 'I'); if ((SER_SAMPLEFAIL == photo->state) || (PHOTO_SAVE_SUCC == photo->state)) { serialport[0].image.state = SER_IDLE; return 2; } return 1; } /* 数据和图片采集数据返回函数 结束*/