problema connessione Arduino Mega 2560 < Firmata > VisualBasic 2010

Ciao a tutti,

sono nuovo nel forum e scusate se vi chiedo subito aiuto, ma spero che qualcuno mi possa dare qualche consiglio sul mio progetto. Come scritto nella presentazione, sto cercando di fare un progetto per controllare un fermentatore tramite Arduino e mandare tutti i dati a Visual Basic per un interfaccia grafica e registrare i dati.

Ho già provato con Firmata, ma dopo qualche minuto (a volte anche secondo) si interrompe la comunicazione e si blocca tutto. Ho caricato su arduino un insieme di Simple Analog e Simple Digital Firmata come visto su un tutoria su internet, caricato in VisualBasic l'applicazione e controllato i pin di Arduino con "FirmataVB1.DigitalWrite(pin, stato)". Tutto funziona perfettamente, ma dopo un po' sembra che si interrompe la comunicazione e su VB mi dice che una periferica collegata non è infunzione.

Ho provato anche a fare una libreria mia ma credo che è troppa la mole di dati da scambiare (forse uso int al posto di Char o qualcosa di simile).

Qualcuno ha qualche consiglio da darmi?

Vi ringrazio fin da subito per il prezioso aiuto.

Giacomo.

Ciao,
allora ... se ben capisco da una parte hai un PC con VB e dall'altra Arduino ...

Arduino, collegato tramite la USB al PC, viene visto da quest'ultimo come una porta COM: quindi, da VB, dovrai aprire la COMx: e parlare con essa.

Dal lato Arduino, lascia stare Firmata e scriviti tu il codice per fare ciò che ti serve. Avrai più flessibilità e tutto sotto controllo :wink:

Ricorda solo che su Arduino la porta seriale lavora "carattere a carattere" ... un carattere alla volta ... quindi, qualsiasi cosa devi trasmettere/ricevere, devi farlo con dei loop che spediscono/ricevono un carattere alla volta.
Studiati attentamente tutti i vari metodi della classe Serial e vedrai che puoi fare veramente di tutto ...

In merito all'uso della porta seriale, qui sul forum ci sono decine e decine di discussioni ... comunque ... se serve, noi siamo qui ... :wink:

Guglielmo

Ciao Guglielmo,

innanzitutto grazie mille per la risposta. Come hai capito perfettamente ho un Arduino che comunica tramite USB com il PC sul quale ho Visual Basic dal quale gestisco tutti i parametri. Per la comunicazione in se per se non ci sono problemi, ovvero riesco a comunicare sia lato Arduino che lato PC, ma usando Firmata dopo un po si blocca tutto, cos' ho deciso di fare una libreria per conto mio (come hai giustamente consigliato tu ;)). Ma anche ora ho dei piccoli problemi: ogni tanto Arduino non fa precisamente quello che voglio io e soprattutto ci mette tanto (5 - 10 secondi) prima di agire, ma non sempre il che provoca problemi (aziono pompe, iniezione di gas, eccc). Vorrei sapere se per caso è un problema di programmazione o è solo un problema di velocità di scambio di dati?
Ecco il codice lato Arduino (lo so, è un cavernicolo come codice) per mandare al PC il valore dell'entrata analogica A0

int sensore;
void setup(){
Serial.begin(57600);
}
void loop(){
sensore = analogRead(A0);
Serial.println(sensore);
}

per quella digitale metto

int sensoreDig;

void setup(){
Serial.begin(57600);
pinMode(5, INPUT);
}

void loop(){
sensoreDig = digitalRead(5)
if (sensoreDig == HIGH){
Serial.println ("A");
}

dal lato PC gli dico che se arriva una "A" vuol dire che il valore del sensoreDig e HIGH

e invece per ricevere comandi, nel loop metto :

int comando;
comando = Serial.read();
if (movemento == 'P'){
digitalWrite(12, HIGH);
}
//avendo dichiarato nel setup che il pin 12 era di OUTPUT

ho decine di segnali da mandare e poteri fare il loop da parte PC ogni 1000 millisecondo e mettere un deley ma ugualmente non va come vorrei? Potrei mettere qualcosa come Byte al posto di int ma non me lo legge da perte PC?

Grazie mille per qualsiasi aiuto in merito.

Giacomo

scusate l'italiano :blush:

gli ultimi due, erano dei punti, non punti di domanda.

Allora, guardando i tre pezzi di codice ...

Il primo :
quello è un loop veramente stretto, nella realtà immagino che farai un'acquisizione dal canale analogico, la trasmetterai e ... aspetterai X millisecondi prima di rileggere, quindi ... aggiungi un delay ...

Il secondo :
... stessa cosa ... se il segnale rimane HIGH ... in un loop così stretto hai una trasmissione continua ... metti anche qui un delay()

Il terzo :
c'è un errore di base che sicuramente ti crea problemi ... non puoi leggere dalla seriale se prima non verifichi che ci sia qualche cosa da leggere (... pena ricevere a raffica il valore -1) ... devi condizionare la Serial.read() ad una :

if (Serial.available() > 0) {
   ...
   ...
}

Guglielmo

... aggiungo, relativamente al primo e secondo pezzo di codice che, come puoi leggere nel reference :

"As of version 1.0, serial transmission is asynchronous; Serial.print() will return before any characters are transmitted."

il che significa che ciò che tu dai da trasmettere viene bufferizzato, ma ... il buffer è piuttosto limitato (credo 64 bytes) e quindi devi dargli il tempo di svuotarsi o ... perdi i dati che trasmetti ...

Guglielmo

Perfetto.

Sembra che possa essere questo il problema. Proverò a condizionare la seriale prima di inviare tutti i dati e metto un delay dopo ogni lettura (ne ho una decina digitali e 7 analogici, per questo uso il Mega) delay(50); può andare bene, anche per far scuotere il buffer o è meglio mettere un delay maggiore tra la parte dello sketch che riceve i dati e quello che manda al PC?

Grazie mille di nuovo.

Giacomo.

... vedo che hai la seriale a 57600 ... il che significa che ogni char impiega come minimo, solo per la trasmissione fisica 1/5760 sec. e quindi, in funzione di quanti caratteri invii (caratteri, mi raccomando ... il numero intero 32500 inviato con una Serial.print via seriale sono come minimo 5 caratteri più, se li trasmetti il CR e LF finali, che fanno in tutto 7) cambia il tempo ...

Comunque, con un delay(50) ... ci dovresti stare dentro alla grande :wink:

Guglielmo

Ok. Provo a fare tutte queste modifiche e ti faccio sapere :wink:

Rieccomi qui e purtroppo non sono riuscito a risolvere i miei problemi :~

sembra che vada tutto bene, i valori analogici mandati da Arduino arrivano bene, ma dopo un po che gli mando dei comandi, a un certo punto si blocca tutto. Dalla parte di VB mi esce un Msg box con scritto:

IOException non è stata gestita
Una periferica collegata al sistema non è in funzione.

Ma fino a un secondo fa reagiva perfettamente e tutto di un tratto si è impuntata.

ti metto il codice per intero, l'ho snellito ma anche così non funziona

int pH1;
int pH2;
int DO;
int Co2 = 8;
int O2 = 12;


void setup(){
  Serial.begin(57600);
  pinMode(Co2, OUTPUT);
  pinMode(O2, OUTPUT);
  
}

void loop(){
 pH1 = analogRead(A1);
 Serial.println(pH1);
 delay(50);
 pH2 = analogRead(A0);
 Serial.println(pH2);
 delay(50);
 DO = analogRead(A2);
 Serial.println(DO);
 delay(50);

 if (Serial.available() > 0){
   int iniezione = Serial.read();
   if (iniezione == '1'){
     digitalWrite(Co2, HIGH);
     digitalWrite(O2, LOW);
   }
   if (iniezione == '2'){
     digitalWrite(Co2, LOW);
     digitalWrite(O2, HIGH);
   }
   if (iniezione == '0'){
     digitalWrite(Co2, LOW);
     digitalWrite(O2, LOW);
   }
   delay(50);
 }
}[code]

dove il comando "iniezione"  lo mando da VB con un timer ogni 300 ms, il cui valore lo cambio premendo dei pulsanti.

Che possa essere un problema di Hardware o che il Pc che sto usando è un po' vecchiotto (ha ancora Windows XP).

Non saprei più cosa provare. Non c'è un comando per svuotare il buffer?

Ti ringrazio ancora per l'infinita pazienza.

Giacomo.

[/code]

Mmm ... a me sembra che non ci sia nulla di sbagliato ... :roll_eyes:

Comunque ...
... relativamente ai buffer ci sono due strade, una per il TX buffer ed una per il RX buffer :

TX Buffer:
Usare la Serial.flush() che ferma il programma fino a quando il TX buffer non è vuoto. Qundi allo statement successivo, sei sicuro che il TX buffer e completamente stato trasmesso.

RX Buffer:
Per svuotare completamente il RX buffer puoi fare un loop stretto del tipo :

while (Serial.available()) {
   Serial.read();
   delay(1);
}

... e all'uscita dal while non ci sono più caratteri disponibili nel buffer.

Solo per fare una prova, allunga il tempo ogni quanto trasmetti da PC qualche cosa ... da 300 msec. prova a fare 750 msec. .... tanto per vedere ...

Guglielmo

Nulla da fare =(.

Ho anche provato a mandare i comandi "iniezione" dalla seriale di Arduino e fino a un po' funziona e poi chiude la connessione e i led di comunicazione TX e RX o rimangono sempre accesi o rimangono sempre spenti. Invece se non mando nulla tutto ve bene e ho provai a lasciarlo anche tutta la notte senza problemi.

ora il codice è così:

int pH1;
int pH2;
int DO;
int Co2 = 8;
int O2 = 12;


void setup(){
  Serial.begin(57600);
  pinMode(Co2, OUTPUT);
  pinMode(O2, OUTPUT);
  
}

void loop(){
 pH1 = analogRead(A1);
 Serial.println(pH1);
 delay(50);
 Serial.flush();
 pH2 = analogRead(A0);
 Serial.println(pH2);
 delay(50);
 Serial.flush();
 DO = analogRead(A2);
 Serial.println(DO);
 delay(50);
 Serial.flush();

 if (Serial.available() > 0){
   int iniezione = Serial.read();
   if (iniezione == '1'){
     digitalWrite(Co2, HIGH);
     digitalWrite(O2, LOW);
   }
   if (iniezione == '2'){
     digitalWrite(Co2, LOW);
     digitalWrite(O2, HIGH);
   }
   if (iniezione == '0'){
     digitalWrite(Co2, LOW);
     digitalWrite(O2, LOW);
   }
   while (Serial.available()){
   Serial.read();
   delay(1);
 }
}

inizio a pensare sul serio che sia un qualche problema di HW. Una cosa: una volta ho collegato il cavo USB ad Arduino mentre era collegato all'alimentazione (9V tramite il Jack) è possibile che si sia danneggiato qualcosa?

Proverò in questi giorni a montare il tutto su un nuovo Arduino Uno che ho e provo a vedere che succede.

Ti ringrazio ancora per la disponibilità.

Ti farò sapere lo sviluppo della vicenda. Buon Week end

Giacomo.

In effetti sembrerebbe un problema HW ... non vorrei fosse un problema del PC ... un po' antiquato ... :grin:

Buon fine settimana anche a te !

Guglielmo

Se ti può aiutare mi esce questa scritta quando si impianta il tutto

Dimensione del file binario dello sketch: 5.380 bytes (su un massimo di 258.048 bytes)
java.io.IOException: Input/output error in writeArray
	at gnu.io.RXTXPort.writeArray(Native Method)
	at gnu.io.RXTXPort$SerialOutputStream.write(RXTXPort.java:1124)
	at processing.app.Serial.write(Serial.java:517)
	at processing.app.Serial.write(Serial.java:540)
	at processing.app.SerialMonitor.send(SerialMonitor.java:200)
	at processing.app.SerialMonitor.access$100(SerialMonitor.java:32)
	at processing.app.SerialMonitor$3.actionPerformed(SerialMonitor.java:89)
	at javax.swing.JTextField.fireActionPerformed(JTextField.java:492)
	at javax.swing.JTextField.postActionEvent(JTextField.java:705)
	at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820)
	at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
	at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
	at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
	at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
	at java.awt.Component.processEvent(Component.java:6040)
	at java.awt.Container.processEvent(Container.java:2041)
	at java.awt.Component.dispatchEventImpl(Component.java:4630)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:704)
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:969)
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:841)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:668)
	at java.awt.Component.dispatchEventImpl(Component.java:4502)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Window.dispatchEventImpl(Window.java:2475)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

