#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "GPIOControl.h" #include "WeatherComm.h" #include SIO_PARAM_SERIAL_DEF serialport; float weatherpntmsg[10]; static void set_baudrate (struct termios *opt, unsigned int baudrate) { cfsetispeed(opt, baudrate); cfsetospeed(opt, baudrate); } static void set_data_bit (struct termios *opt, unsigned int databit) { opt->c_cflag &= ~CSIZE; switch (databit) { case 8: opt->c_cflag |= CS8; break; case 7: opt->c_cflag |= CS7; break; case 6: opt->c_cflag |= CS6; break; case 5: opt->c_cflag |= CS5; break; default: opt->c_cflag |= CS8; break; } } static void set_parity (struct termios *opt, char parity) { switch (parity) { case'N':/* 无校验 */ case 'n': opt->c_cflag &= ~PARENB; break; case'E':/*偶校验*/ case 'e': opt->c_cflag |= PARENB; opt->c_cflag &= ~PARODD; break; case'O':/* 奇校验 */ case 'o': opt->c_cflag |= PARENB; opt->c_cflag |= ~PARODD; break; default: /*其它选择为无校验 */ opt->c_cflag &= ~PARENB; break; } } static void set_stopbit (struct termios *opt, const char *stopbit) { if (strcmp(stopbit, "1") == 0) { opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */ } else if(0 == strcmp(stopbit, "1.5")) { opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */ } else if(0 == strcmp (stopbit,"2")) { opt->c_cflag |= CSTOPB; /*2 位停止位 */ } else { opt->c_cflag &= ~CSTOPB; /*1 位停止位 */ } } int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin ) { struct termios opt; tcgetattr(fd, &opt); set_baudrate(&opt, baudrate); //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */ opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG); set_data_bit(&opt, databit); set_parity(&opt, parity); set_stopbit(&opt, stopbit); opt.c_oflag = 0; //opt.c_lflag |= 0; opt.c_oflag &= ~OPOST; opt.c_cc[VTIME] = vtime; opt.c_cc[VMIN] = vmin; tcflush (fd, TCIFLUSH); return (tcsetattr (fd, TCSANOW, &opt)); } static void setInt(int cmd, int value) { int fd = open("/dev/mtkgpioctrl", O_RDONLY); IOT_PARAM param; param.cmd = cmd; param.value = value; // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); if( fd > 0 ) { int res = ioctl(fd, IOT_PARAM_WRITE, ¶m); // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); close(fd); } return; } static void setRS485Enable(bool z) { setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); } static void set485WriteMode() { setInt(CMD_SET_485_STATE, 1); } static void set485ReadMode() { setInt(CMD_SET_485_STATE, 0); } static void set12VEnable(bool z) { setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); } static void setCam3V3Enable(bool enabled) { setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0); } /********************************************************************************* * 气象数据处理 * **********************************************************************************/ void PortDataProcess( void ) { float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/; //WORD uDevAddr; unsigned char cmdidx; int i, j, aipnt, datanum; SIO_PARAM_SERIAL_DEF *pPortParam; char szbuf[64]; pPortParam = &serialport; //取出装置地址,开始处理地址+++ if(0x02 == pPortParam->m_au8RecvBuf[5]) { //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4]; return; } cmdidx = pPortParam->m_au8RecvBuf[5]; #if 0 aipnt = pPortParam->SameTypeDevIdx; uDevAddr = serialport->m_au8RecvBuf[4]; if(0 == srdt.IsReadWireTem) { if(uDevAddr != pPortParam->devaddr) return; } #endif fvalua = &fvalue; datanum = pPortParam->m_au8RecvBuf[6]; if((0x08 != cmdidx) && (0x09 != cmdidx)) return; for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 ) { if(0x08 == cmdidx) fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16) +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4]; else { *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4]; *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3]; *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2]; *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1]; } switch(pPortParam->m_au8RecvBuf[j]) { case 1: /*温度*/ weatherpntmsg[0] = fvalue; LOGE("温度:%0.3f ", fvalue); break; case 2: /*气压*/ weatherpntmsg[5] = fvalue; LOGE("气压:%0.3f ", fvalue); break; case 3: /*湿度*/ weatherpntmsg[1] = fvalue; LOGE("湿度:%0.3f ", fvalue); break; case 4: /*雨量*/ break; case 5: /*日照*/ break; case 6: /*风速*/ weatherpntmsg[2] = fvalue; LOGE("风速:%0.3f ", fvalue); break; case 7: /*风向*/ weatherpntmsg[3] = fvalue; LOGE("风向:%0.3f ", fvalue); break; case 8: /*拉力*/ case 9: /*倾角传感器X轴倾角*/ case 10: /*倾角传感器Y轴倾角*/ case 11: /*测温球导线温度*/ case 12: /*测温球内部温度*/ break; case 13: /*测温球导线X轴倾角*/ break; case 14: /*测温球导线Y轴倾角*/ break; case 15: /*测温球导线电流*/ break; case 16: /*测温球电池电压*/ break; case 17: /*A相泄漏电流平均值;*/ break; case 18: /*A相泄漏电流最大值;*/ break; case 19: /*A相超过3mA的脉冲频次*/ break; case 20: /*A相超过10mA的脉冲频次*/ break; case 21: /*B相泄漏电流平均值;*/ break; case 22: /*B相泄漏电流最大值;*/ break; case 23: /*B相超过3mA的脉冲频次*/ break; case 24: /*B相超过10mA的脉冲频次*/ case 25: /*C相泄漏电流平均值;*/ case 26: /*C相泄漏电流最大值;*/ case 27: /*C相超过3mA的脉冲频次*/ case 28: /*C相超过10mA的脉冲频次*/ break; } } } //*************************************************************** //* 按照协议格式化接收数据 * //*************************************************************** static void RecvData(u_char *buf, int len)// 规约读数据处理 { int i, ictime; //WORD crc, check; SIO_PARAM_SERIAL_DEF *pPortParam; pPortParam = &serialport; ictime = (int)time(NULL); if(pPortParam->m_iRecvLen == 0) { pPortParam->iRecvTime = ictime; } else { if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0)) pPortParam->iRecvTime = ictime; else if(ictime - pPortParam->iRecvTime > 2) { pPortParam->m_iRecvLen = 0; pPortParam->m_iRevStatus = 0; } } for(i=0; im_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(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE) { PortDataProcess(); pPortParam->m_iRevStatus = 0; pPortParam->RevCmdFlag = 1; } 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; } } } static long get_msec(void ) { struct timeval tv; gettimeofday(&tv, NULL); long time_in_msec = tv.tv_sec * 1000 + tv.tv_usec/1000; return time_in_msec; } //int inum =0; //int itimecnt=0; static int weather_comm(SERIAL_PARAM weatherport) { int fd = -1; int len, i,ret, icnt=0; long ictime, iruntime, isendtime, irecvtime; unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16}; char recvbuf[256], szbuf[512]; //char serial_description[] = "/dev/ttyS0"; #if 0 DIR *dir = opendir("/dev"); if (dir == NULL) { LOGE("_test_ opendir"); return -1; } // 读取目录项 struct dirent *entry; while ((entry = readdir(dir)) != NULL) { // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头 if ((strncmp(entry->d_name, "ttyS2", 5) == 0) || (strncmp(entry->d_name, "ttyS0", 5) == 0)) { LOGE("_test_ Found serial port: %s\n", entry->d_name); } } // 关闭目录 closedir(dir); #endif serialport.RevCmdFlag = 1; serialport.m_iRecvLen = 0; serialport.m_iRevStatus = 0; set12VEnable(true); setCam3V3Enable(true); setRS485Enable(true); sleep(2); //ictime = (int)time(NULL); ictime = get_msec(); for(;;) { if(fd < 0) { fd = open(weatherport.pathname, O_RDWR | O_NDELAY); //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY); if(fd < 0) { LOGE("_test_ open serial error \n"); perror(weatherport.pathname); return -1; } ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */ if(ret < 0) { LOGE("_test_ set uart arrt faile \n"); return -1; } } usleep(10000); //iruntime = (int)time(NULL); iruntime = get_msec(); if((iruntime - ictime > 120000) || (iruntime - ictime < 0)) ictime = iruntime; if(iruntime - ictime > 20000) { memset(szbuf, 0, sizeof(szbuf)); sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0); LOGE("%s", szbuf); break; } if(1 == serialport.RevCmdFlag) { set485WriteMode(); len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */ serialport.RevCmdFlag = 0; LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime); //isendtime = time(NULL); isendtime = get_msec(); if (len < 0) { LOGE("write data error \n"); return -1; } else { memset(szbuf, 0, sizeof(szbuf)); sprintf(szbuf, "Send:"); for (i = 0; i < len; i++) { sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]); } LOGE("%s", szbuf); //icnt = 0; //inum++; } tcdrain(fd); //usleep(50000); } else { //irecvtime = time(NULL); irecvtime = get_msec(); if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0)) isendtime = irecvtime; if (irecvtime-isendtime > 300) { LOGE("传感器超过%ld毫秒未应答", irecvtime-isendtime); serialport.RevCmdFlag = 1; serialport.m_iRecvLen = 0; serialport.m_iRevStatus = 0; close(fd); //set12VEnable(false); //setCam3V3Enable(false); //setRS485Enable(false); fd = -1; continue; } } set485ReadMode(); memset(recvbuf, 0, sizeof(recvbuf)); len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */ if (len < 0) { LOGE("serial read error \n"); continue; } if(0 == len) { //icnt++; continue; } memset(szbuf, 0, sizeof(szbuf)); sprintf(szbuf, "Recv:"); for (i = 0; i < len; i++) { sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]); } __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf); RecvData((u_char*)recvbuf, len); //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt); icnt = 0; //serialport.RevCmdFlag =1; } close(fd); set12VEnable(false); setCam3V3Enable(false); setRS485Enable(false); //exit(-1); return(0); } int serial_port_comm() { SERIAL_PARAM portparm; //struct timeval tv; //gettimeofday(&tv, NULL); //long time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec; //LOGE("Current time in microseconds: %ld\n", time_in_microseconds); #if 1 memset(portparm.pathname, 0, sizeof(portparm.pathname)); sprintf(portparm.pathname, "/dev/ttyS0"); portparm.parity = 'N'; portparm.databit = 8; portparm.baudrate = B9600; memset(portparm.stopbit, 0, sizeof(portparm.stopbit)); sprintf(portparm.stopbit, "1"); #endif //itimecnt = (int)time(NULL); //for(;;) weather_comm(portparm); return 0; }