Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 23
  1. #1

    [C] aiuto Comunicazione Seriale

    Salve ragazzi mi sono appena iscritto al forum, sono giorni ormai che spulcio su e giù per la rete in cerca di una risposta al mio quesito ma purtroppo non ne sono ancora venuto a capo
    Dunque, sto facendo un piccolissimo programma in C per comunicare con Arduino, quello che vorrei fare è inviare/ricevere dati tramite la porta seriale (nel mio caso specifico la COM9).

    Venendo al punto per l'invio dei dati ad arduino non ci dovrebbero essere problemi, ho creato uno sketch semplicissimo (conteggia quante volte riceve il carattere 'a' dalla seriale (utilizzando la funzione Serial.read() ) e se il numero di volte è pari accende un led altrimenti lo spegne), mentre dal lato C ho scritto quanto segue:
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    int main(){
    	FILE *file;
    	system("mode com9: baud=9600 parity=o data=8 stop=1 xon=off");
    	if((file = fopen("COM9", "wb+"))==NULL)
    		printf("Errore");
    	fprintf(file, "a");
    	fclose(file);
            system("PAUSE");
            return 0;
    }
    All'inizio non funzionava troppo bene, poichè omettevo la funzione "system("mode com9: baud=9600 parity=o data=8 stop=1 xon=off");" che ho trovato su internet e della quale non ho ancora ben compreso il funzionamento (se qualcuno fosse così gentile da spiegarmelo gli sarei più che grato )
    Comunque per quanto riguarda l'invio del carattere tutto ok piu o meno..il vero problema sta nella ricezione!
    Nello sketch di arduino ho provato ad inserire un "Serial.println("ciaomondo");" e con il programma in C ho provato a scrivere:
    codice:
    	char string[50];
    	fscanf(file,"%s", string);
    	printf("str: %s \n", string);
    	rewind(file);
    senza alcun risultato purtroppo..
    Sareste così gentili da spiegarmi dove sbaglio?
    E per la funzione "system("mode com9: baud=9600 parity=o data=8 stop=1 xon=off");" che mi dite?

    Ringrazio in anticipo chiunque vorrà rispondere!
    Ciao!!!
    Vincenzo

  2. #2

    Moderazione

    Benvenuto sul forum! Ti ricordo che il codice va specificato tra tag [CODE] ... [/CODE], altrimenti perde l'indentazione.

    Ora correggo io, in futuro imposta correttamente la discussione fin da subito.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Ok ho capito, grazie della correzione ci starò più attento in futuro!

  4. #4
    Ciao _Achille_ grazie per i consigli, comunque ho risolto ed effettivamente ho abbandonato quella soluzione :P posto qui di seguito il codice che ho scritto, funziona bene (se trovate eventuali errori/aggiustamenti fatemi sepere naturalmente)
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    int main(){
    
    	//	apro porta seriale in lettura e scrittura
    	HANDLE hCom;
    	hCom = CreateFile("COM9", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
    	//controllo (assolutamente obbligatorio)
    	if(hCom == INVALID_HANDLE_VALUE){
    		printf("errore durante l'apertura della porta\n");
    		return -1;
    	}
    
    	printf("porta aperta\n");
    
    	//leggo i parametri correnti
    	DCB myDCB;
    	memset(&myDCB, 0, sizeof(DCB));
    	BOOL Ok = GetCommState(hCom, &myDCB);
    	printf("BaudRate: %d \n", myDCB.BaudRate);
    	printf("ByteSize: %d \n", myDCB.ByteSize);
    	printf("Parity: %d \n", myDCB.Parity);
    	printf("StopBits: %d \n", myDCB.StopBits);
    
    	//Per parità e bit di stop, otteniamo le define di Windows. Per una visualizzazione completa, dovremmo creare degli switch. Esempio per i bit di stop:
    
    //	switch(myDCB.StopBits)
    //	{
    //	case ONESTOPBIT:
    //	     printf("ONESTOPBIT\n");
    //	     break;
    //	case ONE5STOPBITS:
    //	     printf("ONE5STOPBITS\n");
    //	     break;
    //	case TWOSTOPBITS:
    //	     printf("TWOSTOPBITS\n");
    //	     break;
    //	}
    
    	//settare la velocità della porta a 9600 baud
    	myDCB.BaudRate = CBR_9600;
    	Ok = SetCommState(hCom, &myDCB);
    
    	//aggiungiamo la scrittura della stringa
    	char msg[]="a";
    	DWORD NumeroByteScritti = 0;
    	DWORD NumeroByteDaScrivere = strlen(msg);
    	Ok = WriteFile(hCom, msg, NumeroByteDaScrivere, &NumeroByteScritti, NULL);
    	printf("Scritto %d bytes \n", NumeroByteScritti);
    
    	system("PAUSE");
    
    	//mi metto in "polling" e leggo (il ciclo si interrompe con un tasto)
    	printf("lettura\n\n");
    	for(;;){
    		char c;
    		DWORD NumeroByteLetti;
    		Ok = ReadFile(hCom, &c, 1, &NumeroByteLetti, NULL); //NB l'1 sta a indicare che legge un carattere alla volta (compreso il newline "\n")
    		if(NumeroByteLetti > 0)
    			printf("%c", c);
    
    		if(c=='a'){
    			printf("TROVATO!\n");
    			break;
    		}
    
    		int tastouscita = _kbhit();
    		if(tastouscita)
    			break;
    	}
    
    	CloseHandle(hCom);
    	system("PAUSE");
    
    	return 0;
    }
    Come dicevo questo codice funziona bene (o per lo meno a me non da problemi), l'unica cosa che non mi torna è che per farlo funzionare correttamente devo collegare Arduino al pc, e aprire il SerialMonitor dal suo IDE. Dopodichè il C fa tutto a dovere, altrimenti da una marea di simboli strani secondo voi che può essere?

  5. #5
    PS naturalmente prima di lanciare il programma C devo chiudere il serial monitor altrimenti non può accedere alla porta.. comunque ancora non ho capito cosa devo fare esattamente, sicuramente avrò omesso qualche settaggio, sono nelle vostre mani

  6. #6
    Nono aspetta un momento, mi sarò spiegato male io sicuramente!
    Dunque le cose stanno così:

    1) attacco Arduino al PC (altrimenti ne il monitor seriale del suo IDE ne il programma in C riescono a connettersi perchè la porta COM9 rimane giustamente chiusa se non collego dispositivi ad essa)

    2) una volta attaccato arduino, apro il monitor seriale del suo IDE per controllare se effettivamente funziona (lo sketch è semplicissimo: mi da i valori di una fotoresistenza collegata ad esso e scrive "X" se il valore della fotoresistenza sale oltre una certa soglia)

    3) a questo punto CHIUDO il monitor seriale di Arduino e APRO l'exe che ho costruito con C (naturalmente una porta seriale "supporta" un accesso alla volta, quindi se io ho aperto il monitor seriale di Arduino la COM9 è "occupata" e se apro il programma C mi dice appunto che non può aprirla perchè è già aperta da un altra parte. Viceversa se il programma C è in funzione, non posso accedere contemporaneamente anche al monitor seriale di Arduino perchè naturalmente la risorsa COM9 è aperta da un altra parte. In poche parole se uso il monitor seriale non posso usare il prog C e se uso il programma C non posso usare il monitor seriale perchè la porta non "regge" 2 accessi contemporaneamente. Ma fin qui è tutto normale, deve essere così)

    I problemi sorgono quando "inverto" i punti 2) e 3) ovvero:
    Siccome Arduino è dotato di una memoria che, anche se lo scolleghi e ricolleghi successivamente, gli permette di rieseguire l'ultimo sketch caricato (senza stare quindi a caricare ogni volta lo stesso sketch), se io lo stacco dalla usb e lo ricollego in seguito, lui dovrebbe riprendere a funzionare normalmente (ed infatti i led sull'Arduino che si illuminano quando invia/riceve dati cominciano a funzionare da soli, quindi Arduino sta effettivamente eseguendo quello sketch) dunque se io aprissi il programma C non dovrebbe darmi problemi: alla fine esegue una connessione sulla porta dove è connesso anche lui e ne preleva le informazioni.

    Invece non è così, mi da una serie di caratteri incomprensibili e non funziona, ovvero non riesce a "decifrare" quando la fotoresistenza fa si che arduino invii il carattere "X".
    Di conseguenza, OGNI VOLTA che attacco Arduino al PC devo PER FORZA aprire il suo monitor seriale e poi chiuderlo (PRIMA), e solo DOPO questa operazione il mio programma in C funziona.

    Non posso dunque collegare arduino al pc e successivamente far partire il programma C, devo passare per forza per la strada apri monitor seriale, chiudi monitor seriale.

    Ed è questo che non capisco...
    Alla fine non è un problema così grave, aprire e chiudere il monitor seriale di Arduino è una questione di un secondo..però naturalmente è un problema ed io vorrei capirne le cause

    Spero di essermi spiegato bene

  7. #7
    Tre suggerimenti:

    Imposta il campo DCBlength della struttura myDCB prima di chiamare la GetCommState.

    Imposta anche altri campi del DCB, alcuni sono molto importanti (http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx).

    Controlla il valore di ritorno di tutte le funzioni che chiami, non solo della CreateFile, e verifica eventuali errori.

  8. #8
    Ciao ESSE-EFFE, grazie dei suggerimenti proverò a scrivere qualche riga oggi stesso e vi farò sapere.
    Comunque a proposito di questi settaggi, ho dato un occhiata al link che mi hai lasciato e ho visto che posso settare anche la "parità" della porta, ho visto in giro per la rete molti altri esempi che la settano ma sinceramente non ho trovato nulla che mi dica che cos'è!
    Sapreste aiutarmi? Che cos'è la "parity" di un porta? secondo quale criterio dovrò settarla?

    Altra domanda, sempre in quel documento (al link che mi hai dato) spiega come settare ogni campo del DCB però non spiega a cosa serve ogni suddetto campo! Io oggi provo a fare qualche ricerca ma intanto butto là questa seconda domanda:
    quali sono i campi "principali" da settare del DCB? E con che criterio li dovrò settare?
    Grazie!!

    PPS se scopro qualcosa "da solo" ve lo farò sapere!

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  10. #10
    Ok ho capito che la parità è uno dei metodi più semplici per rilevare gli errori in una trasmissione di dati..benissimo grazie, comunque a questo punto nel mio caso specifico è una cosa che posso omettere o potrebbe risolvere il mio problema..? Scusate la mia ignoranza in materia (anche perchè se non fossi ignorante probabilmente non cercherei aiuto :P ) ma non riesco a capire la causa del problema quindi effettivamente non so se è un problema di parità o di qualche altra roba e ho letto che con le porte seriali c'è da starci molto attenti quindi vorrei evitare di andare "a tentativi" con i settaggi
    quello che non ho capito è, quindi in un sistema di comunicazione seriale che non utilizza le funzioni di parity che problemi possono insorgere?
    e per il mio caso specifico, secondo gli esperti o anche chi ha già avuto a che fare con cose del genere, a che settaggio devo pensare?
    Grazie!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.