Processing: Varie ed Eventuali

se hai seguito il mio codice l'oggetto(variabile per capirci, ma io non ve l'ho detto :zipper_mouth_face:) ris è di tipo String, quindi documentazione java:
http://docs.oracle.com/javase/6/docs/api/index.html?overview-summary.html
classe String:
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
e tra i metodi troviamo:

length
public int length()
Returns the length of this string. The length is equal to the number of Unicode code units in the string.
Specified by:
length in interface CharSequence
Returns:
the length of the sequence of characters represented by this object.

quindi la correzione è:

ris = ris.substring(0, ris.length()-1);

edit: consiglio una bella lettura delle classi File, BufferInputStream (e Output), ObjectInputStram (e Output), Socket, Thread (very hard! programmazione parallela!)

da notare che int, float, double, long hanno anche una classe che li rappresenta Integer, Float e Double, che mette a disposizione un sacco di utility. Però fai attenzione che NON sono la stesa cosa, int, float, double e long sono un retaggio per non far spaventare troppo chi arriva dal C, e per sprecare meno RAM, cosa di cui possiamo fregarcene allegramente sui sistemi moderni per la nostra tipologia di applicazioni

ci ero arrivato anche io, pero' non mi aveva funzionato, probabilmente si era staccato qualcosa.
quindi tutto ok, funge.

grazie anche dei consigli, vedro' di leggermi un po' di cose.

Dimmi un'ultima cosa, visto che quest'esempio usa un valore tra 0 e 255, senza punto decimale, dichiarare Float la variabile brigthness e' un obbligo, perche' chenneso' le funzioni richiaate vogiono per forza variabili float, oppure potrei modificare tutti per usare INT ?

grazie ancora a Te, Leo, e gli altri che hanno letto e intervenuto.
credo questo post sia utile a molti

nono, puoi usare quello che vuoi. Se ci fai caso java ogni metodo lo fornisce per mille tipi di dato differente proprio per legarti il meno possibile dai tipi di dato (overloading dei metodi, lo stesso sistema usato anche dalla Serial.println() per intenderci)

Testato:
c'e' da dire che Leo, nonostante abbia subito deto che non conosceva processing, gia' la pagina scorsa aveva "indovinato" che la M era difficile da convertire in numero :slight_smile:

Il Leo è il Leo, scusa se è poco :stuck_out_tongue:

rimettetemi in carreggiata con quest'altro problema, molto simile, che sottolinea le mie lacune in merito :cold_sweat:

con Processing stampo verso la seriale

ArduinoPort.write (minute());

su arduino non ricevo ad esempio il minuto 38, ma il carattere & perche' credo che la seriale giustamente ragiona in ascii, e quindi prende il numero 38 e lo converte, e' giusto il ragionamento ?

indi io per risolvere dovrei trasformare 38 in una stringa ascii giusto ? cioe' dovrei spedire verso la seriale 51-56 in modo che il terminale convertendo in ascii staperebbe 38 ?

ho trovato riferimenti ad ITOA, IntTOAscii, e' corretto ? ma non trovo come applicarlo in processing.

non sparatemi se ho detto stupidaggini, mi piacerebbe almeno di aver fatto una corretta diagnosi del problema :slight_smile:

Scusa ma tu ricevi il byte 38, perché perdere tempo a trasformarlo con funzioni strane? Usalo così com'è.

Oppure, se vuoi comunque le decine ed unità, fai così:

byte decine;
byte unita;
byte lettura;
  lettura=Serial.read();
  decine=lettura/10;
  unita=lettura-(decine*10);

Il mio obiettivo e' ricevere 38 su un ipotetico terminale. Quindi questo sto tentando di imparare. Quello da te consigliato funziona, gia provato.
Ho letto di almeno un paio di approcci per convertire int in ascii. Sei daccordo sull'analisi generale o ci sono fesserie ?

