Go Down

Topic: Arduino comandato da Processing via web tramite pc o smartphone Android (Read 30928 times) previous topic - next topic

camperos

#45
Dec 05, 2013, 01:33 am Last Edit: Dec 05, 2013, 10:16 am by camperos Reason: 1
per ora il tutto  sembra andare a buon fine, mettendo  i "float" a   pulsanti spie ecc   i valori visualizzati sembrano ok,
domani sera provo meglio
:)

rimetto passo passo come attivare android
------------
Code: [Select]
caricare sketch Processing su Android

dicembre 2013
spero di non avere saltato qualche passo
provato su un pc portatile [b]vergine[/b]

preparazione per  tablet o cell:
nel tablet si deve spuntare "debug USB", ma l'opzione non è visibile , qui sotto istruzioni per il 4.2 (per altri android cercare in internet)
http://www.thesmarthacks.com/2013/04/enabling-usb-debugging-mode-on-android.html

preparazione PC:
Processing 2.0.3 scaricabile dal sito (altri non so, pare che la 2.1 abbia problemi)

click ,aprire processing
click, tendina con "java"
click, add mode
click, install "android mode"
attendere il download
click, chiudere tutti i processing

click, riaprire processing
click, tendina con java
click, android
errore manca "SDK"
click, NO
siete reindirizzati sul sito download (nel caso non venite indirizzati, https://developer.android.com/sdk/index.html)

click, "use an existing ide"
click, download SDK for Windows (sono circa84 mega)
estrarre il file compresso

installare e segnarsi dove viene installata "SDK manager" = (punto importante!!)

si apre da solo "SDK manager"
click,install x (10?) package (gia spuntati da loro)
click,accept license
30 minuti il download

scaricare ancora:
spuntare "android 2.3.3 (API 10) (4 file, non servono tutti...ma alcuni indispensabili)
click,accept license
20 minuti il download

click, close
click,chiudere "android SDK manager"
click, chiudere tutti i processing se aperti

click, aprire processing
errore manca SDK
click, si
si apre esplora file (chiede dove è la cartella SDK)
cercare cartella SDK (segnata precedentemente) (android SDK contenente dei file e cartelle)
OK
click, chiudere tutti i processing se aperti


click,aprire processing
collegare il tablet o cell con cavetto USB

provare se il tutto è andato a buon fine

ad esempio:

click,file
click,esempi
click,basic
click,array
ci vogliono circa 50 secondi

se dovete comunicare con arduino ricordarsi di spuntare i relativi permessi
Processing --> android --> sketch permission -->
spunta "internet" se si ha ethernet shield
due spunte "bluetooth" per bluetooth
ecc..

camperos

a video pc ,il tuo file lo vedevo così come negli android qui sotto.
ho rapportato pari pari il tutto in modo che qualsiasi (o quasi)  display lo veda  nella stessa dimensione.,
solo nella parte bassa dei video, lo spazio vuoto puo aumentare o diminuire.

ora servono le dimensioni  e posizioni pulsanti piu idonei per questi piccoli schermi , deci di tu

i 2 android.. se clicco il pulsante di un  android, dopo pochi secondi si illumina il pulsante anche sull'altro android  :)
ciao


ZioWally

Hai fatto un bellissimo lavoro!
Il piccolo tutorial su come installare per android è molto prezioso e lo sto seguendo passo-passo anch'io per vedere se è chiaro e completo.

Bellissima anche l'interfaccia scalabile, per la grandezza dei pulsanti possiamo adottare un sistema simile a quello che hai gia adottato e forse ci avevi già pensato anche tu:
il comando image può avere 4 parametri:
image (nome immagine, coordinata X, coordinata Y, Larghezza X, Altezza Y)
quindi il nostro pulsante che ha dimensioni 70x70 pixel se impostiamo:
image (pulsante, x, y, 35, 35)
verrà disegnato grande la metà.
Con lo stesso sistema possiamo andare a rivedere ogni immagine, per questo che tutte le immagini le ho volute separate e non in uno sfondo che già le contenesse tutte, peserà di più ma è più flessibile.
Se non ci hai già pensato tu, ci sarà da ridimensionare anche il cerchietto rosso che disegna per evidenziare quando sei nell'area clikkabile del pulsante, ma non la vedo come una cosa critica.

Il protocollo UDP mi era piaciuto anche perchè agilmente mi permetteva di far rispondere ad Arduino verso qualsiasi fonte lo avesse interrogato. Per cui ogni volta che un processing interroga arduino, lui risponde esattamente all'indirizzo da cui ha ricevuto il comando, fregandosene da dove viene il comando o in quanti sono a richiederlo.
Ricorda che tutto nasce per darlo in mano a persone (spero poche) che potrebbero accendere o spegnere relay in qualsiasi momento e senza che una sappia delle manovre dell'altra, e importante avere quindi il monitoraggio costante dell'intero pannello in tempo reale.

Grazie ancora, mi sei di grandissimo aiuto! :smiley-mr-green:


camperos

#48
Dec 05, 2013, 07:46 pm Last Edit: Dec 05, 2013, 07:49 pm by camperos Reason: 1
mi hai dato un sistema gia pronto per gli sviluppi futuri del mio progetto,
prima non capivo nulla del tuo sketch, ma a continuare a leggerlo inizia a diventare chiaro   :)

