Software per uscite random

Salve a tutti, sono Michele e sono nuovo del forum, conosco abbastanza Arduino ed è per questo ho in mente di usarlo per creare un circuito.
Ho bisogno di realizzare 10 uscite diverse da Arduino che si accendano random con una durata inferiore a 15 secondi. Qualcuno ha idea di come progettare il software ? Servono ad alimentare un relè che di conseguenza accenderla le luci nelle case in miniatura di un plastico.

Buona sera e benvenuto sul forum, essendo il tuo primo post, nel rispetto del regolamento, ti chiedo cortesemente di presentarti QUI ([u]spiegando bene quali conoscenze hai di elettronica e di programmazione[/u] ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, [u]NON[/u] necessariamente inerenti alla tua domanda: - serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections - pinout delle varie schede by xxxPighi: Pinout - link [u]generali[/u] utili: Link Utili

Scusatemi, ora potete vedere la mia presentazione sul forum, nell’ apposito topic.
Michele

Dunque, tu vuoi 10 uscite che normalmente sono in un certo stato ... diciamo "spente" ... in modo casuale vuoi che esse si accendano, ma ... quanto tempo ciascuna deve rimanere accesa ? Si devono accendere tutte e 10 comunque entro 15 secondi ? E dopo i 15 secondi che succede ? ...

Magari se descrivi un po' più precisamente tutto quello che intendi fare ... riusciamo anche ad aiutarti ... ::)

Guglielmo

Si tratta di 10 uscite che si accendono e si spengono casualmente. L' unico cosa è che la durata in cui un' uscita resta accesa, deve essere di massimo 15 secondi.

Puoi usare la istruzione random, la quale ti permette di generare un numero compreso tra un MIN e un MAX. esempio time1=random(min, max); questo per un solo relè, per gli altri sarà facile visto che hai una certa base . Poi ho letto il tuo ulteriore post, quindi ci vuole un random principale, che abilita di volta in volta l'istruzione random sugli altri 10 pin.

... ancora NON hai risposto completamente ... accensione casuale, facile, basta una random tra 1 e 10 e ci dice quale è quello da accendere, ma ... dopo quanto spegnerlo ? Anche questo random tra 1 e 15 secondi ? e .. ogni quanto fare l'accensione causale ? Perché se le fai a raffica, vista la velocità del ciclo di loop() .. in un attimo li hai tutti accesi !

Guglielmo

michelecastelvero: Servono ad alimentare un relè che di conseguenza accenderla le luci nelle case in miniatura di un plastico.

Oltre alle cose che già hanno scritto, aggiungo una mia domanda: a che ti servono i relè se è un plastico? Non ti bastano 10 LED?

Comunque per chiedere consiglio, PRIMA scrivi tu qualcosa postandone il codice, POI potrai trovare qualcuno che ti dia consigli, nessuno qui scrive codice per "conto terzi" :)

PS/EDIT: hai detto di conoscere "abbastanza" Arduino, ma poi chiedi se qualcuno "ha idea" di come progettare il codice: tu proprio "non hai idea" perché non hai mai programmato per Arduino o hai un poco di pratica (e allora scrivi il tuo codice, e postalo)?

Anziché fare un’accensione veramente casuale, potresti prestabilire una sequenza apparentemente casuale ma, in realtà, ben studiata per ottenere le combinazioni che preferisci evitando, ad esempio, che in certi momenti si spengano tutte, oppure che si accendano tutte; puoi anche fare un periodo in cui sono tutte spente perché è notte fonda. Per fare questo fai due array di variabili: uno che contiene dei valori che esprimono quali luci si accendono o si spengono (con valori da 1 a 512: 10 bit) e l’altro che contiene dei valori pari alla durata in secondi della combinazione corrente.
Per semplificare la programmazione, oltre a quello dei tempi puoi fare un array con le luci che si accendono e un altro con quelle che, allo stesso tempo, si spengono.

Io a questo punto pensavo che per semplificare il tutto di scrivere un software il quale attiva e spegne le uscite con un tempo impostato. E quindi di creare un programmino abbastanza lungo in modo che venga riprodotto ciclicamente il meno possibile cosi da sembrare quasi casuale.

docdoc: Oltre alle cose che già hanno scritto, aggiungo una mia domanda: a che ti servono i relè se è un plastico? Non ti bastano 10 LED?

Comunque per chiedere consiglio, PRIMA scrivi tu qualcosa postandone il codice, POI potrai trovare qualcuno che ti dia consigli, nessuno qui scrive codice per "conto terzi" :)

PS/EDIT: hai detto di conoscere "abbastanza" Arduino, ma poi chiedi se qualcuno "ha idea" di come progettare il codice: tu proprio "non hai idea" perché non hai mai programmato per Arduino o hai un poco di pratica (e allora scrivi il tuo codice, e postalo)?

Tu collegheresti direttamente ad arduino una cinquantina di LED ? La tua risposta mi è sembrata un pò inutile. Inoltre, non ho chiesto su questo forum che qualcuno mi scriva il codice ma solamente dei consigli su come partire. Saluti.

