Offline
Jr. Member
Karma: 1
Posts: 83
|
 |
« on: December 04, 2012, 05:02:41 am » |
ciao a tutti, vorrei sapere se c'è un modo per usare la funzione micros() di arduino programmato tramite processing. mi spiego meglio: devo misurare la curva di carica e scarica di un condensatore, dunque, siccome la funzione millis() non è abbastanza "risoluta" ho chiamato la funzione micros() per triggerare l'istante iniziale e tutti gli altri istanti.
ora vorrei riscrivere il codice per processing così da poter plottare a video il grafico, ma a quanto ho visto processing riconosce solo la funzione millis().
duqneu tornando alla domanda principale: c'è un modo per richiamare la funzione micros() di arduino tramite processing?
P.S. sto lavorando con Arduino UNO Rev3, Arduino IDE 101, Processing 2.05, windows7
|
|
|
|
« Last Edit: December 11, 2012, 01:03:01 pm by aureliusss »
|
Logged
|
|
|
|
|
Capo d'Orlando
Offline
God Member
Karma: 2
Posts: 652
|
 |
« Reply #1 on: December 04, 2012, 01:03:32 pm » |
Io non ho capito bene, hai un arduino che parla con processing tramite seriale e vuoi visualizzare il grafico in tempo reale?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 83
|
 |
« Reply #2 on: December 04, 2012, 01:07:02 pm » |
no, non ho la necessità di visualizzare il grafico il tempo reale, ma per prendere più punti di misura sulla caratteristica, utilizzo la funzione micros() di arduino. esiste un equivalente o un modo per farlo con processing?
|
|
|
|
|
Logged
|
|
|
|
|
Capo d'Orlando
Offline
God Member
Karma: 2
Posts: 652
|
 |
« Reply #3 on: December 04, 2012, 01:18:37 pm » |
Non puoi passare i valori che prendi da arduino con la funzione micros e passarli a processing allora? Non ti servi comunque dell'arduino per catturare i valori di Vc nel tempo?
|
|
|
|
|
Logged
|
|
|
|
|
BZ (I)
Offline
Brattain Member
Karma: 161
Posts: 15707
+39 349 2158303
|
 |
« Reply #4 on: December 04, 2012, 05:49:19 pm » |
Spiega meglio come stai trasferendo i dati dal Aruino al PC. Ciao Uwe
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 83
|
 |
