RSeries astromech firmware
SabertoothDriver.h
Go to the documentation of this file.
1 /*
2 Arduino Library for SyRen/Sabertooth Packet Serial
3 Copyright (c) 2012-2013 Dimension Engineering LLC
4 http://www.dimensionengineering.com/arduino
5 
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9 
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
14 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
16 USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 
19 #ifndef SabertoothDriver_h
20 #define SabertoothDriver_h
21 
22 #include "ReelTwo.h"
23 
32 {
33 public:
40  SabertoothDriver(byte address, Stream& port) :
41  fAddress(address),
42  fPort(&port)
43  {
44  }
45 
50  inline byte address() const
51  {
52  return fAddress;
53  }
54 
59  inline void setAddress(byte addr)
60  {
61  fAddress = addr;
62  }
63 
68  void autobaud(boolean dontWait = false) const
69  {
70  if (fPort != nullptr)
71  {
72  autobaud(*fPort, dontWait);
73  }
74  }
75 
81  static void autobaud(Stream& port, boolean dontWait = false)
82  {
83  if (!dontWait)
84  {
85  delay(1500);
86  }
87  port.write(0xAA);
88  port.flush();
89  if (!dontWait)
90  {
91  delay(500);
92  }
93  }
94 
100  void command(byte command, byte value) const
101  {
102  if (fPort != nullptr)
103  {
104  //printf("CMD{%d}:%d:%d:%d\n", address(), command, value, (address() + command + value) & B01111111);
105  fPort->write(address());
106  fPort->write(command);
107  fPort->write(value);
108  fPort->write((address() + command + value) & B01111111);
109  }
110  }
111 
116  void motor(int power) const
117  {
118  motor(1, power);
119  }
120 
126  void motor(byte motor, int power) const
127  {
128  if (motor >= 1 && motor <= 2)
129  {
130  throttleCommand((motor == 2 ? 4 : 0) + (power < 0 ? 1 : 0), power);
131  }
132  }
133 
138  void drive(int power) const
139  {
140  throttleCommand(power < 0 ? 9 : 8, power);
141  }
142 
147  void turn(int power) const
148  {
149  throttleCommand(power < 0 ? 11 : 10, power);
150  }
151 
155  void stop() const
156  {
157  motor(1, 0);
158  motor(2, 0);
159  }
160 
165  void setMinVoltage(byte value) const
166  {
167  command(2, (byte)min((int)value, 120));
168  }
169 
175  void setMaxVoltage(byte value) const
176  {
177  command(3, (byte)min((int)value, 127));
178  }
179 
185  void setBaudRate(long baudRate) const
186  {
187  #if defined(ARDUINO) && ARDUINO >= 100
188  fPort->flush();
189  #endif
190 
191  byte value;
192  switch (baudRate)
193  {
194  case 2400:
195  value = 1;
196  break;
197  default:
198  case 9600:
199  value = 2;
200  break;
201  case 19200:
202  value = 3;
203  break;
204  case 38400:
205  value = 4;
206  break;
207  case 115200:
208  value = 5;
209  break;
210  }
211  command(15, value);
212 
213  #if defined(ARDUINO) && ARDUINO >= 100
214  fPort->flush();
215  #endif
216 
217  // (1) flush() does not seem to wait until transmission is complete.
218  // As a result, a Serial.end() directly after this appears to
219  // not always transmit completely. So, we manually add a delay.
220  // (2) Sabertooth takes about 200 ms after setting the baud rate to
221  // respond to commands again (it restarts).
222  // So, this 500 ms delay should deal with this.
223  delay(500);
224  }
225 
234  void setDeadband(byte value) const
235  {
236  command(17, (byte)min(int(value), 127));
237  }
238 
244  void setRamping(byte value) const
245  {
246  command(16, (byte)min(int(value), 80));
247  }
248 
257  void setTimeout(int milliseconds) const
258  {
259  command(14, (byte)((constrain(milliseconds, 0, 12700) + 99) / 100));
260  }
261 
262 private:
263  void throttleCommand(byte command, int power) const
264  {
265  power = constrain(power, -126, 126);
266  this->command(command, (byte)abs(power));
267  }
268 
269 private:
270  byte fAddress;
271  Stream* fPort = nullptr;
272 };
273 
274 #endif
SabertoothDriver::autobaud
static void autobaud(Stream &port, boolean dontWait=false)
Definition: SabertoothDriver.h:81
SabertoothDriver::address
byte address() const
Definition: SabertoothDriver.h:50
ReelTwo.h
SabertoothDriver::setMinVoltage
void setMinVoltage(byte value) const
Definition: SabertoothDriver.h:165
SabertoothDriver::motor
void motor(int power) const
Definition: SabertoothDriver.h:116
SabertoothDriver::setBaudRate
void setBaudRate(long baudRate) const
Definition: SabertoothDriver.h:185
SabertoothDriver::command
void command(byte command, byte value) const
Definition: SabertoothDriver.h:100
SabertoothDriver::setAddress
void setAddress(byte addr)
Definition: SabertoothDriver.h:59
SabertoothDriver::setDeadband
void setDeadband(byte value) const
Definition: SabertoothDriver.h:234
SabertoothDriver::SabertoothDriver
SabertoothDriver(byte address, Stream &port)
Definition: SabertoothDriver.h:40
SabertoothDriver::motor
void motor(byte motor, int power) const
Definition: SabertoothDriver.h:126
SabertoothDriver::setTimeout
void setTimeout(int milliseconds) const
Definition: SabertoothDriver.h:257
SabertoothDriver::turn
void turn(int power) const
Definition: SabertoothDriver.h:147
SabertoothDriver::stop
void stop() const
Definition: SabertoothDriver.h:155
SabertoothDriver::setRamping
void setRamping(byte value) const
Definition: SabertoothDriver.h:244
SabertoothDriver
Definition: SabertoothDriver.h:31
SabertoothDriver::autobaud
void autobaud(boolean dontWait=false) const
Definition: SabertoothDriver.h:68
SabertoothDriver::drive
void drive(int power) const
Definition: SabertoothDriver.h:138
SabertoothDriver::setMaxVoltage
void setMaxVoltage(byte value) const
Definition: SabertoothDriver.h:175