文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何实现温度传感器和OLED

2024-04-02 19:55

关注

本篇内容主要讲解“如何实现温度传感器和OLED”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何实现温度传感器和OLED”吧!

1. OLED驱动

2. 温湿度传感器AHT20驱动

3. 画表盘

由于表盘是半个圆,而且一般是从9点钟方向开始,顺指针旋转,与实际的温度值相对应,9点钟对应最小值,3点钟对应最大值,

因此我们画表盘的时候最好从9点钟对应的角度为0, 12点钟对应的角度90度,3点钟对应的角度为180度。

画表盘就是设置好圆心(x,y)和半径r,然后计算圆周上的两个点,将相邻的两个点调用画直线函数连接起来。

  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”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