Tasks are not running and I don't know why

Hi everyone,

I’m using Arduino_FreeRTOS to make my code more fluid. I’ve been refactoring quite a bit since I want my robot to be able to obtain RSSI values while trying to connect to a server. To achieve this, I’ve been tackling smaller changes before focusing on the bigger ones.

Regarding my Motor.cpp and Motor.h files, my goal was to create a task that handles the motor control. However, when I created the task, it didn’t run. I simplified the task to just include a Serial print statement to check if it was executing, but it never reached that point. I’m wondering why this might be happening.

Any insights or suggestions would be greatly appreciated!

This is my Motor.cpp file:

(other headers above)
#include "Arduino_FreeRTOS.h"


const int MAX_SPEED = 255;
const int MED_SPEED = 200;
const int LOW_SPEED = 150;

// Universal Object
Motors myMotors;

// Create motor shield object with the default 12C address
Adafruit_MotorShield motorShield = Adafruit_MotorShield();

// Select which port
Adafruit_DCMotor *motor1 = motorShield.getMotor(1);
Adafruit_DCMotor *motor2 = motorShield.getMotor(2);
Adafruit_DCMotor *motor3 = motorShield.getMotor(3);
Adafruit_DCMotor *motor4 = motorShield.getMotor(4);

// My constructor
Motors::Motors(): mCurrentDirection(MOTOR_STOP) {

}

//where I initialize my motors
void Motors::motorSetup() {
    Serial.println("Motor Setup");
    motorShield.begin();
    //setting speeds of all motors to high
    motor1->setSpeed(MED_SPEED);
    motor2->setSpeed(MED_SPEED);
    motor3->setSpeed(MED_SPEED);
    motor4->setSpeed(MED_SPEED);

    xTaskCreate(Motors::taskMotorMovement, "Motor Movement", 256, NULL, 3, NULL);
}



void Motors::motorLoop() {  
    // will be empty
    if(myMotors.mNewDirection != myMotors.mCurrentDirection) {
            Serial.print("Motor Direction: ");
            Serial.println(myMotors.mNewDirection);
            myMotors.mCurrentDirection = myMotors.mNewDirection;
            myMotors.adjustDirection();
        }
}

void Motors::taskMotorMovement(void *pvParameters) {
    (void) pvParameters;
    
    for(;;) {
        Serial.println("motor task starting");
        vTaskDelay(100 / portTICK_PERIOD_MS );
    }
    

}

Here is my Motors.h:

#pragma once
#include "Arduino.h"
#include "states&types/MotorControlStates.h"

class Motors {
public:

    Motors();

    void motorSetup();
    void motorLoop();

    void setDirection(String dir) {
       mNewDirection = dir;   
    }

    void moveForwards(float distance) {
        mNewDirection = MOTOR_FORWARD;
    }

    void moveBackwards(float distance) {
        mNewDirection = MOTOR_BACKWARD;
    }

    void turnLeft(float rads) {
        mNewDirection = MOTOR_LEFT;
    }

    void turnRight(float rads) {
        mNewDirection = MOTOR_RIGHT;
    }

    void justStop() {
        mNewDirection = MOTOR_STOP;
    }
private:
    void motorForwards();
    void motorBackwards();
    void motorLeft();
    void motorRight();
    void motorStop();

    // Motor drive task
    static void taskMotorMovement(void *pvParameters);

    void adjustDirection();

    String mCurrentDirection;
    String mNewDirection;
};

extern Motors myMotors;

It runs within a manager class which is then ran through my main.cpp:

#include <Arduino.h>
//testing purposes (Currently)
void setup() {
  Serial.begin(9600);
  while(!Serial) {
      ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("main: setup()");
  followBotManager.followBotSetup();
}

//testing purposes (Currently)
void loop() {
  //empty
}

If you’re wondering what the manager class is, it’s essentially the same as the main function, containing both the setup and loop functions. In the FollowBotSetup, the myMotor object is called to run the motor setup.

I’m not familiar with Arduino SDK, but isn’t usually vTaskStartScheduler finally called in setup ? Somewhere it must be called to start the created tasks.
Also the stack size of your motors::taskMotorMovement task seems too small.
Note that printf-family functions need quite a bit of stack.
You should enable FreeRTOS stack checking during development.
See FreeRTOS stack usage and stack overflow checking - FreeRTOS™

1 Like

also, what does xTaskCreate() return?

Another good test is to remove all the motor control code and just create a simple task in the setup function and see if you can get it to work -

void Task( void * param )
{
  ( void ) param;
  
  for( ;; )
  {
    Serial.println("FreeRTOS Task");
    vTaskDelay( pdMS_TO_TICKS( 1000 ) );
  }
}

void setup()
{
  Serial.begin(9600);
  while(!Serial) {
      ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("main: setup()");
  xTaskCreate(Task, "Task", 256, NULL, 3, NULL);
}
1 Like