attivazione tramite sequenza di segnali entro un lasso di tempo

ciao a tutti, avrei un quesito, se possibile vorrei aggiungere una funzione a questo progetto.

https://create.arduino.cc/projecthub/wrighi/steering-controller-for-3ch-radio-with-lights-and-fpv-cam-6762fb?ref=user&ref_id=1552375&offset=0

attualmente il canale ausiliario del mio radiocomando 3ch aziona un servo che muove una microcamera in cabina.
essendo un canale ausiliario on-off posso decidere se far girare la cam insieme allo sterzo oppure se lasciarla ferma con la visuale solo avanti.

lo sketch funziona benissimo e fa molte cose quindi non vorrei stravolgerlo, tutte le funzioni presenti vorrei che rimanessero immutate.
però se possibile vorrei attivare un buzzer o claxon quando viene azionato aux 4 volte di seguito nell'arco di 1 secondo.
allo stesso modo vorrei spegnere il claxon quando viene ripetuta nuovamente la sequenza.

mi chiedo se sia possibile e come potrei fare?

la condizione dovrebbe essere: se il segnale aux in è maggiore o minore di 1500 per 4 volte consecutive nell'arco di 1000 millis si attiva un piedino per il buzzer, viceversa si disattiva.
ho pensato a 4 impulsi giusto per sicurezza per non attivare per sbaglio il buzzer ma tornare comunque alla condizione iniziale dell'interruttore aux (in modo da non spostare la microcamera).. ovviamente andrebbe bene anche solo con 2 impulsi.
ovvero aux si troverebbe in condizione iniziale attorno a 1000, passa a 2000 e torna a 1000 il tutto in circa 1 secondo, questo dovrebbe azionare il cicalino.

potete darmi qualche suggerimento per favore? da dove posso partire per ottenere una funzione del genere?

Si penso sia fattibile :slight_smile:

1)ho una variabile che mi conta gli impulsi, con valore iniziale zero
2)ho un contatore di tempo tramite la funzione millis() che calcola intervalli di tempo di 1 secondo
3)Se nel tempo di un secondo la variabile ha valore 4, suono, e porto la variabile allo stato zero

byte impulsi=0;
byte stato=0; //stato zero suona, stato 1 ferma il suono
unsigned long intervallo=0;


void setup(){

    intervallo=millis();
}

void loop(){


    if(millis()-intervallo<=1000){//Se non è passato un secondo

        
          if(impulsi==4){

              if(stato==0)
                  //suona
              else
                  // spegni suono
              impulsi=0;
              stato=!stato;
         }// end if

    }else{//Se è passato un secondo

          impulsi=0;
          intervallo=millis();

    }//end if


}

grazie dell'aiuto.
ho inserito le tue stringhe di codice nello sketch, sono quelle con la dicitura (aggiunta) e non rende errori però mi sfugge chi sia il buzzer: dovrei definire un piedino per il cicalino e credo che "impulsi" sia in realtà da sostituire con "Auxpulse" che sarebbe il segnale del canale aux.
prima di testarlo devo capire meglio anche perchè dovrò aprire la centralina per aggiungere i piedini per questo claxon.

questo è il codice con aggiunte le tue stringhe, le ho inserite dove mi sembrava più corretto.

//----------- signal setup -------------------------------------
#define Neutral 1445 // -- default 1500//minimum throttle forward signal or neutral position
#define Maxspeed 1932 // -- default 2000//maximum throttle forward signal 
#define Antsx 1041 // -- default 1000//in front servo signal sx
#define Antdx 1968 // -- default 2000//in front servo signal dx


//----------- rear servo setup -------------------------------
#define Postsx 700 //-- default 1000//out rear servo sx end point (if inverted with postdx it reverse)
#define Postdx 2000 //-- default 2000//out rear servo dx endpoint (if inverted with postsx it reverse)
#define Center 150 //-- default 0//add or subtract your value to center steering (+- 50 or more)

 
//--------- user driving setup ------------------------------ 
#define Max_gain 550 //-- default 400//gain steering reduction width at max throttle (if work reverse add (-) before value)
#define Slowlimit 1600 //-- default 1600//slow forward percentage without endpoint correction



