اتصال چند ماژول با آدرس‌های مشابه I2C به آردوینو توسط TCA9548A

فهرست مطالب

مقدمه

آیا تاکنون خواسته‌اید از 2 سنسور با آدرس I2C مشابه به طور همزمان استفاده کنید؟ قطعا برای این کار با چالش‌هایی روبه رو شده‌اید؟

در پروژه‌های بسیاری، قطعات و سنسورهایی را توسط پروتکل ارتباطی I2C راه‌اندازی کرده‌ایم. همچنین گاهی اوقات از چند سنسور توسط پروتکل I2C در ارتباط با میکروکنترلر در پروژه خود بهره برده‌ایم. اگر آدرس I2C همه آنها با یکدیگر متفاوت بود، می‌توانستیم به راحتی انتقال دیتا با آنها را انجام دهیم. اما اگر آدرس I2C حتی دو سنسور مشابه بود، در انتقال دیتا با این دو سنسور به مشکل برمی‌خوردیم. این مشکل، مسئله بسیار مهمی است که احتمال زیاد با آن روبه‌رو شده‌اید. اگر به این مشکل برخورده‌اید پس مطالعه این آموزش قطعا برایتان مفید خواهد بود.

این مشکل به دو صورت نرم‌افزاری و سخت‌افزاری قابل حل می‌باشد. در این آموزش قصد داریم راه‌حلی سخت‌افزاری برای حل این مشکل ارائه کنیم. برای حل آن، ماژول توسعه TCA9548A را اضافه کرده و سنسورهای با آدرس I2C مشابه را از طریق آن به آردوینو متصل می‌کنیم.

آنچه در این آموزش یاد می‌گیرید

همانطور که بیان شد، چالش مهم در مورد پروتکل I2C اتصال چند سنسور با آدرس های مشابه به آردوینو و یا هر میکروکنترلر دیگری می‌باشد.

در این آموزش ابتدا به سراغ راه‌اندازی دو سنسور دما و رطوبت GY-21  و LM75 با آدرس‌های I2C متفاوت رفته و دمای آن‌ها را با یک نمایشگر OLED که آن هم دارای ارتباط I2C است، نمایش می‌دهیم. کتابخانه‌های آن‌ها را با هم ترکیب کرده و دمای هر دو سنسور را بر روی نمایشگر نشان می‌دهیم.
سپس ماژول توسعه I2C با نام TCA9548A را به مدار اضافه می‌کنیم. اما در این مرحله از سه سنسور GY-21 ، SHT20 و HTU21D با آدرس های I2C مشابه استفاده می‌کنیم. تغییراتی در برنامه ایجاد کرده و دمای اندازه‌گیری شده توسط سه سنسور را بر روی نمایشگر OLED نمایش می‌دهیم.

عکس زیر گویای نتایج خروجی می‌باشد. در ادامه و انتهای آموزش قادر خواهید بود اطلاعات 3 سنسور دما با آدرس‌های مشابه I2C را مانند تصویر زیر بر روی نمایشگر OLED نمایش دهید.

پروتکل I2C چیست و چگونه کار می کند؟

 Inter-Integrated Circuit یک پروتکل ارتباطی است که آنرا با نام‌های دیگری مانند IIC و I2C و… نیز نمایش می‌دهند. این پروتکل به طور گسترده در میکروکنترلرها کاربرد دارد. در این ارتباط Master ها و Slave ها (Master ها عموما تجهیزات اصلی مانند میکروکنترلرها و Slave ها سنسورها و دیگر تجهیزات مدار هستند.) از طریق دو سیم با هم در ارتباط هستند:

  • SDA(Serial Data): خطی برای ارسال و دریافت دیتا و اطلاعات بین Master و Slave
  • SCL(Serial Clock): خطی برای ارسال کلاک
نکته

در آردوینو UNO پایه SDA ،A4 و پایه A5 نیز SCL می‌باشد.

