Torna indietro   BaroneRosso.it - Forum Modellismo > Elettronica > Circuiti Elettronici


Rispondi
 
Strumenti discussione Visualizzazione
Vecchio 05 maggio 20, 10:55   #1 (permalink)  Top
User
 
L'avatar di nicolap
 
Data registr.: 02-10-2019
Residenza: Orvieto
Messaggi: 388
Forse è un'idea malsana ma una strada percorribile potrebbe essere quella di far leggere solo il canale dello sterzo e dare al servo delle ruote posteriori un andamento esponenziale... Del resto in massima velocità difficilmente si porta lo stick dello sterzo a fine corsa...credo
Con la lettura di un solo canale, dalle prove che ho fatto, mi è sembrato che i valori acquisiti siano abbastanza precisi.


Inviato dal mio PRA-LX1 utilizzando Tapatalk
nicolap non è collegato   Rispondi citando
Vecchio 05 maggio 20, 13:01   #2 (permalink)  Top
Guest
 
Data registr.: 17-07-2013
Messaggi: 3.734
con un solo canale funziona perfettamente l'altro sketch, quello nel quale decidi solo la corsa e il verso.
certo che a tutto gas ti trovi a dare tutto sterzo.. il senso di questa applicazione è solo quella di limitarlo proporzionalmente quando superi un certo valore del gas, altrimenti va benissimo l'altra dove il gas non è collegato.
mi riferisco a questa che funziona benissimo https://pastebin.com/s27QJ37c

comunque la soluzione è questa

Codice:
#include <Servo.h>
Servo myservo;
 
 
#define N_STORIASTERZO  7              // numero valori passati utilizzati per il calcolo della media valori sterzo. Da cambiare sperimentalmente
#define N_STORIAGAS     7              // numero valori passati utilizzati per il calcolo della media valori gas. Da cambiare sperimentalmente

unsigned int storiaSterzo[ N_STORIASTERZO ];  // array di N_STORIASTERZO elementi che memorizza gli ultimi valori di sterzo letti dal radiocomando per calcolarne la media
unsigned int storiaGas[ N_STORIAGAS ];        // array di N_STORIAGAS elementi che memorizza gli ultimi valori di gas letti dal radiocomando per calcolarne la media
 
long totaleStoriaSterzo = 0;            // conterrà sempre la somma degli ultimi N_STORIA valori di sterzo letti dal radiocomando, per poi fare la media
                                        // (inizializzato a zero perché tutti i valori inizialmente sono zero)
                                        // lo dichiaro long perché se N_STORIA è grande la somma di int potrebbe andare in overflow
 
long totaleStoriaGas = 0;               // conterrà sempre la somma degli ultimi N_STORIA valori di gas letti dal radiocomando, per poi fare la media
                                        // (inizializzato a zero perché tutti i valori inizialmente sono zero)
                                        // lo dichiaro long perché se N_STORIA è grande la somma di int potrebbe andare in overflow                                        
                                 
int indiceSterzo = 0;                   // posizione del prossimo elemento che entra nella storia, da spostare passo dopo passo. Partiamo da zero
                                        // (in realtà, dato che al primo passo si incrementa subito, potremmo inizializzarlo a -1, ma non cambia nulla
                                        // perché fa tutto il giro
 
int indiceGas = 0;                      // posizione del prossimo elemento che entra nella storia, da spostare passo dopo passo. Partiamo da zero
                                        // (in realtà, dato che al primo passo si incrementa subito, potremmo inizializzarlo a -1, ma non cambia nulla
                                        // perché fa tutto il giro                                        
                                 
 

 
unsigned int Rxpulse;
unsigned int Gaspulse ;
 
unsigned int Gain;
unsigned int NewPos, OldPos;
void setup() {
 
  for ( int i=0; i<N_STORIASTERZO; i++ ) storiaSterzo[ i ] = 0;
  for ( int i=0; i<N_STORIAGAS; i++ ) storiaGas[ i ] = 0;
 
  myservo.attach(10); //-- rear servo signal out pin
  pinMode(8, INPUT); //-- front servo signal in pin
  pinMode(7, INPUT); //-- throttle signal in pin
}
 
