باس I2C برای ارتباطات بین یک میکروکنترلر و قطعات دیگر همانند یک LCD بکاربرده میشود. باس رابط دو سیم I2C (TWI) صرفنظر از تعداد دستگاهها از دو خط سیگنال استفاده میکند: داده سریال (SDA) و کلاک سریال (SCL).
میکروکنترلر با تمامی دستگاهها ارتباط برقرار میکند و این پیام شامل آدرس دستگاه موردنظر است، از این رو تنها دستگاه مربوطه به آن پاسخ میدهد. جفت پینهای I2C آردوینو، A4 برای SDA و A5 برای SCL میباشند. یک باس I2C تعداد پینهای ورودی آردوینو برای ارتباط با یک LCD را از ۶ به ۲ کاهش میدهد. کنتراست صفحه نمایش LCD با یک پتانسیومتر باس I2C کنترل میشود. میتوان برای خاموش کردن بلک لایت LCD جامپر انتهای باس I2C را قطع کرد.
میکروکنترلر برای ارتباط با گذرگاه I2C به آدرس هگز باس I2C نیاز دارد. آدرس I2C برای سنسورها و ماژولها در the-list https://learn.adafruit.com/i2c-addresses/ موجود میباشد. کدهای زیر آدرس تمام رابطهای I2C متصل به آردوینو را نمایش میدهند. در ارسال به رابط I2C، قطعه “0” را برای نشان دادن یک ارسال موفق برمیگرداند، در حالیکه، برای مثال بازگشت “4” نشاندهنده خطا است. در لیست زیر آدرسهای I2C از 0x00 تا 0x07 و ox78 تا 0x7F رزور شدهاند، بنابراین برای شناسایی رابط I2C اسکن نمیشوند.
#include
int device = 0; // include Wire library
// set device counter to 0
void setup()
{
Serial.begin (9600);
Wire.begin();
for (int i=8; i<120; i++)
{
Wire.beginTransmission (i); // set Serial output baud rate
// start I2C bus
// scan through channels 8 to 119
// transmit to device at address i
if (Wire.endTransmission () == 0) // device response to transmission
{
Serial.print("Address 0x");
Serial.println(i, HEX);
device++;
delay(10);
}
}
Serial.print(device);
// print to screen "Address 0x"
// print to screen I2C address in HEX
// increment device count
// delay 10ms
// print to screen device count
Serial.println(" device found"); // print to screen " device found"
}
void loop()
{} // nothing in void loop() function
I2C با سنسور دما و فشار
برای نمایش اتصال بیش از یک رابط I2C به برد آردوینو، دما و فشار خواندهشده از سنسور BMP280 که از طریق I2C یا SPI با برد آردوینو ارتباط برقرار میکند برروی LCD نمایش داده میشود. سنسور BMP280 دمای بین ℃ ۸۵ تا ۴۰- را با دقت ℃ ۰.۰۱± و فشار را با دقت hPa ۰.۱۲ ± اندازهگیری میکند. چندین کتابخانه برای سنسور BMP280 در IDE آردوینو وجود دارد. برای این منظور کتابخانههای Adafruit BMP280 و Adafruit Unified Sensor را با استفاده از روش سوم نصب کنید.
از آنجایی که برد آردینو با ۵ ولت و سنسور BMP280 در ۳.۳ ولت کار میکند، برای کاهش ولتاژ سیگنال فرستادشده از آردوینو یک مبدل سطح منطقی (LLC) موردنیاز میباشد. در سمت ولتاژ پایین پینهای SDI و SCK به ترتیب به پینهای TX و RX مبدل سطح منطقی متصل میشوند (شکل.۱ را مشاهده کنید). در سمت ولتاژ بالا، پینهای TX و RX مبدل سطح منطقی به پینهای I2C آردوینو، به ترتیب به A4 (SDA) و A5 (SCK) متصل میشوند. پایه SD0 BMP280 را باید به زمین متصل کرد. به دلیل اتصال پایه SD0 به زمین آدرس I2C سنسور BMP280 0x76 میباشد، ولی در حالت پیش فرض این آدرس برابر 0x77 است.
کتابخانه LiquidCrystal_I2C در IDE آردوینو وجود دارد و با استفاده از روش سوم نصب میشود. در IDE آردوینو مسیر Sketch->Include->Manage libraries را انتخاب و LiquidCrystal_I2C را وارد کرده، سپس برروی More Info کلیک کنید. آخرین ورژن را انتخاب و Install کنید.
پس از اتصال باس I2C و سنسور BMP280 (جدول.۱ را مشاهده کنید)، آدرس باس I2C 0x3F است. اسکس با وجود کتابخانههای Wire و LiquidCrystal_I2C، LCD را مقداردهی اولیه میکند. اسکچ از طریق بافر مانیتور سریال زمان، دما و فشار فعلی را با ساعت و دقیقههای اولیه واردشده نمایش میدهد. دستور while (Serial.available()>0) تضمین میکند که کل بافر سریال خوانده شده است. دستور ()Serial.parseInt تا زمانیکه مقدار غیرعددی وارد بافر سریال شود اعداد صحیح را از بافر سریال میخواند و سپس مقادیر عددی قبلی را به عددی صحیح تبدیل میکند. در این اسکچ، کامای پس از ساعت متغیر غیرعددی موردنیاز تابع ()Serial.parseInt است.
دستور مشابه () Serial.parseFloat، اعداد حقیقی را از بافر سریال میخواند. در اسکچ، تابع ()void setup ، متن ثابت را برروی LCD نمایش میدهد، آپدیت دما، زمان و فشار در تابع ()void loop اتفاق میافتد.
جدول 1. اتصالات LCD با باس I2C و سنسور BMP280
کد LCD با باس I2C و سنسور BMP280
#include // include Wire library
#include // include LiquidCrystal_I2C library
int I2Caddress = 0x3F; // I2C address of I2C bus
int LCDcol = 16; // number of LCD columns
int LCDrow = 4; // number of LCD rows
LiquidCrystal_I2C lcd(I2Caddress,LC Dcol,LCDrow); // I2C address
// and LCD size
#include // include Unified Sensor library
#include // include BMP280 library
Adafruit_BMP280 bmp; // associate bmp with Adafruit_BMP280 library
int BMPaddress = 0x76; // I2C address of BMP280
int sec = 0;
int min, hour;
float temp, pressure;
void setup()
{
lcd.init(); // initialise LCD
bmp.begin(BMPaddress); // initialise BMP280 sensor
Serial.begin(9600); // define Serial output baud rate
Serial.print("Enter time as hh,mm"); // print text to screen
lcd.setCursor(0,0); // move cursor to column 1 row 1
lcd.print("Current"); // print "Current" to LCD
lcd.setCursor(0,1); // move cursor to column 1 row 2
lcd.print("time"); // print "time" to LCD
lcd.setCursor(0-4,2); // move cursor to column 1 row 3
lcd.print("temp"); // and reduce col by 4 for 3rd and 4th rows
lcd.setCursor(0-4,3); // move cursor to column 1 row 4
lcd.print("pres");
}
void loop()
{
while (Serial.available()>0) // read data in Serial buffer
{
hour = Serial.parseInt(); // first integer in Serial buffer is hours
min = Serial.parseInt(); // second integer in buffer is minutes
}
sec++; // short for sec = sec + 1
if(sec>59) // increase minutes when seconds = 60
{
sec = 0; // reset seconds to 0
min++; // increase minutes by 1
}
if(min>59) // increase hours when minutes = 60
{
min = 0; // reset minutes to 0
hour++; // increase hours by 1
}
if(hour>23) hour = 0; // set hours to 0 when hours = 24
lcd.setCursor(6, 1); // move cursor to column 6 row 2
if(hour < 10) lcd.print(" "); // spacing for hours < 10
lcd.print(hour); // print hour to LCD
lcd.print(":"); // print ":" to LCD
if(min<10) lcd.print("0"); // leading zero for minutes < 10
lcd.print(min); // print minutes to LCD
lcd.print(":");
if(sec<10) lcd.print("0"); // leading zero for seconds < 10
lcd.print(sec); // print seconds to LCD
temp = bmp.readTemperature(); // read temperature from sensor
pressure = bmp.readPressure()/100.0; // read pressure from sensor
lcd.setCursor(6-4,2); // move cursor to column 6 row 3
lcd.print(temp, 1); // print temperature to LCD to 1DP
lcd.print(char(178)); // print degree character to LCD
lcd.print("C");
lcd.setCursor(6-4,3); // move cursor to column 6 row 4
lcd.print(pressure, 1); // print pressure to LCD to 1DP
lcd.print(" hPa");
delay (1000); // delay 1000ms
}