funzione RANDOM

Buongiorno!

Avrei qualche domanda per quanto riguarda:

  • la creazione di una funzione random per funzioni e condizioni ( nello sketch chiamate come CASO1-CASO2…CASO) Non mi è chiaro come possa presentare i casi e le funzioni in maniera randomica non vincolata all’interno della condizionata

  • creazione di una una condizione in cui:
    a. a stato di riposo - HC-SR501 - Sensore Infrarossi - rileva la presenza dell’oggetto in alto - ma sia il led e lo schermo lcd sono spenti

b. una volta rimosso l’oggetto soprastante - HC-SR501 - Sensore Infrarossi - rileva il movimento -

c. una volta rimesso nella posizione iniziale - HC-SR501 - Sensore Infrarossi avverte l’oggetto nella posizione di partenza e attiva il sistema (scritta sullo schermo lcd e accensione led)

d. MA, SOLO se tocco il sensore Touch, facendo le azioni precedenti (a,b,c) allora si attivano le funzioni ipotetiche e il random

int sec;

//TOUCH SENSOR
#define touchpin 6 // sets the capactitive touch sensor @pin 4
[tt][/tt]
//bool on = false; // variabile on/off
int spengooggetto = 1; //Corretto con uno, ma forse è 0 


//BUZZER
const int buzzer = 4;
const int songLength = 18;

//SENSORE INFRAROSSI
int pirPin = 5; // Input per HC-SR501 - Sensore Infrarossi (5)
int pirValue; // Lettura valore PIR


// JANSJO
int LED=A3; // Da sostituire con Jansjo

// SCHERMO LCD
#include <LiquidCrystal.h> // include the library code:
const int rs = 2, en = 3, d4 = 7, d5 = 8, d6 = 12, d7 = 13;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

//RGB1 
int redPin = 11;
int greenPin = 10;
int bluePin = 9 ;
//ne mancabo 2 da aggiungere

int pins[] = { A0, A1, A4,};  //Array dei pin - led in sequenza // da sostituire con RGB
int i;
#define num_pins 3  //Numero dei pins


void setColor(int red, int green, int blue)
{
#ifdef COMMON_ANODE
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}

void timer() // tempo tra l'appoggio della sfera della lampada e l'output
{
  digitalWrite(LED, HIGH); 
  for(sec=70; sec>=0; sec--) {
    lcd.clear() ;
    if((sec>13) && (sec<70)){
      lcd.write("aspetta il responso");
      
  }
    
    //delay(1000); //Provare con tempi minori per aumentare la precisione
    
} 
   }
void casouno() //CASO1 (buzzer)
{
  int i;
for(int i =1000; 1 > 0; i = i-50)
{
tone(buzzer,1000,200);
delay(i);
} 
} 

void alternanzaluci() // CASO2
{
  int t;
  
for(t=0; t<255;t++){analogWrite(bluePin, t); 
analogWrite(redPin,t);
delay(10);
  
}

analogWrite(redPin, 0);
analogWrite(bluePin, 0);

for(t=0; t<255;t++){analogWrite(greenPin, t); 
analogWrite(bluePin, t);
delay(10);
  
}  
analogWrite(greenPin, 0);
analogWrite(bluePin, 0);
}

/*void sequenzaled();
for(i = 0; i < num_pins; i++)
     {
         digitalWrite(pins[i], HIGH);
         delay(timer);
         digitalWrite(pins[i], LOW);
     }
     for (i = num_pins - 1; i >= 0; i--)
     {
         digitalWrite(pins[i], HIGH);
         delay(timer);
         digitalWrite(pins[i], LOW);
     }
     */
void  cambiocolore();
setColor(80, 0, 80); 
delay(10);
  setColor(255,165,0);
delay(10);
setColor(80, 0, 80);
delay(10);
 setColor(255,165,0);
delay(10);
 }

*/


