Hola, quiero hacer un proyecto con arduino pero soy totalmente novato al nivel más bajo....
Lo que quiero hacer es accionar un servo mediante un pulsador pero que el servo no se mueva hasta pasados unos 5 segundos, después que el servo vuelva a su posición inicial.
A su vez en esa franja de 5 segundos que todavía no se está moviendo el servo, cierre un interruptor el cual dure unos 15 o 20 segundos y vuelva a abrir el interruptor.
¿Y entonces?...
¿Cuándo te pones a leer tutoriales y/o libros?
Material tienes de sobra.
Y si tu intención es que alguien te escriba el código, no es éste el lugar indicado.
en ningún momento he dicho eso, lo primero es saber si es posible
Pues te faltó justamente hacer esa pregunta. ![]()
Claro que se puede y es mucho más sencillo de hacer de lo que puedas imaginar.
Anímate!
Gracias, en cuanto me llegue la placa me pongo a trastear!
Puedes trabajar con https://wokwi.com/ y simular lo que gustes.
Ve haciendo lo que puedas y consultas. Pero te aseguro que aunque no este exactamente lo que quieres hacer, si lo separas por pequeñas cosas iras entendiendo como hacerlo funcionar.
Muchas gracias! ![]()
Buenas, tras unos días viendo algún videotutorial y algo de lectura y copiar un poco
(La mayoría de conceptos me siguen sonando a chino...)
Casi he conseguido lo que quiero pero me falta algo de retoque y saber si el código esta bien o cambiaríais algo!
#include <Servo.h>
Servo Myservo;
#define Rele 4
#define Push 2
int pos=0;
void setup()
{
pinMode(2,INPUT);
pinMode(4,OUTPUT);
Myservo.attach(3);
}
void loop()
{
if(digitalRead(2)==LOW){
Myservo.write(92);
while
(digitalRead(2)==HIGH){
delay(200);
digitalWrite(4,HIGH);
delay(5*1000);
Myservo.write(0);
}
if (digitalRead(4)==HIGH){
delay(10*1000);
digitalWrite(4,LOW);
}
}
}
Bueno, uno de los "problemas" ya que si se queda así tampoco me preocupa mucho es que me gustaría que el tiempo que tarda el servo en volver de 0º a 92º fuera de 2 segundos en vez de 5 pero por como tengo echo el código parece no ser posible.
Otro problema es que el servo funciona correctamente al pasar de 92º a 0º (un retardo de 5s desde que se enciende el relé) pero luego por el propio código no vuelve a 0º al cabo de otros 5s sino que se espera a que se vuelva a apagar el relé, como podría cambiar esto?
No se si lo he escrito un poco lioso o se llega a entender ![]()
Después de muchas pruebas y muchos ejemplos he conseguido lo que quería pero no se si el código es el mejor que se podía hacer. Esta semana espero poder probarlo con los componentes para ver si de verdad funciona.
Dejo el código para que le echéis un vistazo.
#include <VarSpeedServo.h>
VarSpeedServo Myservo;
unsigned long t;
byte Pulsador=2;
byte Rele=4;
int pos=0;
void setup() {
pinMode(Pulsador, INPUT_PULLUP);
pinMode(Rele, OUTPUT);
Myservo.attach(3);
Myservo.write(98, 100, true);
}
void loop() {
if(digitalRead(Pulsador)==LOW){
delay(200);
digitalWrite(Rele, HIGH);
delay(5000);
Myservo.write(0, 255, true);
t = millis();
}
else if(millis()-t>=2000){
Myservo.write(98, 100, true);
}
if(millis()-t>=3000){
digitalWrite(Rele, LOW);
}
}
He añadido la librería VarSpeedServo para controlar de forma más sencilla la velocidad de movimiento del servo.
De nada sirve
if(millis()-t>=3000){
digitalWrite(Rele, LOW);
}
con los delay() que tienes cuando presionas el pulsador
Esto código tiene una máquina de estados. No esta probado de modo que si tiene errres o falta definir alguna variable verifícalo y haz las correcciones necesarias.
#include <VarSpeedServo.h>
VarSpeedServo Myservo;
unsigned long t;
byte Pulsador = 2;
byte Rele = 4;
int pos = 0;
bool accion = false;
int estado;
enum _modos = {NOSEMUEVE, CINCOSEG, CIERRO_RELE};
_modos modo = NOSEMUEVE;
void setup() {
pinMode(Pulsador, INPUT_PULLUP);
pinMode(Rele, OUTPUT);
Myservo.attach(3);
Myservo.write(98, 100, true);
}
void loop() {
estado = digitalRead(Pulsador);
if (estado == LOW) {
accion = true;
}
if (accion)
switch(modo) {
case NOSEMUEVE: digitalWrite(Rele, HIGH);
t = millis();
modo = CINCOSEG;
break;
case CINCOSEG : if (millis() - t > 5000UL) {
Myservo.write(0, 255, true);
t = millis();
modo = CIERRO_RELE;
}
break;
case CIERRO_RELE: if (millis() - t > 15000UL) {
digitalWrite(Rele, LOW);
modo = NOSEMUEVE;
accion = false;
}
break;
}
}
Muchas gracias!
Respecto al código simplemente he tenido que borrar el "=" de enum _modos y añadir la funcion para que el servo vuelva a 98 grados antes de que el relé se apague pero todo funciona a la perfección.
No se si era tu intención pero el relé no se cerraba a los 15 segundos si no que lo hacia a los 20 segundos.
Así ha quedado el código!
#include <VarSpeedServo.h>
VarSpeedServo Myservo;
unsigned long t;
byte Pulsador = 2;
byte Rele = 4;
int pos = 0;
bool accion = false;
int estado;
enum _modos {NOSEMUEVE, CINCOSEG, CIERRO_SERVO, CIERRO_RELE};
_modos modo = NOSEMUEVE;
void setup() {
pinMode(Pulsador, INPUT_PULLUP);
pinMode(Rele, OUTPUT);
Myservo.attach(3);
Myservo.write(98, 100, true);
}
void loop() {
estado = digitalRead(Pulsador);
if (estado == LOW) {
accion = true;
}
if (accion)
switch(modo) {
case NOSEMUEVE: digitalWrite(Rele, HIGH);
t = millis();
modo = CINCOSEG;
break;
case CINCOSEG : if (millis() - t > 5000UL) {
Myservo.write(0, 255, true);
t = millis();
modo = CIERRO_SERVO;
}
break;
case CIERRO_SERVO: if (millis() - t > 2000UL) {
Myservo.write(98, 100, true);
t = millis();
modo = CIERRO_RELE;
}
break;
case CIERRO_RELE: if (millis() - t > 2000UL) {
digitalWrite(Rele, LOW);
modo = CIERRO_SERVO;
accion = false;
}
break;
}
}
Saludos.
Por cierto, me gusta lo de la máquina de estados!
No me percaté que anidé dos retardos con millis() 5 y 15 segundos pero como veras puedes ajustarlo a tu gusto.
La maquina de estados obliga a pensar de otro modo pero cuando te acostumbras ves que es muy limpia y te permite hacer absolutamente de todo.
La única exigencia es no usar librerías bloqueantes o sea que actúen como un nuevo delay().
Ejemplo DHT es una librería bloqueante que te deja 2 seg sin hacer nada pero si buscas encontrarás librerias que lo hacen bien.
Lo mismo con el DS18b20 en general tardan 125 a 750 mseg pero tmb las hay que no te detienen.
Hola de nuevo, resulta que el código no deja volver a iniciar la secuencia. Cuando pulsas el pulsador inicia todo con los tiempos indicados, etc pero ya no vuelve a funcionar más si vuelves a pulsar el pulsador, me estoy volviendo loco intentando buscar la solución y estoy seguro de que es una tonteria pero no lo consigo, podrías echarme una mano por favor? ![]()
Agrega esto
if (estado == LOW) {
accion = true;
estado = NOSEMUEVE;
}
Muchísimas gracias por la velocidad! justo estaba probando todo y no se como no había probado bien el código y no me di cuenta de eso... Y ahora con los nervios no daba con el fallo.
Por cierto, corregido pero en vez de estado con modo:
if (estado == LOW) {
accion = true;
modo = NOSEMUEVE;
}
Lo dicho, muchas gracias por todo.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.