Comunicazione tramite seriale

di il
30 risposte

Comunicazione tramite seriale

Buongiorno a tutti, sono un novizio del C++ e avrei bisogno di aiuto. Io dovrei scrivere un piccolo eseguibile in C++ che permettesse di prendere dei dati numerici da un file .txt e inviarli tramite porta seriale (COM2 nel mio caso) a un microcontrollore. Il problema è che non ho mai lavorato con le seriali e in più sono all'inizio della programmazione in C++. Non vi chiedo certo di risolvermi completamente il problema, ma vi chiedo se potreste per favore scrivermi alcune righe di codice per darmi un'idea di come si inizia un lavoro di questo tipo. Sono in alto mare proprio perchè non so come cominciare. Grazie in anticipo a tutti.

30 Risposte

  • Re: Comunicazione tramite seriale

    Ciao, dipende da che sistema operativo utilizzi.
    Se sei in Windows puoi utilizzare la API CreateFile()
    
    CreateFile(
          "\\\\.\\COM2",     // address of name of the communications device
          GENERIC_READ|GENERIC_WRITE,          // access (read-write) mode
          0,                  // share mode
          NULL,               // address of security descriptor
          OPEN_EXISTING,      // how to create
          0,                  // file attributes
          NULL                // handle of file with attributes to copy
       );
    
    E poi per spedire caratteri usi WriteFile() e per leggere usi ReadFile().
    Ad ogni modo qui è spiegato bene http://www.codeproject.com/Articles/3061/Creating-a-Serial-communication-on-Win32
    Spero di esserti stato d'aiuto
  • Re: Comunicazione tramite seriale

    Innanzitutto grazie delle preziose info che mi hai dato. Si io utilizzo Windows 7 come sistema operativo. L'unica cosa che non ho capito è l'utilizzo della funzione CreateFile. Come la devo usare se, ad esempio, voglio inviare tramite COM2 i dati provenienti da un file chiamato "prova.txt"?grazie dell'aiuto.
  • Re: Comunicazione tramite seriale

    Fossi in te userei una classe già fatta se no diventa lungo. Leggi le info di come si usa questa classe e poi vedrai che il tuo codice sarà lungo 10 righe al massimo.
    http://www.codeproject.com/Articles/992/Serial-library-for-C
  • Re: Comunicazione tramite seriale

    Allora ho scaricato i file .h e .cpp relativi alla classe CSerial, ma mi da alcuni errori in fase di compilazione all'interno del file .cpp

    Vi posto solo il codice relativo alle righe che danno errore e poco altro, così da non inserire cose inutili:
    
    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <stdio.h>
    #include <windows.h>
    #include "CSerial.h"
    
    CSerial::CSerial()
    {
    
    	....
            ....
    
    
    if (m_bOpened) return(TRUE);
    
    	char szPort[15];
    	char szComParams[50];
    	DCB dcb;
    	wsprintf(szPort, "COM%d", nPort); // ERRORE!!!!!!!
    
    
    	m_hIDComDev = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
    	if (m_hIDComDev == NULL) return(FALSE); // ERRORE!!!!!!
    
    	memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED));
    	memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));
    
    	COMMTIMEOUTS CommTimeOuts;
    	CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
    	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
    	CommTimeOuts.ReadTotalTimeoutConstant = 0;
    	CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
    	CommTimeOuts.WriteTotalTimeoutConstant = 5000;
    	SetCommTimeouts(m_hIDComDev, &CommTimeOuts);
    
    	wsprintf(szComParams, "COM%d:%d,n,8,1", nPort, nBaud); // ERRORE!!!!!!!!
    
    ...
    ...
    ...
    
    Gli errori sono tutti e 3 di questo tipo':
    - impossibile convertire l'argomento 1 da 'char [15]' a 'LPCWSTR'

    Sembra che le parole incriminate siano: "szPort", "COM%d", "szComParams", "COM%d:%d,n,8,1".

    Sapreste dirmi dove ho sbagliato?Io ho semplicemente scaricato questi due file e inseriti nel mio progetto (che al momento è ancora vuoto).

    Grazie
  • Re: Comunicazione tramite seriale

    Secondo me dovresti fare un passo indietro e provare a ricompilare il progetto di esempio.
    Il problema che hai è probabilmente dovuto ad header sbagliati (vedi stdafx.h) ma, come ti dicevo, è meglio se parti dal programma di esempio.
  • Re: Comunicazione tramite seriale

    Il problema è che non c'è nessun programma di esempio! Esistono solo questi due file Serial.h e Serial.cpp che io non posso fare altro che includere nel progetto e tentare di far funzionare!...Però mi segnala questo errore e non capisco perchè...

    Cosa intendi con "errore dovuto a header sbagliati"?Quali sarebbero secondo te?
  • Re: Comunicazione tramite seriale

    Magari puoi sostituire l'header stdafx.h con
    
    #define STRICT
    #include <crtdbg.h>
    #include <tchar.h>
    #include <windows.h>
    
    come è spiegato nell'articolo stesso.
  • Re: Comunicazione tramite seriale

    Allora ho utilizzato la classe CSerial come suggerito da skynet. Ho provato a scrivere un po' di codice ma non riesco a trovare un modo per inviare i dati contenuti nel mio file di testo tramite seriale.
    Il file di testo contiene dati disposti su 3 colonne e n righe
    (es. 1 2 3)
    4 7 9
    8 4 10
    2 4 1

    Vorrei inviarli riga per riga (cioè prima 1 2 3, poi 4 7 9, etc...) tramite la mia porta seriale, ma mi manca la parte del codice relativa all'invio di dati. Per giunta non trovo neanche esempi sul web. Help please. Grazie a tutti in anticipo.
    Vi posto il codice che ho scritto:
    
    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include <crtdbg.h>
    #include <string>
    #include <tchar.h>
    #include <windows.h>
    #include "Serial.h"
    
    
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        #define MAXR 100
    	float mat[MAXR][3];
    
    	// legge dati dal file txt
    	ifstream dati("C:\\Users\\ALESSANDRO\\Desktop\\Parte1.txt");
    	int r = 0;
    	while (!dati.eof())
    	{
    		dati >> mat[r][0] >> mat[r][1] >> mat[r][2];
    		r++;
    	}
    	dati.close();
    
    	CSerial serial; // utilizzo della classe CSerial
    	if (serial.Open(2, 9600)) // apre la porta seriale COM2
    	{
    		CODICE CHE MI MANCA DA SCRIVERE
    	}
    	else
    		MessageBox(HWND_DESKTOP, "Failed to open port!", "Error", MB_OK);
    	return 0;
    }
    
  • Re: Comunicazione tramite seriale

    serial.Write("Hello world");
    
    Cosa non comprendi?
    Sei sicuro di aver aperto la porta seriale correttamente?
    Che impostazioni si aspetta il microcontrollore come parita, bit di stop, handshaking ecc?
    Hai impostato un evento/messaggio custom da cui puoi ricevere le risposte della porta seriale?

    Cmq in nessun contesto della classe non vedo l'apertura porta col numero, ma sempre come stringa quindi fai attenzione anche ai valori di ritorno della funzione Open.
    virtual LONG Open (LPCTSTR lpszDevice, DWORD dwInQueue = 0, DWORD dwOutQueue = 0, bool fOverlapped = SERIAL_DEFAULT_OVERLAPPED);
    
  • Re: Comunicazione tramite seriale

    Altra cosa da segnalare.
    Tu non hai un MessageLoop in quanto sei in console. Il MessageBox che usi ha come parent il desktop. Quindi senza MessageLoop non puoi avere messaggi custom da cui non puoi ricevere risposta dal microcontrollore.
    Se questa è una cosa sporadica (mando dati e stop) può anche andar bene ma controlla l'apertura porta e impostazioni di connessione.
  • Re: Comunicazione tramite seriale

    bool CSerialPortManager::Initialize( CWnd *pParent )
    {
    	std::wstring comPort = std::move(_T("COM") + to_string(m_comPortNumber,0));
    	LONG lastError = Open(comPort.c_str(),pParent,UWM_SERIAL,m_comPortNumber);
    	if(lastError == ERROR_SUCCESS)
    	{
    		Setup(CSerialMFC::EBaud2400,CSerialMFC::EData8,CSerialMFC::EParNone,CSerialMFC::EStop1);
    		SetupHandshaking(CSerialMFC::EHandshakeOff);
    		SetupReadTimeouts(CSerialMFC::EReadTimeoutNonblocking);
    		return true;
    	}
    	return false;
    }
    
    Piccolo esempio (anche se in MFC) di apertura porta e controllo errore.
  • Re: Comunicazione tramite seriale

    Per inviare una stringa scritta sul momento (tipo "Hello World") ho capito come si fa, ma non so bene quale sia il codice corretto per inviare dei dati presi da un certo file. Magari è molto simile il codice, ma non essendo molto esperto non sono riuscito a scriverlo.
    No a dirti la verità non sono affatto sicuro di averla aperta correttamente, dato che è la prima volta che lo faccio!!:)...Ci ho provato, ma probabilmente nel mio codice ci sono ancora delle lacune. Per questo lo ho postato, così almeno potrò imparare qualcosa dalle vostre correzioni.

    Grazie ancora
  • Re: Comunicazione tramite seriale

    Le impostazioni della comunicazione col microcontrollore li sai solo tu quindi informati di questo e possiamo modificare il tuo codice di conseguenza.
  • Re: Comunicazione tramite seriale

    Ok ti ringrazio. Il microcontrollore non lo ho progettato io, ma un'altra persona e quindi devo chiedere a lui le specifiche e così potrò comunicartele.
    Nel frattempo ti chiedo una cosa riguardo il codice da te postato: il tuo codice scritto in MFC è molto diverso da quello che dovrei scrivere io oppure cambia solo un po' la dicitura?...
Devi accedere o registrarti per scrivere nel forum
30 risposte