проблемы с несколькими SoftwareSerial
- Войдите на сайт для отправки комментариев
Пнд, 26/01/2015 - 21:02
Всем привет.
Столкнулся со следующей проблемой.
подключаю к Arduino 2 Rfid Readera работающих через UART, создаю 2 SoftwareSerial подключения, инициализирую их в setup. все вроде правильно но работает только тот порт который инициализировался последним.
Вот пример кода который накидал просто для пробы.
#include <SoftwareSerial.h> SoftwareSerial SoftSerial(2, 3); SoftwareSerial SoftSerial1(4, 5); unsigned char buffer[64]; // buffer array for data recieve over serial port int count=0; // counter for buffer array unsigned char buffer1[64]; // buffer array for data recieve over serial port int count1=0; // counter for buffer array void setup() { SoftSerial1.begin(9600); // the SoftSerial baud rate SoftSerial.begin(9600); // the SoftSerial baud rate Serial.begin(9600); // the Serial port of Arduino baud rate. } void loop() { if (SoftSerial.available()) // if date is comming from softwareserial port ==> data is comming from SoftSerial shield { while(SoftSerial.available()) // reading data into char array { buffer[count++]=SoftSerial.read(); // writing data into array if(count == 64)break; } Serial.write(buffer,count); // if no data transmission ends, write buffer to hardware serial port clearBufferArray(); // call clearBufferArray function to clear the storaged data from the array count = 0; // set counter of while loop to zero } if (SoftSerial1.available()) // if date is comming from softwareserial port ==> data is comming from SoftSerial shield { while(SoftSerial1.available()) // reading data into char array { buffer1[count1++]=SoftSerial1.read(); // writing data into array if(count1 == 64)break; } Serial.write(buffer1,count1); // if no data transmission ends, write buffer to hardware serial port clearBufferArray1(); // call clearBufferArray function to clear the storaged data from the array count1 = 0; // set counter of while loop to zero } } void clearBufferArray() // function to clear buffer array { for (int i=0; i<count;i++) { buffer[i]=NULL; } // clear all index of array with command NULL } void clearBufferArray1() // function to clear buffer array { for (int i=0; i<count1;i++) { buffer1[i]=NULL; } // clear all index of array with command NULL }
в таком варианте работает только SoftSerial порт. SoftSerial1 не работает.
если поменять порядок инициализации портов то и работать будет другой порт.
void setup() { SoftSerial1.begin(9600); // не будет работать SoftSerial.begin(9600); // будет работать Serial.begin(9600); // этот работает всегда }
void setup() { SoftSerial.begin(9600); // не будет работать SoftSerial1.begin(9600); // будет работать Serial.begin(9600); // этот работает всегда }
вопрос с чем это связано и как быть?
в данный момент я подключаю 2 RFID но уже есть задача с 5...7 RFID на одном устройстве.
Вот здесь http://arduino.ua/ru/prog/SoftwareSerial, например, написано
"Среди известных ограничений библиотеки SoftwareSerial можно перечислить следующие:
При использовании нескольких последовательных портов, в каждый момент времени только один из них может получать данные."
ну так у меня они поочереди работают.
сначала опрашивается SoftSerial и если на нем есть данные то обрабатываем их, и только потом переходим к SoftSerial1.
Эта библиотека при приеме данных использует прерывание. Это прерывание только одно. Значит одновременно принимать два порта не могут. Опросить порт можно, но данные будут только псле того как он примет их. Ощущаете разницу ?
с трудом но кажется понемного понимаю.
в общем на ардуине нет возможности запустить больше 1 UART устройства работающего на передачу через SoftwareSerial. печально.
А если инициализировать непосредственно перед использованием в лупе? То есть инициализируем опрашиваем если есть выполняем нет проскакиваем обрубаем первый инициализируем второй опрашиваем есть выполняем нет проскакиваем обрубаем второй инициализируем первый.
Интересная мысль.
Вопрос только как обрубать? Подскажите функцию деинициализации.
Serial.end
А что будет если данные придут когда порт отключен ? :-)
с трудом но кажется понемного понимаю.
в общем на ардуине нет возможности запустить больше 1 UART устройства работающего на передачу через SoftwareSerial. печально.
если только на передачу - то можно
А что будет если данные придут когда порт отключен ? :-)
Данные, пришедшие в отключенный порт, теряются. К.О.
Ну это очевидно. Задал вопрос что бы тс задумался.
Ну так как исходная задача RFID то сигнал инициирует человек и в случае непрочтения с первого раза можно попробовать второй.
Можно и третий :) или четвертый - пятый. Пока человек не охренеет... Халтура будет .
Ну это очевидно. Задал вопрос что бы тс задумался.
Простите, я провтыкал..
А взять мегу что мешает?
блин не когда даже тему почитать. соответственно проверить предложеное решение с обрубанием порта пока не получается. как проверю - отпишусь.
взять мегу не сильно спасает т.к. это максимум 5 портов (с учетом одного софтового) а нужно больше. к тому же она здоровая и дорогая.
потерянные данные не сильно большая проблема как мне кажется. зависит от скорости работы RFID redera. если он в секунду раз 10 будет карточку опрашивать то скорее всего пользователь не заметит проблем. надо пробовать.
Вы хотите более 5 риадеров повесить на один контроллер? и 10$ мега "дорогая"? А риадеры у Вас почем?
Но я бы делал не так. Я бы взял жменю атмега8 (по одному контроллеру на риадер), настроил бы его на работу с внутренним генератором (чтобы работал без кварца), далее соединил их через i2c или spi в сеть с ардуиной, ну а дальше уже работает софт.
Решил вопрос с RC522 вот пример можно и больше ридеров повесить....
Попробуй так.
if
(Serial1.available()){
26
Serial
.println(
"Test1"
);
27
reader1Blink = millis()+500;
28
while
(Serial1.available()) Serial1.read();
//purge buffer
29
}
//if(Serial1)
Или так
http://arduino.ru/forum/apparatnye-voprosy/mega-25602xrdm-6300-ili-2xrc5...
подключаю к Arduino 2 Rfid Readera работающих через UART, создаю 2 SoftwareSerial подключения, инициализирую их в setup. все вроде правильно но работает только тот порт который инициализировался последним.
вопрос с чем это связано и как быть?
Посмотрите здесь описание библиотеки SoftSerial.
Перед тем как считывать данные с софтового порта, его необходимо перевести в режим ожидания данных функцией SoftSerial.listen()
Все пере пробовал. Ни чего не помогло.
В итоге сделал на каждый ридер свою нану. Громоздко и дорого но работает.
столкнулся с тоже проблеммой 2 программных порта на атмега 328, лучше конечно использовать аппаратный и программный но увы плату протравил и спаял не подумав, путём проб смог добится работы 2 устройств
recvL.listen();
delay(28);
while(recvL.available()>0)
primL = recvL.read();
recvR.listen();
delay(28);
while(recvR.available()>0)
primR = recvR.read();
оказалось что нужне ещё некое время на отработку прерываний
попробуйте так
и скорость больше 19200 лучше не использовать
это работает через раз и тоже требует задержки во времяни, в предыдущей версии 28 милисикунд, стабильно получает пакеты
от использования "listen" я отказался, так как переодически получал кракозябры
Есть задержка звука при запуске 2-х МП3 плееров (только передача по TX). Код приложен.
А если запараллелить вход MP3-плееров - они стартанут в одно и то же время или у них есть ещё разнообразная внутренняя задержка?
Сейчас проверю. Спасибо за подсказку.
Задержка-то она всегда будет уже только на том основании, что МК с библиотекой софтсериал блокируется в цикле передачи по одному из виртуальных UART. Вопрос только в том, насколько её удастся сократить.
Форматирование памяти МП3 плеера и перезапись файлов решили проблему.
Тут нет ни прогмема, ни иных блокирующих фрагментов кроме самого софтсериала. В принципе, чтобы локализовать проблему, нужно логаналайзером присесть на оба TX и посмотреть интервал между окончаниями посылок. Тогда будет ясно - плееры тупят или действительно софтваресериал медленный.