Contents

การเพิ่ม ADC ให้กับ Raspberry Pi ของคุณ: สิ่งที่คุณต้องรู้

ประเด็นที่สำคัญ

Raspberry Pi ไม่สามารถประมวลผลสัญญาณอะนาล็อกได้โดยตรง อย่างไรก็ตาม สามารถติดตั้งตัวแปลงอนาล็อกเป็นดิจิทัล (ADC) ภายนอกได้ เพื่อแปลงค่าแรงดันไฟฟ้าทางกายภาพให้อยู่ในรูปแบบดิจิทัลที่เหมาะสมสำหรับการจัดเก็บข้อมูล การจัดการ และการจัดการ

ตัวเลือกตัวแปลงอนาล็อกเป็นดิจิทัล (ADC) ยอดนิยมประกอบด้วย MCP3004/MCP3008 ซึ่งให้ความสมดุลระหว่างความเร็วและความแม่นยำ เช่นเดียวกับ ADS111x ซึ่งให้ความละเอียด 16 บิตที่ความถี่สุ่มตัวอย่างต่ำกว่า

ADS1115 ซึ่งมีจำหน่ายผ่าน Adafruit เป็นโซลูชันสุดหรูที่มีเครื่องขยายสัญญาณแบบตั้งโปรแกรมได้ (PGA) ช่วยให้ตรวจจับความต่างของแรงดันไฟฟ้าเพียงเล็กน้อย ขณะเดียวกันก็อำนวยความสะดวกในการปรับอัตราขยายแบบไดนามิกระหว่างการทำงาน การบูรณาการกับ Raspberry Pi ผ่าน I2C ไม่ใช่เรื่องท้าทายแต่อย่างใด

ข้อบกพร่องเบื้องต้นของ Raspberry Pi ในการจัดหาอินพุตแบบอะนาล็อกทำให้มันแตกต่างจากแพลตฟอร์มที่เน้นไมโครคอนโทรลเลอร์เช่น Arduino ซึ่งอาจจำกัดความสามารถเมื่อเปรียบเทียบกับทางเลือกเหล่านั้น

แม้ว่าอาจดูน่ากลัว แต่ก็มีทางเลือกมากมายให้สำรวจ คุณสามารถเริ่มต้นด้วยการใช้ Raspberry Pi ร่วมกับตัวแปลงอนาล็อกเป็นดิจิทัล (ADC) ภายนอกเพื่อการทำงานที่ราบรื่น

ทำไมต้องเพิ่มอินพุต?

ในโลกธรรมชาติ มีเหตุการณ์มากมายที่อาจสรุปได้สะดวกผ่านการใช้ศักย์ไฟฟ้า ด้วยการแปลงศักยภาพเหล่านี้เป็นค่าเทียบเท่าไบนารี จึงสามารถจัดเก็บ จัดการ และใช้เป็นวิธีการในการควบคุมปัจจัยเพิ่มเติมและเปิดใช้งานกลไกเพิ่มเติมได้

เราอาจปรารถนาที่จะดูแลความชื้นของโลก ความอบอุ่นในเรือนร้อน หรือน้ำหนักของสัตว์ฟันแทะ อาจพยายามรวมตัวควบคุมระดับเข้ากับ Raspberry Pi สร้างแถบเลื่อนทั้งหมด หรือประดิษฐ์จอยสติ๊กรุ่นใหม่ การใช้งานที่เป็นไปได้นั้นกว้างขวางและหลากหลายเป็นส่วนใหญ่

ตัวเลือกสำหรับ ADC

แล้ว ADC ตัวไหนดีที่สุดสำหรับผู้เริ่มต้น?

