Arduino+Processing trasmettere array e visualizzarlo

Buongiorno a tutti, sto facendo un programma per il monitoraggio di vari sensori.

Arduino legge 3 valori da tre sensori che non ho ancora quindi per ora sul void loop() ho creato una variabile incrementale che continua a inviare un numero crescente.

Dalla parte Processing ho creato un interfaccia grafica con controlp5

Ora sono in alto mare non riesco a proseguire:

Cosa non riesco a fare:

ARDUINO:
Inviare un array di tre sensori (valori) tramite seriale e riceverli in processing.

PROCESSING:
Collegare le variabili prese in seriale all' oggetto knob dell' interfaccia per far si che si muova la "lancetta" del manometro.

Sostanzialmente non riesco a mandare tre valori diverso da arduino a processing e lato processing non ho idea di come pescare i valori e metterli nel oggetto per far si che si muova la lancetta.

Spero che qualcuno mi possa aiutare perchè non riesco a ritrovare la strada =(

ARDUINO:

const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);            
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);  
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);           

  // print the results to the serial monitor:
  Serial.print("sensor = " );                       
  Serial.print(sensorValue);      
  Serial.print("\t output = ");      
  Serial.println(outputValue);   

  // wait 2 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(2);                     
}

PROCESSING:

import processing.serial.*; 
import controlP5.*;    // import controlP5 library
ControlP5 controlP5;   // controlP5 object


Serial myPort;    // The serial port: 
PFont myFont;     // The display font: 
String inString;  // Input string from serial port: 
int lf = 10;      // ASCII linefeed 
int deg, val;
int myColorBackground = color(0,0,0);
Knob myKnob1;
Knob myKnob2;
Knob myKnob3;
int knobValue = 100;


 
void setup() { 
  size(640,480); 
  smooth();  //ControlP5
  controlP5 = new ControlP5(this);   //ControlP5
  myKnob1 = controlP5.addKnob("PrexOlio",0,360,0,10,10,200);
  myKnob2 = controlP5.addKnob("TempOlio",0,360,0,10,240,200);
  myKnob3 =controlP5.addKnob("PrexTurbo",0,360,0,250,40,380);

  println(Serial.list());  
  myPort = new Serial(this, Serial.list()[4], 9600); 
  myPort.bufferUntil(lf);
} 




void draw() { 
  background(myColorBackground);
  text("Punto GT 1.4 Turbo", 270,10);
  text("Lettura: " + inString, 70,235);
  text("Lettura: " + inString, 70,465);
  text("Lettura: " + inString, 400,445);
} 


 void serialEvent(Serial p) { 
  inString = p.readString(); 
}

Grazie a tutti

Ti invitiamo a presentarti qui: Re: Presentazioni nuovi iscritti, fatevi conoscere da tutti! (Part 1) - Generale - Arduino Forum
e a leggere il regolamento: [REGOLAMENTO] Come usare questa sezione del forum - Italiano - Arduino Forum

lalogt:
ARDUINO:
Inviare un array di tre sensori (valori) tramite seriale e riceverli in processing.

Cosa c'entra un array? Devi inviare 3 valori. Punto e basta. Li invii semplicemente con Serial.print() ed è meglio mettere davanti al valore un carattere che indica quale sensore. Esempio A,B e C
Nel tuo esempio per Arduino leggi 1 solo sensore. Rifallo con i 3 sensori e che spari su Serial i 3 valori.
Quale valore spedirai da Arduino? Quello tra 0-1023 o quello 0-255 ?

Serial.print("A"); Serial.println(outputValue1);
Serial.print("B"); Serial.println(outputValue2);
Serial.print("C"); Serial.println(outputValue3);

Poi se vuoi per forza usare un array allora dichiari outputValue come array e userai:

Serial.print("A"); Serial.println(outputValue[0]);
Serial.print("B"); Serial.println(outputValue[1]);
Serial.print("C"); Serial.println(outputValue[2]);

Ovviamente devi triplicare le letture dei potenziometri, le map, i const pin, etc.

In Processing leggi la stringa ma dovrai leggere il primo carattere A,B o C per sapere il valore a quale knob appartiene.

void serialEvent(Serial p) { 
  inString = p.readString(); 
  char primo=inString.charAt(0);  // primo carattere
  String cifra=inString.substring(1);  // da secondo carattere in poi
  int val=int(cifra);          // valore da 0-255 o 0-1023, non sò cosa spedirai
  switch(primo)
  { case 'A': myKnob1.setValue(val);
      break;
    case 'B': myKnob2.setValue(val);
      break;
    case 'C': myKnob3.setValue(val);
      break;
  }
}

P.S. codice non testato e non conosco di preciso controlP5, pare esista il metodo setValue() per i knob

Come prima cosa ti ringrazio veramente molto perchè avevo un gap nel capire come funzionava la lettura seriale, parlavo di array perchè avevo in mente il pescaggio dati dalle tabelle sql in php e per qualche stupido motivo davo per scontato che arduino inviava i 3 valori su tre righe e processing pescava e da un array pescavo la riga uno due o tre, comunque a parte il casino che mi sono creato in testa.

Ho avuto due giorni di tempo per capire il codice e sono gia un paio di giorni che sono progredito un po nel capire come funziona la gestione dei knob in controlp5, e facendo un' pò di debug ho trovato un problema, credo che il problema stia su come viene letto quello che arriva in seriale a processing.

Allego i sorgenti completi e aggiornati e mi spiego.

ARDUINO:

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int Stempolio = A1;
int Sprexolio = A2;
int Sprexturbo = A3; 
int Vtempolio = A1;
int Vprexolio = A2;
int Vprexturbo = A3;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  Serial.begin(9600); 
  pinMode(Stempolio, INPUT);     
  pinMode(Sprexolio, INPUT);
  pinMode(Sprexturbo, INPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  Vtempolio = analogRead(Stempolio);
  Vprexolio = analogRead(Sprexolio);
  Vprexturbo = analogRead(Sprexturbo);
  Serial.print("A"); Serial.println(Vtempolio);
  Serial.print("B"); Serial.println(Vprexolio);
  Serial.print("C"); Serial.println(Vprexturbo);
}

Output Seriale:

C149
A1023
B70
C149
A1022
B73
C150
A1023
B73
C150
A1023
B74
....

PROCESSING:

import processing.serial.*; 
import controlP5.*;    // import controlP5 library
ControlP5 controlP5;   // controlP5 object

Serial myPort;    // The serial port: 
PFont myFont;     // The display font: 
String inString;  // Input string from serial port: 
int lf = 10;      // ASCII linefeed 
int deg, val;
int myColorBackground = color(0,0,0);
Knob myKnob1;
Knob myKnob2;
Knob myKnob3;
int knobValue = 100;
int Vtempolio = 0;
int Vprexolio = 0;
int Vprexturbo = 0;

void setup() { 
  size(640,480); 
  smooth();  //ControlP5
  controlP5 = new ControlP5(this);   //ControlP5
//  myKnob1 = controlP5.addKnob("PrexOlio",100,1024,0,10,10,200);
//  myKnob2 = controlP5.addKnob("TempOlio",0,1024,0,10,240,200);
//  myKnob3 =controlP5.addKnob("PrexTurbo",0,1024,0,250,40,380);
  
  myKnob1 = controlP5.addKnob("PrexOlio")
               .setRange(0,1024)
               .setValue(0)
               .setPosition(10,10)
               .setRadius(100)
               .setDragDirection(Knob.VERTICAL)
               ;
 
  myKnob2 = controlP5.addKnob("TempOlio")
               .setRange(0,1024)
               .setValue(0)
               .setPosition(10,240)
               .setRadius(100)
               .setDragDirection(Knob.VERTICAL)
               .setNumberOfTickMarks(20)
               .snapToTickMarks(true)
               .setTickMarkLength(6)
               ;
               
  myKnob3 = controlP5.addKnob("PrexTurbo")
               .setRange(0,1024)
               .setValue(0)
               .setPosition(250,40)
               .setRadius(190)
               .setNumberOfTickMarks(10)
               //.setTickMarkLength(4)
               //.snapToTickMarks(true)
               .setColorForeground(color(255))
               .setColorBackground(color(255, 255, 255))
               .setColorValueLabel(color(159,20,23))
               .setColorActive(color(51,124,189))
               .setDragDirection(Knob.HORIZONTAL)
               ;

  println(Serial.list());  
//  myPort = new Serial(this, Serial.list()[33], 9600); 
  myPort = new Serial(this, "/dev/ttyUSB0", 9600);
  myPort.bufferUntil(lf);
} 

