Последовательные порты на Arduino UNO/Leonardo инициализируются по-разному?

Каковы различия в последовательной связи между ПК <---> Arduino UNO (ATMEGA328p) и ПК <---> Arduino Leonardo (ATMEGA32u4)?

Я спрашиваю из-за проблемы, связанной с использованием этих двух плат Arduino для регистрации данных следующим образом:

  1. ПК отправляет определенную строку символов в Arduino через последовательный порт для инициализации регистрации данных.
  2. Arduino измеряет данные, скажем, фиксированное количество показаний АЦП
  3. Arduino прекращает измерение и отправляет данные обратно на ПК через последовательный порт.
  4. Arduino ожидает получения новых последовательных данных, прежде чем записывать новые данные.

Если я отправляю/получаю данные через последовательный монитор Arduino IDE, эта процедура работает на обеих платах. Однако я хочу, чтобы отдельная программа с графическим интерфейсом (Qt) обрабатывала последовательную связь, когда нужно щелкнуть кнопку, чтобы отправить данные на шаге 1, и отобразить данные с шага 3 на графике.

Я написал простой графический интерфейс Qt, в котором при нажатии кнопки измеренные данные выводятся на экран графического интерфейса. Наблюдения во время тестирования:

  • Arduino UNO в качестве регистратора данных: Arduino подключается к USB-разъему ПК, затем я запускаю графический интерфейс, затем нажимаю кнопку, чтобы начать сбор данных. Данные показаны. Программа работает нормально.
  • Arduino Leonardo в качестве регистратора данных: Arduino подключается к USB-разъему ПК, затем я запускаю графический интерфейс и нажимаю кнопку, чтобы начать сбор данных. Данные не принимаются, программа зависает.

Затем

  • Arduino Leonardo в качестве регистратора данных: Arduino подключается к USB-разъему ПК, открывает последовательный монитор Arduino IDE, отправляет команду для сбора данных. Затем закройте последовательный монитор Arduino IDE, запустите графический интерфейс, нажмите кнопку, чтобы начать сбор данных. Теперь программа с графическим интерфейсом работает.

Долгая история, но, по сути, существует разница при использовании двух плат Arduino с внешними программами для последовательной связи. Может ли кто-нибудь обрисовать различия и почему Леонардо нужен «старт», описанный выше, с использованием последовательного монитора Arduino? В конечном счете, я хочу решить проблему и избежать взлома.

Не хочу публиковать код Qt на платформе обмена стеками Arduino, но вот как я запускаю последовательный порт:

ui->setupUi(this);
microcontroller_is_available = false;
microcontroller_port_name = "false";
microcontroller = new QSerialPort(this);
qDebug() << "Number of available ports: " << QSerialPortInfo::availablePorts().length();
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
    qDebug() << "Has product ID " << serialPortInfo.hasProductIdentifier();
    if(serialPortInfo.hasProductIdentifier()){qDebug() << "Product ID: " << serialPortInfo.productIdentifier();}
    qDebug() << "Has vendor ID " << serialPortInfo.hasVendorIdentifier();
    if(serialPortInfo.hasVendorIdentifier()){qDebug() << "Vendor ID: " << serialPortInfo.vendorIdentifier();}
}

foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
   if(serialPortInfo.hasVendorIdentifier() && serialPortInfo.hasProductIdentifier()){
       if(serialPortInfo.vendorIdentifier() == micro_vendor_id){
           if(serialPortInfo.productIdentifier() == micro_product_id){
              microcontroller_port_name = serialPortInfo.portName();
              microcontroller_is_available = true;
           }
       }
   }
}

if(microcontroller_is_available){  // открыть и настроить последовательный порт
    microcontroller->setPortName(microcontroller_port_name);
    microcontroller->open(QSerialPort::ReadWrite);
    microcontroller->setBaudRate(QSerialPort::Baud115200);
    microcontroller->setDataBits(QSerialPort::Data8);
    microcontroller->setParity(QSerialPort::NoParity);
    microcontroller->setStopBits(QSerialPort::OneStop);
    microcontroller->setFlowControl(QSerialPort::NoFlowControl);
}
else{QMessageBox::warning(this, "Port error", "Cannot connect DAQ.");}

Настройка моего кода Arduino:

