Pages: [1] 2   Go Down
Author Topic: funzione micros() con processing -- comunicazione seriale  (Read 1780 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
God Member
*****
Karma: 2
Posts: 723
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Io non ho capito bene, hai un arduino che parla con processing tramite seriale e vuoi visualizzare il grafico in tempo reale?
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
God Member
*****
Karma: 2
Posts: 723
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 236
Posts: 20273
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Spiega meglio come stai trasferendo i dati dal Aruino al PC.
Ciao Uwe
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

questo il codice che ho scritto per arduino:
Code:
#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 Offline
Shannon Member
****
Karma: 117
Posts: 10112
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dunque l'approccio che sto usando è sbagliato, perfetto!  smiley-cry
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 Offline
Shannon Member
****
Karma: 117
Posts: 10112
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

con un loop scrivi i dati dell'array, e con un altro loop li leggi... esattamente come fai ora per un valore singolo.
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
God Member
*****
Karma: 2
Posts: 723
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ho scritto questi due codici di prova, ma l'output che ricevo non lo capisco:
codice arduino:
Code:
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:
Code:
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:
Code:
...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:
Code:
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 :
Code:
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 Offline
God Member
*****
Karma: 2
Posts: 723
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Shannon Member
****
Karma: 117
Posts: 10112
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1] 2   Go Up
Jump to: