¡Bienvenido visitante ! ¡Apúntate al foro ! ¡Es gratuito !
Aquí encontrarás respuesta a muchas de tus preguntas sobre modelismo ferroviario.
¡Puedes preguntar a tus anchas y aportar tus conocimientos!
Aquí encontrarás respuesta a muchas de tus preguntas sobre modelismo ferroviario.
¡Puedes preguntar a tus anchas y aportar tus conocimientos!
MOVIENDO DESVÏOS
MOVIENDO DESVÏOS
Hola
Tengo casi terminado un "motor" para mover desvíos basado en un servo bajo el tablero
Dejo unas fotos del primer prototipo, en unos días subiré los ficheros STL para imprimirlo en 3D
He usado un servo SG90 y una corredera para tener un movimiento lineal, el brazo del servo se recorta para dejar solo el 1er agujero donde se inserta un tornillo de M2x10mm, le h eañadido un remache para mejorar el rozamiento.
Un video del funcionamiento
Saludos
Tengo casi terminado un "motor" para mover desvíos basado en un servo bajo el tablero
Dejo unas fotos del primer prototipo, en unos días subiré los ficheros STL para imprimirlo en 3D
He usado un servo SG90 y una corredera para tener un movimiento lineal, el brazo del servo se recorta para dejar solo el 1er agujero donde se inserta un tornillo de M2x10mm, le h eañadido un remache para mejorar el rozamiento.
Un video del funcionamiento
Saludos
- Adjuntos
-
- VISTA_3.jpg (106.19 KiB) Visto 447 veces
-
- VISTA_2.jpg (125.33 KiB) Visto 447 veces
-
- VISTA_1.jpg (133.45 KiB) Visto 447 veces
-
- DESPIECE.jpg (1.05 MiB) Visto 449 veces
Lenz + 2C + K.Bay
Re: MOVIENDO DESVÏOS
Hola
Os dejo los ficheros STL por si es de interés de alguien
Saludos
Os dejo los ficheros STL por si es de interés de alguien
Saludos
- Adjuntos
-
- SG90 Servo holder.zip
- (70.93 KiB) Descargado 27 veces
Lenz + 2C + K.Bay
Re: MOVIENDO DESVÏOS
Muchas gracias por la información.
Saludos Luis.
Saludos Luis.
Multimaus,DCC-gen,NanoX-88+Minimaus(ultimo firm),RENFE-H0 y de momento sin maqueta.
Re: MOVIENDO DESVÏOS
Muy ingenioso Salus. Y más cómodo que los soportes de chapa de aluminio que hice yo.
Saludos.
Manolo
Saludos.
Manolo
Vivan las motos gordas
Re: MOVIENDO DESVÏOS
para quitarse el sombrero.
Sunpongo que la velocidad se prodrá regular a gusto del consumidor
saludos
Sunpongo que la velocidad se prodrá regular a gusto del consumidor
saludos
Re: MOVIENDO DESVÏOS
Hola
Inicialmente monte estos soportes, van bien y son más sencillos, pero en escala N y vía código 55, la oscilación del alambre hace que sobresalga demasiado, según la posición y qhe algún material rodante roce y descarrile, el ajuste es muy crítico. en H0 no daría ningún problema, pero si en N.
Por ello he pasado al diseño ma´s complejo, pero consiguiendo un desplazamiento lineal
Saludos
Inicialmente monte estos soportes, van bien y son más sencillos, pero en escala N y vía código 55, la oscilación del alambre hace que sobresalga demasiado, según la posición y qhe algún material rodante roce y descarrile, el ajuste es muy crítico. en H0 no daría ningún problema, pero si en N.
Por ello he pasado al diseño ma´s complejo, pero consiguiendo un desplazamiento lineal
Saludos
- Adjuntos
-
- DISEÑO ANTIGUO
- IMG-1532.jpg (1.13 MiB) Visto 396 veces
Lenz + 2C + K.Bay
Re: MOVIENDO DESVÏOS
Muy cierto Salus, doy fe. No con tus soportes, naturalmente, pero sí con los de chapa de aluminio que yo me hice y que tienen el mismo funcionamiento oscilante.
Saludos.
Manolo
Vivan las motos gordas
- palaycarbon
- Forero
- Mensajes: 615
- Registrado: Jue Feb 16, 2006 4:54 pm
- 20
Re: MOVIENDO DESVÏOS
En su día adapté el mecanismo de Melinda (h0-fine.de) para usar servos "grandes". Su sistema está hecho a base de piezas planas y separadores, de los utilizados en electrónica para montar una placa sobre otra.
También incorpora un mecanismo de palanca para girar la señal que indica la posición del cambio de agujas.
Lástima no tener la posibilidad de sacarles una foto. Y como sigamos saturando los bares y zonas de ocio no lo podré hacer en una temporada.
También incorpora un mecanismo de palanca para girar la señal que indica la posición del cambio de agujas.
Lástima no tener la posibilidad de sacarles una foto. Y como sigamos saturando los bares y zonas de ocio no lo podré hacer en una temporada.
¡Vivan las estaciones sin señales de entrada! 
Re: MOVIENDO DESVÏOS
Son ferritas lo que aparecen en el cable de los servos para evitar interferencias? ¿de que tipo?
Re: MOVIENDO DESVÏOS
Lenz + 2C + K.Bay
Re: MOVIENDO DESVÏOS
Hola a todos/as
Dejé esto a medias por estar con otro "lio", que cerré ayer
Como decoder para controlar servos, además de los comerciales, hay muchos montajes en la web con PIC y con Arduino.
Para mover un servo, he optado por la opción de Arduino, usando el “attiny85” de la familia de micros usados en las placas Arduino, pero con un formato DIL8, programable desde el IDE de Arduino
Desde hace tiempo tenía ganas de usar este micro, poco a poco me metí en ello y este es el resultado, le he llamado SERVO_MOTOR_2020
Aquí está todo lo referente a cómo usar este chip https://teslabem.com/arduino/programar- ... duino-uno/
El montaje se hace sobre un PCB de 35x38 mm, que encaja en el soporte del servo
En un principio el soporte era vertical, aunque simple, lo cambie por los problemas que explico en mi anterior post, cambiando la tapa de la versión final del soporte, el PCB encaja encima, quedando un montaje muy robusto.
En los adjuntos está el esquema y algunas fotos, el proyecto del PCB está aquí https://circuitmaker.com/Projects#/servo-motor/7//1
Diferencias ATtiny85/UNO
Memoria Flash (KB) - 8/32, para el sketch
SRAM (kB) - 0.5/2, para las variables
Pins I/O - 6/22, sumando digitales y analógicos
Control del servo
La librería “Servo.h” que se instala por defecto al instalar el IDE usa un “timer” de 16 bits, este micro tiene un “timer” de 8 bits, he probado varias librerías para control del servo con este micro, la que me ha dado mejor resultado (y ocupa menos memoria) es la librería “SoftwareServo.h”, cuando movemos el servo hay que añadir una llamada a la función “SoftwareServo::refresh()”
Uso pin “reset”
Este micro tiene un pin de “reset”, también se puede usar como pin analógico o digital, pero es complicado hacerlo ya que hemos de programarlo quemando los fusibles del micro, con esto nos complicamos la vida para hacer marcha atrás y programarlo de nuevo, para no desperdiciar este pin, usaremos un “truco” para que sea fácil de usar en el sketch.
Para forzar un reset, la tensión de este pin ha de ser menor de 2,2V aproximadamente, con un partidor resistivo (ver esquema) mantenemos la tensión a unos 3.8V, cuando pulsamos K1 la tensión sube a 5V
En la función “ResetRead()”, con analogRead() obtenemos el valor digital correspondiente a 3.8V, alrededor de “650” y de “1023” para 5V, este valor lo comparamos con la variable “AnLimit”, si es inferior la tecla no está pulsada, si es superior la tecla está pulsada, con ello retornamos un 1 ó 0, como si de una lectura de un pin digital se tratara
Memoria
Este micro solo tiene 8K de memoria para el sketch, a diferencia de los 32K del UNO o NANO, con 8K se pueden hacer muchas cosas, pero hay que controlar el tamaño del sketch
El sketch
Inicialmente quería hacer un solo sketch para las dos versiones (analógico y digital), aunque hay funciones comunes complica mucho el seguimiento del proceso, terminé por hacer dos sketch
La programación la he hecho sobre un Arduino UNO, para poder tenerlo conectado por el puerto USB y usar el terminar serie como DEBUG, luego he hecho los ajustes sobre el ATTINY, al inicio del sketch hay unas directivas para el compilador (#define), para cambiar la compilación del programa según nos interese
#define ATTINY - habilita la compilación según micro, comentar para usar UNO/NANO
#define SERIAL_DEBUG - habilita Serial.print, usar solo con UNO/NANO
#define RELE - habilita el relé, comentar para no usar el relé
#define DOS_TECLAS - para usar una o dos teclas RECTO/DESVIADO en la versión analógica
El sketch esta comentado para poder seguir el flujo del proceso, al inicio se encuentra un manual de uso
Compilando la versión digital se ocupa el 91% del espacio en memoria para el ATTINY85
Saludos
Dejé esto a medias por estar con otro "lio", que cerré ayer
Como decoder para controlar servos, además de los comerciales, hay muchos montajes en la web con PIC y con Arduino.
Para mover un servo, he optado por la opción de Arduino, usando el “attiny85” de la familia de micros usados en las placas Arduino, pero con un formato DIL8, programable desde el IDE de Arduino
Desde hace tiempo tenía ganas de usar este micro, poco a poco me metí en ello y este es el resultado, le he llamado SERVO_MOTOR_2020
Aquí está todo lo referente a cómo usar este chip https://teslabem.com/arduino/programar- ... duino-uno/
El montaje se hace sobre un PCB de 35x38 mm, que encaja en el soporte del servo
En un principio el soporte era vertical, aunque simple, lo cambie por los problemas que explico en mi anterior post, cambiando la tapa de la versión final del soporte, el PCB encaja encima, quedando un montaje muy robusto.
En los adjuntos está el esquema y algunas fotos, el proyecto del PCB está aquí https://circuitmaker.com/Projects#/servo-motor/7//1
Diferencias ATtiny85/UNO
Memoria Flash (KB) - 8/32, para el sketch
SRAM (kB) - 0.5/2, para las variables
Pins I/O - 6/22, sumando digitales y analógicos
Control del servo
La librería “Servo.h” que se instala por defecto al instalar el IDE usa un “timer” de 16 bits, este micro tiene un “timer” de 8 bits, he probado varias librerías para control del servo con este micro, la que me ha dado mejor resultado (y ocupa menos memoria) es la librería “SoftwareServo.h”, cuando movemos el servo hay que añadir una llamada a la función “SoftwareServo::refresh()”
Uso pin “reset”
Este micro tiene un pin de “reset”, también se puede usar como pin analógico o digital, pero es complicado hacerlo ya que hemos de programarlo quemando los fusibles del micro, con esto nos complicamos la vida para hacer marcha atrás y programarlo de nuevo, para no desperdiciar este pin, usaremos un “truco” para que sea fácil de usar en el sketch.
Para forzar un reset, la tensión de este pin ha de ser menor de 2,2V aproximadamente, con un partidor resistivo (ver esquema) mantenemos la tensión a unos 3.8V, cuando pulsamos K1 la tensión sube a 5V
En la función “ResetRead()”, con analogRead() obtenemos el valor digital correspondiente a 3.8V, alrededor de “650” y de “1023” para 5V, este valor lo comparamos con la variable “AnLimit”, si es inferior la tecla no está pulsada, si es superior la tecla está pulsada, con ello retornamos un 1 ó 0, como si de una lectura de un pin digital se tratara
Memoria
Este micro solo tiene 8K de memoria para el sketch, a diferencia de los 32K del UNO o NANO, con 8K se pueden hacer muchas cosas, pero hay que controlar el tamaño del sketch
El sketch
Inicialmente quería hacer un solo sketch para las dos versiones (analógico y digital), aunque hay funciones comunes complica mucho el seguimiento del proceso, terminé por hacer dos sketch
La programación la he hecho sobre un Arduino UNO, para poder tenerlo conectado por el puerto USB y usar el terminar serie como DEBUG, luego he hecho los ajustes sobre el ATTINY, al inicio del sketch hay unas directivas para el compilador (#define), para cambiar la compilación del programa según nos interese
#define ATTINY - habilita la compilación según micro, comentar para usar UNO/NANO
#define SERIAL_DEBUG - habilita Serial.print, usar solo con UNO/NANO
#define RELE - habilita el relé, comentar para no usar el relé
#define DOS_TECLAS - para usar una o dos teclas RECTO/DESVIADO en la versión analógica
El sketch esta comentado para poder seguir el flujo del proceso, al inicio se encuentra un manual de uso
Compilando la versión digital se ocupa el 91% del espacio en memoria para el ATTINY85
Código: Seleccionar todo
/*
Control de versiones
V1 - Funcionamiento para Arduino UNO
V2 - Funcionamiento para ATtiny85
V3 - Version final para ATtiny85, con rele monoestable
V4 - Cambio a rele biestable, pulsador en pin analógico
V5 - Se mejora el control del servo (attach/detach)
V6 - Se optimizan funciones de inicializaciónReducción para reducir el uso de memoria
MANUAL DE FUNCIONAMIENTO
Funcionamiento normal, desde la central se selecciona la dirección DCC programada, con las teclas +/- se cambia la posición del servo
Tecla multifunción K1, se usa para mover el servo manualmente y para la programación de la dirección DCC, la velocidad y los ángulos de desplazamiento del servo
K1 pulsado al arranque > mueve servo a posición central, se detiene el programa, para alinear los espadines en la instalación en la maqueta
K1 multifuncion, depende de la duración de la pulsación se accede a una función diferente, se ha de soltar la tecla en el momento adecuado para pasar a la función deseada
El paso de una funciona a otra se muestra con un parpadeo del LED, cada 3s aproximadamente
Pulsación corta (<3s) cambia la posición del servo, el relé cambia a mitad del recorrido
Pulsación (>3s y <6s), muestra la dirección DCC a base de destellos del LED, se muestran 4 dígitos
Pulsación (>6s y <9s), programación de una nueva dirección DCC, el led parpadea, hasta que se envíe una nueva dirección DCC desde la central
enviando una orden de cambio a la nueva dirección, esta quedará programada, el led de apagará
Pulsación (>9s y <12s), programación de los ángulos de desplazamiento
- El servo se mueve a posición central, el led parpadea
- Desde la central, seleccionando la dirección DCC programada, movemos el servo con las teclas +/-, para ajustar la posición RECTO
- Al pulsar K1, la posición del servo se guarda como posición RECTO del desvío
- El LED hace un parpadeo lento
- Desde la central, seleccionando la dirección DCC programada, movemos el servo con las teclas +/-, para ajustar la posición DESVIADO
- Al pulsar K1, la posición del servo se guarda como posición DESVIADO del desvío
- El LED se apaga
- Durante el ajuste, si el LED deja de parpadear y luce fijo, es el aviso de que se ha llegado al límite máximo/mínimo
- Al seleccionar por separado los angulos para las posiciones RECTO/DESVIADO, no importa la instalación mecánica del servo
Pulsación (>12s y <15s), programación de la velocidad de desplazamiento
- El servo se mueve alternativamente de un lado a otro, el led parpadea
- Desde la central, seleccionando la dirección DCC programada, movemos el servo con las teclas +/- para cambiar la velocidad de desplazamiento
- Al pulsar K1, la velocidad del servo se guarda, el LED se apaga
- Durante el ajuste, si el LED deja de parpadear y luce fijo, es el aviso que se ha llegado al límite máximo/mínimo
Pulsación (>15s)
- Se programan los valores por defecto, la dirección DCC pasa a ser la #1
*/
// configuración para la compilación
#define ATTINY // habilitar compilación según micro, comentar para usar UNO/NANO
//#define SERIAL_DEBUG // para habilitar Serial.print, solo con UNO
#define RELE // comentar para no usar relé
#if defined ATTINY // DEFINICIONES ATTINY85
#include <SoftwareServo.h> // libreria para el Servo 8 bits
SoftwareServo ElServo; // crea objeto servo
#define PinLED 0 // (5) pin LED
#define PinServo 1 // (6) pin servo
#define PinDCC 2 // (7) pin entrada DCC
#define PinKey1 A0 // (A0) pin tecla 1 cambio posición
#else // DEFINICIONES UNO / NANO
#include <Servo.h> // libreria para el Servo
Servo ElServo; // crea objeto servo
#define PinLED 13 // (13) pin LED
#define PinServo 11 // (11) pin servo
#define PinDCC 2 // (2) pin 2 como entrada de señal DCC
#define PinKey1 A0 // (A0) pin tecla 1 cambio de posición
#endif
#if defined RELE
#define PinReleRecto 3 // (2) pin control relé posición recto
#define PinReleDesvi 4 // (3) pin control relé posición desviado
#define RELE_RECTO {digitalWrite(PinReleRecto, LOW); LedOFF; delay(10); digitalWrite(PinReleRecto, HIGH); LedON;}
#define RELE_DESVI {digitalWrite(PinReleDesvi, LOW); LedOFF; delay(10); digitalWrite(PinReleDesvi, HIGH); LedON;}
#endif
// Otras librerias usadas
#include <EEPROM.h> // Se usa la EEPROM para guardar los valores de configuracion
#include <NmraDcc.h> // Gestion DCC
// variables de control y asignacion
NmraDcc Dcc; // objeto control DCC
#define LimitMin 1 // limite minimo de desplazamiento, el valor 0 da problemas con algún servo
#define LimitMax 91 // limite maximo de desplazamiento
#define PosMid (LimitMax - LimitMin) / 2 // posición media según LimitMin y LimitMax
#define VelRet 30 // retardo por defecto para ajustes, a menor valor movimiento más rápido, "SIEMPRE mayor que 0"
#define SrvRetMax 75 // retardo máximo para movimiento del servo, a menor valor movimiento más rápido, "SIEMPRE mayor que 0"
#define SrvRetMin 10 // retardo minimo para movimiento del servo, "SIEMPRE mayor que 0"
#define WaitTime 300 // tiempo de espara para acciones especiales al pulsar una tecla
#define AnLimit 900 // usamos el pin de RESET como pin analógico, este es el límite para leer pulsación
#define LedOFF digitalWrite(PinLED, HIGH)
#define LedON digitalWrite(PinLED, LOW)
#define LedFlashTime 20 // frecuencia de parpadeo de un LED con millis()
#define LedFlash {LedON; delay(LedFlashTime);LedOFF;}
#define LedOnOff {digitalWrite(PinLED, !digitalRead(PinLED)); prevMillis = millis();} // control parpadeo LED
#define WaitNewDirDCC 15000 // tiempo de espera para recibir una nueva direccion DCC
// variables de trabajo para el control del movimiento del servo
int Contador; // variable de uso general como contador
byte PosActual; // posición actual del servo
byte PosRecto; // posición para desvío recto
byte PosDesvi; // posición para desvío desviado
byte Retardo; // valor para velocidad de movimiento
#if defined RELE
byte PosRele; // Posición donde se activa el rele
#endif
long prevMillis = 0; // variable para almacenar valor previo de millis()
boolean NewDirDCC = false; // true = en proceso de capturar nueva dirección
boolean NewSetDCC = false; // true = en proceso de capturar nueva posición/velocidad del servo
byte AjtPosVel = 3; // control para lectura de teclas +/- desde el mando para ajustes de posición/velocidad del servo
int DirDCC = 1; // direccione base DCC a manejar (direccion del accesorio)
int MaxDirDCC = 1020; // maxima direccion DCC posible
int OldDirDCC = 0; // variable para guardar la última direccion DCC recibida
byte OldDirection = 0; // variable para guardar la última posición del accesorío recibida
//------------------------------------------------------------------------------------------------------
void setup() {
#if defined SERIAL_DEBUG
Serial.begin(9600);
#endif
DirDCC = ((EEPROM[3]*256) + EEPROM[4]); //direccione base DCC a manejar (direccion del accesorio)
if (EEPROM[9] != 111 || DirDCC == 0){ // si NO encontramos el valor "111" en la EEPROM, quiere decir que es un micro nuevo
InitialSet(); // inicializamos a valores por defecto
}
PosActual = EEPROM[0]; // posición actual del servo
PosRecto = EEPROM[1]; // posición para desvío recto
PosDesvi = EEPROM[2]; // posición para desvío desviado
Retardo = EEPROM[5]; // Valor para velocidad de movimiento
pinMode(PinDCC, INPUT);
pinMode(PinLED, OUTPUT);
LedOFF;
if (ResetRead() == true) { // con K1 pulsado al arranque, situamos servo en posición media
#if defined SERIAL_DEBUG
Serial.println(">> MOVE MID");
#endif
LedON;
MoveToPos(PosMid);
while(true); // detenemos la ejecución del programa
}
#if defined RELE // si usamos relé, inicializamos pins y variables
pinMode(PinReleRecto, OUTPUT);
pinMode(PinReleDesvi, OUTPUT);
PosRele = (PosRecto + PosDesvi) / 2; // calculamos punto médio para activar el relé
if(PosActual == PosRecto) RELE_RECTO // se actualiza el estado del rele
else RELE_DESVI
#endif
MoveToPos(PosActual); // movemos el servo a la última posición guardada
Dcc.pin(0,2, 1); // inicializamos librería DCC
Dcc.initAccessoryDecoder(MAN_ID_DIY, 1, FLAGS_OUTPUT_ADDRESS_MODE, 0);
#if defined SERIAL_DEBUG
Serial.print("PosActual: "); Serial.println(PosActual);
Serial.print("Retardo : ");Serial.println(Retardo);
Serial.print("Dir DCC : ");Serial.println(DirDCC);
Serial.println("END SETUP --------------------------------------------------");
#endif
LedFlash;
}
//
// FUNCIONES PRINCIPALES
//
void loop() {
Dcc.process(); // lanzamos el proceso de escucha DCC de forma recurrente
if (ResetRead() == true) { // verificamos tecla K1 pulsada
byte OptionNum = 0;
Contador = 0;
while (ResetRead() == true && OptionNum < 5) { // controlamos la duración de la pulsación para seleccionar opción
delay(10);
Contador++;
if(Contador == WaitTime){
OptionNum++;
Contador = 0;
LedFlash; // emitimos un destello para indicar cambio de opción
}
}
#if defined SERIAL_DEBUG
Serial.print("OptionNum ");
Serial.println(OptionNum);
#endif
switch (OptionNum) {
case 0: // Movemos el servo
if(PosActual == PosRecto) { // cambiamos la posición del servo
MoveToPos(PosDesvi);
}
else {
MoveToPos(PosRecto);
}
break;
case 1: // se muestra la dirección DCC con flash del LED
VerNumero(DirDCC);
break;
case 2: // ajustamos nueva direccion DCC
NewDirDCC = true; // activamos flag
GetDDCAddr();
break;
case 3: // ajustamos posicion servo
NewSetDCC = true; // activamos flag
SetPos();
NewSetDCC = false; // desactivamos flag
break;
case 4: // ajustamos velocidad de desplazamiento
NewSetDCC = true; // activamos flag
SetVel();
NewSetDCC = false; // desactivamos flag
break;
case 5: // hacemos reset a valores por defecto
while(ResetRead() == true) {delay(10);} // esperamos a que K1 deje de estar pulsada
LedON;
InitialSet();
MoveToPos(PosRecto);
LedOFF;
break;
}
}
}
void Re_Set(){
while(ResetRead() == true) {delay(10);} // esperamos a que K1 deje de estar pulsada
LedON;
InitialSet();
MoveToPos(PosRecto);
LedOFF;
}
// Control de lectura en pin analógico
// para poder tener una entrada más en el ATTINY85, usamos el pin de reset para leer una tecla
// este pin se puede programar para que sea una entrada digital, pero se complica el proceso de programación del micro
// para no complicarnos, el pin esta a +5V por defecto, conectado a un partidor resistivo y una tecla que al ser pulsada
// hace que el valor sea de unos 3V, la lectura analógica está por debajo del valor de AnLimit
// con esta funcion retornamos 0/1 como si de un pin digital se tratara
boolean ResetRead(){
if(analogRead(PinKey1) > AnLimit) return true;
else return false;
}
// funcion de manejo de las direcciones DCC
void notifyDccAccTurnoutOutput(uint16_t Addr, uint8_t Direction, uint8_t OutputPower){
/* #if defined SERIAL_DEBUG // descomentar para ver las lecturas
Serial.println("LECTURA DCC ---------------------");
Serial.print("Addr ");Serial.println(Addr, DEC);
Serial.print("Dir ");Serial.println(Direction);
Serial.print("Out ");Serial.println(OutputPower);
Serial.print("HByte ");Serial.println(highByte(Addr));
Serial.print("LByte ");Serial.println(lowByte(Addr));
Serial.println("---------------------------------");
#endif */
if (OutputPower != 1) return; // solo ordenes para accesorios
if (NewDirDCC == true){ // si estamos esperando una nueva dirección DCC
#if defined SERIAL_DEBUG
Serial.print("Cur Dir ");Serial.println(DirDCC);
#endif
if (Addr <= MaxDirDCC){ // si la dirección recibida está dentro de los límites
DirDCC = Addr; // actualizamos valor de la variable DirDCC
EEPROM[3] = highByte(DirDCC); // direccion DCC base byte H // actualizamos EEPROM
EEPROM[4] = lowByte(DirDCC); // direccion DCC base byte L
NewDirDCC = false; // deshabilitamos la espera de nueva DirDCC
#if defined SERIAL_DEBUG
Serial.print("New Addr ");Serial.println(DirDCC,DEC);
Serial.print("HByte ");Serial.println(highByte(DirDCC));
Serial.print("LBYTE ");Serial.println(lowByte(DirDCC));
#endif
}
return; // retornamos
} // proceso normal de una dirección DCC
if(Addr == DirDCC){ // si la dirección decibida es la nuestra
if(NewSetDCC == true){ // si estamos en un proceso de ajuste del movimiento del servo
AjtPosVel = Direction; // retornamos el valor para el ajuste en la variable AjtPosVel
return;
}
if(OldDirDCC == Addr && OldDirection == Direction) return; // si es la misma DirDCC y Dirección que la vez anterior, retornamos
if(Direction == true) { // si no hemos retornado anted, movemos el servo
MoveToPos(PosRecto); // movimiento a recto si Direcction = 1
}
else {
MoveToPos(PosDesvi); // movimiento a recto si Direcction = 0
}
OldDirDCC = Addr; // guardamos valores para la próxima vez
OldDirection = Direction;
}
}
// Mueve el servo a una pocición según el parámetro "NewPos"
void MoveToPos(byte NewPos){
#if defined SERIAL_DEBUG
Serial.print("PosActual FROM : ");Serial.println(PosActual);
Serial.print("NewPos TO : ");Serial.println(NewPos);
#endif
if (NewPos == PosActual) return; // si NewPos es la posición actual, cancelamos
LedON;
boolean RelStatus = false;
if (NewPos == PosRecto) RelStatus = true; // calculamos valor para mover relé
ServoActivo(true); // inicializacion el servo
if (NewPos > PosActual) { // movimiento a recto // bucle para movimiento incrementando angulo
for (byte i = PosActual; i <= NewPos; i++) {
MoveServo(i, RelStatus);
}
}
else { // bucle para movimiento decrementando angulo
for (byte i = PosActual; i >= NewPos; i--) {
MoveServo(i, RelStatus);
}
}
ServoActivo(false); // deshabilitamos el servo
PosActual = NewPos; // actualizamos posición
EEPROM[0] = PosActual; // guardamos posicion
LedOFF;
}
// Habilita/deshabilita el servo según parámetro "Estado"
// La idea de de habilitar/deshabilitar el servo la he copiado de PC
void ServoActivo(boolean Estado){
if(Estado == true){
ElServo.attach(PinServo); // inicializacion el servo
}
else{
if (ElServo.attached()){
while (digitalRead(PinServo)== HIGH); // Esperamos a que acabe el pulso
ElServo.detach(); // lo desconectamos
digitalWrite(PinServo,LOW); // nos aseguramos de que esta desconectado
}
}
}
// Desplaza el servo según parámetro "i", controla el estado del relé
void MoveServo(byte i, boolean RelStatus){
ElServo.write(i); // desplaza el servo
#if defined ATTINY
SoftwareServo::refresh(); // si usamos ATTINY refrescamos
#endif
delay(Retardo); // aplicamos retardo
#if defined RELE // si usamos el relé, cambiamos su estado según parámetro "Relstatus"
if(i == PosRele) { // si estamos en el punto de cambio del relé lo actualizamos
if(RelStatus == true) RELE_RECTO
else RELE_DESVI
}
#endif
}
//
// FUNCIONES PARA LA CONFIGURACION DE VALORES, direccion DCC, posiciones, velocidad de desplazamiento y reset de valores
//
// Se espera una nueva dirección DCC
void GetDDCAddr(){
#if defined SERIAL_DEBUG
Serial.println("SetAdr");
#endif
while(NewDirDCC == true){
Dcc.process();
if(millis() - prevMillis > LedFlashTime * 5) LedOnOff // control parpadeo LED
if(digitalRead(PinKey1) == LOW) NewDirDCC = false; // salimos si pulsamos K1
}
LedOFF;
}
// Definimos valores para las posiciones recto/desviado
void SetPos(){
#if defined SERIAL_DEBUG
Serial.println("SetPos");
#endif
LedON; // encendemos LED
while(ResetRead() == true) {delay(10);} // esperamos a que K1 deje de estar pulsada
PosRecto = GetPos(); // definimos posicion RECTO
EEPROM[1] = PosRecto; // guardamos nuevo valor para posición DESVIADO
PosActual = PosRecto;
#if defined SERIAL_DEBUG
Serial.print("RECTO ? ");Serial.println(PosRecto);
#endif
LedOFF; delay(1000);LedON; // parpadeo del LED
PosDesvi = GetPos(); // definimos posicion DESVIADO
EEPROM[2] = PosDesvi; // guardamos nuevo valor para posición DESVIADO
PosActual = PosDesvi; // actualizamos posición actual
#if defined SERIAL_DEBUG
Serial.print("DESVI ? ");Serial.println(PosDesvi);
#endif
#if defined RELE // recalculamos punto de cambio, si usamos relé
PosRele = (PosRecto + PosDesvi)/2;
#endif
LedOFF; // apagamos LED
}
byte GetPos() {
byte Contador = PosMid; // usamos la variable contador para ajustar la posicion del servo
byte PContador = PosMid;
MoveToPos(PosMid); // movemos el servo a posición media
ServoActivo(true); // inicializacion el servo
while(ResetRead() == false){
Dcc.process();
if(Contador == LimitMax || Contador == LimitMin){ // si se ha llagado a algún límite encendemos el LED
LedON;
}
else{
if((millis() - prevMillis) > LedFlashTime * 5) LedOnOff // control parpadeo LED
}
if (AjtPosVel == 1 && Contador < LimitMax) Contador++; // aumentamos angulo
if (AjtPosVel == 0 && Contador > LimitMin) Contador--; // disminuimos angulo
if (PContador != Contador){ // comparamos con valor anterior
ElServo.write(Contador); // movemos servo
#if defined ATTINY
SoftwareServo::refresh(); // si usamos ATTINY refrescamos
#endif
PContador = Contador; // guardamos valor anterior
}
AjtPosVel = 3; // asignamos valos diferente a 0 y 1
}
ServoActivo(false); // deshabilitamos servo
while(ResetRead() == true) {delay(10);} // esperamos desactivación K1
return Contador; // retornamos valor
}
// Definimos velocidad de movimiento del servo
void SetVel(){
#if defined SERIAL_DEBUG
Serial.println("SetVel");
#endif
while(ResetRead() == true) {delay(10);}
NewSetDCC = true;
Contador = VelRet; // inicializamos valor para velocodad de desplazamiento
byte PosMin = min(PosRecto, PosDesvi); // identificamos valores máximo y mínimo para recorrido
byte PosMax = max(PosRecto, PosDesvi);
ServoActivo(true); // inicializacion el servo
while(ResetRead() == false) { // bucle para desplazamiento del serveo entre valores PosMin/PosMax
for (int i = PosMin; i<=PosMax; i++) {
if (ResetRead() == true) break;
if(Contador == SrvRetMax || Contador == SrvRetMin){ // si se ha llegado a los retardos máximos/mínimos, el LED luce fijo
LedON;
}
else{
if((millis() - prevMillis) > Contador * 5) LedOnOff // control parpadeo LED
}
ElServo.write(i);
#if defined ATTINY
SoftwareServo::refresh(); // si usamos ATTINY refrescamos
#endif
GetTime();
}
for (int i = PosMax; i >= PosMin; i--) {
if (ResetRead() == true) break;
if(Contador == SrvRetMax || Contador == SrvRetMin){ // si se ha llegado a los retardos máximos/mínimos, el LED luce fijo
LedON;
}
else{
if((millis() - prevMillis) > Contador * 5) LedOnOff // control parpadeo LED
}
ElServo.write(i);
#if defined ATTINY
SoftwareServo::refresh(); // si usamos ATTINY refrescamos
#endif
GetTime();
}
}
ServoActivo(false);
NewSetDCC = false;
EEPROM[5] = Contador; // guardamos retardo
Retardo = Contador;
MoveToPos(PosActual); // movemos el servo a posición actual
LedOFF;
}
// Obtenemos retardo para ajustar la velocidad de movimiento
void GetTime() {
Dcc.process(); // llamamos proceso DCC
if(AjtPosVel == 0 && Contador < SrvRetMax) Contador++; // según dato recibido incrementamos/decrementamos valor para ajuste
if(AjtPosVel == 1 && Contador > SrvRetMin) Contador--;
AjtPosVel = 3; // asignamos valos diferente a 0 y 1
delay(Contador); // aplicamos retardo
#if defined SERIAL_DEBUG
Serial.println(Contador);
#endif
}
//
// OTRAS FUNCIONES AUXILIARES
//
// Se muestra la dirección DCC con flash del LED
void VerNumero(int VerContador){
#if defined SERIAL_DEBUG
Serial.print("VerNumero : ");
Serial.println(VerContador);
#endif
delay(2000);
byte Millar, Centen, Decena, Unidad; // obtenemos digitos correspondientes
Millar = VerContador/1000;
Centen = (VerContador - Millar*1000)/100;
Decena = (VerContador - Millar*1000 - Centen*100)/10;
Unidad = (VerContador - Millar*1000 - Centen*100 - Decena*10);
BlinkLED(Millar);
delay(2000);
BlinkLED(Centen);
delay(2000);
BlinkLED(Decena);
delay(2000);
BlinkLED(Unidad);
}
// Emite parpadeos en funcion del parámetro "v"
void BlinkLED(int v){
int t= 500;
if (v == 0) {
LedON;
delay (3 * t);
LedOFF;
}
else {
while (v > 0) {
LedON;
delay (t);
LedOFF;
delay(t);
v--;
}
delay(1.5 * t);
}
}
// Inicializa a valores por defecto
void InitialSet(){ // inicializamos valores por defecto
EEPROM[0]=LimitMin; //
PosActual=LimitMin;
EEPROM[1]=LimitMin; // posicion recto
EEPROM[2]=LimitMax; // posicion desviado
EEPROM[3]=0; // direccion DCC base byte H
EEPROM[4]=1; // direccion DCC base byte L
EEPROM[5]=VelRet; // velocidad
EEPROM[9]=111; // control
}
//////////////////////////////////////////////////////////////////////////////////////////
- Adjuntos
-
- Adaptador para montar el PCB sobre el servo
- IMG_1563.JPG (1.27 MiB) Visto 320 veces
Última edición por sls_h0e el Dom Jun 14, 2020 8:33 pm, editado 1 vez en total.
Lenz + 2C + K.Bay
Re: MOVIENDO DESVÏOS
Mas fotor
- Adjuntos
-
- Montaje versión analógica
- VISTA_ANA.jpg (683.15 KiB) Visto 317 veces
-
- Componentes y conexiones
- Componentes y conexiones.jpg (386.29 KiB) Visto 317 veces
-
- Versión con soporte antiguo
- MONTAJE INICIAL.jpg (1.24 MiB) Visto 317 veces
-
- Versión final digital
- FINAL_DIG.jpg (650.73 KiB) Visto 317 veces
-
- Esquema
- Esquema SERVO_MOTOR_2020.jpg (210.79 KiB) Visto 317 veces
Lenz + 2C + K.Bay
Re: MOVIENDO DESVÏOS
Hola Salus:
muy completo el post, la mitad es como si estuviera en chino, pero se lee
. Por lo menos ya sé lo que es un sketch , llevo meses leyendo la palabra en foros y pensaba que era algo de hardware.
Una pregunta, la placa ¿te la han hecho a medida?
saludos
muy completo el post, la mitad es como si estuviera en chino, pero se lee
Una pregunta, la placa ¿te la han hecho a medida?
saludos
Re: MOVIENDO DESVÏOS
Hola Gonzalo
La placa de circuitoimpreso la diseñe aquí https://circuitmaker.com/Projects#/servo-motor/7//1 , luego pedí a un proveedor chino que las fábricara, a unos 0,5€ unidad para 5u
Para meter tantos componentes me hacía falta doble cara
Este es el sketch de la versión analógica, como el anterios, al inicio hay un manual de uso
Saludos
La placa de circuitoimpreso la diseñe aquí https://circuitmaker.com/Projects#/servo-motor/7//1 , luego pedí a un proveedor chino que las fábricara, a unos 0,5€ unidad para 5u
Para meter tantos componentes me hacía falta doble cara
Este es el sketch de la versión analógica, como el anterios, al inicio hay un manual de uso
Saludos
Código: Seleccionar todo
/*
Control de versiones
V1 - Funcionamiento para Arduino UNO
V2 - Funcionamiento para ATtiny85
V3 - Version final para ATtiny85, con rele monoestable
V4 - Cambio a rele biestable, añadido pulsador en pin analógico
V5 - Se mejora el control del servo (attach/detach)
V6 - Se optimizan funciones de inicializaciónReducción para reducir el uso de memoria
V6 - Añadida opción una o dos teclas para la maniobra (para la configuración siempre se usan las dos teclas)
Control manual de servo para mover desvíos
K1 pulsación corta > mueve servo a posición DESVIADO
K2 pulsación corta > mueve servo a posición RECTO
- En Ambos casos el relé cambia de posición a la mitad del recorrido del servo
K1 pulsación larga > configuración de velocidad de desplazamiento
- Se enciende el LED
- El servo empezará a moverse a un lado y a otro
- Ajustar la velocidad de desplazamiento con K1 y K2
- Pulsar K1+K2 para grabar la posición y terminar
- El LED se apaga
K2 pulsación larga > configuración de angulos de desplazamiento
- Se enciende el LED
- El servo se desplazará a la posición central
- Ajustar la posición RECTO con K1 y K2
- Pulsar K1+K2 para grabar la posición
- El LED parpadea
- El servo retornará a la pocición central
- Ajustar la posición DESVIADO con K1 y K2
- Pulsar K1+K2 para grabar la posición y terminar
- El LED se apaga
K1 pulsado al arranque > reset a valoeres por defecto según InitialSet()
K2 pulsado al arranque > mueve servo a posición central (90º) para anclarlo mecanicamente
*/
// configuración para la compilación
#define ATTINY // habilitar compilación según micro, comentar para usar UNO/NANO
//#define SERIAL_DEBUG // para habilitar Serial.print, solo con UNO/NANO
#define RELE // comentar para no usar el rele
#define DOS_TECLAS // para usar dos teclas RECTO/DESVIADO, comentar para uso de una sola tecla
#if defined ATTINY // DEFINICIONES ATTINY85
#include <SoftwareServo.h> // libreria para el Servo 8 bits
SoftwareServo ElServo; // crea objeto servo
#define PinLED 0 // (5) pin LED
#define PinServo 1 // (6) pin servo
#define PinKey2 2 // (7) pin tecla 2 posición desviado
#define PinKey1 A0 // (A0) pin tecla 1 posición recto
#else // DEFINICIONES UNO / NANO
#include <PWMServo.h> // libreria para el Servo
PWMServo ElServo; // crea objeto servo
#define PinLED 13 // (13) pin LED
#define PinServo 11 // (11) pin servo
#define PinKey2 2 // (2) pin tecla 2 posición desviado
#define PinKey1 A0 // (A0) pin tecla 1 posición recto (ha de ser un pin analógico
#endif
#if defined RELE
#define PinReleRecto 3 // (2) pin control relé posición recto
#define PinReleDesvi 4 // (3) pin control relé posición desviado
#define RELE_RECTO {digitalWrite(PinReleRecto, LOW); LedON; delay(10); digitalWrite(PinReleRecto, HIGH); LedOFF;}
#define RELE_DESVI {digitalWrite(PinReleDesvi, LOW); LedON; delay(10); digitalWrite(PinReleDesvi, HIGH); LedOFF;}
#endif
// Otras librerias usadas
#include <EEPROM.h> // Se usa la EEPROM para guardar los valores de configuracion
// variables de control y asignacion
#define LimitMin 1 // limite minimo de desplazamiento (grados)
#define LimitMax 46 // limite maximo de desplazamiento (grados)
#define PosMid (LimitMax - LimitMin) / 2 // posición media según LimitMin y LimitMax
#define VerRet 30 // velocidad por defecto para ajuste
#define SrvRetMax 75 // maximo retardo para movimiento
#define SrvRetMin 10 // minimo retardo para movimiento
#define WaitTime 300 // tiempo de espara para acciones especiales al pulsar una tecla (300 = 3s)
#define AnLimit 900 // usamos el pin de RESET como pin analógico, este es el límite para leer pulsación
#define LedOFF digitalWrite(PinLED, HIGH)
#define LedON digitalWrite(PinLED, LOW)
#define LedFlashTime 20 // frecuencia de parpadeo de un LED con millis()
#define LedFlash {LedON; delay(LedFlashTime);LedOFF;}
// variables de trabajo para el control del movimiento del servo
int Contador; // variable de uso general como contador
byte PosActual; // posición actual del servo
byte PosRecto; // posición para desvío recto
byte PosDesvi; // posición para desvío desviado
byte Retardo; // Valor para velocidad de movimiento
#if defined RELE
byte PosRele; // Punto de cambio donde se activa el rele
#endif
//------------------------------------------------------------------------------------------------------
void setup() {
#if defined SERIAL_DEBUG
Serial.begin(9600);
#endif
if (EEPROM[9] != 111) { // si NO encontramos el valor "111" en la EEPROM, quiere decir que es un micro nuevo
InitialSet(); // inicializamos a valores por defecto
}
// iniciamos variables con los valores guardados en la sesión anterior
PosActual = EEPROM[0]; // posición actual del servo
PosRecto = EEPROM[1]; // posición para desvío recto
PosDesvi = EEPROM[2]; // posición para desvío desviado
Retardo = EEPROM[5]; // Valor para velocidad de movimiento
pinMode(PinKey2, INPUT_PULLUP);
pinMode(PinLED, OUTPUT);
LedOFF;
if (digitalRead(PinKey2) == LOW) { // con K2 pulsado al arranque, situamos servo en posición media
#if defined SERIAL_DEBUG
Serial.println(">> MOVE MID");
#endif
LedON;
MoveToPos(PosMid);
while(true); // detenemos la ejecución del programa
}
if (ResetRead() == true) { // con K1 reseteamos a valores por defecto
for(byte i=0;i<5;i++){ // avisamos con parpadeos del LED
LedFlash;
delay(100);
}
InitialSet(); // inicicializamos valires por defecto
while(true); // detenemos la ejecución del programa
}
#if defined RELE // inicializamos relé
pinMode(PinReleRecto, OUTPUT);
pinMode(PinReleDesvi, OUTPUT);
PosRele = (PosRecto + PosDesvi) / 2;
if(PosActual == PosRecto) RELE_RECTO // se actualiza el estado del relé
else RELE_DESVI
#endif
MoveToPos(PosActual); // movemos el servo a la última posición guardada
#if defined SERIAL_DEBUG
Serial.print("PosActual: "); Serial.println(PosActual);
Serial.print("Retardo : ");Serial.println(Retardo);
#endif
LedFlash;
}
//
// FUNCIONES PRINCIPALES
//
void loop() {
// verificamos si hay tecla pulsada de forma continua, actuamos según la pulsación es larga/corta y si usamos una/dos teclas
if (digitalRead(PinKey2) == LOW) { // verificamos tecla K2 pulsada
#if defined SERIAL_DEBUG
Serial.println("K2");
#endif
Contador = WaitTime;
while (digitalRead(PinKey2) == LOW && Contador != 0) { // controlamos tiempo de pulsación
delay(10);
Contador--;
}
if (Contador == 0) { // identificamos pulsación larga o corta
#if defined SERIAL_DEBUG
Serial.println(">> SET_POS");
#endif
SetPos(); // si es posición larga, pasamos a programación de posiciones del servo
}
else { // si es posición corta
#if defined DOS_TECLAS
MoveToPos(PosRecto); // si usamos dos teclas, movemos servo a RECTO
#else // si usamos una tecla, cambiamos la posición del servo
if(PosActual == PosRecto) MoveToPos(PosDesvi);
else MoveToPos(PosRecto);
#endif
}
}
if (ResetRead() == true) { // verificamos tecla K1 pulsada
#if defined SERIAL_DEBUG
Serial.println("K1");
#endif
Contador = WaitTime;
while (ResetRead() == true && Contador != 0) { // controlamos tiempo de pulsación
delay(10);
Contador--;
}
if (Contador == 0) { // si es posición larga, pasamos a programación de la velocidad de desplazamiento del servo
SetVel();
#if defined SERIAL_DEBUG
Serial.println(">> SET_VEL");
#endif
}
#if defined DOS_TECLAS
else MoveToPos(PosDesvi); // si usamos dos teclas, movemos servo a DESVIADO
#endif
}
}
// Control de lectura en pin analógico
// para poder tener una entrada más en el ATTINY85, usamos el pin de reset para leer una tecla
// este pin se puede programar para que sea una entrada digital, pero se complica el proceso de programación del micro
// para no complicarnos, el pin esta a +5V por defecto, conectado a un partidor resistivo y una tecla que al ser pulsada
// hace que el valor sea de unos 3,5V, la lectura analógica está por debajo del valor de AnLimit
// Con esta funcion retornamos 0/1 como si de un pin digital se tratara
boolean ResetRead(){
if(analogRead(PinKey1) > AnLimit) return true;
else return false;
}
// Mueve el servo a una pocición según el parámetro "NewPos"
void MoveToPos(byte NewPos){
if (NewPos == PosActual) return; // si NewPos es la posición actual, cancelamos
boolean RelStatus = false;
if (NewPos == PosRecto) RelStatus = true; // calculamos valor para mover relé
#if defined SERIAL_DEBUG
Serial.print("PosActual FROM : ");Serial.println(PosActual);
Serial.print("NewPos TO : ");Serial.println(NewPos);
#endif
ServoActivo(true); // inicializacion el servo
if (NewPos > PosActual) { // bucle para movimiento incrementando angulo
for (byte i = PosActual; i <= NewPos; i++) {
MoveServo(i, RelStatus);
}
}
else { // bucle para movimiento decrementando angulo
for (byte i = PosActual; i >= NewPos; i--) {
MoveServo(i, RelStatus);
}
}
ServoActivo(false); // deshabilitamos el servo
PosActual = NewPos; // actualizamos posición
EEPROM[0] = PosActual; // guardamos posicion
}
// Habilita/deshabilita el servo según parámetro "Estado"
// Lo de habilitar/deshabilitar el servo me lo he copiado de PC
void ServoActivo(boolean Estado){
if(Estado == true){
ElServo.attach(PinServo); // inicializacion el servo
}
else{
if (ElServo.attached()){
while (digitalRead(PinServo)== HIGH); // Esperamos a que acabe el pulso
ElServo.detach(); // lo desconectamos
digitalWrite(PinServo,LOW); // nos aseguramos de que esta desconectado
}
}
}
// Desplaza el servo según parámetro "i", controla el estado del relé
void MoveServo(byte i, boolean RelStatus){
ElServo.write(i); // desplaza el servo
#if defined ATTINY
SoftwareServo::refresh(); // si usamos ATTINY refrescamos
#endif
delay(Retardo); // aplicamos retardo
#if defined RELE // si usamos el relé, cambiamos su estado según parámetro "Relstatus"
if(i == PosRele) { // si estamos en el punto de cambio del relé lo actualizamos
if(RelStatus == true) RELE_RECTO
else RELE_DESVI
}
#endif
}
//
// FUNCIONES PARA LA CONFIGURACION DE VALORES, angulo de posiciones recto/curvo, velocidad de desplazamiento y reset de valores
//
// Definimos valores para las posiciones recto/desviado
void SetPos(){
#if defined SERIAL_DEBUG
Serial.println("SetPos");
#endif
LedON; // encendemos LED
while(digitalRead(PinKey2) == LOW) {delay(10);} // esperamos a que K2 deje de estar pulsada
PosRecto = GetPos(); // definimos posicion DESVIADO
EEPROM[1] = PosRecto; // guardamos nuevo valor para posición DESVIADO
PosActual = PosRecto;
LedOFF; // parpadeo del LED 0,5s
delay(500);
LedON;
PosDesvi = GetPos(); // definimos posicion DESVIADO
EEPROM[2] = PosDesvi; // guardamos nuevo valor para posición DESVIADO
PosActual = PosDesvi; // actualizamos posición actual
#if defined RELE // si usamos relé, recalculamos punto de cambio
PosRele = (PosRecto + PosDesvi)/2;
#endif
LedOFF; // apagamos LED
}
// Definimos posición del servo con las teclas K1/K2
byte GetPos() {
byte Contador = PosMid; // usamos la variable contador para ajustar la posicion del servo
MoveToPos(PosMid); // movemos el servo a posición media
ServoActivo(true); // inicializacion el servo
while (true) { // entramos en un bucle para ajustar la posición del servo mediante K1/K2
if (ResetRead() == true && Contador < LimitMax) Contador++; // si K1 pulsada aumentamos angulo
if (digitalRead(PinKey2) == LOW && Contador > LimitMin) Contador--; // si K2 pulsada disminuimos angulo
ElServo.write(Contador); // movemos servo
#if defined ATTINY
SoftwareServo::refresh(); // si usamos ATTINY refrescamos
#endif
delay(VerRet); // aplicamos retardo
if (digitalRead(PinKey2) == LOW && ResetRead() == true) { // si pulsamos K1+K2 salimos del bucle
break;
}
}
ServoActivo(false); // deshabilitamos servo
return Contador; // retornamos valor
}
// Definimos velocidad de movimiento del servo
void SetVel(){
LedON;
#if defined SERIAL_DEBUG
Serial.println("SetVel");
#endif
Contador = VerRet; // inicializamos valor para velocidad de desplazamiento
byte PosMin = min(PosRecto, PosDesvi);
byte PosMax = max(PosRecto, PosDesvi);
ServoActivo(true); // inicializacion el servo
while (true) { // entramos en un bucle para ajustar la velocidad del servo mediante K1/K2, movemos el servo de forma continua entre "PosMin" y "PosMax"
for (int i = PosMin; i<=PosMax; i++) { // movemos desde PosMin a PosMax
if (digitalRead(PinKey2) == LOW && ResetRead() == true) break; // si pulsamos K1+K2 salimos del bucle "for"
ElServo.write(i); // movemos servo
#if defined ATTINY
SoftwareServo::refresh(); // si usamos ATTINY refrescamos
#endif
delay(10);
GetTime(); // cambiamos valor del retardo
}
for (int i = PosMax; i >= PosMin; i--) { // movemos desde PosMax a PosMin
if (digitalRead(PinKey2) == LOW && ResetRead() == true) break; // si pulsamos K1+K2 salimos del bucle "for"
ElServo.write(i); // movemos servo
#if defined ATTINY
SoftwareServo::refresh(); // si usamos ATTINY refrescamos
#endif
delay(10);
GetTime(); // cambiamos valor del retardo
}
if (digitalRead(PinKey2) == LOW && ResetRead() == true) break; // si pulsamos K1+K2 salimos del bucle "while"
}
ServoActivo(false); // deshabilitamos servo
EEPROM[5]=Contador; // Guardamos nuevo valor del retardo
Retardo = Contador;
LedOFF;
}
// Obtenemos nuevo valor para retardo según K1/K2
void GetTime() {
if (digitalRead(PinKey2) == LOW && Contador <= SrvRetMax) Contador++; // si K2 pulsada, incrementamos valor
if (ResetRead() == true && Contador >= SrvRetMin) Contador--; // si K1 pulsada, decrementamos valor
delay(Contador); // aplicamos retardo
#if defined SERIAL_DEBUG
Serial.println(Contador);
#endif
}
// Inicializa a valores por defecto
void InitialSet(){
EEPROM[0]=LimitMin; // posición actual segín límite mínimo (angulo) de desplazamiento del servo
PosActual=LimitMin; // inicializamos posición actual
EEPROM[1]=LimitMin; // posicion K1 recto, (angulo) de desplazamiento del servo
EEPROM[2]=LimitMax; // posicion K2 desviado, (angulo) de desplazamiento del servo
EEPROM[5]=VerRet; // retardo para fejar la velocidad de desplazamiento del servo
EEPROM[9]=111; // control inicial
#if defined SERIAL_DEBUG
Serial.println(">> RESET");
#endif
}- Adjuntos
-
- VISTA PISTAS.jpg (844.18 KiB) Visto 295 veces
Lenz + 2C + K.Bay
Re: MOVIENDO DESVÏOS
Madre mía con los chinos. Te habrá costado más caro el transporte que las placas. A 50 céntimos y doble cara. Como para hacerlas en casa. Lo único el mes que habrá que esperar.
Muchas gracias
saludos
Muchas gracias
saludos
-
- Menú CTMS Y MAS
-
- Contacto