//------------ servo cam setup ------------------------------
#define tolerance 3 //-- default 4//servo cam vibration cutoff 
#define front 10 //-- default 0//servo cam front center in moving aux position
#define Camsx -10 //--default 5// servo cam endpoint sx (reverse with camdx)
#define Camdx 180//-- default 175// servo cam endpoint dx (reverse with camsx)
#define fix 1500 //-- default 90//servo cam front center in fix aux position


//-------------led setup ------------------------------------
#define Streight 1300 //-- default 1500//neutral signal steering centered position for blinking arrow light 
#define Blinkpoint 200 //-- default 300//steering value where led start to blink.
#define rearstart 1400 //-- default 1300// reverse gear light start at 1300

//----------------------------------------- program part, nothing to do here ---------------

#include <Servo.h>
Servo myservo;
Servo camservo; 
#define N_STST  7 // default 7//rear steering vibration cutoff 
unsigned int stSt[ N_STST ];  
long toStSt = 0;           
int inSt = 0;                                         
int Tol = 0;
unsigned int auxpulse;           
unsigned int Rxpulse;
unsigned int Gaspulse ;
unsigned int Gain;
unsigned int NewPos, OldPos;
unsigned int newloc, oldloc;
unsigned int Centerpos = fix ;
int led1 = 4;
int led2 = 5;
int led3 = 6;
int led4 = 3;
byte impulsi=0;//(aggiunta)
byte stato=0; //stato zero suona, stato 1 ferma il suono (aggiunta)
unsigned long intervallo=0;//(aggiunta)
void setup() {
for ( int i=0; i<N_STST; i++ ) stSt[ i ] = 0;

myservo.attach(10); //--  rear servo signal out pin 10
pinMode(8, INPUT); //--  front servo signal in pin 8
pinMode(7, INPUT); //-- throttle signal in pin 7
camservo.attach(11); //-- cam servo out pin 11
pinMode(9, INPUT); //--aux servo signal in pin 9
pinMode(led1, OUTPUT); //--led blinker dx out pin 4
pinMode(led2, OUTPUT); //--led blinker sx out pin 5
pinMode(led3, OUTPUT); //--led retro brake out pin 6
pinMode (led4, OUTPUT); //-- led maxspeed out pin 3
intervallo=millis();//(aggiunta)
}
void loop(){  
auxpulse = pulseIn(9, HIGH);
Gaspulse = pulseIn(7, HIGH);
  noInterrupts();
Rxpulse = pulseIn(8, HIGH);   
interrupts();
delay(5);  
if (Gaspulse > Slowlimit){  //-- default >// if your throttle signal is reverse must change "<" 
Gain = map(Gaspulse, Slowlimit, Maxspeed, 0, Max_gain );
NewPos = map(Rxpulse, Antsx, Antdx, (Postsx + Gain), (Postdx - Gain));
} 
else{ 
NewPos = map(Rxpulse, Antsx, Antdx, Postsx, Postdx);
} 
if (abs(NewPos - OldPos)> Tol){ 
OldPos = NewPos;
myservo.write(NewPos + Center);}

//-- led part ----------
 if (OldPos > Streight+Blinkpoint) {digitalWrite(led1, (millis() / 100) % 2); //--default 100// is led blink speed 
              
 }else   digitalWrite(led1, LOW);  
if (OldPos < Streight-Blinkpoint){ digitalWrite(led2, (millis() / 100) % 2); //--default 100// is led blink speed 
               
} else  digitalWrite(led2, LOW);
  
if (Gaspulse < rearstart){digitalWrite(led3,HIGH); 

}else  digitalWrite(led3, LOW);
if (Gaspulse > Maxspeed-100){digitalWrite(led4,HIGH); //-- default 100// higher values start light before maxspeed

}else  digitalWrite(led4, LOW);

//-- aux cam part ----------

if(millis()-intervallo<=1000){//Se non è passato un secondo(aggiunta)
if(impulsi==4){//(aggiunta)
if(stato==0);//suona(aggiunta)
 else// spegni suono(aggiunta)
impulsi=0;//(aggiunta)
stato=!stato;}// end if(aggiunta)
}else{//Se è passato un secondo(aggiunta)
impulsi=0;//(aggiunta)
intervallo=millis();}//end if(aggiunta)
if (auxpulse > 1600){//--default > 1600// change aux position but check best value will can be 1400
camservo.write(fix);
delay (4);

}else {
 newloc = map(pulseIn(8, HIGH),Antsx,Antdx,Camsx,Camdx);


if(abs(newloc - oldloc) > tolerance){
oldloc = newloc;
camservo.write(newloc + front);
}
}
}

il cicalino non lo so usare, mi è capitato una sola volta di doverlo usare e credo che dovrei aggiungerlo scrivendo:

const int     = 2;//  piedino 2 libero al momento

pinMode(BUZZER_PIN, OUTPUT);

if condizione
digitalWrite( BUZZER_PIN, HIGH );

else
digitalWrite( BUZZER_PIN, LOW );

ho scritto Buzzer-pin per praticità ma non so ancora come aggiungerlo nel programma se sostituire a "stato", vedo cosa riesco a fare prima di testarlo sul modello.

ti ringrazio per la tua disponibilità.

questo è il codice che sto usando adesso sul camion compresi i settaggi che ho impostato.. funziona tutto molto bene.

//----------- signal setup -------------------------------------
#define Neutral 1445 // -- default 1500//minimum throttle forward signal or neutral position
#define Maxspeed 1932 // -- default 2000//maximum throttle forward signal 
#define Antsx 1041 // -- default 1000//in front servo signal sx
#define Antdx 1968 // -- default 2000//in front servo signal dx


//----------- rear servo setup -------------------------------
#define Postsx 700 //-- default 1000//out rear servo sx end point (if inverted with postdx it reverse)
#define Postdx 2000 //-- default 2000//out rear servo dx endpoint (if inverted with postsx it reverse)
#define Center 150 //-- default 0//add or subtract your value to center steering (+- 50 or more)

 
//--------- user driving setup ------------------------------ 
#define Max_gain 550 //-- default 400//gain steering reduction width at max throttle (if work reverse add (-) before value)
#define Slowlimit 1600 //-- default 1600//slow forward percentage without endpoint correction



//------------ servo cam setup ------------------------------
#define tolerance 3 //-- default 4//servo cam vibration cutoff 
#define front 10 //-- default 0//servo cam front center in moving aux position
#define Camsx -10 //--default 5// servo cam endpoint sx (reverse with camdx)
#define Camdx 180//-- default 175// servo cam endpoint dx (reverse with camsx)
#define fix 1500 //-- default 90//servo cam front center in fix aux position


//-------------led setup ------------------------------------
#define Streight 1300 //-- default 1500//neutral signal steering centered position for blinking arrow light 
#define Blinkpoint 200 //-- default 300//steering value where led start to blink.
#define rearstart 1400 //-- default 1300// reverse gear light start at 1300

//----------------------------------------- program part, nothing to do here ---------------