void setup()
{

lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display } 
lcd.display();
lcd.setCursor(0, 1); 
lcd.write("Tocca da 1 a 3!"); 
    delay(1000);
lcd.clear();

pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);


//Dichiara tutti i pins come OUTPUT
     for (i = 0; i < num_pins; i++)
         pinMode(pins[i], OUTPUT);


pinMode(touchpin, INPUT); //sets the touch sensor as input
pinMode(buzzer, OUTPUT);
pinMode(pirPin, INPUT);

Serial.begin(9600); // set baud rate



}
void loop()
{

lcd.setCursor(0, 1);


pirValue = digitalRead(pirPin);
           digitalWrite(redPin, pirValue);

int value= digitalRead(pirPin); // la funzione digitalread legge il sensore 
if(value == HIGH){ // se è high vuol dire che rileva la presenza e accende il led
           digitalWrite(LED,HIGH); // da cambiare con la Janson
           
    
        if (digitalRead(touchpin)){ 
         timer(); // da impostare un range
          lcd.write("Poni il quesito")
         }
      
       lcd.clear();
           
}
else {
           digitalWrite(LED,LOW);
}


  // ELEMENTO RANDOM DA AGGIUNGERE  all'interno delle graffe della funzione if(digitalRead(touchpin)) 
// CASO1
casouno();

// CASO2
digitalWrite(redPin, HIGH);

// CASO3- luci che si alternano
  alternanzaluci();

// CASO4
 lcd.write("Ripeti la domanda");

// CASO5
digitalWrite(redPin, HIGH);
casouno();

// CASO6- luci che si alternano
 cambiocolore();
/*
setColor(80, 0, 80);
  setColor(255,165,0);
delay(10);
setColor(80, 0, 80);
  setColor(255,165,0);
delay(10);
setColor(80, 0, 80);
  setColor(255,165,0);
delay(10);
setColor(80, 0, 80);
  setColor(255,165,0);
delay(10);
setColor(80, 0, 80);
  setColor(255,165,0);
delay(10);
*/

 

// CASO7
// buzzer suono prolungato

// CASO8
//janson lampeggia
  digitalWrite(LED, HIGH);  // accende il LED  
  delay(1000);              // aspetta un secondo  
  digitalWrite(LED, LOW);   // spegne il LED  
  delay(1000);              // aspetta un secondo  

// CASO9- 3 rgb in progressione
//  sequenzaled();

}
}
}
}
}

Grazie mille anticipatamente, Valeria

Buongiorno, essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD ([u]spiegando bene quali conoscenze hai di elettronica e di programmazione[/u] ... possibilmente [u]evitando[/u] di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie. :)

Guglielmo

secondo me hai un problema di fondo... il sensore di movimento quando è in condizione iniziale da te definita a riposo "non dovrebbe rilevare" alcun movimento (anche se il solo fatto di mettere una copertura al sensore genera un segnale logico)... Non penso che ci sia un modo algoritmico per escludere la tua azione iniziale su quel sensore se non il semplice conteggio di impulsi. ma non sarebbe efficiente poiché ammesso che escluda la copertura iniziale potresti avere 10 movimenti validi che non devono essere considerati come ricopertura dello stesso sensore. io andrei piuttosto di fotoresistenza per sapere se c'è qualcosa che copre il sensore.

valeriafinale: Buongiorno! - la creazione di una funzione random per funzioni e condizioni ( nello sketch chiamate come CASO1-CASO2...CASO) Non mi è chiaro come possa presentare i casi e le funzioni in maniera randomica non vincolata all'interno della condizionata

...
  // ELEMENTO RANDOM DA AGGIUNGERE  all'interno delle graffe della funzione if(digitalRead(touchpin)) 
// CASO1
casouno();
// CASO2
digitalWrite(redPin, HIGH);
// CASO3- luci che si alternano
  alternanzaluci();
// CASO4
 lcd.write("Ripeti la domanda");
...

Usi la funzione random(min,max) e un switch...case

