การวัดค่าเฉลี่ยปัจจุบันด้วย uC และปัดปัจจุบัน


12

นี่คือโพสต์แรกของฉัน ฉันเป็นคนที่แต่งตัวประหลาดซอฟต์แวร์พยายามที่จะทำฮาร์ดแวร์ดังนั้นอ่อนโยน :)

วงจรไฟฟ้า

ฉันกำลังออกแบบวงจรขนาดเล็ก (ดูรูปและขออภัยสำหรับแผนผังที่ยุ่งเหยิง) ที่เรียบง่ายและเรียบง่ายเป็นมอสเฟตต์และตัวขับเกตที่ออกแบบมาเพื่อสลับโหลดตัวต้านทาน (แผ่นความร้อนในกรณีนี้) จากไมโครคอนโทรลเลอร์ องค์ประกอบความร้อนมักจะมีความต้านทานต่ำมากและเพื่อรักษาพลังงานในระดับที่ต้องการ MOSFETS จะเปลี่ยนโดยใช้ PWM

การวัด

นอกจากด้านการใช้งานอย่างหมดจดแล้วยังมีจุดเน้นด้านการศึกษาอีกด้วย ฉันต้องการที่จะได้รับข้อเสนอแนะเกี่ยวกับการบริโภคในปัจจุบัน และวิธีการที่ไร้เดียงสาของฉันคือเพียงแค่โยนเซ็นเซอร์ IC ตัวปัดปัจจุบันบางตัว เมื่อใช้มัลติมิเตอร์เพื่อวัดแรงดันเอาต์พุตจากเซ็นเซอร์ฉันได้รับบางสิ่งที่ดูเหมือนกระแสเฉลี่ย (ด้วยการสลับ PWM) เนื่องจาก "ความช้า" ของแอมป์มิเตอร์ แต่เมื่อเชื่อมต่อเอาต์พุตเดียวกันกับ atmega328p ADC ฉันได้รับการอ่านที่ไม่ดี - ความเร็วที่นี่ทำให้การอ่านที่ใดก็ได้บนคลื่นสี่เหลี่ยม PWM

ดังนั้นคำถามของฉันคือฉันจะไปเกี่ยวกับการวัดกระแส (เฉลี่ย) เมื่อสลับกับ PWM ได้อย่างไร

ดูเหมือนว่าการออกแบบจะใช้ได้ แต่ฉันอาจพลาดบางสิ่งทั้งในการออกแบบและวิธีใช้ uC ADC ในบริบทนี้

แผนผัง


ฉันคิดว่าตัวกรองสามารถใช้เพื่อให้แรงดันเฉลี่ยจาก PWM บทความที่น่าสนใจที่อธิบายตัวกรองดังกล่าวและค่าใช้ขึ้นอยู่กับความถี่ PWM เป็นคนนี้
alexan_e

มีคำตอบที่เกี่ยวข้องในคำถามนี้ แต่พวกเขาเพียงกล่าวถึงการใช้สับและไอซีเพื่อวัดกระแส แม้ว่าจะไม่มีการกล่าวถึง PWM แต่อย่างใด
Ricardo

ขอบคุณสำหรับความคิดเห็น @alexan_e: TI กำลังแสดงตัวกรองอินพุตในแผ่นข้อมูล INA197 แต่ฉันไม่แน่ใจว่าจะใช้งานอย่างไร มันอาจเป็นวิธีที่จะไปเมื่อไม่มีแรงดันไฟฟ้าที่เสถียร
ltj

ฉันคิดว่านี่เป็นวิธีแก้ปัญหาของคุณ แต่ฉันอยากมีประสบการณ์เพิ่มเติมเกี่ยวกับเรื่องนี้ให้คำตอบโดยละเอียดนั่นคือเหตุผลที่ฉันโพสต์สิ่งนี้เป็นความคิดเห็น
alexan_e