void serialEvent(Serial p) { 
  inString = p.readString(); 
  char primo=inString.charAt(0);  // primo carattere
  String cifra=inString.substring(1);  // da secondo carattere in poi
  int val=int(cifra);          // valore da 0-255 o 0-1023, non sò cosa spedisce arduino
  print(primo); //debug
  print(cifra); //debug
  switch(primo) { 
    case ('A'): myKnob1.setValue(val);
      break;
    case ('B'): myKnob2.setValue(val);
      break;
    case ('C'): myKnob3.setValue(val);
      break;
  }
}

void draw() { 
  background(myColorBackground);
  fill(knobValue);
  text("Punto GT 1.4 Turbo", 270,10);
  text("Lettura: " + Vtempolio, 70,235);
  text("Lettura: " + Vprexolio, 70,465);
  text("Lettura: " + Vprexturbo, 400,445);
}

In processing se faccio stampare in console il valore primo e cifra il risultato è

primo:

 ABCABCABCABC....

cifra:

73
150
1023
70
149
1022
72
150
1023
71
149
1023

Credo che il problema sia sulla parte di codice che prende la stringa che arriva da seriale.

Il setValue sul knob funziona se io ci metto un valore fisso myKnob1.setValue(100); la lancetta del knob resta fissa a 100 e funziona se invece gli passo la variabile val resta tutto a zero e facendo "debug" quindi

switch(primo) { 
    case ('A'): myKnob1.setValue(val);
    print(val);
    ....

il risultato è una sfilza di zeri 0000000000000

PS: I valori che mando sono 0-1023.

Ti ringrazio ancora moltissimo per tutto.

Allora questa non funziona:

int val=int(cifra);

Non conosco bene Java e Processing (quale versione? io uso 2.2)
cifra è un oggetto String e quindi un testo, devi convertirlo in valore intero dentro a val.
Prova int val = parseInt(cifra);
Comunque a me questo funziona:

void setup()
{ String p="1234";
  int x=parseInt(p);
  int y=int(p);
  println(p);
  println(x);
  println(y);
}
void draw() {}

Il print di val ti conviene metterlo insieme agli altri

print("primo="); print(primo); //debug
print("  cifra="); print(cifra); //debug
print("  val="); println(val);

Mi hai aperto gli occhi facendomi notare che cifra è una stringa era scritto bello in grande e io non me ne rendevo conto XD

Il tuo suggerimento è corretto andava convertita la variabile val ma non in int ma in Float perche setValue(Float) vuole una float

Il pezzo di codice funzionante è

nid69ita ti ringrazio veramente molto se non c' eri tu non ce l' avrei fatta.

void serialEvent(Serial p) { 
  inString = p.readString(); 
  char primo=inString.charAt(0);  // primo carattere
  String cifra=inString.substring(1);  // da secondo carattere in poi
  float val=parseFloat(cifra);          // valore da 0-255 o 0-1023, non sò cosa spedisce arduino
  print("primo=");  println(primo); //debug
  print("cifra=");  println(cifra); //debug
  print("val=");    println(val);

  switch(primo) { 
    case ('A'): myKnob1.setValue(val);
      break;
    case ('B'): myKnob2.setValue(val);
      break;
    case ('C'): myKnob3.setValue(val);
      break;
  }
}

lalogt:
nid69ita ti ringrazio veramente molto se non c' eri tu non ce l' avrei fatta.

Prego, fa piacere aiutare :smiley: