Ciao a tutti!
Ho un problema per quanto riguarda la porta seriale di arduino. Ho fatto un programma che dovrebbe, tramite due comandi seriali, accendere due led e farli lampeggiare( uno con il millis e uno no), il problema è che non riesco a capire perchè mi lampeggia un led solo per volta mentre io li vorrei in contemporanea. posto il codice e ringrazio per un eventuale risposta.
if (Serial.available() > 0)
{
inByte = Serial.read();
stato = inByte;
stato1 = inByte;
}
stato e stato1 sono sempre uguali
dovresti fare una cosa del genere
if (Serial.available() > 0)
{
stato = Serial.read();
delay(2); //giusto per essere sicuro che sia arrivato anche il secondo byte
stato1 = Serial.read();
}
avendo l'accortezza di trasmettere sempre due caratteri alla volta
Ciao ho letto questo post e visto che ho trovato lo stesso problema aggiungo;
ma se non voglio mandare due caratteri per volta come posso risolvere???
fidelpoli2 ha la necessita di usare solo 2 uscite ma se ne volessi usare 10 come posso fare?
La mia idea sarebbe quella di gestirle tipo interrupt mi spiego non è possibile con arduino una volta entrata in un if lo continui a fare all'infinito fina a che tramite un altro if lo spengo?
Nessuno sa risolvere questo problema?
Ho fatto delle prove anche con i case, ma non riesco a risolvere, una volta entrato nel case mi fa lampeggiare il led solo per un numero di volte e poi si spenge
Grazie
Ti ringrazio per l'aiuto sto diventando pazzo ho letto praticamente tutti i post di questo forum
Sicuramente per i non programmatori come me questo forum è una nave scuola notevolissima e quello che colpisce è che nonostante gran parte delle domande fatte da noi "principianti" siano per un guro sciocche tutti abbiamo sempre le proprie risposte
Un grazie sentito a tutte le persone che con pazzienza portano avanti questo progetto open source
if (Serial.available() > 1)//ci devono essere ALMENO 2 byte disponibili, per più bite basta modificare... e per la lettura usare un'array di stati e un for...
{
stato = Serial.read();
//via il delay!
stato1 = Serial.read();
}
secondo problema:
ochhio che se interval è < del delay succedono casini
consiglio vivamente di imparare a usare i millis, si sprecano molti meno clock
@lesto
è sì, togliere il delay e aspettare di ricevere due caratteri è molto meglio e "un po' " più sicuro
@ARDUIX
il seguente codice dovrebbe gestire 8 uscite in maniera indipendente tramite l'invio di un carattere da seriale. il "dovrebbe" è perché non l'ho testato fisicamente. Le 8 uscite possono avere tempi di accensione e spegnimento anche diversi
// variabili per la gestione delle uscite
const int num_output = 8;
int stato_uscita = 0; // indica se l'uscita n-esima è ON o OFF
int comando_uscita = 0; // indica se l'uscita n-esima è abilitata a lampeggiare
// i seguenti define servono solo a ricordare che l'uscita 1 è mappata sul primo bit, la 2 sul secondo e così via
#define OUT_1 0x01
#define OUT_2 0x02
#define OUT_3 0x04
#define OUT_4 0x08
#define OUT_5 0x10
#define OUT_6 0x20
#define OUT_7 0x40
#define OUT_8 0x80
// permette di utilizzare non necessariamente le prime 8 uscite digitali
int trascodifica_uscite[num_output] = { 4, // OUT_1
5, // OUT_2
7, // OUT_3
10, // OUT_4
9, // OUT_5
11, // OUT_6
12, // OUT_7
13}; // OUT_8
// variabili per le tempistiche
unsigned long istante_cambio_stato[num_output];
unsigned long tempo_on[num_output] = {200, // OUT_1
200, // OUT_2
200, // OUT_3
200, // OUT_4
200, // OUT_5
200, // OUT_6
200, // OUT_7
200}; // OUT_8
unsigned long tempo_off[num_output] = {200, // OUT_1
200, // OUT_2
200, // OUT_3
200, // OUT_4
200, // OUT_5
200, // OUT_6
200, // OUT_7
200}; // OUT_8
// variabili relative alla seriale
int serial_rx;
// elenco dei comandi
// i comandi per abilitare il blink devono essere consecutivi
#define BLINK_OUT_1 int('a')
#define BLINK_OUT_2 int('b')
#define BLINK_OUT_3 int('c')
#define BLINK_OUT_4 int('d')
#define BLINK_OUT_5 int('e')
#define BLINK_OUT_6 int('f')
#define BLINK_OUT_7 int('g')
#define BLINK_OUT_8 int('h')
// può esserci un buco tra i comandi di blink e di disabilitazione
// i comandi per disabilitare il blink devono essere consecutivi
#define DISABLE_OUT_1 int('k')
#define DISABLE_OUT_2 int('l')
#define DISABLE_OUT_3 int('m')
#define DISABLE_OUT_4 int('n')
#define DISABLE_OUT_5 int('o')
#define DISABLE_OUT_6 int('p')
#define DISABLE_OUT_7 int('q')
#define DISABLE_OUT_8 int('r')
void gestione_comandi(int serial_rx)
{
if ((serial_rx >= BLINK_OUT_1) && (serial_rx <= BLINK_OUT_8))
{
comando_uscita |= (1 << (serial_rx - BLINK_OUT_1));
}
if ((serial_rx >= DISABLE_OUT_1) && (serial_rx <= DISABLE_OUT_8))
{
comando_uscita &= ~(1 << (serial_rx - DISABLE_OUT_1));
}
}
void gestione_uscite()
{
unsigned long currentMillis = millis();
int i;
for (i = 0; i < num_output - 1; i++)
{
if(comando_uscita & (1 << i))
{
// l'i-esima uscita deve lampeggiare
if (stato_uscita & (1 << i))
{
// l'i-esima uscita è ON
if((currentMillis - istante_cambio_stato[i]) >= tempo_on[i])
{
digitalWrite(trascodifica_uscite[i], LOW);
stato_uscita ^= (1 << i);
istante_cambio_stato[i] = currentMillis;
}
}
else
{
// l'i-esima uscita è OFF
if((currentMillis - istante_cambio_stato[i]) >= tempo_off[i])
{
digitalWrite(trascodifica_uscite[i], HIGH);
stato_uscita ^= (1 << i);
istante_cambio_stato[i] = currentMillis;
}
}
}
else
{
// l'i-esima uscita deve essere disabilitata
digitalWrite(trascodifica_uscite[i], LOW);
}
}
}
void setup()
{
byte i;
for (i = 0; i < num_output - 1; i++)
{
pinMode(trascodifica_uscite[i], OUTPUT);
digitalWrite(trascodifica_uscite[i], LOW);
}
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0)
{
serial_rx = Serial.read();
gestione_comandi(serial_rx);
}
gestione_uscite();
}
Ciao Frog, è 4 giorni che studio sul tuo codice e delle cose le ho capite bene e ti faccio i complimenti perchè io non ci sarei mai arrivato!Però ci sono delle cose che non riesco a capire:
if (stato_uscita & (1 << i)){ // è un puntatore?? (perchè se faccio la moltiplicazione di bit mi da sempre 0 e credo che non abbia significato)
if((currentMillis - istante_cambio_stato) >= tempo_on*)// cosa fa precisamente questo if? ho notato che quando si usa millis questa espressione è ricorrente{ digitalWrite(trascodifica_uscite, LOW); stato_uscita ^= (1 << i);// anche in questo caso mi servono spiegazioni istante_cambio_stato = currentMillis;// questo serve per resettare il millis???} _} else { // stesse cose del pezzo sopra _ if((currentMillis - istante_cambio_stato) >= tempo_off) _{_ digitalWrite(trascodifica_uscite, HIGH); stato_uscita ^= (1 << i); istante_cambio_stato = currentMillis; _} }*_
dunque: if (stato_uscita & (1 << i))controlle se l'i-esimo bit della variabile stato_uscita è uguale a uno
& è l'AND bit-a-bit
<< è l'operatore shift_a_sinistra
if((currentMillis - istante_cambio_stato[i]) >= tempo_on[i])se da quando mi sono acceso (istante_cambio_stato) è passato abbastanza tempo (>= tempo_on) sono pronto a spegnermi digitalWrite(trascodifica_uscite*, LOW). stato_uscita ^= (1 << i);l'i-esimo bit della variabile stato_uscita viene cambiato di valore. (^ è lo XOR bit-a-bit) Si poteva anche fare (in maniere probabilmente più leggibile) stato_uscita &= ~(1 << i); in questa parte di codice e* stato_uscita |= (1 << i); in quella successiva istante_cambio_stato[i] = currentMillis;più che reset direi che è l'aggiornamento della variabile per tenere memoria dell'istante in cui l'uscita è stato accesa/spenta. _*la spiegazione un po' più approfondita dei vari operatori ~, &, ... la trovi sulle reference http://arduino.cc/en/Reference/HomePage*_