ارتباط RS-485 بین STM32 و بورد Arduino Uno

پروتکل‌های ارتباطی بخش مهمی از سیستم‌های نهفته و تجهیزات الکترونیک دیجیتال محسوب می‌شوند. در هر جایی که بحث تعامل و ارتباط گرفتن چند میکروکنترلر با یکدیگر و یا با سایر اجزاء یک سیستم باشد، به منظور تبادل داده میان آنها باید از یک پروتکل ارتباطی استفاده شود. در حال حاضر انواع مختلفی از پروتکل‌های ارتباطی سریال وجود دارند. RS485 یکی از این انواع است که به کرات در تجهیزات الکترونیک صنعتی و ماشین‌آلات غول‌پیکر از آن استفاده می‌شود.

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

در آموزش‌های پیشین، درباره‌ی چگونگی استفاده از این پروتکل در ارتباط بین یک بورد Arduino Uno و یک بورد Arduino Nano توضیح داده‌ایم و در این جلسه می‌خواهیم به سراغ طرز استفاده از آن در میکروکنترلر STM32 برویم. اگر تا این لحظه آشنایی چندانی با این میکروکنترلر ندارید و یا پروژه‌ای با آن انجام نداده‌اید، پیشنهاد می‌کنیم ابتدا به جلسه‌ی مقدماتی که شامل آشنایی با میکروکنترلر STM32 و انجام یک پروژه‌ی ساده‌ی LED چشمک‌زن با آن است، بروید و مرحله به مرحله پیش بیایید. آموزش‌های دیگری نیز از انجام پروژه‌های مختلف با این میکروکنترلر در سایت موجود می‌باشد که بهتر است نگاهی به آنها هم داشته باشید.

در این پروژه قصد داریم بورد میکروکنترلر STM32 را به عنوان Master ارتباط سریال و بورد Arduino Uno را به عنوان Slave قرار دهیم. سپس از طریق ارتباط سریال، وضعیت سه LED موجود بر روی بورد آردوینو را با سه عدد کلید فشاری که به میکروکنترلر وصل می‌شود، کنترل کنیم.

این کار را با مقدمه‌ی مختصری از پروتکل ارتباط سریال RS-485 شروع می‌کنیم.

پروتکل ارتباطی RS-485

RS-485 یک پروتکل ارتباط سریال آسنکرون است. آسنکرون بودن آن به این معناست که نیازی به کلاک ندارد.

برای انتقال دیتاهای باینری از یک دستگاه به دستگاه دیگر، این پروتکل از روشی به نام تفاضل سیگنال (differential signal) استفاده می‌کند.

روش Differential Signal Transfer چیست؟

تکنیک DST براساس یک اختلاف ولتاژ که آن را با دو سیگنال 5V+ و 5V- می‌سازد عمل می‌کند.

زمانی که از دو سیم برای آن استفاده کنیم، یک ارتباط دو طرفه همزمان (Full-Duplex) و زمانی که از یک سیم برای آن استفاده کنیم، یک ارتباط دو طرفه غیر‌ همزمان (Half-Duplex) برای ما فراهم می‌کند.

مزایای استفاده از RS-485 عبارتند از:

  • سرعت بالای انتقال داده (تا 30Mbps)
  • نسبت به پروتکل RS-232، داده‌ها را در مسافت‌های طولانی‌تری انتقال می‌دهد. (تا ۱۲۰۰ متر)
  • یکی از بهترین مزیت‌های آن نسبت به RS-232، این است که درRS-485 می‌توانیم برای هر Master چندین Slave داشته باشیم اما در RS-232، هر Master تنها می‌توانست یک Slave بپذیرد.
  • ۳۲ دستگاه مختلف می‌توانند در این پروتکل به یکدیگر متصل شوند.
  • از آنجایی که برای انتقال داده‌ها از روش تفاضل سیگنال استفاده می‌کند، نسبت به نویز ایمنی بیشتری دارد.
  • نسبت به پروتکل I2C پروتکل سریع‌تری محسوب می‌شود.

ماژول RS-485 را می‌توان به هر میکروکنترلری که پورت USB داشته باشد متصل کرد. اما برای متصل کردن آن به یک ماژول واسطه به نام مبدل 5V MAX485 TTL to RS485 نیاز داریم. این ماژول با آی‌سی Maxim MAX485 ساخته می‌شود و یک ارتباط سریال تا مسافت ۱۲۰۰ متر را پشتیبانی می‌کند، دارای ارتباط دو طرفه غیر همزمان است و حداکثر سرعت انتقال آن 2.5Mbps است.

