Due to high demand expect some shipping delays at this time, orders may not ship for 1-2 business days.
0

State machine code with dc motor
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

State machine code with dc motor

by maxpo on Fri Jun 18, 2021 2:40 am

Hi dear community,

I ran into some problems here with programming. I am trying to put together a code for 4dc motors, buzzer, ultrasonic and lcd to work together,. they will together make up a small car. when the distance to the ultrasonic is smaller than 10cm, the buzzer makes a random sound, and a funny face. Meanwhile the motors will stop for 2 seconds, goes back for 2 seconds and do a turning motion for 8 seconds. However. I do not want to use the delay function for the motors since it will cause the buzzer to sound too slowly. I know I should use a state machine.
but when I tried to put the motor controls in, my motors does not turn, can someone help me with spotting what is the problem here? could it be that the motor library is locked?
Thank you!

Code: Select all | TOGGLE FULL SIZE
#define HALT_TIME 2000
#define BACK_TIME 2000
#define TURN_TIME 8000
#define trigPin A1
#define echoPin A0
#include <LiquidCrystal.h>
#include <NewTone.h>
#include<AFMotor.h>

static long duration;
static int distance;
static int distanceUltra;
static int maximum = 100;
static int buzzerPin = A2;
static int dur = 100;

LiquidCrystal lcd(8, 9, 4, 7, 12, 13);
AF_DCMotor motor1(1, MOTOR12_1KHZ);
AF_DCMotor motor2(2, MOTOR12_1KHZ);
AF_DCMotor motor3(3, MOTOR34_1KHZ);
AF_DCMotor motor4(4, MOTOR34_1KHZ);

enum ApplicationState {
  BeginDrive,
  Drive,
  BeginHalt,
  Halt,
  BeginBack,
  Back,
  BeginTurn,
  Turn
};

static enum ApplicationState currentApplicationState = BeginDrive;

static unsigned long t = 0;

static bool sensorTriggered() {

  if (distance <= 10){return true;}

  else {return false;}
}

static void funnyFace() {

    lcd.setCursor(6,0);
    lcd.write("x");
    lcd.setCursor(8,0);
    lcd.write("x");
    lcd.setCursor(7,1);
    lcd.write("o");
    randSound(maximum);//random sound for buzzer
}

static void beginDriveHandler() {

    Serial.println(currentApplicationState);

    motor1.setSpeed(100);
    motor1.run(BACKWARD);
    motor2.setSpeed(100);
    motor2.run(BACKWARD);
    motor3.setSpeed(100);
    motor3.run(BACKWARD);
    motor4.setSpeed(100);
    motor4.run(BACKWARD);
  currentApplicationState = Drive;
  //t = millis();
}

static void driveHandler() {
 
  if (sensorTriggered()) {
    Serial.println(currentApplicationState);
    t = millis();
    currentApplicationState = BeginHalt;
  }
}

static void beginHaltHandler() {
  Serial.println(currentApplicationState);
    motor1.setSpeed(0);
    motor1.run(RELEASE);
    motor2.setSpeed(0);
    motor2.run(RELEASE);
    motor3.setSpeed(0);
    motor3.run(RELEASE);
    motor4.setSpeed(0);
    motor4.run(RELEASE);
 
  funnyFace();
  currentApplicationState = Halt;
  //t = millis();
}

static void haltHandler() {
 
  if (millis() - t > HALT_TIME) {
    Serial.println(currentApplicationState);
    t = millis();
    currentApplicationState = BeginBack;
  }
  //currentApplicationState = BeginBack;
}

static void beginBackHandler() {
Serial.println(currentApplicationState);
    motor1.setSpeed(100);
    motor1.run(FORWARD);
    motor2.setSpeed(100);
    motor2.run(FORWARD);
    motor3.setSpeed(100);
    motor3.run(FORWARD);
    motor4.setSpeed(100);
    motor4.run(FORWARD);
  currentApplicationState = Back;
  //t = millis();
}

static void backHandler() {
 
  if (millis() - t > BACK_TIME) {
    Serial.println(currentApplicationState);
    t = millis();
    currentApplicationState = BeginTurn;
  }
  //currentApplicationState = BeginTurn;
}

static void beginTurnHandler() {
Serial.println(currentApplicationState);
    motor1.setSpeed(100);
    motor1.run(FORWARD);
    motor2.setSpeed(100);
    motor2.run(FORWARD);
    motor3.setSpeed(100);
    motor3.run(BACKWARD);
    motor4.setSpeed(100);
    motor4.run(BACKWARD);
  currentApplicationState = Turn;
  //t = millis();
}

static void turnHandler() {
 
  if (millis() - t > TURN_TIME) {
    //t = millis();
    Serial.println(currentApplicationState);
    currentApplicationState = BeginDrive;
  }
  //currentApplicationState = BeginDrive;
}

void setup() {
  Serial.begin(9600);
  lcd.begin(16,2);
 // pinMode (trigPin, OUTPUT);
 // pinMode (echoPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
  currentApplicationState = BeginDrive;
  t = 0;
}

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  //Serial.println(sensorTriggered());
  duration = pulseIn(echoPin, HIGH);
  distance = (float)duration*0.017;
  switch (currentApplicationState) {

    case BeginDrive:
    beginDriveHandler();
    break;

    case Drive:
    driveHandler();
    break;

    case BeginHalt:
    beginHaltHandler();
    break;

    case Halt:
    haltHandler();
    break;

    case BeginBack:
    beginBackHandler();
    break;

    case Back:
    backHandler();
    break;

    case BeginTurn:
    beginTurnHandler();
    break;

    case Turn:
    turnHandler();
    break;
  }

  //Serial.println(currentApplicationState);
}

void randSound(int maximum){
  NewTone(buzzerPin, random(maximum, 10*maximum),dur);
  delay(maximum);
  noNewTone(buzzerPin);
}

maxpo
 
Posts: 1
Joined: Fri Jun 18, 2021 2:17 am

Re: State machine code with dc motor

by blnkjns on Fri Jun 18, 2021 3:15 am

What board are you using? Did you look into the timer interrupts on your board?
I get the idea that the motor library and the tone function might rely on the exact same interrupt timer.
You posted under Clue, but you also include LiquidCrystal.h, so I was wondering if you really use the CLUE as it already has a better display on board.
If it is the CLUE, we need to look at the nRF52840 timers.

blnkjns
 
Posts: 680
Joined: Fri Oct 02, 2020 3:33 am

Re: State machine code with dc motor

by adafruit_support_bill on Sat Jun 19, 2021 6:29 am

It looks like you are using the AFMotor library. That library is for the long-discontinued V1 motor shield. We do not make that shield anymore and the library for it is no longer supported.

If you have one of our V2 motor shields, you need to use the V2 library: https://github.com/adafruit/Adafruit_Mo ... V2_Library

adafruit_support_bill
 
Posts: 82451
Joined: Sat Feb 07, 2009 10:11 am

Please be positive and constructive with your questions and comments.