void loop(){
  Rxpulse = pulseIn(8, HIGH);
  Gaspulse = pulseIn(7, HIGH);
 
 
  Rxpulse  = mediaStoriaSterzo( Rxpulse );
  Gaspulse = mediaStoriaGas( Gaspulse );
  
 
  if (Gaspulse > Slowlimit) {
    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)> Tolerance) {
    OldPos = NewPos;
    myservo.write(NewPos + Center);
  }
}
 
unsigned int mediaStoriaSterzo( unsigned int valore ) {
  /*
   * questa funzuine ritorna il valor medio degli ultimi N_STORIA valori elaborati,
   * incluso l'ultimo, cancellando il più vecchio dei valori attualmente memorizzati
   * I valori sono memorizzati nell'array 'storia'
   * Per cancellare e sostituire il valore più vecchio, invece di spostarli tutti all'indietro e far posto al nuovo,
   * andiamo noi a scegliere il valore da sostituire spostando un indice.
   * Si parte da 0 e si va avanti sino in fondo, poi si torna a zero.
   * Il primo giro in assoluto sostituiamo i valor iniziali tutti a zero, poi effettivamente cominceremo a sostituire il più veccio di tutti
   */
 
   // determino la posizione su cui operare: incremento l'indice per andare sul prossimo, se arriva in fondo torna a zero
   if ( ++indiceSterzo >= N_STORIASTERZO ) indiceSterzo = 0;
 
   // aggiorno il totale, sottraendo il valore vecchio e sommando il nuovo
   totaleStoriaSterzo = totaleStoriaSterzo - storiaSterzo[ indiceSterzo ] + valore;
 
   // memorizzo il nuovo valore al posto di quello vecchio
   storiaSterzo[ indiceSterzo ] = valore;
 
   // ritorno la media: totale diviso numero elementi
   return( totaleStoriaSterzo / N_STORIASTERZO );
}
 
unsigned int mediaStoriaGas( unsigned int valore ) {
  /*
   * come la precedente, ma per il valore di Gas
   */
 
   // determino la posizione su cui operare: incremento l'indice per andare sul prossimo, se arriva in fondo torna a zero
   if ( ++indiceGas >= N_STORIAGAS ) indiceGas = 0;
 
   // aggiorno il totale, sottraendo il valore vecchio e sommando il nuovo
   totaleStoriaGas = totaleStoriaGas - storiaGas[ indiceGas ] + valore;
 
   // memorizzo il nuovo valore al posto di quello vecchio
   storiaGas[ indiceGas ] = valore;
 
   // ritorno la media: totale diviso numero elementi
   return( totaleStoriaGas / N_STORIAGAS );

}
non vibra più nulla
wrighizilla non è collegato   Rispondi citando
Vecchio 05 maggio 20, 14:15   #3 (permalink)  Top
User
 
L'avatar di ElNonino
 
Data registr.: 06-05-2007
Residenza: Tre Ville (Preore)
Messaggi: 3.605
Invia un messaggio via MSN a ElNonino
Ma in Arduino per iniziallizzare un array a 0 occore fare così:

for ( int i=0; i<N_STORIASTERZO; i++ ) storiaSterzo[ i ] = 0;
for ( int i=0; i<N_STORIAGAS; i++ ) storiaGas[ i ] = 0;

Per il resto la soluzione adottata è una semplice media mobile (credo si potrebbe fare meglio anche in Wire) sul segnale d'ingresso che è evidentemente "ballerino", sarebbe da verificare il tempo di risposta all'impulso di tali filtri, considerando che il mezzo è lento non dovrebbe dare problemi.