scusami ancora, ma ho fatto spendere un bel po al dipartimento pensando che potevo farcela, ma credo che sia più difficile di quanto pensassi

Stai usando l'ultima versione dell'IDE vero ? 1.0.5-r2 ???

Guglielmo

... mi sono permesso di aggiustartelo ... ottimizzandolo un po' ...

int pH1;
int pH2;
int DO;
int Co2 = 8;
int O2 = 12;
//
char iniezione;
//
void setup(){
   Serial.begin(57600);
   pinMode(Co2, OUTPUT);
   pinMode(O2, OUTPUT);
}
//
void loop(){
   pH1 = analogRead(A1);
   Serial.println(pH1);
   delay(50);
   Serial.flush();
   //
   pH2 = analogRead(A0);
   Serial.println(pH2);
   delay(50);
   Serial.flush();
   //
   DO = analogRead(A2);
   Serial.println(DO);
   delay(50);
   Serial.flush();
   //
   if (Serial.available() > 0){
      iniezione = Serial.read();
      switch (iniezione) {
      case '1':
         digitalWrite(Co2, HIGH);
         digitalWrite(O2, LOW);
         break;
      case '2':
         digitalWrite(Co2, LOW);
         digitalWrite(O2, HIGH);
         break;
      case '0':
         digitalWrite(Co2, LOW);
         digitalWrite(O2, LOW);
         break;
      default:
         break;
      }
      //
      while (Serial.available()){
         Serial.read();
         delay(1);
      }
   }
}