برای بردهای دیگر و همچنین میکروکنترلرهای مختلف این پایه‌ها متفاوت می‌باشد. به راحتی می‌توانید از دیتاشیت، شماره پایه های I2C آنها را پیدا کنید.

از مهمترین ویژگی‌های پروتکل I2C عبارت است از:

  • خیلی سریع نمی‌باشد (اما برای استفاده از آن به اندازه کفایت سرعت دارد.)
  • مناسب برای فواصل کوتاه (برای مثال فاصله مجاز در سرعت پایین 100KHz حدود یک متر است)
  • این ارتباط سنکرون می‌باشد.
  • اطلاعات به صورت سریال ارسال می‌گردد.
  • سطح ولتاژ آن 5 یا 3.3 ولت می‌باشد.

در پروتکل I2C دو نوع تجهیز برای اتصال به باس I2C وجود دارد: Master و Slave. در این ارتباط هم می‌توان چند Slave متفاوت را به یک عدد Master مانند یک میکروکنترلر متصل کرد و هم می‌توان یک Slave را از طریق چند Master مختلف کنترل و مانیتور نمود، اما در هر لحظه فقط یک Master می‌تواند فعال باشد. هر Master می‌تواند انتخاب کند که با کدام یک از Slave ها می‌خواهد ارتباط برقرار کند. این انتخاب از طریق آدرس‌های 7 بیتی Slave ها (در بعضی موارد 10 بیت) مشخص می‌شود. پس تقریبا می‌توان حدود 128 عدد تجهیز Slave را به باس I2C متصل کرد. بنابراین هر Slave آدرس مخصوص خود را دارد و در ضمن آدرسی برای Master ها اختصاص داده نشده است.
دیتای ارسال شده بر روی باس I2C توسط پایه کلاک، سنکرون می‌شود. عمل سنکرون‌سازی توسط پایه کلاک بر عهده Master می‌باشد.

نکته

دو پایه SDA و SCL در مدار بایستی Pull-Up شوند. در سرعت‌های بالا مانند 400kbps مقاومت 2KΩ کافی است و در سرعت‌های پایین‌تر مثل 100kbps مقاومت 10KΩ استفاده می‌شود.

نحوه عملکرد I2C

دیتای انتقالی بین دو تجهیز در بر روی خط SDA در پروتکل I2C شامل بخش‌های زیر می‌باشد:

  • Start: ابتدا خط SDA از سطح ولتاژ به سطح ولتاژ LOW تغییر می‌کند. سپس و در ادامه آن خط SCL نیز به همین صورت تغییر می‌کند.
  • Addressشامل 7 بیت (در بعضی موارد 10 بیت) آدرس سنسوری است که Master قصد ارتباط با آن را دارد. این 7 بیت همواره از طرف Master به سمت Slave می‌شود. بعد از ارسال آدرس، هر Slave این آدرس را با آدرس خودش مقایسه کرده و در صورت تطابق، یک بیت (ACK Bit) با وضعیت LOW را به سمت Master ارسال می‌کند.
  • R/W Bit: این بیت که همراه 7 بیت آدرس فرستاده می‌شود(کم‌ارزش‌ترین بیت یا همان LSB می‌باشد.)، مشخص می‌کند که آیا Master فرستنده است یا گیرنده. اگر این بیت HIGH باشد، Master گیرنده و اگر LOW باشد، فرستنده است.
  • : ACK/NACK Bit بعد از اینکه هر اطلاعات 8 بیتی توسط Master و یا Slave دریافت شد، سمت گیرنده توسط این بیت اعلام می‌کند که آیا اطلاعات 8 بیتی به درستی به آن رسیده است یا خیر. اگر گیرنده این بیت را به درستی دریافت کند، حالت Acknowledge است و یک بیت با سطح ولتاژ LOW را به خط SDA ارسال می‌کند.
  • Date: پس از اینکه برای اولین بار بیت ACK ارسالی از طرف Slave توسط Master به درستی شناسایی شد، اولین بایت دیتا آماده ارسال می‌شود. دقت شود که انتهای ارسال هر بایت دیتا توسط فرستنده، گیرنده بایستی برای تایید دریافت دیتا، بیت ACK را در وضعیت LOW قرار دهد.
  • Stop: پس از اتمام انتقال دیتاهای موردنظر، ابتدا خط SCL از وضعیت LOW به HIGH و سپس خط SDA از وضعیت LOW به HIGH تغییر می‌کند.