Se i campionamenti sono multipli di 2 (ed è bene che lo siano) anzichè usare la divisione spesso conviene usare lo spostamento a dx di n bit, mentre la divisone richiede diversi cicli del microprocessore lo shifright ne usa uno solo.

__________________
Peace & Love
Fate le cose nel modo più semplice possibile, ma senza semplificare. (A. Einstein)
ElNonino non è collegato   Rispondi citando
Vecchio 05 maggio 20, 14:44   #4 (permalink)  Top
Guest
 
Data registr.: 17-07-2013
Messaggi: 3.734
in pratica questo è un filtro.
La funzione mediaStoria ( entrambe, sono uguali) funzionano un po' come se mettessi un condensatore in parallelo al filo che porta i valori: invece di darti il valore diretto lo media con i precedenti.
se i valori oscillano intorno al valore 10, come 7, 9, 11, 12, 10
la loro media è 9.
Se il prossimo valore fosse 13, si butta via il 7, la media diventa 11. Se il prossimo fosse 8 la media sarà 10.
Quindi le oscillazioni vengono ammortizzate.
Più grande è il numero di elementi che vengono conservati e meno pesa un valore difforme dagli altri, quindi tutto si stabilizza.
Ma accelerando devono uscire diversi valori bassi prima che i nuovi valori alti prevalgano e alzino la media, quindi si ottiene una maggiore lentezza della risposta.
Il tutto si svolge in microsecondi ad ogni giro.
il ritmo effettivo lo determina pulseIn che sta fermo a misurare la linea in attesa dei fronti del segnale.

questo è lo sketch ripulito dai commenti, rivisto e corretto.
perfettamente stabile e funzionante.

Codice:
//----------- signal setup -------------------------------------
#define Neutral 1500 // -- minimum throttle forward signal
#define Maxspeed 2000 // -- maximum throttle forward signal
#define Antsx 1000 // -- in front servo signal sx
#define Antdx 2000 // -- in front servo signal dx
#define Postsx 1000 // out rear servo sx end point (if inverted with postdx it reverse)
#define Postdx 2000 //-- out rear servo dx endpoint (if inverted with postsx it reverse)
#define Center 0 //-- add or subtract your value to center steering (+- 50 or more)
 
//--------- user driving setup ------------------------------
 
#define Max_gain 600 //-- gain steering reduction width at max throttle (if reverse add (-) before value)
#define Slowlimit 1700 //-- slow forward percentage without endpoint correction
 
#define Tolerance 0 //-- if poor quality servo vibrates try 5 

//----------------------------
 
#include <Servo.h>
Servo myservo; 
#define N_STST  7              
#define N_STGAS     7    
unsigned int stSt[ N_STST ];  
unsigned int stGas[ N_STGAS ];       
long toStSt = 0;           
long toStGas = 0;         
int inSt = 0;                                         
int inGas = 0;           
unsigned int Rxpulse;
unsigned int Gaspulse ;
unsigned int Gain;
unsigned int NewPos, OldPos;
void setup() {
for ( int i=0; i<N_STST; i++ ) stSt[ i ] = 0;
for ( int i=0; i<N_STGAS; i++ ) stGas[ i ] = 0;
myservo.attach(10); //-- rear servo signal out pin
pinMode(8, INPUT); //-- front servo signal in pin
pinMode(7, INPUT); //-- throttle signal in pin
}
void loop(){
Rxpulse = pulseIn(8, HIGH);
Gaspulse = pulseIn(7, HIGH);
Rxpulse  = meStSt( Rxpulse );
Gaspulse = meStGas( Gaspulse );
if (Gaspulse > Slowlimit) {
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)> Tolerance) {
OldPos = NewPos;
myservo.write(NewPos + Center);
}
}
unsigned int meStSt( unsigned int val ) {
if ( ++inSt >= N_STST ) inSt = 0;
toStSt = toStSt - stSt[ inSt ] + val;
stSt[ inSt ] = val;
return( toStSt / N_STST );
}
unsigned int meStGas( unsigned int val ) {
if ( ++inGas >= N_STGAS ) inGas = 0;
toStGas = toStGas - stGas[ inGas ] + val;
stGas[ inGas ] = val;
return ( toStGas / N_STGAS );
}

Ultima modifica di wrighizilla : 05 maggio 20 alle ore 14:48
wrighizilla non è collegato   Rispondi citando
Vecchio 05 maggio 20, 15:06   #5 (permalink)  Top
User
 
Data registr.: 03-05-2020
Residenza: milano
Messaggi: 47
Eccomi di ritorno.

Un po' di dati

Frequenza segnale in uscita dalla radio 50 Hz (alcune anche 60Hz)
numero di impulsi in un secondo quindi 50.

se per fare il calcolo ne aspettiamo 2 di impulsi abbiamo un ritardo di 1sec/50cicli=20msx2=40 mS.
Attendendo i 7 necessari a fare la media diventano 20*7=140 ms.
Abbiamo un ritardo di 1.4 decimi di secondo..

Non va bene per la reattività giusto?

avete letto il post 106 ?
Smsteves non è collegato   Rispondi citando
Vecchio 05 maggio 20, 16:32   #6 (permalink)  Top
Guest
 
Data registr.: 17-07-2013
Messaggi: 3.734
Citazione:
Originalmente inviato da Smsteves Visualizza messaggio
Eccomi di ritorno.

Un po' di dati

Frequenza segnale in uscita dalla radio 50 Hz (alcune anche 60Hz)
numero di impulsi in un secondo quindi 50.

se per fare il calcolo ne aspettiamo 2 di impulsi abbiamo un ritardo di 1sec/50cicli=20msx2=40 mS.
Attendendo i 7 necessari a fare la media diventano 20*7=140 ms.
Abbiamo un ritardo di 1.4 decimi di secondo..

Non va bene per la reattività giusto?

avete letto il post 106 ?
i valori accettabili del filtro sono tra 5 e 10
sotto 5 tornano le vibrazioni, sopra 15 ti accorgi che lo sterzo diventa troppo lento.
ho messo entrambi a 7 aggiungendo una spiegazione in modo che chiunque possa provarlo e trovare il miglior setup per la sua combo.

https://pastebin.com/CCwhsw6F

l'ho letto il post 106 ma non tutte le combo sono uguali, anche solo cambiando il servo cambia molto sul mio banco prova.
l'oscilloscopio non lo possiedo nemmeno.
però faccio volenteri mattina incaponito a provare

ad ogni modo non posso che ringraziarvi tutti perchè è solo in questo modo che sono potuto andare avanti ed aver impararato qualcosa.

se volete vi giro un video del risultato ottenuto.

Ultima modifica di wrighizilla : 05 maggio 20 alle ore 16:38
wrighizilla non è collegato   Rispondi citando
Vecchio 05 maggio 20, 16:40   #7 (permalink)  Top
User
 
L'avatar di ElNonino
 
Data registr.: 06-05-2007
Residenza: Tre Ville (Preore)
Messaggi: 3.605
Invia un messaggio via MSN a ElNonino
Chris, quello che fai è appunto una media mobile, in un altro post l'avevo consigliata mi pare a Minestrone per un suo problema di acquisizione dati, viene usata assai spesso per filtrare dati provenienti da convertitori A/D, sensori I2C, SPI che possono essere sporchi, però in genere la si applica in routine che non dipendono dal main loop, in genere o si lavora sotto interrupt od in DMA che blocca il micro per pochissimi microsecondi.

Come ha scritto Smsteves avrai un ritardo di, a mio avviso, 40 x 8 = 320ms più forse altri ms per calcoli e varie, non è sicuramente un sistema reattivo e forse al limite anche per il tuo camion ( a proposito: complimenti veramente molto bello e ben fatto).

Il problema di Arduino è che molte librerie sono bloccanti, cioè quando ne viene richiamata una funzione il micro resta in attesa fino alla fine della stessa, hai provato a vedere cosa succede se spegni il Tx dopo aver mosso lo stick del gas o dello sterzo ? Se la routine resta impallata in attesa degli impulsi il camion diventa incontrollabile, andrebbe perlomeno inserito un timeout che metta tutto in stato di sicurezza.

IMHO

__________________
Peace & Love
Fate le cose nel modo più semplice possibile, ma senza semplificare. (A. Einstein)
ElNonino non è collegato   Rispondi citando
Vecchio 05 maggio 20, 16:59   #8 (permalink)  Top
User
 
L'avatar di nicolap
 
Data registr.: 02-10-2019
Residenza: Orvieto
Messaggi: 388
Citazione:
Originalmente inviato da ElNonino Visualizza messaggio
Chris, quello che fai è appunto una media mobile, in un altro post l'avevo consigliata mi pare a Minestrone per un suo problema di acquisizione dati, viene usata assai spesso per filtrare dati provenienti da convertitori A/D, sensori I2C, SPI che possono essere sporchi, però in genere la si applica in routine che non dipendono dal main loop, in genere o si lavora sotto interrupt od in DMA che blocca il micro per pochissimi microsecondi.



Come ha scritto Smsteves avrai un ritardo di, a mio avviso, 40 x 8 = 320ms più forse altri ms per calcoli e varie, non è sicuramente un sistema reattivo e forse al limite anche per il tuo camion ( a proposito: complimenti veramente molto bello e ben fatto).



Il problema di Arduino è che molte librerie sono bloccanti, cioè quando ne viene richiamata una funzione il micro resta in attesa fino alla fine della stessa, hai provato a vedere cosa succede se spegni il Tx dopo aver mosso lo stick del gas o dello sterzo ? Se la routine resta impallata in attesa degli impulsi il camion diventa incontrollabile, andrebbe perlomeno inserito un timeout che metta tutto in stato di sicurezza.



IMHO



La funzione di timeout già esiste..
pulsein(pin, HIGH, 20000)

Dove l'ultima cifra è appunto il timeout espresso in microsecondi, se non riceve segnali in quel lasso di tempo restituisce 0. 20000 corrisponde al tempo che intercorre tra due impulsi successivi

Inviato dal mio PRA-LX1 utilizzando Tapatalk
nicolap non è collegato   Rispondi citando
Vecchio 05 maggio 20, 17:04   #9 (permalink)  Top
Guest
 
Data registr.: 17-07-2013
Messaggi: 3.734
Citazione:
Originalmente inviato da ElNonino Visualizza messaggio
Chris, quello che fai è appunto una media mobile, in un altro post l'avevo consigliata mi pare a Minestrone per un suo problema di acquisizione dati, viene usata assai spesso per filtrare dati provenienti da convertitori A/D, sensori I2C, SPI che possono essere sporchi, però in genere la si applica in routine che non dipendono dal main loop, in genere o si lavora sotto interrupt od in DMA che blocca il micro per pochissimi microsecondi.

Come ha scritto Smsteves avrai un ritardo di, a mio avviso, 40 x 8 = 320ms più forse altri ms per calcoli e varie, non è sicuramente un sistema reattivo e forse al limite anche per il tuo camion ( a proposito: complimenti veramente molto bello e ben fatto).

Il problema di Arduino è che molte librerie sono bloccanti, cioè quando ne viene richiamata una funzione il micro resta in attesa fino alla fine della stessa, hai provato a vedere cosa succede se spegni il Tx dopo aver mosso lo stick del gas o dello sterzo ? Se la routine resta impallata in attesa degli impulsi il camion diventa incontrollabile, andrebbe perlomeno inserito un timeout che metta tutto in stato di sicurezza.

IMHO