برای استفاده از این ماژول به یک تغذیه‌ی ۵ ولتی نیاز داریم.

مطلب پیشنهادی:  معرفی CMSIS

پایه‌های Rs-485

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

ویژگی‌های ماژول RS485

  • ولتاژ کاری آن ۵ ولت است.
  • دارای چیپ MAX485 است.
  • مصرف توان پایین در ارتباط RS-485.
  • دارای گیرنده با Slew-rate محدود.
  • دارای ترمینال 08mm pitch 2P.
  • دارای wiring مناسب برای ارتباط RS-485.
  • تمام پایه‌های قابلیت کنترل شدن از طریق میکروکنترلر را دارند.
  • ابعاد بورد آن ۴۴×۱۴ میلی‌متر می‌باشد.

استفاده از این ماژول به همراه بوردهای میکروکنترلر STM32 و Arduino Uno بسیار راحت است و کافی است که از پورت‌های ارتباط سریال این میکروکنترلرها استفاده کنیم. این پین‌ها را برای هر دو بورد در ادامه می‌بینیم.

  • STM32F103C8: Pins PA9 (TX) & PA10 (RX)
  • Arduino Uno: Pin 0 (RX) & 1 (TX)

حتی پروگرم کردن این ارتباط نیز بسیار ساده است. برای این کار از تابع ()Serial.print استفاده می‌کنیم تا داده‌ها را به ماژول RS485 ارسال کنیم و از تابع ()Serial.Read هم برای خواندن داده‌ها از آن استفاده می‌کنیم. به صورت متناظر پین‌های RE و DE ماژول RS485 را در هنگام ارسال داده در وضعیت LOW و در هنگام دریافت داده در وضعیت HIGH قرار می‌دهیم.

نیازمندی‌های اجرای پروژه

  • میکروکنترلر STM32F103C8
  • بورد Arduino UNO
  • ۲ عدد مبدل MAX485 TTL به RS485
  • پتانسیومتر 10K
  • سه عدد کلید فشاری
  • سه عدد LED
  • مقاومت
  • برد بورد
  • سیم برد بوردی

نقشه مدار و اتصالات

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

همان طور که گفتیم در این پروژه بورد میکروکنترلر را که به یک مبدل MAX485 TTL به RS485 متصل است به عنوان Master و بورد Arduino Uno را که آن نیز به یک مبدل از همان نوع متصل است، به عنوان Slave در نظر می‌گیریم.

اتصال STM32 به ماژول مبدل

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

اتصال STM32 به کلیدهای فشاری

سه کلید فشاری را به همراه سه مقاومت پول دان 10K، به پین‌های PA1 ،PA0 و PA2 میکروکنترلر وصل می‌کنیم.

اتصال بورد Arduino Uno به مبدل

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

ابتدا آنود سه عدد LED را با واسطه‌ی سه مقاومت ۳۳۰ اهمی به پین‌های شماره‌ی ۴، ۷ و ۸ بورد آردوینو وصل می‌کنیم. کاتود LEDها را هم به زمین متصل می‌کنیم.

پروگرم کردن Arduino Uno و STM32 برای برقراری ارتباط سریال RS-485

برای پروگرم کردن هر دو بورد از Arduino IDE استفاده می‌کنیم. اما برای هر کدام از آنها مطمئن شوید که پورت و بورد را به درستی انتخاب کرده باشید. (از مسیرهای Tools -> Port و Tools -> Board) اگر سوال یا مشکلی داشتید، به آموزش مربوط به پروگرم کردن STM32 با استفاده از پورت USB و Arduino IDE مراجعه کنید.

برنامه‌ای که برای این پروژه باید بنویسیم از دو قسمت تشکیل شده است؛ یک کد برای STM32) Master) و یک کد برای Arduino Uno) Slave). هر دو بخش را در ادامه توضیح می‌دهیم.

پروگرم کردن STM32 به عنوان Master

