Sensor EMG

Estoy haciendo una mano robotica con servos y arduino pro micro, la mano se controla por bluetooth con una app del movil y tambien con un sensor emg que mide la actividad muscular.
Con el bluetooth estoy conforme con la programacion pero el sensor funciona siempre que se este haciendo una contraccion muscular.
Haciendo una fuerza media hace un movimiento y haciendo mas fuerza otro movimiento.
Pero lo que quiero es que haciendo una fuerza media por un cierto tiempo haga el movimiento y dejando de hacer fuerza siga con ese movimiento hasta que se vuelva a hacer fuerza, que funcione como un interruptor mas o menos. Y lo mismo cuando se hace mas fuerza.
Esto es lo que tengo hasta ahora.

#include <Servo.h> // incluimos la libreria servo

Servo servo1; // creamos un objeto servo llamado servo1 para mover el dedo pulgar
Servo servo2; // creamos un objeto servo llamado servo2 para mover el dedo indice
Servo servo3; // creamos un objeto servo llamado servo3 para mover los dedos restantes
const int pinsensor = A0; // pin analogo del sensor emg
int valsensor = 0; // variable para guardar el valor del sensor emg
int posicion = 0; // variable indica la posicion o agarre de la mano
boolean funcion = 0; // variable indica la funcion que permite distintos agarres
const int boton = 16;
const int boton2 = 10;
boolean estado = 0;
boolean estado2 = 0;
char BT = 0;

void setup() {

  servo1.attach(7); // vinculamos el pin 8 con el servo1
  servo2.attach(8); // vinculamos el pin 9 con el servo2
  servo3.attach(9); // vinculamos el pin 10 con el servo3
  pinMode(boton, INPUT);
  pinMode(boton2, INPUT);
  pinMode(pinsensor, INPUT);
  Serial.begin(9600);
  Serial1.begin(9600);
  servo1.write(0);
  servo2.write(0);
  servo3.write(180);
 
}

void loop() {

  estado = digitalRead(boton);
  
  if (estado == HIGH){
            
      if (Serial1.available() > 0){
      
      BT = Serial1.read();

      if (BT == 'a'){ // mano abierta
      servo1.write(0);
      servo2.write(0);
      servo3.write(180);
      }
      if (BT == 'b'){ // agarre en pinza
      servo1.write(70);
      servo2.write(180);
      servo3.write(180);
      }
      if (BT == 'c'){ // agarre de fuerza
      servo1.write(100);
      servo2.write(180);
      servo3.write(10);
      }  
      if (BT == 'd'){ // posicion para pulsar teclas con el dedo indice
      servo1.write(0);
      servo2.write(0);
      servo3.write(10);
      }  
      if (BT == 'e'){ // agarre de gancho 1
      servo1.write(0);
      servo2.write(90);
      servo3.write(60);
      }
      if (BT == 'f'){ // agarre de gancho 2
      servo1.write(0);
      servo2.write(180);
      servo3.write(10);  
      }
    }
  }
  else if (estado == 0){

    valsensor = analogRead(pinsensor); // leemos el valor del sensor y guardamos en valsensor
  
    estado2 = digitalRead(boton2);

    if (estado2 == HIGH){
        funcion = 1;
    }
    else {
      funcion = 0;
    }
  
    if (funcion == 0){
    
      if (valsensor < 400){
          posicion = 0;
      }
      if (valsensor >= 400 && valsensor <= 900){
          posicion = 1;
      }
      if (valsensor > 900){
          posicion = 2;
      }
    }
  
    if (funcion == 1){
      if (valsensor < 400){
          posicion = 3;
      }
      if (valsensor >= 400 && valsensor < 900 ){
          posicion = 4;  
      }
      if (valsensor >= 900){
           posicion = 5;
      }     
    }
  if (posicion == 0){ // mano abierta
      servo1.write(0);
      servo2.write(0);
      servo3.write(180);
  }
  if (posicion == 1){ // agarre en pinza
      servo1.write(70);
      servo2.write(180);
      servo3.write(180);
  }
  if (posicion == 2){ // agarre de fuerza
      servo1.write(100);
      servo2.write(180);
      servo3.write(10);
  }  
  if (posicion == 3){ // posicion para pulsar teclas con el dedo indice
      servo1.write(0);
      servo2.write(0);
      servo3.write(10);
  }  
  if (posicion == 4){ // agarre de gancho 1
      servo1.write(0);
      servo2.write(90);
      servo3.write(60);
  }
  if (posicion == 5){ // agarre de gancho 2
      servo1.write(0);
      servo2.write(180);
      servo3.write(10);  
  }
  Serial.println(valsensor);
  }
}

Hubiera sido algo mas didáctico enfatizar que esta parte

if (funcion == 0){
    
      if (valsensor < 400){
          posicion = 0;
      }
      if (valsensor >= 400 && valsensor <= 900){
          posicion = 1;
      }
      if (valsensor > 900){
          posicion = 2;
      }
    }
  
    if (funcion == 1){
      if (valsensor < 400){
          posicion = 3;
      }
      if (valsensor >= 400 && valsensor < 900 ){
          posicion = 4;  
      }
      if (valsensor >= 900){
           posicion = 5;
      }     
    }

Es la que básicamente quieres mejorar con el concepto de fuerza por tiempo agregando N estados mas a cada caso.

He considerado 3 nuevos subestados, basados en T1 y T2.
T1 = 250mseg
T2 = 500mseg obviamente estos valores son modificables.

Se darán entonces 3 situaciones posibles
Si se contrae el músculo durante un lapso menor a T1 es el cambio = 0
si se contrae el músculo entre T1 y T2 es el cambio = 1
si se contrae mas de T2, entonces cambio = 2.
Esto agrega 3 nuevos subestados a los 6 estados que ya dispones. Llevando la cuenta a 6x3 = 18 posibilidades, pero te dejo a ti esa enfoque porque puedes jugar con combinaciones para cada caso.

El tema es que para mi todo depende de

estado2 = digitalRead(boton2);

y del momento en que cambia de estado, que ESPERO sea trate de un switch. Si no es un switch lo que hice sobre el momento de inicio no servirá como lo he imaginado porque cada vez que pulses un botón se daría una situación de inicio de subestados y cuando lo sueltas otras.
Esto es válido con un switch y tmb con un pulsador pero ya no es tan práctico.
Espero que se comprenda esto.
Con un switch tendríamos estados bien definidos. También con un pulsador pero al soltar el pulsador volveríamos a estar en detectar cosas y eso me parece como estresante para persona y sistema.

Lo dejo acá y seguimos conversando

#include <Servo.h> // incluimos la libreria servo

Servo servo1;             // creamos un objeto servo llamado servo1 para mover el dedo pulgar
Servo servo2;             // creamos un objeto servo llamado servo2 para mover el dedo indice
Servo servo3;             // creamos un objeto servo llamado servo3 para mover los dedos restantes
const int pinsensor = A0; // pin analogo del sensor emg
int valsensor       = 0;  // variable para guardar el valor del sensor emg
int posicion        = 0;  // variable indica la posicion o agarre de la mano
int cambio0         = 0;  // variable indica el tiempo que permanece entre intervalos T1, T2 o > T2
int cambio1         = 0;  // variable indica el tiempo que permanece entre intervalos T1, T2 o > T2
boolean funcion     = 0;  // variable indica la funcion que permite distintos agarres
const int boton     = 16;
const int boton2    = 10;
boolean estado      = false;
boolean estado2     = false;
boolean estado2Ant  = false;
char BT             = 0;
unsigned long T1    = 250; // 250 mseg
unsigned long T2    = 500; // 500 mseg 
unsigned long start0, start1;

void setup() {

  servo1.attach(7);       // vinculamos el pin 8 con el servo1
  servo2.attach(8);       // vinculamos el pin 9 con el servo2
  servo3.attach(9);       // vinculamos el pin 10 con el servo3
  pinMode(boton, INPUT);
  pinMode(boton2, INPUT);
  pinMode(pinsensor, INPUT);
  Serial.begin(9600);
  Serial1.begin(9600);
  servo1.write(0);
  servo2.write(0);
  servo3.write(180);
 
}

