1.1.1 【实验目的】
熟悉contiki 操作系统
熟悉Ipv6 的通信协议
通过本实验掌握stm32w108的ADC使用方法
1.1.2 【实验环境】
Ipv6蜂鸣器控制模块
VMware 虚拟机
PC机 XP、Window7/8
1.1.3 【实验内容】
编写烟雾传感器的ADC程序,实现定时向server端发送ADC采集的数据。
1.1.4 【实验原理】
有原理图可知,烟雾引脚与STM32W108的PA_5引脚相连,查找芯片手册ADC章节,可知PC_5引脚对应的ADC5通道。
1.1.5 【实验步骤】
打开VMware虚拟软件,打开Ubuntu镜像,进入Vi下的contiki-2.7-stm目录文件夹,执行ls命令。
进入继电器源码文件,路径如下:
/home/user/songl/contiki-2.7-stm/contiki-2.7-stm/examples/mbxxx/rpl-udp-Gas
接着你只需打开udp-Gas-client.c和udp- Gas -server.c两个文件,修改他们之间的通信协议。
编译程序
执行命令:
./build.sh
会生成udp- Gas -server.bin和udp- Gas -client.bin两个bin文件。
连接设备如下(请参照第11.4.3章节“镜像烧写”),注意任何模块都可以作为服务端的底板,只需烧写server程序即可。这里运用继电器模块做服务端。
烧写程序:
服务端(继电器)烧写 udp- Gas -server.bin。
客户端(烟雾)烧写 udp- Gas -client.bin。
上图继电器模块连接到PC机上,打开串口调试。查看服务端接收到的数据。分析数据的内容是否正确。
1.1.6 【实验结果】
利用串口调试工具做实验,打开串口调试工具,波特率115200、串口号(你的电脑的端口号)、点击打开。
注意:要先把模块的开关打开,等到串口上有数据后,把打火机的口对准烟雾传感器,然后按下打火机放出气体,这时观察调试助手的数据信息。
接收到的数据如下:
可以通过串口发送21 49 04 00 47 00 06 74 00 00 78控制继电器的开。
21 49: 为字符‘!I’
04 00 :设备地址 注意:04 为低八位地址,00为高八位地址
47 :设备类型 ‘G’ ,是烟雾传感器
00 06 74: ADC的数据值:12位AD值06为高四位,74为第8位。
78 :校验和。
1.1.7 【实验参考代码】
PROCESS_THREAD(udp_client_process, ev, data)
{
uint8_t result = 0;
uint8_t i = 0;
txbuf[0] = '!';
txbuf[1] = 'I';
txbuf[2] = addresses_L;
txbuf[3] = addresses_H;
txbuf[4] = 'G';
PROCESS_BEGIN();
PROCESS_PAUSE();
// GPIO_DBGCFG |= (1<<5);
set_global_address();
PRINTF("UDP client process started\r\n");
print_local_addresses();
/* new connection with remote host */
client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL);
if(client_conn == NULL) {
PRINTF("No UDP connection available, exiting the process!\r\n");
PROCESS_EXIT();
}
udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT));
PRINTF("Created a connection with the server ");
PRINT6ADDR(&client_conn->ripaddr);
PRINTF(" local/remote port %u/%u\r\n",
UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport));
etimer_set(&et_send,CLOCK_SECOND*4);
while(1) {
PROCESS_YIELD();
if(ev == tcpip_event) {
tcpip_handler();
#if 0
if(rxlen == 7)
{
if(rxbuf[0] == '#' && rxbuf[1] == 'C'&& rxbuf[2] == 'I' && rxbuf[3] == 'r' && rxbuf[4] ==addresses_H && rxbuf[5] == addresses_L)
{
if((rxbuf[6] - '0') == Relay_on)
{
halGpioSet(PORTx_PIN(PORTC,2),1);
PRINTF(" Open Relay\n");
flag = 1;
}
else if((rxbuf[6] - '0') == Relay_off)
{
halGpioSet(PORTx_PIN(PORTC,2),0);
PRINTF("Close Relay\n ");
flag = 0;
}
rxlen = 0;
}
}
#endif
}
#if 0
if(ev == serial_line_event_message) {
if(*((uint8_t *)data) == 0x90)
continue;
txbuf[count++] = *((uint8_t *)data);
if (count == 24) {
uip_udp_packet_sendto(client_conn, (char *)txbuf, 24,&server_ipaddr, UIP_HTONS(UDP_SERVER_PORT));
count = 0;
}
}
#endif
if(ev == PROCESS_EVENT_TIMER)
{
unsigned int temp = temperature_sensor.value(0);
txbuf[7] = temp;
txbuf[6] = temp >> 8;
for(i=0;i<(11-2);i++)
{
result ^= txbuf[i+1];
}
txbuf[10] = result;
uip_udp_packet_sendto(client_conn, (char *)txbuf, 11, &server_ipaddr, UIP_HTONS(UDP_SERVER_PORT));
result = 0;
etimer_reset(&et_send);
}
}
PROCESS_END();
}
Client 向服务器发送数据,主要用到etimer事件PROCESS_EVENT_TIMER,etimer_set(&et_send,CLOCK_SECOND*4)设置需要的时间;默认CLOCK_SECOND 1000 毫秒,也就是说每个4秒就会产生一个PROCESS_EVENT_TIMER事件。因此四秒发送一次设备状态数据。