-
Notifications
You must be signed in to change notification settings - Fork 0
/
motorDriver.cpp
209 lines (181 loc) · 4.67 KB
/
motorDriver.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
* Copyright (C) 2016 Tolga Ceylan
*
* CopyPolicy: Released under the terms of the GNU GPL v3.0.
* This file incorporates work covered by the following copyright and
* permission notice:
*/
/******************************************************************
This is the library for the Adafruit Motor Shield V2 for Arduino.
It supports DC motors & Stepper motors with microstepping as well
as stacking-support. It is *not* compatible with the V1 library!
It will only work with https://www.adafruit.com/products/1483
Adafruit invests time and resources providing this open
source code, please support Adafruit and open-source hardware
by purchasing products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information.
All text above must be included in any redistribution.
******************************************************************/
#include "motorDriver.h"
#include "logger.h"
#include "i2c.h"
#include <errno.h>
#include <string.h>
namespace robo
{
#define LOW 0
#define HIGH 1
MotorDriver::MotorDriver(I2C *driver, Thread *thr)
:
m_freq(0),
m_state(STATE_IDLE),
m_pwm(driver, thr)
{
}
MotorDriver::~MotorDriver()
{
shutdown();
}
void MotorDriver::shutdown()
{
logger(LOG_INFO, "MotorDriver shutting down");
m_pwm.shutdown();
m_freq = 0;
m_state = STATE_IDLE;
}
int MotorDriver::initialize(int address, uint16_t freq)
{
logger(LOG_INFO, "MotorDriver initializing freq=%u", freq);
int res = m_pwm.initialize(address, freq);
if (res)
{
logger(LOG_ERROR, "MotorDriver pwm error addr=%d err=%d", address, res);
return res;
}
m_freq = freq;
m_state = STATE_INITIALIZE;
return 0;
}
int MotorDriver::update(uint64_t now)
{
int res = 0;
switch (m_state)
{
case STATE_INITIALIZE:
{
if (!m_pwm.is_initialized())
break;
for (uint8_t i = 0; i < 16; ++i)
{
res = m_pwm.set_pwm(i, 0, 0);
if (res)
break;
}
if (res)
break;
res = m_pwm.execute();
if (res)
break;
m_state = STATE_INITIALIZING;
}
break;
case STATE_INITIALIZING:
{
static uint64_t tmp = 0;
if (tmp == 0)
tmp = now;
// Add some delay until we are fully initialized to avoid
// multi threading perf issues (scanner and motor commands running
// at the same time)
if (Timer::get_elapsed_usec(tmp, now) < 5000)
break;
tmp = 0;
m_state = STATE_INITIALIZED;
}
break;
default:
break;
}
if (!res)
res = m_pwm.update(now);
return res;
}
int MotorDriver::run_dc(DCMotor motor, uint8_t cmd)
{
int res = 0;
switch (cmd)
{
case FORWARD:
res = set_pin(motor.in2, LOW); // take low first to avoid 'break'
if (!res)
res = set_pin(motor.in1, HIGH);
break;
case BACKWARD:
res = set_pin(motor.in1, LOW); // take low first to avoid 'break'
if (!res)
res = set_pin(motor.in2, HIGH);
break;
case RELEASE:
res = set_pin(motor.in1, LOW);
if (!res)
res = set_pin(motor.in2, LOW);
break;
default:
return EINVAL;
}
return res;
}
int MotorDriver::execute()
{
return m_pwm.execute();
}
int MotorDriver::set_dc_speed(DCMotor motor, uint8_t speed)
{
return set_pwm(motor.pwm, speed * 16);
}
int MotorDriver::set_pwm(uint8_t pin, uint16_t value)
{
if (value > 4095)
return m_pwm.set_pwm(pin, 4096, 0);
return m_pwm.set_pwm(pin, 0, value);
}
int MotorDriver::set_pin(uint8_t pin, uint8_t value)
{
if (value == LOW)
return m_pwm.set_pwm(pin, 0, 0);
return m_pwm.set_pwm(pin, 4096, 0);
}
DCMotor MotorDriver::get_dc_motor(int num)
{
DCMotor motor;
switch (num)
{
case 1:
motor.pwm = 8;
motor.in2 = 9;
motor.in1 = 10;
motor.id = num;
break;
case 2:
motor.pwm = 13;
motor.in2 = 12;
motor.in1 = 11;
motor.id = num;
break;
case 3:
motor.pwm = 2;
motor.in2 = 3;
motor.in1 = 4;
motor.id = num;
case 4:
motor.pwm = 7;
motor.in2 = 6;
motor.in1 = 5;
motor.id = num;
default:
break;
}
return motor;
}
} // namespace robo