如何实现温度传感器和OLED
发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,本篇内容主要讲解"如何实现温度传感器和OLED",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何实现温度传感器和OLED"吧!1. OLED驱动2. 温湿
千家信息网最后更新 2024年09月22日如何实现温度传感器和OLED
本篇内容主要讲解"如何实现温度传感器和OLED",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何实现温度传感器和OLED"吧!
1. OLED驱动
2. 温湿度传感器AHT20驱动
3. 画表盘
由于表盘是半个圆,而且一般是从9点钟方向开始,顺指针旋转,与实际的温度值相对应,9点钟对应最小值,3点钟对应最大值,
因此我们画表盘的时候最好从9点钟对应的角度为0, 12点钟对应的角度90度,3点钟对应的角度为180度。
画表盘就是设置好圆心(x,y)和半径r,然后计算圆周上的两个点,将相邻的两个点调用画直线函数连接起来。
/*DrawArc.画一个半圆 * start_angle in degree * sweep in degree * x,y是圆心的位置 * radius是半径 * start_angle 起始角度,9点钟作为0角度 * sweep 扫描角度 * 从9点钟开始作为0角度,顺时针旋转 */ void ssd1306_DrawArc_from9(uint8_t x, uint8_t y, uint8_t radius, uint16_t start_angle, uint16_t sweep, SSD1306_COLOR color) { float approx_degree; uint32_t approx_segments; uint8_t xp1,xp2; uint8_t yp1,yp2; uint32_t count = 0; uint32_t loc_sweep = 0; float rad; loc_sweep = ssd1306_NormalizeTo0_360(sweep); count = (ssd1306_NormalizeTo0_360(start_angle)); approx_segments = loc_sweep; approx_degree = 1; while(count < approx_segments) { rad = ssd1306_DegToRad(count*approx_degree); xp1 = x - (int8_t)(cos(rad)*radius); yp1 = y - (int8_t)(sin(rad)*radius); count++; if(count != approx_segments) { rad = ssd1306_DegToRad(count*approx_degree); } else { rad = ssd1306_DegToRad(loc_sweep); } xp2 = x - (int8_t)(cos(rad)*radius); yp2 = y - (int8_t)(sin(rad)*radius); ssd1306_DrawLine(xp1,yp1,xp2,yp2,color); } return; }
4.画指针
画指针比较简单,就是在圆周上找一个点,将这个点和圆心连接,就变成了一个指针,改变半径的大小,就可以实现指针的长短。
难点是如何将指针的角度和实际的温度值对应起来。假设温度的范围为-15摄氏度到45摄氏度,共60摄氏度,则每一个角度对应的温度值为60/180;
如果当前温度是20度,则对应的角度为20*60/180度。
/* 画一条圆心到圆周的直线,实现指针 */ void ssd1306_draw_line_of_arc(uint8_t x, uint8_t y, uint8_t radius, uint16_t angle,SSD1306_COLOR color) { float approx_degree; uint8_t xp1; uint8_t yp1; uint32_t count = 0; float rad; count = (ssd1306_NormalizeTo0_360(angle)); approx_degree = 1; rad = ssd1306_DegToRad(count*approx_degree); xp1 = x - (int8_t)(cos(rad)*radius); yp1 = y - (int8_t)(sin(rad)*radius); ssd1306_DrawLine(x, y, xp1, yp1, color); }
5. 画刻度
画刻度的方法,可以参考上面画指针的方法,从同一个角度画出的直线,与两个同圆心不同半径的圆的交点,将这两个交点连接起来就是刻度
/* 画一条刻度线 */ void ssd1306_draw_line_of_kedu(uint8_t x, uint8_t y, uint8_t radius, uint16_t angle,SSD1306_COLOR color) { float approx_degree; uint8_t xp1,xp2; uint8_t yp1,yp2; uint32_t count = 0; float rad; count = (ssd1306_NormalizeTo0_360(angle)); approx_degree = 1; rad = ssd1306_DegToRad(count*approx_degree); xp1 = x - (int8_t)(cos(rad)*radius); yp1 = y - (int8_t)(sin(rad)*radius); xp2 = x - (int8_t)(cos(rad)*(radius-4));//刻度线的长度为4 yp2 = y - (int8_t)(sin(rad)*(radius-4)); ssd1306_DrawLine(xp1, yp1, xp2, yp2, color); }
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(); }
7. I2C管脚的初始化和任务初始化
void Ssd1306TestTask(void* arg) { (void) arg; uint32_t retval = 0; GpioInit(); IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA); IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL); I2cInit(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE); WatchDogDisable(); usleep(20*1000); ssd1306_Init(); ssd1306_Fill(Black); ssd1306_SetCursor(0, 0); ssd1306_DrawString("Hello HarmonyOS!", Font_7x10, White); uint32_t start = HAL_GetTick(); ssd1306_UpdateScreen(); uint32_t end = HAL_GetTick(); printf("ssd1306_UpdateScreen time cost: %d ms.\r\n", end - start); // retval = AHT20_Calibrate(); printf("AHT20_Calibrate: %d\r\n", retval); TestGetTick(); while (1) { float temp = 0.0, humi = 0.0; //retval = AHT20_StartMeasure(); //printf("AHT20_StartMeasure: %d\r\n", retval); retval = AHT20_GetTemperHumi(&temp, &humi); printf("AHT20_GetMeasureResult: %d, temp = %.2f, humi = %.2f\r\n", retval, temp, humi); ssd1306_update_temper(temp, humi); sleep(1); //ssd1306_TestAll(); } }
到此,相信大家对"如何实现温度传感器和OLED"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
温度
角度
指针
表盘
刻度
圆心
传感器
两个
半径
半圆
圆周
实际
就是
方法
直线
交点
内容
函数
半圆形
湿度
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
管理服务器角色
云服务器 性能
互联网科技对接会
河北机电软件开发公司
数据库成功修复
魔兽怀旧服一直与服务器断开连接
冷备份数据库时需要关闭什么
模式与关系数据库定义
内网服务器端口
九江软件开发外包公司
福建统一软件开发服务以客为尊
上海 网络技术有限公司
目前社会面临的问题网络安全
苏州国兴互联网络科技
黄陂软件开发与定制
华科网络安全学院怎样
象山财务软件开发报价
中国地图软件开发者
数据库类简历
网络技术公司取名
本地服务器有nas和oss吗
贵州时代网络技术分类市场价
password网络安全术语
网络安全配置思维导图
爱推大数据库
高港区自动化网络技术诚信合作
益阳象佳软件开发有限公司
市多举措抓好网络安全工作
根据数据库行号查询
网络技术专业网络构建简称网构