Monday 24 July 2017

การย้าย ค่าเฉลี่ย กรอง C


เป็นไปได้ที่จะใช้ค่าเฉลี่ยเคลื่อนที่ใน C โดยไม่จำเป็นต้องมีหน้าต่างของตัวอย่าง Ive พบว่าฉันสามารถเพิ่มประสิทธิภาพบิตโดยการเลือกขนาดหน้าต่าง thats อำนาจของสองเพื่อให้บิตขยับแทนการหาร แต่ไม่จำเป็นต้อง บัฟเฟอร์จะดี มีวิธีแสดงผลลัพธ์เฉลี่ยเคลื่อนที่ใหม่ตามผลการค้นหาเดิมและตัวอย่างใหม่กำหนดค่าเฉลี่ยเคลื่อนที่ตัวอย่างเช่นข้ามหน้าต่างตัวอย่าง 4 ตัวอย่าง: เพิ่มตัวอย่างใหม่ e: ค่าเฉลี่ยเคลื่อนที่สามารถใช้งานได้แบบ recursively , แต่สำหรับการคำนวณที่แน่นอนของค่าเฉลี่ยเคลื่อนที่คุณต้องจำตัวอย่างการป้อนข้อมูลที่เก่าแก่ที่สุดในผลรวม (เช่นในตัวอย่างของคุณ) สำหรับค่าเฉลี่ยเคลื่อนที่ N ที่คุณคำนวณ: โดยที่ yn คือสัญญาณขาออกและ xn เป็นสัญญาณขาเข้า อีคิว (1) สามารถเขียน recursively เป็นดังนั้นคุณจำเป็นต้องจำตัวอย่าง xn-N เพื่อคำนวณ (2) ที่ระบุโดย Conrad Turner คุณสามารถใช้หน้าต่างแทนยาวได้ (ไม่ จำกัด ) แทนซึ่งจะช่วยให้คุณสามารถคำนวณเอาท์พุทได้เฉพาะจากผลลัพธ์ที่ผ่านมาและอินพุทปัจจุบัน: แต่นี่ไม่ใช่ค่าเฉลี่ยเคลื่อนที่ (unweighted) แต่เป็นค่าชี้แจง (อย่างน้อยที่สุดในทางทฤษฎี) คุณไม่เคยลืมอะไรเลย (น้ำหนักเพียงเล็กน้อยและเล็กลงสำหรับตัวอย่างที่ไกลในอดีต) ฉันใช้ค่าเฉลี่ยเคลื่อนที่โดยไม่มีหน่วยความจำรายการสำหรับโปรแกรมติดตาม GPS ที่ฉันเขียน ฉันเริ่มต้นด้วย 1 ตัวอย่างและหารด้วย 1 เพื่อให้ได้ค่าเฉลี่ยปัจจุบัน จากนั้นผมจะเพิ่มตัวอย่าง anothe และหารด้วย 2 เป็นค่าเฉลี่ยปัจจุบัน นี้ยังคงจนกว่าฉันจะได้รับความยาวเฉลี่ย ทุกครั้งหลังจากนั้นฉันเพิ่มในตัวอย่างใหม่ให้ได้ค่าเฉลี่ยและลบค่าเฉลี่ยดังกล่าวออกจากยอดรวม ฉันไม่ใช่นักคณิตศาสตร์ แต่ดูเหมือนจะเป็นวิธีที่ดีที่จะทำ ฉันคิดว่ามันจะเปิดท้องของคนที่แต่งตัวประหลาดคณิตศาสตร์จริง แต่ก็จะเปิดออกเป็นหนึ่งในวิธีที่ได้รับการยอมรับในการทำมัน และทำงานได้ดี เพียงแค่จำไว้ว่ายิ่งความยาวของคุณยิ่งใหญ่เท่าไรก็ยิ่งช้าลงตามสิ่งที่คุณต้องการทำ นั่นอาจไม่สำคัญตลอดเวลา แต่เมื่อไปตามดาวเทียมถ้าคุณช้าเส้นทางอาจอยู่ไกลจากตำแหน่งจริงและจะดูไม่ดี คุณอาจมีช่องว่างระหว่างจุดเริ่มต้นและจุดต่อท้าย ฉันเลือกความยาวของ 15 ปรับปรุง 6 ครั้งต่อนาทีเพื่อให้ได้อย่างราบรื่นเพียงพอและไม่ได้รับไกลจากตำแหน่งนั่งจริงกับจุดเส้นทางที่ราบรื่น ตอบ 16 พค. 16 ที่ 23:03 เริ่มต้นทั้งหมด 0, นับ 0 (ทุกครั้งที่เห็นค่าใหม่จากนั้นหนึ่งอินพุท (scanf) หนึ่งเพิ่ม totalnewValue, หนึ่งที่เพิ่มขึ้น (นับ) หนึ่งหารเฉลี่ย (totalcount) นี้จะเป็นค่าเฉลี่ยเคลื่อนที่มากกว่า input ทั้งหมดในการคํานวณคาเฉลี่ยโดยใชเพียง 4 อินพุทตอไปเทานั้นจะตองใช4 inputvariables อาจคัดลอก input แตละ input ไปยัง inputvariable ที่สูงกวาจากนั้นคา new moving average เปน sum ของ inputvariables 4 หารดวย 4 (right shift 2) ดีถ้าทุกปัจจัยการผลิตเป็นบวกเพื่อให้การคำนวณเฉลี่ยตอบกุมภาพันธ์ 3 15 ที่ 4:06 ที่จริงจะคำนวณค่าเฉลี่ยรวมและไม่เฉลี่ยเคลื่อนไหวตามนับได้รับผลกระทบขนาดใหญ่ของตัวอย่างการป้อนข้อมูลใหม่ ๆ กลายเป็น vanishingly ขนาดเล็ก ndash Hilmar Feb คุณรู้ว่านี่เป็นไปได้ด้วยการเพิ่มตามต่อ: แต่ฉันจริงๆต้องการหลีกเลี่ยงการใช้เพิ่มฉันมี googled และไม่พบตัวอย่างใด ๆ ที่เหมาะสมหรืออ่านได้โดยทั่วไปฉันต้องการติดตาม การเคลื่อนย้าย ค่าเฉลี่ยของกระแสข้อมูลสตรีมของจำนวนจุดลอยโดยใช้ตัวเลข 1000 รายการล่าสุดเป็นตัวอย่างข้อมูล วิธีที่ง่ายที่สุดในการทำแบบทดสอบนี้คือการใช้อาร์เรย์แบบวงกลมค่าเฉลี่ยเคลื่อนที่แบบเสวนาและค่าเฉลี่ยเคลื่อนที่ที่เรียบง่ายกว่าและพบว่าผลลัพธ์จากอาร์เรย์แบบวงกลมเหมาะกับความต้องการของฉันมากที่สุด ถาม 12 มิ.ย. 12 เวลา 4:38 หากความต้องการของคุณเรียบง่ายคุณอาจลองใช้ค่าเฉลี่ยเคลื่อนที่แบบเสวนา ใส่เพียงแค่คุณสร้างตัวแปรสะสมและเมื่อโค้ดของคุณดูที่ตัวอย่างแต่ละโค้ดจะอัปเดตข้อมูลสะสมด้วยค่าใหม่ คุณสามารถเลือกค่า alpha คงที่ระหว่าง 0 ถึง 1 และคำนวณค่านี้: คุณเพียงแค่หาค่า alpha ที่ผลของตัวอย่างที่กำหนดจะใช้เวลาประมาณ 1000 ตัวอย่างเท่านั้น อืมฉันไม่แน่ใจว่านี่เหมาะกับคุณแล้วตอนนี้ฉันวางมันไว้ที่นี่แล้ว ปัญหาคือว่า 1000 เป็นหน้าต่างยาวสวยสำหรับค่าเฉลี่ยเคลื่อนที่ที่อธิบายไม่แน่ใจว่ามีอัลฟาที่จะกระจายค่าเฉลี่ยมากกว่า 1000 หมายเลขล่าสุดโดยไม่ต้อง underflow ในการคำนวณจุดลอย แต่ถ้าคุณต้องการค่าเฉลี่ยที่เล็กลงเช่น 30 ตัวเลขหรือมากกว่านี่เป็นวิธีที่ง่ายและรวดเร็วในการดำเนินการ ตอบ 12 มิ.ย. 12 เวลา 4:44 1 ในโพสต์ของคุณ ค่าเฉลี่ยเคลื่อนที่ที่อธิบายได้จะทำให้ตัวแปรอัลฟ่าเป็นตัวแปรได้ ดังนั้นจึงช่วยให้สามารถใช้คำนวณค่าเฉลี่ยของฐานเวลา (เช่นไบต์ต่อวินาที) ถ้าเวลานับตั้งแต่การอัปเดตสะสมครั้งล่าสุดเป็นเวลามากกว่า 1 วินาทีคุณจะยอมให้ alpha เป็น 1.0 มิเช่นนั้นคุณสามารถปล่อยให้ alpha เป็น (usecs ตั้งแต่ update1000000 ครั้งล่าสุด) ndash jxh Jun 12 12 at 6:21 โดยทั่วไปฉันต้องการติดตามค่าเฉลี่ยเคลื่อนที่ของกระแสอย่างต่อเนื่องของกระแสตัวเลขจุดลอยใช้ล่าสุด 1000 หมายเลขเป็นตัวอย่างข้อมูล โปรดทราบว่าด้านล่างปรับปรุงชุดค่าผสมทั้งหมดเป็นองค์ประกอบที่เพิ่มขึ้นโดยไม่ต้องเสียค่าใช้จ่ายในการคำนวณ O (N) traversal เพื่อคำนวณผลรวม - จำเป็นสำหรับค่าเฉลี่ย - ตามความต้องการ ทั้งหมดถูกกำหนดเป็นพารามิเตอร์อื่นจาก T เพื่อสนับสนุนเช่น ใช้ยาวนานเมื่อรวม 1000 ยาว s, int สำหรับ char s หรือ double เพื่อรวม float s นี่เป็นบิตที่มีข้อบกพร่องในการที่ numsamples อาจผ่าน INTMAX - ถ้าคุณสนใจคุณสามารถใช้ unsigned long long หรือใช้สมาชิกข้อมูล bool พิเศษเพื่อบันทึกเมื่อเติมคอนเทนเนอร์เป็นครั้งแรกในขณะที่วนรอบ numsamples รอบ (ดีที่สุดแล้วเปลี่ยนชื่อบางอย่างที่ไม่เป็นอันตรายเช่น pos) ตอบ 12 มิ.ย. 12 at 5:19 สมมติว่าตัวดำเนินการ quotvoid (T sample) quot ก็คือ quotvoid operatorltlt (T sample) quot ndash o วันที่ 8 มิ.ย. 14 เวลา 11:52 น. oPhút ahhh เห็นดี จริงฉันตั้งใจจะให้โมฆะดำเนิน () (T ตัวอย่าง) แต่แน่นอนคุณสามารถใช้สิ่งที่คุณต้องการสัญกรณ์. จะแก้ไขขอบคุณ ndash Tony D มิ.ย. 8 14 เวลา 14: 27 ตามที่คนอื่น ๆ พูดถึงคุณควรพิจารณาตัวกรอง IIR (การตอบสนองต่ออิมพัลส์ไม่ จำกัด ) แทนที่จะใช้ตัวกรองฟิลเตอร์ FIR ที่คุณกำลังใช้อยู่ มีมากขึ้นไปได้ แต่ในตอนแรกอย่างรวดเร็วตัวกรอง FIR จะถูกนำมาใช้เป็นตัวคั่นที่ชัดเจนและตัวกรอง IIR ที่มีสมการ ตัวกรอง IIR ที่ฉันใช้เป็นจำนวนมากในไมโครคอนโทรลเลอร์คือตัวกรองสัญญาณขาเดียวแบบขั้วเดียว นี่คือดิจิตอลเทียบเท่าของตัวกรองสัญญาณ R-C แบบง่าย สำหรับแอปพลิเคชันส่วนใหญ่คุณลักษณะเหล่านี้จะมีลักษณะที่ดีกว่าตัวกรองช่องที่คุณใช้อยู่ การใช้ส่วนใหญ่ของตัวกรองกล่องที่ฉันพบเป็นผลมาจากคนที่ไม่ให้ความสนใจในคลาสการประมวลผลสัญญาณดิจิทัลไม่ใช่จากลักษณะเฉพาะของพวกเขา ถ้าคุณต้องการลดความถี่สูงที่คุณรู้ว่าเป็นสัญญาณรบกวนตัวกรองสัญญาณขาเดียวแบบขั้วเดียวจะดีกว่า วิธีที่ดีที่สุดในการใช้งานแบบดิจิทัลในไมโครคอนโทรลเลอร์คือ: FILT lt - FILT FF (NEW - FILT) FILT เป็นสถานะที่มีความคงทน นี่เป็นตัวแปรเดียวที่คุณต้องใช้เพื่อคำนวณตัวกรองนี้ NEW เป็นค่าใหม่ที่ตัวกรองจะได้รับการอัปเดตด้วยการทำซ้ำนี้ FF คือส่วนของตัวกรอง ซึ่งจะปรับความหนักเบาของตัวกรอง ดูที่ขั้นตอนนี้และดูว่าสำหรับ FF 0 ตัวกรองเป็นแบบอนันต์หนักเนื่องจากผลลัพธ์ไม่เคยเปลี่ยนแปลง สำหรับ FF 1 จริงๆไม่มีตัวกรองเลยตั้งแต่เอาท์พุททำตาม input ค่าที่เป็นประโยชน์อยู่ระหว่าง ในระบบขนาดเล็กที่คุณเลือก FF เป็น 12 N เพื่อให้คูณด้วย FF สามารถทำได้เป็น shift ขวาโดย N บิต ตัวอย่างเช่น FF อาจเป็น 116 และคูณด้วย FF ดังนั้นจึงมีการเลื่อนทางขวาเป็น 4 บิต มิเช่นนั้นตัวกรองนี้จะต้องมีเพียงหนึ่งคำเดียวลบออกและเพิ่มหนึ่งครั้งแม้ว่าตัวเลขจะต้องกว้างกว่าค่าอินพุท (มากกว่าความแม่นยำเชิงตัวเลขในส่วนที่แยกต่างหากด้านล่าง) ฉันมักจะใช้เวลาอ่านโฆษณาอย่างมีนัยสำคัญเร็วกว่าที่จำเป็นและใช้ตัวกรองเหล่านี้สองตัวเรียงกัน นี่คือดิจิตอลเทียบเท่าของตัวกรอง R-C สองชุดและลดลง 12 dBoctave เหนือความถี่ rolloff อย่างไรก็ตามสำหรับการอ่านโฆษณามักจะมีความเกี่ยวข้องมากขึ้นในการดูตัวกรองในโดเมนเวลาโดยพิจารณาการตอบกลับขั้นตอน นี่จะบอกคุณว่าระบบของคุณจะเห็นการเปลี่ยนแปลงอย่างไรเมื่อสิ่งที่คุณกำลังวัดการเปลี่ยนแปลง เพื่ออำนวยความสะดวกในการออกแบบตัวกรองเหล่านี้ (ซึ่งหมายถึงการเลือก FF และการตัดสินใจว่าจะให้น้ำตกมากเพียงใด) ฉันใช้ FILTBITS ของโปรแกรม คุณระบุจำนวนของบิต shift สำหรับแต่ละเฟรมในชุดตัวกรองแบบเรียงซ้อนและคำนวณค่าการตอบสนองขั้นตอนและค่าอื่น ๆ ที่จริงฉันมักจะใช้นี้ผ่าน wrapper script PLOTFILT ของฉัน การดำเนินการนี้จะเรียกใช้ FILTBITS ซึ่งจะสร้างไฟล์ CSV จากนั้นแปลงไฟล์ CSV ตัวอย่างเช่นนี่คือผลของ PLOTFILT 4 4: พารามิเตอร์สองตัวของ PLOTFILT หมายความว่าจะมีตัวกรองสองแบบเรียงตามลำดับชั้นดังกล่าวข้างต้น ค่าของ 4 ระบุจำนวนของกะบิตเพื่อให้เกิดการคูณด้วย FF ทั้งสองค่า FF จึงเป็น 116 ในกรณีนี้ การติดตามสีแดงคือการตอบสนองต่อหน่วยและเป็นสิ่งสำคัญที่ต้องดู ตัวอย่างเช่นข้อมูลนี้บอกให้คุณทราบว่าหากข้อมูลอินพุตเปลี่ยนแปลงทันทีผลลัพธ์ของตัวกรองรวมจะกำหนดให้เท่ากับ 90 ค่าใหม่ใน 60 ซ้ำ ถ้าคุณสนใจเกี่ยวกับเวลาการตั้งถิ่นฐาน 95 แล้วคุณต้องรอประมาณ 73 ซ้ำและสำหรับเวลาการตกตะกอนเพียง 26 ซ้ำ ร่องรอยสีเขียวแสดงให้เห็นว่าคุณได้รับเอาท์พุทจากการขยายความกว้างเต็มรูปแบบเดียว นี้จะช่วยให้คุณมีความคิดของการปราบปรามเสียงสุ่ม ดูเหมือนว่าไม่มีตัวอย่างเดียวจะทำให้เกิดการเปลี่ยนแปลงในเอาท์พุทมากกว่า 2.5 ร่องรอยสีน้ำเงินคือการให้ความรู้สึกอัตนัยของสิ่งที่ตัวกรองนี้ทำด้วยเสียงสีขาว นี่ไม่ใช่การทดสอบอย่างเข้มงวดเนื่องจากไม่มีการรับประกันว่าเนื้อหาใดเป็นตัวเลขสุ่มที่เลือกเป็นสัญญาณเสียงรบกวนสีขาวสำหรับการทำงานของ PLOTFILT นี้ เพียงเพื่อให้คุณรู้สึกขรุขระของเท่าใดก็จะถูกแบนและเรียบเป็นอย่างไร PLOTFILT บางที FILTBITS และสิ่งที่มีประโยชน์อื่น ๆ โดยเฉพาะอย่างยิ่งสำหรับการพัฒนาเฟิร์มแวร์ของ PIC มีอยู่ในซอฟต์แวร์ PIC Development Tools ที่หน้าดาวน์โหลดซอฟต์แวร์ของฉัน เพิ่มความแม่นยำเชิงตัวเลขที่ฉันเห็นจากความคิดเห็นและตอนนี้เป็นคำตอบใหม่ที่มีความสนใจในการพูดคุยเกี่ยวกับจำนวนบิตที่จำเป็นในการใช้ตัวกรองนี้ โปรดทราบว่าคูณด้วย FF จะสร้างบิตใหม่ Log 2 (FF) ด้านล่างจุดไบนารี ในระบบขนาดเล็ก FF มักจะได้รับเลือกให้เป็น 12 N เพื่อให้การคูณนี้เกิดขึ้นจริงโดยการเปลี่ยน N บิตที่ถูกต้อง FILT จึงเป็นจำนวนเต็มจุดคงที่ โปรดทราบว่านี้ไม่ได้เปลี่ยนคณิตศาสตร์ใด ๆ จากมุมมองของตัวประมวลผล ตัวอย่างเช่นถ้าคุณกำลังกรองการอ่านโฆษณา 10 บิตและ N 4 (FF 116) คุณต้องใช้เศษเศษส่วนด้านล่าง 10 บิตจำนวนเต็ม AD อ่าน โปรเซสเซอร์ส่วนใหญ่คุณจะต้องดำเนินการเป็นจำนวนเต็ม 16 บิตเนื่องจากการอ่านค่า 10 บิต AD ในกรณีนี้คุณยังคงสามารถดำเนินการได้ตามจำนวนเต็ม 16 บิตเดิม แต่เริ่มต้นด้วยการอ่านค่า AD ด้านซ้ายที่เปลี่ยนไป 4 บิต โปรเซสเซอร์ไม่ทราบความแตกต่างและไม่จำเป็นต้องทำ การทำคณิตศาสตร์กับจำนวนเต็ม 16 บิตทั้งหมดใช้งานได้ไม่ว่าคุณจะถือว่าเป็น 12.4 จุดคงที่หรือจำนวนเต็ม 16 บิตจริง (16.0 จุดคงที่) โดยทั่วไปคุณจำเป็นต้องเพิ่มบิต N แต่ละขั้วกรองหากคุณไม่ต้องการเพิ่มเสียงเนื่องจากการแสดงตัวเลข ในตัวอย่างข้างต้นตัวกรองที่สองของสองจะต้องมี 1044 18 บิตเพื่อไม่สูญเสียข้อมูล ในทางปฏิบัติบนเครื่อง 8 บิตซึ่งหมายความว่าคุณต้องใช้ค่าบิต 24 เทคนิคเฉพาะขั้วที่สองของสองจะต้องมีค่ามากขึ้น แต่สำหรับความเรียบง่ายของเฟิร์มผมมักจะใช้การแทนเดียวกันและด้วยรหัสเดียวกันสำหรับเสาทั้งหมดของตัวกรอง ฉันมักจะเขียนโปรแกรมย่อยหรือแมโครเพื่อทำการดำเนินการของเสากรองหนึ่งตัวจากนั้นจึงนำไปใช้กับเสาแต่ละอัน ไม่ว่าจะเป็นโปรแกรมย่อยหรือแมโครขึ้นอยู่กับว่าวงจรหรือหน่วยความจำโปรแกรมมีความสำคัญมากกว่าในโครงการนั้นหรือไม่ ไม่ว่าจะด้วยวิธีใดก็ตามฉันใช้สถานะการขูดขีดเพื่อส่ง NEW เข้าไปใน subroutinemacro ซึ่งอัปเดต FILT แต่ยังโหลดข้อมูลที่เป็นสถานะการขีดข่วนเหมือนเดิม NEW ซึ่งทำให้ง่ายต่อการใช้เสาหลายอันเนื่องจาก FILT อัปเดตของเสาเดียวคือ NEW ของหน้าถัดไป เมื่อโปรแกรมย่อยมีประโยชน์ที่จะมีจุดชี้ไปที่ FILT ระหว่างทางซึ่งได้รับการอัปเดตเป็นเพียง FILT เมื่อออกไป ด้วยวิธีนี้โปรโตคอลย่อยจะทำงานกับตัวกรองข้อมูลที่ต่อเนื่องในหน่วยความจำโดยอัตโนมัติหากเรียกหลาย ๆ ครั้ง กับแมโครคุณไม่จำเป็นต้องชี้ตั้งแต่คุณผ่านในที่อยู่ในการทำงานในแต่ละซ้ำ ตัวอย่างโค้ดนี่เป็นตัวอย่างของมาโครตามที่อธิบายไว้ข้างต้นสำหรับ PIC 18: และนี่คือแมโครที่คล้ายกันสำหรับ PIC 24 หรือ dsPIC 30 หรือ 33: ทั้งสองตัวอย่างนี้ถูกใช้เป็นแมโครโดยใช้ตัวประมวลผลแอ็กเซสเซอร์ของ PIC ของฉัน ซึ่งมีความสามารถมากขึ้นกว่าสิ่งอำนวยความสะดวกที่มีมาโครภายในตัวใดตัวหนึ่ง ปัญหาอื่นที่ควรจะกล่าวถึงคือการใช้เฟิร์มแวร์ คุณสามารถเขียนโพรโทคอลต่ำผ่านโพรเซสเซอร์ได้เพียงครั้งเดียวจากนั้นใช้หลายครั้ง ในความเป็นจริงฉันมักจะเขียนเช่น subroutine เพื่อนำตัวชี้ในหน่วยความจำไปยังสถานะตัวกรองแล้วมีมันล่วงหน้าตัวชี้เพื่อที่จะสามารถเรียกอย่างต่อเนื่องในการรับรู้หลายตัวกรองขั้ว ndash Olin Lathrop Apr 20 12 at 15:03 1. ขอบคุณมากสำหรับคำตอบของคุณ - ทั้งหมด ฉันตัดสินใจที่จะใช้ตัวกรอง IIR นี้ แต่ตัวกรองนี้ไม่ได้ใช้เป็นตัวกรอง LowPass มาตรฐานเพราะฉันต้องการเฉลี่ยค่าตัวนับและเปรียบเทียบเพื่อตรวจจับการเปลี่ยนแปลงในช่วงที่กำหนด เนื่องจากค่าเหล่านี้มีมิติแตกต่างกันไปโดยขึ้นอยู่กับฮาร์ดแวร์ที่ฉันต้องการใช้โดยเฉลี่ยเพื่อให้สามารถตอบสนองต่อการเปลี่ยนแปลงเฉพาะฮาร์ดแวร์เหล่านี้ได้โดยอัตโนมัติ ถ้าคุณสามารถอยู่กับข้อ จำกัด ของจำนวนสองรายการโดยเฉลี่ย (เช่น 2,4,8,16,32 ฯลฯ ) จากนั้นหารสามารถทำได้อย่างง่ายดายและมีประสิทธิภาพใน micro ประสิทธิภาพต่ำโดยไม่มีการทุ่มเทแบ่งเพราะสามารถทำได้เป็นบิตเปลี่ยน การเปลี่ยนสิทธิแต่ละครั้งเป็นหนึ่งในพลังของสองเช่น: OP คิดว่าเขามีปัญหาสองข้อแบ่งใน PIC16 และหน่วยความจำสำหรับบัฟเฟอร์แหวนของเขา คำตอบนี้แสดงให้เห็นว่าการหารไม่ใช่เรื่องยาก เป็นที่ยอมรับมันไม่ได้อยู่ที่ปัญหาหน่วยความจำ แต่ระบบ SE ช่วยให้คำตอบบางส่วนและผู้ใช้สามารถใช้อะไรจากคำตอบสำหรับตัวเองหรือแม้กระทั่งการแก้ไขและรวมคำตอบของผู้อื่น เนื่องจากบางส่วนของคำตอบอื่น ๆ ต้องการการดำเนินการแบ่งพวกเขาจะไม่เหมือนกันเหมือนกันเนื่องจากพวกเขาไม่แสดงวิธีการอย่างมีประสิทธิภาพบรรลุนี้บน PIC16 มีคำตอบสำหรับตัวกรองค่าเฉลี่ยเคลื่อนที่ที่แท้จริง (aka boxcar filter) ที่มีความต้องการหน่วยความจำน้อยกว่าถ้าคุณไม่เข้าใจการสุ่มตัวอย่าง เรียกว่าตัวกรองแบบผสมผสาน (cascaded integrator-comb filter) (CIC) แนวคิดคือคุณมีผู้ผสานรวมที่คุณใช้ความแตกต่างในช่วงเวลาหนึ่งและอุปกรณ์ประหยัดหน่วยความจำที่สำคัญคือโดยการสุ่มตัวอย่างคุณไม่จำเป็นต้องเก็บค่าของ Integrator ทุกตัว สามารถใช้งานได้โดยใช้ pseudocode ต่อไปนี้: ความยาวเฉลี่ยที่มีประสิทธิภาพของการเคลื่อนไหวของคุณคือ decimationFactorstatesize แต่คุณต้องเก็บตัวอย่างไว้ทั่ว เห็นได้ชัดว่าคุณสามารถทำงานได้ดีขึ้นหาก stateize และ decimationFactor ของคุณมีอำนาจเท่ากับ 2 เพื่อให้ตัวหารและตัวดำเนินการที่เหลือถูกแทนที่ด้วย shift และ mask-ands Postscript: ฉันเห็นด้วยกับ Olin ว่าคุณควรพิจารณาตัวกรอง IIR แบบธรรมดาก่อนที่จะใช้ตัวกรองเฉลี่ยที่เคลื่อนที่ หากคุณไม่จำเป็นต้องใช้ null-frequency ของตัวกรองรถกระบะตัวกรองความถี่ต่ำ 1 ขั้วหรือ 2 เสาจะทำงานได้ดี ในทางตรงกันข้ามถ้าคุณกำลังกรองเพื่อให้เป็นไปตามวัตถุประสงค์ของการ decimation (การป้อนข้อมูลที่มีอัตราการสุ่มตัวอย่างสูงและค่าเฉลี่ยสำหรับการใช้งานโดยกระบวนการที่มีอัตราต่ำ) ตัวกรอง CIC อาจเป็นเพียงสิ่งที่คุณกำลังมองหา (โดยเฉพาะถ้าคุณสามารถใช้ stateize1 และหลีกเลี่ยง ringbuffer ทั้งหมดด้วยค่า integrator เดียวก่อนหน้านี้) Theres บางการวิเคราะห์ในเชิงลึกของคณิตศาสตร์ที่อยู่เบื้องหลังการใช้ตัวกรอง IIR คำสั่งแรกที่ Olin Lathrop ได้อธิบายไว้แล้วในการประมวลผลสัญญาณสแตก สมการสำหรับตัวกรอง IIR คือ: สามารถใช้งานได้โดยใช้ตัวเลขจำนวนเต็มเท่านั้นและไม่มีส่วนใดโดยใช้รหัสต่อไปนี้ (อาจจำเป็นต้องมีการดีบักขณะที่กำลังพิมพ์จากหน่วยความจำ) ตัวกรองนี้ใกล้เคียงกับค่าเฉลี่ยเคลื่อนที่ของ ตัวอย่าง K ล่าสุดโดยการกำหนดค่า alpha เป็น 1K ทำเช่นนี้ในรหัสก่อนหน้าโดยกำหนด ing BITS เพื่อ LOG2 (K) เช่นสำหรับ K 16 ชุด BITS ถึง 4 สำหรับ K 4 ตั้ง BITS เป็น 2 ฯลฯ (ตรวจสอบรหัสไม่ได้ระบุไว้ที่นี่ทันทีที่ฉันได้รับการเปลี่ยนแปลงและ แก้ไขคำตอบนี้ถ้าจำเป็น.) ตอบ 23 มิถุนายน 12 ที่ 4:04 Heres เดียวขั้วต่ำผ่านตัวกรอง (เฉลี่ยเคลื่อนที่ด้วย cutoff ความถี่ CutoffFrequency) ง่ายมากเร็วมากใช้งานได้ดีและไม่มีค่าใช้จ่ายหน่วยความจำเกือบ หมายเหตุ: ตัวแปรทั้งหมดมีขอบเขตเกินกว่าฟังก์ชันตัวกรองยกเว้นการส่งผ่านข้อมูลใหม่หมายเหตุ: นี่เป็นตัวกรองแบบขั้นตอนเดียว หลายขั้นตอนสามารถต่อเข้าด้วยกันเพื่อเพิ่มความคมชัดของตัวกรอง ถ้าคุณใช้มากกว่าหนึ่งขั้นตอนคุณจะต้องปรับ DecayFactor (เกี่ยวข้องกับ Cutoff-Frequency) เพื่อชดเชย และเห็นได้ชัดว่าสิ่งที่คุณต้องมีคือสายสองเส้นวางไว้ที่ใดก็ได้พวกเขาไม่จำเป็นต้องใช้ฟังก์ชันของตัวเอง ตัวกรองนี้มีเวลาในการเล่นทางไกลก่อนที่ค่าเฉลี่ยเคลื่อนที่จะเป็นค่าของสัญญาณขาเข้า ถ้าคุณต้องการหลีกเลี่ยงเวลาที่เพิ่มขึ้นคุณสามารถเริ่มต้น MovingAverage ให้เป็นค่าแรกของ newInput แทนที่จะเป็น 0 และหวังว่าการป้อนข้อมูลใหม่ไม่ได้เป็นข้อผิดพลาด (CutoffFrequencySampleRate) มีช่วงระหว่าง 0 ถึง 0.5 DecayFactor คือค่าระหว่าง 0 ถึง 1 โดยปกติจะใกล้เคียงกับ 1. Single-precision floats ดีพอสำหรับสิ่งต่างๆส่วนใหญ่ฉันชอบคู่ผสม ถ้าคุณต้องการติดตัวเลขจำนวนเต็มคุณสามารถแปลง DecayFactor และ Amplitude Factor เป็นจำนวนเต็มเศษซึ่งเลขจะถูกเก็บไว้เป็นจำนวนเต็มและตัวหารจะเป็นจำนวนเต็มเท่ากับ 2 (เพื่อให้คุณสามารถเปลี่ยนบิตไปทางขวาได้ ตัวแทนที่จะแบ่งช่วงวนกรอง) ตัวอย่างเช่นถ้า DecayFactor 0.99 และคุณต้องการใช้ integers คุณสามารถตั้งค่า DecayFactor 0.99 65536 64881 จากนั้นทุกครั้งที่คุณคูณด้วย DecayFactor ในลูปไส้กรองของคุณเพียงแค่เปลี่ยนผลการค้นหา 16. สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ ออนไลน์บทที่ 19 เกี่ยวกับตัวกรอง recursive: dspguidech19.htm PS สำหรับกระบวนทัศน์ Moving Average วิธีการที่แตกต่างในการตั้งค่า DecayFactor และ AmplitudeFactor ที่อาจเกี่ยวข้องกับความต้องการของคุณมากขึ้นให้สมมติว่าคุณต้องการก่อนหน้านี้ประมาณ 6 รายการโดยเฉลี่ยด้วยกันทำเป็น discretely คุณเพิ่ม 6 รายการและหารด้วย 6 ดังนั้น คุณสามารถตั้งค่า AmplitudeFactor เป็น 16 และ DecayFactor ไปที่ (1.0 - AmplitudeFactor) ได้ ตอบวันที่ 14 พฤษภาคมเวลา 12: 00 น. ทุกคนได้ให้ความเห็นอย่างละเอียดเกี่ยวกับประโยชน์ของ IIR กับ FIR และในส่วนของอำนาจของทั้งสองฝ่าย Id ต้องการให้รายละเอียดการใช้งาน ด้านล่างทำงานได้ดีกับไมโครคอนโทรลเลอร์ขนาดเล็กที่ไม่มี FPU ไม่มีการคูณและถ้าคุณเก็บกำลังของ N ไว้ 2 ส่วนทั้งหมดจะถูกขยับบิตรอบเดียว บัฟเฟอร์แหวน FIR พื้นฐาน: เก็บบัฟเฟอร์ที่กำลังทำงานของค่า N ล่าสุดและค่า SUM ที่ใช้งานอยู่ทั้งหมดในบัฟเฟอร์ ทุกครั้งที่มีตัวอย่างใหม่ให้ลบค่าที่เก่าแก่ที่สุดในบัฟเฟอร์จาก SUM แทนที่ด้วยตัวอย่างใหม่ให้เพิ่มตัวอย่างใหม่เป็น SUM และ SUMN ออก การแก้ไขบัฟเฟอร์วงแหวน IIR: ให้ SUM ที่ทำงานอยู่ของค่า N ล่าสุด ทุกครั้งที่มีตัวอย่างใหม่เข้ามา SUM - SUMN ให้เพิ่มตัวอย่างใหม่และเอาต์พุต SUMN ตอบอ่าน 28 สิงหาคม 13 เวลา 13:45 หากอ่านหนังสือคุณถูกต้องคุณจะอธิบายตัวกรอง IIR แรกที่สั่งซื้อค่าที่คุณลบออกไม่ใช่ค่าที่เก่าแก่ที่สุดซึ่งหลุดออก แต่แทนที่จะเป็นค่าเฉลี่ยของค่าก่อนหน้า ตัวกรอง IIR ในลำดับแรกอาจเป็นประโยชน์ แต่ฉันไม่แน่ใจว่าคุณหมายถึงอะไรเมื่อคุณแนะนำว่าเอาท์พุทจะเหมือนกันสำหรับสัญญาณเป็นระยะ ๆ อัตราการสุ่มตัวอย่าง 10 กิโลเฮิรตซ์การป้อนคลื่นความถี่ 100Hz ลงในตัวกรองกล่อง 20 ขั้นตอนจะให้สัญญาณที่เพิ่มขึ้นอย่างสม่ำเสมอสำหรับ 20 ตัวอย่างอยู่สูง 30 หยดสม่ำเสมอสำหรับ 20 ตัวอย่างและอยู่ต่ำกว่า 30 ลำดับแรก ตัวกรอง IIR ndash supercat Aug 28 13 at 15:31 จะทำให้คลื่นที่เริ่มเพิ่มขึ้นอย่างรวดเร็วและค่อยๆลดระดับลงใกล้ (แต่ไม่อยู่ที่) ค่าอินพุตสูงสุดจากนั้นจะเริ่มลดลงอย่างรวดเร็วและค่อยๆลดระดับลงใกล้ (แต่ไม่น้อยกว่า) อินพุตต่ำสุด พฤติกรรมที่แตกต่างกันมาก ndash supercat Aug 28 13 at 15:32 ประเด็นหนึ่งก็คือค่าเฉลี่ยเคลื่อนที่ที่เรียบง่ายอาจเป็นประโยชน์หรือไม่ก็ได้ ด้วยตัวกรอง IIR คุณจะได้รับตัวกรองที่ดีกับ calcs ค่อนข้างน้อย FIR ที่คุณอธิบายสามารถให้สี่เหลี่ยมผืนผ้าได้ในเวลาเดียวเท่านั้นคือ sinc in freq และคุณไม่สามารถจัดการด้านข้างได้ มันอาจจะคุ้มค่าที่จะโยนในจำนวนเต็มไม่กี่คูณเพื่อทำให้มันสมมาตรปรับ FIR ที่ดีถ้าคุณสามารถสำรองนาฬิกาเห็บ ScottSeidman: ความจำเป็นในการคูณถ้าหนึ่งมีเพียงขั้นตอนของ FIR ทั้งสองเอาท์พุทค่าเฉลี่ยของการป้อนข้อมูลไปยังขั้นตอนนั้นและค่าที่เก็บไว้ก่อนหน้านี้และจากนั้นเก็บข้อมูล (ถ้ามี ช่วงตัวเลขหนึ่งสามารถใช้ผลรวมมากกว่าค่าเฉลี่ย) (การตอบสนองขั้นตอนของตัวกรองกล่องที่มีความล่าช้าโดยรวมของ 1ms ตัวอย่างเช่นจะมีการขัดขวาง d2dt ที่น่ารังเกียจเมื่อมีการเปลี่ยนแปลงการป้อนข้อมูลและอีก 1 ล้านครั้งในภายหลัง แต่จะมีค่าต่ำสุด ddt ที่เป็นไปได้สำหรับตัวกรองที่มีความล่าช้าทั้งหมด 1ms) เมื่อ mikeselectricstuff กล่าวว่าถ้าคุณต้องการจริงๆเพื่อลดความต้องการหน่วยความจำของคุณและคุณ dont ใจตอบสนองต่อแรงกระตุ้นของคุณเป็นเลขชี้กำลัง (แทนชีพจรสี่เหลี่ยมผืนผ้า) ฉันจะไปสำหรับตัวกรองเฉลี่ยเลขยกกำลัง. . ฉันใช้พวกเขาอย่างกว้างขวาง ด้วยตัวกรองชนิดดังกล่าวคุณไม่จำเป็นต้องมีบัฟเฟอร์ใด ๆ คุณไม่ต้องเก็บตัวอย่างที่ผ่านมา N แค่หนึ่ง. ดังนั้นความต้องการหน่วยความจำของคุณได้รับการลดลงโดยปัจจัยของเอ็นนอกจากนี้คุณไม่จำเป็นต้องแบ่งใด ๆ สำหรับที่ เฉพาะ multiplications ถ้าคุณมีการเข้าถึงเลขคณิตลอยตัวใช้ multiplications ทศนิยม มิฉะนั้นให้ทำ multiplications จำนวนเต็มและเลื่อนไปทางขวา อย่างไรก็ตามเราอยู่ในปี 2012 และขอแนะนำให้คุณใช้คอมไพเลอร์ (และ MCU) ที่ช่วยให้คุณสามารถทำงานกับตัวเลขลอยตัวได้ นอกเหนือจากหน่วยความจำที่มีประสิทธิภาพมากขึ้นและเร็วขึ้น (คุณ dont ต้องปรับปรุงรายการในวงกลม buffer ใด ๆ ) ฉันจะบอกว่ามันเป็นธรรมชาติมากขึ้น เนื่องจากการตอบสนองของแรงกระตุ้นเลขชี้กำลังจะตรงกับลักษณะการทำงานของธรรมชาติในกรณีส่วนใหญ่ ตอบเมื่อ 20 เมษายน 2012 เวลา 9:59 น. ปัญหาหนึ่งที่มีตัวกรอง IIR เกือบสัมผัสกับ olin และ supercat แต่เห็นได้ชัดว่าถูกมองข้ามโดยคนอื่น ๆ ก็คือการปัดเศษลงแนะนำข้อมูลบางอย่างที่ไม่ถูกต้อง (และอาจเกิดขึ้นได้ biastruncation) สมมติว่า N เป็นพลังของสองและใช้เลขคณิตจำนวนเต็มเท่านั้นการเปลี่ยนสิทธิจะทำให้ LSBs ของตัวอย่างใหม่เป็นระบบ นั่นหมายความว่าระยะเวลาที่เคยเป็นแบบนี้ค่าเฉลี่ยจะไม่นำมาพิจารณา ตัวอย่างเช่นสมมุติว่าชุดที่ลดลงอย่างช้าๆ (8,8,8. 8,7,7,7 .7,6,6) และสมมติว่าค่าเฉลี่ยมีค่าเริ่มต้นอยู่ที่ 8 ตัวอย่างกำปั้น 7 จะนำค่าเฉลี่ยไปที่ 7 โดยไม่คำนึงถึงความแข็งแรงของตัวกรอง เพียงแค่หนึ่งตัวอย่างเท่านั้น เรื่องเดียวกันสำหรับ 6 ฯลฯ ตอนนี้คิดว่าตรงข้าม ซีรีส์ขึ้น ค่าเฉลี่ยจะอยู่ที่ 7 ตลอดไปจนกว่าตัวอย่างจะใหญ่พอที่จะทำให้การเปลี่ยนแปลง แน่นอนคุณสามารถแก้ไขอคติโดยการเพิ่ม 12N2 แต่ที่เคยชินจริงๆแก้ปัญหาความแม่นยำ ในกรณีนี้ซีรีส์ที่ลดลงจะคงอยู่ตลอดไปที่ 8 จนกว่าตัวอย่างจะเป็น 8-12 (N2) สำหรับ N4 ตัวอย่างเช่นตัวอย่างใด ๆ ที่อยู่เหนือศูนย์จะทำให้ค่าเฉลี่ยไม่เปลี่ยนแปลง ผมเชื่อว่าการแก้ปัญหาแบบนี้จะถือเป็นการสะสมแอ็คเซสเซอร LSB ที่หายไป แต่ฉันไม่ได้ทำให้ไกลพอที่จะมีรหัสพร้อมและ Im ไม่แน่ใจว่าจะไม่เป็นอันตรายต่ออำนาจ IIR ในกรณีอื่น ๆ บางชุด (ตัวอย่างเช่น 7,9,7,9 จะเฉลี่ย 8 แล้ว) โอลินน้ำตกสองขั้นตอนของคุณก็จะต้องมีคำอธิบายบ้าง คุณหมายถึงการถือครองค่าเฉลี่ยสองค่าด้วยผลลัพธ์จากการนับครั้งแรกเป็นวินาทีในแต่ละการทำซ้ำ อะไรคือประโยชน์ของตัวกรองเฉลี่ยการย้าย (ตัวกรอง MA) กำลังโหลดอยู่ ตัวกรองค่าเฉลี่ยเคลื่อนที่เป็นตัวกรองแบบ FIR (Finite Impulse Response) แบบ Low Pass ที่ใช้กันโดยทั่วไปสำหรับการจัดเรียงข้อมูลตัวอย่างแบบสุ่มตัวอย่าง ใช้เวลา M ตัวอย่างของการป้อนข้อมูลในแต่ละครั้งและใช้ค่าเฉลี่ยของ M-samples เหล่านี้และสร้างจุดเอาต์พุตเดี่ยว เป็นโครงสร้าง LPF (Low Pass Filter) ที่เรียบง่ายซึ่งเป็นประโยชน์สำหรับนักวิทยาศาสตร์และวิศวกรในการกรององค์ประกอบเสียงรบกวนที่ไม่พึงประสงค์จากข้อมูลที่ต้องการ เมื่อความยาวของตัวกรองเพิ่มขึ้น (พารามิเตอร์ M) ความนุ่มนวลของเอาต์พุตจะเพิ่มขึ้นในขณะที่ความคมชัดของการเปลี่ยนข้อมูลจะเพิ่มมากขึ้น นี่หมายความว่าตัวกรองนี้มีการตอบสนองโดเมนเวลาที่ยอดเยี่ยม แต่มีการตอบสนองต่อความถี่ต่ำ ตัวกรอง MA ทำหน้าที่สำคัญ 3 ประการคือ 1) ต้องใช้ M Input Point, คำนวณค่าเฉลี่ยของ M-points เหล่านี้และสร้างจุดเอาต์พุตเดี่ยว 2) เนื่องจากมีการคำนวณการคำนวณ ตัวกรองแนะนำจำนวนครั้งที่แน่นอนของความล่าช้า 3) ตัวกรองทำหน้าที่เป็น Low Pass Filter (มีการตอบสนองโดเมนความถี่ต่ำและการตอบสนองโดเมนที่ดี) รหัส Matlab: โค้ด MATLAB ดังต่อไปนี้จะจำลองการตอบสนองโดเมนเวลาของตัวกรองค่าเฉลี่ยเคลื่อนที่แบบ M-point และคำนวณการตอบสนองความถี่สำหรับความยาวของตัวกรองต่างๆ การตอบสนองโดเมนระยะเวลา: ในพล็อตแรกเรามีข้อมูลเข้าที่จะเข้าสู่ตัวกรองค่าเฉลี่ยเคลื่อนที่ การป้อนข้อมูลมีเสียงดังและวัตถุประสงค์ของเราคือการลดเสียงรบกวน ตัวเลขต่อไปคือการตอบสนองการส่งออกของตัวกรองการเคลื่อนที่เฉลี่ย 3 จุด สามารถอนุมานได้จากรูปที่ตัวกรอง 3 จุด Moving Average ไม่ได้ทำอะไรมากนักในการกรองเสียงรบกวน เราเพิ่มตัวกรองก๊อกเป็น 51 จุดและเราจะเห็นว่าเสียงในเอาต์พุตลดลงมากซึ่งแสดงในรูปถัดไป เราเพิ่มก๊อกต่อไปที่ 101 และ 501 และเราสามารถสังเกตได้ว่าถึงแม้จะมีสัญญาณรบกวนอยู่เกือบเป็นศูนย์การเปลี่ยนภาพจะลดลงอย่างเห็นได้ชัด (สังเกตความชันที่ด้านข้างของสัญญาณและเปรียบเทียบกับการเปลี่ยนแปลงของผนังอิฐที่เหมาะสมใน ข้อมูลของเรา) การตอบสนองต่อความถี่: จากการตอบสนองต่อความถี่คุณสามารถยืนยันได้ว่าการม้วนออกช้ามากและการลดทอนของแถบหยุดไม่ดี เมื่อพิจารณาการลดทอนแถบหยุดนี้อย่างชัดเจนตัวกรองค่าเฉลี่ยเคลื่อนที่จะไม่สามารถแยกย่านความถี่หนึ่งจากอีกความถี่หนึ่งได้ อย่างที่เราทราบดีว่าประสิทธิภาพที่ดีในโดเมนเวลาทำให้ประสิทธิภาพในโดเมนความถี่ต่ำและในทางกลับกัน ในระยะสั้นค่าเฉลี่ยเคลื่อนที่เป็นตัวกรองความราบเรียบที่ดีเยี่ยม (การทำงานในโดเมนเวลา) แต่เป็นตัวกรองความถี่ต่ำที่ไม่ดี (การดำเนินการในโดเมนความถี่) ลิงก์ภายนอก: หนังสือแนะนำ: Primary Sidebar

No comments:

Post a Comment