void loop() {

  estado = digitalRead(boton);
  
  if (estado == HIGH){
      if (Serial1.available() > 0){
          BT = Serial1.read();
          if (BT == 'a'){ // mano abierta
              servo1.write(0);
              servo2.write(0);
              servo3.write(180);
          }
          if (BT == 'b'){ // agarre en pinza
              servo1.write(70);
              servo2.write(180);
              servo3.write(180);
          }
          if (BT == 'c'){ // agarre de fuerza
              servo1.write(100);
              servo2.write(180);
              servo3.write(10);
          }  
          if (BT == 'd'){ // posicion para pulsar teclas con el dedo indice
              servo1.write(0);
              servo2.write(0);
              servo3.write(10);
          }  
          if (BT == 'e'){ // agarre de gancho 1
              servo1.write(0);
              servo2.write(90);
              servo3.write(60);
          }
          if (BT == 'f'){ // agarre de gancho 2
              servo1.write(0);
              servo2.write(180);
              servo3.write(10);  
          }
      }
  }
  else if (estado == 0){

    valsensor = analogRead(pinsensor); // leemos el valor del sensor y guardamos en valsensor
    estado2 = digitalRead(boton2);
    if (estado2 && !estado2Ant) { // transición 0 a 1
        funcion = 1;
        start1 = millis();
    }
    if (!estado2 && estado2Ant) { // transición 1 a 0
        funcion = 0;
        start0 = millis();
    }
    estado2Ant = estado2;
    
    cambio1 = 0;
    if (abs(millis()-start1) < T1) {
        cambio1 = 1;
    }
    if (abs(millis()-start1-T1) < T2) {
        cambio1 = 2;
    }
    // tendrias una situación en la que se supera T2 que daría otro estado mas
    if (abs(millis()-start1) > T2) {
        cambio1 = 3;
    }

    cambio0 = 0;
    if (abs(millis()-start0) < T1) {
        cambio0 = 1;
    }
    if (abs(millis()-start0-T1) < T2) {
        cambio0 = 2;
    }
    // tendrias una situación en la que se supera T2 que daría otro estado mas
    if (abs(millis()-start0) > T2) {
        cambio0 = 3;
    }

    // ahora debes combinar cambioX con posicion para obtener 3 estados nuevoes por cada posicion

    if (funcion == 0){
        if (valsensor < 400){
            posicion = 0;
        }
        if (valsensor >= 400 && valsensor <= 900){
            posicion = 1;
        }
        if (valsensor > 900){
            posicion = 2;
        }
    }

  
    if (funcion == 1){
        if (valsensor < 400){
            posicion = 3;
        }
        if (valsensor >= 400 && valsensor < 900 ){
            posicion = 4;  
        }
        if (valsensor >= 900){
            posicion = 5;
        }     
    }

  if (posicion == 0){ // mano abierta
      servo1.write(0);
      servo2.write(0);
      servo3.write(180);
  }
  if (posicion == 1){ // agarre en pinza
      servo1.write(70);
      servo2.write(180);
      servo3.write(180);
  }
  if (posicion == 2){ // agarre de fuerza
      servo1.write(100);
      servo2.write(180);
      servo3.write(10);
  }  
  if (posicion == 3){ // posicion para pulsar teclas con el dedo indice
      servo1.write(0);
      servo2.write(0);
      servo3.write(10);
  }  
  if (posicion == 4){ // agarre de gancho 1
      servo1.write(0);
      servo2.write(90);
      servo3.write(60);
  }
  if (posicion == 5){ // agarre de gancho 2
      servo1.write(0);
      servo2.write(180);
      servo3.write(10);  
  }
  Serial.println(valsensor);
  }
}

esas variables cambiox cambian cuando se acciona el switch de estado2, no con el valor del sensor, esta bien eso?

yo antes habia intentado usar un codigo para que un pulsador funcione como interruptor:

const int boton = 4;
const int led = 13;
boolean estadoAC = 0;
boolean estadoAN = 0;
boolean inicio = 0;

