salve ho un problema con uno sketch.
la situazione è questa ho 3 display a 7 segmenti a 3 cifre ognuno collegati a 3 sonde di temperatura e ho anche integrato dei maxim7219 per utilizzare meno pin di arduino. Alla fine tutto funziona bene ogni sonda interagisce con il rispettivo display.
pensavo che il difficile era fatto invece non è cosi. il mio obiettivo è quello di interagire con le varie temperatura per creare degl'allarmi. la temperatura di riferimento se la imposto direttamente nel codice arduino gli allarmi funzionano. Pero il mio intento è quello di impostare la temperatura con visual basic e inviarla tramite porta seriale. Ed ecco che nasce il problema e cioe non funziona.
leggendo la guida della funzione serialport.write() di visual basic ho capito che questo comando invia sulla porta seriale una valore di tipo stringa e quindi nel mio caso ad arduino arriva una stringa che ovviamente non potra interagire con i valori delle sonde che sono di tipo "int"
Secondo Voi è questo il problema?
Come posso risolvere?
Non conosco visual basic, però posso assicuranti che tutte le trasmissioni di dati via seriale avvengono un byte alla volta. Un byte può rappresentare in binario un valore decimale massimo di 255.
Nel vecchio basic c'èra una istruzione CHR("A") che restituisce il codice ASCII numerico che corrisponde al carattere A, cioè 65. Un byte spedito o ricevuto è sempre un numero binario che può essere interpretato come preferiamo noi. Più byte insieme possono rappresentare un numero maggiore di 255, es 4 byte possono rappresentare un numero decimale con o senza segno con virgola mobile o meno.
Se spedisci delle stringhe queste per essere interpretate dal programma C su arduino devono terminare con il carattere terminatore di stringa '\0' o Null string. In C il tipo che può contenere una stringa è: char myString[strlen], che in breve è un array di caratteri che termina con null string.
Grazie per la risposta ma non ho le idee troppo chiare. A me non serve convertire un stringa in ASCII ma bensì una stringa in numero senza alterare niente cioè la temperatura stringa 20 deve diventare temperatura int 20 su arduino. Da quello che ho capito leggendo il tuo post dovrò spedire la mia stringa da visual basic seguito da\O quindi il mio 20 in arduino diventerà 20\O. Giusto? Poi in arduino devo gestire questa stringa con char ed estrapolare il 20 che mi serve in una variabile che sarà di tipo int. Giusto?
nikola291:
... A me non serve convertire un stringa in ASCII ma bensì una stringa in numero senza alterare niente ...
Una volta che hai la tua stringa sotto forma di "array di char" terminata correttamente con 0x00 (le stringhe di caratteri vanno sempre terminate con il carattere 0x00 che indica alle varie funzioni che le trattano la fine stringa), puoi usare le funzioni atoi() o atol() per effettuare le conversioni in numeri (fanno parte della stdlib.h che è automaticamente inclusa dall'IDE di Arduino).
grazie Guglielmo
a quindi portando un esempio dovrebbe essere cosi
visualbasic
' temperatura di 20°
serialprint.write(200x00)
arduino (riprto solo quello che va scritto nel void loop
String letturavisualbasic=Serial.read();
char val[5];
String letturarduino=letturavisualbasic.substring(1,2);
letturarduino.toCharArray(val,5);
A me non serve convertire un stringa in ASCII ma bensì una stringa in numero senza alterare niente cioè la temperatura stringa 20 deve diventare temperatura int 20 su arduino.
Quello che devi fare tu, lo sai solo tu. Rimane il fatto che attraverso una connessione elettrica dove transitano dati digitali questi sono dei numeri, punto. Che poi questi numeri si decide di interpretarli come caratteri (tramite la tabella ASCII) o prenderli come byte o collezionarli in 2 o 4 byte e interpretarli come interi o float è un compito che spetta al programmatore.
"String" è un classe di arduino core, che permette di collezionare caratteri. Se vuoi usare String sappi che è oneroso in termini di consumo risorse CPU.
char val[n] deve essere grande quanto basta a contenere tutti i caratteri + 1 detto null string.
La conversione toCharArray inserisce alla fine della collezione di caratteri il carattere null string.
val puoi usarlo con atof, atoi ecc.
Non fare confusione tra la classe String e l'array di caratteri con il terminatore null string.
NO, come ti ha detto Mauro, io ho parlato di stringhe di caratteri che sono degli array di char e NON di variabili di tipo String che sono tutt'altra cosa e che ... dato come sono fatte (allocazione dinamica della memoria), te le sconsiglio caldamente !
Quindi io intendevo un :
char miaStringa[10];
... io ho messo, per fare un esempio, 10 char, ma tu dovrai dimensionarla in funzione del numero massimo di caratteri che dovrà contenere più uno ... lo 0x00 terminatore.
Poi ...
... se leggi il reference, la Serial.read() legge UN SOLO char alla volta e non un insieme di caratteri ! Sarà compito tuo fare un loop in cui leggi carattere a carattere, metti nella giusta posizione all'interno dell'array miaStringa (... ad esempio), controlli se ricevi un carattere terminatore a tua scelta (es. il CR o LF o quello che vuoi) e, a quel punto aggiungi lo 0x00 e trasformi ciò che hai ricevuto come vuoi
quindi volendo nel io caso leggere un numero una stringa sempre composta da 2 caratteri il mio char deve essere [4].(2 sono i caratteri 1 è il carattere terminatore e 1 lo 0x00) mentre per quanto riguarda il discorso di lettura della porta quindi per ricevere la stringa 20 la porta dovra leggere 2 vole piu la terza volta per leggere il carattere di fine stringa.
Bé ... se poi vuoi convertire la stringa ricevuta in un numero (es. con atoi) ... il tuo carattere terminatore lo devi scartare (... darebbe fastidio nella conversione) e mettere come ultimo carattere SOLO 0x00.
In ogni caso ti consiglio di fare quell'array un po' più lungo ... se domani invece di 20 devi mandargli, ad esempio, 210 ... che fai ? Modifichi il programma ? Dimensionalo per il massimo che ti potrà servire, tanto il fine stringa è identificato dallo 0x00
Puoi prendere spunto anche dalla funzioni presenti nelle librerie allegate all'IDE, ad esempio la parseInt, e crearti la tua funzione di lettura specifica.
// returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// function is terminated by the first character that is not a digit.
long Stream::parseInt()
{
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
}
// as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar)
{
boolean isNegative = false;
long value = 0;
int c;
c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == skipChar)
; // ignore this charactor
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == skipChar );
if(isNegative)
value = -value;
return value;
}
... NON solo quelle funzioni sono DIESEDUCATIVE (... la prima volta che invece di un int o un long devi ricevere una struttura ti spari ... visto che usandole non impari nulla e non sai come gestire una trasmissione/ricezione seriale) e poi ... NON hai alcun controllo sugli errori di trasmissione ... ti perdi i dati che è una bellezza (... ricorda che scartano, senza dare errore, ma zero, qualsiasi cosa non sia del tipo che si aspettano), quindi ... caldamente da evitare !!!
Guglielmo
Edit : Al limite, se proprio uno non si vuole sbattere (... ed imparare) allora è meglio suggerire la Serial.readBytesUntil() ... almeno hai molto più controllo su quello che ricevi !!!
Quindi dalla tua risposta precedente penso di aver capito che sono sulla buona strada giusto? Se vuoi indicarmi dove imparare quello che voglio fare te ne sarei grato e magari ti darò così meno fastidio in futuro a hahaha
Infatti Guglielmo, non gli ho detto di prenderla paro paro, ma di trarne spunto per crearsi una sua funzione di lettura, secondo un suo protocollo di comunicazione.
Non è necessario inventare ogni volta la ruota, si può anche scopiazzare, l'open source serve anche per questa.
nikola291:
Quindi dalla tua risposta precedente penso di aver capito che sono sulla buona strada giusto?
Si, sei sulla strada giusta e ... se fai n po' di ricerche qui sul forum ... t'accorgerai che l'argomento è stato trattato decine e decine di volte e ... troverai tutte le info che ti servono ... XD XD XD
PaoloP:
Non è necessario inventare ogni volta la ruota, si può anche scopiazzare, l'open source serve anche per questa.
Non sono affatto d'accordo ... lo scopiazzare NON serve a nulla, occorre CAPIRE perché si fa una cosa per imparare e poi andare avanti con le proprie gambe !!!