Consigli su invio dati tramite processing. [RISOLTO]

Ciao a tutti sono nuovo, mi presento, mi chiamo Davide ed ho inziato a pasticciare con arduino da circa un mesetto, dopo aver acceso luci varie ecc volevo provare a costruire un piccolo braccio robotico (meccanica compresa...) con 3 snodi e un motore sulla pinza prensile.

mi sono messo in testa di controllarlo tramite seriale, e da qui son iniziati i problemi.....
Inanzitutto vorrei chiedervi dove trovare dei manuali dettagliati sul protocollo seriale di arduino (sinceramente non ci sto capendo una fava...), e già che ci sono vorrei sottoporvi il codice (che funziona) per capire come migliorarlo....
P.s. i motori ancora non li ho, arriveranno spero domani, quindi mi limito a controllare la luminosità del led tramite PWM, controllato tramite interfaccia processing.
arduino:

unsigned int val = 5;
unsigned int valt= 4;
int led = 10;

void setup ()
{
  Serial.begin (115200);
}
 
void loop ()
{
  val = Serial.parseInt ();
  if(val!=0){
    val=val-1000;
    if(val!=valt){
      valt=val;
      analogWrite(led, val);
    }
  }
}

processing:

...............
void mousePressed(){
  r1.muovi();
  String valore=String.valueOf(r1.angolo()+1000);
  arduino.write(valore);
  println(valore);
  r2.muovi();
  r3.muovi();
  r4.muovi();
}

Il codice completo è in allegato.....
Già che ci sono, come si può trasformare una classe che ho creato in processing in una libreria (così posso compattare il codice)e per le risposte
Ringrazio anticipatamente

robotcontrol.pde (3.83 KB)

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda:
- serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections
- pinout delle varie schede by xxxPighi: Pinout
- link generali utili: Link Utili

Dopo che avrai fatto quanto su richiesto ...

... considera che questo è il forum di Arduino.cc dove si fornisce assistenza per problemi relativi a problematiche che coinvolgono Arduino, i suoi collegamenti e la sua programmazione.

Per problematiche relative invece a "Processing" e bene che tu ti rivolga al forum di supporto di "Processing" dove ne sanno sicuramente più di noi e potrai ricevere risposte più rapidamente.

Ciò non toglie che, se qualcuno avesse la risposta al tuo quesito, sicuramente cercherà di aiutarti :wink:

Guglielmo

ciao ghiso983,

lasciami dire...quando ho letto, nella tua presentazione, "...classe leggermente disinteressata..." mi sono messo a ridere :smiley: ...hai il mio sostegno dato che il ruolo dell'insegnante è fondamentale.
detto questo...alcune precisazioni:
in Processing, da quel che so, la creazione di una libreria, l'esportazione e la sua successiva "inclusione" in uno sketch non è semplice come in arduino QUI un link da dove iniziare a guardare. Diverso però è se si vuole creare un file.pde contenete una o più classi da includere ai vari progetti...allora basta creare un file.pde con la nostra classe...salvarlo in una cartella XYZ e ad ogni nuovo progetto copiare quel file.pde nella nuova cartella; facendo così nell'IDE di Processing avremmo, oltre alla TAB iniziale anche una o più TAB riferite a quei file aggiunti...già adesso puoi aggiungere altre TAB (freccia verso il giù nella TAB esistente)...e se salvi il progetto ti salve n file.pde quante sono le TAB create.
Quindi se vuoi "snellire" lo sketch dedica una TAB alla classe ed una al vero sketch.

nel tuo sketch di Processing vedo che stampi, verso Arduino, solo :

  String valore=String.valueOf(r1.angolo()+1000);
  arduino.write(valore);

in pratica invii una Stringa; mentre lato arduino fai:

val = Serial.parseInt ();

che traduce una Stringa in una LONG e non in una INT...guarda QUI

detto questo dicci che problema reale riscontri.

Hai ragione sono stato distratto!
Però il codice in effetti funziona comunque, solo che è lento (ci mette più di un secondo a cambiare lo stato del led dopo che ho inviato il codice e penso non sia molto normale!)
Ora sto studiando un modo per passare il tutto tramite byte ed evitare il parseint.
Solo che il byte di processing è signed e quello di arduino è unsigned.
E devo trovare il modo di convertire i due formati in qualche modo...

ciao,

in quel link che ti ho indicato e che si riferisce alla parseInt(), tra le varie cose, c'è scritto:

Initial characters that are not digits or a minus sign, are skipped;

Parsing stops when no characters have been read for a configurable time-out value, or a non-digit is read;

If no valid digits were read when the time-out (see Serial.setTimeout()) occurs, 0 is returned;

ci mette molto perchè aspetta il time out...tu dovresti raggruppare il tutto sotto un:

if(Serial.available()){
//il tuo codice
}

prova e fammi sapere

Non cambia nulla a parte che posso eliminare parti di codice inutile (quindi servito è servito), però il tempo di risposta rimane enorme.
Il problema però è di processing in quanto se mando il comando tramite ide arduino il cambio della luminosità è immediato!
Quindi grazie dell'aiuto!

Alla fine ho risolto da solo. Arduino aspettava un comando di fine stringa, che a quanto pare processing non inviava. Così invio una,stringa con il numero che arduino aspetta ed immediatamente dopo una stringa vuota e funziona.

Scusate, mi sapete dire cosa sbaglio?
ho scritto il seguente codice e funziona, però ci mette tipo un secondo buono per ricevere il segnale da seriale....

#include <Servo.h>
Servo servosnodi[4];
#define velo 10

long int val = 0;
long int tempo = 0;
byte snodi[4] = {0, 0, 0, 0};
byte snodimem[4] = {0, 0, 0, 0};
int g = 10;
int r = 11;
int b = 9;

void setup () {
  servosnodi[0].attach(9);
  servosnodi[1].attach(10);
  servosnodi[2].attach(11);
  servosnodi[3].attach(6);
  Serial.begin (9600);
}

void loop ()
{
  if (Serial.available() > 0) {
    val = Serial.parseInt ();
  }
  for (int i = 1; i < 5; i++) {
    if (val < i * 1000 + 190 && val > (i * 1000 - 1)) {
      val = val - 1000 * i;
      snodimem[i - 1] = (byte) val;
    }
  }
  if (tempo + velo < millis()) {
    for (int i = 0; i < 4 ; i++) {
      if (snodi[i] < snodimem[i]) {
        snodi[i]++;
      }
      if (snodi[i] > snodimem[i]) {
        snodi[i]--;
      }
      servosnodi[i].write(snodi[i]);
      tempo = millis();
    }
  }
}

Non riesco a capire perché attenda il timeout.....

ciao,

il prototipo della funzione parseInt() è così:

  long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
  // returns the first valid (long) integer value from the current position.
  // lookahead determines how parseInt looks ahead in the stream.
  // See LookaheadMode enumeration at the top of the file.
  // Lookahead is terminated by the first character that is not a valid part of an integer.
  // Once parsing commences, 'ignore' will be skipped in the stream.

mentre la funzione vera e prorpia funziona così:

// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.

long Stream::parseInt(LookaheadMode lookahead, char ignore)
{
  bool isNegative = false;
  long value = 0;
  int c;

  c = peekNextDigit(lookahead, false);
  // ignore non numeric leading characters
  if(c < 0)
    return 0; // zero returned if timeout

  do{
    if(c == ignore)
      ; // ignore this character
    else if(c == '-')
      isNegative = true;
    else if(c >= '0' && c <= '9')        // is c a digit?
      value = value * 10 + c - '0';
    read();  // consume the character we got with peek
    c = timedPeek();
  }
  while( (c >= '0' && c <= '9') || c == ignore );

  if(isNegative)
    value = -value;
  return value;
}

quindi come vedi... se metti lo "skipChar" (corrispondente al char ignore) quando questo viene trovato dovrebbe uscire prima dalla funzione senza aspettare il "time out".

Non ho capito....
devo passare una char da ignorare tipo una a?
e poi passare una stringa tipo "2045a" e dovrebbe funzionare?
P.s.
ho provato parseInt("a"); ma mica funziona...

ciao,

adesso che guardo meglio il metodo parseInt() che accetta solo un char come "skipChar" è protected;
quindi dovresti scrivere una cosa tipo:

Serial.parseInt(SKIP_ALL, 'a');

attenzione che devi passare una char tipo 'a' e non una String tipo "a".

Funziona grazie mille....
Che errore da fesso quello di "a"..... ma sai che non lo sapevo proprio? :confused:

Ma magari invece di 'a' intercetta un terminatore standard, come '\r' (carriage return, codice 0x13).