Passaggio valori a funzione

Praticamente ho un'arduino mega con montato lo shield midi.
Sulla seriale1 ricevo i dati dal pc e in base a quello che mando creo il comando midi da unviare sulla seriale0

Poi perchè se tolgo tutti i Serial.print, non i Serial1, la stringa non si compone ?
Devo per forza stampare su Serial per storare il dato da Serial.read ?

Grazie ancora Alberto

Hai chiuso male le varie funzioni. In pratica dopo SendCCMidi ci sono 2 "}" mentre una di esse dovrebbe stare prima, perché la funzione SendCCMidi deve stare fuori da loop(). Ogni funzione è a sé stante, non puoi incapsularla all'interno di un'altra.

Cioè così:

/*===========================
TITLE: Serial Echo Code v1.1
AUTHOR: Fayaz Kadir
DESCRIPTION: If you send a string starting with "!" and ending with "*", the Arduino responds back with "$Y" for valid data string, or $N for invalid data string. You can modify this code for your use.
COMPATIBLE BOARD: Arduino Mega (but any other Arduino should work fine)
============================*/

char string[25];
int i=0;
int string_len;
int inByte;
int last_inByte;
int counter=0;

void setup() {
  Serial.begin(9600); //INTIALISING THE MIDI SERIAL PORT
  Serial1.begin(9600); //INTIALISING THE CONTROLLER SERIAL PORT
}

// La stringa in arrivo deve avere un ! per ogni lettera e deve terminare con un *
// All'inizio va raddoppiato !! altrimenti perdo la prima lettera
// Esempio !!P!R!O!V!A*

void loop()  // LOOP FUNCTION
{
  inByte = Serial1.read();
  string_len=0;
  if (inByte == '!')  read_serial();  // If Start of line ("!") is found, call read_serial() function
}

void read_serial()  // FUNCTION FOR READING THE SERIAL MESSAGE
{
   Serial.println ("SOL FOUND and reading");  // THE SOL (Start of Line) found notice.
   Serial1.print("READ : !\n");  //Saying that it has read "!" on the serial port
   while (inByte!= '*') // As long as EOL not found, keep reading
   if (Serial1.available() > 0) // if new data is available
     { 
       inByte = Serial1.read(); // Read new byte
       Serial.print("READ : "); // Display the new byte
       string[string_len] = inByte; // Save the data in a character array
       Serial.println(string[string_len]); // Print the characters that was recieved
       string_len++;
     }
     else if (Serial1.available() == 0) 
       {
           Serial.println("EOL not available, data string invalid"); // If EOL not in the string
           Serial1.print("$N"); //FAIL SIGNATURE
           break;
       }

 if (inByte == '*')
{
 Serial1.println ("$Y"); //SUCCESS SIGNATURE
 for (int i=0; i <= (string_len-2); i++){
   Serial.print (string[i]);
   } 

 
 Serial.print ("\n");
    switch (string[0]) 
      {
        case 'CC':
          int cmd1 = (int)(string[1]);
          int cmd2 = (int)(string[2]);
          int cmd3 = (int)(string[3]);
          SendCCMidi(cmd1,cmd2,cmd3);
          break;
      }
   }
}

void SendCCMidi(int cmd, int data1, int data2) {
  Serial.write(cmd);
  Serial.write(data1);
  Serial.write(data2);
}

Grazie :slight_smile:

Mi sapresti dire anche qualcosa sulla seconda domanda, che ho postato mentre rispondevi ?

TNX; alberto

Non ho capito il tuo problema. Scusa.

Help me, please

Da VB invio una stringa così:
"!!CC!0xB0!0x01!0x7F!*"

Per il momento tralascio il primo CC lo usero più avati

Alla fine in arduino la tasformo in tre Stringhe
Comando
Data1
Data2

Quando li stampo dal monitor seriale vedo perfettamente:
0xB0
0x01
0x7F

Ora quello che non so fare è come inviare le 3 stringhe in 3 byte con serial.write nelle ultime 3 righe commentate.

Mi date una mano ?

Grazie, Albverman

char string[25];
int i=0;
int string_len;
int inByte;
int last_inByte;
int counter=0;

String TipoComando;
String Comando;
String Data1;
String Data2;

void setup() 
{
  Serial.begin(9600); //INTIALISING THE MIDI SERIAL PORT
  Serial1.begin(9600); //INTIALISING THE CONTROLLER SERIAL PORT
}