เนื่องจากเอาต์พุตเป็น cucle PWM หน้าที่หลากหลายคุณสามารถใช้วงจรตัวตรวจจับสูงสุดและวัดค่าด้วย ADC
Martin

คำตอบ:


6

บางครั้งสิ่งที่ดูเรียบง่ายนั้นไม่ง่ายเลย คุณมีการวัดที่ค่อนข้างซับซ้อน แต่คุณต้องการผลลัพธ์ที่ง่าย สิ่งที่คุณต้องการวัดนั้นไม่คงที่มันเปลี่ยนแปลงไปตามกาลเวลา คุณสามารถคำนวณคุณสมบัติหนึ่งอย่างหรือหลายอย่างของปริมาณการใช้ปัจจุบันขึ้นอยู่กับระดับความต้องการของคุณ คุณสมบัติเหล่านี้จะช่วยให้คุณตรวจสอบระบบได้ดีขึ้น ฉันเสนอวิธีแก้ปัญหาต่าง ๆ ให้คุณ 3 ข้อโดยเพิ่มความซับซ้อน

โซลูชันที่ 1: ค่าเฉลี่ย

คุณต้องการได้ผลลัพธ์หนึ่งค่า -> รับเวลาโดยเฉลี่ย ตามที่เสนอโดย @akellyirl ให้ใช้ตัวกรอง low-pass คำนวณfloat y = alpha*input + (1-alpha)*yสำหรับแต่ละตัวอย่างซึ่งalphaเป็นปัจจัยที่ทำให้เรียบ ดูWikipediaสำหรับรายละเอียด

โซลูชันที่ 2: สูงสุด + ค่าเฉลี่ย

คุณน่าสนใจในการรับค่าเฉลี่ยและค่าสูงสุด การตรวจสอบค่าสูงสุดอาจน่าสนใจสำหรับการกำหนดขนาดส่วนประกอบเช่น

if (y > max)
  max = y;

โซลูชันที่ 3: ส่วนเบี่ยงเบนมาตรฐาน + สูงสุด + ค่าเฉลี่ย

ทำไม?

ดูแผนภูมิด้านล่าง มีสัญญาณ 3 แบบที่แตกต่างกัน สามเหลี่ยมเป็นไซน์และขัดขวางสัญญาณ พวกมันทั้งหมดเป็นคาบที่มีช่วงเวลาเดียวกัน, แอมพลิจูดเดียวกัน, ค่าเฉลี่ยเดียวกัน, และminและmaxเดียวกัน แต่พวกเขามีรูปร่างที่แตกต่างกันและแน่นอนพวกเขามีเรื่องราวที่แตกต่างอย่างสิ้นเชิง ...

สัญญาณและฮิสโตแกรมของพวกเขา

หนึ่งในความแตกต่างคือส่วนเบี่ยงเบนมาตรฐาน นั่นเป็นเหตุผลที่ฉันแนะนำให้คุณขยายการวัดของคุณและรวมถึงค่าเบี่ยงเบนมาตรฐาน ปัญหาคือว่าวิธีการมาตรฐานในการคำนวณนั้นเป็นการใช้งาน CPU หวังว่าจะมีทางออกหนึ่งทาง

อย่างไร?

ใช้วิธีฮิสโตแกรม สร้างฮิสโตแกรมของการวัดทั้งหมดและแยกสถิติ (min, max, avg, เบี่ยงเบนมาตรฐาน) ของชุดข้อมูลได้อย่างมีประสิทธิภาพ กลุ่มฮิสโทแกรมจะรวมค่าที่มีค่าเท่ากันหรือช่วงของค่าเดียวกัน ข้อได้เปรียบคือการหลีกเลี่ยงการเก็บตัวอย่างทั้งหมด (เพิ่มจำนวนเวลา) และมีการคำนวณที่รวดเร็วในจำนวนข้อมูลที่ จำกัด

