2016-03-20 4 views
1

Итак, я создал базовый графический интерфейс QT, где я хочу установить связь с Arduino Nano через USB. Я посылаю номер через GUI, и Arduino получает номер и обрабатывает его.Arduino не получает данные после повторного подключения к USB

Связь прекрасно работает, когда я загружаю код в Arduino и сразу же открываю GUI и запускаю процесс. Однако, когда я отсоединяю Arduino от USB (или перезагружаю свой компьютер - я уже пробовал оба) и снова подключаю его к GUI, Arduino ведет себя так, как будто ничего не получил.

Более конкретно, в первом случае Serial.available() возвращает «1», поскольку он правильно принимает номер, но в последнем случае он возвращает «0», поэтому он ничего не делает.

Я сделал код настолько простым, насколько я мог попытаться отследить проблему, и проблема продолжается.

Так вот главный QT GUI код:

depth_ = insertDepthEdit->text().toInt(); // user input from GUI 
myThread *mThread; 
mThread = new myThread(this, depth_); 
connect(mThread, SIGNAL(valueRead(QString)), this, SLOT(onTextChange(QString))); 
//valueRead is the signal emitted from Arduino 
//onTextChange the function that processes the received string 
mThread->start(); 
mThread->wait(100); 
mThread->quit(); 

Код резьбы Arduino (также QT):

void myThread::run() { 

    QSerialPort serial; 
    serial.setPortName("COM3"); 
    serial.setBaudRate(QSerialPort::Baud9600); 
    serial.setDataBits(QSerialPort::Data8); 
    serial.setParity(QSerialPort::NoParity); 
    serial.setStopBits(QSerialPort::OneStop); 
    serial.setFlowControl(QSerialPort::NoFlowControl); 
    serial.open(QIODevice::ReadWrite); 

    if (serial.isOpen() && serial.isWritable()) { 

     qDebug() << "Ready to write..." << endl; 
     QByteArray ba(QString::number(depth_).toStdString().c_str()); 
     qDebug() << ba << endl; 
     serial.write(ba); 

     if (serial.bytesToWrite() > 0) { 
      serial.flush(); 
      if (serial.waitForBytesWritten(1000)) { 
       qDebug() << "data has been sent" << endl; 
      } 
     } 
     if (serial.flush()) { 
      qDebug() << "ok" << endl; 
     } 
    } 
    else { 
     qDebug() << "Error"; 
    } 
    if (serial.isOpen() && serial.isReadable()) { 
     qDebug() << "Ready to read..." <<endl; 
     while (serial.waitForReadyRead(5000)) { 
      QByteArray inByteArray = serial.readLine(); 
      input_ = QString(inByteArray); 
      qDebug() << input_; 
      qDebug() << "ok" << endl; 
      emit valueRead(input_); 
     } 
    } 
    serial.close(); 
} 

И, наконец, код Arduino:

int c = 0; 
const int ledPin = 13; 

void setup() { 
    Serial.begin(9600); 
} 

void loop() { 
    Serial.print(Serial.available()); 
    while (Serial.available() > 0) { 
    digitalWrite(ledPin, HIGH); 
    delay(5); 
    c = Serial.read() - '0'; 
    Serial.flush(); 
    } 
    delay(1000); 
    digitalWrite(ledPin, LOW); 
    delay(500); 
} 

Когда Я загружаю код в Arduino, он работает нормально, независимо от того, закрываю ли я GUI и перезапускаю его. Проблема возникает только в том случае, если Arduino теряет питание, например: когда я отключу его от USB или перезагрузите компьютер.

~~~~~~~~~~~~~~~~~~~~~~~~~~ РЕДАКТИРОВАТЬ ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~

COM-порт остается неизменным после повторного подключения, и светодиод Arduino Rx нормально мигает, когда я отправляю данные через графический интерфейс.

~~~~~~~~~~~~~~~~~ РЕДАКТИРОВАТЬ 2 ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~

