Общение двух Atmega328p по COM порту
- Войдите на сайт для отправки комментариев
Здравствуйте уважаемые форумчане.
Так как я начинающий в этом деле прошу не бронить меня.
Мне необходима Ваша помощь в создании связи между двух Atmega328p.
Задача состоит в следующем. Два помещения находятся на расстоянии 300 метров между которыми есть холостая витая пара. В помещении первом стоит одна Atmega328p настроенная на приём 8 событий, вторая же Atmega328p на приём и информирование о событиях в первом помещении. Я настроил оба контроллера и они общаются между собой через COM по RX/TX пинам, после завершения пилотирования поставлю RS485.
Логика и схема такова:
1 – контроллер –
· 8 пинов на вход событий
· 1 пин лед отклик от второго устройства что он не завис
· 1 пин переключение режима на RS485
2 – Контроллер
· 8 пинов леды информирующие о сработке на первом контроллере
· 1 пин лед отклик от первого устройства что он не завис
· 1 пин кнопка при нажатии которого посылается код опроса первого устройства на котором 3 раза моргнёт лед и вернётся код об успешном отклике, затем 3 раза маргнёт лед на втором устройстве.
· 1 пин пищалка в случае любого события на первом контроллере пищит
· 2 пина LED дисплей 16х2 по I2C на котором тоже высвечивается информация о сработке.
ЛОГИКА:
ДЕЙСТВИЕ СРАБОТКА
1 Контроллер – в случае сработки посылает в COM букву или цифру соответствующую данному действию.
2 Контроллер приняв букву выполняет действия (зажигает лед, пищит, пишет на экране)
Точно также происходит выключение действия.
ДЕЙСТВИЕ ПРОВЕРКА СВЯЗИ
Только со второго контроллера по нажатию кнопки отправляется буква в серийный порт на который реагирует первый контроллер трёх разовым морганием и ответом в порт буквой и соответственно на втором тоже начинает мигать лед 3 раза и уже становится ясно что связь есть и контроллер не завис.
В чём нужна Ваша помощь:
1 – для избежания ложных сработок при помехах на линии которая будет 300 метров я дописал в коде чтобы каждое событие пересылалось 3 раза подряд, но хочу чтобы на втором контроллере происходило суммирование и сверка затем одно действие.
Например – пришло событие: B B B - где каждое B это отдельная команда принта в серийный порт, а второй контроллер приняв данное сообщение соединил их в одно значение “BBB” и выполнил условие как у меня сейчас выставлено на одну “B”.
2 – скорее всего я пытаюсь изобрести колесо и всё уже есть и работает но я не смог найти подходящий мне вариант. Как быть если была сработка а ВВВ дошло повреждённым например «ВАА»? как создать условие если пришло что то что не совпадает ни с одной из 16 команд заного запросить событие с первого устройства?
3 – можно ли сделать мануальный или циклический опрос портов на первом устройстве со второго устройства?
Это код первого устройства:
#include <LiquidCrystal_I2C.h> #include <Wire.h> LiquidCrystal_I2C lcd(0x27,16,2); // устанавливаем адрес 0x27, и дисплей 16 символов в 2 строки (16х2) #define LED_PINS 2 // для пинга со второго контроллера моргает 3 раза #define BUTTON_PINA 3 // реле 1 #define BUTTON_PINB 4 // реле 2 #define BUTTON_PINC 5 // реле 3 #define BUTTON_PIND 6 // реле 4 #define BUTTON_PINE 7 // реле 5 #define BUTTON_PINF 8 // реле 6 #define BUTTON_PING 9 // реле 7 #define BUTTON_PINJ 10 // реле 8 #define BUTTON_PINK 11 // Временно не нужен #define RXTX_PIN 12 // RXTX ACTIVATION #define DEBOUNCE_TIME 5000 int _previousValueA = 0; int _previousValueB = 0; int _previousValueC = 0; int _previousValueD = 0; int _previousValueE = 0; int _previousValueF = 0; int _previousValueG = 0; int _previousValueJ = 0; int _previousValueK = 0; void setup() { Serial.begin(115200); pinMode(LED_PINS, OUTPUT); pinMode(BUTTON_PINA, INPUT); pinMode(BUTTON_PINB, INPUT); pinMode(BUTTON_PINC, INPUT); pinMode(BUTTON_PIND, INPUT); pinMode(BUTTON_PINE, INPUT); pinMode(BUTTON_PINF, INPUT); pinMode(BUTTON_PING, INPUT); pinMode(BUTTON_PINJ, INPUT); pinMode(BUTTON_PINK, INPUT); pinMode(RXTX_PIN, OUTPUT); // RXTX предназначен для активациии режима приёма RS485 _previousValueA = digitalRead(BUTTON_PINA); _previousValueB = digitalRead(BUTTON_PINB); _previousValueC = digitalRead(BUTTON_PINC); _previousValueD = digitalRead(BUTTON_PIND); _previousValueE = digitalRead(BUTTON_PINE); _previousValueF = digitalRead(BUTTON_PINF); _previousValueG = digitalRead(BUTTON_PING); _previousValueJ = digitalRead(BUTTON_PINJ); _previousValueK = digitalRead(BUTTON_PINK); digitalWrite(LED_PINS, LOW); digitalWrite(RXTX_PIN, LOW); } void SobitiePING() // сработка при получении кода от первого устройства о состоянии связи { digitalWrite(LED_PINS, HIGH); delay(1000); digitalWrite(LED_PINS, LOW); delay(1000); digitalWrite(LED_PINS, HIGH); delay(1000); digitalWrite(LED_PINS, LOW); delay(1000); digitalWrite(LED_PINS, HIGH); delay(1000); digitalWrite(LED_PINS, LOW); Serial.println("S"); // ответ для второго контроллера } //------------------------------------------------------------------------------------- // ниже приведены действи при изменениях на восьми входах void SobitieAHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("0"); delay(100); Serial.println("0"); delay(100); Serial.println("0"); delay(100); //lcd.setCursor(0, 1); //lcd.print("V"); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieALow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("1"); delay(100); Serial.println("1"); delay(100); Serial.println("1"); delay(100); //lcd.setCursor(0, 1); //lcd.print("X"); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void SobitieBHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("2"); delay(100); Serial.println("2"); delay(100); Serial.println("2"); delay(100); //lcd.setCursor(1, 1); //lcd.print("V"); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieBLow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("3"); delay(100); Serial.println("3"); delay(100); Serial.println("3"); delay(100); //lcd.setCursor(1, 1); //lcd.print("X"); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void SobitieCHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("4"); delay(100); Serial.println("4"); delay(100); Serial.println("4"); delay(100); //lcd.print("V"); //lcd.setCursor(2, 1); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieCLow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("5"); delay(100); Serial.println("5"); delay(100); Serial.println("5"); delay(100); //lcd.print("X"); //lcd.setCursor(2, 1); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void SobitieDHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("6"); delay(100); Serial.println("6"); delay(100); Serial.println("6"); delay(100); //lcd.setCursor(3, 1); //lcd.print("V"); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieDLow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("7"); delay(100); Serial.println("7"); delay(100); Serial.println("7"); delay(100); //lcd.setCursor(3, 1); //lcd.print("X"); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void SobitieEHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("8"); delay(100); Serial.println("8"); delay(100); Serial.println("8"); delay(100); //lcd.setCursor(6, 1); //lcd.print("V"); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieELow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("9"); delay(100); Serial.println("9"); delay(100); Serial.println("9"); delay(100); //lcd.setCursor(6, 1); //lcd.print("X"); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void SobitieFHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("A"); delay(100); Serial.println("A"); delay(100); Serial.println("A"); delay(100); //lcd.setCursor(7, 1); //lcd.print("V"); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieFLow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("B"); delay(100); Serial.println("B"); delay(100); Serial.println("B"); delay(100); //lcd.setCursor(7, 1); //lcd.print("X"); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void SobitieGHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("C"); delay(100); Serial.println("C"); delay(100); Serial.println("C"); delay(100); //lcd.setCursor(8, 1); //lcd.print("V"); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieGLow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("D"); delay(100); Serial.println("D"); delay(100); Serial.println("D"); delay(100); //lcd.setCursor(8, 1); //lcd.print("X"); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void SobitieJHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("E"); delay(100); Serial.println("E"); delay(100); Serial.println("E"); delay(100); //lcd.setCursor(9, 1); //lcd.print("V"); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieJLow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("F"); delay(100); Serial.println("F"); delay(100); Serial.println("F"); delay(100); //lcd.setCursor(9, 1); //lcd.print("X"); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void SobitieKHigh() { digitalWrite(RXTX_PIN, HIGH); Serial.println("G"); delay(100); Serial.println("G"); delay(100); Serial.println("G"); delay(100); //lcd.setCursor(12, 1); //lcd.print("GOOD"); digitalWrite(RXTX_PIN, LOW); } //----------------------------------- void SobitieKLow() { digitalWrite(RXTX_PIN, HIGH); Serial.println("J"); delay(100); Serial.println("J"); delay(100); Serial.println("J"); delay(100); //lcd.setCursor(12, 1); //lcd.print("FIRE"); digitalWrite(RXTX_PIN, LOW); } //------------------------------------------------------------------------------------- void loop() { if(Serial.available()>0) { char letter = Serial.read(); if (letter == 'R') // это получение кода от кнопки проверки на втором устройстве { SobitiePING(); } } //------------------------------------------------------------------------------- int currentValueA = digitalRead(BUTTON_PINA); if (_previousValueA != currentValueA) { if (currentValueA == HIGH) { SobitieAHigh(); } else { SobitieALow(); } _previousValueA = currentValueA; } //------------------------------------------------------------------- int currentValueB = digitalRead(BUTTON_PINB); if (_previousValueB != currentValueB) { if (currentValueB == HIGH) { SobitieBHigh(); } else { SobitieBLow(); } _previousValueB = currentValueB; } //------------------------------------------------------------------- int currentValueC = digitalRead(BUTTON_PINC); if (_previousValueC != currentValueC) { if (currentValueC == HIGH) { SobitieCHigh(); } else { SobitieCLow(); } _previousValueC = currentValueC; } //------------------------------------------------------------------- int currentValueD = digitalRead(BUTTON_PIND); if (_previousValueD != currentValueD) { if (currentValueD == HIGH) { SobitieDHigh(); } else { SobitieDLow(); } _previousValueD = currentValueD; } //------------------------------------------------------------------- int currentValueE = digitalRead(BUTTON_PINE); if (_previousValueE != currentValueE) { if (currentValueE == HIGH) { SobitieEHigh(); } else { SobitieELow(); } _previousValueE = currentValueE; } //------------------------------------------------------------------- int currentValueF = digitalRead(BUTTON_PINF); if (_previousValueF != currentValueF) { if (currentValueF == HIGH) { SobitieFHigh(); } else { SobitieFLow(); } _previousValueF = currentValueF; } //------------------------------------------------------------------- int currentValueG = digitalRead(BUTTON_PING); if (_previousValueG != currentValueG) { if (currentValueG == HIGH) { SobitieGHigh(); } else { SobitieGLow(); } _previousValueG = currentValueG; } //------------------------------------------------------------------- int currentValueJ = digitalRead(BUTTON_PINJ); if (_previousValueJ != currentValueJ) { if (currentValueJ == HIGH) { SobitieJHigh(); } else { SobitieJLow(); } _previousValueJ = currentValueJ; } //------------------------------------------------------------------- // int currentValueK = digitalRead(BUTTON_PINK); // if (_previousValueK != currentValueK) // { // if (currentValueK == HIGH) // { // SobitieKHigh(); // } // else // { // SobitieKLow(); // } // _previousValueK = currentValueK; // } delay(DEBOUNCE_TIME); }
ЭТО КОД ВТОРОГО УСТРОЙСТВА
#include <LiquidCrystal_I2C.h> #include <Wire.h> #include <Bounce2.h> Bounce bouncer = Bounce(); LiquidCrystal_I2C lcd(0x27,16,2); // устанавливаем адрес 0x27, и дисплей 16 символов в 2 строки (16х2) #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 #define BEEP_PINK 2 // Пищалка сигнал при сработке #define LED_PINS 11 // Лед сигнал о нормальной связи #define BUTTON_TEST 12 // Тестовая кнопка проверки связи int _previousValueTEST = 0; int soundPin = 2; //объявляем переменную с номером пина, на который мы подключили пьезоэлемент void setup() { bouncer.attach(12); // устанавливаем кнопку bouncer.interval(150); // устанавливаем параметр stable interval = 150 мс Serial.begin(115200); lcd.init(); // инициализация LCD lcd.backlight(); // включаем подсветку lcd.clear(); // очистка дисплея lcd.setCursor(0, 0); lcd.print("1"); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(1, 0); lcd.print("2"); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(3, 0); lcd.print("3"); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(4, 0); lcd.print("4"); lcd.setCursor(4, 1); lcd.print(" "); lcd.setCursor(6, 0); lcd.print("5"); lcd.setCursor(6, 1); lcd.print(" "); lcd.setCursor(7, 0); lcd.print("6"); lcd.setCursor(7, 1); lcd.print(" "); lcd.setCursor(9, 0); lcd.print("7"); lcd.setCursor(9, 1); lcd.print(" "); lcd.setCursor(10, 0); lcd.print("8"); lcd.setCursor(12, 1); lcd.print(" "); 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 pinMode(soundPin, OUTPUT); // BEEPER pinMode(LED_PINS, OUTPUT); // LED TEST pinMode(BUTTON_TEST, INPUT); _previousValueTEST = digitalRead(BUTTON_TEST); } void SobitiePINS() // RX/TX TEST LED BLINK { digitalWrite(LED_PINS, HIGH); delay(1000); digitalWrite(LED_PINS, LOW); delay(1000); digitalWrite(LED_PINS, HIGH); delay(1000); digitalWrite(LED_PINS, LOW); delay(1000); digitalWrite(LED_PINS, HIGH); delay(1000); digitalWrite(LED_PINS, LOW); delay(1000); } //---------------------------------------------------------------------------------------------------------------- void SobitieAHigh() { //Serial.println("1 NORMAL"); digitalWrite(LED_PINA, LOW); lcd.setCursor(0, 1); // устанавливаем курсор lcd.print(" "); SobtitleBeepS(); } void SobitieALow() { //Serial.println("1 ATTENTION"); digitalWrite(LED_PINA, HIGH); lcd.setCursor(0, 1); // устанавливаем курсор lcd.print("X"); SobtitleBeepL(); } //---------------------------------------------------------------------------------------------------------------- void SobitieBHigh() { //Serial.println("2 NORMAL"); digitalWrite(LED_PINB, LOW); lcd.setCursor(1, 1); // устанавливаем курсор lcd.print(" "); SobtitleBeepS(); } void SobitieBLow() { //Serial.println("2 ATTENTION"); digitalWrite(LED_PINB, HIGH); lcd.setCursor(1, 1); // устанавливаем курсор lcd.print("X"); SobtitleBeepL(); } //---------------------------------------------------------------------------------------------------------------- void SobitieCHigh() { //Serial.println("3 NORMAL"); digitalWrite(LED_PINC, LOW); lcd.setCursor(3, 1); // устанавливаем курсор lcd.print(" "); SobtitleBeepS(); } void SobitieCLow() { //Serial.println("3 ATTENTION"); digitalWrite(LED_PINC, HIGH); lcd.setCursor(3, 1); // устанавливаем курсор lcd.print("X"); SobtitleBeepL(); } //---------------------------------------------------------------------------------------------------------------- void SobitieDHigh() { //Serial.println("4 NORMAL"); digitalWrite(LED_PIND, LOW); lcd.setCursor(4, 1); // устанавливаем курсор lcd.print(" "); SobtitleBeepS(); } void SobitieDLow() { //Serial.println("4 ATTENTION"); digitalWrite(LED_PIND, HIGH); lcd.setCursor(4, 1); // устанавливаем курсор lcd.print("X"); SobtitleBeepL(); } //---------------------------------------------------------------------------------------------------------------- void SobitieEHigh() { //Serial.println("5 NORMAL"); digitalWrite(LED_PINE, LOW); lcd.setCursor(6, 1); // устанавливаем курсор lcd.print(" "); SobtitleBeepS(); } void SobitieELow() { //Serial.println("5 ATTENTION"); digitalWrite(LED_PINE, HIGH); lcd.setCursor(6, 1); // устанавливаем курсор lcd.print("X"); SobtitleBeepL(); } //---------------------------------------------------------------------------------------------------------------- void SobitieFHigh() { //Serial.println("6 NORMAL"); digitalWrite(LED_PINF, LOW); lcd.setCursor(7, 1); // устанавливаем курсор lcd.print(" "); SobtitleBeepS(); } void SobitieFLow() { //Serial.println("6 ATTENTION"); digitalWrite(LED_PINF, HIGH); lcd.setCursor(7, 1); // устанавливаем курсор lcd.print("X"); SobtitleBeepL(); } //---------------------------------------------------------------------------------------------------------------- void SobitieGHigh() { //Serial.println("7 NORMAL"); digitalWrite(LED_PING, LOW); lcd.setCursor(9, 1); // устанавливаем курсор lcd.print(" "); SobtitleBeepS(); } void SobitieGLow() { //Serial.println("7 ATTENTION"); digitalWrite(LED_PING, HIGH); lcd.setCursor(9, 1); // устанавливаем курсор lcd.print("X"); SobtitleBeepL(); } //---------------------------------------------------------------------------------------------------------------- void SobitieJHigh() { //Serial.println("8 NORMAL"); digitalWrite(LED_PINJ, LOW); lcd.setCursor(10, 1); // устанавливаем курсор lcd.print(" "); SobtitleBeepS(); } void SobitieJLow() { //Serial.println("8 ATTENTION"); digitalWrite(LED_PINJ, HIGH); lcd.setCursor(10, 1); // устанавливаем курсор lcd.print("X"); SobtitleBeepL(); } //---------------------------------------------------------------------------------------------------------------- //void SobitieKHigh() //{ // Serial.println("The TEMP is GOOD"); // digitalWrite(LED_PINK, LOW); // lcd.setCursor(12, 1); // устанавливаем курсор // lcd.print("GOOD"); //} //void SobitieKLow() //{ // Serial.println("The TEMP is FIRE"); // digitalWrite(LED_PINK, HIGH); // lcd.setCursor(12, 1); // устанавливаем курсор // lcd.print("FIRE"); //} //---------------------------------------------------------------------------------------------------------------- void SobtitleBeepS() { tone (soundPin, 1000); //включаем на 500 Гц delay(2000); //ждем 100 Мс noTone(soundPin); } void SobtitleBeepL() { 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); } void loop() { if (bouncer.update()) { //если произошло событие if (bouncer.read()==0) { //если кнопка нажата Serial.println("R"); //вывод сообщения о нажатии } } //------------------------------------------------------------------------------- if(Serial.available()>0) { char letter = Serial.read(); if (letter == '0') { SobitieAHigh(); } else if (letter == '1') { SobitieALow(); } //------------------------------------------------------------------------------- if (letter == '2') { SobitieBHigh(); } if (letter == '3') { SobitieBLow(); } //------------------------------------------------------------------------------- if (letter == '4') { SobitieCHigh(); } if (letter == '5') { SobitieCLow(); } //------------------------------------------------------------------------------- if (letter == '6') { SobitieDHigh(); } if (letter == '7') { SobitieDLow(); } //------------------------------------------------------------------------------- //------------------------------------------------------------------------------- if (letter == '8') { SobitieEHigh(); } else if (letter == '9') { SobitieELow(); } //------------------------------------------------------------------------------- if (letter == 'A') { SobitieFHigh(); } if (letter == 'B') { SobitieFLow(); } //------------------------------------------------------------------------------- if (letter == 'C') { SobitieGHigh(); } if (letter == 'D') { SobitieGLow(); } //------------------------------------------------------------------------------- if (letter == 'E') { SobitieJHigh(); } if (letter == 'F') { SobitieJLow(); } //------------------------------------------------------------------------------- //------------------------------------------------------------------------------- // if (letter == 'G') // { // SobitieKHigh(); // } // if (letter == 'J') // { // SobitieKLow(); // } //------------------------------------------------------------------------------- if (letter == 'S') { SobitiePINS(); } } }