ก่อนเริ่มการวัดให้สร้างอาร์เรย์เพื่อเก็บฮิสโตแกรม มันเป็นอาร์เรย์จำนวนเต็ม 1 มิติขนาด 32ตัวอย่างเช่น:

int histo[32];

ปรับฟังก์ชั่นด้านล่างขึ้นอยู่กับช่วงของแอมมิเตอร์ ตัวอย่างเช่นถ้าช่วงเป็น 256mA ก็หมายความว่า bin 0 ของฮิสโตแกรมจะเพิ่มขึ้นตามค่าระหว่าง 0 และ 8 mA, bin 1 โดยค่าระหว่าง 8 ถึง 16 mA ฯลฯ ... ดังนั้นคุณจะต้องมีจำนวนเต็มแทน หมายเลขถังฮิสโทแกรม:

short int index;

ทุกครั้งที่คุณรับตัวอย่างให้ค้นหาดัชนีถังที่เกี่ยวข้อง:

index = (short int) floor(yi);

และเพิ่มช่องเก็บนี้:

histo[index] += 1;

ในการคำนวณค่าเฉลี่ยให้รันลูปนี้:

float mean = 0;
int N = 0;
for (i=0; i < 32 ; i++) {
  mean = i * histo[i]; // sum along the histogram
  N += i; // count of samples
}
mean /= N; // divide the sum by the count of samples.
mean *= 8; // multiply by the bin width, in mA: Range of 256 mA / 32 bins = 8 mA per bin.

ในการคำนวณค่าเบี่ยงเบนมาตรฐานให้เรียกใช้ลูปนี้:

float std_dev = 0;

for (i=0; i < 32 ; i++) {
  std_dev = (i - mean) * (i - mean) * histo[i]; // sum along the histogram
}
std_dev /= N; // divide the sum by the count of samples.
std_dev = sqrt(std_dev); // get the root mean square to finally convert the variance to standard deviation.

กลยุทธ์ของวิธีฮิสโตแกรมคือการทำให้การทำงานช้าลงในถังขยะจำนวนน้อยแทนที่จะเป็นตัวอย่างสัญญาณที่ได้มาทั้งหมด ยิ่งขนาดตัวอย่างยาวเท่าไรก็ยิ่งดีเท่านั้น หากคุณต้องการรายละเอียดเพิ่มเติมโปรดอ่านหน้านี้ที่น่าสนใจHistogram, PMF และ PDF


คำอธิบายอย่างละเอียดและชัดเจนมาก ในระดับปฏิบัติคุณจะมั่นใจได้อย่างไรว่าการสุ่มตัวอย่าง ADC นั้นถูกกระจาย "อย่างดี" นั่นคือไม่ได้ล็อคด้วยสัญญาณ PWM ในทางใดทางหนึ่ง? ฉันต้องยอมรับว่าตอนนี้ฉันเพิ่งใช้ Arduino (hw + sw) สำหรับทั้งการสุ่มตัวอย่าง PWM และ ADC อาจเป็นได้ว่าฉันควรตั้งค่าตัวจับเวลาในตัวเอง ฉันเดาว่าความถี่การสุ่มตัวอย่างน่าจะสูงกว่าความถี่ PWM ใช่ไหม
ltj

1
ทันทีที่คุณเริ่มการสุ่มตัวอย่างสิ่งต่าง ๆ จะค่อนข้างซับซ้อน สิ่งแรกที่ต้องทำคือการจำไว้ว่าเป็นทฤษฎีบท Nyquist-Shannon สิ่งที่เข้าใจได้ง่ายคือยิ่งความถี่ในการสุ่มตัวอย่างสูงเท่าไหร่คุณก็ยิ่งมีข้อมูลมากขึ้นเท่านั้น แต่สิ่งที่ไม่ได้ใช้งานง่ายแม้พื้นฐานคือก่อนการสุ่มตัวอย่างที่ความถี่ Fs คุณต้องอย่าง low-pass filter (ประสิทธิภาพ analogic / อิเล็กทรอนิกส์) สัญญาณที่ Fs / 2 มิฉะนั้นคุณจะได้รับผลกระทบจากนามแฝง ฉันขอแนะนำให้คุณเลือกความถี่การสุ่มตัวอย่างสูงสุด ถ้าเป็นไปได้ ~ 10 เท่าของความถี่ PWM
RawBean

