forked from virtualrobotix/DRVMotor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDRV8835MotorShield.cpp
117 lines (103 loc) · 3.25 KB
/
DRV8835MotorShield.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "DRV8835MotorShield.h"
const unsigned char DRV8835MotorShield::_M1DIR = 7;
const unsigned char DRV8835MotorShield::_M2DIR = 8;
const unsigned char DRV8835MotorShield::_M1PWM = 9;
const unsigned char DRV8835MotorShield::_M2PWM = 10;
boolean DRV8835MotorShield::_flipM1 = false;
boolean DRV8835MotorShield::_flipM2 = false;
void DRV8835MotorShield::initPinsAndMaybeTimer()
{
// Initialize the pin states used by the motor driver shield
// digitalWrite is called before and after setting pinMode.
// It called before pinMode to handle the case where the board
// is using an ATmega AVR to avoid ever driving the pin high,
// even for a short time.
// It is called after pinMode to handle the case where the board
// is based on the Atmel SAM3X8E ARM Cortex-M3 CPU, like the Arduino
// Due. This is necessary because when pinMode is called for the Due
// it sets the output to high (or 3.3V) regardless of previous
// digitalWrite calls.
digitalWrite(_M1PWM, LOW);
pinMode(_M1PWM, OUTPUT);
digitalWrite(_M1PWM, LOW);
digitalWrite(_M2PWM, LOW);
pinMode(_M2PWM, OUTPUT);
digitalWrite(_M2PWM, LOW);
digitalWrite(_M1DIR, LOW);
pinMode(_M1DIR, OUTPUT);
digitalWrite(_M1DIR, LOW);
digitalWrite(_M2DIR, LOW);
pinMode(_M2DIR, OUTPUT);
digitalWrite(_M2DIR, LOW);
#ifdef DRV8835MOTORSHIELD_USE_20KHZ_PWM
// timer 1 configuration
// prescaler: clockI/O / 1
// outputs enabled
// phase-correct PWM
// top of 400
//
// PWM frequency calculation
// 16MHz / 1 (prescaler) / 2 (phase-correct) / 400 (top) = 20kHz
TCCR1A = 0b10100000;
TCCR1B = 0b00010001;
ICR1 = 400;
#endif
}
// speed should be a number between -400 and 400
void DRV8835MotorShield::setM1Speed(int speed)
{
init(); // initialize if necessary
boolean reverse = 0;
if (speed < 0)
{
speed = -speed; // make speed a positive quantity
reverse = 1; // preserve the direction
}
if (speed > 400) // max
speed = 400;
#ifdef DRV8835MOTORSHIELD_USE_20KHZ_PWM
OCR1A = speed;
#else
analogWrite(_M1PWM, speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
#endif
if (reverse ^ _flipM1) // flip if speed was negative or _flipM1 setting is active, but not both
digitalWrite(_M1DIR, HIGH);
else
digitalWrite(_M1DIR, LOW);
}
// speed should be a number between -400 and 400
void DRV8835MotorShield::setM2Speed(int speed)
{
init(); // initialize if necessary
boolean reverse = 0;
if (speed < 0)
{
speed = -speed; // make speed a positive quantity
reverse = 1; // preserve the direction
}
if (speed > 400) // max PWM duty cycle
speed = 400;
#ifdef DRV8835MOTORSHIELD_USE_20KHZ_PWM
OCR1B = speed;
#else
analogWrite(_M2PWM, speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
#endif
if (reverse ^ _flipM2) // flip if speed was negative or _flipM2 setting is active, but not both
digitalWrite(_M2DIR, HIGH);
else
digitalWrite(_M2DIR, LOW);
}
// set speed for both motors
// speed should be a number between -400 and 400
void DRV8835MotorShield::setSpeeds(int m1Speed, int m2Speed){
setM1Speed(m1Speed);
setM2Speed(m2Speed);
}
void DRV8835MotorShield::flipM1(boolean flip)
{
_flipM1 = flip;
}
void DRV8835MotorShield::flipM2(boolean flip)
{
_flipM2 = flip;
}