byte caso=random(1,3);        // genera numero quasi casuale tra 1 e 3
switch(caso)
{ case 1: 
      casouno(); 
      break;
  case 2: 
      digitalWrite(redPin, HIGH);
      break;
  case 3:
      alternanzaluci();
      break;

}  // fine switch
byte caso=random(1,3);        // genera numero quasi casuale tra 1 e 3

solo una nota.... random( min(optional), max) genera un numero casuale tra min incluso e max escluso cioè tra min e max-1

nel caso in cui il min non venga incluso:

byte caso=random(3);

anche qui il numero è compreso tra 0 e valore-1

Grazie @Patric, me l'ero scordato che esclude il max.

Grazie mille a tutti, siete stati gentilissimi!!!

Patrick_M: solo una nota.... random( min(optional), max) genera un numero casuale tra min incluso e max escluso cioè tra min e max-1

Ulteriore precisazione:

Esiste una funzione, la randomSeed(), che consente di far generare alla random() combinazioni sempre diverse dell'intervallo di valori specificato, all'accensione della scheda. Se non si usa la randomSeed() le combinazioni di valori prodotte dalla random() saranno predeterminate dopo ciascuna riaccensione, una comportamento che si ripete (virtualmente) all'infinito.

Esempio di quello che succede senza usare la randomSeed(): accendo la scheda e stampo a video sulla console seriale i primi 5 valori; spengo la scheda e la riaccendo; ripeto la prima operazione.

In ambo i casi leggerai per esempio (sequenza inventata da me): 1 3 2 2 1

Se vuoi che questo non avvenga, cioè vuoi avere una varietà di combinazioni, nella funzione setup si può scrivere "randomSeed(analogRead(0));"

Quell'istruzione significa che Arduino "pescherà le carte dal mazzo", ossia la sua sequenza casuale, consentitemi la similitudine, sulla base di un valore aleatorio letto dal PIN analogico n°0. Ciò presuppone che al PIN non sia collegato nulla, in gergo si dice che un PIN in tale condizione è flottante, e che di conseguenza riceva i disturbi provenienti dall'ambiente esterno che sono per loro natura casuali.

Trovi maggiori dettagli nella reference di Arduino:

random() randomSeed()

Certamente, la randomSeed() va sicuramente utilizzata, però ci ragionavo l'altro giorno: anche con analogRead() di un pin flottante tu hai di fatto non più di 1024 possibili sequenze di numeri casuali. Quindi teoricamente in almeno 1024 attivazioni di Arduino puoi avere almeno due sequenze identiche.

La soluzione che ho trovato per mitigare questa limitazione è: poiché la randomSeed() ha come parametro un unsigned long e la analogRead() restituisce , per avere una maggiore casualità sarebbe opportuno combinare almeno DUE letture (o sullo stesso pin a distanza di un certo tempo, o di due pin flottanti). Ad esempio questa funzione mi dà 1 miliardo di combinazioni di seed:

unsigned long initRandom(int pin) {
  unsigned long seed = analogRead(pin);
  randomSeed(seed);
  delay(random(100));
  seed += analogRead(pin)*1024UL;
  delay(random(100));
  seed += analogRead(pin)*1024UL*1024UL;
  randomSeed(seed);
  return seed;
}

La soluzione è la libreria di Leo (il nostro "admin" leo72) che si trova QUI :D

Guglielmo

Si, certamente, Guglielmo, conosco bene l’implementazione di un registro lineare a scorrimento controreazionato (LSRF) perché l’ho fatto anche per lavoro :wink: (anzi, per alcune funzioni di cifratura ho anche avuto a che fare con LSFR di Galois, per dire, più efficienti per implementazioni critiche…).

Io non volevo sminuire il nostro admin ovviamente, ma per cose non particolarmente critiche (come questa) preferisco la mia soluzione perché più compatta come occupazione di memoria e più rapida come esecuzione… :smiley: