Programa Carrito Seguidor de Línea

1:20

Aquí tienes otro ejemplo de programa para un carrito seguidor de línea, sin depender de la biblioteca QTRSensors. En este ejemplo se leen 8 sensores conectados a los pines analógicos (A0 a A7) y se usan para cacular la posición de la línea. Se utiliza un driver TB6612FNG para controlar dos motores. Puedes ajustar los pines, la ganancia proporcional y otros parámetros según tu hardware:

Cpp


/******************************************************
 * Seguidor de Línea - Código Alternativo
 * Componentes:
 * - Arduino Nano
 * - Sensor de línea: 8 sensores analógicos conectados a A0 a A7
 * - Driver TB6612FNG para dos motores DC
 * - Motores N20 6V, 1000 rpm
 ******************************************************/

const int NUM_SENSORS = 8;
int sensorPins[NUM_SENSORS] = {A0, A1, A2, A3, A4, A5, A6, A7};

// Pines de control para el driver TB6612FNG
// Motor A
const int AIN1 = 3;
const int AIN2 = 4;
const int PWMA  = 5;

// Motor B
const int BIN1 = 6;
const int BIN2 = 7;
const int PWMB  = 9;

const int baseSpeed = 150;      // Velocidad base (0 - 255)
const int maxSpeed = 255;       // Velocidad máxima

// Inicializa el driver deteniendo ambos motores
void setupMotors() {
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(PWMA, OUTPUT);
  
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  
  digitalWrite(AIN1, LOW);
  digitalWrite(AIN2, LOW);
  analogWrite(PWMA, 0);
  
  digitalWrite(BIN1, LOW);
  digitalWrite(BIN2, LOW);
  analogWrite(PWMB, 0);
}

// Control del Motor A
void setMotorA(int speed) {
  if (speed > 0) {
    digitalWrite(AIN1, HIGH);
    digitalWrite(AIN2, LOW);
  } else if (speed < 0) {
    digitalWrite(AIN1, LOW);
    digitalWrite(AIN2, HIGH);
    speed = -speed;
  } else {
    digitalWrite(AIN1, LOW);
    digitalWrite(AIN2, LOW);
  }
  analogWrite(PWMA, constrain(speed, 0, maxSpeed));
}

// Control del Motor B
void setMotorB(int speed) {
  if (speed > 0) {
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
  } else if (speed < 0) {
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, HIGH);
    speed = -speed;
  } else {
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, LOW);
  }
  analogWrite(PWMB, constrain(speed, 0, maxSpeed));
}

// Función que lee los 8 sensores y calcula una posición ponderada
int readLinePosition() {
  long sumValues = 0;
  long weightedSum = 0;
  
  for (int i = 0; i < NUM_SENSORS; i++) {
    int sensorValue = analogRead(sensorPins[i]);
    sumValues += sensorValue;
    // Se asume que cada sensor representa una posición escalada (0, 1000, 2000, ... 7000)
    weightedSum += (long)sensorValue * i * 1000;
  }
  
  if (sumValues == 0) {
    return -1;  // Línea no detectada
  }
  
  int position = weightedSum / sumValues;
  return position;
}

void setup() {
  Serial.begin(115200);
  
  // Configurar pines de sensores
  for (int i = 0; i < NUM_SENSORS; i++) {
    pinMode(sensorPins[i], INPUT);
  }
  
  setupMotors();
  Serial.println("Inicio de seguidor de línea");
}

void loop() {
  int pos = readLinePosition();
  
  if (pos == -1) {
    // Si no se detecta la línea, detenerse.
    setMotorA(0);
    setMotorB(0);
    Serial.println("Línea no detectada");
    delay(100);
    return;
  }
  
  // El punto central ideal de la línea es a la mitad: ((NUM_SENSORS-1)*1000)/2
  int center = ((NUM_SENSORS - 1) * 1000) / 2;  // en este caso, 3500
  int error = pos - center;
  
  // Control proporcional simple
  float Kp = 0.2;
  int correction = Kp * error;
  
  int motorSpeedA = baseSpeed + correction;
  int motorSpeedB = baseSpeed - correction;
  
  // Asegurar la velocidad dentro de los límites
  motorSpeedA = constrain(motorSpeedA, 0, maxSpeed);
  motorSpeedB = constrain(motorSpeedB, 0, maxSpeed);
  
  setMotorA(motorSpeedA);
  setMotorB(motorSpeedB);
  
  Serial.print("Posicion: ");
  Serial.print(pos);
  Serial.print(" | Error: ");
  Serial.print(error);
  Serial.print(" | SpeedA: ");
  Serial.print(motorSpeedA);
  Serial.print(" | SpeedB: ");
  Serial.println(motorSpeedB);
  
  delay(10);
}
Detalles:
  • Lectura de sensores:
    Se leen los 8 pines analógicos para obtener la intensidad reflejada de cada sensor y se calcula una posición ponderada. Si ninguno de los sensores detecta la línea (sumatoria = 0), se detienen los motores.
  • Control de motores:
    Se utilizan pines específicos para el driver TB6612FNG para controlar ambos motores. La corrección se calcula mediante un control proporcional para ajustar la trayectoria.
  • Ajustes:
    Revisa los pines y valores de velocidad (baseSpeed, maxSpeed y Kp) de acuerdo a tu montaje y ajustes de calibración.
Espero que este código se ajuste mejor a tus requerimientos. ¡Prueba y ajusta los parámetros según el comportamiento de tu carrito!
la constante pwmb a donde se conecta?

0:13

La constante PWMB en el código define el pin de salida PWM asignado para el control de velocidad del Motor B. En este ejemplo se configura como el pin 9 del Arduino, el cual debe conectarse al pin de velocidad (PWM input) del controlador TB6612FNG correspondiente al Motor B.
This PWM signal is used to adjust the speed of Motor B, and its value is modulated to increase or decrease the motor speed according to your control algorithm.
Connect PWM
Check pin assignments
Verify PWM functionality
Ready to work

Documents

    Documents are markdown text files which describe project goals, capture details, or even simulation outputs.

    Assets

    No assets added.

    Relaxed Blue Liquid Breathing Apparatus

    Relaxed Blue Liquid Breathing Apparatus thumbnail
    Welcome to your new project. Imagine what you can build here.

    Properties

    Properties describe core aspects of the project.

    Pricing & Availability

    Distributor

    Qty 1

    Arrow

    $213.50–$236.50

    Digi-Key

    $22.90–$55.86

    LCSC

    $138.23

    Mouser

    $35.14–$42.90

    Verical

    $107.95–$272.59

    Controls