本帖最后由 断点0216 于 2020-11-3 19:56 编辑
上一篇在MaaXBoard安装了qtcreator,并通过qt实现了仪表和曲线图控件,但显示的数据是程序模拟的,并非真实的外部数据。今天抽空来让MaaXBoard与Zigbee碰撞一下。本篇MaaXBoard将作为物联网网关,与Zigbee网络的协调器通过串口连接。Zigbee协调器负责创建和维护网络,是网络中的唯一节点,Zigbee终端负责加入网络,将采集到的传感器数据无线传输给协调器。协调器通过串口传给MaaXBoard。
接线方式如下:
协调器1个 终端3个
数据传输方式采用广播的方式。
数据发送部分代码:
- void SampleApp_SendPeriodicMessage( void )
- {
- byte SendData[18]="end1,hello world!";
- if( AF_DataRequest( &SampleApp_Periodic_DstAddr,
- &SampleApp_epDesc,
- SAMPLEAPP_PERIODIC_CLUSTERID,
- 17,
- SendData,
- &SampleApp_TransID,
- AF_DISCV_ROUTE,
- AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
- {
- }
- else
- {
- HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);
- // Error occurred in request to send.
- }
- }
复制代码
数据接收处理代码
- void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
- {
- uint16 flashTime;
- byte buf[18];
- byte tmpbuf[10];
- switch ( pkt->clusterId )
- {
- case SAMPLEAPP_PERIODIC_CLUSTERID: //收到广播数据
- osal_memset(buf, 0 , 18);
- osal_memcpy(buf, pkt->cmd.Data, 17); //复制数据到缓冲区中
-
- if(buf[0]=='e' && buf[1]=='n' && buf[2]=='d')
- {
- HalLedBlink(HAL_LED_1, 0, 50, 500);//如果是则Led1间隔500ms闪烁
- #if defined(ZDO_COORDINATOR)
- SampleApp_SendPeriodicMessage();
- HalUARTWrite(0,"Receive data from ", strlen("Receive data from "));//串口发送
- HalUARTWrite(0,buf, 4);
- HalUARTWrite(0,"\n", 1);
- #endif
- }
- else
- {
- HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);
- }
- break;
- case SAMPLEAPP_FLASH_CLUSTERID: //收到组播数据
- flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
- HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
- break;
- }
- }
复制代码
接下来是MaaXBoard串口的读取,这里有段小插曲,之前没有留意到板卡的40pin还有个串口2,我一直用的USB转TTL的串口转换板。接入后执行lsusb命令,已经能看到CH340的设备,但是在/dev目录下怎么也找不到设备(或者说根本区分不出哪个设备是USB串口),开发指南和说明文档上也没有关于USB转串口这部分的说明。好在仔细浏览了一遍文档,才发现有TTL串口。
串口设备找到了,那就用吧。创建一个c文件myuart.c。
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <time.h>
- #include <pthread.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <termios.h>
- #include <sys/types.h>
- int Option_Set(int fd,int baudRate,int nBits,char nEvent,int nStop)
- {
- struct termios newtio,oldtio;
- if(tcgetattr(fd,&oldtio)!=0)
- {
- return -1;
- }
- bzero(&newtio,sizeof(newtio));
- newtio.c_cflag |= CLOCAL |CREAD;
- newtio.c_iflag &= ~CSIZE;
- switch(nBits)
- {
- case 5:
- newtio.c_cflag |= CS5;
- break;
- case 6:
- newtio.c_cflag |= CS6;
- break;
- case 7:
- newtio.c_cflag |= CS7;
- break;
- case 8:
- newtio.c_cflag |=CS8;
- break;
- default:
- newtio.c_cflag |=CS8;
- break;
- }
- switch(nEvent)
- {
- case 'o':
- newtio.c_cflag |= PARENB;
- newtio.c_cflag |=PARODD;
- newtio.c_iflag |=(INPCK | ISTRIP);
- break;
- case 'E':
- newtio.c_iflag |=(INPCK | ISTRIP);
- newtio.c_cflag |=PARENB;
- newtio.c_cflag &= ~PARODD;
- break;
- case 'N':
- newtio.c_cflag &= ~PARENB;
- break;
- default:
- newtio.c_cflag &= ~PARENB;
- break;
- }
- switch(baudRate)
- {
- case 2400:
- cfsetispeed(&newtio,B2400);
- cfsetospeed(&newtio,B2400);
- break;
- case 4800:
- cfsetispeed(&newtio,B4800);
- cfsetospeed(&newtio,B4800);
- break;
- case 9600:
- cfsetispeed(&newtio,B9600);
- cfsetospeed(&newtio,B9600);
- break;
- case 57600:
- cfsetispeed(&newtio,B57600);
- cfsetospeed(&newtio,B57600);
- break;
- case 115200:
- cfsetispeed(&newtio,B115200);
- cfsetospeed(&newtio,B115200);
- break;
- case 460800:
- cfsetispeed(&newtio,B460800);
- cfsetospeed(&newtio,B460800);
- break;
- default:
- cfsetispeed(&newtio,B9600);
- cfsetospeed(&newtio,B9600);
- break;
- }
- if(nStop == 1)
- {
- newtio.c_cflag &= ~CSTOPB;
- }
- else if(nStop == 2)
- {
- newtio.c_cflag |= CSTOPB;
- }
- newtio.c_cc[VTIME] = 0;
- newtio.c_cc[VMIN] = 1;
- tcflush(fd,TCIFLUSH);
- if((tcsetattr(fd,TCSANOW,&newtio))!=0)
- {
- printf("com set error");
- return -1;
- }
- return 0;
- }
- int SerialInit(const char* ttyName,int baudRate,int nBits,char nEvent,int nStop)
- {
- if (NULL == ttyName)
- {
- printf("ttyName is NULL");
- return -1;
- }
- int nComFd = 0;
- nComFd = open(ttyName, O_RDWR|O_NOCTTY);
- if (nComFd <= 0 )
- {
- printf("Couldn't open %s", ttyName);
- return -2;
- }
- else
- {
- printf("open %s success!", ttyName);
- }
- Option_Set(nComFd,baudRate,nBits,nEvent,nStop);
- fcntl( nComFd, F_SETFL, 0 );
- return nComFd;
- }
- int SerialDestroy(int nComFd)
- {
- if (nComFd > 0)
- {
- close(nComFd);
- }
- return 0;
- }
- int main(void)
- {
- int fd = 0;
- fd = SerialInit("/dev/ttymxc1", 9600, 8, 'N', 1);
- if (fd < 0)
- {
- printf("/dev/ttymxc1 does not exist!\n");
- return 0;
- }
- char RcvBuf[1024] = {0};
- int nRead = 0;
- while (1)
- {
- memset(RcvBuf, 0, 1024);
- nRead = read(fd, RcvBuf, 1024);
- if (nRead > 0)
- {
- //printf("recv %d data: %s", nRead, RcvBuf);
- printf(RcvBuf);
- }
- sleep(0.1);
- }
- SerialDestroy(fd);
- return 0;
- }
复制代码
编译代码 gcc myuart.c -o main,生成可执行文件main
给zigbee模块上电,并执行main文件
./main
协调器会收到3个zigbee终端定时发出的数据包,至此,初步的组网和数据上传网关功能完成。下一篇,通过qt编写zigbee网关程序,并将数据写入共享内存,qt窗体程序和共享内存交互,实现控件的联动。
|