Skip to content

Commit 8cb2d33

Browse files
authored
Merge pull request #32 from facchinm/nano33ble
Initial porting to mbed cores (Nano33BLE)
2 parents fe4ee1d + bab7b25 commit 8cb2d33

File tree

4 files changed

+136
-1
lines changed

4 files changed

+136
-1
lines changed

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ sentence=Allows Arduino/Genuino boards to control a variety of servo motors.
66
paragraph=This library can control a great number of servos.<br />It makes careful use of timers: the library can control 12 servos using only 1 timer.<br />On the Arduino Due you can control up to 60 servos.<br />
77
category=Device Control
88
url=http://www.arduino.cc/en/Reference/Servo
9-
architectures=avr,megaavr,sam,samd,nrf52,stm32f4
9+
architectures=avr,megaavr,sam,samd,nrf52,stm32f4,mbed

src/Servo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
#include "nrf52/ServoTimers.h"
7272
#elif defined(ARDUINO_ARCH_MEGAAVR)
7373
#include "megaavr/ServoTimers.h"
74+
#elif defined(ARDUINO_ARCH_MBED)
75+
#include "mbed/ServoTimers.h"
7476
#else
7577
#error "This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor."
7678
#endif

src/mbed/Servo.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#if defined(ARDUINO_ARCH_MBED)
2+
3+
#include <Arduino.h>
4+
#include <Servo.h>
5+
6+
class ServoImpl {
7+
mbed::DigitalOut *pin;
8+
mbed::Timeout timeout; // calls a callback once when a timeout expires
9+
mbed::Ticker ticker; // calls a callback repeatedly with a timeout
10+
11+
public:
12+
ServoImpl(PinName _pin) {
13+
pin = new mbed::DigitalOut(_pin);
14+
}
15+
16+
~ServoImpl() {
17+
ticker.detach();
18+
timeout.detach();
19+
delete pin;
20+
}
21+
22+
void start(uint32_t duration_us) {
23+
duration = duration_us;
24+
ticker.attach(mbed::callback(this, &ServoImpl::call), 0.02f);
25+
}
26+
27+
void call() {
28+
timeout.attach(mbed::callback(this, &ServoImpl::toggle), duration / 1e6);
29+
toggle();
30+
}
31+
32+
void toggle() {
33+
*pin = !*pin;
34+
}
35+
36+
int32_t duration = -1;
37+
};
38+
39+
static ServoImpl* servos[MAX_SERVOS]; // static array of servo structures
40+
uint8_t ServoCount = 0; // the total number of attached servos
41+
42+
#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min) // minimum value in uS for this servo
43+
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max) // maximum value in uS for this servo
44+
45+
#define TRIM_DURATION 15 //callback overhead (35 uS) -> 15uS if toggle() is called after starting the timeout
46+
47+
Servo::Servo()
48+
{
49+
if (ServoCount < MAX_SERVOS) {
50+
this->servoIndex = ServoCount++;
51+
} else {
52+
this->servoIndex = INVALID_SERVO; // too many servos
53+
}
54+
}
55+
56+
uint8_t Servo::attach(int pin)
57+
{
58+
return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
59+
}
60+
61+
uint8_t Servo::attach(int pin, int min, int max)
62+
{
63+
pinMode(pin, OUTPUT); // set servo pin to output
64+
servos[this->servoIndex] = new ServoImpl(digitalPinToPinName(pin));
65+
66+
this->min = (MIN_PULSE_WIDTH - min);
67+
this->max = (MAX_PULSE_WIDTH - max);
68+
return this->servoIndex;
69+
}
70+
71+
void Servo::detach()
72+
{
73+
delete servos[this->servoIndex];
74+
servos[this->servoIndex] = NULL;
75+
}
76+
77+
void Servo::write(int value)
78+
{
79+
// treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
80+
if (value < MIN_PULSE_WIDTH)
81+
{
82+
if (value < 0)
83+
value = 0;
84+
else if (value > 180)
85+
value = 180;
86+
87+
value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX());
88+
}
89+
writeMicroseconds(value);
90+
}
91+
92+
void Servo::writeMicroseconds(int value)
93+
{
94+
if (!servos[this->servoIndex]) {
95+
return;
96+
}
97+
// calculate and store the values for the given channel
98+
byte channel = this->servoIndex;
99+
if( (channel < MAX_SERVOS) ) // ensure channel is valid
100+
{
101+
if (value < SERVO_MIN()) // ensure pulse width is valid
102+
value = SERVO_MIN();
103+
else if (value > SERVO_MAX())
104+
value = SERVO_MAX();
105+
106+
value = value - TRIM_DURATION;
107+
if (servos[this->servoIndex]->duration == -1) {
108+
servos[this->servoIndex]->start(value);
109+
}
110+
servos[this->servoIndex]->duration = value;
111+
}
112+
}
113+
114+
int Servo::read() // return the value as degrees
115+
{
116+
return map(readMicroseconds(), SERVO_MIN(), SERVO_MAX(), 0, 180);
117+
}
118+
119+
int Servo::readMicroseconds()
120+
{
121+
if (!servos[this->servoIndex]) {
122+
return 0;
123+
}
124+
return servos[this->servoIndex]->duration;
125+
}
126+
127+
bool Servo::attached()
128+
{
129+
return servos[this->servoIndex] != NULL;
130+
}
131+
132+
#endif

src/mbed/ServoTimers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#define _Nbr_16timers 32

0 commit comments

Comments
 (0)