Accensione led in modo completamente casuale

Salve ragazzi ....
sono in cerca del vostro aiuto... vi spiego in cosa consiste .
dovrei accendere dei led 6 di preciso in modo totalmente casuale, per ora aiutandomi col forum sono riuscito a scrivere un programma che li fa accendere casualmente ma solo uno per volta.
a me invece servirebbe molto più casuale.. per esempio..
se ne accende 1 poi 4 poi tutti poi 3 poi di nuovo tutti proprio a casaccio...ma non so proprio dove andar a sbattere la testa , lo trovo già troppo avanzato per me come scrittura del codice che sono solo al secondo progetto

potreste aiutarmi grazie

Una delle tante possibili soluzioni:

  • 6 led -> 6 bit
  • 2^6 = 64;

Ad esempio con un Arduino Uno (ATmega328P), potresti usare il direct port manipulation mettendo i led tutti in fila ad esempio sui pin D8 - D13 (registro PORTB).

int out = random(0, 64);
PORTB = out;
1 Like

...o, ancora più semplicemente:
PORTB = random (0, 64);

Naturalmente bisogna prima impostare i pin come uscite nel setup():
DDRB = 63;
equivalente a:
DDRB = 0b00111111;

A volte la manipolazione diretta delle porte rende semplicissime e velocissime delle operazioni che, altrimenti, richiederebbero molte righe di programma. L'unico lato che può essere considerato negativo è che il codice deve essere scritto specificamente per quel microcontrollore che si intende usare. Per utilizzare queste tecniche bisogna conoscere i numeri binari:
https://www.google.com/search?q=i+numeri+binari
e gli operatori bit a bit (bitwise):

Anni fa abbiamo affrontato lo stesso problema

Prova a dare uno sguardo qui:

E qui:

Ciao e innanzitutto grazie per l'aiuto
grazie a voi già ho capito in cosa consiste PORTB che non conoscevo da neofita
sarebbe l'intera sezione dei pin da 8 a 13 mentre PORTD da 0 a 7 giusto?
ora aggiungendo la stringa PORTB = random (0, 64); sono riuscito a ottenere quasi il risultato cercato...

la mia domanda è se con questa istruzione si possa avere un breve spegnimento totale fra un lampeggio e l'altro

al momento questo è quello che ho scritto

byte led1 = 13;
byte led2 = 12;
byte led3 = 11;
byte led4 = 10;
byte led5 = 9;
byte led6 = 8;
int R = 0;


void setup() {
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);
  pinMode(led4,OUTPUT);
  pinMode(led5,OUTPUT);
  pinMode(led6,OUTPUT);
}

void loop() {
  PORTB = random (0, 64);
  
  randomSeed(millis());
  R = random(8,14);
  if(R == 8)
  {
    digitalWrite(led1,HIGH);
    delay(300);
    digitalWrite(led1,LOW);
    delay(300);
  }
  if(R == 9)
  {
    digitalWrite(led2,HIGH);
    delay(300);
    digitalWrite(led2,LOW);
    delay(300);
  }
  if(R == 10)
  {
    digitalWrite(led3,HIGH);PORTB = random (0, 64);
    delay(300);
    digitalWrite(led3,LOW);
    delay(300);
  }
  if(R == 11)
  {
    digitalWrite(led4,HIGH);
    delay(300);
    digitalWrite(led4,LOW);
    delay(300);
  }
  if(R == 12)
  {
    digitalWrite(led5,HIGH);
    delay(300);
    digitalWrite(led5,LOW);
    delay(300);
  }
  if(R == 13)
  {
    digitalWrite(led6,HIGH);
    delay(300);
    digitalWrite(led6,LOW);
    delay(300);
  }
  delay(500);
}

Altra domanda sarebbe possibile poi mettere il codice da arduino uno a arduino nano senza modificare niente??

Si, hanno lo stesso microcontrollore.

1 Like

Per spegnere i primi 6 bit (qui accesi 0b00111111) puoi usare questo comando:

PORTB = PORTB & ~63;

In binario allora avrai 0b00000000.
La cosa funziona anche con una variabile ad esempio

uint8_t data = 0b10111111;
Serial.println(data);  // stampa 191 decimale
data = data & ~63;
Serial.println(data); // stampa 128 in decimale

data alla fine vale in binario 0b10000000 quello acceso (1) è il bit 7.

Puoi anche fare ovviamente PORTB = data;

Ciao.

che equivale a scrivere:

//              PB76543210
PORTB = PORTB & 0b11000000;

allora di nuovo grazie....
aggiungendo PORTB = PORTB & ~63; rimane tutto spento, ho eliminato parte del codice che credo fosse obsoleto ma rimettendolo funziona un pò e poi si blocca...
cosa ho sbagliato?

byte led1 = 13;
byte led2 = 12;
byte led3 = 11;
byte led4 = 10;
byte led5 = 9;
byte led6 = 8;
int R = 0;


void setup() {
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);
  pinMode(led4,OUTPUT);
  pinMode(led5,OUTPUT);
  pinMode(led6,OUTPUT);
}

void loop() {
  PORTB = random (0, 64);

  randomSeed(millis());
  R = random(8,14);
  if(R == 8)
  

  delay(300);
}

Si può anche ridurre:

void setup() 
{ 
DDRB=63; // Uscite da B0 a B5.
} 

void loop() 
{ 
PORTB = random (0, 64); 
randomSeed(millis()); 
PORTB &= 0b11000000; // Moltiplica per 0 da B0 a B5.
delay(500); // Mezzo secondo di buio. 
}

Dici che il precedente si blocca?...

SI si blocca fisso su uno acceso

volevo mettere un video ma non sembra si possa fare :slight_smile:

co

così non va tutto spento .. non saprei

Smettila di copiare pezzi di codice a caso
Cerca invece di capire il significato di quello che scopiazzi

E vai a vedere dove ti ho indicato

Eh... per forza rimane tutto spento! Ho spento tutto immediatamente dopo aver acceso! Ci vuole un delay (1000); prima di spegnere!

Poi il PORT va fatto solo sui bit su cui si vuole agire:
PORTB |= random (0, 64);

Già, stessa cosa per DDRB |= 63;
I due bit alti PB6 e PB7 sono fisicamente connessi al risonatore o quarzo.

Neanche PORTD è completa (8-bit) se vogliamo usare la seriale e potere scrivere lo sketch in flash.

Ciao.

1 Like

Li ho letti, ma perdonami se non capisco d'altronde sono solo al 2° giorno che uso arduino
quindi i pezzi di codice che ho "scopiazzato" sono quelli che ho capito.
Nella funzione che hai scritto te partendo dal fatto che hai usato {2 , 0 , 0} {3, 0 , 0} etc che non so cosa siano ho potuto intuire che serve un pulsante per far partire il tutto cosa che devo escludere , ma anche la non saprei come fare

Eh beh...
Il C bisogna conoscerlo...