Comunicazione seriale RS485 - problema ricezione dati

Salve a tutti,
premetto che non sono ferratissimo di programmazione e cerco di documentarmi il più possibile tramite ricerche su questo forum e su internet ma non ne vengo fuori.

Il progetto attualmente consiste in 2 arduino mega 2560 (master + slave) collegati con schedine per la trasmissione seriale rs 485 (dovrò poi sviluppare una centralina per controllo tempo per gare di tiro con l'arco e ci sarà un controller che invierà un numero e lo stato di un semaforo a dei display led a distanza).

Attualmente lo sketch consistono in:

MASTER:

fa un count down e invia stato semaforo e nuoro (scomposto in cifre) allo slave
comunica anche alla seriale del pc cosa sta inviando cosi da poter verificare se opera correttamente

#define SSerialTxControl 23
#define RS485Transmit    HIGH
#define RS485Receive     LOW

#define Pin13LED         13

char *rosso = "rosso";
char *giallo = "giallo";
char *verde = "verde";

void setup() {
  Serial.begin(19200);
  Serial1.begin(19200);
  pinMode(Pin13LED, OUTPUT);
  pinMode(SSerialTxControl, OUTPUT);
  digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver
  Serial.write("Pronto ad inviare");
}



void loop() {

  for (int n = 10; n >= 0; n--) {
    semaforo(rosso);                         // funzione per inviare stato semaforo (led)
    invianumero(n);                          // funzione per inviare numero a slave
    digitalWrite(Pin13LED, RS485Transmit);   // blink led per visualizzare la trasmissione dei dati 
    delay(500);
    digitalWrite(Pin13LED, RS485Receive);
    delay(500);
  }

  for (int n = 120; n >= 0; n--) {          // ciclo identico al precedente cambia la tempistica de count down
    if (n > 30) {
      semaforo(verde);
    } else {
      semaforo(giallo);
    }
    invianumero(n);
    digitalWrite(Pin13LED, RS485Transmit);
    delay(500);
    digitalWrite(Pin13LED, RS485Receive);
    delay(500);
  }
}

void invianumero (int num) {                            
  digitalWrite(SSerialTxControl, RS485Transmit);
  Serial1.write(1);                                   // cumunica allo slave che sta inviando un numero
  String Lnum = (String)num;                          // scompongo il numero in cifre ed invio anche la lunghezza del numero
  byte l = Lnum.length();
  Serial1.write(l);
  if (l == 1) {
    Serial1.write(num);
    Serial.println(num);
  } else  if (l == 2) {
    Serial1.write(num / 10);
    Serial.print(num / 10);
    Serial1.write(num % 10);
    Serial.println(num % 10);
  } else  if (l == 3) {
    Serial1.write(num / 100);
    Serial.print(num / 100);
    Serial1.write((num % 100 - num % 10) / 10);
    Serial.print((num % 100 - num % 10) / 10);
    Serial1.write(num % 10);
    Serial.println(num % 10);
    digitalWrite(SSerialTxControl, RS485Receive);
  }
}

void semaforo (char *colore) {
  digitalWrite(SSerialTxControl, RS485Transmit);
  Serial1.write(2);                                       //comunica allo slave che sto inviando il colore del semaforo
  if (colore == "rosso") {
    Serial1.write(253);
  } else if (colore == "giallo") {
    Serial1.write(252);
  } else if (colore == "verde") {
    Serial1.write(251);
  }
  digitalWrite(SSerialTxControl, RS485Receive);
}

SLAVE:
riceve le istruzioni dal master, accende 3 led (il semaforo) verde giallo e rosso e stampa sul serial monitor il numero ricevuto.

#define SSerialTxControl 23   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW
#define ROSSO            6
#define GIALLO           5
#define VERDE            4
#define BUZ              13

int n = 0;
byte f = 0;
byte a = 0;
byte b = 0;
byte c = 0;
byte lung = 0;

byte trit = 2;

void setup() {
  Serial.begin(19200);
  Serial1.begin(19200);
  pinMode(BUZ, OUTPUT);
  pinMode(VERDE, OUTPUT);
  pinMode(GIALLO, OUTPUT);
  pinMode(ROSSO, OUTPUT);
  pinMode(SSerialTxControl, OUTPUT);
  digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver


}

void loop() {
  while (!Serial1.available()) {      //attendo comunicazione da master
  }
  f = Serial1.read();                 //prima byte che ricevo è la funzione da fare

  if (f == 1) {

    numero();
  }
  if (f == 2) {
    while (!Serial1.available()) {
    }
    byte col = Serial1.read();        //invio secondo byte che identifica il colore
    semaforo (col);
  }
}


void numero() {                         // funzione che ricere lunghezza e i 3 byte e ricompone il numero
  a = 0;
  b = 0;
  c = 0;
  lung = 0;
  while (!Serial1.available()) {
  }
  lung = Serial1.read();

  if (lung == 1) {
    while (!Serial1.available()) {
    }
    c = Serial1.read();
  }
  if (lung == 2) {
    while (!Serial1.available()) {
    }
    b = Serial1.read();
    while (!Serial1.available()) {
    }
    c = Serial1.read();
  }
  if (lung == 3) {
    while (!Serial1.available()) {
    }
    a = Serial1.read();
    while (!Serial1.available()) {
    }
    b = Serial1.read(); 
    while (!Serial1.available()) {
    }
    c = Serial1.read();
  }

  n = a * 100 + b * 10 + c;
  Serial.print(lung);
  Serial.print(a);
  Serial.print(b);
  Serial.println(c);
  Serial.println(n);
}


void semaforo (byte sem) {
  f = 0;
  if (sem == 253) {
    digitalWrite(ROSSO, HIGH);
    digitalWrite(VERDE, LOW);
    digitalWrite(GIALLO, LOW);
  } else    if (sem == 252) {
    digitalWrite(GIALLO, HIGH);
    digitalWrite(VERDE, LOW);
    digitalWrite(ROSSO, LOW);
  } else    if (sem == 251) {
    digitalWrite(VERDE, HIGH);
    digitalWrite(GIALLO, LOW);
    digitalWrite(ROSSO, LOW);
  } else    if (sem == 250) {
    digitalWrite(VERDE, LOW);
    digitalWrite(GIALLO, LOW);
    digitalWrite(ROSSO, LOW);
  }
}

Funziona a dovere per i numeri da 0 a 99 ma da 100 in su non capisco il motivo che non modifica lo stato del led e non scrive alcun numero.

Ho provato a mettere delay tra i vari byte inviati ma peggiora la situazione e a modificare la velocità di trasmissione ma niente.

Qualcuno sa aiutarmi o consigliarmi un protocollo di comunicazione per stramettere dati tra master e slave?
Ho visto il MODBUS ma non capisco se fa al mio caso.

Grazie

ciao...ho dato un'occhiata veloce...come suggerito più volte dovresti evitare la classe String in quanto porta a sicuri problemi...che poi nella funzione "invianumero" usi solo per capire se il numero ha 1, 2 o 3 cifre...fare un:

if(num>=0 && num<10)...
else if (>=10 && num<100)...
etc

Poi...non vorrei aver visto male ma non vedo alcun controllo del pacchetto dati inviato dal Master allo Slave...tipo un carattere di inizio ed uno di fine messaggio...un checksum un CRC etc.

se non ho capito male cosa vuoi fare tu il modbus è "esagerato"...però è bello che pronto..cioè ci sono librerie per master e slave...che fanno tutti i controlli del caso e ritornano tutte le info se processo ok o se si è verificato un problema ...tocca però capire il modbus (abbastanza semplice in verità) e studiare la libreria che utilizzerai.

diversamente devi farti tu un protoccolo per gestire l'invio dati...come detto basta anche un carattere di inizio ed uno di fine flusso dati...un checksum per controllo qualità dati...poi l'ordine dei byte che invii lo sai tu e lo gestisci.

Grazie per il consiglio, di solito mi complico la vita quando le cose sono semplici...
Non ho capito di preciso dove stesse il problema, ma penso in questo punto qui nel codice del master in qui al'interno dell' if mettevo in ricezione come visto su un tutorial a fine trasmissione:

  } else  if (l == 3) {
    Serial1.write(num / 100);
    Serial.print(num / 100);
    Serial1.write((num % 100 - num % 10) / 10);
    Serial.print((num % 100 - num % 10) / 10);
    Serial1.write(num % 10);
    Serial.println(num % 10);
    digitalWrite(SSerialTxControl, RS485Receive);
  }

ho risolto mettendo sempre in trasmissione il master in quanto dovrà solo trasmettere.

Ho dato una sguardo veloce al MODBUS ma devo veramente far comunicare un numero e un colore dal master allo slave quindi preferisco per quanto incompleto possa essere il mio protocollo di trasmissione di scriverlo o almeno provarci!!
terrò in considerazione l'aggiunta di un inizio trasmissione e una fine anche se il codice non sarà molto più di quello postato se non che al posto di accendere un del accenderò una striscia di le ws2812b.

Grazie per il consigli[/code]