« Reply #5 on: December 05, 2012, 05:02:20 am » |
questo il codice che ho scritto per arduino: #define RELAY_PIN 3 //digital pin to control the relay #define c_pin A1 //capacitor analog pin #define ps_pin A0 //power supply analog pin #define num_misure 65
// defines for setting and clearing register bits #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif
void setup() { // set prescale to 16 sbi(ADCSRA,ADPS2) ; cbi(ADCSRA,ADPS1) ; cbi(ADCSRA,ADPS0) ;
pinMode(RELAY_PIN, OUTPUT); Serial.begin(9600); // open serial Serial.println("Press the spacebar to start to measure"); }
void loop() { static int relayVal = 0; int cmd; float c_voltage, ps_voltage, current; static float res = 3.59; unsigned long int time1, time2, time0; unsigned long int PS_TIME[num_misure], C_TIME[num_misure]; float PS_VOLTAGE[num_misure], C_VOLTAGE[num_misure], CURRENT[num_misure]; int j = 0;
while(Serial.available() > 0) { cmd = Serial.read();
switch(cmd) { case ' ': { relayVal ^= 1; Serial.println("Relay on"); break; } default: { Serial.println("Press the spacebar to start to measure"); } }
if(relayVal) { do{ digitalWrite(RELAY_PIN, HIGH); delay(20); // relay transition time ---------- problema, ho impostato questo ritardo // per aspettare la commutazione del relay, ma questa non è tempocostante
time0 = micros(); // time the measure start do {
c_voltage = analogRead(c_pin); time1 = micros()-time0; //time c_voltage measurement ps_voltage = analogRead(ps_pin); time2 = micros() - time0; //time ps_voltage measurement
c_voltage = (c_voltage * 5) /1023; ps_voltage = (ps_voltage * 5) / 1023; current = ((ps_voltage - c_voltage)*1000)/res; // to obtain mA
//put all the measurements in their arrays PS_VOLTAGE[j] = ps_voltage; PS_TIME[j] = time2; C_VOLTAGE[j]= c_voltage; C_TIME[j] = time1; CURRENT[j] = current; j++; delayMicroseconds(1380); } while(current >0 && j < num_misure);
//capacitor discharge digitalWrite(RELAY_PIN, LOW); do { c_voltage = (analogRead(c_pin) >> 2); c_voltage = (c_voltage * 5) / 1023; } while(c_voltage > 0.001);
} while( j <= num_misure - 1 );
//stampa risultati Serial.println(" PS_VOLTAGE"); for ( j = 0; j < num_misure ; j++) { Serial.print(PS_VOLTAGE[j]); Serial.print(" "); Serial.println(PS_TIME[j]); } j=0; Serial.println("\n\n CURRENT"); for ( j = 0; j < num_misure ; j++) { Serial.println(CURRENT[j]); } Serial.println(" C_VOLTAGE"); for ( j = 0; j < num_misure ; j++) { Serial.print(C_VOLTAGE[j]); Serial.print(" "); Serial.println(C_TIME[j]); }
relayVal = 0; //reitialize relayVal
Serial.print("\n\n");
Serial.print("Do you want to repeat the measure?"); }
} }
diciamo che è stato il primo step, funziona così: attivo il relè premendo la spacebar, attivando il relè collego il generatore di tensione al condensatore che si carica, salvo i valori in vari array e poi li visualizzo sul monitor seriale. ora, dato che è abbastanza grezzo visualizzare i dati su seriale vorrei poter plottare il grafico a video usando processing. leggendo in giro ho scoperto firmata, quindi uploadando standard firmata su arduino, dovrei poter scrivere il codice corrispondente con processing per poi ottenere i grafici corrente-tensione, tensione-tempo. quindi esiste un modo per usare micros() con processing? spero di essermi spiegato
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 82
Posts: 8212
:(){:|:&};:
|
 |
« Reply #6 on: December 05, 2012, 05:37:35 am » |
quello che vuoi fare è fondamentalmente errato. Quello che andresti a misurare non è la scarica del condensatore ma il tempo di comunicazione della seriale. Mica crederai che la comunicazione è istantanea?! al contrario! con 9600 baud hai 960 caratteri al secondo, quindi poco più di 1ms per scrivere una lettera!
Quindi la soluzione è di inviare un comando ad arduino che effettua in modo completamente autonomo la misura e poi la ritorna a processing una volta conclusa.
Firmata, visto che usa la seriale per inviare il codice dal PC ad arduino istruzione per istruzione in "real time", è in realtà lentissimo proprio a causa di questa limitazione.
certo puoi dirmi che puoi aumentare il baudrate, ma se hai bisogno di tempi di risposta nell'ordine del microsecondo allora il fatto di leggere dei comandi da Seriale, interpretarli ed eseguirli è un peso assurdo in confronto ad eseguire dei comandi già compilati in codice nativo.
edit: BTW processing non possiede una funzione al di sotto dei millis, per il semplice fatto che molti (vecchi) timer di PC accessibili lato utente non scendono al di sotto dei 10 millisecondi: i tempi sono basati sull'RTC che non ha un clock molto elevato. Poi in realtà i PC moderno usano altre serie di timer "ad alta velocità" che permettono ri raggiungere la precisione del nanosecondo.
Passare da processing a java è semplice, e avari a diosposizione una serie molto più vasta di instruzioni.
|
|
|
|
« Last Edit: December 05, 2012, 05:43:45 am by lesto »
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 83
|
 |
« Reply #7 on: December 05, 2012, 05:54:41 am » |
dunque l'approccio che sto usando è sbagliato, perfetto!  ripartendo dall'inizio allora: -arduino prende le misure e le memorizza negli array; -arduino passa questi array a processing; -processing plotta gli array; ora, come eseguo il passaggio degli array da arduino a processing? edit: si tratterebbe forse di importare via seriale i dati che ho e questi dati li faccio ''analizzare'' da processing
|
|
|
|
« Last Edit: December 05, 2012, 06:01:32 am by aureliusss »
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 82
Posts: 8212
:(){:|:&};:
|
 |
« Reply #8 on: December 05, 2012, 06:05:49 am » |
con un loop scrivi i dati dell'array, e con un altro loop li leggi... esattamente come fai ora per un valore singolo.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 83
|
 |
« Reply #9 on: December 05, 2012, 12:37:30 pm » |
non ho capito cosa intendi: in processing dovrei usare un loop per leggere i dati che sono scritti su seriale e con un altro loop li metto in un altro array che analizzo per la visualizzazione?
|
|
|
|
|
Logged
|
|
|
|
|
Capo d'Orlando
Offline
God Member
Karma: 2
Posts: 652
|
 |
« Reply #10 on: December 05, 2012, 01:44:15 pm » |
Raccogli i dati relativi al condensatore dall'arduino e li memorizzi in un array o meglio ancora in una matrice(C[Vc][t] ad esempio) e una volta concluse le misure li mandi con un loop sulla seriale in tutta tranquillità e da processing leggi il valore sempre con un loop. Ovviamente dietro la parola 'loop' ci sono doversi significati, i dati li raccogli in maniera più o meno diversa a seconda del formato e del tipo..
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 83
|
 |
« Reply #11 on: December 06, 2012, 10:39:36 am » |
ho scritto questi due codici di prova, ma l'output che ricevo non lo capisco: codice arduino: int val;
void setup(){ Serial.begin(9600); }
void loop(){ val = analogRead(0);//collegato al pin centrale di un potenziometro Serial.print(val); Serial.print("\n"); delay(1000);
} codice processing: import processing.serial.*; String val; Serial commport;
void setup() { size(200, 200); commport = new Serial(this, "COM6", 9600); commport.write(65); }
void draw() { }
void serialEvent(Serial port) {
val = commport.readStringUntil('\n');
println("raw input:" + val); }
sulla ''console'' di processing questo è l'output che ricevo: ...raw input:null raw input:null raw input:null raw input:753 ... ricevo tanti null quante sono le cifre del numero edit: ho modificato il codice arduino richiamando la funzione Serial.available in questo modo: if (Serial.available > 0) { Serial.read(); val = analogRead(0); Serial.print(val); Serial.print("\n"); delay(1000);
} ma in compilazione mi da un errore che non avevo ancora visto : error: invalid use of member (did you forget the '&' ?)
|
|
|
|
« Last Edit: December 06, 2012, 10:49:03 am by aureliusss »
|
Logged
|
|
|
|
|
Capo d'Orlando
Offline
God Member
Karma: 2
Posts: 652
|
 |
« Reply #12 on: December 06, 2012, 11:08:38 am » |
L'errore probabilmente è dato dal fatto che manca "()" dopo available, essendo una funzione. Suppongo tu abbia messo quella conduzione per capire quando apri processing visto che mandi quel valore all'inizio..
Comunque questa cosa antipatica del null è capitata anche a me e non riuscendone a capire l'origine ho messo un filtro su processing del tipo if(val!= 'null') e via, tanto a te dopo qualche null ti arriva qualche valore atteso no?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 82
Posts: 8212
:(){:|:&};:
|
 |
« Reply #13 on: December 06, 2012, 03:34:33 pm » |
sciorty ha ragione lato arduino, e spero che tu ti renda conto che in quel caso arduino ti scrive un messaggio solo se prima legge un qualsiasi carattere sulla seriale
lato java il "null" è il valore che indica il vuoto, ovvero che un oggetto non è stato inizializzato.
questo vuol dire che il tuo serialEvent viene chiamato, ma tra i dati raccolti fino a quel momento non viene trovato uno \n, e infatti quando lo \n arriva processing stampa il valore.
esistono vari sistemi per aggirare la cosa.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 83
|
 |
« Reply #14 on: December 10, 2012, 06:29:58 am » |
ok, grazie a tutti, ora sulla seriale ho finalmente l'output giusto, nel senso che la condizione su null funziona. ora però mi sorge un altro problema: non riesco a convertire la stringa in numero. Ho provato a usare sia string.parseInt che Integers.valueOf(string).intValue() ma genera un eccezione
secondo voi mi conviene scompattare la stringa in array di caratteri e poi usare il parseInt o parseFloat?
|
|
|
|
|
Logged
|
|
|
|
|
|