Связь двух arduino через Serial

Тема в разделе "Arduino & Shields", создана пользователем gfox, 13 дек 2017.

  1. gfox

    gfox Нерд

    У тебя код с ошибками, но я понял что ты имеешь ввиду. В общем, произвел замеры и сравнил, вот результат:
    Когда нет данных:
    С кейсами: 15,50 мкс
    С массивом: 15,38 мкс

    Когда приходит не стартовый байт:
    С кейсами: 24,87 мкс (значения времени прыгают от 19,19 до 36,06, это среднее время)
    С массивом: 19,17 мкс (от 19,00 до 19,25)

    Обработка полученных данных (среднее):
    С кейсами: 2224,113 мкс
    С массивами: 2299,918 мкс

    Далее попробовал замерить быстродействие с помехами.

    Когда приходит не стартовый байт:
    С кейсами: 24,93 мкс
    С массивом: 19,50 мкс

    Обработка полученных данных (среднее):
    С кейсами: 2297,412 мкс
    С массивами: 2242,517 мкс

    Выводы:
    1. В целом обработка данных занимает одно и тоже время (так как собственно происходит одно и тоже), но вот когда данных нет и пришел не стартовый байт, то алгоритм с массивами справляется лучше, и в совокупности работает быстрее.
    2. Для того чтобы программа успевала обрабатывать данные надо установить задержку на передающем устройстве больше 3 мс.

    Вот переделанный скетч принимающей стороны:
    Код (C++):
    #include <Joystick.h>
    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(8, 9);     // RX, TX
    byte imsg[4];             // Массив кнопок byte
    bool ButtonStateBool[12];        //Массив кнопок bool
    Joystick_ Joystick;              

    void setup() {
        Joystick.begin();            // инициализация джойстика
        mySerial.begin(9600);        // инициализация порта
        mySerial.setTimeout(1);        // таймаут для порта
    }

    bool chek(){
    byte k=0;
               if(bitRead(imsg[1],0)==1) k++;
               if(bitRead(imsg[1],1)==1) k++;
               if(bitRead(imsg[1],2)==1) k++;
                                                                                        // Проверям на четность каждые 3 бита принятых данных,                                                          
               if((k&1)!=bitRead(imsg[2],4)) return false;        // если четность данных не совподает, прекращаем работу и возвращаем false
               k=0;                                                                      
             
               if(bitRead(imsg[1],3)==1) k++;
               if(bitRead(imsg[1],4)==1) k++;
               if(bitRead(imsg[1],5)==1) k++;
             
               if((k&1)!=bitRead(imsg[2],5))return false;
               k=0;
             
               if(bitRead(imsg[1],6)==1) k++;
               if(bitRead(imsg[1],7)==1) k++;
               if(bitRead(imsg[2],0)==1) k++;
             
               if((k&1)!=bitRead(imsg[2],6))return false;
               k=0;
             
               if(bitRead(imsg[2],1)==1) k++;
               if(bitRead(imsg[2],2)==1) k++;
               if(bitRead(imsg[2],3)==1) k++;
             
               if((k&1)!=bitRead(imsg[2],7))return false;

               return true;

    }

    void loop() {

    if(mySerial.available()){
           imsg[0] = imsg[1];
           imsg[1] = imsg[2];
           imsg[2] = imsg[3];
           imsg[3] = mySerial.read();                         // Получаем данные по байтам в очередь
         
           if(imsg[0]==165 && imsg[3]==189) {                // Если стартовый байт и стоповый на первом и последнем месте - пакет собран
             
               if(chek()) {                                              // Если данные проверены и все в порядке выполняем обработку
                 
                    for(int i=0;i<8;i++){                          // Переносим биты данных в логический массив, если писать сразу в Joystick, то возникают тормоза (почему так?)
                        if(bitRead(imsg[1],i)==1) ButtonStateBool[i]=true; else ButtonStateBool[i]=false;
                    }
             
                    for(int i=8;i<12;i++){
                        if(bitRead(imsg[2],i-8)==1) ButtonStateBool[i]=true; else ButtonStateBool[i]=false;
                    }

                    for (int i=0; i<12; i++) Joystick.setButton(i, ButtonStateBool[i]);        // Жмем кнопки на геймпаде
         
               }
             
           }
         
       }
     
    }
    Я по прежнему не использую CRC, так как проверка четности пока справляется без проблем. Если есть еще предложения по улучшению алгоритма, буду очень рад!
     
  2. MihaNN52

    MihaNN52 Нерд

    Процент потерь пакетов какой? Зачем отправлять что то если ни что не нажималось?
     
  3. gfox

    gfox Нерд

    Здесь я погорячился, 20 самое то :)
    Процент потерь - это для выяснения качества связи, оно меня не особо интересует, тем более что я вряд ли её улучшу.
    А я скажу зачем, тут видишь как, можно в принципе отправлять один раз, принимать и если все ок, то отправлять обратно, что все ок или не ок, а если ответа нет по таймеру отправлять повторно пока не достучишься, но это для других задач, мне это не подходит. Еще можно отправлять только когда кнопки нажаты, но тогда кто будет отжимать кнопки, не нажатая кнопка - это тоже состояние кнопки и его тоже нужно обработать. Т. е. был бы это какой-то аварийный сигнал, который большую часть времени находится в одном состоянии, то это логично, но кнопки геймпада меняют свое состояние часто, поэтому мы и шлем и 0 и 1, чтобы иметь в каждый момент актуальную информацию.
     
  4. MihaNN52

    MihaNN52 Нерд

    Вот ради интереса почитай как работает клавиатура она передает код нажатой кнопки, код отпускания кнопки и в завершении снова код кнопки чтоб знать какую кнопку отжали. Если поставить камушек типо stm32c8t6 который поддерживает прерывания на всех портах и может отправлять в усарт сообщения без участия процессора напрямую из памяти (читай о DMA) то можно сделать что то более интересное и познакомится с стм32)))
     
  5. gfox

    gfox Нерд

    Ну это уже требует время на изучения вопроса, тем более если программировать под Arduino IDE то, на сколько мне известно DMA использовать не получиться. В общем, может в будущем..
     
  6. MihaNN52

    MihaNN52 Нерд

    Надо изучать новое чтоб было где его применить.