void loop()  // LOOP FUNCTION
{
  inByte = Serial1.read();
  string_len=0;
  if (inByte == '!')  read_serial();  // If Start of line ("!") is found, call read_serial() function
}

void read_serial()  // FUNCTION FOR READING THE SERIAL MESSAGE
{
   Serial.println ("SOL FOUND and reading");  // THE SOL (Start of Line) found notice.
   Serial1.print("READ : !\n");  //Saying that it has read "!" on the serial port
   while (inByte!= '*') // As long as EOL not found, keep reading
   if (Serial1.available() > 0) // if new data is available
     { 
       inByte = Serial1.read(); // Read new byte
       Serial.print("READ : "); // Display the new byte
       string[string_len] = (int)inByte; // Save the data in a character array
       Serial.println(string[string_len]); // Print the characters that was recieved
       string_len++;
     }
     else if (Serial1.available() == 0) 
       {
           Serial.println("EOL not available, data string invalid"); // If EOL not in the string
           Serial1.print("$N"); //FAIL SIGNATURE
           break;
       }

 if (inByte == '*')
{
 Serial1.println ("$Y"); //SUCCESS SIGNATURE

      Comando=((String)string[3]+(String)string[4]+(String)string[5]+(String)string[6]);
      Data1=((String)string[8]+(String)string[9]+(String)string[10]+(String)string[11]);
      Data2=((String)string[13]+(String)string[14]+(String)string[15]+(String)string[16]);
      
      Serial.println(Comando);
      Serial.println(Data1);
      Serial.println(Data2);

//      Serial.write(Comando);
//      Serial.write(Data1);
//      Serial.write(Data2);
      
 }
}

Serial.print(Comando, HEX);

non è il valore in hex, ma la sua rapresentazione ascii (ovvwro leggibile da un umano). La write scrive il vero e proprio byte in 1 e 0, quindi perde di significato se dire binario, hex o altro

Uso arduino ide 1.0
Mi da errore:
no matching function for call to 'HardwareSerial::write(String&,int)'

sei stato più veloce della mia edit, è print non write

Ma io dovrei mandare il byte alla periferica midi quindi devo usare write.

Sa fò ?

:grin:

Io dovrei mandare l'equivalente:

Serial.wryte(0xB0);
Serial.write(0x01);
Serial.write(0x7F);

se non erro la write manda un byte solo, mentre stai cercando di inviare valori a 2 byte. quindi scomponili:
int invio = 0X16;
serial.write(invio<<8);
serial.write(invio);

comunque cerca nel reference, c'è scritto tutto

Scusa per la domanda ma sono in confusione

se ho una stringa che contiene "0xB0" quanti byte sono ?

scusa è un byte, mi son confuso!
Serial.wryte(0xB0);
Serial.write(0x01);
Serial.write(0x7F);
a me funzionano, ide 1.0

Ahhhh

Comunque anche a me funziona
Serial.write(0xB0);

Quello che non funziona è mandare una stringa 'Comando' che contiene 0xB0 cioè
Serial.Write(Comando,HEX) ..... come mi avevi suggerito tu

comando è un array, che viene letto come array di byte, e il numero di elementi da leggere..
per esempio
int a[lunghezza];

Serial.Write(a,lunghezza*sizeof(int));

No .... Comando è una stringa !!

allora dai la lunghezza della stringa in byte... occhio che se parli di Classe Stringa allora devi fare Comando.getCharArray o qualcosa di simile. trovi tutto sul reference

Ho partorito questa cosa ma non funziona :blush:
Invio da vb !!CC!0xB0!0x01!0x7F!*
Mi visualizza solo due byte e se riprovo non visualizza più nulla.

Help please

#include <MIDI.h>

char string[25];
int i=0;
int string_len;
int inByte;
int last_inByte;
int counter=0;

String TipoComando;
String Comando;
String Data1;
String Data2;

void setup() {
  Serial.begin(9600); //INTIALISING THE MIDI SERIAL PORT
  Serial1.begin(9600); //INTIALISING THE CONTROLLER SERIAL PORT
}

// La stringa in arrivo deve avere un ! per ogni lettera e deve terminare con un *
// All'inizio va raddoppiato !! altrimenti perdo la prima lettera
// Esempio !!P!R!O!V!A*

