กลับไปหน้ารวมไฟล์
two-x-six-sided-die-sketch-using-74hc595-ics-a8c6b9.md

title: Rolling the Dice, Part 2 - การควบคุมลูกเต๋าผ่าน Shift Register 74HC595

การทอดลูกเต๋า ภาคที่ 2: ก้าวข้ามขีดจำกัดของจำนวน Pin ด้วย SIPO IC

บทความนี้เป็นภาคต่อของโปรเจกต์เครื่องทอดลูกเต๋าอิเล็กทรอนิกส์ โดยใน ภาคแรก (Part 1) เราได้เรียนรู้วิธีการสร้างลูกเต๋า 1 ลูก โดยใช้ LED 7 ดวงจัดวางตามรูปแบบแต้มลูกเต๋ามาตรฐาน (Pip Patterns) และเชื่อมต่อเข้ากับขา Digital I/O ของบอร์ด Arduino โดยตรง

อย่างไรก็ตาม ในภาคที่ 2 นี้ เราจะยกระดับโปรเจกต์ให้มีความเป็นมืออาชีพและขยายขีดจำกัดได้มากขึ้น (Scalability) ด้วยการนำไอซี Serial-Parallel Input/Output (SIPO) หรือที่รู้จักกันดีในชื่อ 74HC595 Shift Register มาใช้งาน ซึ่งช่วยให้เราสามารถควบคุมลูกเต๋ากี่ลูกก็ได้ โดยใช้ขาสัญญาณจากไมโครคอนโทรลเลอร์เพียง 3 ขาเท่านั้น!

ความแตกต่างระหว่างภาค 1 และ ภาค 2

ในภาคแรก LED แต่ละดวงจะถูกจองด้วยขา I/O ของ Arduino หนึ่งขา ซึ่งหากเราต้องการเพิ่มลูกเต๋าเป็น 2 หรือ 3 ลูก จำนวนขา I/O จะไม่เพียงพออย่างรวดเร็ว (ลูกเต๋า 2 ลูกต้องใช้ถึง 14 ขา)

ในภาคที่ 2 เราจึงนำ 74HC595 IC ขนาด 8 บิต มาเป็นตัวช่วยหลัก:

  1. การประหยัดทรัพยากร: ใช้สายสัญญาณเพียง 3 เส้น (Data, Clock, Latch) ในการขับเคลื่อน Output ได้ไม่จำกัดผ่านการต่อแบบ Cascade (Daisy Chaining) หรือการนำไอซีมาต่อพ่วงกันไปเรื่อยๆ
  2. การจัดสรรทรัพยากร: ในโปรเจกต์นี้เราใช้ลูกเต๋า 2 ลูก จึงใช้ 74HC595 จำนวน 2 ตัว (ตัวละ 8 พอร์ต) โดย LED 7 ดวงของลูกเต๋าแต่ละลูกจะเชื่อมต่อกับไอซี 1 ตัว ทำให้เหลือพอร์ตว่าง 1 พอร์ต (พอร์ต QA) ในไอซีแต่ละตัว ซึ่งเราออกแบบซอฟต์แวร์ให้รองรับส่วนนี้ไว้แล้ว
  3. การเขียนโปรแกรม: เราเปลี่ยนจากการใช้ digitalWrite() ตรงๆ มาเป็นการใช้งานผ่านไลบรารี ez_SIPO8_lib ซึ่งช่วยให้การจัดการข้อมูลแบบบิต (Bit Manipulation) และการส่งข้อมูลไปยังไอซีหลายๆ ตัวพร้อมกันทำได้ง่ายและเป็นระเบียบมากขึ้น

เจาะลึกการทำงานของ 74HC595 และการแสดงผลแต้ม

ไลบรารี ez_SIPO8_lib จะทำงานในลักษณะ "Virtual Memory" โดยจะจำลองสถานะของพอร์ตต่างๆ ไว้ในรูปแบบ Bit-mapped Bytes (1 ไบต์ต่อลูกเต๋า 1 ลูก) เมื่อเรากำหนดแต้มที่ต้องการเสร็จแล้ว จึงค่อยสั่งการส่งข้อมูล (Transfer หรือ xfer) ออกไปยังตัวไอซีจริงในขั้นตอนเดียว

