วันพฤหัสบดีที่ 3 กรกฎาคม พ.ศ. 2557

PIC16F648A กับ Mouse Wheel

วันนี้ก็มาเป็นบทความเกี่ยวกับวิชาการกันบ้างดีกว่า เป็นแหล่งความรู้เผื่อจะมีคนค้น แต่ผมว่าบทความต่อไปนี้กลุ่มคนที่จะค้นบทความนี้เจอก็คงมีไม่มากหรอกมั้งครับเป็นบทความเฉพาะกลุ่มคนจริง ๆ แคบ มาก ๆ และก็ไม่ใช่เรื่องยาก หรือใหม่สักเท่าไหร่ แต่ก็ไม่ค่อยมีใน google ครับ ประมาณว่าผมรู้แล้วจึงมาบอกต่อ

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

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

จุดประสงค์ของภารกิจนี้ก็คือ หุ่นยนต์ ที่เรียกว่า Crawling Robot ครับ  ก็คือหุ่นยนต์ ก็ไม่คล้ายกับหุ่นยนต์สักเท่าไหร่หรอกครับ คือเขาจะมีแต่แขนยาว ๆ น่าจะเรียกว่ารยางค์ (เขียนแบบนี้หรือเปล่านะ) เหมือนพวก flagella  (เขียนงี้ป่าว) ของพวกสิ่งมีชีวิตเซลล์เดียว นะครับ

คงไม่อธิบายมากแปะ youtube ที่มาต้นเรื่องให้ดูดีกว่าครับ


และก็ตัวนี้จากคำบอกเล่าของน้องทั้งสองก็น่าจะมีหน้าตาประมาณนี้มากกว่า

ก็คือเป็นการใช้พวก Machine Learning หล่ะนะเข้ามา แต่บังเอิญว่าพวกเราไม่ได้มีอุปกรณ์เหล่านี้อยู่ในภาควิชาดังนั้น อาจารย์ก็เลยบอกว่าสร้างเอง !!!!   น้องที่มาก็เป็นผู้หญิงเสียด้วย แล้วก็ต้องมานั่งเรียนอิเลคทรอนิกส์เบื้องต้น มานั่งดูเพือที่จะออกแบบสร้างสรรค์หุ่นยนต์ด้วยวิชา กพอ. ที่ร่ำเรียนมาตั้งแต่สมัยยังประถมศึกษา งานนี้บอกตามตรงก็ว่ายากอยู่แหล่ะ

นี่ขนาดเตรียมวัตถุดิบเริ่มต้นนะครับยังไม่ได้เจาะเข้าสู่่หัวใจของการเขียนโปรแกรม Machine Learning ซึ่งเป็นหัวข้อจริง ๆ ของโปรเจ็คจบตัวนี้เลยนะครับเนี่ยก็เหนื่อยปาดเหงื่อกันแล้ว

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

และสิ่งที่ผมจะต้องค้นคว้าก็คือผมจะต้องค้นคว้าในเรื่องของ servo motor, PIC Microcontroller เพราะตอนที่ผมจบนั้นผมใช้ Basic Stamp ซึ่งตอนนี้ก็คง out ไปแล้ว ไม่ค่อยเห็นมีคนใช้กันสักเท่าไหร่ครับ (สมัยก่อนก็ด้วยหล่ะมั้งครับเพราะก็ไม่เห็นมีบทความมากนัก ..... ที่สมัยผมเรียนผมเลือก Basic Stamp เพราะดูมันยุ่งยากน้อยกว่า PIC มั้งครับ)   และอีกตัวหนึ่งซึ่งเป็นสิ่งที่บทความนี้จะนำเสนอก็คือตัว Mouse Wheel ครับ