void setup() {
  
  pinMode(boton, INPUT);
  pinMode(led, OUTPUT);
}

void loop() {

  estadoAC = digitalRead(boton);
  if (estadoAC == 1 && estadoAN == 0){
    inicio = 1 - inicio;
    delay(100);   
  }
  estadoAN = estadoAC;
  if(inicio == 1){
    digitalWrite(led, HIGH);
  }
  else{
    digitalWrite(led, LOW);
    }  
}

estuve practicando con eso, con un potenciometro y el led 13 del arduino uno, y me salio esto:

const int pot = A0;
const int led = 13;
int val_pot = 0;
unsigned long t = 0;
unsigned long t2 = 0;
int Dt = 1500;
boolean temp = 0;
boolean estado = 0;
int cont = 0;

void setup() {

  pinMode(pot, INPUT);
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  
}

void loop() {
  
  val_pot = analogRead(pot);

  if(val_pot <= 500){
    temp = 0;
  }
  if(val_pot > 500 && temp == 0 ){
    t = millis();
    temp = 1 - temp;
  }
  if(temp == 1 && millis() > t + Dt){
    estado = 1 - estado;
    temp = 1 - temp;
    cont = cont + 1;
  }
    
  if(estado == 1){
    digitalWrite(led, HIGH);
    t2 = millis();
    if(millis() > t2 + 2000){
      temp = 0;
    }
  }
  else if(estado == 0){
    digitalWrite(led, LOW);
  }
  
  //Serial.print("val_pot: ");
 // Serial.println(val_pot);
  Serial.print("cont: ");
  Serial.println(cont);
  //Serial.print("estado: ");
  //Serial.println(estado);
  
  
}

si el valor del potenciometro es >500 pasados 1500ms (por poner algun valor) enciende el led por lo menos por 2000ms y sigue encendido aunque el valor baje a menos de 500. Cuando el valor del potenciometro vuelve a ser >500 por 1500ms se apaga. Si el valor de 500 no baja me funciona mal, pero con el sensor emg no se estaria haciendo fuerza todo el tiempo (una vez que hace el moviemiento de deja de hacer fuerza)

quise lleva esto a la mano robotica y solo funciona cuando el valor del sensor es <400 y cuando >= 400 && <= 900
cuando es >900 no sirve

No entendido lo que te he explicado.

Esas variables cambioX se modifican con valorsensor y de acuerdo a 3 tiempos que te expliqué debidamente.
0 < t < T1
T1 < t < T2
t > T2

Pero para cada valor de switch o pulsador2 tienes a su vez 3 posiciones posibles dados por el valor de la contracción del músculo.
o sea que cada combinación te da 9 estados posibles.

Combinalos como quieras.

Se comprende?

no entiendo porque esas variables cambio no se modifican con el valor del sensor, pero cuando acciono el interruptor si cambian pero una queda en 3 y la otra va de 1 hasta 3.

Porque lo estas pensado como tu crees que yo lo hice pero yo te lo expique ya dos veces.

A ver plantea bien la pregunta. Dime que quieres?

Tenemos un switch en dos posiciones posibles.
Tenemos una persona que segun el nivel de contractura tu puedes determinar 3 estados.

estado 0 => valsensor < 400
estado 1 => 400 < valorsensor < 900
estado 2 => valorsensor > 900

tambien a su vez tenemos los tiempos que no se si esta o no bien aún no lo respondiste.
Yo fije 2 tiempos limites que genera 3 posiblidades a estas 3 posibildades.

entonces si estas en el estado = 0 y el tiempo es menor a T1, entre T1 y T2 o mayor a T2 tendras 3 estados nuevos.
llamemos a eso estado1 = 0, 1, 2

Ahora supongamos que valor sensor esta entre 400 y 900
tendremos estado1 = 3, 4, 5
y si valorsenosr es > 900 tendremos
estado1 = 6, 7 y 8
Todo eso con switch en 1 o sea funcion = 1

Lo mismo se repite para switch en LOW o función en 0

estado0 = 9, 10, 11, 12, 13, 14, 15, 16, 17

Se comprende?

Lee el privado