Pages: [1] 2   Go Down
Author Topic: plot grafico tramite processing real time  (Read 1681 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,
ho già scritto un post (sezione hardware) su un primo lavoro di tesi che sto facendo: rilevare la caratteristica corrente tensione di un alimentatore.http://arduino.cc/forum/index.php/topic,126840.0.html

dopo aver implementato questo circuito su breadboard


con il codice corrispondente per rilevare tensioni e corrente

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


void setup()
{
  pinMode(RELAY_PIN, OUTPUT);
  Serial.begin(9600); // open serial
  Serial.println("Press the spacebar to toggle relay on/off");
}


void loop()
{
  static int relayVal = 0;
  int cmd;
  float c_voltage, ps_voltage, current;
  static float res = 5.2;
 
  while (Serial.available() > 0)
  {
    cmd = Serial.read();
     
    switch (cmd)
    {
    case ' ':
      {
        relayVal ^= 1; // xor current value with 1 (causes value to toggle)
        if (relayVal)
          Serial.println("Relay on");
       
        break;
      }
    default:
      {
        Serial.println("Press the spacebar to toggle relay on/off");
      }
    }
     
    if (relayVal)
    {
      digitalWrite(RELAY_PIN, HIGH);
      delay(20);           // relay transition time
      do
      {
        c_voltage = analogRead(c_pin);
        ps_voltage = (analogRead(ps_pin));
       
        c_voltage = c_voltage *5 /1023;
        ps_voltage = ps_voltage * 5 / 1023;
        current = (ps_voltage - c_voltage)/res;
       
        Serial.print(ps_voltage);
        Serial.print("  ");
        Serial.print(c_voltage);
        Serial.print("  ");
        Serial.print(current);
        Serial.print("\n");
      }
      while(current >0.000001);
     
      Serial.println("Please wait for the capacitor to discharge");
      digitalWrite(RELAY_PIN, LOW);
      do
      {
        c_voltage = analogRead(A1);
        c_voltage = c_voltage * 5 / 1023;
       
        Serial.println(c_voltage);
        delay(50);  // just a delay to not print all the values
       
      }
      while(c_voltage > 0.001);
     
      relayVal = 0;  // reinitialze the relayVal
      Serial.println("\nThe relay is off, press the spacebar");
      Serial.println("again if you want to repeat the measure\n");
    } 
     

    }
}


vorrei riuscire a plottare in real time i dati che ricevo su corrente e tensione tramite processing.

ho letto tutti i vari post qui sul forum che riguardano processing  e visto anche qualche tutorial, ma non ho trovato come fare a prendere le due serie di dati e plottarli in un semplice grafico tipo questo ottenuto con excel



grazie per l'aiuto
Logged

0
Online Online
Edison Member
*
Karma: 20
Posts: 2223
Have you mooed today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao,
prova a dare un'occhiata a questo progetto:
http://code.google.com/p/arduinoscope/
dovresti trovare tutti gli strumenti che ti servono per realizzare il tuo progetto  smiley-razz
Logged

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao

questo in c#, sorgenti su GitHub:
http://www.lucadentella.it/2011/11/08/analogdemo-plot-di-dati-e-invio-a-pachube-in-c/

bye
Logged

lucadentella.it

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10101
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

leggi i dati dalla seriale e li metti in un ArrayList. Questo arrayList va sempre usato in un blocco
syncronize(nomeArrayList){
   //ora puoi usare in sicurezza l'arrayList
}

Questo è necessario perchè l'acquisizione su seriale e il disegno sono su due thread diversi; usare una line per ogni valore seriale manderebbe in palla la grafica, che non riuscirebbe a disegnare abbastanza in fretta, mentre usare un array non sincronizzato può creare dei casini si concorrenza esagerati

ogni draw() scorri gli ultimi A valori dell'arraylist (dove X è la scala lungo l'asse X) e poi disegni delle righe col comando
line(X1, Y1, X2, Y2);

dove Y1 è il valore attuale, Y2 il prossimo valore, X1 e X2 un valore che si incrementa di Tot, dove tot è la larghezza della finestra diviso A

se vuoi disegnare più righe, basta ripetere questa parte del codice, sommando una costante ad Y per evitare che i dati si sovrappongano (se non vuoi la sovrapposizione)  facendo attenzione anche a non uscire dallo schermo!

sempre per non uscire dallo schermo, probabilmente dovrai usare uno zoom anche sull'asse Y, ovvero tutti i valori di Y moltiplicarli per B, esattamente come quelli di X li ai divisi per A
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

scusate ragazzi, il professore mi ha chiesto di mofificare lo sketch che ho sopra scritto, per avere più misure e visualizzare anche il tempo a cui vengono effettuate le misure, impostando come t=0 l'istante in cui inizio l'acquisizione dei dati?
coem faccio a impostare un cronometro? e che ''risoluzione'' può avere questo cronometro secondo voi?
Logged

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

guarda la funzione millis() di Arduino:
http://www.arduino.cc/en/Reference/Millis
Logged

lucadentella.it

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

secondo voi come potrei aumentare il numero di misure effettuate? esiste un modo per aumentare la frequenza dell'analogRead?
Logged

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10101
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sì, diminuendo il prescaler. Però diminuisce anche la precisione della lettura, se non erro a 16 (il prescaler di defautl mi pare sia sui 128) ha una precisione a 8bit se non meno (cioè, i valori "reali" vanno da 0 a 255, il resto è rumore, anzichè i classici 10bit da 0 a 1023)
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

http://arduino.cc/forum/index.php/topic,6549.0.html
mi basta mettere il codice che trovo in questo post per aumentare la velocità dell'adc quindi?
Logged

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10101
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

esatto
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

ma con il codice che ho scritto, anzi esattamente questo segmento:
Code:
c_voltage = analogRead(c_pin);
          time1 = micros()-time0; //time c_voltage measurement
          ps_voltage = analogRead(ps_pin);
          time2 = micros() - time0; //time ps_voltage measurement

secondo voi time1 e time2 che poi andrò a stampare, sono esattamente il tempo in cui arduino prende la misura o sono posticipati?
Logged

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10101
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

posticipati, direi di circa 204microsecondi (200 microsecondi di lettura + 4 microsecondi per la nuova richiesta di micros)

essendo un valore fisso, di solito si può ignorare senza conseguenze, semplicemente il grafico è sballato di 200 micros sull'asse del tempo (se prendi come riferimento l'inizio lettura, se prendi la fine lettura sei quasi perfetto)
« Last Edit: October 29, 2012, 10:12:47 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

possibile che siano addirittura posticipati di 204 microsecondi? forse ho sbaglaito a non postarvi tutto il codice, perchè da quello che vedo io in output ad esempio, la prima misura sul c_voltage avviene al tempo di 20us
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
// 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("How many measure do you want to take?");
}


void loop()
{
 
  int num_misure;
  float c_voltage, ps_voltage, current;
  static float res = 3.59;
  unsigned long time1, time2, time0;
  int i ;
 
 
  if(Serial.available() > 0)
  {
     num_misure = Serial.parseInt(); // Arduino stream function which receive a string on the serial port and then changes it int an integer
     if(num_misure > 0)
     {
     
      for(i = 1 ; i <= num_misure; i++)
     {
      Serial.print("Misura n.");
      Serial.println(i);
     
      digitalWrite(RELAY_PIN, HIGH);
      delay(20);            // relay transition time::::::: problema, ho impostato questo ritardo per aspettare la commutazione del ralay, ma questo non ha un tempo fisso
      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)/res;
       
        Serial.println(ps_voltage);
        Serial.println(time1);
        Serial.println(c_voltage);
        Serial.println(time2);
        Serial.println(current);
        Serial.print('\n');
      }
      while(current >0.000001);
     
      Serial.println("Please wait for the capacitor to discharge");
      digitalWrite(RELAY_PIN, LOW);
      do
      {
        c_voltage = analogRead(A1);
        c_voltage = c_voltage * 5 / 1023;
       
        Serial.println(c_voltage);
        delay(50);  // just a delay to not print all the values
       
      }
      while(c_voltage > 0.001);
      Serial.print("\n\n");
       
     
     
    }   
  }
  }}
     
l'ho modificato rispetto a quello postato prima settando il prescaler a 16 come mi avevi descritto anche tu

l'output che ho è questo:(lo posto come codice èper renderlo leggibile)
Code:
How many measure do you want to take?
Misura n.1
2.65
32
1.01
48
0.46

2.74
1592
1.03
1612
0.48

2.83
3332
1.11
3352
0.48

3.83
25316
2.09
25336
0.49

5.00
59636
3.58
59656
0.39

5.00
93956
4.86
93976
0.04

5.00
128280
5.00
128296
0.00

Please wait for the capacitor to discharge
5.00
1.64
0.47
0.13
0.01
0.00
Logged

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

inoltre vorrei eliminare quella serie di Serial.print() per aumentare i ''punti'' di misura
avrei pensato alla costruzione di tre array PS_VOLTAGE[], C_VOLTAGE, CURRENT[], in cui storare i dati, e solo in una seconda parte stamparli, magari direttamente su excel o su matlab se riesco a trovare il modo di farlo, in maniera tale da poterli manipolare per grafici direttamente.

secondo voi riesco ad aumentare il  numero di misure che riesco a  prendere se li metto negli array invece che stamparli subito in output?
Logged

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10101
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ah ok, se cambi il prescaler cambia la velocità dell'analogRead, e quindi è giusto che il tempo di "posticipazione" diminuisce.

per rendere il codice più veloce usa la write() invece che la pritn(): la print converte in caratteri ascii, ovvero 1 byte per ogni cifra; con la write scrivi in maniera binaria, quindi scrivi tanti byte quanto la dimensione della variabile.

Cole prescaler a 16 hai una precisione a 8 byte, quindi puoi prendere sono gli 8 byte più significativi (sui 10 che ti restituisce l'analogRead) e quindi aresti un byte per lettura.

Però devi inventarti un sistema per sincronizzare i dati.

a casa ho del codice sia per inviare che per ricevere, ma devo upparlo sul repo. Se hai facebook, ho postato del codice che fa 3 letture analogice (a scelta a 10 o 8 bit di precisione), nel caso di 8 bit le invio dirette al PC, nel caso di 10 bit, faccio la lettura dei 3 dati in un array, poi anzichè inviare 6byte (2 byte per letura, un int) unisco i dati per fare in modo di usare solo 4 byte (4*8=32bit, avanzano 2 bit a scrittura, in teoria facendo un array di 30 elementi guadagni un byte "a gratis" sfruttando anche quei due bit)

il trucco si sincronizzazione è che l'arduino andava in loop finchè processing,. quando pronto a ricevere, inviava un comando.

uesto perchè se inizi a legegre il flusso seriale in un momento a caso non sai il byte che stai leggendo a che misurazione si riferisce, e nel caso di invio di più di un byte a varibaile (da int in su) non sai nemmeno se il byte che hai letto è la parte bassa o la parte alta.
Logged

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

Pages: [1] 2   Go Up
Jump to: