วันจันทร์ที่ 23 กรกฎาคม พ.ศ. 2561

การใช้งาน 7 Segment

การใช้งาน 7 Segment กับ Arduino ตอนที่ 2 7 Segment 4 หลัก


1. รูปแสดง 7 Segment 4 Digit (ขอบคุณรูปภาพจาก tandyonline.co.uk)
การใช้งาน 7 Segment แบบหลายหลัก สามารถควบคุมได้แบบเดียวกับ 7 Segment แบบหลักดียว แต่มีขา Common เพิ่มขึ้นมา เพื่อควบคุมให้ 7 Segment หลักที่ต้องการติดขึ้นมา โดยอาศัยหลักการที่ว่า การแสดงผลตัวเลขในแต่ละหลักสลับกันไปแบบรวดเร็ว (ระดับ 50mS - 1mS) จะทำให้ดวงตาของเราไม่สามารถสังเกตุเห็นการสลับการแสดงผลได้ทัน ทำให้เรามองเห็นตัวเลขติดพร้อมๆกันในทุกๆหลัก ทั้งๆที่ในเสี้ยววินาทีนั้นมีตัวเลขติดแค่หลักเดียว
2. รูปแสดงหลักการแสดงผลตัวเลขของ 7 Segment หลายหลัก (ขอบคุณรูปภาพจาก antronics.co.uk)
3. รูปแสดงขาของ 7 Segment 4 Digit (ขอบคุณภาพจาก arduino.fisch.lu)
การสั่งให้ 7 Segment แสดงผลตัวเลขออกมาในแต่ละหลักจะใช้การควบคุมขา Common
  • Common Anode - ขาคอมม่อนจะต้องได้รับลอจิก 1 ตัวเลขจึงจะแสดงผล
  • Common Cathode - ขาคอมม่อนจะต้องได้รับลอจิก 0 ตัวเลขจึงจะแสดงผล
โดยที่การแสดงผลตัวเลขที่หลักใดๆก็ตาม หลักอื่นๆจะต้องไม่มีการแสดงผล หากมีการแสดงผลหลายๆหลักพร้อมกันจะทำให้การแสดงผลตัวเลขไม่สมบูรณ์ (มองไม่เป็นตัวเลข)
การต่อวงจรใช้งานกับ Arduino
ทั้งแบบ Common Anode และ Common Cathode ต่อใช้งานแบบเดียวกัน แต่จะแตกต่างกันในส่วนของโค้ดโปรแกรม
โค้ดโปรแกรม Arduino
เนื่องจากการจะเขียนโปรแกรมให้ภายในลูป (loop function) นั้นจัดการการแสดงผลตัวเลขไปพร้อมๆกับการประมวลผลอื่นๆจะทำให้ค่อนข้างที่จะเขียนโค้ดได้ยาก ดังนั้นเพื่อให้ง่ายต่อการเขียนโค้ด จึงต้องใช้อินเตอร์รัพท์ภายในเข้ามาเกี่ยวข้อง ซึ่งอินเตอร์รัพท์นี้จะช่วยแสดงผลตัวเลขได้ตลอดเวลา แม้ภายในฟังก์ชั่นหลัก (loop setup function) จะทำงานอย่างอื่น เช่น ติด delay() อยู่ก็ตาม การแสดงผลตัวเลขก็ยังดำเนินต่อไปแบบไม่มีปัญหา
เนื่องจากการใช้อินเตอร์รัพท์แบบภายในค่อนข้างยุ่งยากในการใช้งาน ดังนั้นจึงต้องใช้ไลบารี่ TimerOne เข้ามาเกี่ยวข้อง เพื่อความง่ายในการใช้งาน
สามารก๊อบโค้ดด้านล่างอัพลงบอร์ด Arduino แล้วดูผลการทำงานได้เลย
#include "TimerOne.h"

int D1 = 8;
int D2 = 9;
int D3 = 10;
int D4 = 11;
int CommonAK = 1; // Common Anode set to 1, Common Cathode set to 2

int num[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F };
int OnDigi = 0;
int NumberDisplay = 0;
bool ColonShow = false;


