You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
TermApp/app/src/main/cpp/WeatherComm.cpp

559 lines
16 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <jni.h>
#include <string>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include "GPIOControl.h"
#include "WeatherComm.h"
#include <sys/time.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, &param);
// 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; (i<datanum) && (j<6+pPortParam->m_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; 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(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;
}