Error con Delays

Hola, tengo un problema y ya traté de resolverlo pero nada aún.

En sí quiero que dependiendo de lo que yo le escriba en el monitor serial se muevan dos servomotores de diferente forma (abrir o cerrar). El caso es que ya traté con variables de confirmación pero se las salta. Los delay() que coloqué son porque quiero que se muevan de distinto tiempo también, pero al momento de poner a funcionar todo se mueven al mismo tiempo.

Acá está el código:

#include <Servo.h>
#include <SoftwareSerial.h>

SoftwareSerial Puerta(10, 11); // RX, TX

Servo puerta;
Servo pasador;

int estadoPuerta;

void setup() {
  // Open serial communications and wait for port to open:

  puerta.attach(8);
  pasador.attach(9);
  
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // set the data rate for the SoftwareSerial port
  Puerta.begin(9600);
}

void loop() { // run over and over
  if (Puerta.available()) {
    Serial.write(Puerta.read());

    switch(Puerta.read()) {
      case '1':
        if(estadoPuerta == 1) {
          puerta.write(0);
          delay(1500);
          Serial.println(estadoPuerta);
          pasador.write(20);
          delay(1500);
          estadoPuerta = 2;
          Serial.println(estadoPuerta);
        }
        break;
      case '2':
        if(estadoPuerta == 2) {
          pasador.write(80);
          delay(1500);
          Serial.println(estadoPuerta);
          puerta.write(100);
          delay(1500);
          estadoPuerta = 1;
          Serial.println(estadoPuerta);
        }
        Serial.println(estadoPuerta);
        break;
    } 
  }
}

Y sí, estoy enviando la información por bluetooth. Como son datos de un sensor, el bluetooth envía varios "1" o "2", por lo que creería que eso hace que se repita varias veces, pero no tiene sentido que los servos hagan ambas funciones si le he puesto ya dos verificaciones en ambos casos. En serio ya solo esto falta para terminar el proyecto, les agradecería muchísimo su ayuda.

You can't read twice because you only know that there is one character ready to read.
If you want to echo the character, read it once into a variable.

1 Like

Te aclaro lo que dice @anon43666536

Suponte que envías un "1", con la sentencia

Serial.write(Puerta.read());

lees ese "1" y lo eliminas del buffer.
Entonces no hay caracter para la siguiente lectura, o sea

switch(Puerta.read()) {

porque ya quitaste ese "1" del buffer.

Puedes hacer

if (Puerta.available()) {
  Serial.write(Puerta.peek());

  switch(Puerta.read()) {

ya que peek() no quita el caracter del buffer, o sino guardar el caracter en una variable y trabajar con ella.

Saludos

1 Like

Ya corregí en base a lo que me dijeron ambos. Estuve probando y aún seguía teniendo el problema con los servomotores.

Investigando me di cuenta que había un conflicto con la librería softwareserial y servo, y pensé que talvez eso lo resolvería y nada.

Acá dejo el nuevo código que tengo:

#include <NeoSWSerial.h>

#include <Servo.h>

NeoSWSerial Puerta(10, 11); // RX, TX

Servo puerta;
Servo pasador;

void setup() {
  // Open serial communications and wait for port to open:

  puerta.attach(3);
  pasador.attach(4);

  puerta.write(0);
  pasador.write(20);
  
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Puerta.begin(9600);
}

void loop() { // run over and over
  if (Puerta.available()) {
    int mpu = Puerta.read();
    Serial.write(mpu);

      if(mpu == 1) {
        pasador.write(80);
        delay(1500);
        puerta.write(100);
        delay(1500);
      }
      if(mpu == 2) {
        puerta.write(0);
        pasador.write(20);
      }
  }
}

Por alguna razón esa librería no reconoce el comando peek(), o el parseFloat(), ya que al decirle que la imprima no coloca nada en el monitor serial.

Si, revisé el código de la librería y peek() deliberadamente retorna 0.
Probablemente le causó algún problema al autor porque es raro que haya forzado la devolución de 0.

Me llama la atención que parseFloat() no funcione porque es un método heredado de la clase Stream (la misma que hereda Serial), no se qué decirte...

Ahora, esto no está bien en tu código

int mpu = Puerta.read();

porque si ingresas '1' (el dígito 1) entonces mpu va a tener el valor 49 ya que es el código ASCII del caracter '1'.

En la medida que ingreses dígitos del 0 al 9 y nada más, puedes resolverlo haciendo

int mpu = Puerta.read() - 48; // 48  es el código ASCII de '0'

en otro caso hay que validar el ingreso.

También podrías hacer

if(mpu == 49) { // código ASCII de '1'

O directamente declara mpu de tipo char y luego, por ej.

if(mpu == '1') { // comillas simples porque encierran un caracter

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.