You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
14 KiB
C

5 years ago
// Copyright (C) Pololu Corporation. See LICENSE.txt for details.
/*! \file PololuMaestro.h
*
* This is the main header file for the Pololu Maestro Servo Controller library
* for Arduino.
*
*
* For an overview of the library's features, see
* https://github.com/pololu/maestro-arduino. That is the main repository for
* the library.
*/
#pragma once
#include <Arduino.h>
#include <Stream.h>
/*! \brief Main Maestro class that handles common functions between the Micro
* Maestro and Mini Maestro.
*
* The subclasses, MicroMaestro and MiniMaestro inherit all of the functions
* from Maestro. The Maestro class is not meant to be instantiated directly; use
* the MicroMaestro or MiniMaestro subclasses instead.
*/
class Maestro
{
public:
/** \brief The default device number, used to construct a MicroMaestro or
MiniMaestro object that will use the compact protocol.
*/
static const uint8_t deviceNumberDefault = 255;
/** \brief The default reset pin is no reset pin, used to construct a
MicroMaestro or MiniMaestro object that will not have a reset pin.
*/
static const uint8_t noResetPin = 255;
/** \brief Resets the Maestro by toggling the \p resetPin, if a \p resetPin
* was given.
*
* By default this function will do nothing. If the \p resetPin was
* specified while constructing the Maestro object, it will toggle that pin.
* That pin needs to be wired to the Maestro's RST pin for it to reset the
* servo controller.
*/
void reset();
/** \brief Sets the \a target of the servo on \a channelNumber using the
* Mini SSC protocol.
*
* @param channelNumber A servo number from 0 to 254.
*
* @param target A target position from 0 to 254.
*
*/
void setTargetMiniSSC(uint8_t channelNumber, uint8_t target);
/** \brief Sets the \a target of the servo on \a channelNumber.
*
* @param channelNumber A servo number from 0 to 127.
*
* @param target A number from 0 to 16383.
*
* If the channel is configured as a servo, then the target represents the
* pulse width to transmit in units of quarter-microseconds. A \a target
* value of 0 tells the Maestro to stop sending pulses to the servo.
*
* If the channel is configured as a digital output, values less than 6000
* tell the Maestro to drive the line low, while values of 6000 or greater
* tell the Maestro to drive the line high.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void setTarget(uint8_t channelNumber, uint16_t target);
/** \brief Sets the \a speed limit of \a channelNumber.
*
* @param channelNumber A servo number from 0 to 127.
*
* @param speed A number from 0 to 16383.
*
* Limits the speed a servo channels output value changes.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void setSpeed(uint8_t channelNumber, uint16_t speed);
/** \brief Sets the \a acceleration limit of \a channelNumber.
*
* @param channelNumber A servo number from 0 to 127.
*
* @param acceleration A number from 0 to 16383.
*
* Limits the acceleration a servo channels output value changes.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void setAcceleration(uint8_t channelNumber, uint16_t acceleration);
/** \brief Sends the servos and outputs to home position.
*
* If the "On startup or error" setting for a servo or output channel is set
* to "Ignore", the position will be unchanged.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void goHome();
/** \brief Stops the script.
*
* Stops the script, if it is currently running.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void stopScript();
/** \brief Starts loaded script at specified \a subroutineNumber location.
*
* @param subroutineNumber A subroutine number defined in script's compiled
* code.
*
* Starts the loaded script at location specified by the subroutine number.
* Subroutines are numbered in the order they are defined in loaded script.
* Click the "View Compiled Code..." button and look at the subroutine list
* to find the number for a particular subroutine.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void restartScript(uint8_t subroutineNumber);
/** \brief Starts loaded script at specified \a subroutineNumber location
* after loading \a parameter on to the stack.
*
* @param subroutineNumber A subroutine number defined in script's compiled
* code.
*
* @param parameter A number from 0 to 16383.
*
* Similar to the \p restartScript function, except it loads the parameter
* on to the stack before starting the script at the specified subroutine
* number location.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void restartScriptWithParameter(uint8_t subroutineNumber, uint16_t parameter);
/** \brief Gets the position of \a channelNumber.
*
* @param channelNumber A servo number from 0 to 127.
*
* @return two-byte position value
*
* If channel is configured as a servo, then the position value represents
* the current pulse width transmitted on the channel in units of
* quarter-microseconds.
*
* If the channel is configured as a digital output, a position value less
* than 6000 means the Maestro is driving the line low, while a position
* value of 6000 or greater means the Maestro is driving the line high.
*
* If channel is configured as an input, then the position value represents
* the voltage measured. Analog inputs for channels 0-11: their values range
* from 0 to 1023, representing 0 to 5V. Digital inputs for channels 12-23:
* their values are exactly 0 or exactly 1023.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
uint16_t getPosition(uint8_t channelNumber);
/** \brief Gets the moving state for all configured servo channels.
*
* @return 1 if at least one servo limited by speed or acceleration is still
* moving, 0 if not.
*
* Determines if the servo outputs have reached their targets or are still
* changing and will return 1 as as long as there is at least one servo that
* is limited by a speed or acceleration setting.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
uint8_t getMovingState();
/** \brief Gets if the script is running or stopped.
*
* @return 1 if script is stopped, 0 if running.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
uint8_t getScriptStatus();
/** \brief Gets the error register.
*
* @return Two-byte error code.
*
* Returns the error register in two bytes then all the error bits are
* cleared on the Maestro. See the Errors section of the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
uint16_t getErrors();
/** \cond
*
* This should be considered a private implementation detail of the library.
**/
protected:
Maestro(Stream &stream,
uint8_t resetPin,
uint8_t deviceNumber,
bool CRCEnabled);
void writeByte(uint8_t dataByte);
void writeCRC();
void writeCommand(uint8_t commandByte);
void write7BitData(uint8_t data);
void write14BitData(uint16_t data);
/** \endcond **/
private:
static const uint8_t CRC7Polynomial = 0x91;
static const uint8_t baudRateIndication = 0xAA;
static const uint8_t miniSscCommand = 0xFF;
static const uint8_t setTargetCommand = 0x84;
static const uint8_t setSpeedCommand = 0x87;
static const uint8_t setAccelerationCommand = 0x89;
static const uint8_t getPositionCommand = 0x90;
static const uint8_t getMovingStateCommand = 0x93;
static const uint8_t getErrorsCommand = 0xA1;
static const uint8_t goHomeCommand = 0xA2;
static const uint8_t stopScriptCommand = 0xA4;
static const uint8_t restartScriptAtSubroutineCommand = 0xA7;
static const uint8_t restartScriptAtSubroutineWithParameterCommand = 0xA8;
static const uint8_t getScriptStatusCommand = 0xAE;
uint8_t _deviceNumber;
uint8_t _resetPin;
bool _CRCEnabled;
uint8_t _CRCByte;
Stream *_stream;
};
class MicroMaestro : public Maestro
{
public:
/** \brief Create a MicroMaestro object.
*
* @param stream A class that descends from Stream, like SoftwareSerial or
* one of the Hardware Serial ports.
*
* @param resetPin The pin used by reset() to reset the Maestro. The default
* value is Maestro::noResetPin, which makes reset() do nothing.
*
* @param deviceNumber The device number configured on the Serial Settings
* tab in the Maestro Control Center. When deviceNumber is anything but
* Maestro::deviceNumberDefault, the Maestro communicates via the Pololu
* protocol. Otherwise, it uses the Compact protocol.
*
* @param CRCEnabled When true, the object computes the CRC value for a
* command packet and sends it at the end. The Maestro also has to have the
* Enable CRC option checked on the Serial Settings tab of the Maestro
* Control Center.
*/
MicroMaestro(Stream &stream,
uint8_t resetPin = noResetPin,
uint8_t deviceNumber = deviceNumberDefault,
bool CRCEnabled = false);
};
class MiniMaestro : public Maestro
{
public:
/** \brief Create a MiniMaestro object.
*
* @param stream A class that descends from Stream, like SoftwareSerial or
* one of the Hardware Serial ports.
*
* @param resetPin The pin used by reset() to reset the Maestro. The default
* value is Maestro::noResetPin, which makes reset() do nothing.
*
* @param deviceNumber The device number configured on the Serial Settings
* tab in the Maestro Control Center. When deviceNumber is anything but
* Maestro::deviceNumberDefault, the Maestro communicates via the Pololu
* protocol. Otherwise, it uses the Compact protocol.
*
* @param CRCEnabled When true, the object computes the CRC value for a
* command packet and sends it at the end. The Maestro also has to have the
* Enable CRC option checked on the Serial Settings tab of the Maestro
* Control Center.
*
* The MiniMaestro object adds serial commands only availabe on the Mini
* Maestro servo controllers: setPWM and setMultiTarget.
*/
MiniMaestro(Stream &stream,
uint8_t resetPin = noResetPin,
uint8_t deviceNumber = deviceNumberDefault,
bool CRCEnabled = false);
/** \brief Sets the PWM specified by \a onTime and \a period in units of
* 1/48 microseconds.
*
* @param onTime A number from 0 to 16320.
*
* @param period A number from 4 to 16384.
*
* Sets the PWM output to the specified on time and period, in units of 1/48
* microseconds.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void setPWM(uint16_t onTime, uint16_t period);
/** \brief Sets multiple targets starting with the channel specified by \a
* firstChannel to a list of values listed in \a targetList for a
* contiguous block of channels specified by \a numberOfTargets.
*
* @param numberOfTargets A number from 0 to 24.
*
* @param firstChannel A channel number from 0 to (24 -
* \a numberOfTargets)
*
* @param targetList An array of numbers from 0 to 16383.
*
* The target value representation based on the channel's configuration
* (servo and output) is the same as the Set Target command.
*
* See the Serial Interface section in the [Maestro User's
* Guide](http://www.pololu.com/docs/0J40) for more details.
*
* The compact protocol is used by default. If the %deviceNumber was given
* to the constructor, it uses the Pololu protocol.
*/
void setMultiTarget(uint8_t numberOfTargets,
uint8_t firstChannel,
uint16_t *targetList);
private:
static const uint8_t setPwmCommand = 0x8A;
static const uint8_t setMultipleTargetsCommand = 0x9F;
};