Archive
การตรวจสอบการใช้ Memory ( Measuring Memory Usage )
วิธีในการวินิจฉัยปัญหาของการใช้ memory คือการตรวจสอบจำนวน memory ที่ถูกใช้ไปโดยโปรแกรมที่เราเขียน เรามักต้องให้ความสำคัญกับเรื่อง การใช้ Memory ค่อนข้างมากเนื่องจาก ทรัพยากร Memory มีน้อย ดูได้จาก post ที่แล้ว เราลองมาดูวิธีการตรวจสอบ กันครับ
Flash
การตรวจสอบจำนวน พื้นที่ที่ถูกใช้ของ flash นั้นดูได้จาก ข้อมูลที่ compiler แสดงทุก ครั้ง ที่มีการ compile
EEPROM
สำหรับ EEPROM นั้นเราสามารถรู้ได้แน่นอนว่าพื้นที่ใช้ไปเท่าไร เหลือเท่าไร เนื่องจากการอ่านและเขียนนั้นเราจะต้อง อ้างไปที่ตำแหน่งของ address นั่นๆ เราไม่รู้ไม่ได้
จากรูปการใช้งานจะเห็นว่าการอ่านหรือเขียนข้อมูลกับ EEPROM นั้นจำนวนการใช้ Memory นั้นค่อยข้างชัดเจนและแน่นอนสามารถควบคุมได้ด้วยโปรแกรมเมอร์อย่างชัดเจน
SRAM
สำหรับ SRAM นั้น การใช้งานค่อนข้าง dynamic ทำให้ยากต่อการตรวจวัด การใช้ free_ram() เป็นวิธีเดียวสำหรับการตรวจสอบนี้ ใช้ส่วนของ code นี้ในโปรแกรม แล้วเรียกใช้เพื่อตรวจสอบ ได้เมื่อต้องการ จากจุดต่างๆ ของ code การใช้พื้นที่ของ SRAM นั้นค่อนข้าง คาดเดาได้ยาก จะต้องมีการตรวจสอบด้วย free_ram() เป็นระยะ ทุก จากทุกจุดของ code
การทำงานของ function freeRam() นั้นเป็นตรวจสอบพื้นที่ ว่างระหว่าง heap กับ stack ไม่ได้รวมถึง memory ใน heap ที่ เลิกใช้หรือ de-allocated (หรือเรียกว่า Buried heap space )
Buried heap space นั้นจะถูกทิ้งไว้โดยไม่มีใครสามารถนำไปใช้ได้ ไม่ว่าจะเป็นส่วนของ heap เองหรือ ของ Stack เองก็ตาม
Buried heap space นั้นเป็นพื้นที่ stack เอาไปใช้งานไม่ได้ หรือแม้แต่ heap เอง พื้นที่ ที่คืนมาอาจไม่ต่อเนื่องพอที่จะ allocate ใช้กับข้อมูลที่ต้องการใช้ได้ ก็ต้องทิ้งล้างไป ดังนั้นพื้นที่ ระหว่าง stack และ heap จึงเป็นพื้นที่ ที่เรา monitor เพื่อป้องกันปัญหาเช่น การล่มของ stack
รูปจาก https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory
ครับเป็นเรื่องราวที่จำเป็นจะต้อง ทำความเข้าใจให้ถ่องแท้แน่นอน เพื่อการเขียนโปรแกรมที่มีประสิทธิภาพและใช้ทรัพยากกรที่มีอย่างจำกัดได้ประโยชน์สูงสุดครับ
ติดตามกันต่อไปนะครับ อุปกรณ์ที่เราจะนำมาใช้งานร่วมนั้นก็มีส่วนที่จะต้องใช้ Memory เหมือนกัน ติดตามกันต่อไปครับ
ธีระพงษ์ สนธยามาลย์
อ้่างอิง Arduino – Memory , Measuring Memory Usage
การจัดการ Memory ของ Arduino [Arduino Memories]
Arduino มี Memory อยู่ 3 ชนิดคือ
- Flash หรือ Program Memory
- SRAM
- EEPROM
Flash Memory
ใช้สำหรับการบันทึก Program Image และข้อมูลตั้งต้นต่างๆ เราสามารถ run โปรแกรมจาก flash memory ได้แต่เราไม่สามารถแก้ไขข้อมูลใน flash memory จาก code ที่ทำงานอยู่ได้ หากต้องการแก้ไขข้อมูลเราจะต้องทำการสำเนาไปที่ SRAM
Flash memory นั้นใช้เทคโนโลยีเดียวกันกับ thumb-drive และ SD cards ซึ่งเป็นแบบ non-volatile หมายถึง program หรือข้อมูลจะคงอยู่แม้ว่าจะไม่มีไฟหล่อเลี้ยงอยู่ก็ตามหรือมีลักษณะเหมือน hard disk แต่มันก็มีข้อจำกัดในเรื่องจำนวนครั้งในการเขียนกล่าวคือเราจะเขียนหรือบันทึกข้อมูลลง flash memory ได้ประมาณ 100000 ครั้ง (100000 write cycle) มากพอที่จะใช้งานสัก 10 – 20 ปีแหละครับ ( สมมติว่าเราเขียนลงบน flash memory 10 ครั้งต่อวันเราก็จะใช้เวลาประมาณ 27 ปีครับ )
SRAM
หรือ Static Random Access Memory นั้นสามารถอ่านหรือเขียนได้จากโปรแกรม code ที่ทำงานอยู่ SRAM นั้นถูกใช้ในหลายๆจุดประสงค์คือ
- Static Data เป็นส่วนของ memory ที่กันไว้สำหรับ global variable และ static variable ของโปรแกรมสำหรับตัวแปรที่ถูกกำหนดค่าเริ่มต้นเมื่อเริ่ม start ระบบจะทำการสำเนาค่าเริ่มต้นนั้นจาก flash memory มาใส่ให้
- Heap เป็นส่วนที่เก็บข้อมูลแบบ dynamic หรือข้อมูลที่มีการ allocate ระหว่างที่โปรแกรมทำงาน ส่วนของ Heap นั้นจะขยายจากส่วนบนของ static data ขึ้นไปโดยใช้ส่วนของ memory ที่ว่างไปเรื่อยๆในระหว่างที่มีการจองและใช้งานของโปรแกรมที่ทำงานอยู่
- Stack เป็นส่วนของ memory ที่ใช้เก็บข้อมูลตัวแปรแบบ local และเก็บรายการ interrupts และ function call ต่างๆ memory ในส่วนของ stack จะขยายจากด้านบนสุดของ memory ลงมาหา Heap ดังนั้นทุกๆ ตัวแปร รายการ interrupts และ function call นั้นจะทำให้ memory ส่วน stack ขยายลงมากเรื่อยๆ การ return จาก interrupt หรือจาก function call นั้นจะคืนพื้นที่ว่างให้กับ SRAM
ปัญหาส่วนใหญ่ของ Memory เกิดจากการขยายขนนาดของ stack และ heap จนมาชนกันเมื่อเกิดการชนกันของ stack และ heap พื้นที่ข้อมูลของส่วนที่ถูกบันทึกทับก็จะเสียหายส่งผลให้เกิดการทำงานผิดพลาดแบบไม่สามารถคาดเดาผลการทำงานได้หรือในบางครั้งก็อาจทำให้เกิดการล่มของโปรแกรมไปเลย หรือในบางครั้งผลของการชนกันอาจไม่สังเกตเห็นได้จนกระทั่งเกิด error ขึ้นภายหลังจากนำเอาโปรแกรมไปใช้งานแล้วก็ได้
EEPROM
เป็น non-volatile memory อีกอันหนึ่งซึ่งสามารถอ่านและเขียนโดยโปรแกรม code ที่ทำงานอยู่แต่ข้อจำกัดของมันคือต้องอ่านทีละ byte ทำให้เวลาใช้งานยุงยากหน่อยและการอ่านก็ช้ากว่า SRAM นอกจากนี้ก็ยังมีข้อจำกัดในการเขียนที่ 100000 write cycle ( แต่การอ่านไม่จำกัด )
Arduino Memory Comparison
ตารางด้านล่างแสดงถึงข้อเปรียบเทียบของจำนวน memory แต่ละชนิดของแต่ละ model ของ Arduino และ Arduino compatible board
ครับ เรารู้รูปแบบของ Memory ต่าง ๆ กันคร่าวแล้ว ทำไงเราจะตรวจสอบว่า โปรแกรมที่เราเขียนนั้นใช้ Memory ไปเท่าไร หมายถึงอะไรเท่าไรนะครับ มีคำอธิบายต่อไปเรื่องการตรวจสอบ ใน ตอนต่อไปครับ เรื่อง การตรวจสอบการใช้ Memory ( Measuring Memory Usage )
ขอให้สนุกกับการ เรียนรู้นะครับ
ธีระพงษ์ สนธยามาลย์
วิธีการอ่าน PWM Signals จาก Receiver ด้วย Arduino ขั้นพื้นฐาน
เรามาเรียนรู้วิธีการอ่าน สัญญาณ PWM จาก Receiver กันครับ
จากที่เราทราบกัน นั้น ขาสัญญาณที่ใช้คบคุม servo นั้นส่งสัญญาณออกเป็น PWM และสามารถใช้ควบคุม servo ได้โดยตรง หากเราต้องการใช้สัญญาณนี้เราสามารถอ่าน จากขาสัญญาณเหล่านี้ได้ด้วย Arduino โดยตรง
ภาพบนเป็นภาพลักษณะการใชงานทั่วไป ครับ เนื่องจาก board ที่เราจะใช้นั้นเป็น Arduino UNO จะมีขาสัญญาณ PWM อยู่สามารถอ่านค่าได้โดยตรง ด้วยคำสั่ง pulseIn(…) ดังนั้นเพื่อทำความเข้าใจ ก็จะลองทดสอบอ่านค่าจากขาสัญญาณ จาก receiver ด้วย Arduino ดูนะครับ
อุปกรณ์ที่จะใช้
- board Arduino UNO R3
- Receiver (Futaba) R146iP
- Transmitter T9CHP
เราจะใช้ขา pin 9 ต่อกับ ช่องสัญญาณที่หนึ่งของ Receiver ดังรูป แล้วให้ Power เข้าที่ ช่องสัญญาณที่ 6 แล้วเราลองทดสอบกันด้วยโปรแกรมสั้น ๆ ตามนี้ครับ
int ch1 ; // to keep channel values void setup() { pinMode(9,INPUT); // set out input pin as such Serial.begin(9600); } void loop() { ch1 = pulseIn(9,HIGH,25000); // Read the pulse width of the channel Serial.print(“channel data : “); // print value of Serial.println(ch1) ; // the channel delay(100); }
puleIn() function ต้องการ 3 arguments ตัวแรกก็คือ หมายเลข pin ที่เราต้องการให้สัญญาณ pulse เข้ามา ตัวที่่ 2 คือ pulse ‘HIGH’ หรือ ‘LOW’ ที่เรากำลังสนใจอยู่ และสุดท้ายก็เป็น เวลาที่เรากำหนดให้ function รออ่านค่า เรียกว่า time-out
ค่าที่ return ให้ของ puleIn() ก็คือ ความยาวของ pulse มีหน่วยเป็น microseconds และนี่ก็คือวิธีการอ่านสัญญาณ PWM ซึ่งเป็นวิธีเดียวกับที่ servo อ่านสัญญาณนี้
ค่าที่ได้เราให้แสดงออกทาง terminal เมื่อเราทำการประมวลผลโปรแกรมนี้เราควรจะได้ ตัวแสดงผลขึ้นมาที่หน้า terminal ตัวเลขนี้ค่าควรจะอยู่ระหว่าง 1000 – 2000 และเมื่อเราขยับ joy stick ที่เชื่อมโยงกับช่องสัญญาณนี้ ตัวเลขก็ควรจะเปลี่ยนแปลงให้เห็น
ครับ เท่านี้ก็ถือว่า เป็นการทดสอบที่ สมบูรณ์ และสามารถใช้งาน ได้แล้ว ในเรื่องนี้ยังไม่จบนะครับนี่เป็นจุดเริ่มต้นของการเรียนรู้ในขั้น Advance ต่อไปครับ
ธีระพงษ์ สนธยามาลย์
s.teerapong@gmail.com
เรื่องของ PWM และ PPM
อันที่จริงความรู้อะไรเกี่ยวกับทางนี้ผมก็ไม่ค่อยมีนะครับ หา หา เอาจาก internet พอดีว่ามีความสนใจเล่นเจ้า Arduino เป็นงานอดิเรก [ เกือบเป็นงานหลักแล้วตอนนี้ ] ในการทำโครงงานบางอย่างต้องใช้พื้นฐานความรู้ความเข้าใจในลักษณะสัญาญที่ต้องนำสัญาณนั้นมาใช้บ้างไว้เป็น concept พื้นฐานในการคิดในเรื่องการใช้งานต่อไป
ส่วนตัวผมนอกจากจะสนใจงานทางด้านนี้แล้วยังสนใจและเล่น เครื่องบินบังคับ หรือบ้านเราก็เรียกว่า R/C ครับ ที่กล่าวมานี้ ก็จะบอกว่ามีเครื่องมือชนิดหนึ่งที่เราใช้ในการควบคุม เครื่องบินก็คือ Radio Control และสัญญาณอุปกรณ์นี้ต้องใช้ในการควบคุมระยะใกล้ก็คือคลื่นวิทยุโดยที่มีตัวรับเป็น Receiver เพื่อรับและ decode สัญญาณออกมาควบคุม Servo ทำให้เราต้องรู้จัก PWM และ PPM กันไงครับ
PWM และ PPM นั้นเป็นคำที่เห็นกันบ่อย ๆ ในวงการ R/C เจ้า PWM นั้นย่อมาจาก Pulse Width Modulation และ PPM นั้นย่อมากจาก Pulse Position Modulation อุปกรณ์ที่ใช้ สัญญาณ PWM ในการควบคุม ก็คือ Electronic speed controls หรือ ESC และ servos. PWM เป็นการ encode ข้อมูลด้วยการใช้ความกว้างของ pulse (ด้วยระยะเวลาต่างๆ กัน)
ในระบบ digital electronic นั้นเราก็จะรู้จัก ค่าของ binary ซึ่งมีค่า 1 และ 0 เราจะแทนค่า 1 ด้วย ‘on’ และทนค่า 0 ด้วย ‘off’ ซึ่งตัวอย่างของ การแสดงสัญาณนี้ก็คือ swtich ไฟ เปิดไฟ ก็คือ ‘1’ ปิดไฟก็คือ ‘0’ นั่นเอง แต่ในกรณีของ สัญญาณ PWM/PPM นั้น ก็เช่นเดียวกัน ค่า voltage ใด ๆ แทนค่า 1 และ กลับกันคือ 0 แทนด้วย 0 voltage แต่ในทางการใช้งานควบคุมนั้น แค่ on/off ไม่เพียงพอ ซึ่งนะจุดนี้จึ่งเป็นที่มาของ pulse width
ธีการในการ เข้ารหัสข้อมูล ก็คือการใช้เวลาที่ pulse อยู่ในสถานะ on ในกรณีของ R/C electronics นั้นช่วงเวลาจะอยู่ในรหะว่าง 1-2 milliseconds. (หรือ 0.5 – 2.5 ms )
อุปกรณ์ servo หรือ ESC นั้นจะค่อยดู pulse และจะนับเวลาเมื่อตรวจพบ pulse นี้ จะหยุดนับเวลาเมื่อ pulse หมด pulse ดังนั้นเวลาทั้งหมดที่ pulse มีสถานะเป็น on จะเป็นตัวบอกว่า servo จะหมุนไปแค่ไหน ตัวอย่างเช่น pulse on เป็นเวลา 1 ms จะทำให้ servo หมุนมาทางด้าน ซ้ายสุด แต่ถ้าเวลาเป็น 2ms จะทำให้ servo หมุนไป ซ้ายสุด
รูปแสดง ความกว้างของ pulse ต่อการเคลื่อนที่ของ servo
( ในรูปใช้ ห้วงเวลาระหว่าง 0.5 – 2.5 ms แต่ในคำอธิบายใช้ 1-2 ms )
ทั่วไปแล้ว อุปกรณ์ R/C ทั้งหลาย สัญญาณหนึ่งวงรอบจะใช้ 20 ms ซึ่งเราจะเรียกห้วงเวลานี้ว่า frame ในหนึ่ง fame จะประกอบด้วย ช่วงที่ pulse มีสถานะเป็น high (1-2 ms) และช่วงที่ pulse มีสถานะเป็น low ดังรูปด้านล่าง
ถึงแม้ว่า fame มีความกว้าง 20 ms ก็ตาม ส่วนที่สำคัญของ pulse ก็คือห้วงเวลาที่ pulse มีสถานะเป็น on ซึ่งก็ประมาณ 1-2ms (0.5 – 2.5 ms) แม้ว่าช่วงที่ pulse มีสถานะเป็น off หรือ low นั้นจะไม่ได้ใช้งานอะไร ก็ยังคงเก็บไว้ และ frame ขนาด 20 ms นี้ถือว่าเป็นเวลาที่ดีที่สุดแล้ว หากเพิ่มเวลาให้มากกว่านี้ออกไป อาจทำให้เสียการควบคุม servo ได้ เช่น เสีย holding power อาจทำให้ servo เกิดอาการ กระตุกเป็นระยะได้
ต่อไปนะครับ ว่าทำไมถึงจะต้องรอจนถึง 20 ms ส่วนนี้เป็นข้อกำหนดของ อุปกรณ์ R/C และคำอธิบายจะทำให้เราเข้าใจ PPM ต่อไป
PPM ย่อมาจาก Pulse Position Modulation พูดง่ายๆ ก็คือ PPM นั้นเกิดจากการนำ PWM มาเรียงต่อกัน ดังภาพ
นอกจากเหตุผลในเรื่อง ของการรักษา holding power แล้ว เหตุผลของการใช้ 20ms คือการที่จะทำให้เราสามารถนำเอา PWM มาจัดวางต่อกันใน frame เดียวกันได้ อย่างที่ได้กล่าวไว้ข้างต้นว่า ห้วงเวลาที่ pulse อยู่สถานะ on นั้นเป็นส่วนที่เราใช้ประโยชน์ เราก็นำห้องเวลาของ pulse on มาจัดเลียงในหนึ่ง frame เราสามารถใช้วิธีการในการส่งข้อมูลหลายๆ channels ในห้วงเวลา 20ms ได้พร้อม ๆ กันจิงไหมครับ
เช่น คิดง่าย ๆ ว่า หาก เครื่องส่งวิทยุเป็นแบบช่องสัญญาณเดียวจะส่ง 1 PWM ในหนึ่ง frame (20ms) แต่ถ้า วิทยุเป็นแบบ 8 channels เราก็สามารถซอยห้วงเวลา 1 frame เพื่อที่จะจัดวาง pulse ของ 8 PWM ได้ ซึ่งอาจจะให้ channels ละ 1-2 ms ก็แล้วแต่การใช้งาน
ถึงเวลานี่้คงได้ concept ในเรื่องนี้เพื่อการใช้งานต่อไปครับ รายการด้านล้างจะแบ่งให้ เห็นว่าอถปรณ์ใดใช้ PWM และอุปกรณ์ใดใช้ PPM ครับ
R/C Devices ที่ใช้ PWM -servo -electronic speed controller -R/C switches -R/C lights -R/C receivers -Data loggers -Failsafe's -Autopilot/Stabilization systems -Servo Controller R/C Devices ที่ใช้ PPM -R/C transmitters -R/C receivers -Autopilot/Stabilization systems -PCTx
สำหรับเรื่องนี้ผมเอาไว้เป็นพื้นฐานในการใช้งานในเรื่องของการ อ่านข้อมูลจาก receiver ของ R/C ครับ
จบดีกว่า นะ