ผมใช้เวลาเรียนรู้ไม่นานนัก เพราะน้อง ๆ เองก็ทำให้ผมดู ผมมีพื้นฐานอยู่บ้างแล้วเลยดูดวิชาจากน้องเป็นเร็วครับใช้เวลาไม่นาน ผมก็ถนัดมือแล้วสำหรับคำสั่งง่าย ๆ อย่างไฟกระพริบ  ผมก็เลยเจาะเข้าปัญหาที่น้อง ๆ เจอ ก็คือเรื่องของ Servo Motor การควบคุม ซึ่งผมเองก็ไม่มีความรู้แต่แรกเลยเหมือนกัน (ตอนจบผมใช้ Stepping Motor) ก็เข้าไปอ่าน บทความที่เกี่ยวข้องซึ่งมีมากมายใน Google ก็รู้ว่าแค่ปล่อย pulse ที่มีความกว้างให้ได้ตามสเปคของเขา  servo ก็ขยับได้แล้ว  อาจจะเจอปัญหาบ้างเพราะตอนแรกคาดว่าจะใช้ PWM ของ Microcontroller แต่ปัญหาก็คือ PIC16F648a นั้น มันไม่รองรับความถี่ที่ 50Hz ครับ .... ทำไมจึงต้อง 50Hz เพราะว่าจากข้อมูลที่ค้นมาเขาบอกว่า pulse จะอยู่ในช่วง 1.0 - 2.0 millisecond และก็จะต้องเว้นว่างไป 18 millisecond  ดังนั้นทำให้ความยาวคลื่นลูกหนึ่งยาว 20 millisecond   นั่นหมายความว่าในหนึ่งวินาที ก็จะมีคลื่น 50 ลูก นั่นก็คือ 50Hz นั่นเอง     และพวกคำสั่งบางตัวก็ใช้ไม่ได้เช่น delay_ms ซึ่งในโปรแกรม MikroC นั้นไม่ยอมให้ใส่เป็นตัวแปรครับ เราเลยจบกันที่คำสั่ง delay_cyc ครับ ก็ไม่เลวร้ายอะไรครับ เพียงแต่ข้อจำกัดมันก็มีบ้างที่มันขึ้นกับวงจรของเราคือถ้าใช้ แร่ 4 MHz ก็อาจจะใช้ค่าหนึ่ง  ถ้าใช้แร่ 8 MHz ก็อาจจะต้องลดลงมา แต่ผมก็คิดว่าไม่น่าจะเป็นปัญหาอะไร

จากการที่น้องมา ผมก็ต้องค้นหาความรู้ การดู youtube ค้นคว้าความรู้เพื่อไปสอนน้องต่ออีกทีหนึ่งผลก็คือผมได้เรียนรู้การใช้ โปรแกรม Proteus มาด้วย ซึ่ง ผมถึงกับอุทานเลยว่า ว้าว .... คนเขียนโปรแกรมนี้มันเก่งจริง ๆ คือ เราไม่ต้องต่อวงจร เราก็สามารถรันคำสั่งได้เลย  .... เห้ย โปรแกรมอะไรจะเทพขนาดนี้  ผมยังคิดเลยว่าเด็กสมัยนี้ถึงแม้ว่าวิชาการมันเยอะ เพราะโลกมันมีวิชาประยุกต์ที่ไปไกลมาก ทำให้เรียนตามหลักสูตรเดิมคงได้แต่พื้นฐาน และนั่นอาจจะไม่เพียงพอ ทำให้เด็กสมัยใหม่นี้เหมือนจะต้องขยันกว่าเรามาก เพราะความรู้มันแตกแขนงเยอะ ประยุกต์กันเยอะกว่าสมัยเรามากนัก  แต่เครื่องมืออุปกรณ์วิธีในการเรียนการสอนนั้นก็พัฒนาขึ้นมามากด้วยเช่นกัน ถ้าเจอคนที่ใฝ่ที่จะเรียนจะรู้ Google กับ Youtube นี่เป็นอะไรที่ช่วยมากเลยครับ  ก็ยังแอบคิดในใจครับว่าโหเราเกิดมามีชีวิตในช่วงนี้ เทคโนโลยีสิ่งอำนวยความสะดวกเยอะมากครับเมื่อเทียบจากปากคำของรุ่นพ่อแม่เรา ถือว่านี่ก็เป็นเรื่องที่ดีอีกเรื่องหนึ่งเลยนะครับเนี่ย

