自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

2020征文-鴻蒙開發(fā)板6.WiFi IoT智能家居套件 - 溫度傳感器和OLED實(shí)踐

開發(fā) 前端
在開發(fā)板套件中,有一個(gè)OLED屏幕擴(kuò)展板,溫濕度傳感器擴(kuò)展板,本次我們就用這兩個(gè)擴(kuò)展板來實(shí)現(xiàn)一個(gè)簡易數(shù)字溫度計(jì)。

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com/#zz

這是一份遲來的文章,代碼寫好幾天了,由于太忙,一直沒來得及上傳。

在開發(fā)板套件中,有一個(gè)OLED屏幕擴(kuò)展板,溫濕度傳感器擴(kuò)展板,本次我們就用這兩個(gè)擴(kuò)展板來實(shí)現(xiàn)一個(gè)簡易數(shù)字溫度計(jì)。初步的打算是做一個(gè)儀表盤,用指針指示溫度和濕度,但是由于OLED只有128*64,因此儀表盤不會(huì)很清晰,我們?cè)谂赃呍儆脭?shù)字直接顯示一下。雖然簡陋一點(diǎn),但是只要原理學(xué)會(huì)了,其他復(fù)雜的儀表盤我們同樣可以做出來。


OLED屏幕為128*64的點(diǎn)陣,通信接口為I2C0,從機(jī)地址為0x3C

溫濕度傳感器AHT20,通信接口也是I2C0,從機(jī)地址為0x38

熟悉I2C的朋友都知道,I2C是多從機(jī)模式,只要從機(jī)地址不同,我們可以掛在同一個(gè)總線下,進(jìn)行復(fù)用。

既然如此,那我們就可以同時(shí)使用這兩個(gè)擴(kuò)展板。

1. OLED驅(qū)動(dòng)

OLED驅(qū)動(dòng)開發(fā)方法,參考許思維老師的代碼 https://gitee.com/hihopeorg/harmonyos-ssd1306

此處不再贅述

2. 溫濕度傳感器AHT20驅(qū)動(dòng)

參考許思維老師的代碼 https://gitee.com/hihopeorg/harmonyos-aht20

此處不再贅述。

3. 畫表盤

由于表盤是半個(gè)圓,而且一般是從9點(diǎn)鐘方向開始,順指針旋轉(zhuǎn),與實(shí)際的溫度值相對(duì)應(yīng),9點(diǎn)鐘對(duì)應(yīng)最小值,3點(diǎn)鐘對(duì)應(yīng)最大值,

因此我們畫表盤的時(shí)候最好從9點(diǎn)鐘對(duì)應(yīng)的角度為0, 12點(diǎn)鐘對(duì)應(yīng)的角度90度,3點(diǎn)鐘對(duì)應(yīng)的角度為180度。

