radiocomando rc motor shield rev3

USA IL TAG CODE!

allora la

durata = pulseIn(servo1,HIGH);          // durata impulso

la fai ogni loop, non capisco che diavolo serva la if che hai messo, se non per far casino.

adj_val1 va da 0 a 255, non capisco cosa centri il 551

insomma sistema il codice, in pratica nel loop deve rimanere:
1 pulseIn (ovvero prendere l'input)
2 la gestione del motore

if(durata < 1650) { 
         digitalWrite (dirmotor,LOW);
         analogWrite (pwmmotor,adj_val1);
    }
         if(durata > 1450) { 
         digitalWrite (dirmotor,HIGH);
         analogWrite (pwmmotor,adj_val1);
    }

aggiustando però il fatto che le due durate "cozzano" tra di loro
3 il codice di debug sulla Serial.

devi assicurati che il valore di rc1 vari da 1100 a 1900, e che il motore risponda di conseguenza.

Hi,
are you just trying to use a RC transmitter and receiver to drive dc motors through a 293 or similar ic ?

If so I have a similar project which I plan to complete shortly, mine is a tracked vehicle which I want to control with my RC car transmitter. The transmitter has a trigger for throttle and a wheel for steering so I will be using a simple mapping on the throttle and steering channels to convert the steering input into a speed differential between the left and right motors, over all speed will be determined by the throttle input.

One thing you should consider is instead of using constrain to bring invalid inputs into a valid range, treat invalid input as an error and stop or slow down your vehicle, my RC cars run at 40km so it's very important that I deal with even the smallest error. at the very least you should turn on an indicator led for a short time every time you read an invalid post, that way you can at least tell if you have a problem you need to look into.

sorry for the English again

Duane B

cosi è quello che mi dicevi di usare il tag code? il codice potrebbe andare?l'ho provato ma cosi non mi legge nessun parametro del telecomando, nel serial monotor è tutto a zero.per il codice di dubug seriale non sò come si fa a vederlo.

int pwmmotor = 3; // motor 1 PWM
int dirmotor = 12; // motor 1 DIR
int servo1 = 2; // r/c channel 1
int power = 4; // power for R/C receiver, stays HIGH (5v).

volatile unsigned long servo1_startPulse;
volatile unsigned servo1_val;
volatile int adj_val1;
volatile int servo1_Ready;
volatile int durata;

int low1 = 1100;
int high1 = 1900;
int n = 0;

void setup() {

Serial.begin(9600);

pinMode(pwmmotor, OUTPUT);
pinMode(dirmotor, OUTPUT);
pinMode(power, OUTPUT);
pinMode(servo1, INPUT);

digitalWrite(power, HIGH);

delay(1200);
}

void loop() {

durata = pulseIn(servo1,HIGH); // durata impulso

adj_val1 = map(constrain(servo1_val, 1600, 1900), low1, high1, 0, 255);
constrain(adj_val1, 0, 255);

if(durata > 1600) {
digitalWrite (dirmotor,HIGH);
analogWrite (pwmmotor,adj_val1);
}

if(durata < 1400) {
digitalWrite (dirmotor,LOW);
analogWrite (pwmmotor,adj_val1);
}

Serial.print("ch1: ");
Serial.print(adj_val1);
Serial.print(" ");
Serial.print("rc1: ");
Serial.print(servo1_val);
Serial.print(" ");
Serial.print("loop counter: ");
Serial.print(n);
Serial.println(" ");

}

sì, questo è il tag code... c'è una bella differenza, che dici? :grin:

allora, tu fai:

durata = pulseIn(servo1,HIGH);  // durata impulso

e fin quì ok.
poi fai:

adj_val1 = map(constrain(servo1_val, 1600, 1900), low1, high1, 0, 255);

ma servi1_val non viene "scritta"(si dice inizializzata) da nessuna parte, quindi contiene un valore a caso (in questo caso 0)

di conseguenza adj_val1 rimarrà sempre a 0!
devi mettere durata al posto di servo1_val. (errore di distrazione?)

per codice di debug della seriale intendo il codice con cui mandi i valori via seriale per controllare se sono giusti, appunto il debug.
in pratica il codice di debug è questo:

  Serial.print("ch1:  ");
  Serial.print(adj_val1);
  Serial.print("  ");
  Serial.print("rc1:  ");
  Serial.print(servo1_val);
  Serial.print("  ");
  Serial.print("loop counter:  ");
  Serial.print(n);
  Serial.println("  ");

a cui manca la print di durata.

il resto mi pare a posto, vabbè qualche variabile messa lì a far la muffa ma niente di grave

si molto megliola lettura tag,scusa ma non ne conoscevo l'esistenza.
finalmente inizio a vedere qualche piccolo risultato,ho modificato questo:

adj_val1 = map(constrain(durata, 1600, 1900), low1, high1, 0, 255);
constrain(adj_val1, 0, 255);
e questo:
Serial.print("dura: ");
Serial.print(durata);
Serial.print("ch1: ");
Serial.print(adj_val1);
Serial.print(" ");
Serial.print("rc1: ");
Serial.print(servo1_val);
Serial.print(" ");
Serial.print("loop counter: ");
Serial.print(n);
Serial.println(" ");
ora però quando gli dò solo un inpulso avanti il motore gira in avanti senza variare velocità e senza fermarsi,poi dò un colpetto indietro e il motore inverte il senso di rotaione ma senza mai variare velocità e senza mai fermarsi.funziona un pò come un invertitore di marcia a piena velocità che come un variatore di velocità,non sò se mi sono spiegato.
ecco il serial:

dura: 2018ch1: 255 rc1: 0 loop counter: 0
dura: 1860ch1: 242 rc1: 0 loop counter: 0
dura: 3531ch1: 255 rc1: 0 loop counter: 0
dura: 6336ch1: 255 rc1: 0 loop counter: 0
dura: 1511ch1: 159 rc1: 0 loop counter: 0
dura: 1484ch1: 159 rc1: 0 loop counter: 0
dura: 1570ch1: 159 rc1: 0 loop counter: 0
dura: 1992ch1: 255 rc1: 0 loop counter: 0
dura: 3315ch1: 255 rc1: 0 loop counter: 0
dura: 1507ch1: 159 rc1: 0 loop counter: 0
dura: 1621ch1: 166 rc1: 0 loop counter: 0
dura: 1964ch1: 255 rc1: 0 loop counter: 0
dura: 5891ch1: 255 rc1: 0 loop counter: 0
dura: 1482ch1: 159 rc1: 0 loop counter: 0
dura: 1494ch1: 159 rc1: 0 loop counter: 0
dura: 1619ch1: 165 rc1: 0 loop counter: 0
dura: 1955ch1: 255 rc1: 0 loop counter: 0
dura: 6742ch1: 255 rc1: 0 loop counter: 0
dura: 1523ch1: 159 rc1: 0 loop counter: 0
dura: 1505ch1: 159 rc1: 0 loop counter: 0
dura: 1602ch1: 160 rc1: 0 loop counter: 0
dura: 5377ch1: 255 rc1: 0 loop counter: 0
dura: 6878ch1: 255 rc1: 0 loop counter: 0
dura: 1515ch1: 159 rc1: 0 loop counter: 0
dura: 1598ch1: 159 rc1: 0 loop counter: 0
dura: 1957ch1: 255 rc1: 0 loop counter: 0
dura: 5622ch1: 255 rc1: 0 loop counter: 0
dura: 1392ch1: 159 rc1: 0 loop counter: 0
dura: 1989ch1: 255 rc1: 0 loop counter: 0
dura: 1610ch1: 162 rc1: 0 loop counter: 0
dura: 5622ch1: 255 rc1: 0 loop counter: 0
dura: 10210ch1: 255 rc1: 0 loop counter: 0
dura: 1527ch1: 159 rc1: 0 loop counter: 0
dura: 1482ch1: 159 rc1: 0 loop counter: 0
dura: 1578ch1: 159 rc1: 0 loop counter: 0
dura: 5789ch1: 255 rc1: 0 loop counter: 0
dura: 1497ch1: 159 rc1: 0 loop counter: 0
dura: 1511ch1: 159 rc1: 0 loop counter: 0
dura: 1621ch1: 166 rc1: 0 loop counter: 0
dura: 1569ch1: 159 rc1: 0 loop counter: 0
dura: 6553ch1: 255 rc1: 0 loop counter: 0
dura: 1510ch1: 159 rc1: 0 loop counter: 0
dura: 1476ch1: 159 rc1: 0 loop counter: 0
dura: 1602ch1: 160 rc1: 0 loop counter: 0
dura: 1069ch1: 159 rc1: 0 loop counter: 0
dura: 2013ch1: 255 rc1: 0 loop counter: 0
dura: 1507ch1: 159 rc1: 0 loop counter: 0
dura: 1615ch1: 164 rc1: 0 loop counter: 0
dura: 1502ch1: 159 rc1: 0 loop counter: 0
dura: 6316ch1: 255 rc1: 0 loop counter: 0
dura: 1410ch1: 159 rc1: 0 loop counter: 0
dura: 1511ch1: 159 rc1: 0 loop counter: 0
dura: 1599ch1: 159 rc1: 0 loop counter: 0
dura: 1085ch1: 159 rc1: 0 loop counter: 0
dura: 6094ch1: 255 rc1: 0 loop counter: 0

edit: misono accorto che ho messoda 1600 -1900 anzichè 1100-1900

adj_val1 = map(constrain(durata, 1100, 1900), low1, high1, 0, 255);
constrain(adj_val1, 0, 255);

ora che l'ho cambiato fa lo stesso scherzo solo che quando gira in avanti gira veloce(PWM 255 +- fisso),mentre quando gira indietro(PWM basso) però sempre senza mai fermarsi.
PS.:non funziona più il tag code me lo copia cosi...

Vabbe con i tag ci puoi litigare dopo. Ora l'errore e nella map:tu vuoi che a 1600 il pwm sia 0, e che sia 255 sia a 1100 che a 1900.
O metti 2mappa nell'if oppure una mappa con valori da -255 a255 poi cambi l'of e dici che se il pwm e negativo attivi la retromarcia, se positivo la marcia normale. Poi fai il modulo del pwm e fai l'analogwrite

inanzi tutto non sò come mai se copi il codice con edit>copia per forum non mi copia più nel modo tag code ma copia normalissimamente(nel modo che non ci capisci un cazzo).
allora ho aggiunto un altro blocco map.sembrerebbe funzionare solo che non sò come mai il motore smatta quando gli impulsi di durata sono tra 1400 e 1600,mentre invece dovrebbe essere fermo in quel range o sbaglio?in più quando arrivi a fondo scala con la levetta del telecomando e poi molli,a volte il motore non si ferma rimane alla massima velocità.

int pwmmotor = 3; // motor 1 PWM
int dirmotor = 12; // motor 1 DIR
int servo1 = 2; // r/c channel 1
int power = 4; // power for R/C receiver, stays HIGH (5v).

volatile unsigned long servo1_startPulse;
volatile unsigned servo1_val;
volatile unsigned servo2_val;
volatile int adj_val1;
volatile int adj_val2;
volatile int servo1_Ready;
volatile int durata;

int low1 = 1100;
int high1 = 1400;
int low2 = 1600;
int high2 = 1900;
int n = 0;

void setup() {

Serial.begin(9600);

pinMode(pwmmotor, OUTPUT);
pinMode(dirmotor, OUTPUT);
pinMode(power, OUTPUT);
pinMode(servo1, INPUT);

digitalWrite(power, HIGH);

delay(1200);
}

void loop() {

durata = pulseIn(servo1,HIGH); // durata impulso

adj_val1 = map(constrain(durata, 1100, 1400), low1, high1, 255, 0);
constrain(adj_val1, 0, 255);

adj_val2 = map(constrain(durata, 1600, 1900), low2, high2, 0, 255);
constrain(adj_val2, 0, 255);

if(durata > 1600) {
digitalWrite (dirmotor,HIGH);
analogWrite (pwmmotor,adj_val2);
}

if(durata < 1400) {
digitalWrite (dirmotor,LOW);
analogWrite (pwmmotor,adj_val1);
}

Serial.print("dura: ");
Serial.print(durata);
Serial.print("ch1: ");
Serial.print(adj_val1);
Serial.print(" ");
Serial.print("rc1: ");
Serial.print(servo1_val);
Serial.print(" ");
Serial.print("loop counter: ");
Serial.print(n);
Serial.println(" ");

}

tu VORRESTI che stesse fermo, ma dove dici mai al motore di fermarsi?

scusa ma se adj_val1 modula il PWM da 1100 a 1400 (da 255 a 0) e adj_val2 modula il PWM da 1600 a 1900 (da 0 a 255), la zona da 1400 a 1600 non dovrebbe essere "morta" ovvero senza nessun segnale PWM?poi se porto lo stick del radiocomando avanti tutto arriva un segnale di circa 1900(motore avanti,PWM 255) ok,qundo lo mollo torna in posizione centrale circa 1500,quindi dato che non rientra in nessun valore adj_valX,non dovrebbero esserci segnali PWM in uscita o sbaglio?

ni, il problema è che se il segnale va da 1400 a 1600, tu non chiami l'analogWrite, che di conseguenza continua a ripetere l'ultima cosa che gli hai detto di fare.

quindi dovrei aggiungere un blocco che dice che da 1400 a 1600 e viceversa imposta il motore in HIGH o LOW però a 0 di PWM?!

esatto!
poi secondo me da 1400 a 1600 è troppo, farei da 1450 a 1550 (100 valori), più abbastti questo valore è più è preciso il comando, ma potrebbe diventare TROPPO sensibile...
un consiglio è usare 2 variabili, una che contiene il valore minimo e uno il massimo, in modo che cambiando 2 variabili ti sistemi tutti e 3 gli if come ti sta più comodo!

non avevo ancora letto la tua risposta e avevo provato gia a fare qualche modifica e ora a parte qualche piccolo accorgimento sembra funzionare bene ti metto il codice:
int pwmmotor = 3; // motor 1 PWM
int dirmotor = 12; // motor 1 DIR
int servo1 = 2; // r/c channel 1
int power = 4; // power for R/C receiver, stays HIGH (5v).

volatile unsigned servo1_val;
volatile unsigned servo2_val;
volatile int adj_val1;
volatile int adj_val2;
volatile int durata;

int low1 = 1100;
int high1 = 1450;
int low2 = 1520;
int high2 = 1900;
int n = 0;

void setup() {

Serial.begin(9600);

pinMode(pwmmotor, OUTPUT);
pinMode(dirmotor, OUTPUT);
pinMode(power, OUTPUT);
pinMode(servo1, INPUT);

digitalWrite(power, HIGH);

delay(1200);
}

void loop() {

durata = pulseIn(servo1,HIGH); // durata impulso

adj_val1 = map(constrain(durata, 1100, 1450), low1, high1, 255, 0);
constrain(adj_val1, 0, 255);

adj_val2 = map(constrain(durata, 1520, 1900), low2, high2, 0, 255);
constrain(adj_val2, 0, 255);

if(durata > 1520) {
digitalWrite (dirmotor,HIGH);
analogWrite (pwmmotor,adj_val2);
}

if(durata < 1450) {
digitalWrite (dirmotor,LOW);
analogWrite (pwmmotor,adj_val1);
}

if(durata >= 1450 && durata < 1520) {
digitalWrite (dirmotor,LOW);
analogWrite (pwmmotor,0);
}

Serial.print("dura: ");
Serial.print(durata);
Serial.print("ch1: ");
Serial.print(adj_val1);
Serial.print(" ");
Serial.print("rc1: ");
Serial.print(servo1_val);
Serial.print(" ");
Serial.print("loop counter: ");
Serial.print(n);
Serial.println(" ");

}

sti caxxo di TAG non funzionano più mi dispiace di farti impazzire a leggere.
L'ultimo problema è che quando spengo il telecomando il valore durata scende a zero quindi il motore viene modulato a PWM 255 per colpa del primo if.
ora provo a fare qualche modifichina e vede se riesco a sistemarlo.
Lesto ti ringrazio molto per tutta la pazienza che hai portato e per gli aiuti che mi hai dato,sono felice di essere entrato a far parte di questo forum e di aver conosciuto persone come te.

PS: non pensare che non mi risentirai più,di sicuro avrò ancora bisogno di aiuto :slight_smile:
Grazie

un piccolo trucco che sulla mia RC funziona: tutti i canali hanno un fondo di "rumore" per cui 2 letture non sono quasi mai uguali. Ma quando spengo la trasmittenet il canale del motore (e solo quello) diventa fisso ad un valore (circa 1100) e non cambia mai a meno che non riaccendo la trasmittente!

ma posso fare una roba del genere?

if (durata<1100)
analogWrite(durata.1500);

micky861:
ma posso fare una roba del genere?

if (durata<1100)
analogWrite(durata.1500);

analogWrite(durata.1500);???

scusa ho sbaglito a srivere intendevo aggiungere un blocco con:

if (durata<1100)
digitaWrite(dirmotor,LOW)
analogWrite(pwmmotor,0);
in modo che quando spengo il radiocomando il segnale durata scende a 0 quindi meno di 1100 imposta il PWM a 0, non dovrei puù avere quel probblema.

ok ho fatto cosi solo impostato a 1000 anzichè 1100 e funziona alla grande,devo solo testare il limite dei valori(sensibilità e poi si passa al passo successivo,ovvero conrtrollare un servo (ch2) però gestito da un giroscopio in modo che il servo riporti sempre il gyro in posizione neutra a meno che intervenga il comando da ch2 e bypassy il gyro,praticamente il gyro e servo devono mantenere un albero in asse spostando un peso a pendolo incernierato su di esso a meno che io controlli il servo per far spostare il pendolo e piegare l'asse(bypass del gyro)...

mi spiace ma non è così semplice. il giroscopio piano piano accumula errore. spiega bene cosa devi fare

allora immagina una sfera vuota,con un asse x che la attravesa al centro ok,se a questo asse c'è attaccato un pendolo al centro,spostando il pendolo il centro di gravità si sposta quindi l'asse si inclina,e cosi non sarebbe poi cosi difficile controllando un servo radiocomandato(ormai ho capito :)) però deve lavorare anche al contrario cioè se l'asse si inclina da solo a sinistra x es ,il pendolo controbilancia spostandosi a destra in modo da tenere sempre l'asse in orizzontale a prescindere dale interferenze esterne che potrebbero inclinare l'asse.ipotizzando che tutto funzioni cosi vorrei però poter bypassare il gyro o accelerometro che sia per potere inclinare il pendolo a mio piacimento.
per quanto riguarda la parte meccanica non ci sono problemi,poi ho a disposizione sia un gyro della tinkerkit 4x che un accelerometro sempre tinkerkit.
vorrei farti un disegno ma non sò come fare...