Guglielmo

P.S. : Ricordati sempre di usare da menu dell'IDE ... Tools -> Auto Format ... che ti sistema le indentature del codice :wink:

Credo proprio di si

l'ho scaricata dal sito di Arduino qualche mese fa.

GiacomoSam:
Credo proprio di si ...

... beh ... fai presto a verificarlo ... è scritto in testa all'IDE :wink:

Guglielmo

Ora sembra che funzioni perfettamente :open_mouth: almeno mettendo i dati direttamente dalla seriale :wink:
Sulla testa dell'IDE c'era scritto solo 1.0.5 e quindi ho cancellato tutto (anche Visual Basic però :astonished:) e rimesso tutto facendo attenzione che sia r2. Ho anche usato il switch/case che mi hai proposto. Sembra che vada alla grande. Ti farò sapere se va tutto perfettamente anche con VB.

Grazie mille del preziosissimo aiuto.

Giacomo.

Il problema è che su arduino UNO si sono dimenticati di mettere il controllo di flusso hardware, in arduino2009 non c'era questo problema perchè il segnale DSR è disponibile sul pin2 di X3, basta collegare questo pin ad un qualsiasi pin di meg328 così quando arduino è impegnato abilita l'ingresso DSR per comunicare al PC l'interruzione del flusso.

La cosa identica l'ho fatta quì: ARDUINO1
vedi lo schema in PACK LNCNC

E' comunque possibile variare il firmware su mega16u2 aggiungendo le funzioni per la linea DSR, non sò se è già disponibile in rete