per le dimensioni disegno, solo cambiando altezza larghezza come dici tu non va bene,
30 pixels in un cell è microscopico, per altri il disegno completo può andare fuori schermo,
il sistema che si deve adottare  è simile a questo, che poi è quello che ho fatto.

il disegno deve pressoche occupare il tuo monitor (quello con cui stai lavorando) in orizzontale, cioè meglio lasciare un piccolo spazio sotto, per monitor o display molto larghi e bassi.

i disegni che farai sul "tuo monitor" saranno uguali se visti su  altri monitor se fai così:

larghezza "tuo monitor" diviso n pixels
il tuo monitor è largo 1920 pixels,
fai una ellipse di 100,100

Code: [Select]
ellipse (coordinata X,  coordinata Y,  100 ,  100); //(coordinata X, coordinata Y, Larghezza X, Altezza Y)

1920/100 = 19.2

Code: [Select]
ellipse (coordinata X,  coordinata Y,  width/19.2 ,  width/19.2); //(coordinata X, coordinata Y, Larghezza X, Altezza Y)
notare che non ho usato "height/x"  l'ellipse su un altro monitor risulterebbe ovalizzata.
comunque in questo modo risulta in scala su altri monitor
lo stesso vale per coordinata X,  coordinata Y //width/x, width/x,

per immagini scaricate, ad esempio 70*70

image (nome immagine, coordinata X, coordinata Y, Larghezza X, Altezza Y)
1- anzichè dare una dimensione precisa fare:

Code: [Select]
anzichè //image (pulsante, x, y, 35, 35)

1920/70 = 27.42
Code: [Select]
pulsante.resize (width 27.42  , width/ 27.42); // altezza,larghezza. (il pulsante si adatta al monitor)
pulsante.loadPixels(); questo serve perchè se no da errore su android




camperos

comunque se non vuoi rifare il tutto puoi usare nel "draw(), subito sotto
scale (0.5);

scala tutto ma non il mouse, che deve essere fatto a parte

ZioWally

non si finisce mai di imparare :D
Mi metterò a provare a modificare secondo le tue indicazioni, nella mia testa sembrava più semplice del tipo,
so quanto è grande il display, riscalo le coordinate in funzione di questo e nello stesso modo anche i pulsanti in modo tale che la proporzione tra i pixel del display e quelli del pulsante non cambi. Non avendo ancora fatto delle prove mi sarei sicuramente imbattuto negli errori che tu prontamente mi hai permesso di evitare.

Non so che sistema ti ho fatto trovare pronto, ma sono felice di esserti stato utile. Intanto sto ancora scaricando secondo la tua procedura per android e per il momento è tutto preciso.
Mi piacerebbe avere una copia del tuo sketch con le modifiche per il resize, significherebbe un bel po' di lavoro fatto per poi completarlo con tutti i particolari e i dettagli del caso. Lascio a te però decidere quando sarà più opportuno condividerlo.

camperos

per l'attivazione di android incrociamo le dita  ]:D

la parte ethernet sono azero,
se tutto procede bene si potrebbe  provare in futuro  , non so come,  tu accendi un led a me, io accendo un led a te

ZioWally

Lo strumento per accendermi un led già ce l'hai e lo stai anche adattando ad android.
Se crei un tuo sito internet utilizzando quello che c'è di gratuito tipo dyndns.org oppure no-ip.com e lo interfacci ad arduino+processing come già abbiamo fatto, a me basta conoscere l'indirizzo a cui puntare e il comando giusto.... ed io nel mio scuro e umido ufficio ti posso spegnere la tua tv con la finale dei mondiali di calcio che ti stai guardando dal tuo camper in chissà quale pineta di chissà quale riviera ]:) INVIDIOSO!...no, no semplice sfogo... :D

Se ti serve capire qualcosa in più di come funzionano questi servizi per ospitare siti gratuiti si fa presto a porre rimedio

ZioWally

ho finito di installare android for processing, le tue istruzioni sono perfette, ho provato un esempio (array) e funziona.
non ho resistito ed ho caricato il  mio programma, è andata male perchè mi dice che la dimensione dello sfondo e del display devono essere identiche, adesso capisco perfettamente la tua precisione nel gestire questa faccenda.

camperos



su "draw" al posto di sfondo metti
Code: [Select]
background (0);
dovrebbe partire  ;)

camperos

Code: [Select]
void GestioneSpia220V()
  {
    int Stato220 = int (reply1 [9]); // trasforma la stringa in int
    if (Stato220 == 1)
      {
        image(Spia220_ON,width/3.316, width/384);
      }
    else
      {
        if (millis() - Timer220 < Temp220_Blink) image(Spia220_OFF1, width/3.316, width/384); // spia led accesa per il tempo stabilito
        if (millis() - Timer220 > Temp220_Blink*2) Timer220 = millis();
      }
   
  }


Code: [Select]
/*
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CLASSE Boton(coordinataX, coordinataY, Etichetta)

questa classe permette di definire i vari oggetti Boton, che hanno bisogno dei seguenti campi:
coordinataX = intero, posizione X del pulsante
coordinataY = intero, posizione Y del pulsante
Etichetta = stringa, testo affiancato al pulsante

i metodi della Classe Boton sono i seguenti:

.display() -> attiva la rappresentazione grafica del Pulsante (costituita da due immagini, una acceso, una spento)
.update() [true/false] -> serve a definire lo stato del pulsante, se "true" il pulsante sarà rappresentato attivo (quando richiamato .update)
                          se "false" il pulsante sarà rappresentato spento (quando richiamato il metodo .update)
                         
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
*/


class Boton{
  PImage imagePulsOn;  //definizione dell'immagine del pulsante on, nel programma sarà richiamata led1On
  PImage imagePulsOff; //definizione dell'immagine del pulsante on, nel programma sarà richiamata led1Off
  //dichiarazioni delle variabili funzionali all'esecuzione della classe
  float x;
  float y;
  boolean active = false;
  String BotonEtichetta;
  String ComandoEtichetta;
  int Verso;

  //costruttore
  Boton(float tempX, float tempY, String Etichetta, String Comando)
  { //la Classe Boton necessita di tre campi che devono essere definiti quando si istanzia un nuovo oggetto
                                           //la posizione X, Y ed una stringa che definisce l'etichetta
    x = tempX;  //il campo tempX viene passato alla variabile globale della Classe X
    y = tempY;  //il campo tempY viene passato alla variabile globale della Classe Y
   

    BotonEtichetta = Etichetta; //il campo Etichetta viene passato alla variabile globale della Classe BotonEtichetta
    ComandoEtichetta = Comando; // stessa cosa per il comando da inviare ad arduino
   
    imagePulsOn = loadImage("PulsanteOn.png");    //vengono caricate le immagini .png rappresentative del pulsante acceso e spento
    imagePulsOff = loadImage("PulsanteOff.png");
   
     imagePulsOn.resize (width/27,width/27);
     imagePulsOn.loadPixels();
   
      imagePulsOff.resize (width/27,width/27);
     imagePulsOff.loadPixels();
   
    textSize(width/96); //viene definita dimensione del carattere
    //textAlign(LEFT); //viene definito l'allineamento del testo, a sinistra
                     //questi parametri servono per la rappresentazione dell'etichetta
  }

//METODO update() ---------------------------
  void update(boolean z){ //il metodo si aspetta che sia passato un parametro true/false
    active = z; //il valore del parametro è trasferito alla variabile globale "active", della Classe
  }
//-------------------------------------------


//METODO display() --------------------------
  void display(int Align)
  {
    Verso = Align;
    fill(235, 250, 125); // colore giallo
    if (Verso == 1) // prima serie di pulsanti a Sx
      {
        if (active){      // a seconda del valore della variabile "active" il metodo display() mostra un'immagine diversa del pulsante     
          image(imagePulsOn, x, y);  //immagine del pulsante acceso, se active == true
          //image(TargaInt_ON, x+75, y+30);
        }
        else{                       
          image(imagePulsOff, x, y);  //immagine del pulsante spento, se active == false
          //image(TargaInt_OFF, x+75, y+30);
        }
      textAlign(LEFT);
      text(BotonEtichetta, x+width/21,y+width/35);
       
      strokeWeight(width/960);  //spessore del bordo
      if (Evidenzia(x+width/160, y+width/160, width/48 , width/48 ))
        {  //la funzione Evidenzia restituisce TRUE se il mouse è sopra il rettangolo che rappresenta l'interruttore, altrimenti
        stroke(250, 0, 0); //definizione di una linea di colore rosso
        noFill();
        ellipse(x+width/55, y+width/55, width/38, width/38);  // prima circonferenza MODIFICA PER MIO PRIMO BOTTONE questa tecnica serve ad evideziare il pulsante
        }
      else 
        {
        noStroke(); //nessuna linea
        noFill(); //nessun riempimento
        ellipse(x+width/55, y+width/55, width/38, width/38);  // prima circonferenza MODIFICA PER MIO PRIMO BOTTONE questa tecnica serve ad evideziare il pulsante
        }
      //cambio dello stato del pulsante se tasto mouse premuto
      if ((Evidenzia(x+width/160, y+width/160, width/48, width/48)) && mousePressed)  //se contemporaneamente il mouse è sopra l'area del pulsante ed il tasto sinistro è premuto
        {        //viene cambiato il valore di button in 0 se era 1, oppure in 1 se precedentemente era 0
          delay(Debounce);                                 // questo ciclo di ritardo funziona da debounce del tasto del mouse
          udp.send(ComandoEtichetta, ip, Port_Ard );       // comando che invia il messaggio ad arduino con le informazioni aggiornate
          println(ComandoEtichetta);
         
        }
     }
     
       if (Verso == 2) // prima serie di pulsanti a Sx
      {
        if (active){      // a seconda del valore della variabile "active" il metodo display() mostra un'immagine diversa del pulsante     
          image(imagePulsOn, x, y);  //immagine del pulsante acceso, se active == true
          //image(TargaInt_ON, x-185, y+30);
        }
        else{                       
          image(imagePulsOff, x, y);  //immagine del pulsante spento, se active == false
          //image(TargaInt_OFF, x-185, y+30);
        }
      textAlign(RIGHT);
      text(BotonEtichetta, x-width/36, y+width/36);
 
      strokeWeight(width/960);  //spessore del bordo
      if (Evidenzia(x+width/160, y+width/160, width/48, width/48))
        {  //la funzione Evidenzia restituisce TRUE se il mouse è sopra il rettangolo che rappresenta l'interruttore, altrimenti
        stroke(250, 0, 0); //definizione di una linea di colore rosso
        noFill();
        ellipse(x+width/55, y+width/55, width/38, width/38);  // prima circonferenza MODIFICA PER MIO PRIMO BOTTONE questa tecnica serve ad evideziare il pulsante
        }
      else 
        {
        noStroke(); //nessuna linea
        noFill(); //nessun riempimento
        ellipse(x+width/55, y+width/55, width/38, width/38);  // prima circonferenza MODIFICA PER MIO PRIMO BOTTONE questa tecnica serve ad evideziare il pulsante
        }
      //cambio dello stato del pulsante se tasto mouse premuto
      if ((Evidenzia(x+width/160, y+width/160, width/48, width/48)) && mousePressed)  //se contemporaneamente il mouse è sopra l'area del pulsante ed il tasto sinistro è premuto
        {        //viene cambiato il valore di button in 0 se era 1, oppure in 1 se precedentemente era 0
          delay(Debounce);                           //questo ciclo di ritardo funziona da debounce del tasto del mouse
          udp.send(ComandoEtichetta, ip, Port_Ard ); // the message to send  verificato che arduino lo riceve
          println(ComandoEtichetta);
         
        }
     }

  }
//-----------------------------------------

  boolean Evidenzia(float x, float y, float w, float h)   //funzione Evidenzia, vengono passati i parametri di posizione X e Y, e di larghezza W e altezza H del pulsante
  {
    if (mouseX >= x && mouseX <= x+w &&  mouseY >= y && mouseY <= y+h)
    {
      return true;
    }
    else
    {
      return false;
    }
  }

} // fine class boton

camperos

Code: [Select]
void setup()
{
  smooth(8); // massimo livello di antialiasing (0-2-4-8)
 
  Etichette  = loadStrings("Etichette.txt");
  Link       = loadStrings("Link.txt");
 
  ip         = Link[0];        // indirizzo URL, prima riga del file link.txt
  Port_Proc  = int (Link[1]);  // porta in ascolto, seconda riga del file link.txt
  Port_Ard   = int (Link[2]);  // porta di destinazione verso arduino, terza riga del file link.txt
  Intervallo = int (Link[3]);  // tempo in millis tra una richiesta dati e l'altra
 
  Timer220 = TimerTemp = millis();    // prende il primo valore da cui poi incrementa per il controllo
     
  //settaggi per UDP
  udp = new UDP( this, Port_Proc ); // crea connessione su porta 6100
  udp.log( true );             // stampa l'attività di connessione
  udp.listen( true );          // si mette in ascolto e attende il messaggio in arrivo
  udp.send("P99", ip, Port_Ard ); // invia comando per avere la prima risposta
 
  size(displayWidth,displayHeight);  //dimensione dell'area grafica del programma
  orientation (LANDSCAPE);
 
  fill(0);
  Sfondo       = loadImage ("acciaio_1024_768.png");
  LedSpia_ON   = loadImage ("Led_spia_50_ON.png");
  LedSpia_OFF  = loadImage ("Led_spia_50_OFF.png");
  Vite         = loadImage ("VITE_30.png");
  Spia220_ON   = loadImage ("Led_spia_220_ON.png");
  Spia220_OFF  = loadImage ("Led_spia_220_OFF.png");
  Spia220_OFF1 = loadImage ("Led_spia_220_OFF1.png");
 
  textAlign(CENTER); //viene definito l'allineamen,minimo scala, max scalato del testo, a sinistra
  PFont mono = loadFont("ForgottenFuturist-Bold-42.vlw");
  textFont(mono,width/64);
 
   Volt1 = new Voltmetro(width/7.1 , width/64, Etichette[16]); //istanza dell'oggetto e sua costruzione  x,x,testo,tensione nominale
    Volt2 = new Voltmetro(width/3.178, width/64, Etichette[17]); //istanza dell'oggetto e sua costruzione
 
    Termometro1 = new Termometro (width/4.517 , width/42 , Etichette[18]); // x,y,testo
    Termometro2 = new Termometro (width/3.735 , width/42 , Etichette[19]);
 
  Pulsante0 = new Boton( width/384  , width/38.4 ,  Etichette[0], "P00"); // riga dei pulsanti di sinistra, questo è quello alto, Etichette[0] è la prima riga del file etichette.txt
  Pulsante1 = new Boton(width/384, width/14.22, Etichette[1], "P01"); 
  Pulsante2 = new Boton(width/384, width/8.73, Etichette[2], "P02"); 
  Pulsante3 = new Boton(width/384, width/6.3, Etichette[3], "P03");
  Pulsante4 = new Boton(width/384, width/4.92, Etichette[4], "P04");
  Pulsante5 = new Boton(width/384, width/4.042, Etichette[5], "P05");
  Pulsante6 = new Boton(width/384, width/3.43, Etichette[6], "P06");
  Pulsante7 = new Boton(width/384, width/2.977, Etichette[7], "P07");
 
  Pulsante8  = new Boton(width/2.02 ,  width/38.4 , Etichette[8],  "P08");  // riga dei pulsanti di destra, questo è quello alto
  Pulsante9  = new Boton(width/2.02 , width/14.22, Etichette[9],  "P09"); 
  Pulsante10 = new Boton(width/2.02 , width/8.73, Etichette[10], "P10"); 
  Pulsante11 = new Boton(width/2.02 , width/6.3, Etichette[11], "P11");
  Pulsante12 = new Boton(width/2.02 , width/4.92, Etichette[12], "P12");
  Pulsante13 = new Boton(width/2.02 , width/4.042, Etichette[13], "P13");
  Pulsante14 = new Boton(width/2.02 , width/3.43, Etichette[14], "P14");
  Pulsante15 = new Boton(width/2.02 , width/2.977, Etichette[15], "P15");
 
  Spia0 = new Spia(width/24,  width/24); // x,y
  Spia1 = new Spia(width/24, width/11.64);
  Spia2 = new Spia(width/24, width/7.68);
  Spia3 = new Spia(width/24, width/5.73);
  Spia4 = new Spia(width/24, width/4.57);
  Spia5 = new Spia(width/24, width/3.8);
  Spia6 = new Spia(width/24, width/3.254);
  Spia7 = new Spia(width/24, width/2.8444);
 
  Spia8  = new Spia(width/2.51 , width/24);
  Spia9  = new Spia(width/2.51, width/11.64);
  Spia10 = new Spia(width/2.51, width/7.68);
  Spia11 = new Spia(width/2.51, width/5.73);
  Spia12 = new Spia(width/2.51, width/4.57);
  Spia13 = new Spia(width/2.51, width/3.8);
  Spia14 = new Spia(width/2.51, width/3.254);
  Spia15 = new Spia(width/2.51, width/2.8444);
   
  Sfondo.resize (width,height);
  Sfondo.loadPixels();
 
  LedSpia_ON.resize (width/38,width/38);
  LedSpia_ON.loadPixels();
 
  LedSpia_OFF.resize (width/38,width/38);
  LedSpia_OFF.loadPixels();
 
  Vite.resize (width/38,width/38);
  Vite.loadPixels();
 
  Spia220_ON.resize (width/38,width/38);
  Spia220_ON.loadPixels();
 
  Spia220_OFF.resize (width/38,width/38);
  Spia220_OFF.loadPixels();
 
  Spia220_OFF1.resize (width/38,width/38);
  Spia220_OFF1.loadPixels();

}


Code: [Select]
// ATTENZIONE in mancanza dei dati da arduino, le Spie non vengono visualizzate sul display, nè accese nè spente

class Spia{
 
  PImage TargaInt_ON;
  PImage TargaInt_OFF;
 
  //dichiarazioni delle variabili funzionali all'esecuzione della classe
  float X;
  float Y;
  boolean active = false;
 
 
  //costruttore
  Spia(float tempX, float tempY)
  {                                           
    X = tempX;
    Y = tempY;
    TargaInt_ON =  loadImage ("led_rett_on_180_35.png");
    TargaInt_OFF = loadImage ("led_rett_off_180_35.png");
 
  TargaInt_ON.resize (width/11,width/55);
  TargaInt_ON.loadPixels();

  TargaInt_OFF.resize (width/11,width/55);
  TargaInt_OFF.loadPixels();
}

//METODO update() ---------------------------
  void update(boolean z)
  { //il metodo si aspetta che sia passato un parametro true/false
    active = z; //il valore del parametro è trasferito alla variabile globale "active", della Classe
  }
//-------------------------------------------


//METODO display() --------------------------
  void display()
  {
    if (active) // prima serie di pulsanti a Sx
      { 
       image(TargaInt_ON, X, Y);
      }
    else
      {
       image(TargaInt_OFF, X, Y);
      }
  }
     
} // fine class spia

camperos

Code: [Select]
class Termometro{
 
 //dichiarazioni delle variabili funzionali all'esecuzione della classe
 PImage Termometro1;
 PImage Targa1;
 
 float X;
 float Y;

 float val;                  //definizione della variabile che definisce la rotazione e che varierà tra 0 e 1024
 //float valm;
 String TermometroLable;
 float Altezza1 = -width/77;
 
 //costruttore  
 Termometro(float tempX, float tempY, String lable){ //la Classe Termometro necessita di tre campi che devono essere definiti quando si istanzia un nuovo oggetto
                                             //la posizione X, Y ed una stringa che definisce l'etichetta
   X = tempX; //il campo tempX viene passato alla variabile globale della Classe X
   Y = tempY; //il campo tempY viene passato alla variabile globale della Classe Y
   
   TermometroLable = lable; //il campo lable viene passato alla variabile globale della Classe LedLable
   
   Termometro1 = loadImage ("termometro_35_300.png");
   Targa1      = loadImage ("targa_60_30.png");
   
      Termometro1.resize (width/22,width/6);
 Termometro1.loadPixels();
   
     Targa1.resize (width/32,width/64);
 Targa1.loadPixels();
   
   textAlign(CENTER); //viene definito l'allineamento del testo, a sinistra
                    //questi parametri servono per la rappresentazione dell'etichetta
   }
   
//METODO update() ---------------------------  
 void update(float z){ //il metodo si aspetta che sia passato un parametro tipo numero intero
   val = z; //il valore del parametro è trasferito alla variabile globale "val", della Classe
 }

//METODO display() ---------------------------    
 void display()
   {
     fill(0,0,0);                  //colore di sfondo della barra, nero
     rect(X+width/64, Y+width/8, width/77, -width/8);  // rettangolo di sfondo
     
     Temp = map(val, 0, 255, -25, 50);
     Temp1 = map(Temp, -25, 50, -25, -215); //il valore di ingresso varia 0-->255, la barra ha una dimensione 0-->230
     if (Altezza1 < Temp1) Altezza1 = Altezza1 +1;  // in questo modo l'aggiornamento è progressivo, non a scatti
     if (Altezza1 > Temp1) Altezza1 = Altezza1 -1;
       
     fill(255,0,0);                //colore di riempimento della barra, rosso
     rect(X+width/64, Y+width/8, width/77, Altezza1); // rettangolo che simula il mercurio
     image(Termometro1, X, Y);    //visualizzazione dell'immagine della base del Voltmetro
   
     image(Targa1, X+width/160, Y+width/6.4);
     fill(235, 250, 125); // colore giallo
     textAlign(CENTER);
     text(TermometroLable, X+width/43, Y+width/5.48);
     String Testo = (String.format("%.1f", Temp) + "°");
     text(Testo, X+width/43, Y+width/5.96);
   }
}


