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.
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.
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
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.
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
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:
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:
Supongo que un 2N2222 o un BC547 (NPN) estará bien, pero me quedan dos dudas:
debería usar un diodo de flyback? Cuál me recomiendan en ese caso?
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
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
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.
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.
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.