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++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// 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;
};