溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何實(shí)現(xiàn)溫度傳感器和OLED

發(fā)布時間:2021-10-21 13:43:00 來源:億速云 閱讀:175 作者:iii 欄目:web開發(fā)

本篇內(nèi)容主要講解“如何實(shí)現(xiàn)溫度傳感器和OLED”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“如何實(shí)現(xiàn)溫度傳感器和OLED”吧!

1. OLED驅(qū)動

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

3. 畫表盤

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

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

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

/*DrawArc.畫一個半圓  * start_angle in degree  * sweep in degree  * x,y是圓心的位置  * radius是半徑  * start_angle 起始角度,9點(diǎn)鐘作為0角度  * sweep 掃描角度  * 從9點(diǎn)鐘開始作為0角度,順時針旋轉(zhuǎn)  */  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.畫指針

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

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

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

/*  畫一條圓心到圓周的直線,實(shí)現(xiàn)指針  */  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. 畫刻度

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

/*  畫一條刻度線  */  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. 使用上面幾個函數(shù),畫出我們設(shè)計的溫度表

//更新溫度和濕度  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管腳的初始化和任務(wù)初始化

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();  }  }

到此,相信大家對“如何實(shí)現(xiàn)溫度傳感器和OLED”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI