ساخت OUTPUT Expander با آردوینو

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

همچنین وضعیت پایه ها در حافظه EEPROM داخلی میکروکنترلر ذخیره خواهد ماند تا در صورت ریست میکروکنترلر وضعیت پایه ها حفظ شود.

برای نمایش وضعیت پایه های خروجی میکروکنترلر slave یک led همراه مقاومت با ان در نظر گرفته شده است وهمچنین برای I2C باید مقاومت پول اپ در نظر گرفته شود.

ابتدا برنامه گیرنده (توسعه دهنده پورت خروجی) را توضیح می دهیم :

#include "EEPROM.h"
#include "Wire.h"

ابتدا کتابخانه EEPROM و Wire را فراخوانی می کنیم.

#define pinCount 14

تعداد پورت خروجی استفاده شده را مشخص می کنیم.

long outputs =   -1;

متغییر outputs برای نگه داری وضعیت خروجی پایه ها می باشد که توسط I2C دریافت می شود.

void setup() {

  for(byte x = 0; x < pinCount; x++){

چون شماره پایه ها از 0 تا 13 می باشد خیلی راحت داخل یک حلقه for می توانیم ابتدا پایه ها را

      pinMode(x, OUTPUT);

در وضعیت خروجی قرار دهیم

      if(EEPROM.read(x) == 1) {

و وضعیت قبلی انها را از حافظه EEPROM بخوانیم و در صورت یک بودن وضعیت پایه را به high و در غیر اینصورت به  low  تغییر دهیم.

نکته : ادرسی که در eeprom برای نگه داری وضعیت پایه ها استفاده می شود برابر با همان شماره پایه خروجی می باشد.

digitalWrite(x , HIGH);
      }
      else {
        
            digitalWrite(x , LOW);
      }
    
  }


  Wire.begin(0x66);

راه اندازی i2c میکروکنترلر با ادرس دلخواه خود

  Wire.onReceive(receiveEvent);

فعال کردن وقفه دریافت و مشخص کردن تابعی که باید بعد از دریافت دیتا اجرا شود.

}


void loop() {

  if(outputs != -1){

در صورتی که متغییر outputs مخالف 1- باشد یعنی دیتایی را دریافت کرده ایم

long shift = 1;
    
    for(byte x = 0; x < pinCount; x++) {

خواندن دیتا بیت به بیت به تعداد مشخص شده

if ((outputs & shift) != 0) {

اگر بیت مورد نظر در متغییر برابر با یک بود پایه را در وضعیت یک منطقی قرار داده و وضعیت ان را در eeprom اپدیت می نماییم.

digitalWrite(x ,    HIGH);
          EEPROM.update(x  ,  1);
      }
      else {

در صورتی که بیت صفر بود پایه را در حالت صفر منطقی قرار داده و وضعیت ان را در eeprom اپدیت می کنیم.

digitalWrite(x ,    LOW);
          EEPROM.update(x  ,  0);
      }

      shift = shift << 1;

با هر بار تکرار حلقه مقدار متغییر shift یک واحد به چپ شیفت پیدا می کند تا بتوانیم بیت بعدی را اصطلاحا mask نماییم.چون هر بار یکی از بیت های متغییر shift یک است با انجام and منطقی با متغییر outputs وضعیت ان بیت بدست می اید.

}

    outputs = -1;

در اخر وضعیت متغییر outputs را به 1- بر می گردانیم تا از اجرای تکراری این قسمت برنامه جلوگیری نماییم.

}

}


void receiveEvent(int count) {

نکته : count بیانگر تعداد بایتهای دریافتی می باشد.چون در اینجا از قبل تعداد بایت دریافتی را می دانیم این متغییر کاربردی برای ما ندارد.

در تابع دریافت باید دوبار از i2c بخوانیم.یکبار مقدار پر ارزش را به چپ shift داده تا در جای درست خود قرار بگیرند

    outputs = (Wire.read()) << 8;
    outputs += Wire.read();

و سپس مقدار کم ارزش را با مقدار پرارزش جمع می کنیم تا مقدار کلی بدست بیاید.

هر بیت در این متغییر بیانگر وضعیت یک پایه خروجی می باشد.برای مثال اگر اولین بیت یک باشد باید پایه یک را در حالت یک منطقی و اگر صفر باشد پایه را در حالت صفر منطقی قرار دهیم.

چون در i2c دیتا بصورت جریانی از بایتها ارسال و دریافت می شود در سمت فرستنده برای اینکه 14 حالت پایه ها را بتوانیم بفرستیم باید از دو بایت استفاده نماییم.

}

توضیح قسمت برنامه فرستنده :

#include "Wire.h"

unsigned int counter = 0;

استفاده از متغییر counter برای تست برنامه

void setup() {
  Serial.begin(9600);

تنظیم بادریت سریال به 9600

Serial.println(F("PORT EXPANDER TEST >>>"));
  Serial.println(F(" "));

نمایش پیغام دلخواه روی پورت سریال

  Wire.begin(0x44);

تنظیم پروتکل i2c با ادرس مورد نظر

delay(1000);
}

void loop() {

  Wire.beginTransmission(0x66);

اغاز ارتباط در i2c با ادرس گیرنده که بر روی  0x66تنظیم شده بود.

  Wire.write(counter >> 8);//MSB Byte

ارسال بایت پر ارزش

  Wire.write(counter);//LSB Byte

و سپس ارسال بایت کم ارزش متغییر counter

  Wire.endTransmission();

خاتمه دادن به ارتباط و ایجاد شرایط stop در پروتکل i2c

Serial.print(F("Write IO PORT: "));
  Serial.println(counter);

نمایش مقدار فعلی متغیر کانتر روی پورت سریال

  counter++;

افزایش مقدار متغییر و تکرار برنامه در حلقه بی نهایت

delay(400);

}

برنامه فرستنده برای تست می باشد و شما می توانید طبق نیاز خود ان را تغییر دهید.

در ادامه می توانید فایلهای برنامه ی اصلی و تست را به همراه فایل شبیه سازی دانلود نمایید:

دانلود فایل

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

گیل الکترونیک
سبد خرید
empty basket

هیچ محصولی در سبد خرید نیست.