Программа для передачи в обе стороны

Ардуино: передача данных на большие расстояния — RS485

Первая Ардуино уже не будет постоянно в режиме передатчика, она будет менять режим на приёмник в момент отправки сообщения. Вторая плата будет вести себя аналогичным образом.

Программа для первой платы Ардуино

#define SerialTxControl 2
#define RS485Transmit HIGH
#define RS485Receive LOW

char buffer[100];
byte state = 0;

unsigned long ping_next, t;
unsigned int ping_to = 500;

void setup(void) {
    Serial.begin(115200);
    pinMode(13, OUTPUT); 
    pinMode(SerialTxControl, OUTPUT);
    digitalWrite(SerialTxControl, RS485Receive);
}
 
void loop(void) {
    int i=0;
    if( Serial.available() ){
        delay(5);
        while( Serial.available() ){
            buffer[i++] = Serial.read();
        }
        if(i>0){
            buffer[i++]='\0';
            if( !strcmp(buffer, "pong") ){
                digitalWrite(13, state);
                state = !state;
            }
        }
    }
    // каждые 500 мс отправляем текст "ping"
    t = millis();
    if( t>ping_next ){
        ping_next = t + ping_to;
        digitalWrite(SerialTxControl, RS485Transmit);
        Serial.print("ping"); 
        delay(5);
        digitalWrite(SerialTxControl, RS485Receive);
    }
}

Первая плата отправляет текст «ping» каждые 500 мс. Делается это не с помощью delay, а с помощью таймаутов, о которых мы подробно говорили на одном из уроков: Ардуино: параллельное выполнение задач по таймеру

Программа для второй платы Ардуино

#define SerialTxControl 2
#define RS485Transmit HIGH
#define RS485Receive LOW

char buffer[100];
byte state = 0;

void setup(void) {
    Serial.begin(115200);
    pinMode(13, OUTPUT); 
    pinMode(SerialTxControl, OUTPUT); 
    digitalWrite(SerialTxControl, RS485Receive); 
}
 
void loop(void) {
    int i=0;
    if( Serial.available() ){
        delay(5);
        while( Serial.available() ){
            buffer[i++] = Serial.read();
        }
        if(i>0){
            buffer[i++]='\0';
            if( !strcmp(buffer, "ping") ){
                digitalWrite(13, state);
                state = !state;
                digitalWrite(SerialTxControl, RS485Transmit);
                Serial.print("pong"); 
                delay(10);
                digitalWrite(SerialTxControl, RS485Receive);
            }
        }
    }
}

Загружаем программы. В результате, вторая плата Ардуино будет каждые 500 миллисекунд зажигать встроенный светодиод на выводе №13. Сразу вслед за этим светодиод будет зажигаться и на первой Ардуино. Ещё через 500 мс, светодиоды погаснут в той же последовательности. И так далее.


Изменено:

Ардуино: передача данных на большие расстояния — RS485: 3 комментария

  1. Светодиод не мигает, хотя pjng приходит, проверено через монитор порта, функция сравнения почему-то не работает.

  2. По стандарту полагается тянуть не только линии A и B, но и общий провод, подключая его через последовательный 100-омный резистор на каждом устройстве — это необходимо для уравнивания потенциалов, без него входы могут и погореть. Жаль, что на платке клеммник не имеет такой возможности. Не смертельно, конечно — можно и внешний поставить, а этот использовать для подключения терминатора.
    Кстати, интересно: организовано ли смещение линий A и B? Этих модулей у меня пока нет, куплю — проверю.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.