畫表盤就是設(shè)置好圓心(x,y)和半徑r,然后計(jì)算圓周上的兩個(gè)點(diǎn),將相鄰的兩個(gè)點(diǎn)調(diào)用畫直線函數(shù)連接起來。

  1. /*DrawArc.畫一個(gè)半圓 
  2.  
  3. * start_angle in degree 
  4.  
  5. * sweep in degree 
  6.  
  7. * x,y是圓心的位置 
  8.  
  9. * radius是半徑 
  10.  
  11. * start_angle 起始角度,9點(diǎn)鐘作為0角度 
  12.  
  13. * sweep 掃描角度 
  14.  
  15. * 從9點(diǎn)鐘開始作為0角度,順時(shí)針旋轉(zhuǎn) 
  16.  
  17. */ 
  18.  
  19. void ssd1306_DrawArc_from9(uint8_t x, uint8_t y, uint8_t radius, uint16_t start_angle, uint16_t sweep, SSD1306_COLOR color) { 
  20.  
  21. float approx_degree; 
  22.  
  23. uint32_t approx_segments; 
  24.  
  25. uint8_t xp1,xp2; 
  26.  
  27. uint8_t yp1,yp2; 
  28.  
  29. uint32_t count = 0; 
  30.  
  31. uint32_t loc_sweep = 0; 
  32.  
  33. float rad; 
  34.  
  35. loc_sweep = ssd1306_NormalizeTo0_360(sweep); 
  36.  
  37. count = (ssd1306_NormalizeTo0_360(start_angle)); 
  38.  
  39. approx_segments = loc_sweep; 
  40.  
  41. approx_degree = 1; 
  42.  
  43. while(count < approx_segments) 
  44.  
  45.  
  46. rad = ssd1306_DegToRad(count*approx_degree); 
  47.  
  48. xp1 = x - (int8_t)(cos(rad)*radius); 
  49.  
  50. yp1 = y - (int8_t)(sin(rad)*radius); 
  51.  
  52. count++; 
  53.  
  54. if(count != approx_segments) 
  55.  
  56.  
  57. rad = ssd1306_DegToRad(count*approx_degree); 
  58.  
  59.  
  60. else 
  61.  
  62.  
  63. rad = ssd1306_DegToRad(loc_sweep); 
  64.  
  65.  
  66. xp2 = x - (int8_t)(cos(rad)*radius); 
  67.  
  68. yp2 = y - (int8_t)(sin(rad)*radius); 
  69.  
  70. ssd1306_DrawLine(xp1,yp1,xp2,yp2,color); 
  71.  
  72.  
  73. return
  74.  

 4.畫指針

畫指針比較簡單,就是在圓周上找一個(gè)點(diǎn),將這個(gè)點(diǎn)和圓心連接,就變成了一個(gè)指針,改變半徑的大小,就可以實(shí)現(xiàn)指針的長短。

難點(diǎn)是如何將指針的角度和實(shí)際的溫度值對(duì)應(yīng)起來。假設(shè)溫度的范圍為-15攝氏度到45攝氏度,共60攝氏度,則每一個(gè)角度對(duì)應(yīng)的溫度值為60/180;

如果當(dāng)前溫度是20度,則對(duì)應(yīng)的角度為20*60/180度。

  1. /* 
  2.  
  3. 畫一條圓心到圓周的直線,實(shí)現(xiàn)指針 
  4.  
  5. */ 
  6.  
  7. void ssd1306_draw_line_of_arc(uint8_t x, uint8_t y, uint8_t radius, uint16_t angle,SSD1306_COLOR color) 
  8.  
  9.  
  10. float approx_degree; 
  11.  
  12. uint8_t xp1; 
  13.  
  14. uint8_t yp1; 
  15.  
  16. uint32_t count = 0; 
  17.  
  18. float rad; 
  19.  
  20. count = (ssd1306_NormalizeTo0_360(angle)); 
  21.  
  22. approx_degree = 1; 
  23.  
  24. rad = ssd1306_DegToRad(count*approx_degree); 
  25.  
  26. xp1 = x - (int8_t)(cos(rad)*radius); 
  27.  
  28. yp1 = y - (int8_t)(sin(rad)*radius); 
  29.  
  30. ssd1306_DrawLine(x, y, xp1, yp1, color); 
  31.  

 5. 畫刻度

畫刻度的方法,可以參考上面畫指針的方法,從同一個(gè)角度畫出的直線,與兩個(gè)同圓心不同半徑的圓的交點(diǎn),將這兩個(gè)交點(diǎn)連接起來就是刻度

  1. /* 
  2.  
  3. 畫一條刻度線 
  4.  
  5. */ 
  6.  
  7. void ssd1306_draw_line_of_kedu(uint8_t x, uint8_t y, uint8_t radius, uint16_t angle,SSD1306_COLOR color) 
  8.  
  9.  
  10. float approx_degree; 
  11.  
  12. uint8_t xp1,xp2; 
  13.  
  14. uint8_t yp1,yp2; 
  15.  
  16. uint32_t count = 0; 
  17.  
  18. float rad; 
  19.  
  20. count = (ssd1306_NormalizeTo0_360(angle)); 
  21.  
  22. approx_degree = 1; 
  23.  
  24. rad = ssd1306_DegToRad(count*approx_degree); 
  25.  
  26. xp1 = x - (int8_t)(cos(rad)*radius); 
  27.  
  28. yp1 = y - (int8_t)(sin(rad)*radius); 
  29.  
  30. xp2 = x - (int8_t)(cos(rad)*(radius-4));//刻度線的長度為4 
  31.  
  32. yp2 = y - (int8_t)(sin(rad)*(radius-4)); 
  33.  
  34. ssd1306_DrawLine(xp1, yp1, xp2, yp2, color); 
  35.  

 6. 使用上面幾個(gè)函數(shù),畫出我們?cè)O(shè)計(jì)的溫度表

  1. //更新溫度和濕度 
  2.  
  3. void ssd1306_update_temper(float tempfloat humi) 
  4.  
  5.  
  6. int angle = 0; 
  7.  
  8. char buf[100] = {0}; 
  9.  
  10. ssd1306_Fill(Black); 
  11.  
  12. uint8_t x,y,r; 
  13.  
  14. //溫度表盤,半圓形 
  15.  
  16. x=30; 
  17.  
  18. y=28; 
  19.  
  20. r=28; 
  21.  
  22. ssd1306_DrawCircle(x,y,2,White); 
  23.  
  24. ssd1306_SetCursor(x-r, y); 
  25.  
  26. ssd1306_DrawString("-15", Font_6x8, White); 
  27.  
  28. ssd1306_SetCursor(x+r-6, y); 
  29.  
  30. ssd1306_DrawString("45", Font_6x8, White); 
  31.  
  32. ssd1306_SetCursor(x-6, y-r+6); 
  33.  
  34. ssd1306_DrawString("15", Font_6x8, White); 
  35.  
  36. ssd1306_DrawArc_from9(x, y, r, 0, 180, White); 
  37.  
  38. //ssd1306_DrawArc_from9(x, y, r-1, 0, 180, White); 
  39.  
  40. ssd1306_draw_line_of_kedu(x,y,r,45,White); 
  41.  
  42. ssd1306_draw_line_of_kedu(x,y,r,90,White); 
  43.  
  44. ssd1306_draw_line_of_kedu(x,y,r,135,White); 
  45.  
  46. angle = (int)((temp + 15 )*180/60); 
  47.  
  48. ssd1306_draw_line_of_arc(x, y, r-2,angle, White); 
  49.  
  50. ssd1306_SetCursor(x+r+6, y-r/2); 
  51.  
  52. sprintf(buf, "%.1fC"temp); 
  53.  
  54. ssd1306_DrawString(buf, Font_7x10, White); 
  55.  
  56. //濕度表盤,半圓形 
  57.  
  58. x=30; 
  59.  
  60. y=55; 
  61.  
  62. r=22; 
  63.  
  64. ssd1306_DrawCircle(x,y,2,White); 
  65.  
  66. ssd1306_SetCursor(x-r-4, y); 
  67.  
  68. ssd1306_DrawString("20", Font_6x8, White); 
  69.  
  70. ssd1306_SetCursor(x+r-6, y); 
  71.  
  72. ssd1306_DrawString("100", Font_6x8, White); 
  73.  
  74. ssd1306_SetCursor(x-6, y-r+6); 
  75.  
  76. ssd1306_DrawString("60", Font_6x8, White); 
  77.  
  78. ssd1306_DrawArc_from9(x, y, r, 0, 180, White); 
  79.  
  80. //ssd1306_DrawArc_from9(x, y, r-1, 0, 180, White); 
  81.  
  82. ssd1306_draw_line_of_kedu(x,y,r,45,White); 
  83.  
  84. ssd1306_draw_line_of_kedu(x,y,r,90,White); 
  85.  
  86. ssd1306_draw_line_of_kedu(x,y,r,135,White); 
  87.  
  88. angle = (int)((humi - 20 )*180/80); 
  89.  
  90. ssd1306_draw_line_of_arc(x, y, r-2,angle, White); 
  91.  
  92. ssd1306_SetCursor(x+r+6, y-r/2); 
  93.  
  94. sprintf(buf, "%%%.1f", humi); 
  95.  
  96. ssd1306_DrawString(buf, Font_7x10, White); 
  97.  
  98. //ssd1306_TestArc(); 
  99.  
  100. ssd1306_UpdateScreen(); 
  101.  

 7. I2C管腳的初始化和任務(wù)初始化

  1. void Ssd1306TestTask(void* arg) 
  2.  
  3.  
  4. (void) arg; 
  5.  
  6. uint32_t retval = 0; 
  7.  
  8. GpioInit(); 
  9.  
  10. IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA); 
  11.  
  12. IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL); 
  13.  
  14. I2cInit(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE); 
  15.  
  16. WatchDogDisable(); 
  17.  
  18. usleep(20*1000); 
  19.  
  20. ssd1306_Init(); 
  21.  
  22. ssd1306_Fill(Black); 
  23.  
  24. ssd1306_SetCursor(0, 0); 
  25.  
  26. ssd1306_DrawString("Hello HarmonyOS!", Font_7x10, White); 
  27.  
  28. uint32_t start = HAL_GetTick(); 
  29.  
  30. ssd1306_UpdateScreen(); 
  31.  
  32. uint32_t end = HAL_GetTick(); 
  33.  
  34. printf("ssd1306_UpdateScreen time cost: %d ms.\r\n"end - start); 
  35.  
  36. // 
  37.  
  38. retval = AHT20_Calibrate(); 
  39.  
  40. printf("AHT20_Calibrate: %d\r\n", retval); 
  41.  
  42. TestGetTick(); 
  43.  
  44. while (1) { 
  45.  
  46. float temp = 0.0, humi = 0.0; 
  47.  
  48. //retval = AHT20_StartMeasure(); 
  49.  
  50. //printf("AHT20_StartMeasure: %d\r\n", retval); 
  51.  
  52. retval = AHT20_GetTemperHumi(&temp, &humi); 
  53.  
  54. printf("AHT20_GetMeasureResult: %d, temp = %.2f, humi = %.2f\r\n", retval, temp, humi); 
  55.  
  56. ssd1306_update_temper(temp, humi); 
  57.  
  58. sleep(1); 
  59.  
  60. //ssd1306_TestAll(); 
  61.  
  62.  

 想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com/#zz

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2020-12-29 09:59:01

鴻蒙HarmonyOS智能家居

2020-11-10 12:08:25

開發(fā)框架

2020-12-30 11:02:34

鴻蒙HarmonyOS智能家居

2020-10-26 10:21:39

Wi-Fi IoT智能家居套件

2020-11-04 13:20:14

HiSpark

2020-11-13 11:53:52

4.WiFi IoT

2020-12-16 10:05:48

鴻蒙開發(fā)板Onenet平臺(tái)

2020-10-21 10:01:47

HiSpark Wi-智能家居套件

2015-09-24 13:41:28

物聯(lián)網(wǎng)智能家居傳感器

2022-09-30 13:50:07

設(shè)備開發(fā)鴻蒙

2020-11-24 10:05:54

人工智能

2023-09-22 13:40:12

2020-11-23 13:09:42

HI3861

2020-06-22 14:17:23

智能家居5GWiFi 6

2023-04-25 16:30:58

設(shè)備開發(fā)鴻蒙

2020-12-15 09:33:40

鴻蒙Hi3861開發(fā)板

2015-08-26 10:14:28

2020-12-15 11:57:49

Hi3861 HarmonyOS開發(fā)板

2024-04-12 07:00:00

人工智能物聯(lián)網(wǎng)綠色建筑

2023-03-12 15:21:57

傳感器Wi-Fi
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)