با عرض سلام و وقت بخیر خدمت اساتید محترم
بنده مدتی هست که قصد دارم با استفاده از ماژول های RS485 که در سایت آفتاب رایانه نیز موجود هست برای شبکه کردن چند آردوینو استفاده کنم.
ماژول RS485 موجود در فروشگاه
من میخوام دوتا آردوینو رو با استفاده از این ماژول بهم متصل کنم در این صورت یکی از آردوینو ها (master) و آردوینو دیگر (slave) میشه . تو این تست من از دوتا آردوینو مگا R3 استفاده کردم.
عکسش رو در زیر برای دوستان قرار دادم.
ترتیب اتصال پایه های ماژول rs485 با آردوینو به صورته زیر هست.
RE و DE به یکدیگر پل شده و به پین 4 متصل شده (جهت فعال کردن ارسال درون شبکه کافیه یه بار HIGH بشه و داده ها ارسال بشه و در نهایت LOW بشه)
Ro به پین شماره 2 (در نقش RX)
DI به پین شماره 3 (در نقش TX)
VCC به 5 ولت
و پایه های A و B ماژول های RS485 نیز نظیر به نظیر به یکدیگر متصل می شوند همانند شکل زیر:
نحوه عملکرد کد:
مستر مقادیر ولوم رو از پایه آنالوگ A0 میخونه و این مقادیر رو برای سلیو ارسال میکنه و ال ای دی متصل به اسلیو نیز توسط مقادیری که دریافت کرده میزان روشناییش تغییر میکنه و اسلیو نیز در پاسخ مقادیری رو برای مستر ارسال میکنه.
کد به خوبی کار میکنه فقط من دوتا مشکل دارم:
1- اون پاسخی که اسلیو برای مستر ارسال میکنه رو نمیتونم دریافت کنم، به طوری که گویا ارتباط یک طرفه هست (فقط از مستر به اسلیو)
2- طبق شکل و کدی که برنامه نویس نوشته من نمیتونم ارتباط داشته باشم (یعنی در هردو آردوینو پایه های RO به 2 و DI به 3 ) در عوض من باید در یکی از ماژول ها Ro رو به 2 و توی آردوینو دیگه به 10 وصل کنم به همین ترتیب پایه DI رو به 3 و توی آردوینوی دیگه به 11 وصل کنم که ارتباط برقرار بشه ولی با این حال هنوز ارتباط یک طرفه هست
ممنون میشم راهنماییم کنید تا مشکل برطرف بشه و دوستان دیگه هم بتونن استفاده کنن.
لینک مرجع کد : RS485 communications
و از کد های زیر جهت ارتباط استفاده میکنید:
کد مستر:
کد:
#include "RS485_protocol.h"
#include <SoftwareSerial.h>
const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;
SoftwareSerial rs485 (2, 3); // receive pin, transmit pin
// callback routines
void fWrite (const byte what)
{
rs485.write (what);
}
int fAvailable ()
{
return rs485.available ();
}
int fRead ()
{
return rs485.read ();
}
void setup()
{
rs485.begin (28800);
pinMode (ENABLE_PIN, OUTPUT); // driver output enable
pinMode (LED_PIN, OUTPUT); // built-in LED
} // end of setup
byte old_level = 0;
void loop()
{
// read potentiometer
byte level = analogRead (0) / 4;
// no change? forget it
if (level == old_level)
return;
// assemble message
byte msg [] = {
1, // device 1
2, // turn light on
level // to what level
};
// send to slave
digitalWrite (ENABLE_PIN, HIGH); // enable sending
sendMsg (fWrite, msg, sizeof msg);
digitalWrite (ENABLE_PIN, LOW); // disable sending
// receive response
byte buf [10];
byte received = recvMsg (fAvailable, fRead, buf, sizeof buf);
digitalWrite (LED_PIN, received == 0); // turn on LED if error
// only send once per successful change
if (received)
old_level = level;
} // end of loop
کد اسلیو:
کد:
#include <SoftwareSerial.h>
#include "RS485_protocol.h"
SoftwareSerial rs485 (10, 11); // receive pin, transmit pin
const byte ENABLE_PIN = 4;
void fWrite (const byte what)
{
rs485.write (what);
}
int fAvailable ()
{
return rs485.available ();
}
int fRead ()
{
return rs485.read ();
}
void setup()
{
rs485.begin (28800);
pinMode (ENABLE_PIN, OUTPUT); // driver output enable
}
void loop()
{
byte buf [10];
byte received = recvMsg (fAvailable, fRead, buf, sizeof (buf));
if (received)
{
if (buf [0] != 1)
return; // not my device
if (buf [1] != 2)
return; // unknown command
byte msg [] = {
0, // device 0 (master)
3, // turn light on command received
};
delay (1); // give the master a moment to prepare to receive
digitalWrite (ENABLE_PIN, HIGH); // enable sending
sendMsg (fWrite, msg, sizeof msg);
digitalWrite (ENABLE_PIN, LOW); // disable sending
analogWrite (11, buf [2]); // set light level
} // end if something received
} // end of loop