اتفاقی که باید در سمت Master بیفتد این است که وضعیت کلیدهای فشاری خوانده شده و این داده‌ها به صورت سریال و از طریق پورت سریال شماره یک میکرو (PA9 و PA10)، بر روی ماژول مبدل RS-485 نوشته شوند. فعلا به هیچ کتابخانه‌ی خارجی هم نیاز نداریم چون بورد Arduino خود تمام کتابخانه‌های لازم برای ارتباط سریال را دارد.

ارتباط سریال را روی پین‌های PA9 و PA10 با بادریت ۹۶۰۰ آغاز می‌کنیم.

Serial1.begin(9600);

وضعیت سه کلید را که به پایه‌های PA1 ،PA0 و PA2 متصل هستند می‌خوانیم و در سه متغیر به نام‌های button2val ،button1val و button3val ذخیره می‌کنیم. اگر کلیدها فشار داده شده باشند مقدار متغیرها HIGH (یک) و اگر در وضعیت آزاد باشند، مقدار متغیرها LOW (صفر) خواهد بود.

int button1val = digitalRead(button1);
int button2val = digitalRead(button2);
int button3val = digitalRead(button3);

قبل از اینکه بخواهیم این مقادیر را به RS-458 ارسال کنیم، باید پین‌های RE و DE این ماژول را به حالت HIGH درآوریم. به عبارتی باید پین PA3 میکروکنترلر را یک کنیم. برای این کار کد زیر را به کار می‌بریم.

digitalWrite(enablePin, HIGH);

سپس با استفاده از دستور if، هر کدام از کلیدها که فشار داده شود و وضعیت آن تغییر کند، مقدار آن را به ماژول مبدل ارسال می‌کنیم.

مطلب پیشنهادی:  چگونه یک کتابخانه آردوینو بنویسیم؟

مثلا اگر کلید یک فشار داده شود، عبارت شرطی مربوط به آن صحیح شده و مقدار یک به پورت سریالی که بورد آردوینو به آن متصل است ارسال می‌شود.

if (button1val == HIGH)
    {
      int num1 = 1;
      Serial1.println(num1);
    }

به همین ترتیب اگر کلیدهای ۲ یا ۳ فشار داده شوند، مقادیر مربوط به آنها روی پورت سریال ارسال می‌شود.

else if (button2val == HIGH)
    {
      int num2 =2;
      Serial1.println(num2);
    }
                else if (button3val == HIGH)
    {
      int num3 =3;
      Serial1.println(num3);
    }

 و زمانی هم که تمام کلیدها در حالت آزاد هستند، مقدار صفر به بورد آردوینو فرستاده خواهد شد.

   else
   {
     int num = 0;
     Serial1.println(num);
     }

به این ترتیب پروگرم کردن STM32 به عنوان Master این ارتباط سریال تمام می‌شود.

پروگرم کردن Arduino Uno به عنوان Slave

بورد آردوینو باید مقادیری که توسط STM32 ارسال می‌شوند را روی پورت سریال خود که ماژول مبدل rs485 به آن متصل است، دریافت کند (P0,1). سپس مقداری که می‌خواند را در یک متغیر ذخیره کند و بر اساس آن تصمیم بگیرد که کدام LED باید در وضعیت خاموش یا روشن باشد. (LEDها به پین‌های GPIO بورد آردوینو متصل هستند)

برای داده‌های Master، کافیست پین‌های RE و DE از ماژول RS-485 را در وضعیت LOW قرار دهیم. بنابراین پین ۲ (enablePin) از آردوینو را صفر می‌کنیم.

digitalWrite(enablePin, LOW);

حالا تنها کاری که باید انجام دهیم این است که مقادیر را از پورت سریال بخوانیم و در متغیری ذخیره کنیم.

int receive = Serial.parseInt();

سپس بر اساس مقدار دریافت شده، یکی از LEDها را روشن می‌کنیم.

if (receive == 1)          //Depending Upon Recieved value the corresponding LED is turned ON or OFF
        {
          digitalWrite(ledpin1,HIGH);
        }
        else if (receive == 2)
        {
          digitalWrite(ledpin2,HIGH);
        }
        else if (receive == 3)
        {
          digitalWrite(ledpin3,HIGH);
        }
        else
        {
         digitalWrite(ledpin1,LOW);
         digitalWrite(ledpin2,LOW);
         digitalWrite(ledpin3,LOW);
        }

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

چک کردن ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino UNO

  1. اگر کلید ۱ در سمت Master را فشار دهیم، LED شماره ۱ در سمت Slave روشن می‌شود.

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

  1. اگر کلید ۲ در سمت Master را فشار دهیم، LED شماره ۲ در سمت Slave روشن می‌شود.
مطلب پیشنهادی:  آموزش راه اندازی ماژول +nRF24L01

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

  1. و به همین ترتیب اگر کلید ۳ را در سمت Master فشار دهیم، LED شماره ۳ در سمت Slave روشن می‌شود.

ارتباط سریال بین میکروکنترلر STM32F103C8 و بورد Arduino Uno با استفاده از پروتکل RS-485

به این ترتیب به پایان موفقیت‌آمیز این پروژه می‌رسیم. هر دو بورد یعنی میکروکنترلر STM32 و Arduino Uno از جمله‌ بردهای محبوب و پرکاربرد در انجام پروژه‌ها و تولید prototypeها هستند.

اگر پیشنهادی در روند اجرای این پروژه‌ها دارید و یا حتی اگر سوال یا اشکالی در مورد آنها داشتید حتما در قسمت نظرات با ما درمیان بگذارید.

کد

Master Code:STM32F103C8

//RS-485 Serial Communication Between STM32F103C8 & Arduino Uno

#define button1 PA0
#define button2 PA1
#define button3 PA2
#define enablePin PA3
  
void setup()

{
  Serial1.begin(9600);            // Begins Serial communication at serial1 Port PA9,PA10 at baudrate 9600
  pinMode(enablePin, OUTPUT);

  pinMode(button1,INPUT);
  pinMode(button2,INPUT);
  pinMode(button3,INPUT);
  
  delay(10);
  digitalWrite(enablePin, HIGH);  //  (always high as Master Writes data to Slave)
}

void loop()
{
  int button1val = digitalRead(button1);         //Reads the status of the Push Button
  int button2val = digitalRead(button2);
  int button3val = digitalRead(button3);
 
    if (button1val == HIGH)
    {
      int num1 = 1;
      Serial1.println(num1);                //Sends Push button value 1 if HIGH (Pressed) 
    }
    else if (button2val == HIGH)
    {
      int num2 =2;
      Serial1.println(num2);                //Sends Push button value 2 if HIGH (Pressed)
    }
    else if (button3val == HIGH)
    {
      int num3 =3;
      Serial1.println(num3);                //Sends Push button value 3 if HIGH (Pressed)
    }
   else
   {
     int num = 0;
     Serial1.println(num);                  //Sends 0 if any of push button is not pressed
   }
   delay(50);
}

Slave Code: Arduino UNO:
//RS-485 Serial Communication Between STM32F103C8 & Arduino Uno

#define enablePin 2
#define ledpin1 4
#define ledpin2 7
#define ledpin3 8

 void setup() 
{
  Serial.begin(9600);                   // Begins Serial Communication with baud rate 9600  
  pinMode(ledpin1,OUTPUT);
  pinMode(ledpin2,OUTPUT);
  pinMode(ledpin3,OUTPUT);
  pinMode(enablePin, OUTPUT);
  delay(10);
  digitalWrite(enablePin, LOW);        //  (Pin 8 always LOW to receive value from Master)
}

void loop() 

{
  while (Serial.available())            //While having data at Serial port this loop executes
     {         
        int receive = Serial.parseInt();  // Reads the integer value sent from STM32
    
        if (receive == 1)                //Depending Upon Recieved value the corresponding LED is turned ON or OFF
        {
          digitalWrite(ledpin1,HIGH);
        }
        else if (receive == 2)
        {
          digitalWrite(ledpin2,HIGH);
        }
        else if (receive == 3)
        {
          digitalWrite(ledpin3,HIGH);
        }
        else
        {
         digitalWrite(ledpin1,LOW);
         digitalWrite(ledpin2,LOW);
         digitalWrite(ledpin3,LOW); 
        }
     }
}

ویدئو

امیدواریم آموزش «ارتباط RS-485 بین STM32 و بورد Arduino » برایتان مفید واقع شده باشد. در ادامه پیشنهاد می‌کنیم دیگر آموزش‌های STM32 را نیز مطالعه کنید.

اگر این نوشته‌ برایتان مفید بود لطفا کامنت بنویسید.

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

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