[risolto] problemi con servo e ricevitore rc progetto 4 ruote sterzanti

Buona domenica a tutti, mi sono appena iscritto per cercare informazioni e possibili soluzioni.

sul forum di modellismo che frequento e grazie all'aiuto di altri modellisti più capaci di me, è nato un progetto per fare sterzare le ruote posteriori di un automodello rc

((ho editato il post perchè sono andato avanti e ho trovato molte soluzioni.))

la controller dovrà gestire i seguenti parametri:

-è necessaria la centratura delle ruote definita da utente: define center
-è necessario poter settare i fine corsa del servo posteriore per non sforzare la meccanica: define Postsx Postdx

  • serve poter stringere la corsa del servo in modo inversamente proporzionale al gas in modo da avere una macchina 4 ruote sterzanti a bassa velocità e una macchina con corsa ridotta o annullata del servo posteriore ad alta velocità, portandola ad essere una comune macchina 2 ruote sterzanti: Max_gain
  • serve iniziare a ridurre la corsa del servo solo dopo una certa percentuale di gas avanti in modo di avere le 4 ruote sterzanti con tutta l'escursione possibile quando il modello andrà piano: Slowlimit
  • in retromarcia nulla deve essere cambiato dalla posizione di neutro, ovvero per tutta la retro dovrà esserci le 4 ruote sterzanti al massimo della corsa.

per ottenere questo ho definito la corsa massima del servo anteriore 1000-2000 : Antsx Antdx
ho definito la corsa massima del gas: Maxspeed 2000
ho definito il neutro dove la macchina sarà ferma 1500: Neutral
infine ho aggiunto una tolleranza per le vibrazioni del servo: tolerance

funziona quasi tutto eccetto il problema che descrivo nel post 3
mi potete aiutare a risolverlo per favore?
l'allegato in questo post è obsoleto ma non riesco a rimuoverlo, il codice corretto è al post 3
grazie a tutti.

apud6z1F.txt (505 Bytes)

#include <Servo.h>
Servo myservo;
int rxpulse;
void setup() {
myservo.attach(10); //-- piedino segnale servo
pinMode(8, INPUT); //-- piedino che legge RX-AUX
pinMode(9,INPUT); //--piedino che legge RX-STR
}

void loop() {
rxpulse = pulseIn(8, HIGH); //-- piedino segnale proveniente dalla ricevente
if (rxpulse > 1600)
{
myservo.write( 1500); //-- centratura del servo su canale AUX1
}
else
{
myservo.write(map(pulseIn(9,HIGH), 923,2085,10,175)); //--servo amplifica sterzo in gradi
}
}

Prima di tutto ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post ...

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

Guglielmo

P.S.: Il tuo post è già stato spostato nell'opportuna sezione del forum "Italiano”dove puoi proseguire la discussione.
P.P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

arrivo fino qui ma non riesco a trovare ancora una soluzione

sono riuscito a far funzionare quasi tutto ma rimane un singolo problema che vorrei risolvere.

al momento funziona quasi tutto come dovrebbe, compresa la possibilità di dare un pochino di gas a bassa velocità mantenendo tutto lo sterzo (cambiando valore a Slowlimit)

adesso anche la correzione Gain funziona perfettamente , inversamente proporzionale e fino a chiudere completamente la corsa del servo posteriore (cambiando valore a Max_gain)

anche la centratura del servo e la corsa massima in retromarcia adesso funziona tutto come dovrebbe: rimane la massima corsa disponibile per tutta la retromarcia e posso centrare le ruote su un valore definito.

però se cambio i valori di Slowlimit e Max_gain adesso a macchina ferma in neutral si spostano anche i finecorsa Postdx e Postsx obbligandomi a reimpostarli da capo ogni volta di conseguenza alle modifiche dei suddetti parametri.

è un problema perchè sarebbero valori che dovrebbero restare fissi visto che dipendono dalla effettiva corsa di sterzo a disposizione.
cambiando i parametri e di conseguenza Postsx e Postdx si rischia di allargare la corsa molto oltre quella che lo sterzo meccanicamente permette e questo è spiacevole.

i fine corsa sarebbero uno dei parametri da impostare per primi e poi dimenticare.

non so, manca qualche parentesi oppure va scritto meglio qualcosa, c'è uno sbaglio ma non riesco a trovare l'inghippo.

vorrei poter settare i parametri che indicano il comportamento del servo senza veder cambiare la corsa massima e gli endpoint del servo che vorrei semplicemente definire con Postsx e Postdx

in pratica adesso se tocco Slowlimit e Max_gain accade che si stringono gli endpoint Postsx e Postdx quando la macchina è ferma in neutro col gas a zero e questo costringe a trovare sempre un nuovo compromesso dei fine corsa ogni volta che setto qualcos'altro..

funziona tutto più o meno come dovrebbe, ma questa piccola problematica costringe a trovare ogni volta un compromesso di Postsx e Postdx anche cambiando di poco i settaggi Slowlimit e Max_gain

se avete una soluzione vi ringrazio dell'aiuto.

riporto lo sketch rivisto e corretto al meglio delle sue attuali possibilità

#define Neutral 1500 // -- minimum forward signal
#define Maxspeed 2000 // -- maximum forward signal
#define Antsx 1000 // -- in front servo signal sx
#define Antdx 2000 // -- in front servo signal dx
#define Postsx 5 // out rear servo sx endpoint if inverted with postdx it reverse
#define Postdx 175 //-- out rear servo dx endpoint if inverted with postsx it reverse
#define Center 0 //-- add or subtract xx value to center steering
#define Tolerance 3 //-- if  poor quality servo vibrates try 5
#define Max_gain 100 //--  gain steering reduction by throttle if reverse add -
#define Slowlimit 1700 //-- slow forward without endpoint correction
#include <Servo.h>
Servo myservo;
unsigned int Rxpulse;
unsigned int Gaspulse ;
unsigned int Gain;
unsigned int NewPos, OldPos;
void setup() {
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);
if (Gaspulse > Slowlimit);
else
Gaspulse = constrain (Slowlimit, Neutral, Maxspeed);
Gain = map(Gaspulse, Neutral, Maxspeed, 0, Max_gain);
NewPos = map(Rxpulse, Antsx, Antdx, (Postsx + Gain), (Postdx - Gain));
if (abs(NewPos - OldPos)> Tolerance) {
OldPos = NewPos;
myservo.write(NewPos + Center);
}
}

questo è il circuito dei servi del modello

per favore avete un suggerimento? vedete uno sbaglio, una dimenticanza?

il nodo che non riesco a sciogliere è:

se io uso un define significa che Postsx e Postdx sono definiti, non si toccano. non sono variabili in gioco ma valori definiti.

allora perchè cambiando i valori di Slowlimit e Max_gain ( altri 2 valori definiti ) vedo accorciarsi o allungarsi la corsa del servo appena carico il programma con la radio in neutro?

cambiando Slowlimit mi aspetterei di avere solo maggiore corsa del gas a disposizione per usare lo sterzo posteriore con tutta la corsa definita da Postsx Postdx

cambiando Max_gain mi aspetterei di veder cambiare l'ampiezza della corsa disponibile del servo quando arriva a maxspeed ovvero tutto gas, serve solo a scegliere se arrivati a tutto gas avere chiusa tutta la corsa o lasciarne una parte utilizzabile.

non mi aspetto ed è spiacevole vedere scombinare il settaggio dei fine corsa che sono stati definiti con 2 valori precisi.

ho scritto male oppure manca qualcosa, magari anche solo un paio di { } ma non c'arrivo.

adesso provo a trasformare Postsx Postdx in microseconds.

lo sketch adesso è questo e sta funzionando abbastanza bene, è comunque utilizzabile su una macchina rc con radio 2 canali per controllare lo sterzo posteriore.
col segnale del gas si può decidere di far chiudere il servo alla massima velocità e determinare a quale velocità avviare la correzione.

