//--------------------------------------------------------------------- #include /*标准输入输出定义*/ #include /*标准函数库定义*/ #include #include /*Unix 标准函数定义*/ #include #include #include /*文件控制定义*/ #include /*PPSIX 终端控制定义*/ #include /*错误号定义*/ //--------------------------------------------------------------------- #include "LoRaCell.h" #include "gpio_driver.h" #include "Common/crc16.h" #include "Common/classxml.h" //#define EN_THREAD_WORK_DEBUG #ifdef EN_THREAD_WORK_DEBUG #define THREAD_WORK_DEBUG qDebug #else #define THREAD_WORK_DEBUG(...) #endif #define Swap16(u16) ((quint16)(((quint16)(u16) >> 8)|((quint16)(u16) << 8))) #define Swap32(u32) ((quint32)(((quint32)(u32) >> 16)|((quint32)(u32) << 16))) //--------------------------------------------------------------------- static unsigned char S_LoRaConfig[6] = { 0x00,0xA0, //AddrH,AddrL 0x64, //011 00 100 UART=9600,8N1, 空速9.6kbps 0xC0, //11 0 000 00 分包32字节,RSSI禁用,发射功率22dbm 0x17, //信道23 ,实际频率 = 410.125+ch*1M = 433.125M 0x40 //0 1 0 0 0 000 ,禁用RSSI字节,定点传输,禁用LBT }; static QMutex rs485_mutex; //--------------------------------------------------------------------- LORACELL::LORACELL(const char *dev, int fre, int order) { memset(battVolData,0x00,sizeof(battVolData)); memset(battVolErrCnt,0x00,sizeof(battVolErrCnt)); memset(module0vol,0x00,sizeof(module0vol)); memset(monversion,0x00,sizeof(monversion)); memset(tx_count,0x00,sizeof(tx_count)); memset(rx_count,0x00,sizeof(rx_count)); all_tx = all_rx = 0; FD_NRF905 = this->OpenDev(dev); if (-1 == FD_NRF905) qDebug("Can't Open %s\n", dev); else qDebug("Open %s OK!\n", dev); this->SetDevAttr(FD_NRF905,9600, 8,1,'N'); //初始配置 Write_LoRa_Config(fre); Work_Order = order; Work_Num = 0; BattGroup = 0; EachGroupBattSum = 1; EachGroupModule = 1; readmode = MODE_CYCLE; addr_singlemodule = 0; adj_index = 0; } LORACELL::~LORACELL() { quit(); wait(); } //--------------------------------------------------------------------- //--------------------------------------------------------------------- /** *@brief 设置串口通信速率 *@param fd 类型 int 打开串口的文件句柄 *@param speed 类型 int 串口速度 *@return void */ //--------------------------------------------------------------------- //--------------------------------------------------------------------- static int speed_arr1[] = { B115200, B57600, B38400, B19200, B9600}; static int name_arr1[] = { 115200, 57600, 38400, 19200, 9600}; void LORACELL::set_speed(int fd, int speed) { int status; struct termios Opt; tcgetattr(fd, &Opt); for ( unsigned int i= 0; i < sizeof(speed_arr1) / sizeof(int); i++) { if(speed == name_arr1[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr1[i]); cfsetospeed(&Opt, speed_arr1[i]); status = tcsetattr(fd, TCSANOW, &Opt); if(status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd,TCIOFLUSH); } } } //--------------------------------------------------------------------- /** *@brief 设置串口数据位,停止位和效验位 *@param fd 类型 int 打开的串口文件句柄 *@param databits 类型 int 数据位 取值 为 7 或者8 *@param stopbits 类型 int 停止位 取值为 1 或者2 *@param parity 类型 int 效验类型 取值为N,E,O,,S */ //--------------------------------------------------------------------- int LORACELL::set_Parity(int fd,int databits,int stopbits,int parity) { struct termios options; if(tcgetattr(fd, &options) != 0) { perror("SetupSerial 1"); return(-1); } //--------------- 二进制传输模式 ------------------------- options.c_iflag = 0; options.c_oflag = 0; //------------------------------------------------------ options.c_cflag &= ~CSIZE; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);/*Input*/ options.c_oflag &= ~OPOST;/*Output*/ switch (databits) /*设置数据位数*/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data size\n"); return (-1); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* 转换为偶效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: fprintf(stderr,"Unsupported parity\n"); return (-1); } /* 设置停止位*/ switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bits\n"); return (-1); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd, TCIFLUSH); options.c_cc[VTIME] = 0; /* 0.1S */ options.c_cc[VMIN] = 0; /* Update the options and do it NOW */ if (tcsetattr(fd,TCSANOW,&options) != 0) { perror("SetupSerial 3"); return (-1); } return (0); } //--------------------------------------------------------------------- int LORACELL::OpenDev(const char *Dev) { int fd = open(Dev, O_RDWR|O_NOCTTY|O_NDELAY); return fd; } //--------------------------------------------------------------------- void LORACELL::SetDevAttr(int fd, int bitrate, char bitlen, char stopbitlen, char checktype) { if(fd < 0) return; set_speed(fd, bitrate); if(set_Parity(fd, bitlen, stopbitlen, checktype) < 0) { qDebug("Set Parity Error\n"); } if(fcntl(fd, F_SETFL, FNDELAY) < 0)//非阻塞,覆盖前面open的属性 { qDebug("fcntl failed\n"); } } //--------------------------------------------------------------------- int LORACELL::WriteDev(int fd,void *buf, int len) { if(fd < 0) return 0; return write(fd, (char *)buf, len); } //--------------------------------------------------------------------- int LORACELL::ReadDev(int fd,void *buf, int len) { if(fd < 0) return 0; char *pbuff = (char *)buf; return (read(fd, pbuff, len)); } //--------------------------------------------------------------------- void LORACELL::run() { runEn = true; if(FD_NRF905<0) runEn = false; bool error_count[75]; int error_num = 0; while(true == runEn) { if(readmode == MODE_CYCLE){ memset(error_count,0x01,sizeof(error_count)); for(int retry=1;retry<2;retry++){ error_num = retryerrormodule(retry,retry*500,error_count); if(error_num == 0) break; } msleep(1000); } else { readMonVol(addr_singlemodule,2000); msleep(1000); // qDebug("addr_singlemodule = %d",addr_singlemodule); readMonVersion(addr_singlemodule,2000); msleep(1000); } } } void LORACELL::set_readmode(int mode){ readmode = mode; } void LORACELL::set_addrsingle(int addr){ addr_singlemodule = addr; } int LORACELL::retryerrormodule(int times, int timeout_ms, bool *error_count){ int error_num = 0; for(int maddr=0;maddrCRC)&&(m_RFData->CMD == m_TXData.CMD) &&((m_RFData->Addr[2])==ADDR[2])&&((m_RFData->Addr[3])==ADDR[3])) { return 0; } else { return 1; } } int LORACELL::Write_LoRa_Config(int fre) { QMutexLocker locker(&rs485_mutex);//添加锁 nowfre = fre;//0,15 int ret = 0; Set_LoRa_Mode(3); //msleep(500);如果出现设置不了频段 for(unsigned char n=0;n<3;n++){ ret = Uart_Write_LoRa_Config(fre); if(0 == ret) break; else msleep(500); } Set_LoRa_Mode(0); //msleep(500); return ret; } int LORACELL::Uart_Write_LoRa_Config(int fre) { int res = CommOK; unsigned char tx_data[9] = {0}; unsigned char rx_data[9] = {0}; // switch(fre) // { // case 0: S_LoRaConfig[4] = 23; break; // case 1: S_LoRaConfig[4] = 25; break; // case 2: S_LoRaConfig[4] = 27; break; // case 3: S_LoRaConfig[4] = 29; break; // case 4: S_LoRaConfig[4] = 31; break; // case 5: S_LoRaConfig[4] = 33; break; // case 6: S_LoRaConfig[4] = 35; break; // case 7: S_LoRaConfig[4] = 37; break; // case 8: S_LoRaConfig[4] = 39; break; // case 9: S_LoRaConfig[4] = 41; break; // case 10: S_LoRaConfig[4] = 43; break; // case 11: S_LoRaConfig[4] = 45; break; // case 12: S_LoRaConfig[4] = 47; break; // case 13: S_LoRaConfig[4] = 49; break; // case 14: S_LoRaConfig[4] = 51; break; // case 15: S_LoRaConfig[4] = 53; break; // default:break; // } // switch(fre) // { // case 0: S_LoRaConfig[1] = 0xF0; break; // case 1: S_LoRaConfig[1] = 0xF1; break; // case 2: S_LoRaConfig[1] = 0xF2; break; // case 3: S_LoRaConfig[1] = 0xF3; break; // case 4: S_LoRaConfig[1] = 0xF4; break; // case 5: S_LoRaConfig[1] = 0xF5; break; // case 6: S_LoRaConfig[1] = 0xF6; break; // case 7: S_LoRaConfig[1] = 0xF7; break; // case 8: S_LoRaConfig[1] = 0xF8; break; // case 9: S_LoRaConfig[1] = 0xF9; break; // case 10: S_LoRaConfig[1] = 0xFA; break; // case 11: S_LoRaConfig[1] = 0xFB; break; // case 12: S_LoRaConfig[1] = 0xFC; break; // case 13: S_LoRaConfig[1] = 0xFD; break; // case 14: S_LoRaConfig[1] = 0xFE; break; // case 15: S_LoRaConfig[1] = 0xFF; break; // default:break; // } S_LoRaConfig[1] = 0xA0+fre; S_LoRaConfig[4] = fre; tx_data[0] = 0xC0; //指令 tx_data[1] = 0x00; //起始地址 tx_data[2] = 0x06; for(unsigned char n=0;n<6;n++) { tx_data[3+n] = S_LoRaConfig[n]; } // for(quint8 i=0;i<9;i++) // qDebug("tx_data %d %x",i,tx_data[i]); struct timeval tv; fd_set rfds; for(quint8 t = 0;t<1;t++) //retry 3 times { res = CommOK; //flush rx buffer char tmp[64] = {0}; while(1) { int len = ReadDev(FD_NRF905,tmp, 64); if(len > 0) continue; else break; } if(sizeof(tx_data) != WriteDev(FD_NRF905, tx_data, sizeof(tx_data))) res = CommTxError; if(res == CommOK){ tv.tv_sec = 0; tv.tv_usec = 200000; FD_ZERO(&rfds); FD_SET( FD_NRF905,&rfds ); int sres = select(FD_NRF905+1,&rfds,NULL,NULL,&tv); if(sres>0){ if(sizeof(rx_data) == ReadDev(FD_NRF905,rx_data,sizeof(rx_data))) { if(rx_data[0] != 0xC1) { res = CommDataError; } for(unsigned char n=1;n 0) continue; else break; } if(sizeof(tx_data) != WriteDev(FD_NRF905, tx_data, sizeof(tx_data))) res = CommTxError; if(res == CommOK){ tv.tv_sec = 0; tv.tv_usec = 200000; FD_ZERO(&rfds); FD_SET( FD_NRF905,&rfds ); int sres = select(FD_NRF905+1,&rfds,NULL,NULL,&tv); if(sres>0){ if(sizeof(rx_data) == ReadDev(FD_NRF905,rx_data,sizeof(rx_data))) { for(unsigned char n=0;n=1 && param2 <=16) Write_LoRa_Config(param2); memset(battVolData,0x00,sizeof(battVolData)); memset(battVolErrCnt,0x00,sizeof(battVolErrCnt)); } int LORACELL::setWorkFre(int fre){ int res = CommOK; if(fre>=0 && fre <=15) res = Write_LoRa_Config(fre); memset(battVolData,0x00,sizeof(battVolData)); memset(battVolErrCnt,0x00,sizeof(battVolErrCnt)); return res; } int LORACELL::getWorkFre(){ int workfre = -1; unsigned char rx_data[6] = {0}; if(Read_LoRa_Config(rx_data)==CommOK){ switch(rx_data[4]) { case 23: workfre = 0; break; case 25: workfre = 1; break; case 27: workfre = 2; break; case 29: workfre = 3; break; case 31: workfre = 4; break; case 33: workfre = 5; break; case 35: workfre = 6; break; case 37: workfre = 7; break; case 39: workfre = 8; break; case 41: workfre = 9; break; case 43: workfre = 10; break; case 45: workfre = 11; break; case 47: workfre = 12; break; case 49: workfre = 13; break; case 51: workfre = 14; break; case 53: workfre = 15; break; default:break; } } return workfre+1; } bool LORACELL::readMonVol(int maddr,int timeout_ms){ QMutexLocker locker(&rs485_mutex); int res = CommOK; RFData TX_Data; RFData RX_Data; quint8 tx_addr[4] = {0xAB,0xCD,0x00,0x01}; if(readmode == MODE_CYCLE){ tx_addr[3] = maddr+1; } else { tx_addr[3] = maddr; } memset(&TX_Data,0,sizeof(TX_Data)); memset(&RX_Data,0,sizeof(RX_Data)); TX_Data.Addr[0] = 0xAB; TX_Data.Addr[1] = 0xCD; TX_Data.Addr[2] = S_LoRaConfig[4]; TX_Data.Addr[3] = S_LoRaConfig[1]; TX_Data.CMD = CMD_READVOL; TX_Data.CRC = CRC16::CalCRC16(&TX_Data,sizeof(TX_Data)-2); res = TxPacket(tx_addr,&TX_Data,nowfre); if(res == CommOK){ res = ReadData(&RX_Data,sizeof(RX_Data),timeout_ms/5); } if(res == CommOK){ if(CheckDataIfOK(tx_addr,TX_Data,&RX_Data)!=0)//校验失败 res = CommDataError; } if(res == CommOK){ for(int i=0;i<4;i++){ if(RX_Data.VolData[i]>MON_MAX_VOL) RX_Data.VolData[i] = MON_MAX_VOL; } if(readmode == MODE_CYCLE){ ClassXML::set_battVolData(maddr,RX_Data.VolData,battVolData, Work_Order,EachGroupBattSum,EachGroupModule,BattGroup); if(battVolErrCnt[maddr] != 0) { //qDebug("clean maddr=%d, battVolErrCnt=%d",maddr+1,battVolErrCnt[maddr]); battVolErrCnt[maddr] = 0; } } else { module0vol[0] = RX_Data.VolData[0]; module0vol[1] = RX_Data.VolData[1]; module0vol[2] = RX_Data.VolData[2]; module0vol[3] = RX_Data.VolData[3]; } } else { if(readmode == MODE_CYCLE){ if(++battVolErrCnt[maddr] > 4) { //数据清零 Rx_Data_RF temp; memset(&temp,0,sizeof(temp)); temp.Addr = maddr+1; ClassXML::set_battVolData(maddr,temp.VolData,battVolData,Work_Order, EachGroupBattSum,EachGroupModule,BattGroup); battVolErrCnt[maddr] = 0; } } else { for(int b=0;b<4;b++) { module0vol[b] = 0; } } } return res; } bool LORACELL::readMonVersion(int maddr,int timeout_ms){ QMutexLocker locker(&rs485_mutex); int res = CommOK; RFData TX_Data; RFData RX_Data; quint8 tx_addr[4] = {0xAB,0xCD,0x00,0x01}; tx_addr[3] = maddr; memset(&TX_Data,0,sizeof(TX_Data)); memset(&RX_Data,0,sizeof(RX_Data)); TX_Data.Addr[0] = 0xAB; TX_Data.Addr[1] = 0xCD; TX_Data.Addr[2] = S_LoRaConfig[4]; TX_Data.Addr[3] = S_LoRaConfig[1]; TX_Data.CMD = CMD_VERSION; TX_Data.CRC = CRC16::CalCRC16(&TX_Data,sizeof(TX_Data)-2); res = TxPacket(tx_addr,&TX_Data,nowfre); if(res == CommOK){ res = ReadData(&RX_Data,sizeof(RX_Data),timeout_ms/5); } if(res == CommOK){ if(CheckDataIfOK(tx_addr,TX_Data,&RX_Data)!=0)//校验失败 res = CommDataError; } if(res == CommOK){ if(readmode == MODE_CYCLE){ ; } else { monversion[0] = RX_Data.VolData[0]; monversion[1] = RX_Data.VolData[1]; monversion[2] = RX_Data.VolData[2]; monversion[3] = RX_Data.VolData[3]; } } else { memset(monversion,0x00,sizeof(monversion)); } return res; } bool LORACELL::setmoduleaddr(int num, int num2){//目标模块,设置地址 QMutexLocker locker(&rs485_mutex); int res = CommOK; RFData TX_Data; RFData RX_Data; quint8 tx_addr[4] = {0xAB,0xCD,0x00,0x00}; tx_addr[3] = num; memset(&TX_Data,0,sizeof(TX_Data)); TX_Data.Addr[0] = 0xAB; TX_Data.Addr[1] = 0xCD; TX_Data.Addr[2] = S_LoRaConfig[4]; TX_Data.Addr[3] = S_LoRaConfig[1]; TX_Data.CMD = CMD_SETMONADDR;//0x00A2 TX_Data.VolData[0] = 0xCDAB; TX_Data.VolData[1] = (num2<<8); TX_Data.VolData[2] = 0; TX_Data.VolData[3] = 0; TX_Data.CRC = CRC16::CalCRC16(&TX_Data,sizeof(TX_Data)-2); struct timeval tv; fd_set rfds; for(quint8 t = 0;t<3;t++) //retry 3 times { memset(&RX_Data,0,sizeof(RX_Data)); res = CommOK; //flush rx buffer char tmp[64] = {0}; while(1) { int len = ReadDev(FD_NRF905,tmp, 64); if(len > 0) continue; else break; } res = TxPacket(tx_addr,&TX_Data,nowfre); if(res == CommOK){ tv.tv_sec = 2; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET( FD_NRF905,&rfds ); int sres = select(FD_NRF905+1,&rfds,NULL,NULL,&tv); if(sres>0){ if(sizeof(RX_Data) != ReadDev(FD_NRF905,&RX_Data,sizeof(RX_Data))){//读取失败 res = CommRxError; } else { tx_addr[3] = num2; if(CheckDataIfOK(tx_addr,TX_Data,&RX_Data)!=0)//校验失败 res = CommDataError; } } else{//无返回 res = CommWrFailError; } } if(res == CommOK) break; else { msleep(200); qDebug("setmoduleaddr res = %d",res); } } return res; } bool LORACELL::setmodulefre(int num, int num2){ QMutexLocker locker(&rs485_mutex); int res = CommOK; RFData TX_Data; RFData RX_Data; quint8 tx_addr[4] = {0xAB,0xCD,0x00,0x00}; tx_addr[3] = num; memset(&TX_Data,0,sizeof(TX_Data)); memset(&RX_Data,0,sizeof(RX_Data)); TX_Data.Addr[0] = 0xAB; TX_Data.Addr[1] = 0xCD; TX_Data.Addr[2] = S_LoRaConfig[4]; TX_Data.Addr[3] = S_LoRaConfig[1]; TX_Data.CMD = CMD_SETMONFRE;//0x00A8 TX_Data.VolData[0] = 0xCDAB; TX_Data.VolData[1] = (num2<<8); TX_Data.VolData[2] = 0; TX_Data.VolData[3] = 0; TX_Data.CRC = CRC16::CalCRC16(&TX_Data,sizeof(TX_Data)-2); struct timeval tv; fd_set rfds; for(quint8 t = 0;t<3;t++) //retry 3 times { res = CommOK; //flush rx buffer char tmp[64] = {0}; while(1) { int len = ReadDev(FD_NRF905,tmp, 64); if(len > 0) continue; else break; } res = TxPacket(tx_addr,&TX_Data,nowfre); if(res == CommOK){ tv.tv_sec = 2; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET( FD_NRF905,&rfds ); int sres = select(FD_NRF905+1,&rfds,NULL,NULL,&tv); if(sres>0){ if(sizeof(RX_Data) != ReadDev(FD_NRF905,&RX_Data,sizeof(RX_Data))){//读取失败 res = CommRxError; } else { if(CheckDataIfOK(tx_addr,TX_Data,&RX_Data)!=0)//校验失败 res = CommDataError; } } else{//无返回 res = CommWrFailError; } } if(res == CommOK) break; else { msleep(200); qDebug("setmodulefre res = %d",res); } } return res; } void LORACELL::GetBattVolData(void *data) { int monnum = BattGroup*EachGroupBattSum; for(int i=monnum;i 0){ for(int i=0;i0 && rx_time_out>20) //收到了部分字节后,字节之间超时 x*5ms { //qDebug("rx_len = %d",rx_len); return CommRxError; } //qDebug("rx_time_out = %d timeout_5ms = %d",rx_time_out,timeout_5ms); if(rx_time_out > timeout_5ms) //接收超时 timeout_5ms * 5ms { return CommWrFailError; } } if(rx_len >= len){ return CommOK; } rx_time_out++; msleep(5); } } //一个单体模块的四节单体一起校准 bool LORACELL::adjmon_offset(int num, int vol){//模块地址,偏移量(差值)mV QMutexLocker locker(&rs485_mutex); int res = CommOK; RFData TX_Data; RFData RX_Data; quint8 tx_addr[4] = {0xAB,0xCD,0x00,0x00}; unsigned int TXmoduladdr = 0; TXmoduladdr = num;//单体模块地址 tx_addr[3] = (unsigned char)TXmoduladdr; tx_addr[2] = (unsigned char)(TXmoduladdr>>8); memset(&TX_Data,0,sizeof(TX_Data)); if(vol<0) vol = 0; TX_Data.Addr[0] = 0xAB; TX_Data.Addr[1] = 0xCD; TX_Data.Addr[2] = S_LoRaConfig[4]; TX_Data.Addr[3] = S_LoRaConfig[1]; TX_Data.CMD = CMD_SetADJOffSet; TX_Data.VolData[0] = vol; TX_Data.VolData[1] = 0; TX_Data.VolData[2] = 0; TX_Data.VolData[3] = 0; TX_Data.CRC = CRC16::CalCRC16(&TX_Data,sizeof(TX_Data)-2); struct timeval tv; fd_set rfds; for(quint8 t = 0;t<3;t++) //retry 3 times { memset(&RX_Data,0,sizeof(RX_Data)); res = CommOK; //flush rx buffer char tmp[64] = {0}; while(1) { int len = ReadDev(FD_NRF905,tmp, 64); if(len > 0) continue; else break; } res = TxPacket(tx_addr,&TX_Data,nowfre); if(res == CommOK){ tv.tv_sec = 0; tv.tv_usec = 2000000; FD_ZERO(&rfds); FD_SET( FD_NRF905,&rfds ); int sres = select(FD_NRF905+1,&rfds,NULL,NULL,&tv); if(sres>0){ if(sizeof(RX_Data) != ReadDev(FD_NRF905,&RX_Data,sizeof(RX_Data))){//读取失败 res = CommRxError; } else { if(CheckDataIfOK(tx_addr,TX_Data,&RX_Data)!=0)//校验失败 res = CommDataError; } } else{//无返回 res = CommWrFailError; } } if(res == CommOK) break; else { msleep(200); qDebug("adjmon_offset res = %d",res); } } if(res == CommOK) return true; else return false; } bool LORACELL::adjmon_slope(int num, int vol){//模块地址,斜率值*10000 QMutexLocker locker(&rs485_mutex); int res = CommOK; RFData TX_Data; RFData RX_Data; quint8 tx_addr[4] = {0xAB,0xCD,0x00,0x00}; unsigned int TXmoduladdr = 0; TXmoduladdr = num;//单体模块地址 tx_addr[3] = (unsigned char)TXmoduladdr; tx_addr[2] = (unsigned char)(TXmoduladdr>>8); memset(&TX_Data,0,sizeof(TX_Data)); TX_Data.Addr[0] = 0xAB; TX_Data.Addr[1] = 0xCD; TX_Data.Addr[2] = S_LoRaConfig[4]; TX_Data.Addr[3] = S_LoRaConfig[1]; TX_Data.CMD = CMD_SetADJSlope; TX_Data.VolData[0] = vol; TX_Data.VolData[1] = 0; TX_Data.VolData[2] = 0; TX_Data.VolData[3] = 0; TX_Data.CRC = CRC16::CalCRC16(&TX_Data,sizeof(TX_Data)-2); struct timeval tv; fd_set rfds; for(quint8 t = 0;t<3;t++) //retry 3 times { memset(&RX_Data,0,sizeof(RX_Data)); res = CommOK; //flush rx buffer char tmp[64] = {0}; while(1) { int len = ReadDev(FD_NRF905,tmp, 64); if(len > 0) continue; else break; } res = TxPacket(tx_addr,&TX_Data,nowfre); if(res == CommOK){ tv.tv_sec = 0; tv.tv_usec = 2000000; FD_ZERO(&rfds); FD_SET( FD_NRF905,&rfds ); int sres = select(FD_NRF905+1,&rfds,NULL,NULL,&tv); if(sres>0){ if(sizeof(RX_Data) != ReadDev(FD_NRF905,&RX_Data,sizeof(RX_Data))){//读取失败 res = CommRxError; } else { if(CheckDataIfOK(tx_addr,TX_Data,&RX_Data)!=0)//校验失败 res = CommDataError; } } else{//无返回 res = CommWrFailError; } } if(res == CommOK) break; else { msleep(200); qDebug("adjmon_slope res = %d",res); } } if(res == CommOK) return true; else return false; } void LORACELL::setadjindex(int param){ adj_index = param; } int LORACELL::AdjMonoVol(const quint8 index,const quint16 vol,int index_type) { QMutexLocker locker(&rs485_mutex); int res = CommOK; int get_index = index; if(index_type == 1) get_index = adj_index; quint8 addr_index = ClassXML::getMonModuleAddr(get_index,EachGroupModule,EachGroupBattSum);//计算单体号对应的模块地址 if(addr_index >= Work_Num) res = CommTxError; if(res == CommOK){ RFData TX_Data; RFData RX_Data; quint8 tx_addr[4] = {0xAB,0xCD,0x00,0x00}; unsigned int TXmoduladdr = 0; TXmoduladdr = addr_index+1;//单体模块地址 tx_addr[3] = (unsigned char)TXmoduladdr; tx_addr[2] = (unsigned char)(TXmoduladdr>>8); memset(&TX_Data,0,sizeof(TX_Data)); TX_Data.Addr[0] = 0xAB; TX_Data.Addr[1] = 0xCD; TX_Data.Addr[2] = S_LoRaConfig[4]; TX_Data.Addr[3] = S_LoRaConfig[1]; TX_Data.CMD = CMD_ADJMONVOL; for(int i=0;i<4;i++) TX_Data.VolData[i] = 0; ClassXML::set_addr_VolData(addr_index,TX_Data.VolData,battVolData, Work_Order,EachGroupBattSum,EachGroupModule,BattGroup); ClassXML::set_adj_vol(addr_index,get_index,TX_Data.VolData,vol, Work_Order,EachGroupBattSum,EachGroupModule); TX_Data.CRC = CRC16::CalCRC16(&TX_Data,sizeof(TX_Data)-2); struct timeval tv; fd_set rfds; for(quint8 t = 0;t<3;t++) //retry 3 times { memset(&RX_Data,0,sizeof(RX_Data)); res = CommOK; //flush rx buffer char tmp[64] = {0}; while(1) { int len = ReadDev(FD_NRF905,tmp, 64); if(len > 0) continue; else break; } res = TxPacket(tx_addr,&TX_Data,nowfre); if(res == CommOK){ tv.tv_sec = 0; tv.tv_usec = 2000000; FD_ZERO(&rfds); FD_SET( FD_NRF905,&rfds ); int sres = select(FD_NRF905+1,&rfds,NULL,NULL,&tv); if(sres>0){ if(sizeof(RX_Data) != ReadDev(FD_NRF905,&RX_Data,sizeof(RX_Data))){//读取失败 res = CommRxError; } else { if(CheckDataIfOK(tx_addr,TX_Data,&RX_Data)!=0)//校验失败 res = CommDataError; } } else{//无返回 res = CommWrFailError; } } if(res == CommOK) break; else { msleep(200); } } } if(res == CommOK) return true; else return false; } QString LORACELL::get_version(){ QString ver = QString("version: %1.%2.%3").arg(QString::number(monversion[2])) .arg(QString::number(monversion[1])) .arg(QString::number(monversion[0])); return ver; } void LORACELL::getmodulevol(void *data){ memcpy(data,module0vol,sizeof(module0vol)); }