如何实现温度传感器和OLED
发表于:2025-11-08 作者:千家信息网编辑
千家信息网最后更新 2025年11月08日,本篇内容主要讲解"如何实现温度传感器和OLED",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何实现温度传感器和OLED"吧!1. OLED驱动2. 温湿
千家信息网最后更新 2025年11月08日如何实现温度传感器和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安全错误
数据库的锁怎样保障安全
如何确定服务器数量
行政事业单位的网络安全
开死数据库
上海系统软件开发平台
如何装华为云服务器
北京酷炫网络技术年销售多少
棋七网络技术工作室
英语零基础能学懂软件开发吗
新的域控制器软件开发
北京上海广州计算机网络安全
敏捷开发只能用做软件开发吗
自动驾驶软件开发难吗
cdh验证数据库
密码编制学与网络安全
河南余料套料软件开发商
黄浦区品牌软件开发售后服务
开展网络安全培训课
如何查看数据库的版本
软件开发所需人员
南充网络技术推广方案
手机远程访问服务器文件
多屏软件开发
乐速网络技术有限公司
成都公司内部网络安全电话
服务器的安全控制原理
九江分布式服务器加盟
新能源车电机系统软件开发
数据库中的标志规范是什么意思
天河app软件开发哪家好
铜陵物业管理软件开发需要多少钱