void setup(){
  DDRB  |= B11111111;  // (654210 выходов, вход мисо)
  PORTB &= ~_BV(RF_AMPL);
  DDRD  |= B1100010; 
  PORTD |= (_BV(SRAM_HOLD) | _BV(SRAM_SS1)); 
  ADCSRA=0;
  SPCR = B01010000;           // Инициализация SPI (может обойтись 11010000 на 328p, но не на 32u4)
  SPSR = B00000001;
  PORTD &= ~_BV(SRAM_SS1);     // Инициализация подчиненного устройства
  SPDR=WRMR;  while(!(SPSR & (1<<SPIF)));
  SPDR=SEQUENTIAL_MODE; while(!(SPSR & (1<<SPIF)));
  PORTD |= _BV(SRAM_SS1); 
  __builtin_avr_delay_cycles(160);
  PORTD &= ~_BV(SRAM_SS1); 
  SPDR=RDMR; while(!(SPSR & (1<<SPIF)));
  SPDR=0x00; while(!(SPSR & (1<<SPIF)));
  PORTD |= (_BV(SRAM_HOLD) | _BV(SRAM_SS1)); 
  state1=0;
  count=0;
  pulse_count=0;
  serial_counter=0;
  Serial.begin(115200);  while(!Serial){}
}

, 👍1

Обсуждение

https://www.arduino.cc/en/Guide/ArduinoLeonardoMicro#toc11, @Juraj

Есть ли причина, по которой вы не используете библиотеку SPI?, @Majenko

Мне нужен SPI, который быстрее, чем дает библиотека Arduino SPI., @MichaelT

что произойдет, если вы подключите leonardo -- затем перезагрузите leonardo -- затем запустите графический интерфейс . . . . . . . . . . . . . . . или подключить -- запустить GUI -- перезагрузить ?, @jsotola


2 ответа


Лучший ответ:

1

Я решил эту проблему, перезагрузив Arduino (открыв последовательный порт на скорости 1200 бод, затем закройте последовательный порт) при запуске программы Qt.

Вот соответствующая часть программы Qt:

        microcontroller->setPortName(microcontroller_port_name);
        microcontroller->open(QSerialPort::ReadWrite);
        microcontroller->setBaudRate(QSerialPort::Baud1200);
        microcontroller->setDataBits(QSerialPort::Data8);
        microcontroller->setParity(QSerialPort::NoParity);
        microcontroller->setStopBits(QSerialPort::OneStop);
        microcontroller->setFlowControl(QSerialPort::HardwareControl);

        qDebug() << "open 1200 baud";
        Sleep(10);
        microcontroller->close();
        Sleep(10);

        microcontroller->open(QSerialPort::ReadWrite);
        microcontroller->setBaudRate(QSerialPort::Baud115200);
        microcontroller->setDataBits(QSerialPort::Data8);
        microcontroller->setParity(QSerialPort::NoParity);
        microcontroller->setStopBits(QSerialPort::OneStop);
        microcontroller->setFlowControl(QSerialPort::HardwareControl);

Теперь всякий раз, когда я запускаю программу Qt, Arduino готов принимать последовательные данные.

,

Можно принять ваш ответ, если он является решением проблемы., @VE7JRO


1

Да, есть отличия.

  • У Uno есть ATMega16U2 в качестве моста USB-UART. Когда вы открываете последовательный порт, ATMega16U2 сигнализирует ATMega328p о сбросе и запуске скетча с самого начала.
  • В Leonardo используется ATMega32U4 в качестве основного микроконтроллера, который напрямую подключается к порту USB. Когда вы открываете последовательный порт, вы подключаетесь к своей программе, где бы она ни находилась в данный момент.

Ключевым моментом здесь является то, что когда вы открываете порт Uno, плата перезагружается, и ваш скетч перезапускается. Когда вы открываете порт Леонардо, плата не сбрасывается, и ваш скетч остается там, где он находится.

Итак: вы должны убедиться, что ваш скетч не зависит от вещей в setup() или на раннем этапе его выполнения для обеспечения работы последовательного соединения.

,

Я уже следовал руководству Arduino, чтобы использовать Serial.begin(115200); в то время как (! Серийный) {}. Код установки, размещенный выше (минус определения контактов). Вы видите что-то явно неправильное? Один и тот же скетч Arduino используется для UNO и Leonardo., @MichaelT

Можно ли на устройстве Leonardo распечатать файл/данные через последовательный порт на ПК через USB-порт? Итак, в основном записываем файл на ПК. Мне бы хотелось узнать, возможно ли это, а не использовать только ATMega32U4 с библиотекой клавиатуры., @Melroy van den Berg

Чтобы ответить на свой вопрос, думаю, попробую Lufa: https://github.com/Palatis/Arduino-Lufa., @Melroy van den Berg