michelecastelvero:
Tu collegheresti direttamente ad arduino una cinquantina di LED ?

No, certo, ma banalmente basta qualche MOSFET e quelli si che li piloti direttamente da Arduino :slight_smile:

Guglielmo

michelecastelvero: Tu collegheresti direttamente ad arduino una cinquantina di LED ? La tua risposta mi è sembrata un pò inutile.

Primo, hai parlato di 10 LED, e non "una cinquantina". Secondo, già ti ha risposto Guglielmo: ovviamente non li piloti direttamente, ma il mio consiglio era di NON usare dei relè a mio avviso inutili per una applicazione di questo tipo. Terzo, se chiedi consigli sul SOFTWARE ma non posti nessun TUO codice, di fatto di quale software vogliamo parlare quindi? Non sai come si fa ad alzare il livello di un output digitale, oppure, come credo sia probabile, chiedevi un algoritmo per fare le accensioni semi-casuali? Perché in quest'ultimo caso, ripeto, facci vedere qualcosa che TU hai fatto e che vorresti migliorare o che non ti funziona come vorresti, e possiamo aiutarti.

Se vuoi solo discutere teoricamente dell'algoritmo va bene, basta dirlo, ma essendo casuale ci sono tante possibilità.

Ad esempio come ti hanno consigliato, generi un numero pseudocasuale a 10 bit (ma tra 0 e 1023, non 512) ed usando quindi questi 10 bit hai l'input per accendere i relativi canali (che, pilotati via transistor o MOSFET, accendono quanti LED vuoi per ogni canale).

Se non ti piace che ad ogni restart di Arduino la sequenza sia sempre la stessa, seppur pseudocasuale, puoi usare come seed ad esempio il valore di un pin analogico disconnesso.

Se vuoi rendere più realistica la cosa ossia evitare le transizioni contemporanee tra un evento random ed il successivo, puoi memorizzare per ogni canale l'ora di accensione (basta il millis()) per imporre ad un canale di restare ON (anche se il bit è a zero) se il tempo di accensione minima non è passato, e viceversa di andare OFF se il tempo di accensione massimo è passato. Oppure nell'array parallelo ti memorizzi il millis() di spegnimento programmato e quando questo è passato, spegni quel canale.

Scegli una strada, e se vuoi una mano inizia a scrivere qualcosa e postala qui...

Scusatemi ma riesco a replicare solo ora. poichè mi è stata chiesta la condizione che l' uscita random deve avere un valore di tempo compreso tra 8 e 15 secondi, ho pensato in questo modo. Creare un programma abbastanza lungo che a mio piacimento accende e spegne i vari utilizzatori con un tempo impostato da me. Il software vorrei farlo abbastanza lungo in modo che la ripetizione ciclica del software non sia percepibile (spero di essere stato chiaro).

#define LED1 13            // LED collegato al pin digitale 13  
#define LED2 12 
#define LED3 11 
#define LED4 10 
#define LED5 9 

void setup() {  
pinMode(LED1, OUTPUT);     // imposta il pin digitale come output  
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);

}  

void loop() {  
digitalWrite(LED1, HIGH);  // accende il LED  
 delay(7000);                  // ritardo 7 secondi
digitalWrite(LED5, HIGH);  // spegne il led
 delay(10000); 
digitalWrite(LED1, LOW);
digitalWrite(LED4, HIGH);
delay(1000);
digitalWrite(LED5, LOW);  
digitalWrite(LED2, HIGH);
delay(1000);  
digitalWrite(LED1, HIGH);
delay(11000);  
digitalWrite(LED4, LOW);
delay(2000)
digitalWrite(LED2, LOW);
delay(9000)
digitalWrite(LED3, HIGH);
delay(12000);  
digitalWrite(LED23, LOW);   
delay(1000);              
}

Questo è in linea di massima il software. Ovviamente son sono stato li a guardare se i tempi sono giusti, lo farò in seguito.

Quello che mi chiedevo è: Poichè questo circuito non deve funzionare sempre, ma solamente ad un certo intervallo di tempo, c'è la possibilità di inserire all' ingresso di arduino un imput, il quale quando arriva un segnale la riproduzione del programma va in pausa e quando il segnale in ingresso scompare riprende da dove era rimasto ? Subito ho pensato di togliere l' alimentazione ma una volta rialimentato se son sbaglio il programma riparte dall' inizio e non vorrei che succedesse. vi ringrazio ancora

> michelecastelvero: … ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post #14 (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

Guglielmo

gpb01:
> michelecastelvero: … ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post #14 (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

Guglielmo

Scusami, ora ho risolto

michelecastelvero:
mi è stata chiesta la condizione che l’ uscita random deve avere un valore di tempo compreso tra 8 e 15 secondi

Allora, se ho capito bene, hai 10 LED (o comunque 10 canali), vuoi che l’accensione sia casuale, e che quando acceso un LED resti acceso tra 8 e 15 secondi. Aggiungerei anche che il numero di canali accesi contemporaneamente non sia mai minore di 2 e maggiore di 6.

Io quindi proverei a fare così, l’ho scritto di getto quindi prendilo solo come spunto ovviamente (io ho cambiato i parametri per test in 4 canali e tra 1 e 3 canali accesi contemporaneamente) ma nota anche come ti ho parametrizzato il tutto, per cui modificalo come credi e posta il tuo codice e se ti funziona o se hai problemi:

// Indice del primo pin digitale
#define OFFSET 4
// Numero di linee di LED
#define TOT_LEDS 4
// Pin analogico da usare come seed random
#define SEEDPIN A0
// Numero minimo di canali accesi
#define MINLEDS 1
// Numero massimo di canali accesi
#define MAXLEDS 3
// Tempo minimo di accensione
#define MINTIME 8
// Tempo massimo di accensione
#define MAXTIME 15

// Numero di canali attualmente accesi
int numLed = 0;
// Array dell'istante di spegnimento programmato
long ledOffTime[TOT_LEDS];

void setup() {
  Serial.begin(115200);
  
  randomSeed(analogRead(SEEDPIN));
  for (int i=0; i<TOT_LEDS; i++) {
    pinMode(OFFSET+i, OUTPUT);
    digitalWrite(OFFSET+i, LOW);
    ledOffTime[i] = 0;
  }
  numLed = 0;
}

void loop() {
  long val = 0;
  
  // Verifica se ci sono canali "scaduti" da spegnere
  long mil = millis()/1000;
  Serial.print("mil = ");
  Serial.println(mil);
  for (int i=0; i<TOT_LEDS; ++i) {
    if ( ledOffTime[i] > 0 && mil >= ledOffTime[i] ) {
      ledOffTime[i] = 0;
      --numLed;
      digitalWrite(OFFSET+i, LOW);
    }
    Serial.print("led ");
    Serial.print(i);
    Serial.print(" = ");
    Serial.println(ledOffTime[i]);
  }

  // Verifica se devo accendere i canali minimi
  while ( numLed < MINLEDS ) {
    int i = random(TOT_LEDS+1);
    while ( ledOffTime[i] > 0 )
      i = random(TOT_LEDS+1);
    digitalWrite(OFFSET+i, HIGH);
    ledOffTime[i] = mil + random(MINTIME,MAXTIME+1);
    ++numLed;
  }
  // Accende casualmente anche un altro canale (uno ogni 5 secondi)
  if ( numLed < MAXLEDS && random(5) >= 4) {
    int i = random(TOT_LEDS+1);
    while ( ledOffTime[i] > 0 )
      i = random(TOT_LEDS+1);
    digitalWrite(OFFSET+i, HIGH);
    ledOffTime[i] = mil + random(MINTIME,MAXTIME+1);
    ++numLed;
  }
  delay(1000);
}

Ti ringrazio per il tuo aiuto. ho provato a compilare il software e non mi da errori.

Le modifiche che ho provatoa fare sono:

// Indice del primo pin digitale
#define OFFSET 1
// Numero di linee di LED
#define TOT_LEDS 10
// Pin analogico da usare come seed random
#define SEEDPIN A0
// Numero minimo di canali accesi
#define MINLEDS 3
// Numero massimo di canali accesi
#define MAXLEDS 5
// Tempo minimo di accensione
#define MINTIME 8
// Tempo massimo di accensione
#define MAXTIME 15

Non devo definire tutti i pin digitali che uso in uscita ?

Considerando che devo utilizzare il comando basso per far eccitare il relè mi converrebbe mettere una porta not oppure si pùò a modificare il software ?

michelecastelvero:
Le modifiche che ho provatoa fare sono:

// Indice del primo pin digitale

#define OFFSET 1
// Numero di linee di LED
#define TOT_LEDS 10
// Pin analogico da usare come seed random
#define SEEDPIN A0
// Numero minimo di canali accesi
#define MINLEDS 3
// Numero massimo di canali accesi
#define MAXLEDS 5
// Tempo minimo di accensione
#define MINTIME 8
// Tempo massimo di accensione
#define MAXTIME 15

Messo così tu stai usando il pin D1 (che in genere è della seriale!) come primo pin associato alle uscite: è così?

Non devo definire tutti i pin digitali che uso in uscita ?

No perché quel codice assume i pin tutti sequenziali a partire da OFFSET, ed il numero di pin totali è definito da TOT_LEDS. Quindi con quelle definizioni che hai messo, i pin associati alle uscite vanno da D1 a D10, ma per evitare problemi con la serial ti consiglio di partire dal pin 2 (quindi OFFSET 2) quindi le uscite andranno da D2 a D11.

Considerando che devo utilizzare il comando basso per far eccitare il relè mi converrebbe mettere una porta not oppure si pùò a modificare il software ?

Certamente, basta che tu inverta LOW e HIGH nei digitalWrite (sia nella setup() sia in loop()).

Ho appena provato il software con i led collegati e devo dire che è una bomba. Non so come ringraziarti. Grazie di cuore. Michele