Hello Guys,
I hope I am correct with my question in this category, I am new in this forum
First of all thank you for this Lib and Shield, Ive been working with it for a project and I didnt have any problems until now, everything was well explained.
I was testing your example Code Steer-by-Wire and it worked out of the box. Now Ive tried to run this script by using two arduino due, each for one motor and sending the motor position between them.
I was testing it with I2C but I didnt get a stable connection or a stable behavior of the motors when turning one of the motors.
Then I tried something different, I used a PWM to send the motor position via duty cycle. And on the other arduino uses a hardware interrupt pin to capture the duty cycle. This was working pretty well but with this methode I only got the resolution of 0 … 1000 caused by the frequency of the pwm - the standard pwm of the pwm of 1kHz (measured with micros()). This resolution isnt enough for a smooth behaviour of the motors.
So I came up with something different I knew I can change the frequency by changing some registers. While searching through the datasheet I found a implementation of a waveform and capture mode on the arduino due. So I tried this to send some values and it worked great.
But after merging this into the steer-by-wire code I got problems with the lib working as intended.
Is it possible to change the TC without changing the behaviour of the lib?
I got the receive function working which is at pin 11 and so at TC2. Maybe the problem is TC0 where I send my PWM.
My Code:
#include <SimpleFOC.h>
float motor1_shaft_angle = 0.0F; //shaft angle motor here
float motor2_shaft_angle = 0.0F; //shaft angle motor at slave
// Variables for COM
uint32_t last_dutyCycle = 0xFFFFFFFF;
void setPWMcfg()
{
/************* PIN13 - Timer Counter 0 Channel 0 to generate PWM pulses through TIOB0 ************/
PMC->PMC_PCER0 |= PMC_PCER0_PID27; // Timer Counter 0 channel 0 IS TC0 -> PID27
PIOB->PIO_PDR |= PIO_PDR_P27; // disable PB8 default output (B Pin)
PIOB->PIO_ABSR |= PIO_ABSR_P27; // TC0 signal: TIOB0 (Periperal type B)
TC0->TC_CHANNEL[0].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 // MCK/2, clk on rising edge
| TC_CMR_WAVE // Waveform mode
| TC_CMR_WAVSEL_UP_RC // UP mode with automatic trigger on RC Compare
| TC_CMR_EEVT_XC0 // disable external trigger mode (external trigger to XCO)
| TC_CMR_BCPB_CLEAR // Clear TIOB0 on RB compare match
| TC_CMR_BCPC_SET; // Set TIOB0 on RC compare match
TC0->TC_CHANNEL[0].TC_RC = 10499; // Frequency = (Mck/2)/TC_RC = X Hz
TC0->TC_CHANNEL[0].TC_RB = 5249; // Duty cycle = (TC_RA/TC_RC) * 100 % = X % || Initial Value for Com PWM
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC0 counter and enable
/************* PIN11 - Timer Counter 2 Channel 2 to capture PWM pulses through TIOA8 ************/
PMC->PMC_PCER1 |= PMC_PCER1_PID35; // Timer Counter 2 channel 2 IS TC2 -> PID35
TC2->TC_CHANNEL[2].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 // MCK/1, clk on rising edge
| TC_CMR_ABETRG // TIOA8 is used as the external trigger
| TC_CMR_LDRA_FALLING // load RA on falling edge of trigger input
| TC_CMR_ETRGEDG_RISING; // External Trigger Edge Selection to rising
TC2->TC_CHANNEL[2].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC2 counter and enable
return;
}
void txPWM(uint32_t txVal)
{
TC0->TC_CHANNEL[0].TC_RB = txVal;
return;
}
uint32_t rxPWM(void)
{
// Variables for COM
uint32_t dutyCycle = 0xFFFFFFFF;
uint32_t status;
uint32_t rxVal;
status = TC2->TC_CHANNEL[2].TC_SR;
if (status & TC_SR_LDRAS) { // If ISR is triggered by LDRAS then ....
dutyCycle = (uint32_t) TC2->TC_CHANNEL[2].TC_RA; // get data from capture register A of TC0 channel 1
if (dutyCycle > 200 && dutyCycle < 10200) // overrange detection
{
//printf("DutyCycle = %d\n", dutyCycle);
last_dutyCycle = dutyCycle;
rxVal = dutyCycle;
}
else
{
//dutyCycle = 0xFFFFFFFF;
rxVal = last_dutyCycle;
//printf("ERROR - OVERFLOW!\n"); // receive wrong Value
}
}
else
{
//dutyCycle = 0xFFFFFFFF;
rxVal = last_dutyCycle;
//printf("ERROR - CONNECTION DISCONNECTED!\n");
}
return rxVal;
}
void sendValue(float mVal)
{
uint32_t mapVal;
// Range Check
if (mVal < -50.0f)
{
mVal = -50.0f;
//send error message
}
if (mVal > 50.0f)
{
mVal = 50.0f;
//send error message
}
mapVal = (mVal * 100) + 5200; // Conversion in Com Value
txPWM(mapVal);
return;
}
float recieveValue(void)
{
uint32_t mapVal;
float mVal;
mapVal = rxPWM(); // mapVal in Range 200...10200 and -1 for Error (maybe future introduction of error codes)
//if (mapVal == ERROR_VAL)
mVal = ( ((float) mapVal) - 5200) / 100.0f; // Conversion in Float Value
return mVal;
}
//InlineCurrentSense current_sense1 = InlineCurrentSense(0.01, 50, A0, A2);
BLDCMotor motor1 = BLDCMotor(11);
BLDCDriver3PWM driver1 = BLDCDriver3PWM(5, 9, 6, 8);
MagneticSensorPWM sensor1 = MagneticSensorPWM(7, 4, 923);
void doPWM1(){sensor1.handlePWM();}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
setPWMcfg();
// initialise magnetic sensor hardware
sensor1.init();
// enable the interrupt and start reading the sensor
sensor1.enableInterrupt(doPWM1);
// link the motor to the sensor
motor1.linkSensor(&sensor1);
// init driver
// power supply voltage [V]
driver1.voltage_power_supply = 12;
driver1.init();
// link driver
motor1.linkDriver(&driver1);
// current sense init hardware
//current_sense1.init();
// link the current sense to the motor
//motor1.linkCurrentSense(¤t_sense1);
// set control loop type to be used
motor1.controller = MotionControlType::torque;
// initialise motor
motor1.init();
// align encoder and start FOC
motor1.initFOC();
Serial.begin(115200);
_delay(1000);
}
void loop() {
// receive motor postion
motor2_shaft_angle = recieveValue();
// send motor position
sendValue(motor1.shaft_angle);
// iterative setting FOC phase voltage
motor1.loopFOC();
// virtual link code
motor1.move(5*(motor2_shaft_angle - motor1.shaft_angle));
Serial.print(motor1.shaft_angle);
Serial.print("\t");
Serial.println(motor2_shaft_angle);
}
I thought about using different TCx and different channel but it didnt help.
Sorry if something is not the way how to use a forum. Its my first time writing a question about coding.
Thank you in advance.
Liam