玩转RT-Thread系列教程--485总线读取温湿度
Posted Rb菌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玩转RT-Thread系列教程--485总线读取温湿度相关的知识,希望对你有一定的参考价值。
玩转RT-Thread系列教程(9)–485总线读取温湿度
一、485总线介绍
485(一般称作 RS485/EIA-485)是隶属于 OSI 模型物理层的电气特性规定为 2 线,半双工,多点通信的标准。它的电气特性和 RS-232 大不一样。用缆线两端的电压差值来表示传递信号。RS485 仅仅规定了接受端和发送端的电气特性。它没有规定或推荐任何数据协议。
RS485 的特点包括:
1) 接口电平低,不易损坏芯片。RS485 的电气特性:逻辑“1”以两线间的电压差为+(26)V表示;逻辑“0”以两线间的电压差为-(26)V 表示。接口信号电平比 RS232 降低了,不易损坏接口电路的芯片,且该电平与 TTL 电平兼容,可方便与 TTL 电路连接。
2) 传输速率高。10 米时,RS485 的数据最高传输速率可达 35Mbps,在 1200m 时,传输速度可达 100Kbps。
3) 抗干扰能力强。RS485 接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能力增强,即抗噪声干扰性好。
4) 传输距离远,支持节点多。RS485 总线最长可以传输 1200m 以上(速率≤100Kbps)一般最大支持 32 个节点,如果使用特制的 485 芯片,可以达到 128 个或者 256 个节点,最大的可以支持到 400 个节点。
二、485温湿度传感器使用
2.1、使用PC测试485通信
首先,先按照规定接线方式,进行安装连接,连接好后,打开CommMontor串口监控精灵,如下图:
链接:https://pan.baidu.com/s/1Q6jRuoZfVMEH-rt7gZ5BNw 提取码:y89c
其中 01 03 00 00 00 02 C4 0B为问询帧,所以只要串口发送这一串十六进制即可得到485总线回复
2.2、使用RT-Thread进行485通信
根据我们之前串口实验,我们只需稍作修改即可完成485的通信。
2.2.1、编写485通信代码
uint16_t temp = 0; //定义温度变量
uint16_t humi = 0; //定义湿度变量
char tem[10] = {0}; //存放温度数据的数组
char hum[10] = {0}; //存放湿度数据的数组
unsigned char sensor_T_H[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B}; //温湿度传感器
static void serial_thread_entry(void *parameter)
{
struct rx_msg msg;
rt_err_t result;
rt_uint32_t rx_length;
static char rx_buffer[RT_SERIAL_RB_BUFSZ + 1];
while (1)
{
rt_memset(&msg, 0, sizeof(msg));
rt_device_write(serial, 0, sensor_T_H, sizeof(sensor_T_H)); //发送采集数据指令
/* 从消息队列中读取消息*/
result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
if (result == RT_EOK)
{
/* 从串口读取数据*/
rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
for(uint8_t a = 0; a < 8; a++)
{
rt_kprintf("sensor[%d] = %.2x \\r\\n", a, rx_buffer[a]);
}
temp = 1.0 * ((rx_buffer[3] << 8) + rx_buffer[4]);
humi = 1.0 * ((rx_buffer[5] << 8) + rx_buffer[6]);
sprintf((char*)tem, "%.2f", (float)temp / 100); //拼接到温度数组里
sprintf((char*)hum, "%.2f", (float)humi / 100); //拼接到湿度数组里
/* 打印数据 */
rt_kprintf("tem:[%s] hum:[%s]\\r\\n", tem, hum);
rt_thread_mdelay(1000);
}
}
}
当然了,不要忘记,485问询串口的比特率是9600!!所以我们需要在串口初始化添加修改波特率的配置。
config.baud_rate = BAUD_RATE_9600; //修改波特率为 9600
config.data_bits = DATA_BITS_8; //数据位 8
config.stop_bits = STOP_BITS_1; //停止位 1
config.bufsz = 64; //修改缓冲区 buff size 为 128
config.parity = PARITY_NONE; //无奇偶校验位
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
2.3、编译、下载、查看结果
通过串口可以清晰的看到485设备返回的帧,通过拼接即可得到正确的温度湿度数据。
三、使用LVGL显示温湿度数据
这次我们要结合LVGL来动态显示温湿度数据。为了达到直观的效果,这里的显示我用折线图来显示,用到的控件为lv_chart。
3.1、编码设计
extern int16_t temp; //定义温度变量
extern int16_t humi; //定义湿度变量
const lv_coord_t series1_y[POINT_COUNT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const lv_coord_t series2_y[POINT_COUNT] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
lv_style_t chart_style;
lv_chart_series_t * series1;
lv_chart_series_t * series2;
//任务回调函数
void task_cb(lv_task_t * task)
{
//往series1数据线上添加新的数据点
lv_chart_set_next(chart1,series1,temp);
//往series2数据线上添加新的数据点
lv_chart_set_next(chart1,series2,humi);
}
void lv_gauge_test_start(lv_obj_t * parent)
{
//1.创建样式
lv_style_copy(&chart_style,&lv_style_pretty);
chart_style.body.main_color = LV_COLOR_WHITE;
chart_style.body.grad_color = chart_style.body.main_color;
chart_style.body.border.color = LV_COLOR_BLACK;
chart_style.body.border.width = 3;
chart_style.body.border.opa = LV_OPA_COVER;
chart_style.body.radius = 1;
chart_style.line.color = LV_COLOR_GRAY;
chart_style.text.color = LV_COLOR_WHITE;
//2.创建图表对象
chart1 = lv_chart_create(parent,NULL);
lv_obj_set_size(chart1,250,200);
lv_obj_align(chart1,NULL,LV_ALIGN_IN_RIGHT_MID,-70,0);
lv_chart_set_type(chart1,LV_CHART_TYPE_LINE);
lv_chart_set_series_opa(chart1,LV_OPA_80);
lv_chart_set_series_width(chart1,4);
lv_chart_set_series_darking(chart1,LV_OPA_80);
lv_chart_set_style(chart1,LV_CHART_STYLE_MAIN,&chart_style);
lv_chart_set_point_count(chart1,POINT_COUNT);
lv_chart_set_div_line_count(chart1,4,4);
lv_chart_set_range(chart1,0,100);
lv_chart_set_y_tick_length(chart1,10,3);
lv_chart_set_y_tick_texts(chart1,"100\\n90\\n80\\n70\\n60\\n50\\n40\\n30\\n20\\n10\\n0",5,LV_CHART_AXIS_DRAW_LAST_TICK);
lv_chart_set_x_tick_length(chart1,10,3);
lv_chart_set_x_tick_texts(chart1,"0\\n2\\n4\\n6\\n8\\n10",5,LV_CHART_AXIS_DRAW_LAST_TICK);
lv_chart_set_margin(chart1,40);
//2.2 往图表中添加第1条数据线
series1 = lv_chart_add_series(chart1,LV_COLOR_RED);
lv_chart_set_points(chart1,series1,(lv_coord_t*)series1_y);
//2.3 往图表中添加第2条数据线
series2 = lv_chart_add_series(chart1,LV_COLOR_BLUE);
lv_chart_set_points(chart1,series2,(lv_coord_t*)series2_y);
lv_chart_refresh(chart1);
//4.创建一个任务来显示变化
lv_task_create(task_cb, 300, LV_TASK_PRIO_MID, NULL);
}
3.2、实现效果
当握住温湿度传感器我们可以直观的看到,温度和湿度发生了明显变化,是不是很有成就感呢。
以上是关于玩转RT-Thread系列教程--485总线读取温湿度的主要内容,如果未能解决你的问题,请参考以下文章
玩转RT-Thread系列教程(11)--综合485通信+文件系统综合实战