นี่เป็นความเข้าใจผิดทั่วไปของทฤษฎีบท Nyquist-Shannon ซึ่งระบุว่าต้องการให้คุณทดลองใช้แบนด์วิดท์เป็นสองเท่า การใช้นามแฝงอาจมีประโยชน์ ไม่มีเจตนาดูหมิ่น แต่ดูเหมือนว่าคำตอบจากตำรา แนะนำการสุ่มตัวอย่าง PWM ~ 10 เท่าในสถานการณ์นี้เมื่อรายละเอียดความถี่สูงเป็นไปได้ว่าไม่เกี่ยวข้องมากเกินไป
akellyirl

1

คุณเข้าใจปัญหาอย่างถูกต้อง: คุณต้องได้รับ "เฉลี่ย" ของ PWM เช่นเดียวกับเครื่องวัดที่คุณใช้สำหรับการวัด

คุณสามารถใช้ตัวกรอง RC กับสัญญาณ A1,2,3 ซึ่งค่าคงที่ของเวลาคืออย่างน้อยสิบเท่าของช่วงเวลา PWM ของคุณ นั่นหมายความว่าหากช่วงเวลา PWM ของคุณเป็น 10 ไมโครวินาทีดังนั้นค่าคงที่เวลา RC ควรเป็น 100 ไมโครวินาที ตัวอย่างเช่น 10kOhms x 10nF = 100us

ทางออกที่ดีกว่าคือการกรองสัญญาณดิจิทัลในไมโครคอนโทรลเลอร์เช่นนี้:

float y = (1-0.99)*input + 0.99*y; 

เปลี่ยนค่า "0.99" เพื่อเปลี่ยนค่าคงที่เวลาของตัวกรองดิจิตอลนี้


1
ระวังนามแฝงถ้าคุณทำมันในรหัส
แอนดี้อาคา

การใช้ชื่อแทนไม่จำเป็นต้องเป็นปัญหา เราทุกคนรู้ว่าการสร้างสัญญาณใหม่อัตราตัวอย่างจะต้องมีความถี่สูงสุดอย่างน้อยสองเท่า แต่เมื่อสัญญาณไม่ จำกัดแบนด์วิดธ์คุณจะต้องทำการสุ่มตัวอย่างที่แบนด์วิดท์สองเท่าเท่านั้น สิ่งนี้เรียกว่า undersamplig เนื่องจากสัญญาณนั้นมีความถี่ต่ำเพราะมันขับแผ่นความร้อนดังนั้นอัตราตัวอย่างที่สมเหตุสมผลในช่วง 100 ถึง 1,000 SPS จึงควรจะดี ดู: ni.com/newsletter/50078/th
akellyirl

ควรที่จะตรวจสอบให้แน่ใจว่าอัตรา PWM และอัตราตัวอย่างนั้นดีเลิศซึ่งกันและกันหากใช้การขีดล่าง
akellyirl

ความคิดของฉันอย่างแม่นยำ - หากการวัดผ่าน ADC และสร้าง PWM ใน MCU เดียวกันอาจมีแนวโน้มที่ทั้งสองจะถูกล็อคในเวลา
แอนดี้อาคา

สัญญาณอยู่ที่ความถี่ pwm ไม่ใช่ความถี่ต่ำ ถ้ามันเป็น frq ต่ำมันอาจจะใช้ทรัพยากรน้อยกว่าในการสุ่มตัวอย่างในช่วงเวลาหนึ่งและค่าเฉลี่ยกว่าการใช้เลขทศนิยมในทางนั้น
Scott Seidman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.