ตัวเลือกยอดนิยมและตรงไปตรงมาที่สุดได้แก่ MCP3004 (และ MCP3008 ) ชิปจาก Microchip คุณจะได้รับสี่ (หรือแปด) ช่อง ช่องละ 10 บิต ซึ่งสามารถอ่านได้สูงสุด 200 kSPS ในทางกลับกัน มีอุปกรณ์ ADS111x จาก Texas Instruments ซึ่งอ่าน 16 บิตที่ 860 SPS ดังนั้นจึงมีข้อแลกเปลี่ยนระหว่างความเร็วและความแม่นยำ (และราคาตามธรรมชาติ)

ไมโครคอนโทรลเลอร์หลายตัวมีตัวแปลงอนาล็อกเป็นดิจิทัล (ADC) ในตัว ตัวอย่างเช่น ATMega ที่ใช้กันอย่างแพร่หลายใน Arduinos ส่วนใหญ่มีช่องความละเอียด 10 บิตหลายช่องพร้อมกับฟังก์ชันอื่นๆ ความสามารถนี้ช่วยให้แพลตฟอร์ม Arduino รองรับสัญญาณอินพุตแบบอะนาล็อกที่เกินขีดจำกัดความสามารถของ Raspberry Pi ในกรณีที่ Arduino ที่มีอยู่รวมอยู่ในโปรเจ็กต์และมีความละเอียด 10 บิตเพียงพอสำหรับความแม่นยำที่ต้องการ การใช้โซลูชัน Arduino ที่พร้อมใช้งานอาจพิสูจน์ได้ว่าเป็นแนวทางปฏิบัติที่ง่ายที่สุด

เพื่อความเรียบง่าย เราจะใช้ ADS1115 ซึ่งได้รับความอนุเคราะห์จาก Adafruit ในกรณีนี้

/th/images/ads1115_photo.png

แอมพลิฟายเออร์เกนที่ตั้งโปรแกรมได้คืออะไร?

วงจรรวมมีความสามารถที่น่าสนใจหลายประการ โดยเฉพาะอย่างยิ่ง Programmable Gain Amplifier (PGA) ที่รวมไว้ ซึ่งช่วยให้สามารถตั้งค่าดิจิตอลของสเปกตรัมแอมพลิจูดที่ต้องการได้ PGA อนุญาตให้ระบุช่วงแรงดันไฟฟ้าจนถึงเศษส่วนของโวลต์ ทำให้สามารถตรวจจับความแปรผันในนาทีเล็กๆ น้อยๆ เพียงไม่กี่ไมโครโวลต์ได้ เนื่องจากอาร์เรย์ของค่ามากมายที่แสดงด้วยความละเอียด 16 บิต

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

แล้วมัลติเพล็กซ์ล่ะ?

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

การจัดการกับการลงทะเบียน

ADS1115 มีฟังก์ชันการทำงานมากมายที่สามารถเข้าถึงได้ง่ายผ่านการตั้งค่าการควบคุมต่างๆ ซึ่งรวมถึงความสามารถในการจัดการหลายรายการ

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

เมื่อดู เอกสารข้อมูล ADS111x คุณจะพบว่ารุ่นเหล่านี้มาพร้อมกับรีจิสเตอร์สี่ตัว รวมถึงรีจิสเตอร์การกำหนดค่าที่ควบคุมอุปกรณ์ พฤติกรรมของ€™

/th/images/as1115_config_register.jpg

ในบริบทนี้ บิต 14 ถึง 12 ใช้สำหรับควบคุมการทำงานของมัลติเพล็กเซอร์ ด้วยการใช้เลขฐานสองสามหลักนี้ เราสามารถเลือกการกำหนดค่าที่แตกต่างกันแปดแบบได้ โดยเฉพาะอย่างยิ่ง การกำหนดค่าที่ต้องการในกรณีนี้คือ"100"เนื่องจากเป็นตัวกำหนดสัญญาณส่วนต่างระหว่างช่องอินพุต 0 และกราวด์ ในทางกลับกัน บิต 7 ถึง 5 มีหน้าที่ควบคุมความถี่การสุ่มตัวอย่าง เพื่อให้ได้อัตราการสุ่มตัวอย่างสูงสุดที่เป็นไปได้ที่ 860 ตัวอย่างต่อวินาที การตั้งค่าบิตเหล่านี้เป็น"111"จะเหมาะสมที่สุด

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

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

