Error en mi código?

Buenas, estoy haciendo un mini-proyecto para la universidad donde tengo que calcular la velocidad y aceleración de una pequeña pelota al dejarse caer por una barra que se mueve en diferentes ángulos. He escrito este código, pero cuando lo compilo nada funciona ni la pantalla LCD, ni la barra se mueve ni los sensores ir calculan nada. Alguien puede ayudarme?
Aquí les adjunto el código:


#include <LiquidCrystal_I2C.h>  
      
#include <Wire.h>

#include <Servo.h>

double servo2;
double vel;
double acc;
double t1;
double t2;
double t3;
double vel1;
double t4;
double vel2;
double vel3;

boolean b_s1;
boolean b_s2;
boolean b_s3;
boolean b_s4;

LiquidCrystal_I2C lcd(0x27,16,2);
unsigned long task_time_ms=0;

Servo servo_4;

Servo servo_5;

unsigned long time_timer=millis();


void serial() {
  if((millis()-task_time_ms)>=2000){
    task_time_ms=millis();
    Serial.print(String("Velocitat:  "));
    Serial.println(vel);
    Serial.print(String("Acceleracio: "));
    Serial.println(acc);
  }
}

void LCD() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(String("Vel"));
  lcd.setCursor(8, 0);
  lcd.print(String("Acc"));
  lcd.setCursor(0, 1);
  lcd.print(vel);
  lcd.setCursor(8, 1);
  lcd.print(acc);
}

void servo() {
  for (servo2 = 72; servo2 >= 60; servo2=servo2-2) {
    servo_4.write(servo2);
    delay(100);
  }
  servo_5.write(45);
  delay(2000);
  servo_5.write(0);
  delay(100);
  for (servo2 = 60; servo2 <= 72; servo2=servo2+2) {
    servo_4.write(servo2);
    delay(100);
  }
  delay(3000);
  for (servo2 = 72; servo2 >= 52; servo2=servo2-2) {
    servo_4.write(servo2);
    delay(100);
  }
  servo_5.write(45);
  delay(2000);
  servo_5.write(0);
  delay(100);
  for (servo2 = 52; servo2 <= 72; servo2=servo2+2) {
    servo_4.write(servo2);
    delay(100);
  }
  delay(3000);
  for (servo2 = 72; servo2 >= 44; servo2=servo2-2) {
    servo_4.write(servo2);
    delay(100);
  }
  servo_5.write(45);
  delay(2000);
  servo_5.write(0);
  delay(100);
  for (servo2 = 44; servo2 <= 72; servo2=servo2+2) {
    servo_4.write(servo2);
    delay(100);
  }
}

void sensors() {
  b_s1 = digitalRead(8);
  b_s2 = digitalRead(9);
  b_s3 = digitalRead(10);
  b_s4 = digitalRead(11);
  if ((!b_s1)) {
    time_timer=millis();
    t1 = millis();
    t1 = (t1 / 1000);

  }
  if ((!b_s2)) {
    t2 = millis();
    t2 = (t2 / 1000);
    vel1 = (0.26 / ((t2 - t1)));

  }
  if ((!b_s3)) {
    t3 = millis();
    t3 = (t3 / 1000);
    vel2 = (0.5 / ((t3 - t2)));

  }
  if ((!b_s4)) {
    t4 = millis();
    t4 = (t4 / 1000);
    vel3 = (0.26 / ((t4 - t3)));
    vel = (((vel1 + ((vel2 + vel3)))) / 3);
    acc = (vel / ((t4 - t1)));

  }
}

void setup()
{
  lcd.init();
  lcd.noCursor();
  lcd.backlight();
Serial.begin(9600); Serial.flush(); while(Serial.available()>0)Serial.read();

servo_4.attach(4);

servo_5.attach(5);

pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
  b_s1 = true;
  b_s2 = true;
  b_s3 = true;
  b_s4 = true;
  t1 = 0;
  t2 = 0;
  t3 = 0;
  t4 = 0;
  vel3 = 0;
  vel = 0;
  acc = 0;
  servo2 = 72;

}


void loop()
{

    sensors();
    LCD();
    serial();
    servo();

}
 

Primero que nada, edita tu post y pon el código de acuerdo a las Normas del foro español punto 7.

En principio creo que el problema es que inicias el LCD con

lcd.begin(16,2);

en lugar de

lcd.init();

No puedo comprobarlo ahora pero, de acuerdo al código de la librería, .begin() no inicia Wire (que maneja la comunicación I2C), en cambio .init() sí lo hace.

Imagino que por eso, ni siquiera te muestra nada en el display, porque no hay comunicación.

Otro problema que tiene tu código son los delay(), la secuencia de movimiento de los motores le lleva casi 20 segundos de los cuales el 99% del tiempo no hace nada, solo "parar" esperando que se cumpla el tiempo de los delays.

Amplío:
Viendo la secuencia de tu código, primero lees los sensores indiscriminadamente, uno detras del otro y sin pausa, es prácticamente lo mismo que leerlos todos al mismo tiempo (en total, leer los 4 sensores toma 24 useg según he probado en una simulación). ¿Cómo sabes cuando soltar la pelota y comenzar la medición?
Luego mueves los motores, la maniobra tarda casi 20 seg.
Finalmente imprimes los resultados de lo que leíste al principio y vuelves a empezar.

No hay nada que indique cuando tomar las mediciones, nada que indique la secuencia de medición, o sea, no hay control.

Lo lógico, desde mi punto de vista, sería esperar que lea el primer sensor y tomar el tiempo, luego esperar que lea el 2do y tomar el tiempo de éste, lo mismo los otros 2, finalmente hacer todos los cálculos.

Mostrar los resultados en el display.

Luego mover los motores en un sentido y volver al inicio para repetir el ciclo.

Vas a necesitar diagramar una máquina de estados para que, con cada vuelta del loop, cambie el movimiento de los motores o en su defecto, hacer una lectura de sensores y muestra de resultados después de cada movimiento de la barra.

Saludos

Antes que nada, muchas gracias por responder y ayudarme, he cambiado el pequeño problema de la pantalla LCD.
Entiendo que debo cambiar el orden de cada función, pero al ser nuevo en Arduino, no entiendo la parte de la máquina de estados, ¿cómo se realiza?

Lee los temas Qué es y cómo funciona una máquina de estados y Entender millis y no morir en el intento que te van a ser de mucha ayuda.

Saludos

Planteate el problema para un caso, resuelve un caso y luego agrega a ese caso el ángulo.
Luego plantea los siguientes casos.
Algo debe decirte cuando empieza a rodar la pelota. Eso no esta en tu código.
Otra cosa que debes considerar es que los inicios de los timers deben ser por flanco o sea, en tu caso ya que preguntas por LOW debe ser cuando la detección pasa de HIGH a LOW.
Para ello debes usar otra variable que guarde el estado anterior y claramente para eso no puedes tener delays como bien te ha señalado @anon90500195.

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