void loop()  // LOOP FUNCTION
{
  inByte = Serial1.read();
  string_len=0;
  if (inByte == '!')  read_serial();  // If Start of line ("!") is found, call read_serial() function
}

void read_serial()  // FUNCTION FOR READING THE SERIAL MESSAGE
{
   Serial.println ("SOL FOUND and reading");  // THE SOL (Start of Line) found notice.
   Serial1.print("READ : !\n");  //Saying that it has read "!" on the serial port
   while (inByte!= '*') // As long as EOL not found, keep reading
   if (Serial1.available() > 0) // if new data is available
     { 
       inByte = Serial1.read(); // Read new byte
       Serial.print("READ : "); // Display the new byte
       string[string_len] = (int)inByte; // Save the data in a character array
       Serial.println(string[string_len]); // Print the characters that was recieved
       string_len++;
     }
     else if (Serial1.available() == 0) 
       {
           Serial.println("EOL not available, data string invalid"); // If EOL not in the string
           Serial1.print("$N"); //FAIL SIGNATURE
           break;
       }

 if (inByte == '*')
{
 Serial1.println ("$Y"); //SUCCESS SIGNATURE
      Comando=((String)string[3]+(String)string[4]+(String)string[5]+(String)string[6]);
      Data1=((String)string[8]+(String)string[9]+(String)string[10]+(String)string[11]);
      Data2=((String)string[13]+(String)string[14]+(String)string[15]+(String)string[16]);

//Serial.println(Comando);
//Serial.println(Data1);
//Serial.println(Data2);

String mystr1;
String mystr2;
String mystr3;

char valcmd[6];
char valdt1[6];
char valdt2[6];

String cmd=Comando;
mystr1=cmd.substring(0,4);
mystr1.toCharArray(valcmd,3);

String dt1=Data1;
mystr2=dt1.substring(0,4);
mystr2.toCharArray(valdt1,3);

String dt2=Data2;
mystr3=dt2.substring(0,4);
mystr3.toCharArray(valdt2,3);

Serial.println(valcmd);
Serial.println(valdt1);
Serial.println(valdt2);

      Serial.write(valcmd);
      Serial.write(valdt1);
      Serial.write(valdt2);
    }
}

Perche se commento tutti i Serial.print (non i Serial1.print !!) il programma non mi manda fuori i valori midi mentre se li decommento si.

Grazie, Alberto

#include <MIDI.h>

char string[25];
int i=0;
int string_len;
int inByte;

String TipoComando;
String Comando;
String Valore;
String Canale;

void setup() {
  MIDI.begin();    
  Serial1.begin(9600); //INTIALISING THE CONTROLLER SERIAL PORT
}

void loop()  // LOOP FUNCTION
{
  inByte = Serial1.read();
  string_len=0;
  if (inByte == '!')  read_serial();  // If Start of line ("!") is found, call read_serial() function
}

void read_serial()  // FUNCTION FOR READING THE SERIAL MESSAGE
{
//   Serial.println ("SOL FOUND and reading");  // THE SOL (Start of Line) found notice.
//   Serial.print("READ : !\n");  //Saying that it has read "!" on the serial port
   while (inByte!= '*') // As long as EOL not found, keep reading
   if (Serial1.available() > 4) // if new data is available
     { 
       inByte = Serial1.read(); // Read new byte
//       Serial.print("READ : "); // Display the new byte
       string[string_len] = (int)inByte; // Save the data in a character array
//       Serial.println(string[string_len]); // Print the characters that was recieved
       string_len++;
     }
     else if (Serial1.available() == 0) 
       {
//           Serial.println("EOL not available, data string invalid"); // If EOL not in the string
           Serial1.print("$N"); //FAIL SIGNATURE
           break;
       }

 if (inByte == '*')
{
 Serial1.println ("$Y"); //SUCCESS SIGNATURE
      TipoComando=((String)string[0]+(String)string[1]);
      Comando=((String)string[3]+(String)string[4]+(String)string[5]);
      Valore=((String)string[7]+(String)string[8]+(String)string[9]);
      Canale=((String)string[11]+(String)string[12]+(String)string[13]);

//      Serial.println(Comando);
//      Serial.println(Valore);
//      Serial.println(Canale);
      MIDI.sendControlChange(Comando.toInt(),Valore.toInt(),Canale.toInt());
   }
}