Testato:
Il mio obiettivo e' ricevere 38 su un ipotetico terminale. Quindi questo sto tentando di imparare. Quello da te consigliato funziona, gia provato.
Ho letto di almeno un paio di approcci per convertire int in ascii. Sei daccordo sull'analisi generale o ci sono fesserie ?

Scusa, ma quello che ricevi è già 38, solo che non lo devi visualizzare come ascii, ma come numero.
prova già a trasformare il byte ricevuto con int(). (non provato, ma immagino si faccia così..correggetemi se non è così..)

..credo che la seriale giustamente ragiona in ascii..

no, la seriale ragiona in gruppi di bit, quindi byte, precisamente da 8 bit, che ovviamente sono numeri da 0 a 255. quello che ragiona in ascii è l'utilizzo che fai di questo byte ricevuto.

io ho specificato "dove" intendo ricevere il 38, su un terminale, per leggere 38 su un terminale, sia un terminale sw, sia una telescrivente della seconda guerra mondiale, devo spedirgli la stringa 38, cioe' devo spedirgli due caratteri, il 3 e l'8, rispettando lo standard ascii per quanto riguarda il gruppo di 7 bit che li rappresentano.

La domanda quindi e', come fare in processing (niente arduino, niente maneggi lato terminale), a convertire
Port.write (minute()); che per come e' scritta la funzione mandera' sulla seriale il singolo carattere&, mentre a me serve che mandi 51 56, che letti su un terminale saranno tradotti in 38

condivido la soluzione con tutti :slight_smile:
http://processing.org/reference/str_.html

confermo che la soluzione di cui sopra funziona :slight_smile:

mi manca un ultimo tassello, la funzione hour() di processing elimina gli zeri dal suo risultato, cioe' se sono le 11 riporta 11, ma se e' l'una di notte riporta solo una cifra, 1

A me serve che all'una di notte riporta sempre due cifre, quindi 01

se non volete farmi scervellare un altro giorno intero per un misero zero, dite la vostra :slight_smile:

Trasforma in stringa il risultato. Se è lungo 1 carattere, aggiungi prima uno zero.

Controlla il valore se è minore di 10. Nel caso stampa prima uno zero.

Alla seconda ci avevo pensato e lo so anche fare. Quindi faro la prima :slight_smile:
Hai un esempio ? Devo contare la quantita di caratteri. Interessante :slight_smile:

Testato:
Hai un esempio ? Devo contare la quantita di caratteri. Interessante :slight_smile:

In Processing? No. Non lo so usare.

String stringa;
while (xxx)
stringa+= caratteri;

stringa.length();

visto che cmq dopo aver contato i caratteri della stringa avrei cmq dovuto usare degli IF per capire se erano di uno o due caratteri, e visto che i dati in INT li ho gia' a disposizione, ho optato per usare il secondo canale di Leo :* :slight_smile:

lesto mi dai una conferma:
su arduino abbiamo il setup ed il loop, se scrivo una subroutine chiamata VOID PIPPO, ma poi non la richiamo all'interno del Void LOOP, questa funzione e' come se non esistesse giusto ?

Mentre in processing abbiamo Void SETUP e VOID DRAW, pero' se creo appunto una Void PIPPO, essa viene sempre eseguita, anche se non e' in void Draw, cioe' il Void Draw non e' il corrispettivo di Loop.

C'e' sempre l'obbligo di avere Void Setup e Void Draw ?

grazie

su arduino abbiamo il setup ed il loop, se scrivo una subroutine chiamata VOID PIPPO, ma poi non la richiamo all'interno del Void LOOP, questa funzione e' come se non esistesse giusto ?

non viene proprio compilata, se osservi gli hex non ne trovi traccia.

Mentre in processing abbiamo Void SETUP e VOID DRAW, pero' se creo appunto una Void PIPPO, essa viene sempre eseguita, anche se non e' in void Draw, cioe' il Void Draw non e' il corrispettivo di Loop.

no, avviene la stessa identica cosa di arduino, non viene nemmeno compilata in bytecode (anche se forse viene compilata in alcuni casi per esempio static, devo ammettere che non lo so)
Immagina la draw come un interrupt, che ti avvisa quando sei pronto a disegnare. In realtà è un thread a parte che si occupa della grafica (quindi in parallelo)
Esiste anche un sistema di interrupt software e viene detto "ad eventi", per esempio c'è l'evento se succede qualcosa alla seriale, l'evento pulsante cliccato, etc.. etc..

C'e' sempre l'obbligo di avere Void Setup e Void Draw ?

Normalmente java (e quindi processing) usano una interfaccia che implementa i tutti i metodi astratti (anche il setup e il loop di arduino sono metodi astratti, se non lo sono hanno lo stesso concetto di base fatto in maniera più complessa), in questo modo tu sovrascrivi solo quello che ti serve.

ho studiato un po' :slight_smile:
Ora da ZERO sono arrivato a saperne UNO :slight_smile:

mi spieghi pro e contro di questa metodologia ?

Questo e' un evento, lavora per conto suo anche se e' fuori dal Void Draw
Tu lo chiami anche Interrupt, su arduino gli interrupt sono comunque parte integrante del singolo thread, non e' un multisessione, il loop si ferma e va ad eseguire l'ISR, poi riprende
In processing invece gli eventi lavorano per conto loro, completamente separati, Sono un therad a parte ?

 void serialEvent (Serial ArduinoPort) { 
    if ( ArduinoPort.available() > 0) {  
    valRX = ArduinoPort.readChar();         
    }

Ma anche se tolgo l'Evento, e inserisco la logica di funzionamento nel void Draw, tutto continua a funzionare.
Cosa ho fatto con questa modifica ?
non sto' piu' usando gli Eventi ? non sto' piu' lavorando in multisessione ?
Pro e contro delle due modalita' ?

void draw() {  
if ( ArduinoPort.available() > 0) {  
    valRX = ArduinoPort.readChar();

Thanks :slight_smile:

gli eventi sono simili agli interrupt, vengono generati in parallelo (salvo che il generatore non sia nello stesso thread del ricevente, in tal caso l discorso salta)

poichè sono in parallelo, tutte le azioni sui dai devono essere sincronizzate;

void serialEvent (Serial ArduinoPort) { 
    if ( ArduinoPort.available() > 0) {  
    syncronize(valRX){
    valRX = ArduinoPort.readChar();         
}
    }

in questo caso la variabile valRX viene usata come "blocco", ma attenzione! deve esse un oggetto, e se assegni un nuovo indirizzo alla fariabile usando l'operatore "new" salta tutto! infatti queste variabili di solito sono final (quindi niente "new", ma puoi comunque cambiarne i valori contenuti)

ovvio che poi il blocco va messo anche dove usi la variabile!

c'è una complessità in più come noti. in oltre tra un darw e l'altro, se la grafica è pesante o il pc lento, possono arrivare tanti Event! In fatti di solito si usa un buffer, per esempio una Queue Concurrent, in modo che la gestione della sincronizzazione se la fa java, però lo fa solo finchè usi la queue, nel momento in cui hai ricevuto il dato nulla ti assicura che non succeda nulla al dato.
Un esempio: io ho un mondo fisico e uno grafico, in 2 thread differenti, ed entrambi usano lo stesso array di oggetti da disegnare/muovere.
non posso usare una queue perchè lenta da riempire ogni 60Hz con tutti gli oggetti, e non posso certo fare una sincronize sulla posizione del singolo oggetto, perchè non posso disegnare metà schermo quando un oggetto è al loop fisico 1 e alcuno al loop fisico 2. In questo caso ho usato una variabile di lock ad inizio dei 2 loop, quindi se sta funzionando un loop, l'altro rimane in attesa. Appena finisco di assegnare le posizioni rilascio il lock e proseguo in altre operazioni dei loop in parallelo. notare che può capitare più loop video senza loop fisico, e viceversa, questo slega molto la qualità della visualizzazione video dalla velocità di esecuzione della logica di gioco, però come hai notato aumenta la complessità: pensa se diemntico una sincronize!!