การเดินสายไฟขึ้น

อุปกรณ์นี้อาจเชื่อมต่อกับเขียงหั่นขนมได้อย่างสะดวก ช่วงอินพุตแรงดันไฟฟ้าบวกครอบคลุมตั้งแต่ 2 ถึง 5.5 โวลต์ ทำให้มั่นใจได้ว่าสามารถใช้งานร่วมกับแหล่งจ่ายไฟ 3.3 โวลต์ของ Raspberry Pi

เพื่อเริ่มการทำงาน ให้เชื่อมต่อพิน SDA และ SCL จาก MCP3008 เข้ากับพอร์ตที่เกี่ยวข้องบน Raspberry Pi ในขณะที่เชื่อมต่อกราวด์และการเชื่อมต่อ 3.3V พร้อมกัน นอกจากนี้ ให้ใส่โพเทนชิออมิเตอร์แบบอนุกรมระหว่างสายกราวด์และสายแรงดันไฟฟ้า หลังจากนั้นให้ต่อปลายด้านหนึ่งของตัวนำกลางของโพเทนชิออมิเตอร์เข้ากับอินพุตแรกของตัวแปลงอนาล็อกเป็นดิจิทัล (ADC) เมื่อขั้นตอนเหล่านี้เสร็จสิ้น การตั้งค่าของคุณก็พร้อมใช้งาน

การจัดการกับ I2C

ตัวแปลงแอนะล็อกเป็นดิจิทัล (ADC) ที่หลากหลายใช้โปรโตคอลการสื่อสารที่หลากหลายสำหรับการทำงาน ตัวอย่างเช่น ในบริบทของ ADS1115 เราจะใช้อินเทอร์เฟซเฉพาะที่เรียกว่าวงจรรวมระหว่างกัน (I2C) เพื่อวัตถุประสงค์ในการสื่อสารและการถ่ายโอนข้อมูล

ในการใช้ Python ในการเชื่อมต่อกับตัวแปลงอนาล็อกเป็นดิจิทัล (ADC) บน Raspberry Pi จะต้องเป็นไปตามข้อกำหนดเบื้องต้นบางประการ โชคดีที่การทำซ้ำล่าสุดของระบบปฏิบัติการ (OS) Raspberry Pi ได้ปรับปรุงกระบวนการนี้ให้คล่องตัวขึ้นอย่างมาก หากต้องการเริ่มขั้นตอนการตั้งค่า ให้ไปที่"การตั้งค่า"ภายในเมนูระบบ และเลือก"การกำหนดค่า Raspberry Pi"จากนั้นไปที่แท็บ"อินเทอร์เฟซ"และเปิดใช้งานตัวเลือก"I2C"

/th/images/i2c_enable.jpg

เพื่อให้แน่ใจว่าส่วนประกอบทั้งหมดทำงานอย่างถูกต้อง โปรดเปิดอินเทอร์เฟซบรรทัดคำสั่งโดยเปิดหน้าต่างเทอร์มินัลแล้วดำเนินการคำสั่งต่อไปนี้:

 sudo i2cdetect -y 1 

ข้อความที่ให้มาจะอธิบายสถานการณ์จำลองที่การดำเนินการคำสั่งเฉพาะจะสร้างเอาต์พุตบนกริด ซึ่งมีข้อมูลเกี่ยวกับที่อยู่ของตัวแปลงอนาล็อกเป็นดิจิทัล (ADC) ผู้เขียนเน้นย้ำว่าค่าเลขฐานสิบหกนี้ต้องนำหน้าด้วย"0x"ก่อนที่จะนำไปใช้ภายในโค้ดที่ตามมา ในกรณีนี้ ค่าจะแสดงเป็น 0x48

/th/images/20231108_18h24m38s_grim.jpg