พอเรามีโปรแกรม Proteus แล้วมันก็ง่ายสิครับ เราไม่จำเป็นต้องไปซื้อ Oscilloscope มาเพื่อจับว่า pulse ของเราหน้าตาเป็นอย่างไร เอา Proteus จำลอง โค้ดเรารวดเลยครับ ..... ง่ายสุด ๆ ครับ การทำสิ่งที่เราไม่สามารถมองเห็นได้ก็คือรูป pulse ที่จะเอาไปสั่ง servo motor กลับทำให้มองเห็นได้ง่าย ๆ โดยไม่ต้องลงทุนอะไรเลย (Proteus ผมก็ crack เอาครับ อันนี้คือสิ่งที่ไม่ดีเลยครับ ถ้าผมเป็นภาควิชาผมคงต้องลองเสนอให้ซื้อมาใช้แล้ว อุดหนุนเขาหน่อย)

การขับเคลื่อน Servo ก็เลยง่ายถึงเพียงนั้นแหล่ะครับ   อุปกรณ์การทำรยางค์ของตัวหุ่นยนต์ก็เลยถูกบรรยายไปสั้น ๆ ครับเพราะหลักการก็คือ ๆ กับการทำไฟกระพริบเลย  ถึงแม้ว่าจะหลงทางไปหาทางใช้ PWM อยู่ (ซึ่งจริง ๆ แล้วก็ควรจะใช้ PWM ครับ ในการขับเคลื่อน Servo เพื่อให้คลื่น pulse มันออกได้สม่ำเสมอเรียบเนียน .....  แต่ดูเหมือนว่า PIC 16F648a จะไม่รองรับ การสั่ง PWM ที่ขา CCP แบบความถี่ต่ำ ๆ และถึงแม้จะได้เราก็จะติดปัญหาอีกอย่างหนึ่งก็คือ เราต้องการควบคุม Servo ทีละสองตัว แต่ PIC 16F648a นั้นมาพร้อมกับขา CCP อันเดียวเอง นั่นคือถึงแม้ว่าใช้ได้ ก็จะไม่พอกับโปรเจ็คของเราอยู่ดี  ...     หมายเหตุ ผมไม่มั่นใจนะครับว่าความรู้ที่ผมแชร์นี้จะถูกหรือเปล่า ผมเองก็มือใหม่ครับ)



ทีนี้ก็มาถึงหัวข้อที่ผมจะเขียนถึงก็คือ
การทำอุปกรณ์ในการ Detect ระยะทาง
ในที่นี้ก็คือ Mouse Wheel นั่นเองครับ

ในภายหลังก็มาค้นคว้าครับ ก็จะมี mouse wheel อยู่สองแบบที่เราสามารถพบเจอได้ในเมาส์เสีย ๆ บ่อย ๆ ก็คือ

1. แบบที่ใช้เป็นลำแสง แล้วใช้ซี่ในการตัดแสงเอา 
ซึ่งข้อดีของเขาก็คือเขาไม่ได้ใช้ระบบหน้าสัมผัส เป็นแบบ contact เมื่อไม่มีหน้าสัมผัสเหมือนแบบที่สองที่จะกล่าวถึง ทำให้มันไม่มี pulse รบกวน หรือบางทีก็เรียนว่า Bouncing เหมือนตอนที่เราใช้สวิทซ์แหล่ะครับ เราก็จะต้องมารับมือกับพวกกระแส Bounce นี้ ปวดหัวดีเหมือนกันครับ แต่ในโปรเจ็คนี้ก็ไม่ได้ใช้ Mouse Wheel แบบนี้ครับ  เมาส์ที่เราหาซื้อได้จากร้านขายของเก่า หรือเมาส์ระดับราคาล่าง ๆ ไม่แพง หรือที่พบเจอบ่อยกว่าจะใช้แบบที่สองครับ

Mouse ที่ใช้ Scroll แบบแสงครับ ตัว Wheel ก็จะเป็นซี่ ๆ ให้แสงลอดผ่านได้ เอาไปตัดกับ sensor

2. แบบที่ใช้หน้าสัมผัส เหมือนมีสวิทซ์สองอัน
อันนี้เราจะเจอบ่อยมากครับ เราสามารถหาเมาส์เสีย ๆ มาแงะดูได้ครับ เราจะเจอ Mouse Wheel ที่มีแกนล้อต่อเข้ากับตัวประหลาด ๆ ตัวหนึ่ง มีสามขาครับ อาจจะนับได้ 5 ขา แต่ว่าสองขานั้นคาดว่าจะต่อลง ground หรือไม่ก็เป็นขาสำหรับยึดกับแผ่นปริ้นท์เพื่อให้มีความมั่นคงครับ  ใช้งานจริง ๆ ก็คือ 3 ขานี้แหล่ะครับ ส่วนตัวแล้วที่ผมคิดว่าเราเจอแบบนี้บ่อยกว่าแบบที่ 1 อาจจะเป็นเพราะต้นทุนถูกกว่า (อันนี้ผมคิดเองนะ) แล้วก็เวลาหมุนมันจะเหมือมีกรุบ ๆ ๆ ที่นิ้วมือด้วยมั้งครับ ถ้าเป็นแบบแรกมันจะเบา ๆ ไปหน่อย อันนี้เหมือนมันจะฝืด แล้วก็มีกรุบกรับ ๆ ๆ ที่นิ้วด้วย สัมผัสดี :)

Scroll Mouse แบบที่เจอบ่อยครับ และจะเอามาใช้ในโปรเจ็คนี้

เจ้าตัวนี้แหล่ะครับตัวสามขาที่เราหมายปอง ก็ไม่รู้ว่าชื่อเรียกของมันคืออะไรเหมือนกัน


ที่ผมมีเมาส์เสียเยอะส่วนหนึ่งมาจากของตัวเองด้วย แล้วก็หลายตัวเลยเก็บได้จากถังขยะครับ ผมว่าผมเจอเฉลี่ยปีละตัวนะ ผมก็เก็บไว้เพราะผมจะเอาสวิทซ์ของมันมาเปลี่ยน ส่วนใหญ่เมาส์ที่พังของผมก็คือสวิทซ์เมาส์ด้านซ้ายนะครับ แบบว่ากดบ่อยเกิน อินกับเกมส์เกิน อะไรแบบนั้นบางทีก็กดแรงไปบ้าง ถี่ไปบ้างแล้วแต่เกมส์ :)



ผมก็แนบไฟล์ pdf  โครงสร้างภายในไว้ให้สำหรับ download ด้วยครับ
ดาวน์โหลดรูปแบบไฟล์ pdf

ตอนแรกผมก็ไม่รู้ คือยังไม่ได้เห็นไฟล์นี้ ก็พยายามวัดหาขา Common รู้แค่ว่าโครงสร้างมันน่าจะเป็นสวิทซ์ 2 ตัว วัดแล้วก็แอบงง ว่าเอ๊ะทำไมบางทีมันเชื่อมกันหมด 3 ขาเลย บางทีสองขานี้ไม่เชื่อม มันมี Trick อะไรอยู่หรือเปล่า จนน้องในกลุ่มก็ไปค้นเจออันนี้เข้า จากเว็บหนึ่งของฝรั่ง ขอโทษด้วยครับผมไม่ได้เอาลิ้งค์มาปะเพื่อให้เครดิตแก่เขาเสียด้วย  แถมผมก็ไปเปลี่ยนชื่อไฟล์เสียแล้ว เพราะตอนที่ผมทำการทดลองนั้นไฟล์เอกสารเยอะมาก ผมก็เลยเปลี่ยนชื่อไฟล์เพื่อให้รู้ว่าไฟล์นี้คือเรื่อง MouseWheel ก็เลยไม่รู้ชื่อไฟล์ต้นฉบับแล้วนะครับ ขอโทษเจ้าของไฟล์มา ณ ที่นี้ด้วย



หลังจากดูโครงสร้างแล้วก็รู้แล้วว่าทำไมใช้มัลติมิเตอร์วัดแล้วได้ผลออกมาเป็นแบบนั้น  ก็ทำให้เข้าใจมากขึ้น ก็สรุปว่าอุปกรณ์ชิ้นนี้จะมี 3 ขาครับ คือ Common, A และ B

