Общение двух Atmega328p по COM порту

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

  1. Rauf

    Rauf Нерд

    Ваш код правильный в этом нет сомнения но что то происходит именно в процессе после того как я его совместил с моим. Ваш код и сейчас отдельно проверил всё норма работает и отдельно 8 сработка и 6 сработок.
     
  2. Rauf

    Rauf Нерд

    Может ли проблема связанна из-за того что я не использовал прототипы?
    У меня компилятор не ругается

    Код (C++):
    // Прототипы функций (чтобы компилятор не ругался)
    void displayData();
    void dataManager();
    void buzzer(byte pin);
    void readButtons(byte pin);
    void readSerial(byte rxPin);
    void sendData(byte txPin);
     
  3. Rauf

    Rauf Нерд

  4. Rauf

    Rauf Нерд

    -1 не выводит текстовое сообщение 8 сработки
     
  5. Rauf

    Rauf Нерд

    Проблемы в коде первого устройства я это понял по просмотру посылок серийного порта. Сейчас разбираюсь в чём дело.
     
  6. Tomasina

    Tomasina Сушитель лампочек Модератор

    у меня:
    Код (C++):
    if (c > MSG_COUNT - 1) c = 0;
    У вас:
    Код (C++):
    if(c >= MSG_COUNT-1) c =0;
    ;)
     
  7. Tomasina

    Tomasina Сушитель лампочек Модератор

    немножко оптимизации:
    строки
    Код (C++):
    #define LED_PINA 3   //relay 1
    #define LED_PINB 4   //relay 2
    #define LED_PINC 5   //relay 3
    #define LED_PIND 6   //relay 4
    #define LED_PINE 7   //relay 5
    #define LED_PINF 8   //relay 6
    #define LED_PING 9   //relay 7
    #define LED_PINJ 10  //relay 8
     
    заменяем на строку
    Код (C++):
    const byte out[MSG_COUNT] =       {3, 4, 5, 6, 7, 8, 9, 10}; // пины соответствующих реле (или LED)
     
    в setup() строки
    Код (C++):
      pinMode(LED_PINA, OUTPUT);  // LED 1
      pinMode(LED_PINB, OUTPUT);  // LED 2
      pinMode(LED_PINC, OUTPUT);  // LED 3
      pinMode(LED_PIND, OUTPUT);  // LED 4
      pinMode(LED_PINE, OUTPUT);  // LED 5
      pinMode(LED_PINF, OUTPUT);  // LED 6
      pinMode(LED_PING, OUTPUT);  // LED 7
      pinMode(LED_PINJ, OUTPUT);  // LED 8
    заменяем на строку
    Код (C++):
      for(byte pin = 0; pin < MSG_COUNT; pin++) pinMode(out[pin], OUTPUT);
    Полностью заменяем loop()
    Код (C++):
    void loop()
    {
      displayData();                // отображение информации

      if (bouncer.update())
      { //если произошло событие
        if (bouncer.read()==0)
         { //если кнопка нажата
           Serial.print('Z'); //вывод сообщения о нажатии
         }
      }

      readSerial();
    }
    и readSerial()
    Код (C++):

    void readSerial()
    {
      if (Serial.available())
      {
        char letter = Serial.read();
        switch(letter)
        {
          case 'Q': Sobitie(out[0], HIGH); break; // это первое устройство
          case 'q': Sobitie(out[0], LOW);  break;

          case 'Y': Sobitie(out[1], HIGH); break; // это второе устройство
          case 'y': Sobitie(out[1], LOW);  break;

          case 'S': Sobitie(out[2], HIGH); break;
          case 's': Sobitie(out[2], LOW);  break;

          case 'T': Sobitie(out[3], HIGH); break;
          case 't': Sobitie(out[3], LOW);  break;

          case 'U': Sobitie(out[4], HIGH); break;
          case 'u': Sobitie(out[4], LOW);  break;

          case 'V': Sobitie(out[5], HIGH); break;
          case 'v': Sobitie(out[5], LOW);  break;

          case 'W': Sobitie(out[6], HIGH); break;
          case 'w': Sobitie(out[6], LOW);  break;

          case 'X': Sobitie(out[7], HIGH); break;
          case 'x': Sobitie(out[7], LOW);  break;

          //-------------------------------------------------------------------------------
          // Ниже код для проверки действительности изменения статуса
          // на первом устройстве  и служит для избежания получения неправельных данных
          //-------------------------------------------------------------------------------
          case 'A': Serial.print('a'); delay(10); break;
          case 'B': Serial.print('b'); delay(10); break;
          case 'R': Serial.print('r'); delay(10); break;
          case 'D': Serial.print('d'); delay(10); break;
          case 'E': Serial.print('e'); delay(10); break;
          case 'F': Serial.print('f'); delay(10); break;
          case 'G': Serial.print('g'); delay(10); break;
          case 'H': Serial.print('h'); delay(10); break;
          case 'I': Serial.print('i'); delay(10); break;
          case 'J': Serial.print('j'); delay(10); break;
          case 'K': Serial.print('k'); delay(10); break;
          case 'L': Serial.print('l'); delay(10); break;
          case 'M': Serial.print('m'); delay(10); break;
          case 'N': Serial.print('n'); delay(10); break;
          case 'O': Serial.print('o'); delay(10); break;
          case 'P': Serial.print('p'); delay(10); break;

          //-------------------------------------------------------------------------------
          case 'Z': SobitiePINS(); break;
          case 'z': SobitiePINS(); break;

          default: Serial.print("ERROR: Unknown symbol.");
        }
      }
    }
     
    Вместо вкладок A-H делаем одну:
    Код (C++):
    // Информирование о статусе входа X на устройстве N
    //----------------------------------------------------------------------------------------------------------------
    void Sobitie(byte pin, boolean state)
    {
      digitalWrite(pin, !state);
      Beep(state);
      msgFlag[pin] = !state;  // ставим флаг
    }
    Обновляем вкладку Buzzer:
    Код (C++):
    // Звуковые сигналы о событиях
    void Beep(boolean state)
    {
      if(state == true)         // Сигнал перехода в нормальное состояние
      {
        tone (soundPin, 1000);  //включаем на 500 Гц
        delay(2000); //ждем 100 Мс
      }
      else                      // Сигнал о тревожном сробатовании
      {
        tone (soundPin, 1000); //включаем на 500 Гц
        delay(300); //ждем 100 Мс
        tone(soundPin, 500); //включаем на 250 Гц
        delay(300); //ждем 100 Мс
        tone(soundPin, 1000); //включаем на 100 Гц
        delay(300); //ждем 100 Мс
        tone(soundPin, 500); //включаем на 250 Гц
        delay(300); //ждем 100 Мс
        tone(soundPin, 1000); //включаем на 100 Гц
        delay(300); //ждем 100 Мс
        tone(soundPin, 500); //включаем на 250 Гц
        delay(300); //ждем 100 Мс
      }

      noTone(soundPin);
    }
    Код сократился на 42%, при той же функциональности, и стал более читаемым. :)
     
    Последнее редактирование: 18 окт 2016
    Rauf нравится это.
  8. Rauf

    Rauf Нерд

    Уважаемый Tomasina огромное вам спасибо. Вы невероятно добрый отзывчивый человек. Я исправил ошибку
    Код (C++):
    if (c > MSG_COUNT - 1) c = 0;
    заработало.

    Обнаружил проблему связанную с 10 пином. 8 переключатель на первом устройстве переназначил на 11 пин и всё заработало. Странная штука с этим пином твориться при его включении он имитирует все сработки и посылает в порт все буквы для сработки. Далее поставил тумблер с 10 пина на 11 и там та же история. Как тумблер может глючить что выдаёт столько букв в серийный если подключён только к одному пину?

    Касательно оптимизации это шедевр. Мне бы такие знания! Провёл оптимизацию и произошла странная штука первый переключатель включил 4 сработку, 2 - пятую, 3 - шестую и т.д. а глючный 10 пин сунул на экран цифры 5064.

    Главное вы помогли и у меня есть рабочая программа и всё функционирует, Боюсь оптимизация выдаст проблемы которыми я вас буду мучить.
     
  9. Tomasina

    Tomasina Сушитель лампочек Модератор

    Внешняя подтяжка к питанию у пинов 3-10 есть?

    возможен мой косяк с соответствием букв и выходных пинов в функции readSerial(), к тому времени исходные строки канули в Лету и соответствие проводилось по порядку нарастания пинов.
     
  10. Rauf

    Rauf Нерд

    Собрал на двух раздельных платах. На каждой ATMEGA-328P и SN7517. Связь есть второй отвечает, остались две задачи. Это непонятные символы на экране которые появляются после 6 одновременно включённых событиях. И вторая это если сработают 2 входа то информация на втором будет только об одном событии. Так как использую полудуплекс то приходится правильно настраивать интервалы переключения между приёмом и передачей. Можно ли как то хранить события в буфере и настроить так чтобы правильно было? Чтобы не было отправки пока на другом конце тоже идёт отправка?
     
  11. Tomasina

    Tomasina Сушитель лампочек Модератор

    раз на другом конце идет отправка, значит на этом конце надо срочно переключаться на прием, а не инициировать свою отправку. Всего два устройства в сети, несложно же договориться.
    Непонятно
    Непонятно
     
  12. Rauf

    Rauf Нерд

    Код (C++):
       if (letter == 'A')
       {
          digitalWrite(RXTX_PIN, HIGH);
          delay(5);
          Serial.print('a');
          delay(1);
          digitalWrite(RXTX_PIN, LOW);
       }
       if (letter == 'B')
       {
          digitalWrite(RXTX_PIN, HIGH);
          delay(5);
          Serial.print('b');
          delay(1);
          digitalWrite(RXTX_PIN, LOW);
       }
    //--------------------------------------  
       if (letter == 'R')
       {
          digitalWrite(RXTX_PIN, HIGH);
          delay(5);
          Serial.print('r');
          delay(1);
          digitalWrite(RXTX_PIN, LOW);
       }
       if (letter == 'D')
       {
          digitalWrite(RXTX_PIN, HIGH);
          delay(5);
          Serial.print('d');
          delay(1);
          digitalWrite(RXTX_PIN, LOW);
       }
     
  13. Rauf

    Rauf Нерд

    Это отрывок кода второго устройства, если уменьшаю delay(5); на 1 то вообще не работает. Получается если 2 сработки на первом устройстве то одно из них попадает в эти 5 мс.
     
  14. Rauf

    Rauf Нерд

    Помните видео

    под конец символы бежали. Та же ситуация. Если нужно выводить больше 6 сообщений он вот так начинает глючить. Может там есть буфер который переполняется?
     
  15. Rauf

    Rauf Нерд

    Вновь здравствуйте все!
    Я обнаружил проблему нестабильной работы передачи данных. Она заключалась в коде первого устройства, там в цикле была выставлена задержка
    Код (C++):
    delay(DEBOUNCE_TIME);
    которая ссылалась на значение 5000. Как правильно применить библиотеку Bounce в моём коде и возможно ли это применять к 8 кнопкам? не создаст ли это задержку цикла на 5 сек на каждом канале, итого 40 сек?
     
  16. Tomasina

    Tomasina Сушитель лампочек Модератор

    а откуда там взялось 5000?
    Максимум 50, потом можно еще уменьшить.
     
  17. YeS

    YeS Гик

    300 метров для rs485 это фигня. 100-200 бод это что за скорость будет такая. Для передачи одного символа конечно можно и оставить, но как то не серьёзно )
     
  18. Rauf

    Rauf Нерд

    Мне необходимо такой принцип работы. Если есть событие которое длится 5 сек то выполнить функцию. А в коде у меня получается в конце loop стоит delay 5000. Из-за этого проблемы с передачей и приёмом. Я хочу применить #include <Bounce.h> сейчас читаю о нём. Просто вы как знаток данного дела взгляните пожалуйста и скажите можно ли его применить в моём коде. Или я потрачу уйму времени над тем что изначально не совместимо с моим кодом. Вот такой пример встретил.
    Код (C++):
    // подключаем библиотеку
    #include <Bounce.h>

    #define BUTTON 2
    #define LED 13

    // создаем объект для чтения кнопки без дребезга
    Bounce bouncer = Bounce( BUTTON,5 );

    void setup() {
      pinMode(BUTTON,INPUT);
      pinMode(LED,OUTPUT);
    }

    void loop() {
      // обновляем состояние кнопки
      bouncer.update ( );

      // пишем на ножку светодиода состояние кнопки
      digitalWrite(LED, bouncer.read());
    }
     
  19. Rauf

    Rauf Нерд

    Скорость выставлена такая.
    Код (C++):
    Serial.begin(9600, SERIAL_8E1);
     
  20. Rauf

    Rauf Нерд

    или вот такой есть пример
    Код (C++):
    #include <Bounce.h>
    #define BUTTON7 7
    #define BUTTON6 6

    #define BUTTON5 5
    #define BUTTON4 4

    #define BUTTON3 3
    #define BUTTON2 2

    #define LED 13
    int state7 = 0;
    int prevstate7 = 0;
    int state6 = 0;
    int prevstate6 = 0;

    int state5 = 0;
    int prevstate5 = 0;
    int state4 = 0;
    int prevstate4 = 0;

    int state3 = 0;
    int prevstate3 = 0;
    int state2 = 0;
    int prevstate2 = 0;

    Bounce bouncer7 = Bounce( BUTTON7,5 );
    Bounce bouncer6 = Bounce( BUTTON6,5 );

    Bounce bouncer5 = Bounce( BUTTON5,5 );
    Bounce bouncer4 = Bounce( BUTTON4,5 );

    Bounce bouncer3 = Bounce( BUTTON3,5 );
    Bounce bouncer2 = Bounce( BUTTON2,5 );


    void setup() {
      Serial.begin(115200);
      pinMode(BUTTON7,INPUT);
      pinMode(BUTTON6,INPUT);
      pinMode(LED,OUTPUT);
    }
    void loop() {
    // 7 кнопка начало
      bouncer7.update ( );
    int value7 = bouncer7.read();
    if ( value7 == HIGH) {
       digitalWrite(LED, HIGH );
       state7 = 1;
    } else {
        digitalWrite(LED, LOW );
        state7 = 0;  
    }
    if(state7 != prevstate7){
       if(state7 == 1){
       Serial.println("7");
       }
    }
    prevstate7 = state7;
    // 7 кнопка конец
    // 6 кнопка начало
    bouncer6.update ( );
    int value6 = bouncer6.read();
    if ( value6 == HIGH) {
       digitalWrite(LED, HIGH );
       state6 = 1;
    } else {
        digitalWrite(LED, LOW );
        state6 = 0;  
    }
    if(state6 != prevstate6){
       if(state6 == 1){
       Serial.println("6");
       }
    }
    prevstate6 = state6;
    // 6 кнопка конец

    // 5 кнопка начало
    bouncer5.update ( );
    int value5 = bouncer5.read();
    if ( value5 == HIGH) {
       digitalWrite(LED, HIGH );
       state5 = 1;
    } else {
        digitalWrite(LED, LOW );
        state5 = 0;  
    }
    if(state5 != prevstate5){
       if(state5 == 1){
       Serial.println("5");
       }
    }
    prevstate5 = state5;
    // 5 кнопка конец
    // 4 кнопка начало
    bouncer4.update ( );
    int value4 = bouncer4.read();
    if ( value4 == HIGH) {
       digitalWrite(LED, HIGH );
       state4 = 1;
    } else {
        digitalWrite(LED, LOW );
        state4 = 0;  
    }
    if(state4 != prevstate4){
       if(state4 == 1){
       Serial.println("4");
       }
    }
    prevstate4 = state4;
    // 4 кнопка конец


    // 3 кнопка начало
    bouncer3.update ( );
    int value3 = bouncer3.read();
    if ( value3 == HIGH) {
       digitalWrite(LED, HIGH );
       state3 = 1;
    } else {
        digitalWrite(LED, LOW );
        state3 = 0;  
    }
    if(state3 != prevstate3){
       if(state3 == 1){
       Serial.println("3");
       }
    }
    prevstate3 = state3;
    // 3 кнопка конец
    // 2 кнопка начало
    bouncer2.update ( );
    int value2 = bouncer2.read();
    if ( value2 == HIGH) {
       digitalWrite(LED, HIGH );
       state2 = 1;
    } else {
        digitalWrite(LED, LOW );
        state2 = 0;  
    }
    if(state2 != prevstate2){
       if(state2 == 1){
       Serial.println("2");
       }
    }
    prevstate2 = state2;
    // 2   кнопка конец


    }