Mover servo ausencia de pulso SOLUCIONADO

Buenas noches. Soy principiante y estoy haciendo un proyecto. La cuestion es que tengo, que con un sensor hall, cambiar la posicion de un servo cuando una rueda se quede quieta unos 3 segundos,si esta buelve a girar,vuelva a la posicion de inicial el servo.
El problema es que en el codigo que he encontrado ,el servo se vuelve loco al detectar con tanta frecuencia el iman ya que esta colocado en una rueda . Haber si alguien me puede hechar un cable,ya que he probado varias modificaciones y no consigo que funcione

#include <Servo.h>
int button = 5;  
int press = 0;
Servo servo;
boolean toggle = true;
void setup()
{
  pinMode(button, INPUT);  
  servo.attach(9);  
  digitalWrite(5, HIGH); 
}

void loop()
{
  press = digitalRead(button);
  if (press == LOW)
  
  {
    if(toggle)
    {
      servo.write(80);
      toggle = !toggle;
    }
    else
    {
      servo.write(30);
      toggle = !toggle;
    }
  }
  delay(500);   
}

Gracias de antemano

Puedes explicarte un poco mejor.
Veo que tienes el sensor en el pin 5 y la rueda tiene varios dientes?
cual es la posicion inicial y cual es la que debe mover.

No se comprende la idea! para que necesitas esto?

No entiendo la duda. Voy a usar la bola mágica predictiva para viendo tu fotografía del foro, la rueda y el uso de un sensor hall para presuponer ... ¿¿¿Es un proyecto en una bicicleta eléctrica o similar quizás?

Si dices que el problema está en el imán del sensor que tienes ¿No sería una pregunta en el apartado de hardware? (porque si ese es el motivo no podrás arreglarlo vía código)

En los lenguajes de programación no es muy buena idea utilizar nombre de variables igual a otros que sean de código nativo, aunque en este caso arduino se lo trague. Lo digo por el press.

Lo que veo es que tú código no hace para nada lo que quieres hacer.
No veo que se tenga que volver loco si el circuito está bien y nada afecta al servo.
Ese código sólo cambia alternativamente entre dos posiciones al soltar un pulsador.

¿Tu duda es el contador de tiempo de 3 segundos? No está esa parte, ni la parte que para el servo, ni ninguna otra que comentas. ¿Estás haciendo copy & paste sin mirar que hace el código?

Coméntanos más para entender donde está la duda y cual es el problema, pero el código no tiene nada que ver a lo que CREO que planteas.

Un saludo.

El proyecto es controlar la suspensión de la bicicleta.
El sensor esta colocado en el cambio en la rueda trasera y el imán en la roldana(rueda dentada del cambio) ,que tiene unos 3 cm de diámetro. Al pedalear gira la roldana , el sensor detecta el imán y el servo cambia de 0 grados a unos 40 grados para cambiar el modo del amortiguador y cuando deja de detectarlo vuelve a 0.
Con el código que adjunte anteriormente,no se como hacer que arduino diferencie la frecuencia de paso del iman al girar la roldana y que esta este parada.
El codigo que puse inicialmente era para un pulsador, como mencionas , quizá no sea el adecuado .
Intente utilizar este otro codigo que encontre googleando,pero no me funciona.

#include<Servo.h>
Servo myServo;    // Nombre servo

int inPin = 5;    // Entrada del sensor Hall
int ledPin = 13;  // Pin Led
int val = 0;      // variable del sensor

void setup() 
{
  pinMode(inPin, INPUT);       //Sensor de entrada    
  pinMode(ledPin, OUTPUT);   //Led 
  myServo.attach (9);         //conexion servo
}


void loop()
{
  static bool DetectingHallEffect=false;                    // We will likely detect the hall effect sensor several times, make sure we only react when we first detect it.

  val = digitalRead(inPin);                                 // Read the Hall Effect Sensor
  if((val = 0 ) && (val > 0))                               // Do we see the sensor?
  {
    if(!DetectingHallEffect)                                // Make sure we only do this once for each detection of the hall effect sensor
    {
      DetectingHallEffect=true;                             // This will be true until we don't see the sensor any more
      if(myServo.read()==0)                                 // Check where the servo is and move it to the other position
        myServo.write(90);
      else
        myServo.write(0);
    }
  }
else
  DetectingHallEffect=false;                                // Don't see the sensor any more, permit action the next time we see it
}

hola te voy a explicar como lo haría yo:

cogería una variable tiempo entre detección: 500ms

siguiente detección:

cada vez que el sensor cambia, siguiente detección= millis+ tiempo entre

if millis< tiempo entre
servo a 40º
else
servo a 0

obviamente falta código pero con eso yo apuesto a que funciona. pero yo pondría un pulsador para desbloquear el amortiguador independiente mente del hall, en una bajada te interesa tener amortiguador.

Hola.
Intenta explorar esta vía a ver si es lo que buscas:

#include <Servo.h>

Servo myServo;    // Nombre servo

const int inPin = 5;    // Entrada del sensor Hall
const int ledPin = 13;  // Pin Led
const unsigned long stopTrigger = 3000; // tiempo de inactividad que hará disparar el servo (3 segundos)
unsigned long lastHallDetection; // milisegundo en el que se produjo la última variación del sensor
byte lastVal = LOW;      // variable del sensor

void setup()
{
  pinMode(inPin, INPUT);       //Sensor de entrada   
  pinMode(ledPin, OUTPUT);   //Led
  myServo.attach (9);         //conexion servo
}


void loop()
{
  byte val = digitalRead(inPin);                            // Read the Hall Effect Sensor
  if (val != lastVal) { // el sensor varió
    if (myServo.read() == 0) {
      myServo.write(90);
    }
    lastHallDetection = millis(); // anotamos el milisegundo
  } else { // el sensor no varió
    if ( (millis()-lastHallDetection) >= stopTrigger) { // si ha pasado el tiempo de disparo sin detección
      if (myServo.read() != 0) {
        myServo.write(0);
      }
    }
  }
}

noter:
Hola.
Intenta explorar esta vía a ver si es lo que buscas

Pero si ya está la tarea hecha :grin: ¿Cómo no va a servir más allá de incluso el ejemplo?
Con líneas comentadas y todo. :art: Yo predigo un [Solucionado] en el título.

ese código tiene todas las papeletas de funcionar. Yo solo haría un comentario un Byte son 8 bits coño para la entrada cambia byte por BOOL que seria lo correcto. Luego yo prefiero por eficiencia hacer la suma de millis + tiempo y asignarla a la variable, y comparar millis con esa variable mas que nada porque solo sumas cuando cambia y comparar lo haces casi siempre, la diferencia un par de microsegundos no es mucho y menos para esta aplicación pero en otras un poco mas grandes se nota

aunque un servo para esa aplicacion me parece excesivo, no se de que recursos dispondras para diseñar piezas, o que dureza tendra el bloqueo de la suspension, igual solucionabas con un motor de continua y un engranaje acoplado a la palanca

Funciona de maravilla,ahora ha terminar de calibrar tiempos y grados del servo. y ver si le puedo añadir el acelerometro MPU 6050 para determinar la inclinacion. Lo voy a probar y luego subire el codigo ...

Me alegro que te sea útil. Si además logras comprender cómo funciona, además de solucionarte la papeleta actual, a buen seguro que te puede solucionar muchas futuras. Por ello me molesté casi más en poner comentarios que en implementar el código.

Para juand91, si bien se podría poner bool en lugar de byte, en arduino ambos van a ocupar un byte completo; pero también sería correcto haber usado bool, por supuesto. Lo que quería realmente comentarte es el otro punto:

Luego yo prefiero por eficiencia hacer la suma de millis + tiempo y asignarla a la variable, y comparar millis con esa variable mas que nada porque solo sumas cuando cambia y comparar lo haces casi siempre, la diferencia un par de microsegundos no es mucho y menos para esta aplicación pero en otras un poco mas grandes se nota

Realmente con ese sistema se te podría presentar, aunque en este caso la posibilidad es remota y los efectos leves, un problema con el desbordamiento de millis. Supongamos que la última detección de variación en el hall se produce con millis=FFFFFF00. Sumamos los 3000 ms (0xBB8), y el resultado tras desbordar será (1)00000AB8. Inmediatamente, en la próxima comparación con millis se va a cumplir la condición de disparo (FFFFFF01>00000AB8) aunque no hayan transcurrido los tres segundos. En resumen, los tres segundos anteriores al desbordamiento podrían ser de funcionamiento caótico (tampoco es tanto tres potenciales segundos de mal funcionamiento cada 50 días). Sin embargo, y por gracia de cómo se realizan las operaciones binarias, si calculas el tiempo transcurrido restando, lo que debía resultar como un valor negativo, al ser tratado como unsigned, sigue computando correctamente el tiempo transcurrido.

Buenos días, lo he conseguido, después de varios intentos ,he juntado dos códigos, uno el del acelero metro y el que me ayudasteis anteriormente citado. funciona correctamente,salvo que todas las ordenes las ejecuta el servo en la dirección contraria a la que yo quiero. Me pasa al haberlos unido ,porque por separado si que funcionan en la dirección deseada.
<
#include <Servo.h>
#include <MPU6050.h>
Servo myServo; // Nombre servo

const int inPin = 5; // Entrada del sensor Hall
const int ledPin = 13; // Pin Led
const unsigned long stopTrigger = 1000; // tiempo de inactividad que hará disparar el servo (1 segundos)
unsigned long lastHallDetection; // milisegundo en el que se produjo la última variación del sensor
byte lastVal = HIGH; // variable del sensor
MPU6050 mpu;
int16_t ax, ay, az;
int16_t gx, gy, gz;
int val=0;
int prevVal;
void setup()
{
pinMode(inPin, INPUT); //Sensor de entrada
pinMode(ledPin, OUTPUT); //Led
myServo.attach (9); //conexion servo
pinMode(13, OUTPUT);
Wire.begin();
Serial.begin(38400);
Serial.println("Initialize MPU");
mpu.initialize();
Serial.println(mpu.testConnection() ? "Connected" : "Connection failed");

}

void loop()
{
byte val = digitalRead(inPin); // Read the Hall Effect Sensor
if (val != lastVal) { // el sensor varió
if (myServo.read() == 40) {
myServo.write(50);
}
lastHallDetection = millis(); // anotamos el milisegundo
} else { // el sensor no varió
if ( (millis()-lastHallDetection) >= stopTrigger) { // si ha pasado el tiempo de disparo sin detección
if (myServo.read() != 40) {
myServo.write(40);
}
}
}

int n=1;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
if (n<80) n= 1;
val = map(ay, 0, -17000, 20, 80 );
if (abs(val-60) < 30.0)
{ digitalWrite(13,HIGH);
myServo.write(val);
prevVal = val=20;
}

delay(150);
myServo.write(0);
digitalWrite(13,LOW);

}