ก็ทดสอบกันเลยครับ ผมลองผิดลองถูกอยู่นานนะครับแต่ก็จะเอาเฉพาะส่วนที่คิดว่าน่าจะใช้ประโยชน์ได้มาลงครับ อันที่ทดลองมาสารพัดนั้นคงจะบอกได้แค่ว่า ตอนแรกก็เขียนโปรแกรมอ่าน logic จากขาธรรมดา ไม่เวิร์ก  ไปใช้ interrupt ที่ขา RB0 และขา RB3 (CCP) ไม่เวิร์กอีก  สุดท้ายมาใช้ interrupt ที่ขา 4, 5 ครับ  ผมเองก็ไม่เคยเขียนโปรแกรมในเชิงของ interrupt มาก่อนเลย เขียนแต่แบบ polling ครับกว่าจะเรียนรู้  แต่เรียนรู้แล้วก็รู้สึกว่าตัวเองรู้เยอะขึ้นครับ แต่ก็คงไม่ทั้งหมดของ PIC นะครับ

เป็นไดอะแกรมนะครับ ขอขอบคุณโปรแกรม Proteus มาก ๆ เลยครับ รู้สึกผิดที่ไม่ใช้ของถูกลิขสิทธิ์
อธิบายคร่าว ๆ ครับ สัญญาณจะมาจากตัว MouseWheel ซึ่งเป็นสวิทซ์ในรูปแบบหนึ่งผมต่อวงจรแบบ Active High คือปกติเป็น 0 และถ้าสวิทซ์กดหรือปิดก็จะเป็น 1 นะครับ (ตรงกันข้ามกับใน DataSheet หน้า 2 ในส่วนของ Test Circuit Diagram นะครับ ซึ่งเขาต่อแบบ Active Low)  ขา A,B จะเข้าไปที่ RB4, RB5 ตามลำดับครับ เพื่อใช้ Interrupt ในการจับค่าการเปลี่ยนแปลง Logic ที่ขาครับ (RBIE)

D1 เป็น LED หลดไฟสีฟ้านะครับ จะกระพริบตลอดเวลาให้รูู้ว่าตอนนี้ไมโครคอนโทรลเลอร์ยังทำงานอยู่นะครับ แต่ก็จะกระพริบตาม cycle ของมัน เหมือนสัญญาณชีพจรหล่ะกันครับ เพื่อบอกให้รู้ว่ายังมีชีวิตอยู่ รอรับ Interrupt ที่จะเกิดขึ้น

D2, D3 เป็น LED หลอดไฟสีแดงครับ เป็นตัวบอกทิศทางการหมุนครับ หมุนซ้ายหลอดหนึ่งจะติด แต่ถ้าหมุนอีกทางหนึ่งอีกหลอดจะติดแทนครับ

D4, D5 เป็น LED สำหรับบอกระยะทางการหมุนสะสมครับ ในที่นี้ผมก็เอาไว้แสดงค่าในตัวแปรครับ คือถ้าระยะทางเป็น + หลอดสีเขียวจะติด และถ้าระยะทางเป็น - หลอดสีเหลืองจะติดแทน แต่ถ้าระยะทางเป็น 0 ทั้งสองหลอดจะดับครับ

C1, C2 ความจุ 0.01uF อันนี้ใช้กรอง Bouncing ครับ ก็ใส่ตาม Test Circuit ที่มากับ DataSheet ของเจ้าตัวสามขานั่นแหล่ะครับ

ต่อลงบอร์ดทดลองครับเพื่อจะได้เขียนโค้ดแล้วรันดูจริง ๆ เลย

ซอรส์โค้ดก็เขียนจาก MikroC ครับ  16F648a ความถี่ที่ 8MHz ครับ
/**
* Demonstrate PIC16F648a 8MHz with Mouse Wheel 
* By Chalermchai Namkrachai |  Email: be4dev@gmail.com
**/ 
//ตัวแปรที่คอยจับสัญญาณของเมาส์ที่ส่งมาจากขา A,B -> FB4, FB5
unsigned char gs_signal = 0;
//logic state ปัจจุบันที่ขา FB4, FB5 ซึ่งจะมีค่าเท่ากันตลอดถ้าเม้าส์หมุนลงล้อค
unsigned char currentstate;


unsigned int heartbeat; //ตัวแปรสำหรับคอยให้สัญญาณว่า PIC ยังทำงานอยู่
int hop;  //เก็บค่า distance ว่าหมุนทางซ้าย - หมุนทางขวาแล้วเหลือเท่าไหร่