Code: [Select]
/*
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CLASSE Voltmetro(coordinataX, coordinataY, Etichetta)

questa classe permette di definire i vari oggetti Voltmetro, che hanno bisogno dei seguenti campi:
coordinataX = intero, posizione X dell'Voltmetro
coordinataY = intero, posizione Y dell'Voltmetro
Etichetta = stringa, testo etichetta

i metodi della Classe Button sono i seguenti:

.display() -> attiva la rappresentazione grafica dell'inidcatore
.update() [0 - 1024] -> attraverso questo metodo si trasferisce il valore numerico che l'Voltmetro rappresenterà
                       0 = inizio della scala
                       1024 = fondo scala
                         
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
*/


class Voltmetro{
 
 //dichiarazioni delle variabili funzionali all'esecuzione della classe
 PImage gauge; //definizione dell'immagine della base dell'indicatore
 PImage arrow; //definizione dell'immagine della lancetta
 float InsX;
 float InsY;

 int val;                  //definizione della variabile che definisce la rotazione e che varierà tra 0 e 1024
 float valm;
 String VoltmetroLable;
 
 float Tensione;
 String TextTensione;
 
 //costruttore  
 Voltmetro(float tempX, float tempY, String lable)
 { //la Classe Voltmetro necessita di tre campi che devono essere definiti quando si istanzia un nuovo oggetto
                                             // la posizione X, Y ed una stringa che definisce l'etichetta
   InsX = tempX;                             // il campo tempX viene passato alla variabile globale della Classe X
   InsY = tempY;                             // il campo tempY viene passato alla variabile globale della Classe Y
   
   VoltmetroLable = lable; //il campo lable viene passato alla variabile globale della Classe Lable
   
   gauge = loadImage("strumento_150.png");  // caricamento dell'immagine di sfondo del Voltmetro  
   arrow = loadImage("freccia_150.png");    // caricamento dell'immagine che rappresenta l'indice del Voltmetro
   
 gauge.resize (width/13,width/13);
 gauge.loadPixels();
   
 arrow.resize (width/13,width/13);
 arrow.loadPixels();
   
   textAlign(CENTER); //viene definito l'allineamento del testo,
                    //questi parametri servono per la rappresentazione dell'etichetta
 }
   
   
//METODO update() ---------------------------  
 void update(int z)
   {
    //il metodo si aspetta che sia passato un parametro tipo numero intero
     val = z; //il valore del parametro è trasferito alla variabile globale "val", della Classe
   }

//METODO display() ---------------------------    
 void display(int Tens)
   {
       textAlign(CENTER);
       fill(235, 250, 125); // colore giallo
       text(VoltmetroLable, InsX +width/24, InsY +width/11);
       image(gauge, InsX, InsY);    //visualizzazione dell'immagine della base del Voltmetro
       
       pushMatrix();   // richiamando pushMatrix() prima di traslazioni o rotazioni del sistema di riferimento, permette di rimettere
                       //tutto a posto quando viene richiamato popMatrix(), in pratica tra i due comandi possiamo traslare e ruotare il sistema di riferimento
                       //potendo poi rimettere tutto come di default.
                       
       translate(InsX +width/26, InsY +width/26);  //traslazione dell'origine del sistema di riferimento
 
       valm = map(val, 0, 255, -135, +135); //valm è la traduzione di val in un range che va da -135 a +135
       Tensione = map(val, 0, 255, Tens -(Tens/2), Tens +(Tens/2));  // mi serve per leggere il valore di tensione es per 12v
       
       TextTensione =((String.format("%.2f", Tensione)) + "V") ; // per avere solo 2 decimali stampati più la V
               
       text(TextTensione, X, Y+width/38);
       
       rotate(radians(valm));   // rotazione del sistema di riferimento, il valore di valm (espresso in °) viene tradotto in radianti
       image(arrow, -width/26, -width/26);  // nel sistema di riferimento ruotato e traslato viene rappresentata l'immagine della lancetta
                                // la rotazione del sistema di riferimento è legata proporzionalmente alla variabile "val",
                                // la lancetta è rappresentata ruotata proporzionalmente al campo passato attraverso il metodo .update()
       
       // text(Tensione, 0, -20); // se lascio il testo qui, ruota con la freccia, simpatico
                             
       popMatrix();  //dopo aver traslato e ruotato il sistema di riferimento questo viene rimesso nelle condizioni di default
   }
}



