Bluetooth, como recibir un caracter y realizar un condicional

Buenas noches.
Estoy tratando de hacer una prueba por la cual, al recibir un string desde la terminal de un movil, se decida en base a ese string cuales datos devolver por puerto serie.
Eso está en un código que prende y apaga un pin con una librería de timers y lleva una cuenta de cuantas veces se hizo ese ciclo de encender y apagar el pin (una bomba de agua).
La idea es que si le envío por BT por ej, una letra "c" desde el terminal del celular, me devuelva la cantidad de veces que lleva ese ciclo. Si no envio nada, que no escriba nada, y si envío algo que no es "c" que devuelva "no escribió c".

Pero lo que ocurre es que siempre que hay un caracter enviado desde la terminal, envía interminablemente caracteres numericos al terminal.
O siempre pone que "no escribió c".

Les dejo el código:

El codigo es el siguiente:

// este sketch prende y apaga un pin con los valores
// definidos en timerOn y timerOff

#include <Arduino.h>
#include <BlockNot.h> //libreria de timers

#include <SoftwareSerial.h> //para manejar el BT
SoftwareSerial BT1(10, 11); // RX | TX
char myChar;



const int timerOn = 10000;  //tiempo que el pin permanece prendido (en HIGH)
const int timerOff = 5000; //tiempo que el pin permanece apagado (en LOW)
int contador=0;
BlockNot bombaTimerON(timerOn, GLOBAL_RESET);
BlockNot bombaTimerOFF(timerOff);

const int bomba_PIN = 13;

bool bombaON = false;

bool bombaIsOff() { return !bombaON; }

bool bombaIsOn() { return bombaON; }

void turnbombaOn() {
    digitalWrite(bomba_PIN, LOW);
    bombaTimerON.RESET;
    bombaON = true;
    contador ++;
}

void turnbombaOff() {
    digitalWrite(bomba_PIN, HIGH);
    bombaTimerOFF.RESET;
    bombaON = false;
}

void setup() {
    BT1.begin(38400);
    Serial.begin(9600);
    pinMode(bomba_PIN, OUTPUT);
    resetAllTimers();
    turnbombaOn();    
    Serial.println(F("\nREADY!\n"));
}

void loop() {

    if (bombaTimerON.TRIGGERED && bombaIsOn()) {    //apaga la bomba
        turnbombaOff();        
    }

    if (bombaTimerOFF.TRIGGERED && bombaIsOff()) {  //enciende la bomba
        turnbombaOn();
        Serial.println("bomba On");
        Serial.println(contador);
    }

    if (BT1.available()) {                          //lee BT y envia a Arduino
        Serial.println(BT1.available());        
        myChar = BT1.read();        
        if (myChar = "c"){
          Serial.println(myChar);}
      } else {Serial.println("no escribió c");};
    
     if (Serial.available()) {
       myChar = Serial.read();                      //lee Arduino y envia a BT
        BT1.print(myChar);        
    }  
}

Si a alguien se le ocurre que es lo que está fallando, o si conviene que use otra librería y me orientan un poco, se los voy a agradecer.

EDITO Y AMPLIO LA PREGUNTA:
mi duda es ¿porqué en la siguiente línea

if (BT1.available()) {                          //lee BT y envia a Arduino
        Serial.println(BT1.available());        
        myChar = BT1.read();        
        if (myChar = "c"){
          Serial.println(myChar);}
      } else {Serial.println("no escribió c");};

siempre imprime en el monitor serie algo? No debería imprimir solo si hay un caracter enviado?
Yo entiendo que BT1.available() solo devuelve "true" si hay un caracter enviado por BT.
Entonces, no entiendo porqué devuelve todo el tiempo algo si no envío nada por la terminal.

Gracias y saludos

Preste atención a la sintaxis, en C códigos, "c" es una cadena y 'c' es un carácter. Dado que un carácter no puede ser igual a una cadena, esta condición nunca se cumplirá.

Tal vez haya otros errores en su código, corrija este primero.

1 Like

Gracias por su pronta respuesta.
He corregido el error de sintaxis, y ahora empezó a cumplirse esa condición.
También descubrí que no es un valor boolean lo que devuelve BT1.available().
Y que la condicion del if se escribe con == en vez de =
Por último, la terminal estaba configurada para que envíe lo tipeado mas un LF.
Tuve que dejarlo en NONE para que no interfiera en la lectura.

copio el código corregido, con algunos agregados:

// este sketch prende y apaga un pin con los valores
// definidos en timerOn y timerOff

#include <Arduino.h>
#include <BlockNot.h> //libreria de timers

#include <SoftwareSerial.h> //para manejar el BT
SoftwareSerial BT1(10, 11); // RX | TX

const int timerOn = 10000;  //tiempo que el pin permanece prendido (en HIGH)
const int timerOff = 5000; //tiempo que el pin permanece apagado (en LOW)
int contador=0;
BlockNot bombaTimerON(timerOn, GLOBAL_RESET);
BlockNot bombaTimerOFF(timerOff);

const int bomba_PIN = 13;

bool bombaON = false;

bool bombaIsOff() { return !bombaON; }

bool bombaIsOn() { return bombaON; }

void turnbombaOn() {
    digitalWrite(bomba_PIN, LOW);
    bombaTimerON.RESET;
    bombaON = true;
    contador ++;
}

void turnbombaOff() {
    digitalWrite(bomba_PIN, HIGH);
    bombaTimerOFF.RESET;
    bombaON = false;
}

void setup() {
    BT1.begin(38400);
    Serial.begin(9600);
    pinMode(bomba_PIN, OUTPUT);
    resetAllTimers();
    turnbombaOn();    
    Serial.println(F("\nREADY!\n"));
}

void loop() {

    if (bombaTimerON.TRIGGERED && bombaIsOn()) {    //apaga la bomba
        turnbombaOff();        
    }

    if (bombaTimerOFF.TRIGGERED && bombaIsOff()) {  //enciende la bomba
        turnbombaOn();
        Serial.println("bomba On");
        Serial.print("Desde enciende la bomba>contador :");
        Serial.println(contador);
    }

    if (BT1.available()) {                          //lee BT y envia a Arduino             
        char myChar = BT1.read();
        Serial.println("-------------------------");
        Serial.print ("valor de myChar a testear> ");       
        Serial.println (myChar);
        Serial.println("-------------------------");
        if (myChar == 'c'){
          Serial.println("-------------------------");
          Serial.print("respuesta a comando c> ");
          Serial.print("contador: ");
          Serial.println(contador);
          Serial.println("-------------------------");
          BT1.println("-------------------------");
          BT1.print("respuesta a comando c> ");
          BT1.print("contador: ");
          BT1.println(contador);          
          BT1.println("-------------------------");
          }
          else {
            Serial.println("-------------------------");
            Serial.println("no escribió c");
            Serial.println("-------------------------");
            };
      } 
      //
    
     if (Serial.available()) {
       char myChar = Serial.read();                      //lee Arduino y envia a BT
        BT1.print("Desde Serial.available");
        BT1.print(myChar);        
    }  
}

Ahora está funcionando. Muchas gracias.
Dejo el hilo abierto por unos días por si surge alguna complicación mas.
Saludos

1 Like

Ahora tengo otra pregunta.
La placa Arduino UNO la alimento de un conector USB a la PC.
Cuando conecto el modulo BT (alimentado desde el Vin de la placa Arduino), mas la bomba de agua (1080mW de potencia, conectada a un pin de salida digital), el modulo BT (es un HC-05) funciona bien, pero la bomba no activa).
Si desconecto el BT, la bomba activa, o sea funciona (está cableada al pin digital 13 de la placa).
Es posible que no llegue a mover la bomba por falta de corriente?
No soy muy ducho en esto de calcular los consumos.
Si alguien pudiera darme una mano en esto, lo agradezco.

EDITO

Agrego otra duda: quizás sea necesario usar un relé o un transistor para manejar la bomba?
Hace unos días lo había probado con el pin conectado a la bomba directamente y funcionó. Era una prueba sin mas complicaciones: un sketch que solo prendia y apagaba el pin con un delay.
No entiendo porqué ahora no activa la bomba con ese mismo pin.

Que tiene que ver VIN? En todo caso será 5V y no alimentes jamás una bomba de agua con los 5V del arduino. Usa alimentación externa y comparte GND.

1 Like

Gracias por su respuesta.
Veo que fallé en la descripción.
La bomba estaba conectada a un pin digital.
La idea es que al darle un high a ese pin, se active la bomba. Es una bomba pequeña, de 3 a 5 V de CC .
El Vin lo uso para alimentar al módulo BT. Y funciona bien así.
Leí en un artículo en Internet, que si se usa la placa Arduino alimentada por USB, el pin Vin se puede usar para alimentar pequeñas cargas.
Por su respuesta, parece que no es conveniente.

no está bien. El pin VIN no debe usarse como salida de alimentación, solo como entrada. Al alimentar la placa desde usb, conecte su módulo BT al pin 5v

Por favor, que es una bomba en espanol? :slight_smile:

1 Like

Jaja, es un motor que se sumerge en agua para "bombearla" o llevarla de un recipiente a otro. En este caso, de un recipiente a una maceta. Por ej:
bombaAgua

Cuál es tu lengua nativa?

Por otra parte, estuve leyendo que conviene que la bomba (viene con dos cables, positivo y negativo) esté conectada obviamente una a GND y la otra a través de un relé o de un MOSFET. Pero también veo que los BJT se pueden usar para cargas menores.
Cuál convendría para este caso? La alimentación de la bomba, según quien me la vende, es de 3 a 5V CC y el consumo de 1080 mW.
Encontré este esquema:
arduino-transistor-bjt-montaje-flyback

Supongo que un 2N2222 o un BC547 (NPN) estará bien, pero me quedan dos dudas:

  1. debería usar un diodo de flyback? Cuál me recomiendan en ese caso?
  2. Valor de la resistencia Rb?
1 Like

No uso transistores bipolares. En mi opinión es mejor usar el N-mosfet en modo clave

Es deseable. Puede tomar cualquier diodo con corriente continua 5-10 veces más que la del motor. Creo que en su caso cualquier diodo 1A servirá.

1 Like

Si pudieras especificar cual sería el N-mosfet, y los valores de resistencias, te lo agradezco.

No conectes la bomba de agua a un pin digital jamás.
Usa Mosfet.
Si al bomba de agua es de baja potencia tal vez un 2n7000 sirva, sino busca un IRL510 o 520

1 Like

No puedo recomendar mosfet, pero las resistencias son Rin = 150-250 Ohm, Rgs = 1.5 - 3K

1 Like

Una bomba de agua de acuario, se puede comandar bien con un 2n7000

image
Busca 2n7000 motor y luego imágenes y tendras ejemplos similares.

1 Like

Buenísimo @Surbyte . Muchas Gracias.
En estos días lo pruebo y cuento como fue.

Repito, solo es válido para un motor pequeño como el que describes.
Revisa que tensión de trabajo requiere, no uses el arduino para alimentarlo. No es aconsejable

1 Like

Les quiero consultar porque no entiendo bien la datasheet del MOSFET que conseguí:
IRFZ44N
¿Sirve para usarlo de driver de la bombita con el Arduino?

Creo que si, si usas una placa con un nivel lógico de 5v
El mosfet seleccionado tiene un "gate threshold" de 2 a 4v, es decir, se abrirá completamente desde la señal de arduino.
Si va a utilizar un PWM para controlar un mosfet, debe analizarlo por separado.

1 Like

Gracias.
No entiendo qué sería "analizarlo por separado"?

El modo de funcionamiento del mosfet cuando se usa PWM es muy diferente de un simple interruptor. En este caso, se deben tener en cuenta la capacitancia de un "gate", la frecuencia de conmutación y otros factores. No puedo ayudar con esto.

1 Like

El IRFZ44 es demasiado mosfet, esta pensado para grandes corrientes.
Es como poner un contactor para accionar un motor de 100mA. Funcionará si, pero esta mas que sobredimensionado. Es para cargas de hasta 49A. Entiendes por qué digo que esta sobredimensionado para esta tarea?
Quieres usarlo? Usalo sin problemas.
Pero con el que yo te dije es suficiente para un motor pequeño.

1 Like