Using PCA9685 and USB Serial at same time results in crash/freezing of STM32
Posted: Tue Apr 21, 2020 9:39 pm
Hi
I've been trying to write some code for a walking robot.
My idea has been to write a class that controls one of the legs. The class would take the desired XY coordinates of the foot, calculate the required joint angles and send the appropiate PWM to the servos on that leg.
The mainboard I'm using is the Adafruit STM32 Feather, connected to a PCA9685 breakout which controls the servos (Using Adafruits servo driver library).
However, I have encounted a problem when using the servo driver library with usb serial.
Heres my code so far:
main.cpp
leg.h
leg.cpp
The code complies fine and uploads to the board.
The program should light up the Neopixel blue at the start of Setup(), then green at the end of Setup(). The loop() at this point justs sends the current millis() every 500 milliseconds.
However, the virtual com port does not start and I get an error from windows stating the USB device was not recognised. The Neopixel also does not light up, indicating the STM32 has crashed/froze.
By trail and error I found that the problem occurs when the line is run within leg.cpp
Commenting this line out results in the Neopixels working and the serial port working too.
At first I though it might be a timing issue but the STM32 is controlling the PCA9685 via I2C so the sero library shouldn't be used.
I'm using Platformio in VSCode to upload the code using this cofiguration:
I also tried uploading the code via the Arduino IDE, but that results in the same outcome.
I'm posting here as I'm not really sure where the problem is.
Thanks for any help
I've been trying to write some code for a walking robot.
My idea has been to write a class that controls one of the legs. The class would take the desired XY coordinates of the foot, calculate the required joint angles and send the appropiate PWM to the servos on that leg.
The mainboard I'm using is the Adafruit STM32 Feather, connected to a PCA9685 breakout which controls the servos (Using Adafruits servo driver library).
However, I have encounted a problem when using the servo driver library with usb serial.
Heres my code so far:
main.cpp
Code: Select all
#include <Arduino.h>
#include <Adafruit_NeoPixel.h> // For the Feather on-board RGB LED (Neopixel)
#include <Adafruit_PWMServoDriver.h>
#include "leg.h" // Leg class to control one of the legs
// On-board Neopixel
Adafruit_NeoPixel pixels(1, 8, NEO_GRB + NEO_KHZ800);
// Legs
leg front_right(0, 1, 2);
void setup() {
pixels.begin();
pixels.clear(); // Set all pixel colors to 'off'
pixels.setPixelColor(0, pixels.Color(0, 0, 31)); // Blue at ~1/8 brightness
pixels.show(); // Send the updated pixel colors to the hardware.
Serial.begin(115200);
Serial.println(F("QUAD WALKER"));
delay(1000);
pixels.setPixelColor(0, pixels.Color(0, 31, 0)); // Green at ~1/8 brightness
pixels.show(); // Send the updated pixel colors to the hardware.
}
void loop() {
Serial.println(millis());
delay(500);
// Toggle onboard LED #13 #PC1
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
Code: Select all
#ifndef leg_h
#define leg_h
#include <Arduino.h>
#include <Adafruit_PWMServoDriver.h>
class leg : Adafruit_PWMServoDriver{
public:
leg(int coxa, int femur, int tibia);
void set_angle_limits(int min, int max);
void set_foot_position(int new_x, int new_y, int new_z);
int get_x_position();
int get_y_position();
int get_z_position();
private:
int _coxa; // Servo pin
int _femur; // Servo pin
int _tibia; // Servo pin
int current_x; // Position
int current_y; // Position
int current_z; // Position
int _current_coxa; // Angle
int _current_femur; // Angle
int _current_tibia; // Angle
int _new_coxa; // Angle
int _new_femur; // Angle
int _new_tibia; // Angle
int _min_angle = 0; // Minimum servo angle, decided by mechanics
int _max_angle = 180; // Maximum servo angle, decided by mechanics
};
#endif // leg_h
Code: Select all
#include "leg.h"
leg::leg(int coxa, int femur, int tibia){
_coxa = coxa;
_femur = femur;
_tibia = tibia;
// Default 0x40 address
Adafruit_PWMServoDriver();
Adafruit_PWMServoDriver::begin();
}
void leg::set_angle_limits(int min, int max){
_min_angle = min;
_max_angle = max;
}
void leg::set_foot_position(int new_x, int new_y, int new_z){
// TODO: Calculate new servo angles for leg to make new position possible.
// For a test just move the servo
Adafruit_PWMServoDriver::writeMicroseconds(0, 700);
}
int leg::get_x_position(){return current_x;}
int leg::get_y_position(){return current_y;}
int leg::get_z_position(){return current_z;}
The program should light up the Neopixel blue at the start of Setup(), then green at the end of Setup(). The loop() at this point justs sends the current millis() every 500 milliseconds.
However, the virtual com port does not start and I get an error from windows stating the USB device was not recognised. The Neopixel also does not light up, indicating the STM32 has crashed/froze.
By trail and error I found that the problem occurs when the line
Code: Select all
Adafruit_PWMServoDriver::begin();
Commenting this line out results in the Neopixels working and the serial port working too.
At first I though it might be a timing issue but the STM32 is controlling the PCA9685 via I2C so the sero library shouldn't be used.
I'm using Platformio in VSCode to upload the code using this cofiguration:
Code: Select all
[env:adafruit_feather_f405]
platform = ststm32
board = adafruit_feather_f405
framework = arduino
upload_protocol = dfu
monitor_speed = 115200
; Extra Libraries
lib_extra_dirs =
C:\Users\tomhu\Documents\Libraries
C:\Users\tomhu\.platformio\packages\framework-arduinoststm32\libraries
; Build Flags
build_flags =
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
-D USBCON
-D USBD_VID=0x0483
-D USB_MANUFACTURER=\"Unknown\"
-D USB_PRODUCT=\"FEATHER_F405\"
-D HAL_PCD_MODULE_ENABLED
-D USBD_USE_CDC
-D HAL_UART_MODULE_ENABLED
I'm posting here as I'm not really sure where the problem is.
Thanks for any help
