Go Down

Topic: Arduino ShiftOut tramite porta seriale - Help! (Read 1 time) previous topic - next topic

toti94

Scusate ragazzi ho un problema con questo codice, praticamente io gli invio una serie tipo "0b00110011" tramite php ad arduino,
però praticamente, quando invio il messaggio, i led si spengono, si accendono 3 led (che non corrispondono al messaggio) e poi si riaccendono tutti i led e rimangono così fin quando non invio dell'altro.
Ma come is fa a fargli cambiare stato solo quando invio qualcosa tramite seriale?
questo è il codice:
Code: [Select]
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
   Serial.begin(9600);
}

void loop() {
  if (Serial.read())
  {
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, Serial.read()); 
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
    delay(500);
  }
}

uwefed

Usi in modo errato la funzione serial read.

1) non controlli se ci sono dati nel buffer della seriale
2) leggi un dato del buffer e poi mandi al shift register un altro dato letto nel secondo serial read.

devi controllare se sono dati disponibili nel buffer (con serial.aviable()) e poi leggere il dato e mandarlo sul 595.
http://arduino.cc/en/Serial/Available

Ciao Uwe



leo72

In pratica l'errore è qui:
Code: [Select]
if (Serial.read())
Questo dice di estrarre un carattere dalla seriale, non di controllare se c'è un carattere e basta. Quindi come ti ha spiegato Uwe il primo carattere che arriva lo perdi per strada perché esso non viene assegnato a nessuna variabile ma usato come test per l'if.


toti94

Ma cmq vedo un comportamento anomalo XD
mi spiego,
io invio la serie di bit
ad esempio con 0b10000001 si accendono due led (che non mi sembrano il 1° e l'ultimo) mentre 2 led rimangono accesi sempre, dopo mezzo secondo di delay torna tutto spento tranne i due led perenni, invece senza delay i led che comando si accendono e si spengono così velocemente che quasi non si vedono e i due led perenni continuano ad essere accesi.
Potreste darmi un aiuto? xD

uwefed

Dacci il Sketch da te modificato.
Ciao Uwe

toti94

Code: [Select]
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
   Serial.begin(9600);
}

void loop() {
  if (Serial.available())
  {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, Serial.read()); 
    digitalWrite(latchPin, HIGH);
    // non credo serva il delay, dato che aspetta un altro valore
    // delay(500);
  }
}

leo72

Inizia con un pò di debug altrimenti non riuscirai ad isolare il problema.
Cioè, cerchiamo di capire se il dato arriva corretto ma viene scritto male oppure non arriva per niente.

Quindi modifica il loop() così:
Code: [Select]
void loop() {
  if (Serial.available()) {
    digitalWrite(latchPin, LOW);
    byte temp = Serial.read();
    Serial.println(temp); //eco per vedere cos'è stato ricevuto
    shiftOut(dataPin, clockPin, MSBFIRST, temp); 
    digitalWrite(latchPin, HIGH);
  }
}

toti94

#8
May 24, 2013, 07:41 pm Last Edit: May 24, 2013, 07:45 pm by toti94 Reason: 1
si penso che sia un problema di come invia la variabile .
io ho inviato "0b10000001" e sul monitor seriale mi ha stampato
Code: [Select]
48
98
49
48
48
48
48
48
48
49

è normale? XD
Inoltre comunque i led 5 e 6 rimangono sempre accesi, sarà un problema di arduino? c'è un modo per spegnerli?

leo72

Se hai spedito "0b10000001" con Serial.print è normale. La Serial ha trattato il dato come stringa per cui l'ha spedita byte per byte, e quelli che vedi sono i codici ASCII dei singoli caratteri che componevano quella stringa.

Devi usare
Code: [Select]
Serial.write(0b10000001)
e ti verrà spedito il byte corrispondente a quel valore.

toti94

si ora sul monitor esce esattamente ciò che scrito, ovvero "0b10000001", ma arduino non cambia comportamento

leo72


toti94

Code: [Select]
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
   Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    digitalWrite(latchPin, LOW);
    byte temp = Serial.read();
    Serial.write(temp); //eco per vedere cos'è stato ricevuto
    shiftOut(dataPin, clockPin, MSBFIRST, temp); 
    digitalWrite(latchPin, HIGH);
  }
}

leo72

Ma "come" vengono spediti questi dati?
Se non spedisci in formato byte, siamo punto e a capo. ;)

toti94

io scrivo 0bxxxxxxxx questo non è il formato byte?

Go Up