Передача данных между Arduino

Тема в разделе "Arduino & Shields", создана пользователем VXXXV, 1 дек 2016.

  1. VXXXV

    VXXXV Нуб

    Здравствуйте, собираю систему управления в машину. Состоит из центрального блока на меге и несколько блоков (нано) управления разбросанных по кузову. Все соединено по RS485. Когда сделал первый блок, сконектил к меге без проблем, затем сделал второй, подправил что-то в меге и все, данные теряются.
    Менял только время между командами. Пробовал подстраивать сейчас, не получается. Затем подправил еще скетч, добавил проверку первого и последнего байта. В итоге снова какой то мусор.
    Вот кусок кода slave:
    Код (C++):
    if (RS.available()>=1){byte id=RS.read();
         if(id==30){digitalWrite(13,HIGH);//старт передачи
                    delay(2);
                    RS.write(IDcol),      
                    RS.write(frost),    
                    RS.write(abs(Tmp)),  
                    RS.write(abs(tempd)),  
                    RS.write(spray),    
                    RS.write(Gal),      
                    RS.write(int(MinT)),  
                    RS.write(int(MaxT)),  
                    RS.write(PWM1),      
                    RS.write(PWM2),      
                    RS.write(PWMS),      
                    RS.write(AC),        
                    RS.write(LS),        
                    RS.write(HS),        
                    RS.write(EST),        
                    RS.write(IDcol);      
                    delay(10);
                    digitalWrite(13,LOW);}//стоп передачи
                    }
    А вот прием на мастере:
    Код (C++):
    digitalWrite(13,HIGH);
    delay(1);
    Serial1.write(30);
    delay(1);
    digitalWrite(13,LOW);
    delay(5);
    if (Serial1.available()){   idcol = Serial1.peek();
                                    if(idcol==30){
                                    idcol = Serial1.read();
                                    Frost = Serial1.read();
                                    Tmp1 = Serial1.read();
                                    Tmp2 = Serial1.read();
                                    spray = Serial1.read();
                                    Gal = Serial1.read();
                                    MinT = Serial1.read();
                                    MaxT = Serial1.read();
                                    PWM1 = Serial1.read();
                                    PWM2 = Serial1.read();
                                    PWMS = Serial1.read();
                                    AC = Serial1.read();
                                    LS = Serial1.read();
                                    HS = Serial1.read();
                                    EST = Serial1.read();
                                    IDcol = Serial1.read();
                                    if(idcol==IDcol){ID30_OK=1;}else{ID30_OK=0;}
                                   }}
    Думал уже сделать по протоколу ModBus, но ничего сверхестественного в нем не увидел. Скорость передачи ставил разную, сейчас 57600. Всю неделю пробую, но без результатно, может кто что посоветует, буду благодарен.
     
  2. Radius

    Radius Гик

    В конце линии RS485 резистор 120 Ом стоит? Возможно, что такой резистор стоит в каждом модуле RS485, а должен быть один в конце линии. Осциллографом можете ткнуться и посмотреть форму сигналов? Может все дело не в программе, а в "железе"?
     
  3. Neilon

    Neilon Нерд

    Поправка. Этих резисторов должно быть два (терминаторы), каждый по 120 Ом в случае если линия не слишком длинная, тут как раз такой случай. Они должны стоять на самых удалённых концах шины.
    Т.е. если вы встанете на отключеную шину омметром, он должен показать 60 Ом.
    Практика показала, что большинство приёмопередатчиков до определённого расстояния и без них могут нормально работать, но если вам нужна надёжность, то они должны быть.

    Что касается программной части. Непонятен принцип работы протокола.
    Обычно делают так. Один мастер, несколько слэйвов. Мастер по очереди опрашивает слэвы(т.е. например шлёт в шину идентификатор каждого слэйва по очереди), принимает ответ. в результате сообщения никогда не будут пересекаться, логика всегда ясная, порядок и гармония и ненужно никакого арбитража.
    Советую так и сделать.

    Ну и конкретно по коду. Было бы неплохо иметь какие-то минимальные промежутки времени между пакетами и даже между передаваемыми байтами. Ну так, на всякий случай.
     
  4. VXXXV

    VXXXV Нуб

    Резисторы стоят, хотя работало и без них, т.к. все это на столе и провод 70см сейчас. По поводу программы, я как раз так и делаю. Мастер шлет 30 в сеть, слейв принимает, и если это он, то шлет посылку. Скорость уже поменял на 9600, игрался с задержками, результата нет.
    Сейчас при запуске монитора выдает пару правильных строк, именно когда включаю монитор.
    прием норм.jpg
     
  5. Neilon

    Neilon Нерд

    У тебя проблема с алгоритмом приёмом данных от слэйва. У тя там щас каша. Сделай автомат, который из первого состояния передаст запрос, во втором состоянии будет поочереди принимать байты из UART - 1 байт за проход автомата, пока не примет нужное кол-во байт, потом задержка и автомат в первое состояние
     
  6. VXXXV

    VXXXV Нуб

    т.е. отослать id в слейв, потом прочитать с буфера присланное? каждый параметр так?
     
  7. Neilon

    Neilon Нерд

    да, перед каждым чтением параметра проверять available порта.
     
  8. VXXXV

    VXXXV Нуб

    В общем отвязался я от софтсериала на хардовый. Сделал уже два блока, освещение и охлаждение, если в мастер залить только работу с одним блоком, все работает безупречно, но если залить прошивку с работой двух сразу, начинаются глюки. Алгоритмы передачи там однотипные. Что может быть не так?
     
  9. Neilon

    Neilon Нерд

    текст программы в студию.