LAB 2.1 เขียนโปรแกรมใช้งาน Sensor Input
เอกสารประกอบ :โจทย์
ให้สร้างวงจรต่อไปนี้ให้เสร็จเป็นข้อๆ ไป
- การต่อเซ็นเซอร์เข้ากับ mcu เบื้องต้น – ให้ลองสร้างโคมไฟอัตโนมัติ โดยต่อเซ็นเซอร์แสงเข้ากับ mcu และควบคุมหลอดไฟ LED โดยให้เปิดเมื่อแสงมืด และให้ปิดเมื่อแสงสว่าง
- หลักการ Hysteresis – ให้ปรับปรุงโคมไฟอัตโนมัติข้างต้นโดยป้องกันไม่ให้ไฟติดๆ ดับๆ รัว ขณะที่ค่าเซ็นเซอร์อยู่บริเวณรอยต่อของเงื่อนไข และใช้โปรแกรม Serial Plotter เป็นเครื่องมือแสดงและพิสูจน์พฤติกรรมของเซ็นเซอร์และไฟ
- การใช้ Filter – ให้ปรับปรุงวงจรโดยใช้หลักการตัวกรอง (filter) ป้องกันไม่ให้ไฟเปลี่ยนสถานะในกรณีที่ค่าแสงสว่างเปลี่ยนแปลงชั่วครู่ เช่น ตอนกลางคืนหากมีแสงสว่างที่เกิดเกิดฟ้าแลบฟ้าผ่า หลอดไฟไม่ควรดับ หรือตอนกลางวันถ้ามีเงาพาดผ่านเซ็นเซอร์ทำให้แสงมืดไปชั่วขณะ หลอดไฟก็ไม่ควรติด ขอให้ใช้โปรแกรม Serial Plotter สร้างกราฟเพื่อแสดงให้เห็นผลก่อนและหลังการใช้ filter ด้วยให้ทดลองเปรียบเทียบการใช้ Filter สองแบบคือ
- Analog Filter – ทดลองใช้ Capacitor ทำหน้าที่เป็นตัวกรอง (C3 ในรูปวงจรด้านล่าง) โดยทดลองใช้ Capacitor ค่าต่างๆ เช่น 10 uF และ 100 uF โดยควรจะเห็นผลว่า capacitor ที่ใหญ่ขึ้นก็จะหน่วงให้ค่าเซ็นเซอร์เปลี่ยนช้าลง
- Digital Filter – ทดลองใช้ Digital Filter ผ่านทางการคำนวณหาค่าเฉลี่ยตามที่อธิบายในเอกสารประกอบ
- Analog Filter – ทดลองใช้ Capacitor ทำหน้าที่เป็นตัวกรอง (C3 ในรูปวงจรด้านล่าง) โดยทดลองใช้ Capacitor ค่าต่างๆ เช่น 10 uF และ 100 uF โดยควรจะเห็นผลว่า capacitor ที่ใหญ่ขึ้นก็จะหน่วงให้ค่าเซ็นเซอร์เปลี่ยนช้าลง
ประเด็นการเรียนรู้
- การทำงานของวงจร ADC (Analog to Digital Coverter) เป็นอย่างไร
- Voltage Divider คืออะไร และทำไมต้องนำมาใช้
- การ config PIC เพื่อให้ใช้งาน ADC ภายในตัวมันทำอย่างไรบ้าง
- เรียนรู้ความสำคัญของหลักการ Hysteresis และ Filter ในการป้องกันสัญญาณรบกวนในการนำเซ็นเซอร์ไปควบคุมการทำงานของอุปกรณ์ในชีวิตจริง
แนวทางการต่อวงจร ADC
วงจรแบ่งแรงดัน (Voltage Divider)
เนื่องจากวงจร ADC นั้นจะแปลงแรงดันให้เป็นค่าตัวเลข แต่เซ็นเซอร์แบบ Passive จำนวนมากมักมีค่าความต้านทานที่แปรตามสภาพแวดล้อมที่วัด ดั้งนั้นจึงต้องมีวงจรที่แปลง ความต้านทาน ให้กลายเป็น แรงดัน ซึ่งวงจรที่ง่ายที่สุดสำหรับงานนี้คือ วงจรแบ่งแรงดัน ภาพต่อไปนี้แสดงการต่อวงจรดังกล่าวกับ ADC port บน mcu โดยใช้เซ็นเซอร์แสงเป็นกรณีศึกษา
หลักการทำงานของวงจรแบ่งแรงดันขอให้ศึกษาจากเอกสารประกอบการสอน
แนวทางการใช้งาน Sensor Port บน PIC16
ตัวอย่างโปรแกรม
โปรแกรมต่อไปนี้จะอ่านค่าจากพอร์ท AN0 และพิมพ์ค่าออกมาทางหน้าจอทุกๆ 0.5 วินาที
#include <16F886.h> #device ADC=10 *=16 #FUSES NOWDT //No Watch Dog Timer #FUSES PUT //Power Up Timer #FUSES NOMCLR //Master Clear pin not enabled #FUSES NOPROTECT //Code not protected from reading #FUSES NOCPD //No EE protection #FUSES BROWNOUT //Brownout reset #FUSES IESO //Internal External Switch Over mode enabled #FUSES FCMEN //Fail-safe clock monitor enabled #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #FUSES NODEBUG //No Debug mode for ICD #FUSES NOWRT //Program memory not write protected #FUSES BORV40 //Brodddddwnout reset at 4.0V #FUSES RESERVED //Used to set the reserved FUSE bits #FUSES INTRC_IO #use delay(clock=8M) #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) void main() { setup_adc_ports(sAN0); // setup PIN A0 as analog input setup_adc( ADC_CLOCK_INTERNAL ); printf("Sampling:\r\n"); set_adc_channel( 0 ); // set the ADC chaneel to read delay_us(100); // wait for the sensor reading to finish while (1) { printf("Sensor value = %Lu\r\n", read_adc()); delay_ms(500); } }
อธิบายการทำงาน
PIC หมายเลข 16F886 มี Analog Port (หรือ Sensor Port) ทั้งหมด 11 ช่อง คือ AN0-AN10 โดยการใช้งาน port เหล่านี้ในโปรแกรมมีขั้นตอนดังต่อไปนี้
1. เปิดใช้ port
การใช้งาน Analog Port จะเริ่มต้นด้วยคำสั่งเปิดใช้งานวงจร ADC (Analog to Digital Converter) ดังนี้
setup_adc_ports(sAN0); // setup PIN A0 as analog input setup_adc( ADC_CLOCK_INTERNAL );
คำสั่งแรกใช้เลือกว่าจะเปิด port ใดบ้าง ค่า parameter ที่ใช้ได้กับคำสั่งนี่สามารถเปิดหาดูได้ในไฟล์ 16F886.h แต่ค่าที่ใช้บ่อยๆ ได้แก่
NO_ANALOGS // ปิดการใช้งาน ADC ALL_ANALOGS // เปิดใช้งาน Analog Port หมดทุก port sAN0 // เปิดใช้งาน Analog Port 0 เท่านั้น sAN0 | sAN1 | saN2 // เปิดใช้งาน Analog Port 0,1,2
2. กระตุ้นการทำงาน และอ่านผล
set_adc_channel( 0 ); // กระตุ้นการทำงานของ ADC ในช่องที่เลือก delay_us(100); // รอให้การแปลงค่าจาก Analog เป็น Digital เสร็จสิ้น sensorValue = read_adc(); // อ่านค่ามาเก็บไว้ในตัวแปร
- คำสั่ง set_adc_channel เป็นตัวกำหนดว่าเราจะกระตุ้นให้ Analog Port หมายเลขใดเริ่มทำงาน
- โดยหลังจากกระตุ้นแล้วจะต้องใช้คำสั่ง delay เพื่อรอให้วงจร ADC แปลงค่า Digital ให้เป็น Analog เสร็จสิ้นเสมอ (จุดนี้พลาดกันบ่อยมาก และทำให้โปรแกรมอ่านค่าออกมาผิดเพี้ยน)
- ขั้นตอนสุดท้ายคือการอ่านค่า Analog ออกมาเก็บไว้ในตัวแปร
*หมายเหตุ: เราสามารถกำหนดให้วงจร ADC อ่านค่าออกมาเป็นตัวเลขขนาด 8 หรือ 10 bit ก็ได้ ซึ่งกำหนดโดยคำสั่ง
#device adc=10 // ตั้งค่าให้ ADC อ่านค่าออกมาเป็นตัวเลขขนาด 10 bitโดยคำสั่งดังกล่าวจะต้องวางไว้ที่บรรทัดบนสุดใต้คำสั่ง include <16F886.h>
การแสดงกราฟด้วยโปรแกรม Serial Port Plotter
ในปฏิบัติกานี้การพล๊อทกราฟจะช่วยให้เห็นสิ่งที่เกิดขึ้นได้ดีขึ้น โปรแกรมที่แนะนำให้คือชื่อ Serial Port Plotter
Download Serial Port Plotterการพล๊อทจะทำโดยการส่งค่าตามรูปแบบต่อไปนี้
$value value value;
เช่น หากต้องการแสดงกราฟการนับค่าก็สามารถใช้โปรแกรมนี้ได้
int16 i=0,j=1000; while (1) { printf("$%lu %lu;", i,j); i++; j-- delay_ms(100); }
วิดิโอต่อไปนี้แนะนำวิธีการใช้โปรแกรม Serial Plotter