/* 
I used an inexpensive nano board v3 ATmega 328p the pins used are VIN(+)and GND(-) 
you can feed the power from your bec (5-9 volt) 
the pins I used are: pin D7 throttle signal input. D8 front steering input signal. D10 rear steering signal output.
-----------------------------------------
basic setup instructions: first you get the best mechanical setup of the rear servo.
the values you find by default should make the controller work quite right away.
however if you want to be sure about what are your real radio signals,check them before starting this sketch. 
create a new tab and check your input signals with this program (7 for steering - 8 for throttle gas)

int rxpulse;
void setup () {
Serial.begin (9600);
}
void loop () {
rxpulse = pulseIn (7, HIGH); // - 7 to know true front steering signal 8 throttle
Serial.println (rxpulse);

you can read the values in the serial monitor by turning the steering wheel of the radio control and moving the throttle.
write the values obtained in the first part of the setup, replace the default ones with yours send by transmitter.
-------------------------------------------------- ------
the user driving setup consists of 2 functions: you can choose how much throttle allow at low speed 
before the width of the rear servo starts to close (Speedlimit function).

the second function allows you to determine the rear servo width  at maximum throttle (Max_gain).
you can choose to close it completely or leave a width available to turn with 4 steering wheels even at maximum speed

the other functions are: tolerance that avoids the rhythmic vibrations of the loop.
if the servo is good it could stay at zero, analog or low quality servos want at least a value of 4
it can happen that you exceed with the values and invert the direction, be careful to find the best suitable values for your model.
to get the servo reverse you just have to exchange the Postsx Postdx rear steering values and put a sign (-) in front of the Max_gain value
---------
there is a relationship between Slowlimit and Max_gain, it can happen that if you lower one you will have to raise the other
however I am sure that it will take you little time to understand how it works
*/


//----------- 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 650 //-- gain steering reduction width at max throttle (if reverse add (-) before value)
#define Slowlimit 1800 //-- slow forward percentage without endpoint correction

#define Tolerance 50 //-- if poor quality servo vibrates try 5 (also try (0) before decide)

//------------ here start the program, you don't need to change anything here --------------------------

#include <Servo.h>
Servo myservo;
unsigned int Rxpulse;
unsigned int Gaspulse ;

unsigned int Gain;
unsigned int NewPos, OldPos;
void setup() {
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);

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);
}
}

questa versione è molto più veloce nella risposta e il servo non ha più vibrazioni.
funziona tutto ed è pronta per essere provata su una macchina rc con servo di sterzo posteriore.

/* 
I used an inexpensive nano board v3 ATmega 328p the pins used are VIN(+)and GND(-) 
you can feed the power from your bec (5-9 volt) 
the pins I used are: pin D7 throttle signal input. D8 front steering input signal. D10 rear steering signal output.
-----------------------------------------
basic setup instructions: first you get the best mechanical setup of the rear servo.
the values you find by default should make the controller work quite right away.
however if you want to be sure about what are your real radio signals,check them before starting this sketch. 
create a new tab and check your input signals with this program (7 for steering - 8 for throttle gas)

int rxpulse;
void setup () {
Serial.begin (9600);
}
void loop () {
rxpulse = pulseIn (7, HIGH); // - 7 to know true front steering signal 8 throttle
Serial.println (rxpulse);

you can read the values in the serial monitor by turning the steering wheel of the radio control and moving the throttle.
write the values obtained in the first part of the setup, replace the default ones with yours send by transmitter.
-------------------------------------------------- ------
the user driving setup consists of 2 functions: you can choose how much throttle allow at low speed 
before the width of the rear servo starts to close (Speedlimit function).

the second function allows you to determine the rear servo width  at maximum throttle (Max_gain).
you can choose to close it completely or leave a width available to turn with 4 steering wheels even at maximum speed

the other functions are: tolerance that avoids the rhythmic vibrations of the loop.
if the servo is good it could stay at zero, analog or low quality servos want at least a value of 4
it can happen that you exceed with the values and invert the direction, be careful to find the best suitable values for your model.
to get the servo reverse you just have to exchange the Postsx Postdx rear steering values and put a sign (-) in front of the Max_gain value
---------
there is a relationship between Slowlimit and Max_gain, it can happen that if you lower one you will have to raise the other
however I am sure that it will take you little time to understand how it works
*/

//----------- 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 30 //-- add or subtract your value to center steering (+- 50 or more)
 
//--------- user driving setup ------------------------------
 
#define Max_gain 400 //-- gain steering reduction width at max throttle (if reverse add (-) before value)
#define Slowlimit 1800 //-- 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(){
    noInterrupts();   
Rxpulse = pulseIn(8, HIGH);
Gaspulse = pulseIn(7, HIGH);
     interrupts();     
delay(5);
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);
}
}