Hello! I’m trying to use PA1 as my PWM output. When I run the code, I have no problems until it reaches the ESC.CONTROL(A4956::Forward) on the second iteration of the while loop. At that point it runs the PWM at whatever I’ve set the brake function value to. I don’t understand why this would happen, I explicitly tell it in the class function to write a duty cycle of 100% before resuming the PWM, so why is the brake PWM value bleeding over anyway? Peculiarly, the following ESC.CONTROL(A956ESC::Reverse) works with the correct PWM value. I have put my scope on my PWM line to ensure that the PWM values correspond to my findings. Thanks for any help you can lend me!
#include "mbed.h"
class A4956ESC
{
public:
enum Direction
{
Forward = 1,
Reverse = 0
};
/** Constructor for A4956ESC class, set up pins
* @param PH Phase control logic, digital out
* @param MD Mode control Logic, digital out
* @param EN PWM signal for A4956ESC
* Data sheet at https://www.digikey.com/en/products/detail/allegro-microsystems/A4956GESTR-T/5809983?s=N4IgTCBcDaIIYBYCcBWAbAcwKYGcAuATgLR4gC6AvkA
*/
A4956ESC(PinName PH, PinName MD, PinName EN);
/** Function used to set to reverse or forward
* @param dir enum used to determine which direction
*/
void CONTROL(Direction dir);
/** Function Used to brake ESC
* @param PWM pwm pulse value used for braking
*/
void BRAKE(int PWM);
/** Function Used for Fast Decay mode
* @param dir enum used to determine which direction
* @param PWM pwm pulse in microseconds value used for chop mode
*/
void EN_CHOP(Direction dir, int PWM);
void STOP(void);
private:
PwmOut Enable;
DigitalOut Phase, Mode;
};
#include "mbed.h"
#include "A4956ESC.h"
A4956ESC::A4956ESC(PinName PH, PinName MD, PinName EN) : Phase(PH), Mode(MD), Enable(EN)
{
//initalize digital values and pwm
Enable.period_us(2000);
Enable.write(1.0f);
Enable.suspend();
Phase = 0;
Mode = 0;
}
void A4956ESC::CONTROL(Direction dir)
{
int temp;
switch (dir)
{
case Forward:
Enable.write(1.0f);
// temp = Enable.read_pulsewitdth_us();
// printf("Pulsewidth in us :%d\n", temp);
Phase = 1;
Enable.resume();
break;
case Reverse:
Enable.write(1.0f);
Phase = 0;
Enable.resume();
break;
}
}
void A4956ESC::BRAKE(int PWM)
{
Mode = 1;
Enable.write(PWM);
Enable.resume();
}
void A4956ESC::EN_CHOP(Direction dir, int PWM)
{
switch(dir)
{
case Forward:
Mode = 0;
Phase = 1;
Enable.pulsewidth_us(PWM);
Enable.resume();
break;
case Reverse:
Mode = 0;
Phase = 1;
Enable.pulsewidth_us(PWM);
Enable.resume();
break;
}
}
void A4956ESC::STOP(void)
{
Enable.suspend();
Enable.write(1.0f);
Phase = 0;
Mode = 0;
}
#include "mbed.h"
#include "KB_Functions.h"
#include "A4956ESC.h"
#include <chrono>
#include <cstdint>
#include <array>
static BufferedSerial sbusIn(PA_9, PA_10, 100000); //Buffered serial object for sbus input at baud = 100,000
static BufferedSerial pc(USBTX,USBRX,115200);
AnalogIn MotorCurrent_1(PA_0);
AnalogIn SupplyVoltage(PA_4); //12.47V Equates to 0.56 in u16, 9.91V Equates to .5306
AnalogIn MotorCurrent_2(PA_5);
DigitalIn MicroSW_TOP(PB_1); //UPPER MICROSWITCH
DigitalIn MicroSW_Bot(PA_12); //LOWER MICROSWITCH
DigitalIn ProxSensor(PB_0);
PwmOut Buzzer(PA_11);
// PwmOut EN_ESC(PA_1);
DigitalOut polarity_relay(PA_8);
DigitalOut on_relay(PB_5);
// DigitalOut PH(PA_6);
// DigitalOut MODE(PB_3);
A4956ESC ESC(PA_6, PB_3, PA_1);
char TEST_ARRAY[1] = {0x00};
float voltage_data;
int main()
{
I2C_GPIO.frequency(400000);
if(I2C_GPIO.write(GPIO_IC11_ADDR, TEST_ARRAY, 1) == 0 && I2C_GPIO.write(EEPROM_ADDR, TEST_ARRAY, 1) == 0 && I2C_GPIO.write(GPIO_IC11_ADDR, TEST_ARRAY, 1) == 0)
printf("I2C DEVICES CONNECTED\n");
else printf("I2C DEVICES ERROR\n");
MCP23008_Init_IC11();
Buzzer.period_us(2000);
Buzzer.write(0.5f);
Buzzer.suspend();
while (true)
{
// Buzzer.resume();
// wait_us(1000000);
// Buzzer.suspend();
wait_us(1000000);
ESC.CONTROL(A4956ESC::Forward);
wait_us(4000000);
ESC.CONTROL(A4956ESC::Reverse);
wait_us(4000000);
ESC.BRAKE(0.0f);
wait_us(4000000);
ESC.STOP();
}
}