使用Qt与PeakCan USB适配器接收CAN总线帧遇读取问题求助
Hey there, let's work through this CAN read problem you're facing. Since your write functionality works fine (verified via PCAN View), we can focus on the configuration and signal-slot setup for reading. Here are the key steps to diagnose and fix the issue:
1. Validate Device Connection & Signal-Slot Order
First, your current code doesn't check if the device connection succeeds, and the signal-slot connection order might be off. Let's fix that:
// First connect the signal-slot BEFORE connecting the device (safer for timing) bool connSuccess = connect(m_device, &QCanBusDevice::framesReceived, this, &BusCan::onFramesReceived); qDebug() << "Signal-slot connection status:" << connSuccess; // Now attempt to connect the device, and check for errors if (!m_device->connectDevice()) { qDebug() << "Failed to connect PeakCAN device:" << m_device->errorString(); // Handle the error (e.g., clean up the device pointer) return; } qDebug() << "Device connected successfully. State:" << m_device->state();
- If
connSuccessisfalse, double-check thatBusCan::onFramesReceivedhas the exact same signature as theframesReceivedsignal (no parameters, matching access modifier). - If
connectDevice()fails, the error string will tell you exactly what's wrong (e.g., missing driver, incorrect device name like "usb0" vs "usb1").
2. Check CAN Bus Filter Configuration
PeakCAN devices might have default filters that block incoming frames. Even if writing works, your read setup might be filtering out the frames sent from PCAN View. To disable filtering and receive all frames:
// Set up filters to accept all standard and extended frames QList<QCanBusFilter> filters; // Standard frame filter (ID range 0-0x7FF) QCanBusFilter stdFilter; stdFilter.format = QCanBusFilter::MatchBaseFormat; stdFilter.minId = 0; stdFilter.maxId = 0x7FF; filters.append(stdFilter); // Extended frame filter (ID range 0-0x1FFFFFFF) QCanBusFilter extFilter; extFilter.format = QCanBusFilter::MatchExtendedFormat; extFilter.minId = 0; extFilter.maxId = 0x1FFFFFFF; filters.append(extFilter); // Apply the filters to the device m_device->setConfigurationParameter(QCanBusDevice::FilterKey, filters);
Make sure this is done after connecting the device (some configurations require an active connection).
3. Ensure Receiving Isn't Paused
Accidentally pausing receiving can block the framesReceived signal. Add a check to confirm:
// Make sure receiving is enabled if (m_device->isReceivingPaused()) { m_device->resumeReceiving(); qDebug() << "Resumed receiving"; }
4. Test Manual Frame Reading
If the signal still doesn't trigger, bypass the signal-slot system temporarily to see if frames are actually arriving:
// Add a timer to manually poll for frames (in your constructor) QTimer* readPollTimer = new QTimer(this); connect(readPollTimer, &QTimer::timeout, this, [this](){ QList<QCanBusFrame> receivedFrames = m_device->readAllFrames(); qDebug() << "Manually read" << receivedFrames.size() << "frames"; for (const auto& frame : receivedFrames) { qDebug() << "Frame ID:" << QString::number(frame.frameId(), 16); } }); readPollTimer->start(100); // Poll every 100ms
- If manual reading works, the issue is with the signal-slot connection (double-check the
connect()call and object lifetimes). - If manual reading returns 0 frames every time, go back to checking device connection and filter settings.
Final Notes
Since writing works, your hardware, PeakCAN driver, and Qt PeakCAN plugin are correctly installed. The problem is almost certainly a configuration oversight or signal-slot misstep. Start with step 1, as connection issues and signal-slot order are the most common culprits here.
内容的提问来源于stack exchange,提问作者Romain PETIT

