Usare delle stringhe per accendere un LED

Ciao,
sto cercando di pilotare un led via bluetooth.
Per testare un po' il codice per convertire le stringhe ricevute ho notato che non riesco a spegnere il led una volta acceso.
Ho aggiunto qualche Serial.print per cercare di capire dove si ferma il codice ma nonostante questo non riesco a trovare l'errore.
Sapete dirmi dove sbaglio?
L'ho testato senza successo su circuit di thinkercad (come detto sopra si accende il led ma non si spegne).
Questo è quello che ottengo nel monitor seriale:

bulb
start
HIGH

bulb
HIGH

bulb
HIGH
...

mentre questo è il codice dello sketch:

int LED = 13;
char Mystring[50] = "bulb,start";
char strings[2][10] = {0};
char * token;

void setup()
{
  Serial.begin(9600);
  Serial.println();
  pinMode(LED, OUTPUT);
		digitalWrite(LED, LOW);
		creazioneArray();
}

void loop()
{
		//nothing to do
}

void creazioneArray(){
  byte index = 0;
  token = strtok(Mystring, ",");
  while (token != NULL )
  {
    strcpy(strings[index], token);
    Serial.println( strings[index] );
    index++;
    token = strtok(NULL, ",");
  }

		if (String(strings[0]) == "bulb"){
		checkBulbArray();
	}
	else if (String(strings[0]) == "drop"){
		Serial.println("error #001");
	}
	else {
		Serial.println("error #002");
	}
}


void checkBulbArray(){
	if (String(strings[1]) == "start"){
		//LED ON
		Serial.println("HIGH");
		digitalWrite(LED, HIGH);
		delay(1000);
		char Mystring[50] = "bulb,stop";
		creazioneArray();
	}
	else if (String(strings[1]) == "stop"){
		//LED OFF
		Serial.println("LOW");
		digitalWrite(LED, LOW);
		delay(1000);
		char Mystring[50] = "bulb,start";
		creazioneArray();
	} else{
		Serial.println("error #003");
	}
}

Grazie in anticipo

Per semplificarti la vista ti segnalo la libreria SerialCmd che sicuramente rende molto più facile la cosa ... :wink:

Il thread sul forum, relativo a detta libreria, è QUI, su GitHub la trovi QUI e, naturalmente, la puoi installare direttamente dal "Library Manager". Consiglio un'attenta lettura del "readme" che l'accompagna e degli esempi :wink:

Guglielmo

1 Like

Ciao e grazie per la risposta.
Con quella libreria potrei usare anche dei comandi precompilati in delle variabili?

String prova = "avvia";
...
mySerCmd.AddCmd ( prova , SERIALCMD_FROMALL, set_NLBL );

quanto detto da Guglielmo è verissimo...libreria molto bella... come sempre tocca studiare un poco...resta da chiarire cosa "non va" in quel che hai fatto.
prova a mettere in stampa il registro a cui punta il puntatore "token" (quindi il valore di "token")...intendo per ogni chiamata di strtok()...se intuisco come hai ragionato pensi che la funzione creazioneArray() consideri la variabile Mystring globale o locale a seconda di dove la invochi...prova e facci sapere.

PS: fare attenzione con la riccorsione delle funzioni...rischi di farti "male".

Ho aggiunto un Serial.print(token) subito dopo a
token=strtok(NULL, ",");
Il risultato è

bulb
start
start

HIGH
bulb

HIGH
bulb

HIGH
bulb
....

Purché siano stringhe classiche del 'C' (char array) e NON oggetti della classe String (che abbiamo detto molte volte di NON usare per i problemi che può creare).

Guglielmo

  1. quello che stampi a video mi pare poco utile. aggiungi info:
    Invece del solo Serial.println( strings[index] );
    metti:
    Serial.print(index); Serial.print("="); Serial.println( strings[index] );

  2. un pò usi le funzioni strxxx delle stringhe classiche del C e poi String.
    Questo if(String(strings[1]) == "stop")
    meglio se usi strcmp() if( strcmp(strings[1],"stop")==0)

  3. Hai già dichiarato in testa la programma Mystring da 50 caratteri. Ed è globale. Poi per fare le ulterioriori prove in checkBulbArray() ridichiari la Mystring (locale poi). Non ha senso.
    Dentro la checkBulbArray() devi solo riassegnare i valori, quindi
    sostituisci: char Mystring[50] = "bulb,stop";
    con: strcpy(Mystring,"bulb,stop");

Funziona, ma è una brutta cosa da fare....
if (strcmp(strings[0], "bulb") == 0) fa la stessa cosa, ma non chiama in causa il costruttore String che è inutile visto che stai usando tutti char array.

Questo invece cosa vorrebbe fare? Se pensi di modificare la variabile globale Mystring in questo modo sei completamente fuori strada: stai semplicemente creando un nuovo char array locale che non ha nulla a che vedere con il primo usato invece nella funzione creazioneArray()

Edit.
Mi sono sovrapposto a @nid69ita

ok, grazie ai vostri suggerimenti ho risolto il problema.
Forse è meglio se invece di usare le stringhe utilizzi dei numeri...in questo modo oltre ad essere più semplice potrei usare anche degli switch e non solo degli if...comunque per correttezza indico il codice corretto, non si sa mai che serva ad altri.

int LED = 13;
char Mystring[50] = "bulb,start";
char strings[2][10] = {0};
char * token;

void setup()
{
  Serial.begin(9600);
  Serial.println();
  pinMode(LED, OUTPUT);
		digitalWrite(LED, LOW);
		creazioneArray();
}

void loop()
{
		//nothing to do
}

void creazioneArray(){
    Serial.print("Mystring: ");
	Serial.println(Mystring);
	byte index = 0;
  token = strtok(Mystring, ",");
  while (token != NULL )
  {
    strcpy(strings[index], token);
    Serial.print("index");
    Serial.print(" = ");
    Serial.println(strings[index]);
    index++;
    token = strtok(NULL, ",");
  }

		if (strcmp(strings[0], "bulb") == 0){
		checkBulbArray();
	}
	else {
		Serial.println("error #002");
	}
}


void checkBulbArray(){
  if (strcmp(strings[1], "start") == 0){
		//LED ON
		Serial.println("LED HIGH");
		digitalWrite(LED, HIGH);
		delay(1000);
		strcpy(Mystring, "bulb,stop");
   		 Serial.print("nuovo Mystring: ");
		Serial.println(Mystring);
		Serial.println("***********");
		creazioneArray();
	}
	else if (strcmp(strings[1], "stop") == 0){
		//LED OFF
		Serial.println("LED LOW");
		digitalWrite(LED, LOW);
		delay(1000);
		strcpy(Mystring, "bulb,start");
   		Serial.print("nuovo Mystring: ");
		Serial.println(Mystring);
		Serial.println("***********");
		creazioneArray();
	}
}

Nell'IDE di Arduino usa CTRL+T (formattazione automatica) che ti indenta in automatico il codice e lo rende più leggibile.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.