Arduino Uno, MAX485 TTL to RS-485 컨버터 모듈을 사용하였고, 개발 환경은 Arduino IDE 2.2.1 입니다.
구상도
송수신 과정
1번: Master "A LED ON"을 전송한다.
2번: Slave A/B가 "A LED ON"을 수신받는다. 그리고 Slave A는 LED를 켠다.
3번: Slave A가 "A LED ON"을 전송한다. 그리고 Master는 LED(A 상태)를 킨다.
4번: Master가 "B LED ON"을 전송한다.
5번: Slave A/B가 "B LED ON"을 수신받는다. 그리고 Slave B는 LED를 켠다.
6번: Slave B가 "B LED ON"을 전송한다. 그리고 Master는 LED(B 상태)를 킨다.
7번: Master가 "A LED OFF"을 전송한다.
8번: Slave A/B가 "A LED OFF"을 수신받는다. 그리고 Slave A는 LED를 끈다.
9번: Slave A가 "A LED OFF"을 전송한다. 그리고 Master는 LED(A 상태)를 끈다.
10번: Master가 "B LED OFF"을 전송한다.
11번: Slave A/B가 "B LED OFF"을 수신받는다. 그리고 Slave B는 LED를 끈다.
12번: Slave B가 "B LED OFF"을 전송한다. 그리고 Master는 LED(B 상태)를 끈다.
배선
<참고 자료>
https://blog.naver.com/kwy1052aa/221740261100
코드 - Master
#include <SoftwareSerial.h>
#define RS485Control 7
#define ledA 8
#define ledB 9
SoftwareSerial rs485(2, 3);
char* commandStr[] = {"A LED ON!", "B LED ON!", "A LED OFF!", "B LED OFF!"};
unsigned char receiveEndFlag = 0;
unsigned char sendFlag = 1;
unsigned char commandCnt = 0;
unsigned int sendBufCnt = 0;
unsigned int receiveBufCnt = 0;
char sendBuff[50] = {0};
char receiveBuff[50] = {0};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("=========Master START========");
rs485.begin(9600);
pinMode(RS485Control, OUTPUT);
pinMode(ledA, OUTPUT);
pinMode(ledB, OUTPUT);
digitalWrite(RS485Control, HIGH);
}
void loop() {
// put your main code here, to run repeatedly:
if(receiveBuff[0] == 0 && sendFlag == 1) { // send command
digitalWrite(RS485Control, HIGH);
strcpy(sendBuff, commandStr[commandCnt]);
while(1){
rs485.write(sendBuff[sendBufCnt]);
Serial.print(sendBuff[sendBufCnt]);
if(sendBuff[sendBufCnt++] == '!') {
sendBufCnt = 0;
break;
}
delay(100);
}
Serial.print("\tMASTER 전송 완료\n");
delay(3000);
if(commandCnt == 3) commandCnt = 0;
else commandCnt++;
digitalWrite(RS485Control, LOW);
sendFlag = 0;
}
if(rs485.available()) { // receive command
receiveBuff[receiveBufCnt] = rs485.read();
Serial.print(receiveBuff[receiveBufCnt]);
if(receiveBuff[receiveBufCnt++] == '!') {
receiveEndFlag = 1;
receiveBufCnt = 0;
Serial.print("\tMASTER 수신 완료\n");
delay(3000);
}
delay(100);
}
if(receiveBuff[0] != 0 && receiveEndFlag == 1) { //process receive message
if(receiveBuff[0] == 'A') {
if(strncmp(&receiveBuff[6], "ON", 2) == 0) digitalWrite(ledA, HIGH);
else if(strncmp(&receiveBuff[6], "OFF", 3) == 0) digitalWrite(ledA, LOW);
else Serial.println("receive Fail");
}
else if(receiveBuff[0] == 'B') {
if(strncmp(&receiveBuff[6], "ON", 2) == 0) digitalWrite(ledB, HIGH);
else if(strncmp(&receiveBuff[6], "OFF", 3) == 0) digitalWrite(ledB, LOW);
else Serial.println("receive Fail");
}
else Serial.println("receive Fail");
memset(receiveBuff, 0, sizeof(receiveBuff));
receiveEndFlag = 0;
sendFlag = 1;
}
}
코드 - Slave A
#include <SoftwareSerial.h>
#define RS485Control 7
#define ledA 8
SoftwareSerial rs485(2, 3);
unsigned char receiveEndFlag = 0;
unsigned char sendFlag = 0;
unsigned int sendBufCnt = 0;
unsigned int receiveBufCnt = 0;
unsigned char ledState = 0;
char sendBuff[50] = {0};
char receiveBuff[50] = {0};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.write("==========Slave START==========\n");
rs485.begin(9600);
pinMode(RS485Control, OUTPUT);
pinMode(ledA, OUTPUT);
digitalWrite(RS485Control, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
if(receiveBuff[0] == 0 && sendFlag == 1) { // send command
digitalWrite(RS485Control, HIGH);
if(ledState == 1) strcpy(sendBuff, "A LED ON!");
else strcpy(sendBuff, "A LED OFF!");
while(1){
rs485.write(sendBuff[sendBufCnt]);
Serial.print(sendBuff[sendBufCnt]);
if(sendBuff[sendBufCnt++] == '!') {
sendBufCnt = 0;
break;
}
delay(100);
}
Serial.print("\tSLAVE 전송 완료\n");
delay(3000);
digitalWrite(RS485Control, LOW);
sendFlag = 0;
}
if(rs485.available()) { // receive command
receiveBuff[receiveBufCnt] = rs485.read();
Serial.print(receiveBuff[receiveBufCnt]);
if(receiveBuff[receiveBufCnt++] == '!') {
receiveEndFlag = 1;
receiveBufCnt = 0;
Serial.print("\tSLAVE 수신 완료\n");
delay(3000);
}
delay(100);
}
if(receiveBuff[0] != 0 && receiveEndFlag == 1) { //process receive message
if(receiveBuff[0] == 'A') {
if(strncmp(&receiveBuff[6], "ON", 2) == 0) {
digitalWrite(ledA, HIGH);
ledState = 1;
}
else if(strncmp(&receiveBuff[6], "OFF", 3) == 0) {
digitalWrite(ledA, LOW);
ledState = 0;
}
else Serial.println("receive Fail");
memset(receiveBuff, 0, sizeof(receiveBuff));
receiveEndFlag = 0;
sendFlag = 1;
}
else{
memset(receiveBuff, 0, sizeof(receiveBuff));
receiveEndFlag = 0;
}
}
}
코드 - Slave B
#include <SoftwareSerial.h>
#define RS485Control 7
#define ledB 8
SoftwareSerial rs485(2, 3);
unsigned char receiveEndFlag = 0;
unsigned char sendFlag = 0;
unsigned int sendBufCnt = 0;
unsigned int receiveBufCnt = 0;
unsigned char ledState = 0;
char sendBuff[50] = {0};
char receiveBuff[50] = {0};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.write("==========Slave START==========\n");
rs485.begin(9600);
pinMode(RS485Control, OUTPUT);
pinMode(ledB, OUTPUT);
digitalWrite(RS485Control, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
if(receiveBuff[0] == 0 && sendFlag == 1) { // send command
digitalWrite(RS485Control, HIGH);
if(ledState == 1) strcpy(sendBuff, "B LED ON!");
else strcpy(sendBuff, "B LED OFF!");
while(1){
rs485.write(sendBuff[sendBufCnt]);
Serial.print(sendBuff[sendBufCnt]);
if(sendBuff[sendBufCnt++] == '!') {
sendBufCnt = 0;
break;
}
delay(100);
}
Serial.print("\tSLAVE 전송 완료\n");
delay(3000);
digitalWrite(RS485Control, LOW);
sendFlag = 0;
}
if(rs485.available()) { // receive command
receiveBuff[receiveBufCnt] = rs485.read();
Serial.print(receiveBuff[receiveBufCnt]);
if(receiveBuff[receiveBufCnt++] == '!') {
receiveEndFlag = 1;
receiveBufCnt = 0;
Serial.print("\tSLAVE 수신 완료\n");
delay(3000);
}
delay(100);
}
if(receiveBuff[0] != 0 && receiveEndFlag == 1) { //process receive message
if(receiveBuff[0] == 'B') {
if(strncmp(&receiveBuff[6], "ON", 2) == 0) {
digitalWrite(ledB, HIGH);
ledState = 1;
}
else if(strncmp(&receiveBuff[6], "OFF", 3) == 0) {
digitalWrite(ledB, LOW);
ledState = 0;
}
else Serial.println("receive Fail");
memset(receiveBuff, 0, sizeof(receiveBuff));
receiveEndFlag = 0;
sendFlag = 1;
}
else{
memset(receiveBuff, 0, sizeof(receiveBuff));
receiveEndFlag = 0;
}
}
}
테스트 결과
<참고 자료>
https://powerdeng.tistory.com/213
<첨부 자료>
'개발환경 > Arduino IDE' 카테고리의 다른 글
Timer Interrupt 설정 - ATSAMD21G18A (1) | 2023.11.19 |
---|