buenas soy nuevo en el foro, estoy armando un mando para slot car, lo que quiero hacer es: mediante una entrada analogica (potenciometro) que cada ves q aumente el valor, este vaya del valor menor al valor mayor en X cantidad de tiempo, y una ves q llegue sl valor mayor q quede constante hasta que vuelva a incrementarlo, o reducirlo e incrementarlo, ej valor 50 y aumento a 255 y q en 100ms haga ese transcurso, giro el pote y bajo a 100 subo a 150 y q incremente en tambien 100ms, todo esta pra poder reflejrlo en una salida analogWrite, espero se entienda y me puedan ayudr, muchas gracias por todo lo que vengo aprendiendo del foro en estos años!!!
Ok. Que has hecho? porque si vienes aprendiendo del foro habras leído que hay que leer las normas y que hay que postear los códigos esten bien o mal para que luego podamos sugerirte como corregir los fallos.
si tal cual, con respecto al codigo, es que en verdad es un simple potenciómetro en una entrada analogica, mapeado de 0 a 255, y lo q kiero hacer/entender es que funcion realizar, para cuando estoy en un valor mayor al anterior, transcurra hasta el valor mayor (el cual puede variar y ser menor que el mayor o mayor) y ese transcurso lo haga en cierto tiempo controlado por otra entrada analogica, estoy sin la pc, y no se como citar el codigo aqui, trate de acerlo con un if y lastval pero se me crea un bucle y no es la idea, ya que luego de llegar al valor mayor este pueda disminuir o volver a aumentar y que vuelva a suceder el objetivo deseado, seria como un fade in la idea, o un acelerador de un coche
ni bien tenga acceso al pc ya copio y subo el codigo que va a swr mas facil de entender la idea que quiero lograr
Ahora te he entiendo, y estaba claro solo que a veces no lo visualizo inmediatamente:
este vaya del valor menor al valor mayor en X cantidad de tiempo, y una ves q llegue sl valor mayor q quede constante hasta que vuelva a incrementarlo, o reducirlo e incrementarlo,
Lo que quieres es una rampa de aceleración o desaceleración.
Estas con V1 y pasas a V2, bueno que eso no sea instantáneo sino que le lleve X tiempo. Eso es acelerarar tu slot car o desacelerarlo.
lo mejor que puedes hacer es primero ir a
Ve a Documentación => Indice de temas tutoriales => millis() y también lee máquina de estados.
Lee ambas cosas porque las vas a necesitas.
Basicamente tomas tu V1 como velocidad de partida.
Y el código detecta que cambiaste a V2 para lo que habrá que darle una ventana de tiempo para qu elo haga.
Entonces dado un tiempo T diras, paso de V1 a V2 en ese tiempo y lo hago en tantos pasos que bueno tu determinarás.
Todo esto me hace pensar que tu slot car esta fuencionando con una interfaz de potencia PWM de lo contrario no es posible realizarlo.
Asi que lo primero será detectar que hay un cambio de velocidad en el pulsador (entiendase que es tu potenciómetro).
Luego inciar la secuencia de A/D (aceleracion/desaceleracion).
Qué opinas de la idea?
@surbyte
tal cual y exactamente, uso un npn y un pnp tip42 para el pwm, lo de milis lo tengo el otro ejdmplo nunca lo observe, el tema es q no se me cae una idea de co generar la funcion para q lo haga, solo me interesa q acelere no desacelerar, tendrias una idea de como seria si mediante un if o un while?? como para encaminarme un poco con la idea, igual hoy voy a prestarle mas atencion a lo q me dijiste que lea y me interiorice
Retrasar la aceleración, entiendo que lo quieres para que sea un poco más real. Pero porqué quieres esto también para frenar?
@ElEspanol
creo q aclare q para frenar no me interesa, ya q no seria necesario, pero la parte de aceleracion si se llama anti spinning, pero no encontre nada q me ayude un poco en toda la red
Tengo algunas dudas con la forma de implementarlo.
Transmito mi pensamiento y tu me dices que esperas..
Voy a hablar en terminos de un potenciometro o pulsador que varia de 0 a 1023 tal como el ADC lo convierte.
Entonces supongamos estar a una velocidad (no importa la salida en este análisis) de 300.
Tu presionas el pulsador y cambia a digamos 800.
Lo primero es que debo tener un umbral con el que no haré nada.. digamos Velocidad constante ya que el ADC no reportará siempre un valor fijo de 300, sino que este cambiará digamos en +- 10 Asi que tendriamos que usar algo como un UMBRAL de 10
una funcion tipo
En algún momento defines
#define UMBRAL 10
y luego determinas asi si hubo o no cambios
if (abs(valorActual - valorAnt) > UMBRAL) [
Sería como el comienzo de la deteccion de un cambio de velocidad aunque fuese mínimo.
En nuestro caso de 300 a 800 es un salto de 500 que es lo que se busca
Luego iniciamos una rampa en un tiempo, digamos 2 segundos
El slot car ira de una salida que por ejemplo un map podria facilmente resolver de este modo
pwm = map(velocidad, 0, 1023, 0, 255);
300 del ADC se convierte en => velocidad/1023255 = 74 ya que son enteros
y 800 por su parte en => 800/1023255 = 199
O sea que pasamos de una salida 74 PWM a 199 PWM en 2 segundos
Si armamos un rutina que cada 100mseg incrementamos ese valor en 1/20, ya que hablamos de 2000 mseg dividido 100 mseg, lo que me da 20 pasos.
Obvio cosas simples como el tipo de variable para la variable paso y que debe estar a 0 antes de empezar la aceleración.
La variable velocidad comienza en 300
Entonces una posible rutina de aceleración sería
if (millis() - start > 100UL) {
paso++; // variable tipo byte que lleva los pasos
if (paso <= 20) {
velocidad += (valorActual - valorAnt)/20;
pwm = map(velocidad, 0, 1023, 0, 255);
analogWrite(pin, pwm);
}
}[/code]
start es una variable del tipo unsigned long que se carga con el valor de millis() cuando se detecta cambio de velocidad en el pulsador.
if (abs(valorActual - valorAnt) > UMBRAL) {
start = millis();
}
Ahora lo reviso por si cometi algun error.
Considera que estoy pensando en voz alta, asi que es una primera idea.
Pensando también con los dedos en el teclado, lo solucionaría más bien con un average (promedio), pero depende del tiempo de retrasar. ¿ Hablamos de p.e. 30% a 100% de segundos o de centésimas?
P.s.
#define UMBRAL 10
Mejor
const int umbral=10;
Pero trabajando con un promedio un umbral no hace falta.
centesimas tal cual con un average, ahora voy a buscar info sobre el tema, igualmente no se q esta pasando con los arduinos nano q vienen muy malos, eh quemado dos hoy y sin cortos ni nada raro, asi q hasta que compre un par tengo tiempo para investigar
ahora voy a buscar info sobre el tema
Como se promedia? Sumas N valores y divides por N.
Me llama la atención lo de los NANOs. Jamas he quemado uno y espero que no empiece la cuenta a partir de este comentario.
Que tienes conectado?
En este caso usaría la lib RunningMedian, tiene también función average. Añadir cada x millisegundos un valor de una lectura del poti.
Y para ajustarlo fácil en la practica, conectar otro potenciometro y variar con este el valor x de 1 ms a p.e. 30ms.
Y el RunningMedian con 15 elementos.
ElEspanol:
En este caso usaría la lib RunningMedian, tiene también función average. Añadir cada x millisegundos un valor de una lectura del poti.
Y para ajustarlo fácil en la practica, conectar otro potenciometro y variar con este el valor x de 1 ms a p.e. 30ms.
Y el RunningMedian con 15 elementos.
exacto con otro pote llamado traccion o anti spinning regularia el tiempo, m intereso mucho lo d la libreria y sino con el umbral q lo entendi bastante rapido, mañana lo sumo al mi codigo y lo subo, asi toma forma!!! mas q agradecido!!
Bueno este seria mi código.
Son 3 potes:
1 para regular la cantidad de Freno mapeado de 0 a 255.
2 Curva mapeado de 0 a 100.
3 gatillo (acelerador) mapeado de 0 255.
El gatillo es menor a 30 para tener un poco de presión y no salga andando el auto, corta la salida pwm y comienza la salida del freno.
Acá lo dejo cualquier ayuda de donde y como ir metiendo y armando el código seria un éxito tanto para mi como para los que quieran hacerse un mando electrónico!!!
int pote = A0;
int poteFreno = A1;
int poteCurva = A2;
int frenodemano = 8;
int fdm;
int pwm = 9;
int pinfreno = 10;
int CURVA;
int FRENO;
int pwmin;
int salidapwm;
int salidafreno;
void setup() {
pinMode(frenodemano, INPUT_PULLUP);
}
void loop() {
pwmin = map((analogRead(pote)), 0, 185, 0, 255);
FRENO = map ((analogRead (poteFreno)), 0, 1023, 0, 255);
CURVA = map ((analogRead (poteCurva)), 0, 1023, 0, 100);
salidapwm = map (pwmin, 30, 255, CURVA, 255);
if (pwmin >= 31) {
analogWrite(pinfreno, 0);
analogWrite(pwm, salidapwm);
}
else {
analogWrite(pwm, 0);
analogWrite(pinfreno, FRENO);
}
fdm = digitalRead(frenodemano);
if (fdm == LOW) {
analogWrite(pwm, 0);
analogWrite(pinfreno, 255);
}
}
Ya he visto como es el mando electrónico.

Este podría ser un ejemplo, adaptando un pulsador y luego los controles de freno, etc, etc
O algo asi, con todo integrado:
No se a los demas, pero a mi se me facilitan las cosas cuando las veo.. aunque eso no cambie la programación, ahora entiendo porque hablas de 3 potenciometros por ejemplo y lo que tu das por sentado, para el resto son cosas que tenemos que entender.
Luego te daré algun aporte respecto del código.
surbyte, tal cual no me di cuenta demostrar a lo queme referia, no queria ser redundante, pero si, el gatillo es un pote sale por pwm 9, otro pote el freno sale por pwm 10, un switch en digital 8 que esel freno de mano, y la idea es agregar un 4to pote que seria la traccion/antisppining que regula el tiempo de la rampa ascendente de velocidad, esideal para cuando salimos de una curva en pista si apretamos bastante el gatillo q el auto no salga patinando sino gradualmente
No eres redundante, recuerda que este es un foro de Arduino no de slot car, he visto que hay foros de controladores de slot (motivo de este hilo), que serían mas adecuados pero es un lindo tema para debatir.
si tienes razón!! eh estado viendo varios foros de slot, pero no hay muuucho en concreto con respecto a la programacion, y menos aun con arduino, y como lo mas practicp es usar las placas arduino a comprar pic, me gusto la idea de poder crear un mando completo y funcional, y que quede registrado en la red, para los que nos gusta hacer nuestras propias cosas!! ojala tome forma y salga algo lindo!!!
Gente perdon por mi ignorancia pero seria algo asi el codigo aportado por surbyte? donde y como tendria q colocar la igualdad entre valorActual y valorAnt? se me esta haciendo un embrollo el cerebro, el start1 esta bien asi para el millis?
const int UMBRAL=10;
int pwm;
int pin =9;
int paso=0;
int velocidad;
int valorActual;
int valorAnt;
unsigned long start1;
void setup() {
}
void loop() {
if (abs(valorActual - valorAnt) > UMBRAL) {
start1 = millis();
}
if (millis() - start1 > 100UL) {
paso++;
if (paso <= 20) {
velocidad += (valorActual - valorAnt)/20;
pwm = map(velocidad, 0, 1023, 0, 255);
analogWrite(pin, pwm);
}
}
}
Bueno el programa compila, veamos si hace lo que se pretende.
Aclaro que me gusta mas la propuesta de ElEspanol respecto de RunningMedian porque seguirá mejor los cambios.
Mira esta grafica
En linea verde el promedio movil que siempre he sugerido para muchos casos. Observa cuando hay un cambio brusco que mal se comporta. En cambio el filtro media en azul que indicó ElEspanol, es un calco de lo que se esta haciendo sin ruido.
Esto es el código sin ningún filtro aun. Solo tiene ese umbral que comenté al principio. Veamos como se comporta.
#define PASOS 20
const int UMBRAL = 10;
const byte pinPWM = 9;
int pwmOutput;
byte paso = 0;
unsigned int velocidad;
unsigned int valorActual;
unsigned int valorAnt;
bool flag = false;
unsigned long start1;
void setup() {
}
void loop() {
valorActual = analogRead(A0); // supongo potenciometro conectado a A0
if (abs(valorActual - valorAnt) > UMBRAL) {
velocidad = valorAnt; // establezco el valor desde donde comienza a incrementarse
flag = true; // activo rutina de aceleracion
start1 = millis();
}
if (millis() - start1 > 100UL && flag) {
paso++;
if (paso <= 20) {
velocidad += (valorActual - valorAnt)/PASOS;
pwmOutput = map(velocidad, 0, 1023, 0, 255);
analogWrite(pinPWM, pwmOutput);
}
else {
flag = false; // se alcanzó el final del loop de aceleración.
}
start1 = millis();
}
valorAnt = valorActual; // En cada loop me aseguro que los valores se igualan y
// solo un cambio inica la rutina
}
