Arduino และการหา address สำหรับอุปกรณ์ที่สื่อสารกันผ่าน i2c interface

การหา address ของ I2C บน Arduino Uno

การหา address ของ I2C บน Arduino Uno

ที่มาและความสำคัญ. การเรียนรู้ไมโครคอนโทรลเลอร์ Arduino uno เป็นการเรียนรู้ไมโครขั้นพื้นฐานหากเราศึกษาไปเรื่อยๆเรามักจะมีองค์ประกอบของการใช้งานโมดูอื่นๆเข้ามาเกี่ยวข้อง และเป็นการสื่อสารด้วย interface แบบต่างๆ หนึ่งใน interface ที่มักนิยมใช้งานพบได้บ่อยครั้งคือ interface แบบ i2c ด้วยจุดเด่นต่างๆเช่นความง่าย,สายเชื่อมต่อน้อย,มีไรบรารี่เยอะ หากถามว่าข้อดีข้องการสื่อสารนี้มีข้อดีอย่างไรไปหาอ่านเพิ่มเติมเอาเองขี้เกียจพิมพ์ – -! เราจะข้ามมาที่กระบวนการหาตำแหน่งที่อยู่ของโมดูลหรืออุปกรณ์เลยละกัน เพราะเมื่อเราต่อโมดูลหรืออุปกรณ์นั้นๆแล้ว ลองใช้ code ที่อยู่ใน internet แล้วผลปรากฏไม่สามารถใช้งานได้ หนึ่งในปัญหาที่พบบ่อยคือการระบุที่อยู่ไม่ถูกต้องนั้นเอง เราจึงจำเป็นต้องหาตำแหน่งที่อยู่ก่อนถึงจะเริ่มการเขียน code เพื่อใช้งานกับโมดูลหรืออุปกรณ์ได้ .

การหา address ของอุปกรณ์ I2C บน Arduino Uno สามารถทำได้ด้วยการใช้โค้ดที่เรียกว่า “I2C Scanner” ซึ่งจะทำการสแกนหา address ของอุปกรณ์ I2C ที่เชื่อมต่ออยู่บนบัส I2C ทั้งหมด โค้ดนี้สามารถช่วยให้เราทราบ address ของอุปกรณ์แต่ละตัวที่เชื่อมต่ออยู่ได้

โค้ด I2C Scanner


#include <Wire.h>

void setup() {
  Wire.begin(); // เริ่มการทำงานของ I2C
  Serial.begin(9600); // เริ่มการทำงานของ Serial
  while (!Serial); // รอให้ Serial พร้อม
  Serial.println("I2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for (address = 1; address < 127; address++ ) {
    // ส่งข้อมูลการร้องขอไปยังอุปกรณ์ที่ address นี้
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");

      nDevices++;
    } else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000); // รอ 5 วินาที ก่อนเริ่มการสแกนใหม่
}

    

การอธิบายโค้ด

  1. การเรียกใช้งานไลบรารี:
    #include <Wire.h>

    บรรทัดนี้เป็นการเรียกใช้งานไลบรารี Wire.h ที่จำเป็นสำหรับการสื่อสารผ่าน I2C

  2. การตั้งค่าเริ่มต้นในฟังก์ชัน setup():
    
    void setup() {
      Wire.begin();
      Serial.begin(9600);
      while (!Serial);
      Serial.println("I2C Scanner");
    }
                
    • Wire.begin() เริ่มการทำงานของ I2C
    • Serial.begin(9600) เริ่มการทำงานของ Serial communication ที่ baud rate 9600
    • while (!Serial); รอให้ Serial พร้อมใช้งาน
    • Serial.println("I2C Scanner"); พิมพ์ข้อความ “I2C Scanner” ไปยัง Serial Monitor

  3. ฟังก์ชัน loop() สำหรับการสแกน address:
    
    void loop() {
      byte error, address;
      int nDevices;
    
      Serial.println("Scanning...");
    
      nDevices = 0;
      for (address = 1; address < 127; address++ ) {
        Wire.beginTransmission(address);
        error = Wire.endTransmission();
    
        if (error == 0) {
          Serial.print("I2C device found at address 0x");
          if (address < 16)
            Serial.print("0");
          Serial.print(address, HEX);
          Serial.println("  !");
    
          nDevices++;
        } else if (error == 4) {
          Serial.print("Unknown error at address 0x");
          if (address < 16)
            Serial.print("0");
          Serial.println(address, HEX);
        }
      }
      if (nDevices == 0)
        Serial.println("No I2C devices found\n");
      else
        Serial.println("done\n");
    
      delay(5000);
    }
                
    • ในฟังก์ชันนี้จะทำการสแกน address ทั้งหมดจาก 1 ถึง 126 (0x01 ถึง 0x7E)
    • Wire.beginTransmission(address) เริ่มการส่งข้อมูลไปยัง address นั้น
    • error = Wire.endTransmission() จบการส่งข้อมูลและเก็บผลการส่งไว้ในตัวแปร error
    • ถ้า error == 0 หมายถึงอุปกรณ์ที่ address นั้นตอบกลับมาซึ่งหมายความว่ามีอุปกรณ์อยู่ที่ address นั้น
    • ถ้า error == 4 หมายถึงมีข้อผิดพลาดที่ไม่ทราบสาเหตุ
    • ถ้าไม่พบอุปกรณ์เลย จะพิมพ์ข้อความ “No I2C devices found”

diagram การสื่อสารระหว่าง arduino และอุปกรณ์ต่างๆผ่าน i2c interface

จากรูปไดอแกรมจะเป็นได้ว่ารูปแบบของการสื่อสาร i2c นั้นเรียบง่ายเพราะใช้สายสัญญาณเพียงสองเส้นเท่านั้นคือ SDA(Serial Data Line) ใช้ในการส่งผ่านข้อมูลและ Serial Clock Line (SCL) ใช้กำหนดสัญญาณนาฬิกาของการส่งข้อมูล


ตัวอย่างในการทำงาน ณ ที่นี้จะยกกรณีที่มีการเชื่อมต่ออุปกรณ์ 2 ตัวด้วยการสื่อสาร i2c

จากรูป เราจะเห็นว่าการเชื่อมต่อโมดูลจำนวนสองโมดูลซึ่งทั้งสองโมดูลนี้สื่อสารกับไมโครคอนโทรลเลอร์ด้วย i2c interface มีการต่อใช้งานสายสัญญาณสองเส้นเหมือนกัน ณ ตำแหน่งขา sda ,scl ด้วยกันและจะคุยกันเมื่อส่ง address ไปยังอุปกรณ์ที่ถูกต้อง นั้นหมายความว่าโมดูลแต่ละโมดูลจะมี address เป็นของตัวเองเพื่อให้ในการสื่อสารจากนั้นใน code ที่กล่าวมาข้างต้นจะปรากฎ address ของแต่ละโมดูล,อุปกรณ์.


วีรภัทร : ผู้เขียน
วีรภัทร : เรียบเรียง