void setup() {
  // put your setup code here, to run once:
  Begin7Segment4Digi();
  NumberDisplay = 2558;
}

void loop() {
  
}

void Begin7Segment4Digi() {
  DDRD  = 0xFF;
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);
  pinMode(D4, OUTPUT);
  digitalWrite(D1, (CommonAK==1 ? LOW : HIGH));
  digitalWrite(D2, (CommonAK==1 ? LOW : HIGH));
  digitalWrite(D3, (CommonAK==1 ? LOW : HIGH));
  digitalWrite(D4, (CommonAK==1 ? LOW : HIGH));
  Timer1.initialize(1000); // 1000 = 1mS
  Timer1.attachInterrupt(NextDigi);
}

void NextDigi() {
  digitalWrite(D1, (CommonAK==1 ? LOW : HIGH));
  digitalWrite(D2, (CommonAK==1 ? LOW : HIGH));
  digitalWrite(D3, (CommonAK==1 ? LOW : HIGH));
  digitalWrite(D4, (CommonAK==1 ? LOW : HIGH));
  int ShowOn = 0;
  OnDigi = (OnDigi==4 ? 1 : OnDigi+1);
  if (OnDigi==1) {
    if (NumberDisplay<10)
      ShowOn = NumberDisplay;
    else
      ShowOn = NumberDisplay%10;
  } else if (OnDigi==2) {
    if (NumberDisplay<10)
      ShowOn = 0;
    if (NumberDisplay<100)
      ShowOn = NumberDisplay/10;
    if (NumberDisplay<1000)
      ShowOn = (NumberDisplay/10)%10;
    if (NumberDisplay<10000)
      ShowOn = (NumberDisplay/10)%10;
  } else if (OnDigi==3) {
    ShowOn = (NumberDisplay / 100) % 10;
  } else if (OnDigi==4) {
    ShowOn = NumberDisplay / 1000;
  }
  if (CommonAK==1)
    PORTD = ~((num[ShowOn])|(ColonShow&&OnDigi==3 ? 0x80 : 0));
  else
    PORTD = ((num[ShowOn])|(ColonShow&&OnDigi==3 ? 0x80 : 0));
  if (OnDigi==1) {
    digitalWrite(D1, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D2, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D3, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D4, (CommonAK==1 ? HIGH : LOW));
  } else if (OnDigi==2) {
    digitalWrite(D1, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D2, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D3, (CommonAK==1 ? HIGH : LOW));
    digitalWrite(D4, (CommonAK==1 ? LOW : HIGH));
  } else if (OnDigi==3) {
    digitalWrite(D1, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D2, (CommonAK==1 ? HIGH : LOW));
    digitalWrite(D3, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D4, (CommonAK==1 ? LOW : HIGH));
  } else if (OnDigi==4) {
    digitalWrite(D1, (CommonAK==1 ? HIGH : LOW));
    digitalWrite(D2, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D3, (CommonAK==1 ? LOW : HIGH));
    digitalWrite(D4, (CommonAK==1 ? LOW : HIGH));
  }
}
จากโค้ด หากต้องการเปลี่ยนตัวเลขเป็นตัวเลขใดๆที่แสดงผลในหน้าจอ เพียงแค่เซ็ตตัวแปร NumberDisplay เป็นตัวเลขที่ต้องการ (ไม่เกิน 4 หลัก) ก็จะทำให้ตัวเลขที่แสดงผลเปลี่ยนไป
  • Common Anode - เซ็ตให้ CommonAK = 1
  • Common Cathode- เซ็ตให้ CommonAK = 2
หากต้องการให้เครื่องหมายโคล่อน (:) ติด หรือดับ สามารถควบคุมได้โดยเซ็ตให้ตัวแปร ColonShow เป็น true หรือ false

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

งาน5 ในสถานที่ฝึกงานของ นักศึกษา ใช้ระบบควบคุมคุณภาพอย่างไร

Quality Assurance (QA) กับ Quality Control (QC) QC (Quality Control) หมายถึง  การควบคุมคุณภาพสินค้าให้เป็นไปตามคุณสมบัติที่กำหนดไว้  และส...