From 549cda6b7b2ac68c0bc44718802eb147a29b2f4d Mon Sep 17 00:00:00 2001 From: huyizhong Date: Thu, 6 Jun 2024 15:00:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86weathercomm=E6=96=87=E4=BB=B6=E7=A7=BB?= =?UTF-8?q?=E5=88=B0=E4=B8=BB=E7=9B=AE=E5=BD=95=E4=B8=8B=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=A3=80=E6=B5=8B=E8=AF=BB=E5=8F=96=E4=BC=A0=E6=84=9F?= =?UTF-8?q?=E5=99=A8=E6=97=B6=E9=97=B4=E6=8E=A7=E5=88=B6=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TestComm/app/src/main/cpp/WeatherComm.cpp | 2 +- app/src/main/cpp/CMakeLists.txt | 1 + app/src/main/cpp/WeatherComm.cpp | 535 ++++++++++++++++++++++ app/src/main/cpp/WeatherComm.h | 51 +++ 4 files changed, 588 insertions(+), 1 deletion(-) create mode 100644 app/src/main/cpp/WeatherComm.cpp create mode 100644 app/src/main/cpp/WeatherComm.h diff --git a/TestComm/app/src/main/cpp/WeatherComm.cpp b/TestComm/app/src/main/cpp/WeatherComm.cpp index 01da9869..a27f29be 100644 --- a/TestComm/app/src/main/cpp/WeatherComm.cpp +++ b/TestComm/app/src/main/cpp/WeatherComm.cpp @@ -527,7 +527,7 @@ int serial_port_comm() #endif //itimecnt = (int)time(NULL); - for(;;) + //for(;;) weather_comm(portparm); return 0; } diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index 348464f8..bdb60179 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -302,6 +302,7 @@ add_library( # Sets the name of the library. # TextPaint.cpp CvText.cpp SerialPort.cpp + WeatherComm.cpp ncnn/yolov5ncnn.cpp diff --git a/app/src/main/cpp/WeatherComm.cpp b/app/src/main/cpp/WeatherComm.cpp new file mode 100644 index 00000000..20304c40 --- /dev/null +++ b/app/src/main/cpp/WeatherComm.cpp @@ -0,0 +1,535 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GPIOControl.h" +#include "WeatherComm.h" + +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; + } + } +} + +//int inum =0; +//int itimecnt=0; +static int weather_comm(SERIAL_PARAM weatherport) +{ + int fd = -1; + int len, i,ret, ictime, iruntime, isendtime, irecvtime, icnt=0; + 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); + + ictime = (int)time(NULL); + 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); + if((iruntime - ictime > 120) || (iruntime - ictime < 0)) + ictime = iruntime; + if(iruntime - ictime > 19) + { + memset(szbuf, 0, sizeof(szbuf)); + sprintf(szbuf, "气象采样时间=%d,停止采样!", iruntime-ictime); + LOGE("%s", szbuf); + break; + } + + if(1 == serialport.RevCmdFlag) + { + set485WriteMode(); + + len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */ + serialport.RevCmdFlag = 0; + isendtime = time(NULL); + 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); + if((irecvtime-isendtime > 6) ||(irecvtime - isendtime < 0)) + isendtime = irecvtime; + if (irecvtime-isendtime > 1) + { + LOGE("传感器超过%d秒未应答", 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; +#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; +} + diff --git a/app/src/main/cpp/WeatherComm.h b/app/src/main/cpp/WeatherComm.h new file mode 100644 index 00000000..80c47f98 --- /dev/null +++ b/app/src/main/cpp/WeatherComm.h @@ -0,0 +1,51 @@ +// +// Created by hyz on 2024/6/5. +// + +#ifndef WEATHERCOMM_H +#define WEATHERCOMM_H + +#include +#include "GPIOControl.h" + +#define MAX_STRING_LEN 32 +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF + +#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args) + +// 串口参数 +typedef struct +{ + int baudrate; /* 波特率*/ + int databit; /* 数据位*/ + char stopbit[8]; /* 停止位*/ + char parity; /* 校验位*/ + char pathname[128];/* 串口文件名及路径*/ +} SERIAL_PARAM; + +typedef struct +{ + int m_iRevStatus; /* */ + int m_iRecvLen; /* */ + int m_iNeedRevLength; /* */ + int iRecvTime; /* */ + int RevCmdFlag; + unsigned char m_au8RecvBuf[128];/* */ +} SIO_PARAM_SERIAL_DEF; + +typedef struct +{ + int cmd; + int value; + int result; + long value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +void PortDataProcess( void ); +int serial_port_comm(); +static int weather_comm(SERIAL_PARAM weatherport); +int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin ); + +#endif //WEATHERCOMM_H