Последовательные порты на Arduino UNO/Leonardo инициализируются по-разному?
Каковы различия в последовательной связи между ПК <---> Arduino UNO (ATMEGA328p) и ПК <---> Arduino Leonardo (ATMEGA32u4)?
Я спрашиваю из-за проблемы, связанной с использованием этих двух плат Arduino для регистрации данных следующим образом:
- ПК отправляет определенную строку символов в Arduino через последовательный порт для инициализации регистрации данных.
- Arduino измеряет данные, скажем, фиксированное количество показаний АЦП
- Arduino прекращает измерение и отправляет данные обратно на ПК через последовательный порт.
- 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){}
}
@MichaelT, 👍1
Обсуждение2 ответа
Лучший ответ:
Я решил эту проблему, перезагрузив 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
Да, есть отличия.
- У 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
- Float печатается только 2 десятичных знака после запятой
- Почему запуск последовательного монитора перезапускает скетч?
- Чтение из Serial
- Связь последовательного порта Digispark
- Улучшенное циклическое переключение цветов RGB.
- Распиновка аналога Arduino Pro Micro
- Как получить правильный последовательный порт?
- Может ли Arduino Leonardo одновременно использовать USB-порт и последовательные контакты RX TX?
https://www.arduino.cc/en/Guide/ArduinoLeonardoMicro#toc11, @Juraj
Есть ли причина, по которой вы не используете библиотеку SPI?, @Majenko
Мне нужен SPI, который быстрее, чем дает библиотека Arduino SPI., @MichaelT
что произойдет, если вы
подключите leonardo -- затем перезагрузите leonardo -- затем запустите графический интерфейс
. . . . . . . . . . . . . . . илиподключить -- запустить GUI -- перезагрузить
?, @jsotola