AD轉換器是一種能夠將模擬(連續)量轉換為數字(離散)值的電路。這意味著什么?這意味著盡管數字值只能假設零和一的組合所形成的離散值,但模擬量可以假設范圍內的任何值。例如,如果我們測量理想AA電池的電壓,則可以找到0V至1.5V之間的任何值,因為這是模擬量。理想燈的輸出狀態必須僅假設兩個狀態(關閉或打開),這是一個離散的幅度。由于微控制器使用這種離散邏輯工作,因此我們需要一種能夠將模擬量轉換為數字量(或離散量)的電路。
步驟2:使用的資源
?一根Lolin32 Lite卡v1.0.0
?將Hantek DSO4102C示波器用作信號發生器
步驟3:ESP32 ADC
根據Espressif數據,ESP32芯片可能在測量結果中,從一個芯片到另一個芯片的誤差為+/- 6%。
此外,該轉換對于每個可用的讀取范圍都沒有線性答案。樂鑫提供了一種校準方法,建議用戶在認為有必要達到所需精度時采用其他方法。
我們將進行數據采集,并從中顯示ADC響應和應用數學過程讀取調整的示例。
有幾種(更簡單或更復雜的)方法可以完成這些修正。由您決定最適合您的項目。
此處顯示的內容具有說明性目的,并嘗試解決在調整過程中可以觀察到的有趣點。
步驟4:使用的電路
我使用了示波器,其信號發生器的頻率高達25 MHz,即Hantek DSO4102C。我們產生了由ESP A/D和示波器讀取的波形。收集的數據記錄在csv和電子表格中,我將在文章末尾進行下載。
第5步:使用過的符號
我們選擇了一個低頻梯形信號,該信號可以訪問整個轉換范圍內的斜坡。
步驟6:示波器獲得的數據
捕獲由示波器執行。數據存儲在csv文件中。請注意信號的上升和下降斜率上的輕微彎曲。
步驟7:示波器獲得的數據(Excel中的csv文件)
我們在這里進行采樣。
步驟8:ADC獲得的數據
通過更改傳輸串行速率,我們可以查看ADC捕獲的數據。觀察梯形信號的變形。
在Arduino IDE串行繪圖儀上觀察到的數據
步驟9:ADC獲得的數據-Excel
使用更高的速率和串行終端,我們可以捕獲值并將其應用到Excel中進行比較。
步驟10:爬坡的比較
我們比較兩個擋塊的兩個攀登坡道。
請注意兩個坡道上出現的曲率。
請注意同樣,對于相同的斜坡,ESP32的采樣數要比示波器多。
步驟11:計算采樣數
由于ESP32提供的樣本數量比示波器多,因此我們需要將這些值均等化,因為它們將用作比較兩條曲線的指標。
為此,我們將進行直接比較。
我們有305個示波器斜坡樣本和2365個ADC斜坡樣本。
因為這些斜坡屬于在相同的范圍內,可以說每個示波器大約有7.75個ADC采樣。
將每個示波器采樣的索引乘以相同的曲線,但是索引等于ADC和重新分配的數據。
要填充新職位的缺失數據,我們將應用一條曲線,以統計方式擬合已知數據。
步驟12:填補空白-趨勢線
選擇已知數據(藍點),方法是單擊,然后用右鍵單擊,我們選擇:“添加趨勢線。. 。”
在出現的窗口中,我們選擇多項式類型(階數2就足夠了。)
我們還選中了“在圖表中查看方程式”和“顯示”圖表中的R平方值”。
我們單擊“關閉”。
步驟13:填補空白-2級多項式曲線
Excel為我們提供了兩條新信息:
請記住,距離1越近,方程越合適。
我們不需深入研究所涉及的數學,而僅將其用作工具即可。
步驟14:填補空白-評估函數
讓我們填補用等式生成的數據在采樣間隙中。然后,逐點比較它們。
y = -9E-08x2 + 0,0014x + 0,1505
R2= 0 ,9999
示波器電壓= -9E-08 * index2 + 0,0014 * index + 0,1505
步驟15:將示波器電壓轉換為等效值以與ADC進行比較
讓我們利用這一點還將示波器電壓的值轉換為等效ADC
由于在ESP32的ADP中獲得的最高值為4095,相當于相同索引的2.958V讀數,我們可以這樣說:
每個示波器的測量電壓大約等于AD的1384.4單位。因此,我們可以將示波器的所有測量值乘以該值。
步驟16:比較獲得的兩個斜坡
可視化
步驟17:ADC讀數差異的行為(錯誤)
下面的曲線顯示了ADC讀數的差異如何隨測量變化的行為。通過收集這些數據,我們可以找到校正函數。
要找到此曲線,我們只需繪制每個度量中的差異作為每個可能AD位置(0至4095)的函數即可。
p》
步驟18:ADC讀取差異行為-查找校正函數
我們可以在Excel中通過添加趨勢線來確定校正函數,現在已達到較高的程度,直到它完全適合我們的數據為止。
步驟19:使用其他軟件
用于確定曲線的其他有趣軟件是PolySolve,可直接在以下鏈接上使用:https://arachnoid.com/polysolve/或作為Java應用程序下載
它允許應用高級多項式回歸和格式化函數以及其他功能的交付。
要使用它,只需在第一行文本中輸入數據即可。框。數據必須遵循X,Y的順序,并以逗號或制表符分隔。請謹慎使用正確的點作為小數點。
如果正確設置了輸入數據的格式,則會在下一個框中顯示一個圖表。
這是我們ADC誤差曲線的變化方式。
此窗口將顯示回歸的結果,包括函數充足性數據,該數據可以用幾種方式格式化其輸出:作為C/C ++函數,系數列表,函數
注意:注意小數點分隔符
步驟20:常量和設置()
I在此處指出用于模擬捕獲的GPIO。我初始化了串行端口以及用于模擬捕獲的引腳。
const int pin_leitura = 36; //GPIO usado para captura analógica
void setup() {
Serial.begin(1000000); //Iniciciando a porta serial somente para debug
pinMode(pin_leitura, INPUT); //Pino utilizado para captura analógica
}
步驟21:循環()和校正函數
我們會捕獲調整后的電壓,然后打印帶有或不帶有正確校正的值。
void loop() {
int valor_analogico = analogRead(pin_leitura); //realiza a captura da tens?o ajustada
//Serial.print(valor_analogico + f(valor_analogico)); //imprime os valores para debug (COM CORRE??O)
Serial.print(valor_analogico); //imprimime os valores para debug (SEM CORRE??O)
Serial.print(“,”);
Serial.print(4095);//cria uma linha para marcar o valor máximo de 4095
Serial.print(“,”);
Serial.println(0); //cria uma linha para marcar o valor mínimo de 0
}
第12行中的通知中,我們可以選擇使用
步驟22:使用PolySolve校正函數
在這里,我們在Arduino IDE內部使用PolySolve函數
/*
Mode: normal
Polynomial degree 6, 2365 x,y data pairs
Correlation coefficient (r^2) = 9,907187626418e-01
Standard error = 1,353761109831e+01
Output form: C/C++ function:
Copyright ? 2012, P. Lutus -- http://www.arachnoid.com. All Rights Reserved.
*/
double f(double x) {
return 2.202196968876e+02
+ 3.561383996027e-01 * x
+ 1.276218788985e-04 * pow(x, 2)
+ -3.470360275448e-07 * pow(x, 3)
+ 2.082790802069e-10 * pow(x, 4)
+ -5.306931174991e-14 * pow(x, 5)
+ 4.787659214703e-18 * pow(x, 6);
}
注意逗號分隔作為小數點分隔符。
步驟23:帶有校正的捕獲-繪圖儀序列
步驟24:計算成本
要執行多項式計算,處理器必須處理此任務。這可能會導致執行延遲,具體取決于源代碼和可用的計算能力。
在這里,我們看到了使用多項式多項式的測試結果表。注意使用pow()函數的時間與不使用pow()函數的時間之間的時差。
步驟25:測試代碼-設置()和循環啟動()
在這里,我們有測試中使用的代碼。
void setup() {
Serial.begin(1000000); //Iniciando a porta serial somente para debug
}
void loop() {
float valor_analogico = 500.0; //um valor arbtrario
float quantidade = 10000.0; //quantidade de chamadas
float contador = 0.0; //contador de chamadas
步驟26:測試代碼-循環()和處理
我使用了micros()函數來獲取以微秒為單位的值。
//============= inicia o processo
float agora = micros(); //marca o instante inicial
while (contador 《 quantidade) {
//v(valor_analogico); //fun??o vazia
//r(valor_analogico); //fun??o com retorno
//f0(valor_analogico); //grau 0
//f1(valor_analogico); //grau 1
//f2(valor_analogico); //grau 2
//f3(valor_analogico); //grau 3
//f4(valor_analogico); //grau 4
//f5(valor_analogico); //grau 5
//f6(valor_analogico); //grau 6
//f13_semPow(valor_analogico); //grau 13o SEM a fun??o POW
//f13_comPow(valor_analogico); //grau 13o COM a fun??o POW
contador++;
}
agora = (micros() - agora) / quantidade; //determina o intervalo que se passou para cada itera??o
//============= finaliza o processo
步驟27:測試代碼-循環()-結果
我們打印從13級函數返回的值(帶有和不帶有POW進行比較)以及處理間隔。
//imprime o valor retornado da fun??o de grau 13 com e sem POW para compara??o
Serial.print(f13_semPow(valor_analogico)); //grau 13o SEM a fun??o POW
Serial.print(“ - ”);
Serial.print(f13_comPow(valor_analogico)); //grau 13o COM a fun??o POW
Serial.print(“ - ”);
//imprime o intervalo do processamento
Serial.println(agora, 6);
}
步驟28:測試代碼-使用的函數
空度為0和1的函數(僅帶返回)。
//FUN??O VAZIA
double v(double x) {
}
//FUN??O SOMENTE COM RETORNO
double r(double x) {
return x;
}
//FUN??O DE GRAU 0
double f0(double x) {
return 2.202196968876e+02;
}
//FUN??O DE GRAU 1
double f1(double x) {
return 2.202196968876e+02
+ 3.561383996027e-01 * x;
}
2、3和4級函數。
//FUN??O DE GRAU 2
double f2(double x) {
return 2.202196968876e+02
+ 3.561383996027e-01 * x
+ 1.276218788985e-04 * pow(x, 2);
}
//FUN??O DE GRAU 3
double f3(double x) {
return 2.202196968876e+02
+ 3.561383996027e-01 * x
+ 1.276218788985e-04 * pow(x, 2)
+ -3.470360275448e-07 * pow(x, 3);
}
//FUN??O DE GRAU 4
double f4(double x) {
return 2.202196968876e+02
+ 3.561383996027e-01 * x
+ 1.276218788985e-04 * pow(x, 2)
+ -3.470360275448e-07 * pow(x, 3)
+ 2.082790802069e-10 * pow(x, 4);
}
5和6級函數。
//FUN??O DE GRAU 5
double f5(double x) {
return 2.202196968876e+02
+ 3.561383996027e-01 * x
+ 1.276218788985e-04 * pow(x, 2)
+ -3.470360275448e-07 * pow(x, 3)
+ 2.082790802069e-10 * pow(x, 4)
+ -5.306931174991e-14 * pow(x, 5);
}
//FUN??O DE GRAU 6
double f6(double x) {
return 2.202196968876e+02
+ 3.561383996027e-01 * x
+ 1.276218788985e-04 * pow(x, 2)
+ -3.470360275448e-07 * pow(x, 3)
+ 2.082790802069e-10 * pow(x, 4)
+ -5.306931174991e-14 * pow(x, 5)
+ 4.787659214703e-18 * pow(x, 6);
}
使用POW的13級函數。
//FUN??O DE GRAU 13 USANDO O POW
double f13_comPow(double x) {
return 2, 161282383460e+02
+ 3, 944594843419e-01 * x
+ 5, 395439724295e-04 * pow(x, 2)
+ -3, 968558178426e-06 * pow(x, 3)
+ 1, 047910519933e-08 * pow(x, 4)
+ -1, 479271312313e-11 * pow(x, 5)
+ 1, 220894795714e-14 * pow(x, 6)
+ -6, 136200785076e-18 * pow(x, 7)
+ 1, 910015248179e-21 * pow(x, 8)
+ -3, 566607830903e-25 * pow(x, 9)
+ 5, 000280815521e-30 * pow(x, 10)
+ 3, 434515045670e-32 * pow(x, 11)
+ -1, 407635444704e-35 * pow(x, 12)
+ 9,871816383223e-40 * pow(x,13);
}
不使用13級函數POW。
//FUN??O DE GRAU SEM USAR O POW
double f13_semPow(double x) {
return 2, 161282383460e+02
+ 3, 944594843419e-01 * x
+ 5, 395439724295e-04 * x * x
+ -3, 968558178426e-06 * x * x * x
+ 1, 047910519933e-08 * x * x * x * x
+ -1, 479271312313e-11 * x * x * x * x * x
+ 1, 220894795714e-14 * x * x * x * x * x * x
+ -6, 136200785076e-18 * x * x * x * x * x * x * x
+ 1, 910015248179e-21 * x * x * x * x * x * x * x * x
+ -3, 566607830903e-25 * x * x * x * x * x * x * x * x * x
+ 5, 000280815521e-30 * x * x * x * x * x * x * x * x * x * x
+ 3, 434515045670e-32 * x * x * x * x * x * x * x * x * x * x * x
+ -1, 407635444704e-35 * x * x * x * x * x * x * x * x * x * x * x * x
+ 9, 871816383223e-40 * x * x * x * x * x * x * x * x * x * x * x * x * x;
}
責任編輯:wv
-
示波器
+關注
關注
113文章
6273瀏覽量
185522 -
adc
+關注
關注
98文章
6525瀏覽量
545232
發布評論請先 登錄
相關推薦
評論