RS485 Arduino

RS485 — это последовательный интерфейс передачи данных. Максимальная длина линии при соединении по RS485 составляет 1200 метров. В качестве кабеля для RS485 используется витая пара. Это два провода, сплетенные друг с другом. Чтобы передавать данные на дистанции более 500 метров, потребуется экранированная витая пара.

Для того, чтобы соединить две платы Ардуино по интерфейсу RS485 нам потребуется модуль RS485 в которой используется микросхема MAX485.

В Ардуино реализована аппаратная поддержка интерфейса последовательной передачи данных через цифровые выводы 0 и 1 (которые также используются для связи с компьютером посредством USB). Аппаратная работа с последовательным интерфейсом осуществляется с помощью встроенного в микроконтроллер специального устройства, называемого приемопередатчиком UART.  Библиотека SoftwareSerial которую будем использовать для передачи данных позволяет реализовать последовательный интерфейс практически на любых цифровых выводах Ардуино с помощью программных средств, дублирующих функциональность UART.

Технические характеристики модуля TTL – RS485:

  • Напряжение питания – 5 В;
  • Ток потребления – 10 мА;
  • Ток потребления в режиме ожидания – 5 мА;
  • Скорость передачи данных – до 2,5 Мбит/с;
  • Рабочая температура – 0-70 °С;
  • Размер – 44x14x20 мм.

Назначение контактов:

  • Vcc – питание модуля 5 В;
  • GND – земля;
  • DI – вход передатчика;
  • RO – выход приёмника;
  • DE – разрешение работы передатчика;
  • RE – разрешение работы приёмника;
  • A – линия передачи;
  • B – линия передачи.

Выводы DE и RE необходимо замкнуть между собой.

Выводы модуля A и B, являются выводами линии передачи данных, при этом все модули на линии соединяются одноименными выводами.

Рассмотрим пример использования модулей TTL – RS485 для передачи данных от одной платы Arduino к другой. К первой плате Arduino подключим датчик температуры DS18B20 и будем передавать значение температуры через линию связи RS485 во вторую плату Arduino. К первой плате Arduino может быть подключено несколько датчиков, значения которых можно передавать, для примера, помимо данных о температуре будем передавать число 12.

Скетч для первой платы Arduino (передача данных)

#include <SoftwareSerial.h> // Входит в состав Arduino IDE
#include <OneWire.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip
#include <DallasTemperature.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/DallasTemperature.zip
  OneWire oneWire(A0);// вход датчика 18b20
  DallasTemperature temp(&oneWire);    
  SoftwareSerial rs485(10, 11); // RO и DI
 
void setup() {
  rs485.begin(9600);
  temp.begin(); 
  temp.setResolution(12);//12 бит           
  pinMode(4,OUTPUT);              
  digitalWrite(4,HIGH); // DE-RE оправка данных           
}
 
void loop() { 
    temp.requestTemperatures();
    int t = temp.getTempCByIndex(0)*10;
    rs485.print(100000+t); // 1 - код датчика
    delay(1000);
    rs485.print(200012); // 2 - код датчика
    delay(1000);
}//loop

Скетч для второй платы Arduino (прием данных)

#include <SoftwareSerial.h>   // Входит в состав Arduino IDE
SoftwareSerial rs485(10, 11);  // RO и DI               
long buff;
 
void setup() {
  Serial.begin(9600);     
  rs485.begin(9600); 
  pinMode(4,OUTPUT);               
  digitalWrite(4,LOW); // DE-RE прием данных
}
 
void loop() {
  if( rs485.available() ){
    delay(5); 
  while( rs485.available()>0 ){ 
      buff = rs485.parseInt();
 
      int i = buff/100000; // получение кода датчика
 
      if(i==1){  // если код датчика верен, то выводим значение
      float t = float(buff-100000)/10;
      Serial.println(t,1);}
 
      if(i==2){Serial.println(buff-200000);}          
  }}
}//loop

Полученная информация выводится в монитор порта (со второй платы Arduino)

Как видно на скриншоте, в монитор порта поочередно выводится значение температуры и число 12 полученные с первой платы Arduino.


В следующем примере показан пример использования модулей TTL – RS485 в качестве терморегулятора. Первая плата Arduino управляет первым модулем TTL – RS485, снимает показания цифрового датчика DS18B20 и управляет работой модуля реле (выход D13). Ко второй плате Arduino подключены LCD1602 экран (через I2C модуль PCF8574) и две кнопки, с помощью которых можно установить температуру регулирования.