نکته

تعداد بایت‌های Data محدودیت خاصی ندارند.

نحوه انتقال دیتا در باس I2C

دیتا و اطلاعات دائما در باس I2C بین Slave ها و Master ها در تبادل می‌باشد. همانطور که گفته شد، تجهیز Master ارتباط در باس I2C را آغاز کرده و پالس کلاک را نیز تولید می‌کند. انتقال دیتا بین دو تجهیز در خطوط I2C شامل چند مرحله ‌‌می‌باشد:

مرحله صفر

در این مرحله که هنوز انتقال دیتا شروع نشده است، خط SDA و SCL هر دو در وضعیت HIGH قرار دارند.

مرحله اول

این مرحله در واقع شروع انتقال دیتا می‌باشد. این مرحله توسط Master آغاز می‌شود. در این مرحله ابتدا خط SDA از HIGH به LOW تغییر وضعیت می‌دهد و پس از آن SCL نیز از HIGH به LOW تغییر می‌کند.

مرحله دوم

در این مرحله 7 بیت اطلاعات مربوط به آدرس Slave و همچنین بیت R/W ارسال می‌گردد. کل این اطلاعات شامل یک بایت می‌شود. در تصاویر برای سادگی، انتقال اطلاعات به صورت Byte نمایش داده شده است. اما در عمل دیتا به صورت بیت به بیت ارسال می‌گردد. برای مثال فرض کنید Master می‌خواهد بر روی آدرس 0x40 عمل Read انجام دهد، انتقال اطلاعات به صورت زیر می‌شود:

مرحله سوم

پس از اینکه بایت آدرس به همراه بیت R/W ارسال شد، سنسوری که آدرس آن با مقدار فرستاده شده تطابق دارد یک بیت ACK با وضعیت LOW را به خط برمی‌گرداند. پس از آن گیرنده منتظر اولین بایت دیتای ارسالی از طرف فرستنده می‌شود. با فرض اینکه Master گیرنده باشد(R/W=HIGH) برای مثال Slave می‌خواهد دیتای 0x35 را به Master ارسال کند:

یک یا چند بایت دیتا در هر ارتباط می‌تواند ارسال شود. این بایت‌ها، بیت به بیت توسط کلاک به صورت سنکرون ارسال می‌شوند. انتهای هر بایت نیز طرف گیرنده برای تاکید صحت دریافت دیتا، یک بیت ACK با وضعیت LOW به خط SDA ارسال می‌کند.

زمانی که آخرین بایت دیتا نیز ارسال شد SDA در وضعیت LOW قرار می‌گیرد و SCL در وضعیت HIGH باقی می‌ماند.

نکته

آخرین بایت با دیتاهای قبلی هیچ تفاوتی ندارد.
اگر
Slave فرستنده دیتاست، Master باید از قبل مشخص کرده باشد که انتظار دریافت چند بایت دیتا را دارد. بنابراین زمانی که آخرین دیتا از طرف Slave می‌رسد، Master متوجه آن می‌شود.
تعداد این بایت‌ها بستگی به
Slave دارد.

مرحله چهارم

این مرحله به معنای اتمام انتقال دیتا می‌باشد. بدین منظور خط SDA و SCL هر دو از وضعیت LOW به HIGH تغییر می‌کنند و در همین شرایط باقی می‌مانند.

لوازمی که به آن احتیاج دارید

همانطور که اشاره شد، جهت انجام دقیق و کامل این آموزش نیاز به تعدادی سنسور با رابط I2C و همچنین تعدادی قطعه دیگر دارید که زیر آورده شده است:

سخت افزار های موردنیاز

آردوینو UNO R3 × 1
ماژول نمایشگر 0.96 اینچ OLED و چیپ درایور SSD1306 × 1
ماژول سنسور دما و رطوبت GY-21 SI7021 با رابط I2C × 1
ماژول سنسور دما و رطوبت GY-213V HTU21D × 1
ماژول سنسور دما و رطوبت SHT20 × 1
ماژول سنسور دمای LM75 با رابط I2C × 1
برد توسعه 8 کاناله I2C TCA9548A × 1
برد بورد 400 حفره ای 5.5 * 8.5 cm × 1
سیم جامپر نری به نری 10 سانتی متری × 1
سیم جامپر نری به نری 20 سانتی متری × 1

نرم افزارهای مورد نیاز

برد آردوینو IDE

راه‌اندازی 2 سنسور دما با آدرس‌های I2C مختلف

در ابتدا و قبل از راه‌اندازی سنسورها با آدرس‌های I2C مشابه، ابتدا چند سنسور با I2C متفاوت را راه‌اندازی کرده تا با روند انجام این کار آشنا شوید و مقدمه‌ای باشد برای انجام کار اصلی.

مرحله اول: سیم‌بندی

قبل از هر کاری ابتدا باید مدار آن را آماده کنید. نحوه اتصالات دو سنسور دمای GY-21 و LM75 و نمایشگر OLED با آردوینو به صورت زیر است:

همانطور که در شکل بالا مشاهده می‌کنید، هر سه ماژول دارای ارتباط I2C می‌باشند. پایه A4 آردوینو UNO به عنوان SDA و پایه‌ی A5 آن SCL به شمار می‌رود. این دو پایه I2C در میکروکنترلرهای مختلف و همچنین بردهای دیگر آردینو متفاوت بوده و بایستی برای هر مورد این دو پایه به درستی متصل گردند. اطلاعات بیشتر در این مورد را می‌توانید از طریق این لینک مطالعه کنید.

مرحله دوم: پیدا کردن آدرس های I2C ماژول ها

از  طریق کتابخانه Wire و مثال i2c scanner می‌توانید آدرس های سه ماژول اتصالی به آردینو را بیابید.
بدین منظور کد زیر را بر روی آردوینو آپلود نمائید:

/*
  Made on 18 may 2021
  https://electropeak.com/learn/
  based on Arduino Library
*/

#include <Wire.h>

void setup() {
  Wire.begin();

  Serial.begin(9600);
  while (!Serial); // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

void loop() {
  int nDevices = 0;

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

  for (byte address = 1; address < 127; ++address) {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    byte 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); // Wait 5 seconds for next scan
 }

پس از آپلود برنامه بالا، سریال مانیتور را باز کرده و آدرس‌های ماژول‌ها را به صورت زیر مشاهده کنید:

مرحله چهارم: برنامه اصلی و مشاهده خروجی

در گام قبلی آدرس‌های I2C هر کدام یک از ماژول را پیدا کردیم. حال می‌خواهیم Library های سه ماژول را با هم ترکیب کرده و دمای محیط را توسط دو سنسور فوق بر روی نمایشگر OLED نمایش دهیم. بدین منظور برنامه زیر را بر روی آردوینو آپلود نمائید:

/*
  Made on 1 june 2021
  By Amirmohammad Shojaei
  https://electropeak.com/learn/
*/
#include <Wire.h>

#include "Adafruit_Si7021.h"     //add GY-21 si7021 Library 
Adafruit_Si7021 sensor = Adafruit_Si7021();


#include <Temperature_LM75_Derived.h>  //add LM75 Library
Generic_LM75 LM75;

#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  delay(100);

  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize OLED

}

String T_LM75;
String T_GY21;

void loop() {

  float T_GY21_S = sensor.readTemperature(); //Temperature of GY21 Sensor
  T_GY21= String(T_GY21_S);  
  T_GY21.remove(4,1);        //remmove one Decimal

  float T_LM75_S = LM75.readTemperatureC();   //Temperature of LM75 Sensor
  T_LM75= String(T_LM75_S);
  T_LM75.remove(4,1);        //remmove one Decimal

  Serial.print("T-GY21: ");    
  Serial.print(T_GY21);       //print value of T-GY21 on Serial Monitor
  Serial.print("C");

  Serial.print("   T-LM75: ");
  Serial.print(T_LM75);        //print value of T-LM75 on Serial Monitor
  Serial.println("C");

  display.clearDisplay();
  display.setTextSize(2);      
  display.setTextColor(SSD1306_WHITE); // Draw Yellow text
  display.setCursor(1, 1);     // Start at top-left corner
  display.print("T1: ");
  display.print(T_GY21);
  display.println(" C");

  display.setTextSize(2);      
  display.setTextColor(SSD1306_WHITE); // Draw blue text
  display.setCursor(1, 35);     // Start at (1,35) poin 
  display.print("T2: ");
  display.print(T_LM75);
  display.println(" C");
  display.display();
  delay(1000);
}

در ابتدای برنامه کتابخانه دو سنسور دما و همچنین نمایشگر  OLED اضافه می‌گردد. در حلقه اصلی برنامه توسط توابع موجود در هر کتابخانه مقادیر دو سنسور دما را ذخیره می‌کنیم. سپس توسط متغیر String برای نمایش بهتر بر روی نمایشگر، یک اعشار از این مقادیر کم کرده و مقادیر دماها را با یک رقم اعشار نشان می‌دهیم. در انتهای برنامه نیز توسط توابع کتابخانه نمایشگر OLED، دمای دو سنسور دما را بر روی نمایشگر نمایش می‌دهیم.

خروجی برنامه در عمل به صورت زیر است. دمای دو سنسور LM75 و GY-21 بر روی نمایشگر OLED نمایش داده می‌شود:

راه‌اندازی 3 سنسور دما با آدرس های I2C مشابه

در این مرحله قصد داریم دمای 3 عدد سنسور GY-21 ،SHT20 و HTU21D را که آدرس‌های I2C آنها مشابه است را بر روی نمایشگر OLED نمایش دهیم. اگر آدرس دو سنسور مشابه باشد، آردوینو امکان برقراری ارتباط با این دو سنسور را ندارد. در این موارد می‌توان از ماژول TCA9548A برای رفع این مشکل و گسترش پایه‌های I2C بهره برد.

حال قبل از اینکه برنامه اصلی را اجرا کنیم، لازم است ابتدا اندکی در مورد ماژول TCA9548A بدانیم:

ماژول توسعه TCA9548A

توسط این ماژول می‌توانید یک آدرس I2C را به 8 عدد توسعه دهید. آدرس I2C خود این ماژول 0x70 بوده که خود توسط پایه های A0 تا A2 قابل تغییر است. یعنی شما از 8 عدد از این ماژول به طور همزمان می‌توانید استفاده کنید. و این بدین معناست که می‌توانید توسعه پایه های I2C خود را به 64 عدد برسانید.

Pinout ماژول TCA9548A را تصویر بالا مشاهده می‌کنید. چند نکته قابل توجه است:

  • ولتاژ کاری آن بین 3 تا 5.5 ولت می‌باشد.
  • از پایه RESET برای ریست کردن ماژول استفاده می‌شود.(معمولا این پایه کاربردی ندارد)
  • توسط پایه‌های A0 تا A2 می‌توانید آدرس I2C ماژول را از 0x70 تا 0x77 تغییر دهید.(بنابراین می‌توان از 8 عدد از این ماژول به طور همزمان در ارتباط با آردوینو بهره برد.)
  • پایه SDA و SCL به باس I2C متصل می‌گردد.
  • همانطور که مشاهده می‌شود، این ماژول دارای 8 کانال خروجی I2C می‌باشد.
نکته

پایه‌های SDA و SCL ورودی در ماژول Pull-Up شده‌اند. اما کانال‌های I2C خروجی را باید خودتان توسط مقاومت Pull-Up کنید.

مشاهده آدرس های I2C قبل از اتصال ماژول TCA9548A

قبل از اینکه مدار اصلی را آماده کنیم، 3 سنسور دما و نمایشگر OLED را به پایه های I2C آردیونو متصل کرده و آدرس‌های I2C آن را مشاهده می‌کنیم.

همانطور که مشاهده می‌شود، هر 3 سنسور دما دارای آدرس 0x40 می‌باشد. بنابراین نمی‌توان از آنها استفاده نمود.

حال ماژول توسعه TCA9548A را اضافه کرده و مراحل زیر را برای رسیدن به جواب طی می‌کنیم:

مرحله نخست: سیم‌بندی

در اولین گام مدار زیر را در حضور ماژول توسعه TCA9548A و سه سنسور دمای SHT20، HTU21D و GY-21 و همچنین به همراه یک نمایشگر OLED مانند زیر به آردوینو متصل می‌کنیم:

سیم‌بندی مدار به طور کامل در تصویر بالا رسم شده است. در این مدار برای اطمینان، از ولتاژ 3.3 ولت برای اتصال به سنسورهای دما استفاده شده است. پایه های I2C ماژول TCA9548A نیز هر کدام به طور جداگانه توسط مقاومت‌های 10 کیلواهم Pull-Up شده‌اند.

مرحله دوم: برنامه اصلی و مشاهده خروجی

در این برنامه نیز مانند حالتی که دو سنسور داشتیم عمل می‌کنیم با این تفاوت که اکنون از سه سنسور استفاده می‌کنیم و در ضمن ماژول توسه TCA9548A نیز اضافه شده است. وقتی ماژول توسعه TCA9548A را اضافه می‌کنیم:

  • آدرس سنسورهای متصل به آن، زیر مجموعه‌ای از I2C این ماژول می‌شوند.
  • و هر گاه بخواهیم با سنسوری ارتباط برقرار کنیم، باید دسترسی به کانال آن را به ماژول آدرس دهیم.

برای این کار یک تابع به نام ()TCA9548A در برنامه جدید تعریف کرده و ورودی این تابع را شماره کانالی که می‌خواهیم فعال شود قرار می‌دهیم. حال هر وقت بخواهیم با توابع Library یک سنسور کار کنیم، کافی است این تابع را قبل از آن فراخوانی کنیم و شماره کانال مدنظر را به عنوان ورودی تابع قرار دهیم. برای مثال در حلقه اصلی وقتی می‌خواهیم با استفاده از تابع ()sensor.readTemperature  مقدار دمای سنسور GY-21 را ذخیره کنیم، باید قبل آن تابع TCA9548A(7) را فراخوانی کرده باشیم.(به دلیل اینکه سنسور GY-21 به کانال شماره 7 ماژول توسعه TCA9548A متصل است.)

حال کد برنامه را بر روی آردوینو آپلود کنید:

/*
  Made on 18 may 2021
  By Amirmohammad Shojaei
  https://electropeak.com/learn/
  
*/
#include <Wire.h>

#include "SparkFunHTU21D.h"    //add HTU21D Library 
HTU21D myHumidity;

#include "Adafruit_Si7021.h"     //add GY-21 si7021 Library 
Adafruit_Si7021 sensor = Adafruit_Si7021();

#include "DFRobot_SHT20.h"       //add SHT20 Library 
DFRobot_SHT20 sht20;

#include <Adafruit_SSD1306.h>    //add SSD1306 OLED Library 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void TCA9548A(uint8_t bus) //function of TCA9548A
{
  Wire.beginTransmission(0x70);  // TCA9548A address is 0x70
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
}

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  delay(100);

  TCA9548A(2);
  myHumidity.begin();        //Initialize HTU21D Sensor

  TCA9548A(1);
  sht20.initSHT20();                         // Initialize SHT20 Sensor
  delay(100);
  sht20.checkSHT20();                        // Check SHT20 Sensor

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize OLED

}

String T_SHT20;
String T_HTU21D;
String T_GY21;

void loop() {
  
  TCA9548A(1);
  float T_SHT20_S = sht20.readTemperature();   //Temperature of SHT20 Sensor 
  T_SHT20= String(T_SHT20_S);             //remmove one Decimal
  T_SHT20.remove(4,1);

  TCA9548A(2);
  float T_HTU21D_S = myHumidity.readTemperature();   //Temperature of HTU21D Sensor 
  T_HTU21D= String(T_HTU21D_S);          //remmove one Decimal
  T_HTU21D.remove(4,1);
  
  TCA9548A(7);
  float T_GY21_S = sensor.readTemperature();        //Temperature of GY21 Sensor 
  T_GY21= String(T_GY21_S);            //remmove one Decimal
  T_GY21.remove(4,1);
  
  Serial.print("T-SHT20: ");
  Serial.print(T_SHT20);      //print value of T-SHT20 on Serial Monitor
  Serial.print("C");

  Serial.print("   T-HTU21D: ");
  Serial.print(T_HTU21D);         //print value of T-HTU21D on Serial Monitor
  Serial.print("C");

  Serial.print("   T-GY21: ");
  Serial.print(T_GY21);           //print value of T-GY21 on Serial Monitor
  Serial.println("C");


  display.clearDisplay();
  display.setTextSize(2);      
  display.setTextColor(SSD1306_WHITE); // Draw Yellow text
  display.setCursor(1, 1);     // Start point
  display.print("T1: ");
  display.print(T_SHT20);
  display.println(" C");
  

  display.setTextSize(2);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw Blue text
  display.setCursor(1, 22);     // Start point
  display.print("T2: ");
  display.print(T_HTU21D);
  display.println(" C");


  display.setTextSize(2);      
  display.setTextColor(SSD1306_WHITE); // Draw Blue text
  display.setCursor(1, 45);     // Start point
  display.print("T3: ");
  display.print(T_GY21);
  display.println(" C");
  display.display();
  
  delay(1000);
}

در ابتدای برنامه کتابخانه سه سنسور دما و همچنین نمایشگر  OLED اضافه می‌گردد. بعد از اضافه کردن Library ماژول ها، تابع ()TCA9548A را تعریف می‌کنیم. در ادامه نیز مانند حالت قبل عمل می‌کنیم. با این تفاوت که بایستی قبل از استفاده از توابع Library هر سنسور، ابتدا تابع ()TCA9548A را فراخوانی کنیم. در حلقه اصلی برنامه توسط توابع موجود در هر کتابخانه، مقادیر دمای سنسورها را ذخیره می‌کنیم. سپس توسط متغیر String برای نمایش بهتر بر روی نمایشگر، یک اعشار از این مقادیر کم کرده و مقادیر دماها را با یک رقم اعشار نشان می‌دهیم. در انتهای برنامه نیز توسط توابع نمایشگر OLED دمای سه سنسور را بر روی نمایشگر نمایش می‌دهیم.

سنسور GY-21 به کانال 7، HTU21D به کانال 2 و SHT20 به کانال 1 متصل شده‌اند. خروجی در عمل به صورت زیر می‌باشد. دمای محیط توسط سه سنسور مذکور به طور جداگانه نمایش داده ‌می‌شوند:

یک گام جلوتر

بعد انجام کامل این آموزش، می‌توانیم چالش‌های جدیدی در رابطه با این آموزش را تجربه کنیم:

  • ارتباط دو برد آردوینو از طریق پروتکل I2C
  • به کار بردن دو عدد ماژول TCA9548A به طور همزمان
  • استفاده از دو عدد OLED با آدرس‌های I2C مشابه
  • استفاده از دو Master و چند Slave در ارتباط با باس I2C

آموزش های مشابه

Comments (8)

  • مصطفی Reply

    با سلام و خسته نباشید خیلی عالی کاربردی بود سایت شما ، ببخشید بنده چند تا از این برد oled./ 91 دارم با آدرس مشابه هستند. ، نمیشه آدرس دهی کرد نحوه آدرس دهی oled را با TCA بگویید و همچنین نحوه اتصال چند TCA را خواستارم ممنون لازم دارم هروی گشتم اینترنت پیدا نکردم در این مورد توضیح بدن تا شانسی سایت شما دیدم و همچنین از این ماژول TCA برای خرید میخواهم شما ندارین برای فروش ، بازم خیلی ممنونم

    جولای 19, 2022 at 7:42 ب.ظ
    • مهران ملکی Reply

      سلام.
      توضیحات آموزش به اندازه کافی روشن هستند. با خوندن مجدد آموزش و همچنین کد نوشته شده به راحتی میتونید ماژول‌های مورد نظرتون رو از طریق ماژول TCA9548A به آردوینو متصل کنید. اتصال یک ماژول TCA9548A به یک ماژول TCA9548A دیگه هم مشابه اتصال دیگر ماژول‌های I2C هست و تفاوتی نداره. برای توضیحات بیشتر میتونید آموزش زیر رو هم مطالعه کنید:
      https://create.arduino.cc/projecthub/tarantula3/tca9548a-i2c-multiplexer-module-with-arduino-and-nodemcu-3d3313

      جولای 25, 2022 at 10:46 ب.ظ
  • مصطفی Reply

    با سلام و خسته نباشید ممنون از شما فقط یک سوال دیگه داشتم ، بنده میخواهم ۵۰ عدد oled ssd1306 مشابه را با ۷ عدد ماژول TCA9548a وصل بشه و آدرس دهی بشه وصل کردن سخت افزاری مشکلی ندارم کدنویسی به مشکل افتادم ،کتابخانه چیزی در این مورد پیدا نکردم وقتی ماژول TCAبیشتر شد چطوری کدنویسی می‌شوند، هرکجا سرچ کردم اینترنت پیدا نکردم ، کدنویسی کرده باشه لطفاً ،

    آگوست 23, 2022 at 6:57 ب.ظ
  • علیرضا Reply

    سلام من می خواستم یه سیستم برای تنظیم ارتفاع خودکار برای خودرو انجام بدم ، برای مثال می خوام وقتی که داخل پیش ماشین دور میزنه قسمتی از ماشین که پایین میره با استفاده از سنسور ارتفاع تشخیص بده و به مخزن پنوماتیک دستور بده که ارتفاع اون قسمت رو با افزایش فشار باد به اندازه کافی بالا ببره . می خواستم ازتون کمک بگیرم

    مارس 8, 2024 at 2:50 ق.ظ
    • محمد دمیرچی Reply

      با سلام
      بهتر است این جور سوال ها را در انجمن مطرح کنید.
      اما به صورت کلی بهتر است از سنسور های ژیرسکوپ و فاصله سنج های لیزری برای این موضوع استفاده کنید.

      مارس 9, 2024 at 10:58 ق.ظ
  • پدرام Reply

    سلام عرض ادب
    بنده stm32f103c8 رو با بورد arduino mega 2560 توسط i2c ارتباط دادم و داده ها راحت جابجا شد،
    stm رو یکبار master و یکبار slave کردم و موردی نداشتم اما وقتی ۲ عدد stm رو با هم ارتباط میدم هیچ دیتایی ندارم
    آیا تنظیم خاص سخت افزاری و یا نرم افزاری وجود داره که من فراموش کردم ؟
    ممنون میشم راهنمایی بفرمایید

    جولای 20, 2024 at 9:12 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      یکی از STM ها را Master و دیگری را Slave کرده اید. همچنین زمین بین این 2 را نیز مشترک کرده اید؟؟

      جولای 21, 2024 at 10:41 ق.ظ
      • پدرام Reply

        سلام بله ، مقاومت 10k سر راه SDA و SCK گذاشتم و مشکل برطرف شد
        ممنون از همراهیتون

        جولای 21, 2024 at 1:35 ب.ظ

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.