การใช้ที่อยู่ที่ได้รับอาจใช้ไลบรารี SMBus เพื่อส่งคำสั่ง I2C โดยใช้ขั้นตอนที่แตกต่างกันสองขั้นตอน หนึ่งในวิธีการเหล่านี้เกี่ยวข้องกับการใช้ฟังก์ชัน write\_word\_data() ซึ่งต้องใช้อินพุตสามรายการ ได้แก่ ที่อยู่ของอุปกรณ์ การลงทะเบียนเฉพาะที่กำลังเขียน และค่าข้อมูลที่ต้องการซึ่งจะถูกจารึกไว้ในตำแหน่งดังกล่าว

ฟังก์ชัน read\_word\_data() ใช้สำหรับป้อนที่อยู่อุปกรณ์และรีจิสเตอร์ และทำให้ตัวแปลงอนาล็อกเป็นดิจิทัล (ADC) สุ่มตัวอย่างและจัดเก็บค่าแรงดันไฟฟ้าในรีจิสเตอร์ที่ระบุอย่างต่อเนื่อง ซึ่งช่วยให้สามารถดึงข้อมูลที่เก็บไว้จากรีจิสเตอร์ในภายหลังได้

อาจเลือกที่จะปรับปรุงการนำเสนอด้วยภาพและแสดงผลในภายหลัง ก่อนที่จะกลับเข้าสู่วงจรวนซ้ำ อาจมีการหยุดชั่วคราวหรือหน่วงเวลาเล็กน้อย วิธีการดังกล่าวช่วยป้องกันข้อมูลล้นเกิน

 from smbus import SMBus
import time
addr = 0x48
bus = SMBus(1)

# set the registers for reading
CONFIGREG = 1
CONVERSIONREG = 0

# set the address register to point to the config register
# write to the config registers
bus.write_word_data(addr, CONFIGREG, (0b00000100 << 8 | 0b10000010))

 # define the top of the range
TOP = 26300

while True:
    # read the register
    b = bus.read_word_data(addr, CONVERSIONREG)

    # swap the two bytes
    b = ((b & 0xFF) << 8) | ((b >> 8) & 0xFF)
    
    # subtract half the range to set ground to zero
    b -= 0x8000

    # divide the result by the range to give us a value between zero and one
    b /= TOP

    # cap at one
    b = min(b, 1)

    # bottom is zero
    b = max(b, 0)

    # two decimal places
    b = round(b, 2)
    print(b)
    time.sleep(.01)

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

การจัดการกับเสียงรบกวน

ในกรณีที่สภาพแวดล้อมขาดการจัดระเบียบและความเป็นระเบียบในระดับสูง อาจเห็นได้ชัดว่ามีองค์ประกอบที่ไม่พึงประสงค์บางอย่างอยู่ในข้อมูลที่ถูกรวบรวม ปรากฏการณ์นี้สามารถนำมาประกอบกับความจริงที่ว่าการใช้ช่วงค่าที่น้อยกว่า เช่น ความละเอียด 16 บิต แทนที่จะเป็น 10 บิต นำไปสู่โอกาสที่จะเผชิญกับการรบกวนหรือ"สัญญาณรบกวน"เหล่านี้เพิ่มมากขึ้น

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

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

ก้าวต่อไปด้วยขั้นตอนถัดไปที่เป็นไปได้มากมาย

การใช้ I2C เพื่อจุดประสงค์ในการอ่านเป็นกระบวนการที่ค่อนข้างง่าย เช่นเดียวกับกรณีที่ใช้วิธีการอื่นเช่น SPI ในทำนองเดียวกัน แม้จะมีความแตกต่างที่ชัดเจนระหว่างทางเลือก ADC ต่างๆ แต่ความจริงก็คือเมื่อใครก็ตามได้นำตัวเลือกเหล่านี้ไปใช้อย่างประสบความสำเร็จ ความเชี่ยวชาญที่ได้รับก็สามารถนำไปใช้กับส่วนที่เหลือได้ทันที

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