Итак, я попытался использовать код из документации Arduino Serial, и проблема остается. Когда я загружаю код, Arduino правильно принимает символ и включает светодиод, но как только я его отсоединяю, а затем подключаю обратно, он ничего не делает, светодиод остается низким, так как он никогда не входит в «если».

Вот код, который я использовал:

int incomingByte = 0; 

void setup() { 
    Serial.begin(9600); 
} 

void loop() { 
    if (Serial.available() > 0) { 
     digitalWrite(13, HIGH); 
     incomingByte = Serial.read(); 
    } 
} 

~~~~~~~~~~~~~~~~~~~~~~ EDIT 3 ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Так что у меня следующие 3 сценария:

Использование Сценарий A:

  1. Код загрузки
  2. Запуск GUI
  3. Отправить данные - Он получает правильно
  4. отключить и вновь подключить
  5. Run GUI снова
  6. Отправить данных - мигает RX, но последовательный.доступные возвращает 0

Использовать обычные Сценарий B:

  1. Загрузить код
  2. Run Brays
  3. Отправить данные - Он получает правильно
  4. отключить и вновь подключить
  5. Run Brays снова
  6. Отправить данные - он правильно получает

Использование Сценарий C (самое интересное):

  1. Загрузить код
  2. Run GUI
  3. Отправить данные - Он получает правильно
  4. отключить и вновь подключить
  5. Run Brays этот раз
  6. Отправить данные - Он правильно принимает
  7. Запустите GUI снова после Brays
  8. Отправить данные - Он получает правильно

Я также сделал код QT GUI так просто, как это, но проблема сохраняется:

void myThread::run() 
{ 
    QSerialPort *serial = new QSerialPort(); 
    serial->setPortName("COM3"); 
    serial->setBaudRate(QSerialPort::Baud9600); 
    serial->setDataBits(QSerialPort::Data8); 
    serial->open(QIODevice::WriteOnly); 

    if (serial->isOpen() && serial->isWritable()) 
    { 
     QByteArray ba(QString::number(depth_).toStdString().c_str()); 
     serial->write(ba); 
     serial->flush(); 
     serial->close(); 
    } 
    delete serial; 
} 

~~~~~~~~~~~ ~~~~~~~~~~~ EDIT 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~

Итак, после многих усилий и любопытства я понял, что источником проблемы является не код Arduino, а нечто, связанное с QT или Windows. Я добавил задержки, которые Джефф рекомендовал и заметил, что каждый раз, когда он функционировал должным образом, Rx моргнул, а светодиод стал высоким, как указано в коде. Однако после повторного подключения проблема осталась, но я заметил, что на этот раз сразу после нажатия «Отправить» для отправки символов светодиод моргнул на несколько миллисекунд (возможно, указав некоторую ошибку ??), а затем после 1 секунды задержка Rx мигает, указывающая на получение данных, и светодиод остался низким, поскольку Serial.available остался 0.

Итак, что я пробовал дальше, нужно было удалить одну строку кода за раз, чтобы узнать, что вызывает проблему.И я закончил с буквально пустым кодом Arduino, только пустые настройки и петлевые методы и следующий QT GUI код:

void myThread::run() 
{ 
    QSerialPort *serial1 = new QSerialPort(); 
    serial1->setPortName("COM5"); 
    serial1->open(QIODevice::WriteOnly); 
    serial1->close(); 
} 

Чтобы резюмировать, что происходит сейчас:

  1. Загрузить код Arduino
  2. Run GUI
  3. Отправить данные
  4. Ничего не происходит (нормальное поведение)
  5. Отключите и снова подключите Arduino к USB
  6. Run GUI
  7. Отправить данные привели
  8. Arduino кратковременно мигает один раз (возможно, указывает на какую-то ошибку)
+0

Светодиодный индикатор Arduino, указывающий, что он принимает данные? – Jeff

+0

Да, он нормально мигает, даже после переподключения. Это только serial.available(), который возвращает 0. – r21

+0

Какой вывод вы получаете от Arduino? – Jeff

ответ

1

Итак, после часов после отладки я нашел причину проблемы.

Основой этого было то, что после повторного подключения Arduino каждый раз, когда я вызывал serial.open в QT, Arduino делал сброс (обозначенный миганием светодиода), и к тому времени, когда это было после стадии загрузчика, и запустив код, основная программа уже передала команду serial.write QT без получения данных.

Итак, что я сделал для решения проблемы, было просто добавить Sleep(uint(2000)); после serial.open, чтобы Arduino завершил загрузку, а затем начал отправлять данные.

Благодарим за вашу помощь и немедленные ответы!

0

В моем опыте, этот вопрос не код в Ардуино. Это связано с тем, что последовательный порт получает другое имя при повторном подключении.

Например, в Linux первоначально был порт /dev/ARD0, но когда он отключен и подключен к подключению на ARD0, новый плагин назван /dev/ARD1. (. В Windows, это может быть COM17 затем COM18)

Единственный способ я знаю, чтобы сделать это стало оригинальное название порта, чтобы закрыть все, что связано с ним, прежде чем снова подключить: Закройте Arduino IDE, закройте все программы, открывшие порт и т. д.

+0

Я проверил это, и порт остается неизменным каждый раз, когда я подключаю Arduino, пока порт USB тот же. В моем коде я объявил, что порт является «COM3», и каждый раз, когда я подключаю Arduino, я проверяю диспетчер устройств и подключается там. Как я уже говорил, проблема сохраняется даже при перезагрузке ПК, что означает, что все программы и соединения закрыты. – r21

0

Если вы используете этот пример для документации Arduino Serial, вы получаете отправленные вами символы?

int incomingByte = 0; // for incoming serial data 

void setup() { 
    Serial.begin(9600); // opens serial port, sets data rate to 9600 bps 
} 

void loop() { 

    // send data only when you receive data: 
    if (Serial.available() > 0) { 
     // read the incoming byte: 
     incomingByte = Serial.read(); 

     // say what you got: 
     Serial.print("I received: "); 
     Serial.println(incomingByte, DEC); 
    } 
} 
+0

См. Раздел «РЕДАКТИРОВАТЬ 2» вопроса. Я подытоживаю результаты. – r21

+0

Если вы временно перетаскиваете TX1 и RX0 вместе на Arduino Nano, вы получаете обратно персонажи, которые вы отправляете с помощью вашей программы на ПК? Если нет, попробуйте программу терминала, например «Brays» https://sites.google.com/site/terminalbpp/, чтобы подтвердить выбор порта, драйверы USB, проводку и т. Д. – Jeff

+0

Итак, вот интересная подсказка. Я попробовал тот же процесс с терминалом «Brays», и он правильно принимает данные даже после повторного подключения. Дополнительная информация по основному вопросу «РЕДАКТИРОВАТЬ 3». – r21

0

Схватка на соломинках здесь, замените мои комментарии ниже одной секунды задержки. Редактирование на iPhone немного испортило формат, но я считаю, что вы можете видеть мое намерение.

Редактировать: Кроме того, я думаю, вы не должны делать serial-> близко к своей петле. Я также попытался бы отправить один символ несколько раз, пока у нас не получится работать.

void myThread::run() 
{ 
    QSerialPort *serial = new QSerialPort(); 
    serial->setPortName("COM3"); 
    serial->setBaudRate(QSerialPort::Baud9600); 
    serial->setDataBits(QSerialPort::Data8); 
    serial->open(QIODevice::WriteOnly); 

if (serial->isOpen() && serial->isWritable()) 
{ 
    QByteArray ba(QString::number(depth_).toStdString().c_str()); 
    serial->write("x"); 
      delay 1 second here 
    serial->flush(); 
      delay 1 second here 
} 

serial->close(); 
      delay 1 second here 
delete serial; 
} 
+0

Я попробовал все, что вы рекомендовали, и обнаружил, что корень проблемы в другом месте, но я до сих пор не знаю, как его решить. Пожалуйста, см. EDIT 4 и большое спасибо за вашу помощь. – r21

Смежные вопросы