#include <Servo.h>
Servo servo;
String posProgSe; //posizione programmata tramite seriale
int posEff = 0; //posizione effettiva
char lista;
String t;
int temp = 10;
void velocita();
void movservoAv();
void movservoInd();
void menu();
void stampa();
void setup()
{
servo.attach(9);
Serial.begin(9600);
servo.write(0);
menu();
}
void loop()
{
}
void menu()
{
Serial.print("Seleziona a-b-c-d:");
while (1) {
if (Serial.available() > 0)
{
lista = Serial.read();
Serial.println(lista);
}
switch (lista)
{
case 'a':
velocita();
break;
case 'b':
movservoAv();
break;
case 'c':
movservoInd();
break;
case 'd' :
stampa();
break;
}
}
}
void velocita()
{
//Serial.println(temp);
Serial.print("sono dentro");
t = Serial.readString();
temp = t.toInt();
Serial.println("esco");
menu();
}
void movservoInd()
{
posProgSe = Serial.readString(); //leggo la stringa dalla seriale
int posProg = posProgSe.toInt(); //creo una variabile in cui immetto i valori letti dalla seriale convertiti in INT
Serial.print(posProg);
Serial.println("°");
if (posProg < posEff)
{
for (int x = posEff; x >= posProg; x--)
{
servo.write(x);
delay(10);
posEff = posProg;
}
} menu();
}
void movservoAv()
{
posProgSe = Serial.readString(); //leggo la stringa dalla seriale
int posProg = posProgSe.toInt(); //creo una variabile in cui immetto i valori letti dalla seriale convertiti in INT
Serial.print(posProg);
Serial.println("°");
if (posProg > posEff)
{
for (int x = posEff; x <= posProg; x++)
{
servo.write(x);
delay(10);
posEff = posProg;
}
} menu();
}
void stampa()
{
Serial.println("prova");
delay(10);
menu();
}
Volevo creare un menu da gestire direttamente da seriale, però ho riscontrato un problema con le funzioni: velocita, movservoAv, movservoInd.In pratica appena le richiamo attraverso la funzione "menu()" tramite uno swithc, eseguono le istruzioni in loop continuo e anche quando ritorno al "menu()" quest'ultime continuano a venire eseguite e non permetto di passare ad altre funzioni.Ho voluto aggiungere alla fine una funzione semplice che non implementasse il "Serial.read" e con questa "stampa()" il problema non si pone.Ho fatto diversi tentativi ma niente, non capisco come uscire o meglio fermare l'esecuzione di queste funzioni.Grazie in anticipo per l'aiuto.
Grazie per la risposta, ho provato ma niente, se non metto "menu()" non esce più rimane dentro e continua ad eseguire il codice in loop, senza possibilità di cambiare funzione...
#include <Servo.h>
Servo servo;
String posProgSe; //posizione programmata tramite seriale
int posEff = 0; //posizione effettiva
char lista;
String t;
int temp = 10;
int led1 = 10;
int led2 = 11;
void velocita();
void movservoAv();
void movservoInd();
void menu();
void stampa();
void ledBlink();
void ledFade();
void setup()
{
servo.attach(9);
Serial.begin(9600);
servo.write(0);
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
Serial.print("Seleziona a-b-c-d-e-f:");
}
void loop()
{
menu();
}
void menu()
{
if (Serial.available() > 0)
{
lista = Serial.read();
Serial.println(lista);
}
switch (lista)
{
case 'a':
velocita();
break;
case 'b':
movservoAv();
break;
case 'c':
movservoInd();
break;
case 'd' :
stampa();
break;
case 'e' :
ledBlink();
break;
case 'f' :
ledFade();
break;
}
}
void velocita()
{
//Serial.println(temp);
Serial.print("sono dentro");
t = Serial.readString();
temp = t.toInt();
Serial.println("esco");
menu();
}
void movservoInd()
{
posProgSe = Serial.readString(); //leggo la stringa dalla seriale
int posProg = posProgSe.toInt(); //creo una variabile in cui immetto i valori letti dalla seriale convertiti in INT
Serial.print(posProg);
Serial.println("°");
if (posProg < posEff)
{
for (int x = posEff; x >= posProg; x--)
{
servo.write(x);
delay(10);
posEff = posProg;
}
} Serial.print("ma che");
}
void movservoAv()
{
posProgSe = Serial.readString(); //leggo la stringa dalla seriale
int posProg = posProgSe.toInt(); //creo una variabile in cui immetto i valori letti dalla seriale convertiti in INT
Serial.print(posProg);
Serial.println("°");
if (posProg > posEff)
{
for (int x = posEff; x <= posProg; x++)
{
servo.write(x);
delay(10);
posEff = posProg;
}
}
}
void stampa()
{
Serial.println("prova");
delay(10);
menu();
}
void ledBlink()
{
for(int i = 0;i <= 10; i++)
{
digitalWrite(led1, 1);
delay(1000);
digitalWrite(led1, 0);
delay(1000);
};
menu();
}
void ledFade()
{
for (int i = 0; i <= 255; i++)
{
analogWrite(led2, i);
delay(20);
}
for (int i = 255; i >= 0; i--)
{
analogWrite(led2, i);
delay(20);
}
menu();
}
Ho aggiunto altre funzioni e come per la funzione "stampa()" non ci sono problemi, appena finisce l'esecuzione torna nella funzione "menu()" grazie al richiamo di quest'ultimo, senza rimane bloccato nella funzione, ma il problema rimane per le altre funzioni in cui è implicato Serial.read() a quanto pare bisogna trovare il modo di uscire dal loop che si crea entrando in quelle funzioni, ma non so come...
Ok ma come posso pulire la variabile se continua a restituirmi il valore 0 in loop anche dopo aver inserito un valore, cioè lo spostamento del servo avviene con il valore che inserisco tramite il seriale, ma subito dopo continua a stamparmi il valore 0 e non c'è modo di uscire, anche riuscendo a tornare al menu continua a stampare 0 gradi...
Visto che programmi robot di movimentazione prova a immaginare come lo faresti con un robot
Giusta regola, e qui cambio discorso, io quando ho imparato a programmare robot di saldatura e di movimentazione sapevo già programmare in generale
Ma comunque saper programmare dovrebbe essere quasi universale
Come faresti, e qui torno a bomba, a far eseguire l'azione al robot una volta sola anche se, per esempio il micro di avvio rimanesse impegnato?
Ah, per chi se lo chiedesse...
Quando ero roboticista io non programmavo robot, insegnavo a programmarli...
Senza gli string non muovo il servo, dunque mi servono e torna intendo richiamare il menu non tornare il risultato di una funzione, cmq senza richiamare la funzione si ferma senza fare più nulla e ho provato vari modi per svuotare il buffer ma non c'è modo continua ad andare in loop...il problema è come posso interrompere momentaneamente il Serial.read??? perchè da come si comporta sembra che continui a richiamare la lettura della seriale...e ripeto questo problema si manifesta solo con le funzioni che implicano serial.read, nelle altre funziona perfettamente...
sinceramente non capisco perchè non fai quanto suggerito...che ti risolverebbe il problema...ed intendo il post #2 ed il post #4 (ribadito al post #8).
void menu()
{
Serial.print("Seleziona a-b-c-d:");
while (1) {
lista = 0; // azzera la variabile lista
if (Serial.available() > 0)
{
lista = Serial.read();
Serial.println(lista);
}
Rimuovi le chiamate ricorsive alla funzione menu().
Oppure se non ti serve che lista sia globale la dichiari locale al posto dell'azzeramento di lista.
#include <Servo.h>
Servo servo;
//String posProgSe; //posizione programmata tramite seriale
//int posEff = 0; //posizione effettiva
char lista;
int temp;
int led1 = 10;
int led2 = 11;
void velocita();
void movservoAv();
void movservoInd();
void menu();
void stampa();
void ledBlink();
void ledFade();
void setup()
{
servo.attach(9);
Serial.begin(9600);
servo.write(0);
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
Serial.print("Seleziona a-b-c-d-e-f:");
}
void loop()
{
menu();
}
void menu()
{
if (Serial.available() > 0)
{
lista = Serial.read();
Serial.println(lista);
}
switch (lista)
{
case 'a':
velocita();
break;
case 'b':
movservoAv();
break;
case 'c':
movservoInd();
break;
case 'd' :
stampa();
break;
case 'e' :
ledBlink();
break;
case 'f' :
ledFade();
break;
}
}
void velocita()
{
temp = 0;
delay(100);
if(Serial.available() > 0)
{
temp = Serial.read();
lista = " ";
}
}
void movservoInd()
{
lista = " ";
}
void movservoAv()
{
lista = " ";
}
void stampa()
{
Serial.println("prova");
delay(10);
lista = " ";
}
void ledBlink()
{
for(int i = 0;i <= 10; i++)
{
digitalWrite(led1, 1);
delay(1000);
digitalWrite(led1, 0);
delay(1000);
}
lista = " ";
}
void ledFade()
{
for (int i = 0; i <= 255; i++)
{
analogWrite(led2, i);
delay(20);
}
for (int i = 255; i >= 0; i--)
{
analogWrite(led2, i);
delay(20);
}
lista = " ";
}
Ho rimosso tutte le chiamate alla funzione "menu()" e ora va meglio,però ancora non ho trovato un modo per inserire dei valori tramite seriale per gestire i gradi del servo e anche il settaggio della velocità, dovrei trovare un modo di mappare il valore restituito dalla seriale, oltre a trovare il modo di non fargli interpretare come valore, il carattere che invio per eseguire la funzione.
Inoltre ho cercato altri modi per gestire un servo, ma per ora non sono riuscito a farli funzionare correttamente.
#include <Servo.h>
Servo servo;
char valo[4]; //creo un vettore 3 per gli elementi da iserire e 1 per il carattere di ritorno
int i = 0;
int pos;
void setup() {
servo.attach(9);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) { //se il seriale è disponibile
char ch = Serial.read(); //utilizzo una variabile per leggere i caratteri dalla seriale
if (i < 3 && ch >= '0' && ch <= '9') { //se la variabile i è minore di 3 e la variabile "read" è minore di 0 e maggiore di 9, se rimane all'interno del range di caratteri da 0 a 9
valo[i++]=ch; //carico nel mio vettore i valori letti dalla variabile "read "
}
else { //una volta che la variabile 'i' a superato il valore 3 e rispettato il range esce da if ed entra in "else".
valo[i] = 0; //resetta il vettore
pos = atoi(valo); // con la funzione atoi converto la stringa in un intero
i = 0; //resetto la variabile
}
Serial.print(ch);
}
servo.write(pos);
}
Ho trovato questo esempio, per creare una stringa di array char e convertire poi in int,quello che non capisco è quel "reset" al vettore prima di riversarlo nella variabile "pos" ?