#include <Servo.h>
Servo myservo;
Servo camservo; 
#define N_STST  7 // default 7//rear steering vibration cutoff 
unsigned int stSt[ N_STST ];  
long toStSt = 0;           
int inSt = 0;                                         
int Tol = 0;
unsigned int auxpulse;           
unsigned int Rxpulse;
unsigned int Gaspulse ;
unsigned int Gain;
unsigned int NewPos, OldPos;
unsigned int newloc, oldloc;
unsigned int Centerpos = fix ;
int led1 = 4;
int led2 = 5;
int led3 = 6;
int led4 = 3;
void setup() {
for ( int i=0; i<N_STST; i++ ) stSt[ i ] = 0;

myservo.attach(10); //--  rear servo signal out pin 10
pinMode(8, INPUT); //--  front servo signal in pin 8
pinMode(7, INPUT); //-- throttle signal in pin 7
camservo.attach(11); //-- cam servo out pin 11
pinMode(9, INPUT); //--aux servo signal in pin 9
pinMode(led1, OUTPUT); //--led blinker dx out pin 4
pinMode(led2, OUTPUT); //--led blinker sx out pin 5
pinMode(led3, OUTPUT); //--led retro brake out pin 6
pinMode (led4, OUTPUT); //-- led maxspeed out pin 3
}
void loop(){  
auxpulse = pulseIn(9, HIGH);
Gaspulse = pulseIn(7, HIGH);
  noInterrupts();
Rxpulse = pulseIn(8, HIGH);   
interrupts();
delay(5);  
if (Gaspulse > Slowlimit){  //-- default >// if your throttle signal is reverse must change "<" 
Gain = map(Gaspulse, Slowlimit, Maxspeed, 0, Max_gain );
NewPos = map(Rxpulse, Antsx, Antdx, (Postsx + Gain), (Postdx - Gain));
} 
else{ 
NewPos = map(Rxpulse, Antsx, Antdx, Postsx, Postdx);
} 
if (abs(NewPos - OldPos)> Tol){ 
OldPos = NewPos;
myservo.write(NewPos + Center);}

//-- led part ----------
 if (OldPos > Streight+Blinkpoint) {digitalWrite(led1, (millis() / 100) % 2); //--default 100// is led blink speed 
              
 }else   digitalWrite(led1, LOW);  
if (OldPos < Streight-Blinkpoint){ digitalWrite(led2, (millis() / 100) % 2); //--default 100// is led blink speed 
               
} else  digitalWrite(led2, LOW);
  
if (Gaspulse < rearstart){digitalWrite(led3,HIGH); 

}else  digitalWrite(led3, LOW);
if (Gaspulse > Maxspeed-100){digitalWrite(led4,HIGH); //-- default 100// higher values start light before maxspeed

}else  digitalWrite(led4, LOW);

//-- aux cam part ----------

 
if (auxpulse > 1600){//--default > 1600// change aux position but check best value will can be 1400
camservo.write(fix);
delay (4);

}else {
 newloc = map(pulseIn(8, HIGH),Antsx,Antdx,Camsx,Camdx);


if(abs(newloc - oldloc) > tolerance){
oldloc = newloc;
camservo.write(newloc + front);
}
}
}

sto facendo delle prove ma per adesso ottengo errori se sostituisco auxpulse a impulsi.
però obbligatoriamente dei 3 segnali in entrata devo definire quello di aux per accendere il claxon, è anche l'unico che uso sporadicamente salvo non dover muovere la cam fpv.

wrighi:
credo che "impulsi" sia in realtà da sostituire con "Auxpulse" che sarebbe il segnale del canale aux

No, il codice di Torn24 è un esempio da cui partire e da sviluppare, la variabile 'impulsi' è il contatore di variazioni. Quali variazioni? Quelle della posizione dell'interruttore aux. Come si riconoscono le variazioni? Dalla variazione del valore della variabile 'auxpulse'.

Quindi serve un riconoscitore di variazione, magari con isteresi per ridurre la possibilità di letture errate dovute a disturbi:

if      (0==s0  &&  auxpulse>1750) { variazione = 1;   s0 = 1; }
else if (1==s0  &&  auxpulse<1250) { variazione = 1;   s0 = 0; }
else                               { variazione = 0;           }

A questo punto abbiamo una variabile 'variazione' che diventa 1 per un ciclo di programma quando l'interruttore viene spostato, e con questa variabile possiamo andare ad incrementare il contatore.

Tra l'altro secondo me il conteggio del tempo dovrebbe iniziare con la prima variazione, e da quel momento controllare se entro un secondo il contatore raggiunge il valore 4, UNA LOGICA TIPO QUESTA:

SE stato==0 E variaz

    t = millis
    cnt = 1
    stato = 1

ALTRIMENTI SE stato==1 E variaz

    cnt++
    SE cnt==4
        inverte uscita
        stato = 0

ALTRIMENTI SE stato==1 E timeout

    stato = 0

pensavo fosse una modifica più semplice, in questi termini non credo di arrivarci.
tra l'altro visto che che non si risolve in poche stringhe di codice temo che la modifica potrebbe influire sulla risposta della centralina e quindi sulla velocità di reazione dello sterzo posteriore.
forse per aggiungere un cicalino potrebbe non valerne la pena.
ad ogni modo vi ringrazio delle spiegazioni sempre molto interessanti.