No consigo enlazar dos funciones

Hola a todos.

Este es mi primer mensaje, así que lo más probable es que cometa algún error, pido disculpas por ello.
También decir que soy novato (muy novato) en arduino.

El tema es que he logrado crear el código para activar un motor paso a paso, de varias formas:movimiento continuo, mediante órdenes por serial, etc. (parte del código lo he extraido del foro).

const int dirPin =5;
const int stepPin=2;
const int BOTON=12;

const int paso=200;
int micropasos=1000;

char n;
int vueltas;
int limit=5;


//variables para funcion pushmeter
int ESTADO=LOW;
int CONT;
int a=0;
int b=0;
boolean pisado=true;
boolean proceso=false;


void setup() {

  Serial.begin(115200);
  
  pinMode(dirPin,OUTPUT);
  pinMode(stepPin,OUTPUT);
  pinMode(BOTON,INPUT);
 
}



void loop() { 



      while(Serial.available()){
     
  n=Serial.read();
  if (n=='1'){
  digitalWrite(dirPin,HIGH);
  }else if(n=='0'){
  digitalWrite(dirPin,LOW); 
  }
  int a=1;
  for(int i=0;i<a;i++){
      digitalWrite(stepPin,HIGH);
      delayMicroseconds(micropasos);
      digitalWrite(stepPin,LOW);
      delayMicroseconds(micropasos);
      a++;
      }
   }

Por otro lado he conseguido con otro código, crear un contador mediante un pulsador.

 //Declaracion del pin de conexion
int BOTON=12;
//Declaración e iniciación de variables de estado
int ESTADO=LOW;
int CONT;
int a=0;
int b=0;
boolean pisado=true;

void setup(){

  Serial.begin (115200);
  pinMode(BOTON,INPUT);   //pin 12 como entrada
  
  }

  void loop(){
   
   ESTADO=digitalRead(BOTON);
  
   if( ESTADO==HIGH){ // si el pulsador está presionado 
   
    a++;// dependiendo de la velocidad de barrido, coge valores diferentes. Sumamos y enviamos a comparar.
    pisado=presionado(a,b);//se supone que recibe true

   }

   if(ESTADO==LOW && a>b){// Hemos soltado el pulsador y además ha pasado por el anterior if
    a--;// restamos y enviamos a comparar
    pisado=presionado(a,b);//se supone que se recibe un false
   }
   
   if(pisado==false){
    a=0;
    b=0;
    pisado=true;
    CONT++;//solo si es false se activa el contador
   }
   
   Serial.println(CONT);
        
  }
//Fin de loop*************************************************************************************

  //Funcion que compara el estado de a y b. Mientras a sume es que todavia estamos presionando
boolean presionado(int a,int b){
  if(a>b){
    b=a;
    return(true);
  }
  if(b==a){
    return(false);
  }
}

Este pulsador se acciona mediante una leva que gira con el eje del motor.

Por ahora el motor funciona, y el pulsador funciona, cuando lo presiono con el dedo me cuanta 1 y lo suma.

Lo que no consigo es:

Crear un programa en arduino donde usando los dos códigos pongo en funcionamiento el motor de forma continuada e infinita y que deje de funcionar al dar 5 vueltas tras recibir una señal externa (la del contador ) indicando que ya ha contado 5.

Se que no es muy útil, pero quiero usar el método a modo de señal de aviso o emergencia que me servirá para otros casos.
He creado funciones, las he colocado en el setup, en el loop, he mezclado todo…pero no lo he logrado. Hay algo que no comprendo o que no he conseguido ver.

Si necesitáis fotos de la conexión o de cómo está montado, no es problema.

Gracias de antemano por las ideas o sujerencias que podáis aportar.

Un saludo

Crear un programa en arduino donde usando los dos códigos pongo en funcionamiento el motor de forma continuada e infinita y que deje de funcionar al dar 5 vueltas tras recibir una señal externa (la del contador ) indicando que ya ha contado 5.

Vamos a corregir un poco tu lenguaje técnico para que se comprenda mejor.
Usar un contador no es una señal externa. Externo se considera todo lo que esta por fuera del Arduino. En general señales que pueden provenir por entradas digitales y/o analógicas, o por vias de comunicación sea Serial, I2C, SPI o WIFI/Ethernet.

Cuando unes códigos debes respetar una secuencia lógica muy simple

  1. Todas las librerías de ambos programas deben incluirse antes del setup().
  2. Todas las variables globales exactamente lo mismo. Incluidas antes del setup.
    Nada repetido.
  3. En el setup() colocas todo lo que este en ambos programas sin repeticiones.
  4. En el loop entonces te queda el problema mas importante.
    Basicamente lo mismo que el setup() o sea, copiar ambos códigos sin repetir y tratando de que trabajan de modo adecuado.

Ahora como se hace esto con el tuyo.

Aunque hay cosas que falta resolver, los dos programas juntos quedan asi.

//Declaracion del pin de conexion
const int boton   =  12;
const int dirPin  =   5;
const int stepPin =   2;

const int paso    =  200;
int micropasos    = 1000;

char n;
int vueltas;
int limit=5;

//variables para funcion pushmeter
int estado=LOW;
int cont;
int a=0;
int b=0;

//Declaración e iniciación de variables de estado
int estado = LOW;
int cont;
int a=0;
int b=0;
boolean pisado  = true;
boolean proceso = false;

// Funcion que compara el estado de a y b. Mientras a sume es que todavia estamos presionando
boolean presionado(int a,int b){
  if (a>b){
     b=a;
     return(true);
  }
  if (b==a){
     return(false);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(dirPin,OUTPUT);
  pinMode(stepPin,OUTPUT);
  pinMode(boton,INPUT);
}

void loop() {
  estado = digitalRead(boton);
  
  if (estado == HIGH){          // si el pulsador está presionado
      a++;                      // dependiendo de la velocidad de barrido, coge valores diferentes. Sumamos y enviamos a comparar.
      pisado = presionado(a,b); // se supone que recibe true
  }

  if (estado == LOW && a>b){    // Hemos soltado el pulsador y además ha pasado por el anterior if
      a--;                      // restamos y enviamos a comparar
      pisado = presionado(a,b); // se supone que se recibe un false
  }

  if (pisado == false){
      a=0;
      b=0;
      pisado = true;
      cont++;                   // solo si es false se activa el contador
  }

  Serial.println(cont);

  if (Serial.available()>0) {
      n = Serial.read();
      if (n=='1'){
          digitalWrite(dirPin,HIGH);
      }
      if (n=='0'){
          digitalWrite(dirPin,LOW);
      }
      int a = 1;
      for (int i = 0; i<a; i++){
           digitalWrite(stepPin,HIGH);
           delayMicroseconds(micropasos);
           digitalWrite(stepPin,LOW);
           delayMicroseconds(micropasos);
           a++;
      }
  }
}

Encuentro que b siempre vale 0 de modo que no se qué comparas.
Tienes dos valores '1’y ‘0’ con lo que comandas el motor.
Si esperas hacerlo con el contador a falta hacer algunos cambios.
Solo te dejo esto para que puedas continuar con tu idea.

Gracias surbyte, tienes razón, me falta mucho conocimiento en cuanto expresiones y si cada uno de nosotros usamos expresiones distintas para una misma cosa es un caos. Intentaré corregirlo.

En cuanto a la variable b, sí la comparo, lo hago en la función -> presionado(int a,int b)
cuando la señal es HIGH, a suma y entonces b = a -> b suma.
Cuando es LOW a resta, no es mayor que b y por lo tanto ha debido de soltarse el pulsador.

Aqui lo que busco en concreto es el primer pulso en LOW que es justo después de haber sido presionado el botón. Eso es lo mismo que haber dado una vuelta.
Esto es debido a que el tiempo que se mantiene pisado el botón " HIGH " depende de la velocidad de giro.
Y también se debe a que hay un tiempo de respuesta a la acción de pulsar y/o soltar, que no he conseguido dominar. Por lo que me ha parecido más sencillo utilizar el hecho de que después de un HIGH tiene que haber un LOW. (excepto fallo eléctrico o mecánico)

Voy a probar lo que me propones y te cuento.

Muchas gracias ¡¡¡

He arreglado un poco el código y sigo igual que antes, es decir: Introduzco un 1, el motor gira continuamente, la leva pisa al pulsador, pero el contador se mantiene a 0.

Entonces lo que yo entiendo es que es una cuestión de prioridad (y que estoy haciendo algo mal)

Que tal como lo estoy planteando hasta ahora lo que consigo es dar preferencia a la entrada por el Serial y este hecho anula al pulsador ya que mantiene el contador siempre a cero. O al revés, podría dar prioridad al contador y dejar anulada la entrada por el Serial.

Ninguna de las dos es la solución. Ya que lo que pretendo es que cuando introduzco el 1 en el serial, el motor gire en un sentido y además que si supera un cierto número de vueltas se pare y que el sistema quede esperando a una nueva entrada en el serial, con el contador reseteado a 0 para poder volver a repetir el proceso.

Yo creo que me debería de funcionar con dos funciones, y esto es lo que no logro hacer con arduino. En C o en Java sí que logro hacerlo.

Los dos códigos como skech independientes funcionan, pero juntos no.

¿Sería correcto hacer dos funciones ? ¿Cómo tendría que interactuar con ellas en el loop?

o,¿hay que hacer un nuevo código reacoplando las ordenes? (esta no me gusta, en este caso son solo dos ordenes)

¿Es el uso de Serial.available() la que impide?

Ya me contaréis, mientras voy a seguir dándole vueltas.

Muchas gracias y disculpar por el tocho.

Bien.
Vamos aclarando las cosas.
Cuando tienes dos entradas de control : Serial y otro elemento, debes resolver como actuar en caso de que uno le diga al otro lo que no deseas.

Entonces via Serie enviaras un ‘1’ o un ‘0’ para cambiar de dirección el motor.
Por pulsador accionaras y cuando lo hagas una vez será una cosa y en la siguiente debiera ser la otra. Supongo que esa es la idea.

A ver si esto funciona mas o menos como lo que quieres

#include <Arduino.h>
//Declaracion del pin de conexion
const int botonPin  =  12;
const int dirPin    =   5;
const int stepPin   =   2;

const int paso      =  200;
int micropasos      = 1000;
int limit           = 5;

//variables para funcion pushmeter
bool estadoAnt = false, estado;
bool fcontrol = false;

void setup() {
  Serial.begin(115200);
  pinMode(dirPin,OUTPUT);
  pinMode(stepPin,OUTPUT);
  pinMode(botonPin,INPUT);
}

void loop() {
  estado = digitalRead(botonPin);
  if (estado && !estadoAnt){          // si el pulsador está presionado
      fcontrol = !fcontrol;          // dependiendo de la velocidad de barrido, coge valores diferentes. Sumamos y enviamos a comparar.
  }
  estadoAnt = estado;
  Serial.println(cont);

  if (Serial.available()>0) {
      char n = Serial.read();
      if (n=='1') {
          // controlo direccion horaria
          digitalWrite(dirPin,HIGH);
      }
      if (n=='0'){
          // controlo dirección antihoraria
          digitalWrite(dirPin,LOW);
      }
  }
  if (fcontrol) {
      for (int i = 0; i<limit; i++){
          digitalWrite(stepPin,HIGH);
          delayMicroseconds(micropasos);
          digitalWrite(stepPin,LOW);
          delayMicroseconds(micropasos);
      }
      fcontrol = false;
  }
}

Gracias¡¡¡ surbyte por tu tiempo.

Lo he probado, no arranca.

Voy a ver si haciendo algún pequeño cambio....

De todas formas hay un par de cosas, primero que no sabía que se podía declarar la variable estado tal como lo has hecho.

La segunda es que vinculas el giro a la cantidad de vueltas en el for. Ese caso no interesa, te explico:

La idea es que si todo funcionase bien y sin ningún fallo extra, no necesitaríamos sensores. Sin embargo la realidad es que cuando hay un motor en marcha tenemos que poner un montón de elementos que tienen que limitar, o directamente parar el sistema.

Este caso (que igual esoy equivocado) es experimentación para activar primero un motor y poner yo todas las trabas, la primera que se me ocurre es un fallo de programación y que el sistema de más vueltas reales de las debidas (o menos). O sea, que haga una programación para que suceda una "longitud" de movimiento, pero que en realidad se me vaya de largo.
Pero claro después hay más casos, más levas, botones o sensores que me tienen que detener el programa. Si ahora lo vinculo a un solo pulsador, después tendría que cambiar todo el programa si necesitaría introducir otro elemento.

Imaginate eso pero con 10 sensores.

Por ello decía yo lo de las funciones. (o igual hay otra expresión, en C las llaman funciones, en java métodos).

Te adelanto un poco más cómo va el proyecto:

Ya he conseguido comunicar Java y arduino.
He creado ya una interface que me activa tres motores. con sus giros y sus cantidades de pasos.
En esa interface puedo introducir puntos geométricos,crear líneas y con ello un trayecto, los transformo en un código, que puedo visualizar y reproducir el movimiento en pantalla. Esa misma señal de pantalla es la misma que se envía a arduino a traves del puerto.

Pero.....no detecta fallos humanos o errores tontos como falta de pieza, alguién ha metido la mano, etc.
Y ahí es donde me encuentro:
1ª prueba de fallo -> arduino tiene que recibir el fallo detectado por un sensor o varios y enviarlo a la interface de java.(o al programa que sea). Con el siguiente objetivo, arduino no permite que continue el problema hasta que el programa principal lo valore, espera respuesta y vuelta a empezar.

Pero claro después de solucionar el primer caso, tengo que meter otro segundo sensor porque seguro que habrá más.

Es por ello que el movimiento principal del motor no debe estar vinculado directamente a la señal de uno de los posibles sensoesr, sino que una vez generado el movimiento se producirán datos que actuarán sobre el motor pero no directamente.
No se si he logrado explicarlo.

De nuevo gracias por contestar,

Sigo con ello,

Un saludo.

Hola de nuevo,

Por ahora sigo con mi idea inicial y me han surgido varios problemas.

He hecho unos cambios, he creado una función para arrancar el motor dependiendo del pulsador y he cambiado el for por un while y dentro de éste último el pulsador, parecido a como indicaba surbyte.

Funciona igual que antes, mal. No obedece todo ello junto.

Bien. Para buscar el fallo he ido metiendo ordenes print y dependiendo donde metiese provocaba otro fallo y ralentizaba el movimiento del motor haciendolo más lento.

Y por último en la parte arrancaMotor donde se decide el sentido de giro, he cambiado un if + if por un if + else.
En el if + if entraba el 1, giro horario, pero fallaba si metia el 0, yo creía que se trataba de una conexión, y no, es que da fallo.
Con el else, introduzco el 1 ó 0 y funciona bien,gira en los dos sentidos. Excepto que da la opción a introducir cualquier valor( problema menor).

Adjunto el código nuevo

const int BOTON=12;
const int dirPin =5;
const int stepPin=2;
const int paso=200;
int micropasos=1000;

char n;
int Nvueltas=0;
int estado=LOW;
int limit=5;
int CONT=0;
int a=0;
int b=0;
boolean pisado=true;



// Funcion que compara el estado de a y b. Mientras a sume es que todavia estamos presionando
boolean presionado(int a,int b){
  
  if (a>b){
     b=a;
     return true;
  }
  if (b==a){
     return false;
  }
  
}

void setup() {
  Serial.begin(115200);
  pinMode(dirPin,OUTPUT);
  pinMode(stepPin,OUTPUT);
  pinMode(BOTON,INPUT);


}

void loop() { 

  if(Serial.available()>0){  
    
   n=Serial.read();
   ArrancaMotor(n);
  }
   
   
}

//Funcion contador que devuelve el número de vueltas al pisar con una leva un pulsador


int PushMeter(int ESTADO){
  Serial.print(" dentro del pushmeter recibo  ");
  Serial.println(ESTADO);
    if( ESTADO==HIGH){       // si el pulsador está presionado    
    a++;                     // dependiendo de la velocidad de barrido, coge valores diferentes. Sumamos y enviamos a comparar.
    pisado=presionado(a,b);  //se supone que recibe true
   }

   if(ESTADO==LOW && a>b){   // Hemos soltado el pulsador y además ha pasado por el anterior if
    a--;                     // restamos y enviamos a comparar
    pisado=presionado(a,b);  //se supone que se recibe un false
   }
   
   if(pisado==false){
    a=0;
    b=0;  
    pisado=true;
    CONT++;//solo si es false se activa el contador
    }    
   return CONT;
  
  }


  //Funcion que compara el estado de a y b. Mientras a sume es que todavia estamos presionando


/*
boolean RESET(boolean proceso){
  //si recibimos un false es que todavia no hemos acabado el proceso. N vueltas menor que limite
  if(proceso==false){
    return true;
  }else{
    return false; //enviamos true cuando el proceso es true= ha terminado
  }
}
*/

//funcion que gira motor en una direccion hasta que cambia algo

void ArrancaMotor( char n){
 //int estado=LOW;
 //int Nvueltas=0; 
      if (n=='1'){
    digitalWrite(dirPin,HIGH);
    }
    //if(n=='0'){
    else{
     digitalWrite(dirPin,LOW); 
    }
    Serial.print(" en arrancarmotor antes del while-> vuetas dadas");
    Serial.println(Nvueltas);
    while(limit>Nvueltas){
      
           digitalWrite(stepPin,HIGH);
           delayMicroseconds(micropasos);
           digitalWrite(stepPin,LOW);
           delayMicroseconds(micropasos);
          estado = digitalRead(BOTON);
          Nvueltas=PushMeter(estado);
          // Serial.print(" en arrancarmotor dentro del while-> estado  ");
   // Serial.println(Nvueltas);
          
      }
  // Serial.print(" en arrancarmotor he terminado, vuetas dadas");
  // Serial.println(Nvueltas);
  }

Entonces llego a la siguiente conclusión:

Los dos códigos por seperado funcionan bien.

La mezcla me ralentiza, tanto que dejan de funcionar bien las secuencias if.

Me da la impresión que no consigo enlazar las dos funciones en cadena, creo que es por tema de velocidad de reacción. O sea:

Funciona arrancarmotor.
Funciona mal cuando arrancaMotor llama a pushmeter
Y no funciona la llamada de pushmeter a presionado.

Y a esto ya no sé como meterle mano.

Un saludo

Vamos avanzando.

Bueno, a la pregunta inicial sobre el tema de funciones y programación, ya está solucionado.

Sobre el programa o código arduino, tengo que cambiar el planteamiento.

He logrado arrancar el motor, he logrado pararlo y he logrado que me marque un 5 en pantalla. (el 5 era solo un límite aleatorio).
Pero no lo ha hecho de forma ordenada.

A falta de más investigación por mi parte, el problema está en que hay dos secuencias de tiempo distintas.

En la parte del motor hay que introducir un par de delayMicroseconds, y es después de ellos cuando se hace la llamada para ver el estado del contador, el cuál está utilizando la secuencia de tiempo del loop.

Esto hace que la respuesta no sea la adecuada, van a distinto ritmo.

Un trozo de solución ha sido quitar la espera en la parte del motor y ponerla en la parte del pulsador.

esta es la parte del código donde hago el cambio:

...
...

 while(limit>Nvueltas){
      
           digitalWrite(stepPin,HIGH);
           estado = digitalRead(BOTON);
           Nvueltas=PushMeter(estado);
           //delayMicroseconds(micropasos); //quito la espera para funcionamiento motor y la introduzco en la funcion pushmeter
           digitalWrite(stepPin,LOW);
           estado = digitalRead(BOTON);
           Nvueltas=PushMeter(estado);
          //delayMicroseconds(micropasos); //quito la 2ªespera para funcionamiento motor y la introduzco en la funcion pushmeter
}

...

...

El resultado de este cambio ha sido una mejora (en comprensión de arduino), pero que todavía estoy lejos de la solución, ya que entiendo que hay un conflicto de tiempos.
Quizás la solución pase por hacer algún tipo de librería en C, no lo sé.

Cuando tenga la solución os la comento, porque esto requiere un cambio en el planteamiento del problema.

Un saludo y gracias.

Bueno, veo que has dejado varias respuestas.
Primero una respuesta a tus comentarios sobre mi código: Lo que hice fue simplemente unirte los códigos, no presté atención a lo que querías que hiciera pero solo enfoqué mas o menos la idea.
Muchos de los códigos que sugiero no están probados de modo que si falta algo espero que el interesado sepa resolverlo. Ej. una variable no declarada solo requiere hacerlo y no preguntar indefinidamente cómo se hace.

En el post#5 por primera vez hablas de tu idea general que desconocíamos totalmente.
Así que para nosotros solo eran dos códigos que debían unirse, la idea justamente fue mostrarte como se unen y que de ahí en mas, sigas tu.

Quizás la solución pase por hacer algún tipo de librería en C, no lo sé.

Te aconsejo que en este momento de tu programación no te compliques mas, crear una librería no va a mejorar las cosas.

El problema que veo es que todo esta supeditado a que se ingrese un valor por teclado via PC.
NO se si es la idea pero, esto funcionará al punto que en tu monitor Serie, verás muchos ArrancarMotor que no será de tu agrado pero la rutina debería funcionar como quieres.

Tal vez esto no te sirva pero debería ser mas dinámico

const int botonPin  = 12;
const int dirPin    = 5;
const int stepPin   = 2;
const int paso      = 200;
int micropasos      = 1000;

char n;
int Nvueltas        = 0;
int estado          = LOW;
int limit           = 5;
int cont            = 0;
int a               = 0;
int b               = 0;
bool pisado         = true;
bool presento       = false;



// Funcion que compara el estado de a y b. Mientras a sume es que todavia estamos presionando
boolean presionado(int a,int b){
  if (a>b){
      b=a;
      return true;
  }
  if (b==a){
     return false;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(dirPin,OUTPUT);
  pinMode(stepPin,OUTPUT);
  pinMode(botonPin,INPUT);
}

void loop() {

  if (Serial.available()>0){ 
      n = Serial.read();
      if (n == '1'){
          digitalWrite(dirPin,HIGH);
      }
      //if(n=='0'){
      else {
          digitalWrite(dirPin,LOW);
      }
  }  
  ArrancaMotor(n);
}

//Funcion contador que devuelve el número de vueltas al pisar con una leva un pulsador
int PushMeter(int ESTADO){
  Serial.print(" dentro del pushmeter recibo  ");
  Serial.println(ESTADO);
  if (ESTADO==HIGH){            // si el pulsador está presionado   
      a++;                      // dependiendo de la velocidad de barrido, coge valores diferentes. Sumamos y enviamos a comparar.
      pisado = presionado(a,b); // se supone que recibe true
  }

  if (ESTADO==LOW && a>b){      // Hemos soltado el pulsador y además ha pasado por el anterior if
      a--;                      // restamos y enviamos a comparar
      pisado = presionado(a,b); // se supone que se recibe un false
  }
   
  if (pisado==false){
      a=0;
      b=0; 
      pisado = true;
      cont++;                   // solo si es false se activa el contador
  }   
  return cont;
}

//funcion que gira motor en una direccion hasta que cambia algo
void ArrancaMotor( char n){
 //int estado=LOW;
 //int Nvueltas=0;

  if (presento) {
      Serial.print(" en arrancarmotor antes del while-> vuetas dadas");
      Serial.println(Nvueltas);
      presento = false;      // de este modo presento cuando se digite algun valor en teclado.
  }
  while (limit>Nvueltas){
        digitalWrite(stepPin,HIGH);
        delayMicroseconds(micropasos);
        digitalWrite(stepPin,LOW);
        delayMicroseconds(micropasos);
        estado = digitalRead(botonPin);
        Nvueltas  PushMeter(estado);
        // Serial.print(" en arrancarmotor dentro del while-> estado  ");
        // Serial.println(Nvueltas);
  }
  // Serial.print(" en arrancarmotor he terminado, vuetas dadas");
  // Serial.println(Nvueltas);
}

ahora solo cuando presiones algo sea '1' u otra cosa, veras
"en arrancarmotor antes del while-> vuetas dadas"
el resto del tiempo si Nvueltas supera limit no hará nada.

No sé si se estoy entendiendo.

Hola de nuevo, y gracias surbyte por tu tiempo.

He seguido haciendo pruebas, y el resultado es que de forma directa, como si hiciésemos un programa en C, no funciona. No lo hace porque el barrido lleva un tiempo, el motor lleva otro tiempo.
La señal de control del pusador depende de la velocidad de barrido del loop, y así tiene que ser. Porque sea como sea el funcionamiento del motor, lo que interesa es el estado del pulsador en cada instante. (a poder ser instante más corto posible más fiable)

(Excepto haya algo por ahí que yo desconozca) Lo que sí funciona bien es la señal del pin del pulsador, que da 0 y 1 en tiempo real (auque hay algo de desfase), y la solución a la que he llegado es que sea el programa principal quién y donde se ejecute el conteo del pulsador.

Y me queda la duda de si esto se puede sustituir por una libreria, donde yo envio el dato de estado del pin del pulsador y se ejecute el conteo al instante allí.

El problema que veo es que todo esta supeditado a que se ingrese un valor por teclado via PC.

Sí, pero este no es problema. Tengo que enviar constantemente al menos 9 datos para mover 3 motores (las pruebas estoy haciendo con uno solo). Como ya te he contado a través de una interface he probado ya con un motor PM35s 048 y un driver ULN2003 y todo correcto.
He probado con un Nema 17 y un driver DRV 8825 y todo bien.

Ahora estoy en recibir y ejecutar señales de aviso y parada no programada, por ejemplo que algo me active un pulsador 5 veces y se detenga el motor. O sea, estoy buscando problemas y solucionarlos antes de que me ocurran.

Por ahora la solución pasa por: El programa que gestiona la interface será quien gestione el conteo tras recibir las distintas señales del pin 12 a través del Serial.

Ya enseñaré la solución, si hay alguna otra será bienvenida.

Saludos.