camperos

Code: [Select]
void draw() // versione 3 draw che funziona con 4 invii di 8 bit e carattere di controllo W,204,205,206,207
{
 background(Sfondo);  //sfondo ;

 
 image(Vite, width/384, width/384);
 image(Vite, width/384, width/2.62);
 image(Vite, width/1.94, width/384);
 image(Vite, width/1.94, width/2.62);
 
 
 image(LedSpia_OFF, width/4.86, width/384);
 image(Spia220_OFF, width/3.32, width/384);
 
  Volt1.display(12); //rappresentazione di Volt1, valore in parentesi è la tensione nominale
  Volt2.display(24);
 
  Termometro1.display();
  Termometro2.display();

 if ( millis() - TimerTemp > Intervallo) // con cadenza ogni tot esegue l'elenco
   {
     TimerTemp = millis();
     udp.send("P99", ip, Port_Ard );
     println("P99");
     
   }
 
 //  stampa la verifica "manco mal", poi stampa le 4 parti divise della stringa, poi la conversione binaria della prima stringa
 //  poi solo i caratteri significativi della prima stringa, li lascio tutti anche se non servono, UNA FATICA A CAPIRE COME FARE...
 
  if (Status == 1) // è = 1 solo se la stringa ricevuta inizia con W
 {
   println("MANCO MAL!!");
       
   if (millis() - TempLampLed < TempLedON) image(LedSpia_ON,width/4.86, width/384
   ); // spia led accesa per il tempo stabilito
   
   // estrapolo le informazioni da arduino, la reply1[0] contiene la "W" di controllo ed è gia stata verificata
   println(reply1  [3]);  // Status spie 1 primi 8 pulsanti
   println(reply1  [4]);  // Status spie 2 secondi 8 pulsanti
   GestioneSpie();        // routine spie
       
   println(reply1  [1]);  // mi stampa le singole parti divise della stringa. Questi sono i primi 8 pulsanti
   println(reply1  [2]);  // seconda serie di 8 pulsanti
   GestionePulsanti();    // routine pulsanti
   
   println(reply1  [5]);  // Tensione Batterie 1
   println(reply1  [6]);  // Tensione Batterie 2
   println(reply1  [7]);  // Temperatura sensore 1
   println(reply1  [8]);  // Temperatura sensore 2
   println(reply1  [9]);  // Spia 220v
   GestioneSpia220V();
   
   println(reply1 [10]);  // A disposizione per altri eventuali pin
   
   // gestione Voltmetro
   V1 = Integer.parseInt(reply1 [7]);             // trasforma la stringa in float, che mi serve per il map()
   if (Tensione1 < V1) Tensione1 = Tensione1 +1;  // in questo modo l'aggiornamento è progressivo, non a scatti
   if (Tensione1 > V1) Tensione1 = Tensione1 -1;
   Volt1.update(Tensione1);                       // aggiorno la posizione dell'indicatore ad i
   
   V2 = Integer.parseInt(reply1 [7]);             // trasforma la stringa in float, che mi serve per il map()
   if (Tensione2 < V2) Tensione2 = Tensione2 +1;  // in questo modo l'aggiornamento è progressivo, non a scatti
   if (Tensione2 > V2) Tensione2 = Tensione2 -1;
   Volt2.update(Tensione2);                       // aggiorno la posizione dell'indicatore ad i

   // gestione termometro
   Temp1 = Integer.parseInt(reply1 [7]);          // trasforma la stringa in float, che mi serve per il map()
   Temp2 = Integer.parseInt(reply1 [8]);        // trasforma la stringa in float, che mi serve per il map()
   
   Temp2 = Temp1-60;   // non avendo ancora un valore valido da arduino per Temp2, per test mi invento un valore ricavato da Temp1
   
   Termometro1.update(Temp1);
   Termometro2.update(Temp2);
     
 }
 
} //fine draw

camperos

#59
Dec 05, 2013, 11:52 pm Last Edit: Dec 06, 2013, 12:05 am by camperos Reason: 1
le tab del tuo sketch modificate  :)
se non vuoi che restino a "vista" le cancello

le altre  tab non postate non le ho modificate.
funziona ma va provato bene, gli "int" sono stati modificati con "float"
;)

Go Up