Un'aiutino sul codice

Mi date una mano a risolvere questa cosa ?

Invio una serie dei dati sulla seriale.

Formo una stringa così:
M11
cioè
M = Motore
1 è l’id motore che va a 1 a 20
1 è lo stato che può essere 0,1,2 (0=Deselezionato 1=Salita 2=Discesa)

** Un problema lo ho con l’id motore che non riesco a far diventare 01,02 per fissare la lunghezza del dato

I dati li leggo così:

 if (mySerial.available()) {
    bytesread = 0; 
    while(bytesread<3) // read 3 digit code
    {
      val = mySerial.read();
      code[bytesread] = val; // add the digit
      bytesread++; // ready to read next digit
      Serial.println(code);
    }
  }

come posso scomporre e controllare questa stringa ?

Grazie, Alberto

Ciao, non riesco a capire la tua domanda. La stringa se la leggi cosi' e' gia' scomposta, otterresti dentro code[0] M dentro code[1] e code[2] 1 e 1, se il dato che invii e' M11. In realta' se la lunghezza del dato e' fissa potresti anche leggere direttamente i dati in variabili utili...

 if (Serial.available()>=3) {
    char cmd,apparato,stato;
    cmd=Serial.read();
    apparato=Serial.read();
    stato=Serial.read();
}

dunque, per il problema dell’id, se non erro ce l’hai all’invio del dato. probabilmente ce l’hai in int, giusto? la soluzione è semplice:
if (id < 10)
serial.print(“0”);

a questo punto in ricezioni hai 4 byte (es m012)
ricezione come detto da federico, ma con id e stato ritrasformati in int:
if (Serial.available()>=4) {
char cmd;
int apparato,stato;
cmd=Serial.read();
apparato=( Serial.read() -‘0’)*10+Serial.read() -‘0’;
stato=Serial.read()-‘0’;
}

Grazie per l'aiuto ad entrambi.

Alberto

Perchè questo codice non passa sulla seriale

      switch (ArmedMotor[CurrentMotor]) {
        case 0: //Disattivato mando in salita
          mySerial.print(char('M'));
          mySerial.print(int(CurrentMotor));
          mySerial.print(int(1));
          (ArmedMotor[CurrentMotor] = 1);
          break;
        case 1: //Salita mando in discesa
          mySerial.print(char('M'));
          mySerial.print(int(CurrentMotor));
          mySerial.print(int(2));
          (ArmedMotor[CurrentMotor] = 2);
          break;
        case 2: //Discesa mando a disattivato
          mySerial.print(char('M'));
          mySerial.print(int(CurrentMotor));
          mySerial.print(int(0));
          (ArmedMotor[CurrentMotor] = 0);
          break;
      }

leggendolo con questo codice

  if (mySerial.available()>=3) {
      char cmd,apparato,stato;
      cmd=mySerial.read();
      apparato=mySerial.read();
      stato=mySerial.read();
      
      Serial.println(cmd);
      Serial.println(apparato);
      Serial.println(stato);  
    }

Credo tu debba passare char sulla seriale. Cosa ottieni? La M la leggi?

Non vedo nulla

Ho provato con questo semplice codice ma non esce quello mandato.
Uso la NewSoftSerial come libreria

Su arduino UNO come writer:

#include <NewSoftSerial.h>

#define rxPin 6
#define txPin 7

NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);

void setup()  {
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  mySerial.begin(4800);
}

void loop() {
  mySerial.print("1234");
  delay(100);
}

Su arduino MEGA come reader:

#include <NewSoftSerial.h>

#define rxPin 6
#define txPin 7

int  val = 0; 
char code[4]; 
int bytesread = 0;

NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);

void setup()  {
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  mySerial.begin(4800);
  Serial.begin(9600);
}

void loop() {
  bytesread = 0; 
   
 if (mySerial.available()<=4) {
    val = mySerial.read();
    code[bytesread] = val; // add the digit
    bytesread++; // ready to read next digit
    Serial.println(code);
  }
}

Ma mi esce sempre anche se scollego i fili alla seriale

ÿ
ÿ
ÿ
ÿ

pèerchè sul mega usi la softserial? il mega ha già di suo 4 seriali se non erro...

Perchè sul mega dovro collegare 40 relè ed volevo scegliere io che pin destinare alla seriale. Poi il serial.available funziona solo sulla NewSoftSerial.

non è un grosso problema avaiable, in caso read ritorna -1
comunue, sucuro di aver collegato tx con rx e rx con tx?

ah e togli if (mySerial.available()<=4) che se pre caso nel frattempo che scrivi al pc arrivano più di 4 byte poi il loop() rimane “congelato”

lesto:
non è un grosso problema avaiable, in caso read ritorna -1

Come faccio a gestirlo ?

comunue, sucuro di aver collegato tx con rx e rx con tx?

Si

ah e togli if (mySerial.available()<=4) che se pre caso nel frattempo che scrivi al pc arrivano più di 4 byte poi il loop() rimane “congelato”

Se tolgo la if mi mostra caratteri strani.

NewSoftSerial non è compatibile con la MEGA!!

Ma banalmente 40 rele' si gestiscono con 5 74hc595 e 3 pin di arduino!

Federico: Ma banalmente 40 rele' si gestiscono con 5 74hc595 e 3 pin di arduino!

Dai ....... mi indicheresti qualche schemino ?

Perchè se invio "CIAO" sul ricevente vedo: C I IA IAO IAOC IAOC IAOC ...

con questo codice ? void loop() { bytesread=0; while (mySerial.available()>=4) { val = mySerial.read(); code[bytesread] = val; // add the digit bytesread++; // ready to read next digit Serial.println(code); } }

o prima leggi l'array di char e metti uno '\0' finale (carattere di fine stringa)

void loop() {
  bytesread=0;
  while (mySerial.available()>=4) {
    val = mySerial.read();
    code[bytesread] = val; // add the digit
    bytesread++; // ready to read next digit
  }
  code[bytesread]='\0';
  Serial.println(code);
}

oppure leggi lettera per lettera e poi la stampi.

while (mySerial.available()>=4) {
    val = mySerial.read();
    Serial.println(val);
  }

Come faccio a unire due char ?

se dalla seriale mi arrivano 4 char dove: il primo è M Il secondo 0 il terzo è 1 il quarto è 2

e voglio unire il secondo con il terzo come faccio ?

  char cmd,apparato,stato;
  val = mySerial.read();
  code[bytesread] = val; // add the digit
  bytesread++;           // ready to read next digit
  if (bytesread == 4){
    Serial.println(code);
    cmd=code[1];

    apparato = ?

    stato=code[4];
    Serial.print(cmd);
    Serial.print(apparato);
    Serial.println(stato);  
    bytesread = 0;
}

Grazie, Alberto

char apparato[3]; apparato[0]=code[2]; apparato[1]=code[3]; apparato[2]='\0';//carattere di fine stringa

Ok.

Ma per visualizzarlo ed eventualmente convertirlo in intero :grin:

Grazie, Alberto

per visualizzarlo come hai fatto tu con serial ti va bene tenerlo array char, per la conversione in intero esiste la funzione atoi()

Scusa ma mi perdo facilmente.

Se in apparato[1] ho un char 0 apparato[2] ho un char 1

come faccio ad avere ina variabile intera che coniene il valore 1 con atoi?

int valore = (atoi(apparato[1])+atoi([apparato[2]));