**"Problema con la Comunicazione Seriale con RP2040"**

Sto cercando di stabilire una comunicazione seriale tra un’applicazione C++ su Windows e un microcontrollore RP2040 (XIAO RP2040). Ho implementato una funzione ConnectRP per aprire la porta seriale, configurare i parametri (baud rate, timeout, ecc.), simulare il comportamento del serial monitor attivando/disattivando i segnali DTR/RTS e inviare un segnale di wake-up. Tuttavia, il codice non funziona correttamente a meno che non apra prima un serial monitor (ad esempio, quello integrato in VS Code).

Quando uso il serial monitor:

  • L’RP2040 si “sveglia” correttamente.
  • La comunicazione avviene senza problemi.

Quando uso il mio codice:

  • L’RP2040 non risponde ai comandi successivi.
  • Non ricevo alcuna risposta dal dispositivo.

Ho provato diverse soluzioni, come simulare il comportamento del serial monitor (attivando/disattivando DTR/RTS), inviare caratteri di wake-up (\n\n\n) e aggiungere ritardi, ma il problema persiste.

// Funzione ausiliaria per registrare un errore e chiudere la porta seriale
void CArduMover::LogAndClosePort(const CString& errorMessage) {
	if (m_enableLog) {
		m_moverLog.WriteError(_T("Connect RP"), errorMessage);
	}
	if (m_hSerial_rp != INVALID_HANDLE_VALUE) {
		CloseHandle(m_hSerial_rp);
		m_hSerial_rp = INVALID_HANDLE_VALUE;
	}

	
}

void CArduMover::SimulateSerialMonitor(HANDLE hSerial) {
	// Attiva DTR e RTS per 50 ms
	EscapeCommFunction(hSerial, SETDTR);
	EscapeCommFunction(hSerial, SETRTS);
	Sleep(50); 
}



int CArduMover::ConnectRP() {
	// Recupera la porta seriale associata al dispositivo RP2040
	CString comPort_rp = CGetCom::GetPortRP(CGetCom::ComConnectedType_T::RP2040);
	int iRet = MVR_ERR_SUCCESS;

	// Se non è già connesso, procedi con la connessione
	if (!m_connected_rp) {
		// Verifica che la porta seriale sia valida (lunghezza > 3 caratteri)
		if (comPort_rp.GetLength() > 3) {
			// Formatta il nome della porta seriale per Windows
			comPort_rp = _T("\\\\.\\") + comPort_rp;

			// Apre la porta seriale
			m_hSerial_rp = CreateFile(
				comPort_rp,
				GENERIC_READ | GENERIC_WRITE,
				0,
				NULL,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL,
				NULL
			);

			// Verifica se l'apertura della porta seriale è andata a buon fine
			if (m_hSerial_rp == INVALID_HANDLE_VALUE) {
				if (m_enableLog) {
					m_moverLog.WriteError(_T("Connect RP"), _T("Errore apertura porta seriale"));
				}
				return MVR_ERR_HARDWAREFAIL;
			}

			Sleep(1000);

			SimulateSerialMonitor(m_hSerial_rp);

			Sleep(1000); // Attendi 1 secondo per completare il reset

			// Configura i parametri seriali
			DCB dcbSerialParams = { 0 };
			dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

			if (!GetCommState(m_hSerial_rp, &dcbSerialParams)) {
				LogAndClosePort(_T("Errore nella lettura dello stato della porta seriale"));
				return MVR_ERR_HARDWAREFAIL;
			}

			dcbSerialParams.BaudRate = CBR_256000;
			dcbSerialParams.ByteSize = 8;
			dcbSerialParams.StopBits = ONESTOPBIT;
			dcbSerialParams.Parity = NOPARITY;

			if (!SetCommState(m_hSerial_rp, &dcbSerialParams)) {
				LogAndClosePort(_T("Errore nella configurazione dei parametri seriali"));
				return MVR_ERR_HARDWAREFAIL;
			}

			// Configura i timeout per la lettura/scrittura
			COMMTIMEOUTS timeouts = { 0 };
			timeouts.ReadIntervalTimeout = 50;
			timeouts.ReadTotalTimeoutConstant = 5000;
			timeouts.WriteTotalTimeoutConstant = 1000;

			if (!SetCommTimeouts(m_hSerial_rp, &timeouts)) {
				LogAndClosePort(_T("Errore nella configurazione dei timeout"));
				return MVR_ERR_HARDWAREFAIL;
			}

			// Pulisci i buffer prima di inviare il segnale di wake-up
			PurgeComm(m_hSerial_rp, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

			// Aggiorna lo stato di connessione
			m_connected_rp = true;
			CleanReadBuffer();
		}
		else {
			if (m_enableLog) {
				m_moverLog.WriteError(_T("Connect RP"), _T("Porta seriale non rilevata"));
			}
			return MVR_ERR_HARDWAREFAIL;
		}
	}

	return iRet;
}

Hi there,

So Others may help: G translate…
"
This ensures the stability of serial communication between a C++ application on Windows and an RP2040 microcontroller (XIAO RP2040). I have implemented a ConnectRP function to open the serial port, configure the parameters (baud rate, timeout, etc.), simulate the behavior of the serial monitor by activating/disengaging the DTR/RTS signals and sending a wake-up signal. However, the code does not work correctly unless a serial monitor is present (for example, it is integrated in VS Code).

When I use the serial monitor:

L’RP2040 if “sveglia” correctly.
Communication becomes problematic.
When I use il mio code:

L’RP2040 does not respond to successive commands.
Do not receive any response from the device.
To try various solutions, how to simulate the behavior of the serial monitor (activating/disabling DTR/RTS), sending wake-up characters (\n\n\n) and updating again, the problem persists. "

Are you using the " While Serial " in the code? if so remove or comment it out and try again.
HTH

GL :slight_smile: PJ :v: