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

การใช้งาน 7 Segment กับ Arduino

การใช้งาน 7 Segment กับ Arduino Segment หลักเดียว

เมื่อ 2 ปีที่ผ่านมา

โดย เจ้าของร้าน

สวัสดีครับ ก่อนหน้านี้กลุ่ม Arduino Thailand ก็ได้มีคนมาสอบถามเรื่องการใช้งาน Arduino ร่วมกับ 7 Segment อยู่บ้าง แต่ว่าการตอบลงในกลุ่มแบบละเอียดก็คงจะไม่ค่อยสะดวกเท่าไหร่ บางครั้งที่ตอบไปผู้ถามก็เข้าใจบ้าง ไม่เข้าใจบ้าง ดังนั้นในบทความนี้จึงจะเน้นความ "ง่าย" อยู่เหนือทุกสิ่งครับ

7 Segment คืออะไร

7 Segment คือหน้าจอแสดงผลตัวเลข - ตัวอักษร (ได้บางตัว) ที่มีหน้าจอทำมาจากการจัดวางหลอด LED ในแนวยาว เมื่อทำให้หลอด LED แต่ละดวงติดพร้อมกัน ก็จะทำให้แสดงออกมาเป็นตัวเลขทรงเหลี่ยมได้

1. รูปร่างหน้าตาของ 7 Segment 1 หลัก (ขอบคุณรูปภาพจากเว็บไซต์ tandyonline.co.uk)

2. รูปแสดง 7 Segment ที่แสดงผลออกมาเป็นตัวเลขต่างๆ (ขอบคุณรูปภาพจาก maruen.tistory.com)

3. แสดงขาของ 7 Segment (ขอบคุณรูปภาพจาก projectcircuitpack.yolasite.com)

การแบ่งแยก 7 Segment

แบ่งตามขา Common

Common Anode - ขาคอมม่อนจะต้องต่ออยู่กับขั่วบวก แล้วขาอื่นๆ ต่ออยู่กับกราว์ด จึงจะทำให้ส่วนนั้นๆติดสว่างCommon Cathode - ขาคอมม่อนจะต้องต่ออยู่กับขั่วลบ แล้วขาอื่นๆ ต่ออยู่กับขั้วบวก จึงจะทำให้ส่วนนั้นๆติดสว่าง

แบ่งตามขนาด

7 Segment มีด้วยกันหลายขนาด ขนาดที่เป็นมาตรฐานใช้งานทั่วไปคือขนาด 0.56 นิ้ว มีขนาดเล็กกว่า หรือใหญ่กว่าให้เลือกใช้งานด้วย

แบ่งตามจำนวนตัวเลข

ใน 7 Segment อาจจะมีตัวเลขแสดงผลหลายๆตัวติดอยู่ด้วยกัน ทำให้การต่อวงจรง่ายมากยิ่งขึ้น

แบ่งตามสี

สีแดงสีเขียวสีอื่นๆ - ผสมสีเพื่อให้สีไม่เหมือนกันในแต่ละจุดได้

การสั่งงาน 7 Segment

7 Segment มีขาหลักๆอยู่ด้วยกันทั้งหมด 9 ขา คือ a b c d e f g dot และ common ในกรณีที่มีตัวเลขจำนวนหลักมากขึ้น ก็จะมีขา Common เพิ่มมากขึ้น เป็น com1 สำหรับควบคุมการแสดงผลหลักที่ 1 , com2 ควบคุมการแสดงผลหลักที่ 2 , com(n) ควบคุมการแสดงผลหลักที่ n

จากรูปที่ 2 จะเห็นว่าในแต่ละแถบยาว จะมีตัวอักษรกำกับอยู่ ซึ่งเป็นชื่อของขาที่ใช้ควบคุมแถบนั้น ตัวอย่างเช่น หากต้องการให้แสดงผลตัวเลข 1 จะต้องให้แถบ b และ c ติดสว่าง จึงจะได้เป็นรูปเลข 1 ที่สมบูรณ์ และหากต้องการให้ติดเลข 3 จะต้องให้แถบ a b c d และ g ติดสว่าง จึงจะทำให้แสดงเลข 3 ที่สมบูรณ์