è veloce quanto basta, che ti devo dire..
se lo vuoi migliorare ulteriormente ho condiviso il codice apposta.
non serve a nulla stare a discutere su cosa succede se spengo la tx.. tu spengi la tx su i tuoi modelli accesi? sono forse controllabili i tuoi modelli con la tx spenta?
nel video vedi come si muove adesso e come lo fa a corsa chiusa quando sto dando tutto gas.. vedi anche come si muove con il gas parzializzato e sotto slowlimit compresa la retro.
se non ti piace o ti sembra inutilizzabile aspetto volentieri il tuo sketch con le soluzioni che ti sembreranno migliori.. al momento questo è un risultato che considero molto soddisfacente.


Ultima modifica di wrighizilla : 05 maggio 20 alle ore 17:10
wrighizilla non è collegato   Rispondi citando
Vecchio 05 maggio 20, 17:35   #10 (permalink)  Top
User
 
L'avatar di ElNonino
 
Data registr.: 06-05-2007
Residenza: Tre Ville (Preore)
Messaggi: 3.605
Invia un messaggio via MSN a ElNonino
Citazione:
Originalmente inviato da wrighizilla Visualizza messaggio
è veloce quanto basta, che ti devo dire..
se lo vuoi migliorare ulteriormente ho condiviso il codice apposta.
non serve a nulla stare a discutere su cosa succede se spengo la tx.. tu spengi la tx su i tuoi modelli accesi? sono forse controllabili i tuoi modelli con la tx spenta?
nel video vedi come si muove adesso e come lo fa a corsa chiusa quando sto dando tutto gas.. vedi anche come si muove con il gas parzializzato e sotto slowlimit compresa la retro.
se non ti piace o ti sembra inutilizzabile aspetto volentieri il tuo sketch con le soluzioni che ti sembreranno migliori.. al momento questo è un risultato che considero molto soddisfacente.

Chris, tranquillo, mica ho scritto che non funziona, poi se va bene a te a chi altri deve andare bene ?

Il fail safe era un suggerimento perchè potresti anche perdere il segnale od altro, il camion è tuo ed anche la responsabilità quando lo fai andare quindi la cosa non mi tange.

Non posso metterti uno sketch per Arduino perchè, come ho scritto più volte, lo uso solo per piccole applicazioni ed utilizzo più che altro l'hardware che programmo direttamente i C, senza usare librerie di terzi, chiaramente so leggere un programma scritto in wire essendo simile al C ed alcuni concetti come la media mobile od usare lo shift al posto di divisione e moltiplicazione valgono per qualsiasi microprocessore si utilizzi.

buon divertimento, passo e chiudo.


__________________
Peace & Love
Fate le cose nel modo più semplice possibile, ma senza semplificare. (A. Einstein)
ElNonino non è collegato   Rispondi citando
Rispondi

Bookmarks




Regole di scrittura
Non puoi creare nuove discussioni
Non puoi rispondere alle discussioni
Non puoi inserire allegati
Non puoi modificare i tuoi messaggi

BB code è Attivato
Le faccine sono Attivato
Il codice [IMG] è Attivato
Il codice HTML è Disattivato
Trackbacks è Disattivato
Pingbacks è Disattivato
Refbacks è Disattivato


Discussioni simili
Discussione Autore discussione Forum Commenti Ultimo Commento
buggy da completare BoBoPoP Automodellismo Mot. Scoppio Off-Road 41 18 maggio 16 17:56
monster da completare...! bronto_19 Automodellismo Mot. Elettrico Off-Road 2 22 giugno 10 17:35
Sto costruendo uno schiumino (o tzagi), mi aiutate??? crido96 Aeromodellismo Principianti 72 07 febbraio 10 02:26
Come completare una associated B4? ryan-j Automodellismo Mot. Elettrico On-Road 9 04 maggio 08 11:55



Tutti gli orari sono GMT +2. Adesso sono le 23:07.


Basato su: vBulletin versione 3.8.11
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
E' vietata la riproduzione, anche solo in parte, di contenuti e grafica. Copyright 1998/2019 - K-Bits P.I. 09395831002