What are the differences in serial communication between PC <---> Arduino UNO (ATMEGA328p) and PC <---> Arduino Leonardo (ATMEGA32u4)?
I am asking because of a problem related to using these two Arduino boards for data logging in the following way:
- PC sends a specific char string to Arduino, via serial port, to initialize datalogging
- Arduino measures data, let's say a fixed number of ADC readings
- Arduino stops measuring, sends data back to the PC over serial port
- Arduino waits until new serial data are received before logging new data
If I send/receive data via the Arduino IDE serial monitor, this procedure works on both boards. However, I want a separate GUI program (Qt) to handle the serial communication, where one clicks a button to send the data in step 1, and plot the data from step 3 on a graph.
I wrote a simple Qt GUI where a button is clicked, and the measured data are printed to the GUI screen. Observations while testing it:
- Arduino UNO as datalogger: Arduino is plugged into USB socket of PC, then I launch the GUI, then click button to start data acquisition. The data are shown. Program appears to work fine.
- Arduino Leonardo as datalogger: Arduino is plugged into USB socket of PC, then I launch the GUI, then click button to start data acquisition. The data are not received, program hangs.
Then
- Arduino Leonardo as datalogger: Arduino is plugged into USB socket of PC, Open Arduino IDE serial monitor, send command to acquire data. Then close Arduino IDE serial monitor, launch the GUI, click button to start data acquisition. The GUI program now works.
Long story, but basically there appears to be a difference when using the two Arduino boards with external programs to do serial communication. Can someone outline the differences and why Leonardo needs the "jump start" I described above using Arduino serial monitor? Ultimately I want to fix the problem and avoid that hack.
Reluctant to post Qt code on Arduino stack exchange, but here is how I start the serial port:
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){ // open and configure serialport
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.");}
Setup part of my Arduino code:
void setup(){
DDRB |= B11111111; // (654210 outputs, miso input)
PORTB &= ~_BV(RF_AMPL);
DDRD |= B1100010;
PORTD |= (_BV(SRAM_HOLD) | _BV(SRAM_SS1));
ADCSRA=0;
SPCR = B01010000; // SPI init (could get away with 11010000 on 328p but not 32u4)
SPSR = B00000001;
PORTD &= ~_BV(SRAM_SS1); // Slave init
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){}
}
plug in leonardo -- then reset leonardo -- then start GUI
. . . . . . . . . . . . . . . or,plug in -- start GUI -- reset
?