Vai al contenuto
PLC Forum


cambio scena con 1 pulsante centralina giochi di luce


lga83

Messaggi consigliati

salve a tutti, sto realizzando una centralina che mi genera giochi di luce con dei led, ho fatto il programma per il gioco e anche un potenziometro che mi vara la velocità dei del singolo gioco, ora con il pulsante quando premuto voglio far cambiare gioco di luce il problema e che per cambiare lo devo tenere premuto a lungo e a me non piace, posto lo sketch mi potete indicare dove sbaglio, grazie anticipatamente..

    int puls=12;
    int val=0;
    int contatore=0;
    int i = 0;


    void setup () {
    DDRD=B11111111;
    pinMode(puls,INPUT);
    }

    void loop () {
    val=digitalRead(puls);
    if (val==1){
    contatore=contatore +1;

    }


    for (i = 0; i < 5; i++)
    if (contatore==1) {
    PORTD = B10000001;
    delay(analogRead(0));
    PORTD = B11000011;
    delay(analogRead(0));
    PORTD = B10100101;
    delay(analogRead(0));
    PORTD = B10011001;
    delay(analogRead(0));
    PORTD = B10100101;
    delay(analogRead(0));
    PORTD = B11000011;
    delay(analogRead(0));


    }


    for (i = 0; i < 5; i++)
    if (contatore==2) {
    PORTD = B11111111;
    delay(analogRead(0));
    PORTD = B11111111;
    delay(analogRead(0));
    PORTD = B11111111;
    delay(analogRead(0));
    PORTD = B11111111;
    delay(analogRead(0));
    PORTD = B11111111;
    delay(analogRead(0));
    PORTD = B11111111;
    delay(analogRead(0));
    }
    if (contatore==3) {
    contatore=0;

    } 
    }

 

Link al commento
Condividi su altri siti


Devi usare l'Interrupt per interrompere momentaneamente il ciclo e incrementare la variabile contatore...

 

attachInterrupt(digitalPinToInterrupt(interruptPin), ISR, RISING/FALLING );

 

Link al commento
Condividi su altri siti

Quindi mi consigli di inserire questa funzione per poter far cambiare gioco ua volta che premo il tasto, lo devo studiare perché non ho mai utilizzato questa funzione.. grazie!! 

Link al commento
Condividi su altri siti

Ecco il codice modificato e ottimizzato per l'INTERRUPT, ho dovuto aggiungere il pin 8 per sopperire alla mancanza del pin 2 che appunto quello dedicato all'interrupt esterno...

 

int puls=2;
int val=0;
volatile int contatore=0;
int i = 0;
volatile bool flag = false;

inline void ISR_Button() {
    if (digitalRead(puls) == LOW) {
        contatore = (contatore < 3 ? contatore+=1 : 0);
        flag = true;
    }
}

void Interval() {
    if (flag) return; 
    delay(analogRead(0));
}

void CheckpinINT(unsigned X) {
    PORTD = (X & B11111111);
    digitalWrite(8, (X & B00000100) >> 2);
    Interval();
}

void setup () {
    pinMode(8, OUTPUT);
    DDRD=B11111011;
    pinMode(puls, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(puls), ISR_Button, FALLING);
}

void loop () {

    if (contatore==1) {
        CheckpinINT(B10000001);
        CheckpinINT(B11000011);
        CheckpinINT(B10100101);
        CheckpinINT(B10011001);
        CheckpinINT(B10100101);
        CheckpinINT(B11000011);
    } else if (contatore==2) {
        CheckpinINT(B11111111);
        CheckpinINT(B11111111);
        CheckpinINT(B11111111);
        CheckpinINT(B11111111);
        CheckpinINT(B11111111);
        CheckpinINT(B11111111);
    } else {
        CheckpinINT(B00000000);
    }
    
    Interval();
 
    if (flag) flag = false; 
}

 

Link al commento
Condividi su altri siti

Scusami, ma hai anche inserito la funzione per regolare la velocità del gioco con potenziometro, se si mi puoi indicare quale passaggio e giusto per capire il concetto, poi se voglio inserire altri giochi basta if contatore3 e modificare lo stato dei led.. grazie ancora!!

Link al commento
Condividi su altri siti

ciao, ho provato a caricare lo sketch che hai fatto tu l'ho verificato ed e tutto ok, ma quando vado a caricarlo sulla scheda mi porta questa serie di errori, ho provato a cambiare con uno nuovo arduino(uno) ma la stessa cosa, ho anche provato a inserire un'altro sketch gia fatto e funzionante ma da sempre lo stesso errore se è potuto bruciare il processore?

Arduino:1.6.0 (Windows 7), Scheda:"Arduino Uno"

Lo sketch usa 1.520 byte (4%) dello spazio disponibile per i programmi. Il massimo è 32.256 byte.

Le variabili globali usano 19 byte (0%) di memoria dinamica, lasciando altri 2.029 byte liberi per le variabili locali. Il massimo è 2.048 byte.

avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
Problema di caricamento sulla scheda. Guarda http://www.arduino.cc/en/Guide/Troubleshooting#upload per suggerimenti

  Questo report potrebbe essere più ricco
di informazioni con
  "Mostra un output dettagliato durante la compilazione"
  abilitato in "File > Impostazioni"

 

Link al commento
Condividi su altri siti


trovato errore ho staccato i collegamenti del pulsante e andesso il programma l'ha caricato, a questo punto devo capire come collegare il pulsante

Link al commento
Condividi su altri siti

Il codice fa esattamente come prima per quanto riguarda i giochi di luce, il problema è sempre cercare di eliminare la ridondanza che era presente nel tuo, aggiungendo le funzioni sopra esposte, non devi scrivere righe di codice che non fanno altro che aumentare la lunghezza del testo rendendo di fatto un groviglio di chiamate al quadrato...

 

Per ora avevo lasciato le righe relative all'accensione dei LEDs in fila solo per chiarezza durante il disegno di questi, una volta stabiliti, sarebbe meglio mettere tutto in un Array e inviarli con un semplice ciclo for come da esempio...

 

Se vuoi aumentare i giochi di luce, devi creare ulteriori Array (es. gamelightB[]), aumentare MAX_NGAME in proporzione, e inserire quante righe ti servono nell'istruzione condizionale preposta (es. else if (contatore==3))...

 

Qui, è tutto spiegato abbastanza chiaramente, se non capisci ancora, allora devi studiare ancora un po'... :wallbash:

 

int val=0;
int i = 0;
// si devono dichiarate volatile le variabili che cambiano valore
// all'interno della routine di INTERRUPT
volatile int contatore=0;
volatile bool flag = false; // Se flag = true, vengono elimiante le pause
// Array di byte per i giochi di luce
byte gamelightA[] = {B10000001, B11000011, B10100101, B10011001, B10100101, B11000011};

#define PULS 2 // Il pulsante NA va collegato tra il pin 2 e massa
#define BIT2 8 // Uscita su PORTB al bit 0 pin 9 al posto del pin 2 che diventa l'INTERRUPT
#define MAX_NGAME 3 // Numero massimo di giochi di luce per il reset del contatore

// INTERRUPT SERVICE ROUTINE per intercettare la pressione del pulsante
inline void ISR_Button() {
    // debounce del pulsante per l'anti rimbalzo
    if (digitalRead(PULS) == LOW) { // Riverifica se il pulsante è ancora premuto (LOW)
        contatore = (contatore < MAX_NGAME ? contatore+=1 : 0); // Incrementa/azzera il contatore
        flag = true; // alza la bandierina per segnalare che c'è stato un INTERRUPT
    }
}

// Legge il potenziometro e attua la relativa pausa
// se la bandierina è alzata, non fa nessuna pausa
// e ritorna a quello che stava facendo
void Interval() {
    if (flag) return; 
    delay(analogRead(0)); // <-- Pausa
}

// Scrive su PORTD non modificando lo stato del pin 2
// Legge il bit 2 nel byte X e lo scrive sul pin 8
// Fa una pausa regolabile da potenziometro
void CheckpinINTandWrite(byte X) {
    PORTD = (X & B11111111);
    digitalWrite(BIT2, (X & B00000100) >> 2);
    Interval();
}

void setup () {
    pinMode(BIT2, OUTPUT); // pin 8 come uscita digitale al posto del pin 2
    DDRD=B11111011; // impostazione dei registri della PORTD come IO, I = 0 - O = 1
    pinMode(PULS, INPUT_PULLUP); // Attivo la Pullup sul pin 2 PULS
    // Dichiaro che voglio l'INTERRUPT del pulsante sulla routine ISR_Button
    // sul fronte di discesa del cambio di stato utilizzando il pin 2
    attachInterrupt(digitalPinToInterrupt(PULS), ISR_Button, FALLING);
}

void loop () {

    if (contatore==1) {
        // ciclo il gioco di luce A per la sua intera dimensione
        for (i = 0; i < sizeof(gamelightA); i++) {
            CheckpinINTandWrite(gamelightA[i]);
        }
        
    } else if (contatore==2) {
        // Tutto acceso
        CheckpinINTandWrite(B11111111);
    //} else if (contatore==3) {
        // TO DO
    } else {
        // Tutto spento
        CheckpinINTandWrite(B00000000);
    }
    
    // Pausa
    Interval();
    
    // Abbasso la bandierina
    if (flag) flag = false; 
    
}

 

Link al commento
Condividi su altri siti

Quote

avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

 

Questo è il classico errore di caricamento dello sketch, non c'entra nulla con il debug del codice, il pulsante è NA quindi non influisce minimamente se non lo premi, piuttosto prova a scollegare il pin 0 RX, solitamente se è c'è connesso qualcosa durante il caricamento restituisce quel tipo di errore...

 

Il pulsante va collegato tra il pin 2 e massa...

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...