เพื่อให้ LED แสดงผลเป็นรูปแต้มลูกเต๋าที่ถูกต้อง เราต้องกำหนดรูปแบบบิต (Binary Pattern) ให้สัมพันธ์กับการวางตำแหน่ง LED บน Breadboard ดังนี้:

  • หน้า 1 แต้ม (1 pip): 0b00010000
  • หน้า 2 แต้ม (2 pips): 0b01000100
  • หน้า 3 แต้ม (3 pips): 0b00111000
  • หน้า 4 แต้ม (4 pips): 0b10101010
  • หน้า 5 แต้ม (5 pips): 0b10111010
  • หน้า 6 แต้ม (6 pips): 0b11101110

ข้อสังเกต: เราไม่ได้ใช้งานพอร์ต QA (บิตขวาสุดหรือ LSB) ดังนั้นบิตสุดท้ายจะเป็น 0 เสมอ และหากเราต้องการแสดงแต้ม 2 เราจะสั่งงานที่บิต 2 (QC) และบิต 6 (QG) เพื่อให้ LED ดวงที่ตรงกันติดสว่าง

ภาพรวมการออกแบบฮาร์ดแวร์ (Hardware Design)

โครงสร้างหลักยังคงเน้นความเรียบง่ายแต่ทรงพลัง โดยมีปุ่มกด (Push Button) หนึ่งปุ่มทำหน้าที่สั่งงาน "ทอดลูกเต๋า" เมื่อกดปุ่ม ระบบจะทำการสุ่มค่าและแสดงผลผ่านชุด LED ทั้ง 2 ชุด

ในส่วนของวงจร 74HC595 เราจะต่อแบบอนุกรม (Cascaded) โดยขา Serial Output (Q7') ของไอซีตัวแรกจะเชื่อมเข้ากับ Serial Input (DS) ของไอซีตัวถัดไป วิธีนี้ทำให้ข้อมูลจาก Arduino ไหลผ่านไอซีทุกตัวในแถวเดียวกันได้โดยใช้สัญญาณนาฬิกา (Clock) และสัญญาณ Latch ชุดเดียวกัน

ในการต่อวงจรจริง แนะนำให้ดูที่ฉลากกำกับในไดอะแกรม (SIPO IC1 และ SIPO IC2) เพื่อป้องกันความสับสน เนื่องจากมีการเชื่อมต่อสายไฟจำนวนมากระหว่าง LED และพอร์ต Output (QB-QH) ของไอซี

การวิเคราะห์ซอฟต์แวร์และลอจิกของโปรแกรม

ในการใช้งานโปรเจกต์นี้ จำเป็นต้องติดตั้งไลบรารี 2 ตัวที่พัฒนาโดย Ron Bentley เพื่อความสะดวกและเสถียรภาพของระบบ:

  1. ez_switch_lib: สำหรับจัดการปุ่มกดและการทำ Debouncing (ลดสัญญาณรบกวนจากการกดปุ่ม) ดาวน์โหลดที่นี่
  2. ez_SIPO8_lib: สำหรับควบคุม Shift Register 74HC595 ดาวน์โหลดที่นี่

1. การประกาศและเริ่มต้นระบบ (Initiation)

#include <ez_switch_lib.h>
#include <ez_SIPO8_lib.h>

Switches my_switches(1); // จองพื้นที่สำหรับ 1 ปุ่มกด
SIPO8 my_SIPOs(num_dice, num_SIPO_timers); // จองพื้นที่สำหรับ SIPO IC 2 ตัว

ในส่วน setup() เราจะสร้าง "Bank" ของไอซี ซึ่งเปรียบเสมือนการรวมไอซี 2 ตัวเข้าเป็นกลุ่มเดียวกันเพื่อให้จัดการได้ง่ายขึ้นด้วยคำสั่งเดียว

2. ระบบตรวจสอบการทำงาน (Heart Beat Monitor)

วิศวกรฝังตัวที่ดีควรมีตัวบ่งชี้สถานะระบบ เราได้ใส่ฟังก์ชัน heart_beat เพื่อกะพริบไฟ LED ติดบอร์ด (Pin 13) ที่ความถี่ 1Hz หากไฟนี้ยังกะพริบอยู่ แสดงว่าลอจิกของโปรแกรมยังทำงานปกติ ไม่มีการค้าง (Hanging)

3. ฟังก์ชันสำคัญในการทำงาน

  • clear_pips(): ทำหน้าที่รีเซ็ตค่าใน Bank ทั้งหมดให้เป็น LOW (0) และส่งข้อมูลออกไปเพื่อดับ LED ทุกดวง
  • announce_throw(): สร้างลูกเล่นก่อนแสดงผลแต้มจริง (Strobe effect) โดยจะวิ่งไฟ LED เป็นแพทเทิร์นสั้นๆ เพื่อให้ผู้ใช้รู้สึกว่าลูกเต๋ากำลังถูกทอดอยู่
  • throw_dice(): นี่คือหัวใจของโปรแกรม ฟังก์ชันนี้จะ:
    1. สุ่มค่าแต้มลูกเต๋า 1-6 สำหรับลูกที่ 1 และ 2
    2. นำค่าที่สุ่มได้ไปดึง Pattern จาก Array pip_patterns
    3. เขียนค่าลงในหน่วยความจำเสมือนของไอซีแต่ละตัว (set_bank_SIPO)
    4. สั่งให้ส่งข้อมูลออกไปที่ขาจริงพร้อมกัน (xfer_bank) ด้วยโหมด MSBFIRST
// ตัวอย่างลอจิกการทอดลูกเต๋า
uint8_t die_face;
die_face = random(1, 104640) % faces_per_die; // สุ่มแต้ม
my_SIPOs.set_bank_SIPO(bank_id, die_1, pip_patterns[die_face]); // เตรียมข้อมูลลูกที่ 1
die_face = random(1, 104640) % faces_per_die; 
my_SIPOs.set_bank_SIPO(bank_id, die_2, pip_patterns[die_face]); // เตรียมข้อมูลลูกที่ 2
my_SIPOs.xfer_bank(bank_id, MSBFIRST); // แสดงผลออกทาง LED ทันที

4. Main Loop

ลูปหลักของโปรแกรมทำหน้าที่เพียงอย่างเดียวคือคอยเฝ้าดูสถานะของปุ่มกดผ่านไลบรารี my_switches หากมีการกดและปล่อยปุ่ม โปรแกรมจะกระโดดไปทำงานที่ฟังก์ชัน throw_dice() ทันที

void loop() {
  do {
    heart_beat(); // เลี้ยงสัญญาณชีพของระบบ
    if (my_switches.read_switch(switch_id) == switched) {
      throw_dice(); // เมื่อกดปุ่ม ให้ทอดลูกเต๋า
    }
  } while (true);
}

บทสรุป

ความท้าทายที่สุดของโปรเจกต์ภาค 2 นี้ไม่ใช่การเขียนโค้ด แต่เป็นการจัดการสายไฟ (Wiring) ระหว่าง 74HC595 และ LED ให้ถูกต้องตามผังวงจร อย่างไรก็ตาม เมื่อคุณเข้าใจหลักการทำงานของ Shift Register แล้ว คุณจะพบว่ามันเป็นเครื่องมือที่ทรงพลังมากในการขยายขีดความสามารถของไมโครคอนโทรลเลอร์

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

ข้อมูล Frontmatter ดั้งเดิม

title: "Two x six sided die sketch using 74HC595 ICs"
description: "A sketch to randomly 'roll' 2 dice, using serial-parallel input/output ICs in a cascaded design."
author: "ronbentley1"
category: "Gadgets, Games & Toys"
tags:
  - "sipo"
  - "die"
  - "dice"
  - "74hc595"
  - "ez_switch_lib"
  - "ez_sipo8_lib"
  - "games"
views: 4040
likes: 0
price: 1499
difficulty: "Intermediate"
components:
  - "1x Development Kit Accessory, Jumper Wire Kit"
  - "1x Solderless Breadboard Half Size"
  - "1x Jumper wires (generic)"
  - "1x Solderless Breadboard Full Size"
  - "1x Arduino UNO"
  - "14x Resistor 220 ohm"
  - "1x Tactile Switch, Top Actuated"
  - "14x 5 mm LED: Red"
tools: []
apps:
  - "1x Arduino IDE"
downloadableFiles:
  - "https://projects.arduinocontent.cc/6624b8ad-0d9d-4c13-ac52-9c6db7cc5218.ino"
  - "https://projects.arduinocontent.cc/6624b8ad-0d9d-4c13-ac52-9c6db7cc5218.ino"
documentationLinks: []
passwordHash: "6cb37e86d5cba479b40b42c84dcfab705a1203157a2602b752218dc1499af9da"
encryptedPayload: "U2FsdGVkX18HWNjPtP7aiDzqg5aOUO8wGlMSb9tOaPesM5ka6KJvPtF1sj6q2FAik/g2oTSMp9gx7h7X3P4d4OUCcsqotlI+SqUosTlzKco="
seoDescription: "Build a 2-dice roller using 74HC595 ICs and an Arduino sketch with a cascaded design."
videoLinks: []
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/two-x-six-sided-die-sketch-using-74hc595-ics-a8c6b9_cover.jpg"
lang: "en"