Skip to content

Commit e671f3f

Browse files
motorshield: add Motor Shield V2 library v1.0.1 from Adafruit
- Adafruit_Motor_Shield_V2_Library Github repository: https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library Tag: v1.0.1 Signed-off-by: Dan O'Donovan <[email protected]>
1 parent 146b0bf commit e671f3f

File tree

15 files changed

+1205
-0
lines changed

15 files changed

+1205
-0
lines changed
Lines changed: 396 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,396 @@
1+
/******************************************************************
2+
This is the library for the Adafruit Motor Shield V2 for Arduino.
3+
It supports DC motors & Stepper motors with microstepping as well
4+
as stacking-support. It is *not* compatible with the V1 library!
5+
6+
It will only work with https://www.adafruit.com/products/1483
7+
8+
Adafruit invests time and resources providing this open
9+
source code, please support Adafruit and open-source hardware
10+
by purchasing products from Adafruit!
11+
12+
Written by Limor Fried/Ladyada for Adafruit Industries.
13+
BSD license, check license.txt for more information.
14+
All text above must be included in any redistribution.
15+
******************************************************************/
16+
17+
18+
#if (ARDUINO >= 100)
19+
#include "Arduino.h"
20+
#else
21+
#include "WProgram.h"
22+
#endif
23+
#include <Wire.h>
24+
#include "Adafruit_MotorShield.h"
25+
#include <Adafruit_PWMServoDriver.h>
26+
#ifdef __AVR__
27+
#define WIRE Wire
28+
#else // Arduino Due
29+
#define WIRE Wire1
30+
#endif
31+
32+
33+
#if (MICROSTEPS == 8)
34+
uint8_t microstepcurve[] = {0, 50, 98, 142, 180, 212, 236, 250, 255};
35+
#elif (MICROSTEPS == 16)
36+
uint8_t microstepcurve[] = {0, 25, 50, 74, 98, 120, 141, 162, 180, 197, 212, 225, 236, 244, 250, 253, 255};
37+
#endif
38+
39+
Adafruit_MotorShield::Adafruit_MotorShield(uint8_t addr) {
40+
_addr = addr;
41+
_pwm = Adafruit_PWMServoDriver(_addr);
42+
}
43+
44+
void Adafruit_MotorShield::begin(uint16_t freq) {
45+
// init PWM w/_freq
46+
WIRE.begin();
47+
_pwm.begin();
48+
_freq = freq;
49+
_pwm.setPWMFreq(_freq); // This is the maximum PWM frequency
50+
for (uint8_t i=0; i<16; i++)
51+
_pwm.setPWM(i, 0, 0);
52+
}
53+
54+
void Adafruit_MotorShield::setPWM(uint8_t pin, uint16_t value) {
55+
if (value > 4095) {
56+
_pwm.setPWM(pin, 4096, 0);
57+
} else
58+
_pwm.setPWM(pin, 0, value);
59+
}
60+
void Adafruit_MotorShield::setPin(uint8_t pin, boolean value) {
61+
if (value == LOW)
62+
_pwm.setPWM(pin, 0, 0);
63+
else
64+
_pwm.setPWM(pin, 4096, 0);
65+
}
66+
67+
Adafruit_DCMotor *Adafruit_MotorShield::getMotor(uint8_t num) {
68+
if (num > 4) return NULL;
69+
70+
num--;
71+
72+
if (dcmotors[num].motornum == 0) {
73+
// not init'd yet!
74+
dcmotors[num].motornum = num;
75+
dcmotors[num].MC = this;
76+
uint8_t pwm, in1, in2;
77+
if (num == 0) {
78+
pwm = 8; in2 = 9; in1 = 10;
79+
} else if (num == 1) {
80+
pwm = 13; in2 = 12; in1 = 11;
81+
} else if (num == 2) {
82+
pwm = 2; in2 = 3; in1 = 4;
83+
} else if (num == 3) {
84+
pwm = 7; in2 = 6; in1 = 5;
85+
}
86+
dcmotors[num].PWMpin = pwm;
87+
dcmotors[num].IN1pin = in1;
88+
dcmotors[num].IN2pin = in2;
89+
}
90+
return &dcmotors[num];
91+
}
92+
93+
94+
Adafruit_StepperMotor *Adafruit_MotorShield::getStepper(uint16_t steps, uint8_t num) {
95+
if (num > 2) return NULL;
96+
97+
num--;
98+
99+
if (steppers[num].steppernum == 0) {
100+
// not init'd yet!
101+
steppers[num].steppernum = num;
102+
steppers[num].revsteps = steps;
103+
steppers[num].MC = this;
104+
uint8_t pwma, pwmb, ain1, ain2, bin1, bin2;
105+
if (num == 0) {
106+
pwma = 8; ain2 = 9; ain1 = 10;
107+
pwmb = 13; bin2 = 12; bin1 = 11;
108+
} else if (num == 1) {
109+
pwma = 2; ain2 = 3; ain1 = 4;
110+
pwmb = 7; bin2 = 6; bin1 = 5;
111+
}
112+
steppers[num].PWMApin = pwma;
113+
steppers[num].PWMBpin = pwmb;
114+
steppers[num].AIN1pin = ain1;
115+
steppers[num].AIN2pin = ain2;
116+
steppers[num].BIN1pin = bin1;
117+
steppers[num].BIN2pin = bin2;
118+
}
119+
return &steppers[num];
120+
}
121+
122+
123+
/******************************************
124+
MOTORS
125+
******************************************/
126+
127+
Adafruit_DCMotor::Adafruit_DCMotor(void) {
128+
MC = NULL;
129+
motornum = 0;
130+
PWMpin = IN1pin = IN2pin = 0;
131+
}
132+
133+
void Adafruit_DCMotor::run(uint8_t cmd) {
134+
switch (cmd) {
135+
case FORWARD:
136+
MC->setPin(IN2pin, LOW); // take low first to avoid 'break'
137+
MC->setPin(IN1pin, HIGH);
138+
break;
139+
case BACKWARD:
140+
MC->setPin(IN1pin, LOW); // take low first to avoid 'break'
141+
MC->setPin(IN2pin, HIGH);
142+
break;
143+
case RELEASE:
144+
MC->setPin(IN1pin, LOW);
145+
MC->setPin(IN2pin, LOW);
146+
break;
147+
}
148+
}
149+
150+
void Adafruit_DCMotor::setSpeed(uint8_t speed) {
151+
MC->setPWM(PWMpin, speed*16);
152+
}
153+
154+
/******************************************
155+
STEPPERS
156+
******************************************/
157+
158+
Adafruit_StepperMotor::Adafruit_StepperMotor(void) {
159+
revsteps = steppernum = currentstep = 0;
160+
}
161+
/*
162+
163+
uint16_t steps, Adafruit_MotorShield controller) {
164+
165+
revsteps = steps;
166+
steppernum = 1;
167+
currentstep = 0;
168+
169+
if (steppernum == 1) {
170+
latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
171+
~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
172+
173+
// enable both H bridges
174+
pinMode(11, OUTPUT);
175+
pinMode(3, OUTPUT);
176+
digitalWrite(11, HIGH);
177+
digitalWrite(3, HIGH);
178+
179+
// use PWM for microstepping support
180+
MC->setPWM(1, 255);
181+
MC->setPWM(2, 255);
182+
183+
} else if (steppernum == 2) {
184+
latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
185+
~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
186+
187+
// enable both H bridges
188+
pinMode(5, OUTPUT);
189+
pinMode(6, OUTPUT);
190+
digitalWrite(5, HIGH);
191+
digitalWrite(6, HIGH);
192+
193+
// use PWM for microstepping support
194+
// use PWM for microstepping support
195+
MC->setPWM(3, 255);
196+
MC->setPWM(4, 255);
197+
}
198+
}
199+
*/
200+
201+
void Adafruit_StepperMotor::setSpeed(uint16_t rpm) {
202+
//Serial.println("steps per rev: "); Serial.println(revsteps);
203+
//Serial.println("RPM: "); Serial.println(rpm);
204+
205+
usperstep = 60000000 / ((uint32_t)revsteps * (uint32_t)rpm);
206+
}
207+
208+
void Adafruit_StepperMotor::release(void) {
209+
MC->setPin(AIN1pin, LOW);
210+
MC->setPin(AIN2pin, LOW);
211+
MC->setPin(BIN1pin, LOW);
212+
MC->setPin(BIN2pin, LOW);
213+
MC->setPWM(PWMApin, 0);
214+
MC->setPWM(PWMBpin, 0);
215+
}
216+
217+
void Adafruit_StepperMotor::step(uint16_t steps, uint8_t dir, uint8_t style) {
218+
uint32_t uspers = usperstep;
219+
uint8_t ret = 0;
220+
221+
if (style == INTERLEAVE) {
222+
uspers /= 2;
223+
}
224+
else if (style == MICROSTEP) {
225+
uspers /= MICROSTEPS;
226+
steps *= MICROSTEPS;
227+
#ifdef MOTORDEBUG
228+
Serial.print("steps = "); Serial.println(steps, DEC);
229+
#endif
230+
}
231+
232+
while (steps--) {
233+
//Serial.println("step!"); Serial.println(uspers);
234+
ret = onestep(dir, style);
235+
delayMicroseconds(uspers);
236+
}
237+
}
238+
239+
uint8_t Adafruit_StepperMotor::onestep(uint8_t dir, uint8_t style) {
240+
uint8_t a, b, c, d;
241+
uint8_t ocrb, ocra;
242+
243+
ocra = ocrb = 255;
244+
245+
246+
// next determine what sort of stepping procedure we're up to
247+
if (style == SINGLE) {
248+
if ((currentstep/(MICROSTEPS/2)) % 2) { // we're at an odd step, weird
249+
if (dir == FORWARD) {
250+
currentstep += MICROSTEPS/2;
251+
}
252+
else {
253+
currentstep -= MICROSTEPS/2;
254+
}
255+
} else { // go to the next even step
256+
if (dir == FORWARD) {
257+
currentstep += MICROSTEPS;
258+
}
259+
else {
260+
currentstep -= MICROSTEPS;
261+
}
262+
}
263+
} else if (style == DOUBLE) {
264+
if (! (currentstep/(MICROSTEPS/2) % 2)) { // we're at an even step, weird
265+
if (dir == FORWARD) {
266+
currentstep += MICROSTEPS/2;
267+
} else {
268+
currentstep -= MICROSTEPS/2;
269+
}
270+
} else { // go to the next odd step
271+
if (dir == FORWARD) {
272+
currentstep += MICROSTEPS;
273+
} else {
274+
currentstep -= MICROSTEPS;
275+
}
276+
}
277+
} else if (style == INTERLEAVE) {
278+
if (dir == FORWARD) {
279+
currentstep += MICROSTEPS/2;
280+
} else {
281+
currentstep -= MICROSTEPS/2;
282+
}
283+
}
284+
285+
if (style == MICROSTEP) {
286+
if (dir == FORWARD) {
287+
currentstep++;
288+
} else {
289+
// BACKWARDS
290+
currentstep--;
291+
}
292+
293+
currentstep += MICROSTEPS*4;
294+
currentstep %= MICROSTEPS*4;
295+
296+
ocra = ocrb = 0;
297+
if ( (currentstep >= 0) && (currentstep < MICROSTEPS)) {
298+
ocra = microstepcurve[MICROSTEPS - currentstep];
299+
ocrb = microstepcurve[currentstep];
300+
} else if ( (currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2)) {
301+
ocra = microstepcurve[currentstep - MICROSTEPS];
302+
ocrb = microstepcurve[MICROSTEPS*2 - currentstep];
303+
} else if ( (currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3)) {
304+
ocra = microstepcurve[MICROSTEPS*3 - currentstep];
305+
ocrb = microstepcurve[currentstep - MICROSTEPS*2];
306+
} else if ( (currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4)) {
307+
ocra = microstepcurve[currentstep - MICROSTEPS*3];
308+
ocrb = microstepcurve[MICROSTEPS*4 - currentstep];
309+
}
310+
}
311+
312+
currentstep += MICROSTEPS*4;
313+
currentstep %= MICROSTEPS*4;
314+
315+
#ifdef MOTORDEBUG
316+
Serial.print("current step: "); Serial.println(currentstep, DEC);
317+
Serial.print(" pwmA = "); Serial.print(ocra, DEC);
318+
Serial.print(" pwmB = "); Serial.println(ocrb, DEC);
319+
#endif
320+
MC->setPWM(PWMApin, ocra*16);
321+
MC->setPWM(PWMBpin, ocrb*16);
322+
323+
324+
// release all
325+
uint8_t latch_state = 0; // all motor pins to 0
326+
327+
//Serial.println(step, DEC);
328+
if (style == MICROSTEP) {
329+
if ((currentstep >= 0) && (currentstep < MICROSTEPS))
330+
latch_state |= 0x03;
331+
if ((currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2))
332+
latch_state |= 0x06;
333+
if ((currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3))
334+
latch_state |= 0x0C;
335+
if ((currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4))
336+
latch_state |= 0x09;
337+
} else {
338+
switch (currentstep/(MICROSTEPS/2)) {
339+
case 0:
340+
latch_state |= 0x1; // energize coil 1 only
341+
break;
342+
case 1:
343+
latch_state |= 0x3; // energize coil 1+2
344+
break;
345+
case 2:
346+
latch_state |= 0x2; // energize coil 2 only
347+
break;
348+
case 3:
349+
latch_state |= 0x6; // energize coil 2+3
350+
break;
351+
case 4:
352+
latch_state |= 0x4; // energize coil 3 only
353+
break;
354+
case 5:
355+
latch_state |= 0xC; // energize coil 3+4
356+
break;
357+
case 6:
358+
latch_state |= 0x8; // energize coil 4 only
359+
break;
360+
case 7:
361+
latch_state |= 0x9; // energize coil 1+4
362+
break;
363+
}
364+
}
365+
#ifdef MOTORDEBUG
366+
Serial.print("Latch: 0x"); Serial.println(latch_state, HEX);
367+
#endif
368+
369+
if (latch_state & 0x1) {
370+
// Serial.println(AIN2pin);
371+
MC->setPin(AIN2pin, HIGH);
372+
} else {
373+
MC->setPin(AIN2pin, LOW);
374+
}
375+
if (latch_state & 0x2) {
376+
MC->setPin(BIN1pin, HIGH);
377+
// Serial.println(BIN1pin);
378+
} else {
379+
MC->setPin(BIN1pin, LOW);
380+
}
381+
if (latch_state & 0x4) {
382+
MC->setPin(AIN1pin, HIGH);
383+
// Serial.println(AIN1pin);
384+
} else {
385+
MC->setPin(AIN1pin, LOW);
386+
}
387+
if (latch_state & 0x8) {
388+
MC->setPin(BIN2pin, HIGH);
389+
// Serial.println(BIN2pin);
390+
} else {
391+
MC->setPin(BIN2pin, LOW);
392+
}
393+
394+
return currentstep;
395+
}
396+

0 commit comments

Comments
 (0)