void interrupt()
{
     if (INTCON.RBIF)//เกิด interrupt RBIE ขึ้น
     {
        INTCON.RBIE = 0; //ปิด interrupt ป้องกัน interrupt ซ้อน
        delay_ms(5); //ช่วย Bouncing ใน DataSheet ของ mouse wheel เขาบอกว่าจะมี Bouncing 5ms max.
     
        //ค้นหา phase different ตาม Datasheet ของ mouse wheel หน้าสอง ที่เป็นรูป pulse ที่จะเหลื่อมกันเล็กน้อย คือเมื่ออยู่ใน stable state , logic state ที่ขา A,B จะเป็น ต่างกัน เหมือนกัน ต่างกัน เหมือนกัน เราจึงต้องมาจับ logic state ที่สลับกันนี้ เพื่อป้องกัน error ในการอ่านค่า
        if (gs_signal == (portb.f4 == portb.f5))
        {
           //ดูว่าขาไหนมีการเปลี่ยน logic ก่อนโดย logic state จะตรงกันข้ามกับปัจจุบันเสมอ เพื่อค้นหาว่า mouse wheel หมุนทางไหน จากนั้นแสดงไฟ และเพิ่ม/ลดค่าตัวแปร
           if (portb.f5 != currentstate) 
           {
              portb.f0 = 1;
              portb.f3 = 0;
              hop++;
           }
           else if (portb.f4 != currentstate)
           {
              portb.f3 = 1;
              portb.f0 = 0;
              hop--;
           }
        
           //เก็บค่า ณ ตำแหน่ง statble state เพื่อไว้เทียบกับครั้งหน้า
           gs_signal = !gs_signal;
        }


        //ลูปฟรี เพื่อรอให้ logic state ที่ขาทั้งสองนั้นกลับมาสู่สภาวะเท่ากัน แล้วจึงเก็บค่าสถานะปัจจุบัน, เปิด interrupt เพื่อรอการหมุน mouse wheel จังหวะถัดไป
        while(portb.f4 != portb.f5);
        currentstate = portb.f4;
        INTCON.RBIF = 0;
        INTCON.RBIE = 1;
     
     }
}



void main() {
     //เซ็ตพอร์ต A ให้เป็น output ทั้งหมด
     porta = 0;
     trisa = 0;
     cmcon = 0x07;
     
     //เซ็ตพอร์ต B ให้ ขา RB4,RB5 เป็น input ที่เหลือ output
     portb = 0;
     trisb = 0b00110000;
     
     INTCON = 0b10001000;
     hop = 0;
     while(1)
     {
             //แสดงไฟสัญญาณชีพครับให้รู้ว่าทำงานอยู่
             heartbeat++;
             if (heartbeat >= 60000)
             {
                porta.f0 = !porta.f0; //ไฟกระพริบได้เพราะบรรทัดนี้
                
                heartbeat = 0;
             }
             
             //if นี้แสดงระยะทางการหมุนครับว่าหมุนไปทางไหนมากกว่ากัน หรือถ้าไฟดับทั้งหมดแสดงว่าหมุนซ้าย/หมุนขวาเท่ากัน
             if (hop > 0)
                portb.f6 = 1;
             else if (hop < 0)
                  portb.f7 = 1;
             else
                 portb.f6 = portb.f7 = 0;
     }
}

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



มีวิดีโอมาฝากด้วยครับ :)


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

งานทางด้าน hardware สำหรับผมนี่ ทำเอามันส์ล้วน ๆ ไม่มีอย่างอื่นเจือปนเลยครับ เงินไม่ได้หรอกครับแถมเสียเงินซื้อนู่นนี่มาอีกต่างหาก

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

Keyword:
--------------------------------------------------------------------------------------------
PIC 16F648 Mouse Wheel PIC 16F648a  16F648 ไมโครคอนโทรลเลอร์ ใช้งาน ลูกกลิ้งเมาส์ ด้วย ไมโครคอนโทรลเลอร์ ลูกกลิ้ง พิค Scroll Wheel

มีคนหลงเข้ามาอ่านด้วยเหรอเนี่ย ... อิอิ