Модули TTL – RS485 работаю как на прием данных, так и на отправку данных. При регулировке температуры, информация  о температуре регулирования со второй платы Arduino передается на первую плату, как только данные о температуре поступили на первую плату, она отправляет эти данные обратно во вторую плату для подтверждения удачного приема температуры регулирования. При не удачном приеме данных об температуре регулирования, вторая плата не получит подтвержденную температуру от первой, поэтому отправка данных будет повторяться до получения подтверждения от первой платы.

Скетч для первой платы

#include <DallasTemperature.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/DallasTemperature.zip
#include <SoftwareSerial.h> // Входит в состав Arduino IDE 
#include <OneWire.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip #include <DallasTemperature.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/DallasTemperature.zip
#include <EEPROM.h> // Входит в состав Arduino IDE 
  OneWire oneWire(A0);// вход датчика 18b20
  DallasTemperature temp(&oneWire);    
  SoftwareSerial rs485(10, 11); // RO и DI
 
  int r,t,w;
  long buff;
 
void setup() {
  rs485.begin(9600);
  temp.begin(); 
  temp.setResolution(12);//12 бит           
  pinMode(4,OUTPUT);              
  pinMode(13,OUTPUT);  
  r=EEPROM.read(0);   
}
 
void loop() { 
  ///////// прием данных
  digitalWrite(4,LOW); // DE-RE прием данных
  delay(300);
  if( rs485.available() ){
  while( rs485.available()>0 ){buff = rs485.parseInt();}
   int i = buff/1000; // получение кода датчика
  if(i==3){r = buff-3000;}} 
  else{
    ///////// отправка данных  
  digitalWrite(4,HIGH); // DE-RE оправка данных 
 
    temp.requestTemperatures();
    t = temp.getTempCByIndex(0)*10;
 
    rs485.print(1000 + t); // 1 - код датчика
    delay(1000);
    rs485.print(2000 + r); // 2 - код датчика
    delay(1000);
    EEPROM.update(0,r);
  }
  if(r >= t/10 + 1){digitalWrite(13,HIGH);}
  if(r <= t/10 - 1){digitalWrite(13,LOW);}
}//loop

Скетч для второй платы

#include <SoftwareSerial.h>   // Входит в состав Arduino IDE  
#include <Wire.h> // Входит в состав Arduino IDE 
#include <EEPROM.h>  // Входит в состав Arduino IDE 
#include <LiquidCrystal_I2C.h> //Библиотека - http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей
 SoftwareSerial rs485(10, 11);  // RO и DI               
 long buff;
 float t;
 int reg,r,w=1,w1=1;
 
void setup() {
  Serial.begin(9600);     
  rs485.begin(9600); 
  pinMode (7,INPUT_PULLUP);
  pinMode (8,INPUT_PULLUP);
  lcd.init();                     
  lcd.backlight();// Включаем подсветку дисплея
  pinMode(4,OUTPUT);                
  reg = EEPROM.read(0);
}
 
void loop() {
  if(digitalRead(7)==LOW){reg++;w=1;w1=1;if(reg>125){reg=125;}}
  if(digitalRead(8)==LOW){reg--;w=1;w1=1;if(reg<0){reg=0;}}
 
  if(w1==1){
    lcd.setCursor(0, 1);lcd.print("REG = ");lcd.print(reg);lcd.print((char)223);lcd.print("C");
    w1=0;delay(200);EEPROM.update(0,reg);}
    else{
 
  if(w==0){
  ///////// прием данных
  digitalWrite(4,LOW); // DE-RE прием данных
  if( rs485.available() ){ 
  while( rs485.available()>0 ){buff = rs485.parseInt();}
 
      int i = buff/1000; // получение кода датчика
 
      if(i==1){t = float(buff-1000)/10;}
      if(i==2){r = buff-2000;} 
      if(r!=reg){w=1;}         
 
  lcd.setCursor(0, 0);lcd.print("T = ");lcd.print(t,1);lcd.print((char)223);lcd.print("C");
  lcd.setCursor(12, 0);
  if(r >= t + 1){lcd.print("OFF");}else{lcd.print("ON ");}
 
  lcd.setCursor(0, 1);lcd.print("REG = ");lcd.print(reg);lcd.print((char)223);lcd.print("C");
  lcd.print(" (");lcd.print(r);lcd.print(")  ");
  }
  }
 
  if(w==1){
     ///////// отправка данных  
  digitalWrite(4,HIGH); // DE-RE оправка данных 
 
  rs485.print(3000 + reg); // 3 - код датчика
  delay(100);w=0;}// w=1
    }
}//loop

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

Войти с помощью: