你好,我是愛吃魚香ROS的小魚。上面兩節(jié)通過LED和按鍵學(xué)習(xí)了GPIO的輸出和輸入。
但這種輸入和輸出只有兩種狀態(tài)HIGH或者LOW,我們稱這種為數(shù)字邏輯,這也是輸入輸出函數(shù)稱為數(shù)字輸入和數(shù)字輸出的原因。
但是電池的電壓是一個(gè)在一個(gè)范圍內(nèi)不斷變化的值,明顯無法通過HIGH和LOW來表示,所以本節(jié)我們學(xué)習(xí)使用ADC,將電壓值這個(gè)模擬信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)。
本教程所使用硬件平臺(tái)為MicroROS學(xué)習(xí)板V1.0.0,可點(diǎn)擊閱讀原文購買及查看詳情

一、ADC介紹
ADC(analog to digital converter)模數(shù)轉(zhuǎn)換器是一種非常常見的外設(shè),用于 將電壓等模擬信號(hào)轉(zhuǎn)換為數(shù)字形式 ,以便微控制器可以讀取和處理。
ADC在控制和監(jiān)控應(yīng)用中非常有用,因?yàn)榇蠖鄶?shù)傳感器(例如溫度、壓力、力)都是輸出的模擬電壓,所以我們需要掌握ADC。
與ADC相對應(yīng)的DAC——用于將數(shù)字信號(hào)轉(zhuǎn)換成模擬信號(hào),比如將一段二進(jìn)制的音樂文件轉(zhuǎn)換成一段連續(xù)的電壓信號(hào)播放出來就需要DAC。
二、電池電壓測量原理
在我們的開發(fā)板所使用的ESP32單片機(jī)上,自帶了ADC模塊,我們只需要將需要測量的模擬電壓接入相應(yīng)引腳,接著調(diào)用ADC相關(guān)API即可讀取。
因?yàn)锳DC原理是采用電壓比較方式進(jìn)行測量,而我們的單片機(jī)的供電電壓為3.3V,所以測量的電壓范圍最大不能超過3.3V,但我們采用的電池電壓和板子的供電電壓分別是12V和5V的。
所以想要使用單片機(jī)測量電池電壓,那么就要想辦法將板子測量的電壓按照比例縮小即可,根據(jù)初中物理知識(shí),串聯(lián)分壓原理,小魚就設(shè)計(jì)了這樣的電路。
串聯(lián)分壓,左邊接電機(jī)電壓輸入引腳,右側(cè)接地,R18是40.2千歐阻值的電阻,R19是10千歐的,假如此時(shí)VMOTOR的輸入電壓為5V,那么ESP_IO34的電壓就是

那么如果此時(shí)通過ADC測量出上的電壓,通過下面的等式就可以算出的電壓值。

三、Arduino ADC API
了解了原理,我們來看看Arduino為我們提供了哪些API可以直接獲取到引腳上的電壓。
3.1 設(shè)置ADC衰減系數(shù)(analogReadResolution)
這個(gè)函數(shù)用來設(shè)置ADC讀取時(shí)的衰減系數(shù)。
輸入到引腳的電壓在輸入到ADC之前可能會(huì)衰減。有 4 種可用的衰減選項(xiàng),衰減越高,可測量的輸入電壓就越高,為了能夠測量到12V以上的電壓,我們采用最高的衰減比-ADC_11db。
typedef enum {
ADC_0db,
ADC_2_5db,
ADC_6db,
ADC_11db,
} adc_attenuation_t;
3.2 讀取ADC值(analogRead)
此函數(shù)用于獲取給定引腳或ADC通道的ADC原始值,默認(rèn)是12位分辨率,所以這個(gè)讀出來的值的范圍就是0-2^12,也就是最大4096。
uint16_t analogRead(uint8_t pin);
pin要讀取ADC值的GPIO 引腳
返回值:ADC原始值
3.3 讀取電壓值(analogReadMillivolts)
此函數(shù)用于獲取給定引腳或ADC 通道的 ADC 值(以毫伏為單位)。
uint32_t analogReadMilliVolts(uint8_t pin);
pin要讀取ADC值的GPIO 引腳
返回值:此函數(shù)將以毫伏為單位返回模擬值。
四、編寫程序
利用上面的三個(gè)API和計(jì)算公式就可以實(shí)現(xiàn)電壓的測量,新建example04_adc工程,在main.cpp輸入代碼。
/**
* @file main.cpp
* @author fishros@foxmail.com
* @brief 4.電池電壓測量-學(xué)會(huì)使用ADC
* @version 0.1
* @date 2023-01-04
*
* @copyright Copyright(c) fishros.com 2023
*
*/
#include < Arduino.h >
void setup()
{
Serial.begin(115200);
pinMode(34, INPUT);
analogSetAttenuation(ADC_11db);
}
void loop()
{
int analogValue = analogRead(34); // 讀取原始值0-4096
int analogVolts = analogReadMilliVolts(34); // 讀取模擬電壓,單位毫伏
float realVolts = 5.02 * ((float)analogVolts * 1e-3); // 計(jì)算實(shí)際電壓值
Serial.printf("ADC analog value = %d\\n", analogValue);
Serial.printf("ADC millivolts value = %d\\n", analogVolts);
Serial.printf("realVolts value = %f\\n", realVolts);
delay(100);
}
五、測試
根據(jù)第三節(jié)中的原理圖,我們測量的是VMOTOR的電壓,VMOTOR是通過一個(gè)跳線帽選擇連接到5V還是12V上的,詳情可以看下面的原理圖。

對應(yīng)板子上的位置

這里我們把跳線帽調(diào)整到左側(cè),讓VMOTOR和5V連接,接著打開串口觀察測量到的電壓值。

可以看到我們成功的測量到了實(shí)際的電壓值為5.045V,符合正常電壓值。
如果你有整臺(tái)FishBot小車,可以將跳線帽調(diào)整到12V的位置,打開電池電源開關(guān),看看是否可以正常測量到12V的電壓。
六、總結(jié)
本節(jié)我們通過電池電壓測量的例程,學(xué)習(xí)了ADC的使用,電池電壓測量對我們機(jī)器人來說是非常重要的,當(dāng)電壓低的時(shí)候可以進(jìn)行自動(dòng)返回充電,然后等充電完成后再繼續(xù)工作。
-
adc
+關(guān)注
關(guān)注
100文章
7524瀏覽量
556166 -
電池電壓
+關(guān)注
關(guān)注
0文章
215瀏覽量
12289 -
GPIO
+關(guān)注
關(guān)注
16文章
1329瀏覽量
56252 -
ROS
+關(guān)注
關(guān)注
1文章
294瀏覽量
18755
發(fā)布評論請先 登錄
MCU ADC如何測量超過6V的VCC電池電壓呢?
實(shí)驗(yàn)板用鋰電池供電,怎么測量供電電壓?
請教哪位大俠做過電池內(nèi)阻測量 求助
STM8L的ADC之測量VDD電壓詳解+例程
測量電池電壓,請問有辦法在發(fā)射訊號(hào)時(shí),去量測ADC值嗎?
怎么使用ADC Delsig來測量系統(tǒng)中車載電池的電池容量
如何通過電池管理IC提升電池性能?
通過電池電壓測量的例程學(xué)習(xí)ADC模數(shù)轉(zhuǎn)換器的使用
RT1064學(xué)習(xí)筆記(1)--ADC例程(ADC Demo)
通過電壓電平轉(zhuǎn)換功能實(shí)現(xiàn)智能電池儲(chǔ)能系統(tǒng)
通過電池電壓測量的例程學(xué)習(xí)ADC的使用
評論