PC -> Convertor -> MAX485 ->Leonardo

Тема в разделе "Arduino & Shields", создана пользователем Rustam96, 23 сен 2019.

  1. Rustam96

    Rustam96 Нерд

    Всем привет. Задача опросить Leonardo через RS485.
    Начал изучать этот RS485, для начало хотел просто что нибудь принять в ASCII или Байты. А Leonardo мне каждую секунду посылает 0.

    Или я вообще не правильно написал?

    Код (C++):

    #include <SoftwareSerial.h>

    SoftwareSerial RS485 (2, 3);
    const byte ENABLE_PIN = 10;

    void setup(void) {
      RS485.begin (9600);
      pinMode(ENABLE_PIN, OUTPUT);
      digitalWrite(ENABLE_PIN, LOW); // переводим модуль в режим приёма данных
      delay(100);
    }

    void loop(void) {
      digitalWrite(ENABLE_PIN, HIGH);  // переводим модуль в режим передачи данных
      RS485.write("TEST");
      // RS485.println("123");
      digitalWrite(ENABLE_PIN, LOW);  // переводим модуль в режим приёма данных
      delay(1000);
    }
     
  2. Daniil

    Daniil Гуру

    Можно схему?
    А если после rs485.write сделать задержку?
     
    Rustam96 нравится это.
  3. Rustam96

    Rustam96 Нерд

    Из доки https://doc.arduino.ua/ru/prog/SoftwareSerial в Leonardo 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). поменял на 8 и 9
    Землю GND MAX485 соединил с GND конвертера. Сделал задержку как вы сказали rs485.write. Что то посыпалось !!
    Что бы понять что я получаю изменил данные
    Код (C++):
    float mess[6]  = {1.44, 2.32, 34.666, 454.32, 53.234, 6.334};
    и в void loop(void) вместо RS485.write("TEST");
    Код (C++):
    for (int i=0; i < 6; i++){
          RS485.write(mess[i]);
          delay(10);
        }
    Начал получать
    7F F8 E3 FC E7 FC иногда 7F F8 E3 FC E7 F8 Должно быть по 4 байта на цифру, а он мне возвращает 6 байт.
    Пока не могу до конца понять.

    Схему попробую нарисовать позже выложу
     
  4. Daniil

    Daniil Гуру

    хотелось бы убедиться, что посыпался "тест".
    Проблема была в том, что вы REDE отпускали слишком рано, вот и приходил шум.
    С буквами или интами проще.
    Перед float-ами я советую поиграться с передачей байтов.
    Простой вариант передачи цифр с зпт обсуждал тут.
     
    Rustam96 нравится это.
  5. Rustam96

    Rustam96 Нерд

    Отправил
    Код (C++):
    int mess[6]  = {3, 2, 34, 45, 53, 6};
    Получил
    01 02 22 C6 35 06
    Работает Ура :)
    Схему дорисую выложу что бы тут было. И буду разбираться с float
     
    Daniil нравится это.
  6. Daniil

    Daniil Гуру

    Только 01 не в тему и С6 странные...)
     
  7. Rustam96

    Rustam96 Нерд

    Посмотрел историю 01 было Я выключил включил 03 стало
    Сейчас 03 02 22 2D 35 06 стабильно приходит.
     
    Последнее редактирование: 24 сен 2019
  8. Rustam96

    Rustam96 Нерд

  9. Rustam96

    Rustam96 Нерд

    По хорошему надо резистор на 120Ом поставить на A и B. (но надо до магаза бежать)
    Следующее я попробую разобраться
    1. Как получать float
    2. Как оправлять запросы на контроллер, вариант с
    Код (C++):
    if(RS485.available()==49){
    .....
    }
    Пока не получается. 1DEC = 49ASCII, а как получает контролер через MAX485 пока не разобрался.
    3. Подключу какой нибудь датчик и попробую его опросить.
    Тему пока не закрываем.
     
  10. Daniil

    Daniil Гуру

    рекомендую ознакомиться с примером в ардуино ide - Serial Event. Не знаю как он работает с программным портом.
    Serial.available приверяет наличие байт, чтобы с чем-то сравнить байт, всё-таки надо байт прочитать.
    По моей ссылке выше приведен пример протокола. Как формировать и читать пакеты данных.
    программно rs485 и rs232 и uart ничем не отличаются (rede только), отличается у них только физика. Макс485 эту физику и реализует, поэтому что было на входе, то будет и на выходе.
     
    Последнее редактирование: 24 сен 2019
  11. Daniil

    Daniil Гуру

    Сразу оставлю пару ссылок - раз и два.
    На малых скоростях и длинах резисторы ничего не изменят. На высоких скоростях и длинах резисторы понадобятся их номиналы отдельный холивар, по 2ой ссылке какие-то указаны, но всё равно надо думать)
     
  12. Rustam96

    Rustam96 Нерд

    По float нашел статью float-uart
    передаю произвольные цифры
    Код (C++):
    float mess[6]  = {1.44, 2.32, 34.666, 454.32, 53.234, 6.334};
    совсем чуть чуть поменял функцию из статьи.
    Код (C++):
    void write_float(float f)
    {
      unsigned char *ptr;
      char i;
      ptr = (unsigned char *)&f;
      for (i=0;i<4;i++){
        RS485.write(*(ptr+i));
      }
    }
    и в loop() изменил вывод
    Код (C++):
    for (int e=0; e < 6; e++){
          write_float(mess[e]);
          delay(10);
        }
    Работает, правда задом наперед байты идут.
    EC 51 B8 3F E1 7A 14 40 FC A9 0A 42 F6 28 E3 43 9E EF 54 42 21 B0 CA 40
     
    Daniil нравится это.
  13. Daniil

    Daniil Гуру

    Спасибо, за статейку.
    Цикл можно развернуть в другую сторону.
    For (i=3; i==0; i--)
    ...
     
    Rustam96 нравится это.
  14. Rustam96

    Rustam96 Нерд

    Разобрался с
    Код (C++):
    if(RS485.available()==1){
       .....
    }
    Отправляем HEX 31 он равен ASCII 49 или DEC 1, я привык что отправляя в "COM порт arduino" цифру 1 контроллер принимает в ASCII 49, но тут так не работало. Пришлось использовать Hercules для теста. За одно убедился в том что при этой схеме контроллер принимает данные.

    С датчиком примера не будет. Для этой статьи хватит. Daniil большое спасибо.
    Возможные развитие: В цепочку поставить несколько контроллеров с max485 назначить им адреса и опрашивать их по данным адресам. Но тут нужно писать свой протокол обмена или использовать стандартный протокол типа modbus.
     
    Daniil нравится это.
  15. Rustam96

    Rustam96 Нерд

    Я не правильно написал, RS485.available() считает количество байт в буфере и если я посылаю 1 байт в данном случае выполняет условия. А считывает байты read.
     
    Daniil нравится это.