การจะทำให้แถบแต่ละแถบติดสว่างได้ จะต้องทราบก่อนว่า 7 Segment นั้นเป็นคอมม้อนอะไร เมื่อทราบแล้วจะทำให้สามารถควบคุมการติดดับของแต่ละแถบได้ แบบเดียวกับการควบคุม LED โดยที่หากเป็นคอมม้อน Anode จะต้องต่อขาคอมม้นเข้ากับขั้วบวกของแหล่งจ่ายไฟ (5V) และหากต้องการให้แถบใดติดสว่าง จะต้องให้ขาของแถบนั้นต้องลงกราว์ด (เป็นลอจิก LOW หรือที่เรียกว่า ลอจิกศูนย์)

แต่ถ้าหากเป็นคอมม้อน Cathode จะต้องต่อขาคอมม้อนเข้ากับกราว์ด แล้วต่อขาของแถบที่ต้องการแสดงผลเข้าที่ขั้วบวกของแหล่งจ่าย (เป็นลอจิก HIGH หรือที่เรียกว่าลอจิกหนึ่ง)

ต่อวงจรใช้งานกับ Arduino

เพื่อความง่ายในการต่อวงจร และไม่ยุ่งยากในการเขียนโปรแแกรม ทำให้ในบทความนี้ผมเลือกที่จะใช้ขา 0 ถึงขา 6 ในการต่อร่วมกับ 7 Segment โดยเรียงให้ a - g ต่อเข้าที่ขา 0 - 7

กรณี Comon Anode

กรณี Comon Cathode

การเขียนโปรแกรม Arduino

ในการเขียนโปรแกรมจะอาศัยรีจิสเตอร์ DDRD และ PORTD ในการสั่งงาน ซึ่งจะง่ายกว่าการใช้งาน pinMode() และ digitalWrite() มาก เนื่องจากการเซ็คค่าเข้าไปในรีจิสเตอร์ PORTD จะทำให้สามารถสั่งขาตั้งแต่ขา 0 ถึงขา 7 ได้พร้อมๆกัน

ตามวงจรได้ต่อขา 0 - 6 ไว้กับขา a - g ดังนั้นหากต้องการแสดงเลข 1 จะต้องให้แถบ b และ c ติด ซึ่งจะต้องทำให้ขา b และ c เป็นลอจิก 0 ใน 7 Segment Comon Anode และขาอื่นๆเป็นลอจิก 1 หรือลอจิก 1 ใน 7 Segment Comon Cathode และขาอื่นๆเป็นลอจิก 0

เมื่อนำมาเรียงในเลขฐาน 2 จะได้เป็น

7 Segment Comon Anode

ขา gขา fขา eขา dขา cขา bขา aเลขฐาน 211110010B11111001

7 Segment Comon Cathode

ขา gขา fขา eขา dขา cขา bขา aเลขฐาน 200001100B00000110

แต่โดยปกติแล้วการนำเลขฐาน 2 ไปใส่ในโปรแกรมจะทำให้ซัพซ้อน และยาวมากเกินไป จึงนิยมทำเป็นเลขฐาน 16 มากกว่า ดังนั้นจึงได้

7 Segment Comon Anode : 0xF9

7 Segment Comon Cathode : 0x06

เมื่อนำไปเขียนโค้ดจะได้

void setup() {

  DDRD = 0xFF; // เซ็ตให้ขา 0 - 7 เป็นเอาต์พุต

  PORTD = 0xF9; // เซ็ตให้แสดงค่า 0xF9 ออกไป (แสดงเลข 1 ใน 7 Segment Comon Anode)

}

 

void loop() { }

หรือ

void setup() {

  DDRD = 0xFF; // เซ็ตให้ขา 0 - 7 เป็นเอาต์พุต

  PORTD = 0x06; // เซ็ตให้แสดงค่า 0xF9 ออกไป (แสดงเลข 1 ใน 7 Segment Comon Cathode)

}

 

void loop() { }

เมื่ออัพโหลดโค้ดลงไป ก็จะแสดงเลข 1 ออกทาง 7 Segment

หากต้องการแสดงเลขอื่นๆก็จะต้องทำแบบเดียวกัน คือ การพิจาณาแถบที่ต้องติด นำมาวางเป็นตาราง คิดเป็นเลขฐาน 2 แลัวแปลงเป็นเลขฐาน 16

แต่เพื่อความง่าย ผมได้คิดมาให้แล้ว และเอาลงอาร์เรย์ดังนี้

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

เวลาจะใช้งานก็ใช้คำสั่งเพียง PORTD = num[1]; ก็จะแสดงเลข 1 ออกมา และหากใช้เป็น PORTD = num[9]; ก็จะแสดงเลข 9 ออกมา ซึ่งโค้ดเต็มๆ คือ

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

void setup() {

  DDRD = 0xFF;

  PORTD = num[9];

}

 

void loop() { }

โค้ดด้านบนเป็นของ Common Cathode หากใช้แบบ Common Anode ก็ใส่เพียงเครื่องหมายกลับบิต (~) ไว้ด้านหน้าเท่านั้น

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

void setup() {

  DDRD = 0xFF;

  PORTD = ~num[9];

}

 

void loop() { }

เมื่ออัพโหลดโค้ดลงไป จะได้ผลออกมาดังรูปด้านล่างนี้

หมายเหตุ ในโปรแกรมจะไม่ใส่ตัวต้านทานเนื่องจากใส่ และไม่ใส่ผลที่ได้เป็นแบบเดียวกัน แต่เมื่อนำไปใส่ในวงจรจริงๆจำเป็นต้องใส่เพื่อป้องกันไม่ให้ 7 Segment มีกระแสไหลเกินแล้วพังเสียหายได้

Arduino and Motor Control : Part 1

Arduino and Motor Control : Part 1

เมื่อ 3 ปีที่ผ่านมา

โดย เจ้าของร้าน

วันนี้เรามาพูดถึงการควบคุมมอเตอร์กระแสตรงกันหน่อย  (ขอโฆษณานิดนะครับ ของที่ใช้ในการทำอยู่ในArduino Stater Kit 1)  แต่บอกไว้ก่อนนะครับ ผมกะจะเขียนบทความแบ่งออกเป็นตอนๆ โดยจะมีเนื้อหาในการควบคุมมอเตอร์ชนิดต่างๆ ดังนี้ครับ  

ง่ายสุดก็ DC motor หรือ มอเตอร์กระแสตรง  ซัก 2 ตอน  โดยว่ากันถึงการควบคุมทิศการหมุน และ การควบคุมความเร็วรอบต่อมาก็ Servo motor  ซัก 2 ตอน  และปิดท้ายด้วย Stepping Motor 2 ตอน ครับ

 วันนี้ก็ดูจะง่ายๆ ไปก่อนนะครับ Sketch ที่ใช้เป็นตัวอย่างผมไปเอามาจาก Arduino Cookbook โดยคุณ Michael Margolis นะครับ  แล้วมาเขียนเนื้อหาใหม่ โดยอธิบายให้ง่าย และลึกขึ้น  บอกไว้ก่อนเดี๋ยวจะมีคนหาว่าไปลอกมาอีก

   DC motor ประกอบด้วย 2 ส่วนหลักๆ ได้แก่ โรเตอร์ และสเตเตอร์ นะครับ  โรเตอร์ก็คือส่วนที่หมุน ส่วนสเตเตอร์คือส่วนที่เป็นขดลวดที่สร้างสนามแม่เหล็ก  

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

http://www.walter-fendt.de/ph14e/electricmotor.htm

  ทีนี้ในงานส่วนมาก เราต้องการควบคุมทิศทาง และ ความเร็วรอบของมอเตอร์  ไม่ว่าจะเป็นการขับเคลื่อนสายพาน หรือ ล้อของหุ่นยนต์   เพราะเราคงไม่ต้องการให้หมุนแบบอิสระควบคุมไม่ได้  ดังนั้นก็เลยมีคนคิดวงจรที่ใช้ในการควบคุมมอเตอร์ขึ้นมา  แบบที่นิยมใช้กันเรียกว่าวงจร "H-Bridge"

วงจรที่เห็นนี้ทำหน้าที่ได้ทั้งคุมทิศทางและความเร็วของมอเตอร์นะครับ   มาว่ากันทีละส่วน  เริ่มจากการคุมทิศทางการหมุนก่อนครับ

โดยปกติหากต้องการกลับทิศการหมุนของมอเตอร์กระแสตรง วิธีนึงที่ทำได้คือ กลับทิศแหล่งจ่าย  ทีนี้ลองดูที่รูปวงจร H-Bridge ด้านบนนะครับ

หากต้องการให้หมุนตามเข็ม (Clockwise :CW) ก็ให้ S1 และ S4 ปิดวงจร  และให้ S2 และ S3 เปืดวงจรหากต้องการให้หมุนทวนเข็ม (Conter Clockwise :CCW) ก็ให้ S2และ S3 ปิดวงจร  และให้ S1 และ S4 เปืดวงจร

จะเห็นว่าสวิตช์จะทำงานเป็นคู่นะครับ S1 คู่กับ S4 และ S2 คู่กับ S3 คู่แรกทำงาน คู่สองต้องเปิดวงจร และในทางตรงข้ามก็คือคู่สองทำงาน คู่แรกต้องเปิดวงจร   

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

 

 Schematic ขอวงจร H-Bridge ก็ตามนี้ครับ  จะใช้วงจรนี้ก็ต้องเชิญไปบ้านหม้อและซื้ออุปกรณ์ตามลิงค์นี้มาต่อวงจรกันเอานะครับ   แต่โชคดีที่เรามีทั้ง Motor Shield L293D  Motor Shield L298P    และ IC ที่มีวงจร H-Bridge ให้ครับ  ที่มีขายในบ้านเรามีให้เลือก 2 แบบ หลักๆ คือ L293D และ L298P ครับ  สองตัวนี้ต่างกันอย่างไรเหรอครับ  ก็ที่ขนาดของกระแสที่รับได้  ซึ่งหมายถึงขนาดของมอเตอร์ที่ใช้นะครับ  

ถ้ามากกว่านี้เหรอครับ  คงต้องต่อกันเอาเองแล้วครับ แต่จริงๆ ก็ไม่ได้ยากอะไรขนาดนั้นครับ แค่ต่อตาม Schematic เท่านั้น  แต่แหม เลือกได้คงไม่ต่อเองใช่รึเปล่าครับ

วันนี้ลองมาใช้ L293D ทีให้มาใน Arduino Stater Kit 1ของร้าน Arduitronics เพื่อทดลองคุมทิศทางการหมุนดูนะครับ

   ก่อนอื่นเริ่มจากการต่อวงจรก่อนครับ ก็ต่อตามภาพด้านล่างนี้ครับ (ภาพจาก Arduino Cookbook by Michael Margolis)

ในตัวอย่างนี้ผมใช้ถ่าน 9 V เป็นแหล่งจ่ายนะครับ  อย่าใช้ 5 V จาก Board เป็นแหล่งจ่ายนะครับ เพราะ Port ของ Arduino จ่ายกระแสได้แค่ 50 mA เท่านั้น  อาจจะทำให้บอร์ดพังได้ครับ

Sketch ก็ตามนี้นะครับ

/*
 * Brushed_H_Bridge_simple2 sketch
 * commands from serial port control motor direction
 * + or - set the direction, any other key stops the motors
 */
const int in1Pin = 5;  // H-Bridge input pins
const int in2Pin = 4;
const int in3Pin = 3;  // H-Bridge pins for second motor
const int in4Pin = 2;
void setup()
{
  Serial.begin(9600);
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);
  Serial.println("+ - sets direction of motors, any other key stops motors");
}
void loop()
{
  if ( Serial.available()) {
    char ch = Serial.read();
    if (ch == '+')
    {
      Serial.println("CW");
      // first motor
      digitalWrite(in1Pin,LOW);
      digitalWrite(in2Pin,HIGH);
      //second motor
      digitalWrite(in3Pin,LOW);
      digitalWrite(in4Pin,HIGH);
      
    }
    else if (ch == '-')
    {
      Serial.println("CCW");
      digitalWrite(in1Pin,HIGH);
      digitalWrite(in2Pin,LOW);
      digitalWrite(in3Pin,HIGH);
      digitalWrite(in4Pin,LOW);
    }
    else
    {
      Serial.print("Stop motors");
      digitalWrite(in1Pin,LOW);
      digitalWrite(in2Pin,LOW);
      digitalWrite(in3Pin,LOW);
      digitalWrite(in4Pin,LOW);
    }
  }
}

ถ้าทุกอย่างถูกต้องไม่มีปัญหา จะได้หน้าจอ Serial Monitor ดังนี้ครับ  โดยจะเห็นมอเตอร์หมุนทิศนึงตอนกด "+" และทิศตรงข้ามถ้ากด "-"  ถ้ากดอย่างอื่นจะหยุดหมุนครับ

 

วันนี้ขอเท่านี้ก่อนนะครับ สัปดาห์หน้ามาต่อภาค 2  เรื่องการควบคุมความเร็วครับ

 

 

 

 โดย  Mountain "A"