这是一份迟来的文章,代码写好几天了,由于太忙,一直没来得及上传。
在开发板套件中,有一个OLED屏幕扩展板,温湿度传感器扩展板,本次我们就用这两个扩展板来实现一个简易数字温度计。初步的打算是做一个仪表盘,用指针指示温度和湿度,但是由于OLED只有128*64,因此仪表盘不会很清晰,我们在旁边再用数字直接显示一下。虽然简陋一点,但是只要原理学会了,其他复杂的仪表盘我们同样可以做出来。

OLED屏幕为128*64的点阵,通信接口为I2C0,从机地址为0x3C
温湿度传感器AHT20,通信接口也是I2C0,从机地址为0x38
熟悉I2C的朋友都知道,I2C是多从机模式,只要从机地址不同,我们可以挂在同一个总线下,进行复用。
既然如此,那我们就可以同时使用这两个扩展板。
1. OLED驱动
OLED驱动开发方法,参考许思维老师的代码 https://gitee.com/hihopeorg/harmonyos-ssd1306
此处不再赘述
2. 温湿度传感器AHT20驱动
参考许思维老师的代码 https://gitee.com/hihopeorg/harmonyos-aht20
此处不再赘述。
3. 画表盘
由于表盘是半个圆,而且一般是从9点钟方向开始,顺指针旋转,与实际的温度值相对应,9点钟对应最小值,3点钟对应最大值,
因此我们画表盘的时候最好从9点钟对应的角度为0, 12点钟对应的角度90度,3点钟对应的角度为180度。
画表盘就是设置好圆心(x,y)和半径r,然后计算圆周上的两个点,将相邻的两个点调用画直线函数连接起来。
4.画指针
画指针比较简单,就是在圆周上找一个点,将这个点和圆心连接,就变成了一个指针,改变半径的大小,就可以实现指针的长短。
难点是如何将指针的角度和实际的温度值对应起来。假设温度的范围为-15摄氏度到45摄氏度,共60摄氏度,则每一个角度对应的温度值为60/180;
如果当前温度是20度,则对应的角度为20*60/180度。
5. 画刻度
画刻度的方法,可以参考上面画指针的方法,从同一个角度画出的直线,与两个同圆心不同半径的圆的交点,将这两个交点连接起来就是刻度
6. 使用上面几个函数,画出我们设计的温度表
//更新温度和湿度
void ssd1306_update_temper(float temp, float humi)
{
int angle = 0;
char buf[100] = {0};
ssd1306_Fill(Black);
uint8_t x,y,r;
//温度表盘,半圆形
x=30;
y=28;
r=28;
ssd1306_DrawCircle(x,y,2,White);
ssd1306_SetCursor(x-r, y);
ssd1306_DrawString("-15", Font_6x8, White);
ssd1306_SetCursor(x+r-6, y);
ssd1306_DrawString("45", Font_6x8, White);
ssd1306_SetCursor(x-6, y-r+6);
ssd1306_DrawString("15", Font_6x8, White);
ssd1306_DrawArc_from9(x, y, r, 0, 180, White);
//ssd1306_DrawArc_from9(x, y, r-1, 0, 180, White);
ssd1306_draw_line_of_kedu(x,y,r,45,White);
ssd1306_draw_line_of_kedu(x,y,r,90,White);
ssd1306_draw_line_of_kedu(x,y,r,135,White);
angle = (int)((temp + 15 )*180/60);
ssd1306_draw_line_of_arc(x, y, r-2,angle, White);
ssd1306_SetCursor(x+r+6, y-r/2);
sprintf(buf, "%.1fC", temp);
ssd1306_DrawString(buf, Font_7x10, White);
//湿度表盘,半圆形
x=30;
y=55;
r=22;
ssd1306_DrawCircle(x,y,2,White);
ssd1306_SetCursor(x-r-4, y);
ssd1306_DrawString("20", Font_6x8, White);
ssd1306_SetCursor(x+r-6, y);
ssd1306_DrawString("100", Font_6x8, White);
ssd1306_SetCursor(x-6, y-r+6);
ssd1306_DrawString("60", Font_6x8, White);
ssd1306_DrawArc_from9(x, y, r, 0, 180, White);
//ssd1306_DrawArc_from9(x, y, r-1, 0, 180, White);
ssd1306_draw_line_of_kedu(x,y,r,45,White);
ssd1306_draw_line_of_kedu(x,y,r,90,White);
ssd1306_draw_line_of_kedu(x,y,r,135,White);
angle = (int)((humi - 20 )*180/80);
ssd1306_draw_line_of_arc(x, y, r-2,angle, White);
ssd1306_SetCursor(x+r+6, y-r/2);
sprintf(buf, "%%%.1f", humi);
ssd1306_DrawString(buf, Font_7x10, White);
//ssd1306_TestArc();
ssd1306_UpdateScreen();
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
7. I2C管脚的初始化和任务初始化
征文大赛正在火热进行中,楼主这么优秀的文章真的不考虑参加吗?
例如这篇在标题开头添加“#2020征文-开发板#“,
再找到相应的专栏位置投稿,
就可以参加比赛啦!
详细步骤可以点击链接https://harmonyos.51cto.com/posts/1940进行了解
用更多的文章来赢取更多的奖励和人气吧!期待楼主后续的活跃表现。
动手实践派,赞