Skip to content

Commit 5fef0a1

Browse files
authored
Merge pull request #56 from runger1101001/samd21_dev
Samd21 dev
2 parents 10759a0 + 32a164b commit 5fef0a1

File tree

8 files changed

+1337
-5
lines changed

8 files changed

+1337
-5
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
# SAMD Support
3+
4+
SimpleFOC supports many SAMD21 MCUs, really any SAMD21 supported by Arduino core should work.
5+
6+
## Pin assignments
7+
8+
The SAMD chips have some very powerful PWM features, but do not have flexible pin assignments.
9+
10+
You should be able to use *most* (but not all!), pin combinations for attaching your motor's PWM pins. Please ignore the board descriptions and pinout diagrammes regarding PWM-pins on SAMD boards. They are pretty much all incorrect to varying degrees of awfulness.
11+
12+
On SAMD we use TCC and TC timer peripherals (built into the SAMD chip) to control the PWM. Depending on the chip there are various timer units, whose PWM outputs are attached to various different pins, and it is all very complicated. Luckily SimpleFOC sets it all up automatically *if* there is a compatible configuration for those pins.
13+
14+
Not all timers are created equal. The TCC timers are pretty awesome for PWM motor control, while the TC timers are just ok for the job. So to get best performance, you want to use just TCC timer pins if you can.
15+
16+
By enabling
17+
18+
```
19+
#define SIMPLEFOC_SAMD_DEBUG
20+
```
21+
22+
in drivers/hardware_specific/samd_mcu.cpp<br>
23+
you will see a table of pin assignments printed on the serial console, as well as the timers SimpleFOC was able to find and configure on the pins you specified. You can use this to optimize your choice of pins if you want.
24+
25+
You can configure up to 12 pins for PWM motor control, i.e. 6x 2-PWM motors, 4x 3-PWM motors, 3x 4-PWM motors or 2x 6-PWM motors.
26+
27+
## PWM control modes
28+
29+
All modes (3-PWM, 6-PWM, Stepper 2-PWM and Stepper 4-PWM) are supported.
30+
31+
For 2-, 3- amd 4- PWM, any valid pin-combinations can be used. If you stick to TCC timers rather than using TC timers, then you'll get getter PWM waveforms. If you use pins which are all on the same TCC unit, you'll get the best result, with the PWM signals all perfectly aligned as well.
32+
33+
For 6-PWM, the situation is much more complicated:<br>
34+
TC timers cannot be used for 6-PWM, only TCC timers.
35+
36+
For Hardware Dead-Time insertion, you must use H and L pins for one phase from the same TCC unit, and on the same channel, but using complementary WOs (Waveform Outputs, i.e. PWM output pins). Check the table to find pins on the same channel (like TCC0-0) but complementary WOs (like TCC0-0[0] and TCC0-0[4] or TCC1-0[0] and TCC1-0[2]).
37+
38+
For Software Dead-Time insertion, you must use the same TCC and different channels for the H and L pins of the same phase.
39+
40+
Note: in all of the above note that you *cannot* set the timers or WOs used - they are fixed, and determined by the pins you selected. SimpleFOC will find the best combination of timers given the pins, trying to use TCC timers before TC, and trying to keep things on the same timers as much as possible. If you configure multiple motors, it will take into account the pins already assigned to other motors.
41+
So it is matter of choosing the right pins, nothing else.
42+
43+
Note also: Unfortunately you can't set the PWM frequency. It is currently fixed at 24KHz. This is a tradeoff between limiting PWM resolution vs
44+
increasing frequency, and also due to keeping the pin assignemts flexible, which would not be possible if we ran the timers at different rates.
45+
46+
## Status
47+
48+
Currently, SAMD21 is supported, and SAMD51 is unsupported. SAMD51 support is in progress.
49+
50+
Boards tested:
51+
52+
* Arduino Nano 33 IoT
53+
* Arduino MKR1000
54+
* Arduino MKR1010 Wifi
55+
* Seeduino XIAO
56+
* Feather M0 Basic
57+
58+
Environments tested:
59+
60+
* Arduino IDE
61+
* Arduino Pro IDE
62+
* Sloeber
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
// show the infos for SAMD pin assignment on serial console
3+
// set this #define SIMPLEFOC_SAMD_DEBUG in drivers/hardware_specific/samd21_mcu.h
4+
5+
6+
#include "Arduino.h"
7+
#include <Wire.h>
8+
#include <SimpleFOC.h>
9+
#include <Math.h>
10+
11+
// this is for an AS5048B absolute magnetic encoder on I2C address 0x41
12+
MagneticSensorI2C sensor = MagneticSensorI2C(0x41, 14, 0xFE, 8);
13+
14+
// small BLDC gimbal motor, 7 pole-pairs
15+
BLDCMotor motor = BLDCMotor(7);
16+
// 3-PWM driving on pins 6, 5 and 8 - these are all on the same timer unit (TCC0), but different channels
17+
BLDCDriver3PWM driver = BLDCDriver3PWM(6,5,8);
18+
19+
// velocity set point variable
20+
float target_velocity = 2.0;
21+
// instantiate the commander
22+
Commander command = Commander(SerialUSB);
23+
void doTarget(char* cmd) { command.variable(&target_velocity, cmd); }
24+
25+
26+
void setup() {
27+
Serial.begin(115200);
28+
delay(1000);
29+
Serial.println("Initializing...");
30+
31+
sensor.init();
32+
Wire.setClock(400000);
33+
motor.linkSensor(&sensor);
34+
driver.voltage_power_supply = 9;
35+
driver.init();
36+
motor.linkDriver(&driver);
37+
motor.controller = MotionControlType::velocity;
38+
motor.PID_velocity.P = 0.2;
39+
motor.PID_velocity.I = 20;
40+
motor.PID_velocity.D = 0.001;
41+
motor.PID_velocity.output_ramp = 1000;
42+
motor.LPF_velocity.Tf = 0.01;
43+
motor.voltage_limit = 9;
44+
//motor.P_angle.P = 20;
45+
motor.init();
46+
motor.initFOC();
47+
48+
// add target command T
49+
command.add('T', doTarget, "target velocity");
50+
51+
Serial.println(F("Motor ready."));
52+
Serial.println(F("Set the target velocity using serial terminal:"));
53+
delay(100);
54+
}
55+
56+
57+
58+
void loop() {
59+
// Serial.print("Sensor: ");
60+
// Serial.println(sensor.getAngle());
61+
motor.loopFOC();
62+
motor.move(target_velocity);
63+
// user communication
64+
command.run();
65+
}

src/communication/Commander.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "Commander.h"
22

33

4-
Commander::Commander(HardwareSerial& serial){
4+
Commander::Commander(Stream& serial){
55
com_port = &serial;
66
}
77
Commander::Commander(){
@@ -436,4 +436,4 @@ void Commander::printVerbose(const __FlashStringHelper *message){
436436
}
437437
void Commander::printError(){
438438
print(F("err"));
439-
}
439+
}

src/communication/Commander.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class Commander
3939
*
4040
* @param serial - Serial com port instance
4141
*/
42-
Commander(HardwareSerial &serial);
42+
Commander(Stream &serial);
4343
Commander();
4444

4545
/**
@@ -90,7 +90,7 @@ class Commander
9090
uint8_t decimal_places = 3; //!< number of decimal places to be used when displaying numbers
9191

9292
// monitoring functions
93-
HardwareSerial* com_port = nullptr; //!< Serial terminal variable if provided
93+
Stream* com_port = nullptr; //!< Serial terminal variable if provided
9494

9595
/**
9696
*

src/drivers/hardware_specific/generic_mcu.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#elif defined(_STM32_DEF_) // or stm32
1414

15+
#elif defined(_SAMD21_) // samd21 for the moment, samd51 in progress...
16+
1517
#else
1618

1719
// function setting the high pwm frequency to the supplied pins
@@ -86,4 +88,4 @@ void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, float dead_zone, i
8688
}
8789

8890

89-
#endif
91+
#endif

0 commit comments

Comments
 (0)