Compare commits

...

8 commits
main ... servo

Author SHA1 Message Date
brentru
cab02010aa dispatch servo msg into ws_servo component, still no WS._ledc handler yet 2022-08-08 14:16:36 -04:00
brentru
79eee4f388 remove WS from ledc_servo 2022-08-08 14:05:08 -04:00
brentru
28556e6798 add servo component 2022-08-08 12:29:01 -04:00
brentru
793caa5ba7 add servo driver, rename ledc driver 2022-08-05 13:57:59 -04:00
brentru
5e9bd2485d #include LEDC component 2022-08-04 18:02:08 -04:00
brentru
0741c9061b add LEDC 2022-08-04 12:57:24 -04:00
brentru
dec68f0e66 start adding servo skel. to core application 2022-07-28 15:24:00 -04:00
brentru
fb04193c87 add protobuf messages for servo 2022-07-28 12:29:32 -04:00
19 changed files with 914 additions and 13 deletions

View file

@ -51,6 +51,8 @@ Wippersnapper::Wippersnapper() {
_throttle_topic = 0; _throttle_topic = 0;
_err_sub = 0; _err_sub = 0;
_throttle_sub = 0; _throttle_sub = 0;
}; };
/**************************************************************************/ /**************************************************************************/
@ -780,6 +782,79 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
return is_success; return is_success;
} }
/******************************************************************************************/
/*!
@brief Decodes a servo message and dispatches to the servo component.
@param stream
Incoming data stream from buffer.
@param field
Protobuf message's tag type.
@param arg
Optional arguments from decoder calling function.
@returns True if decoded and executed successfully, False otherwise.
*/
/******************************************************************************************/
bool cbDecodeServoMsg(pb_istream_t *stream, const pb_field_t *field,
void **arg) {
bool is_success = true;
WS_DEBUG_PRINTLN("Decoding Servo Message...");
if (field->tag == wippersnapper_signal_v1_ServoRequest_servo_attach_tag) {
// TODO: This needs a servo_response_tag to be published back to the broker!
// Attempt to decode contents of servo_attach message
wippersnapper_servo_v1_ServoAttachReq msgServoAttachReq =
wippersnapper_servo_v1_ServoAttachReq_init_zero;
if (!pb_decode(stream, wippersnapper_servo_v1_ServoAttachReq_fields,
&msgServoAttachReq)) {
WS_DEBUG_PRINTLN(
"ERROR: Could not decode wippersnapper_servo_v1_ServoAttachReq");
return false; // fail out if we can't decode the request
}
// Dispatch servo attach request message
char *pinName = msgServoAttachReq.servo_pin + 1;
bool did_attach = WS._servoComponent->servo_attach(atoi(pinName), msgServoAttachReq.min_pulse_width, msgServoAttachReq.max_pulse_width, msgServoAttachReq.servo_freq);
// TODO: handle did_attach
}
return true;
}
/**************************************************************************/
/*!
@brief Called when the device recieves a new message from the
/servo/ topic.
@param data
Incoming data from MQTT broker.
@param len
Length of incoming data.
*/
/**************************************************************************/
void cbServoMsg(char *data, uint16_t len) {
WS_DEBUG_PRINTLN("* NEW MESSAGE [Topic: Servo]: ");
WS_DEBUG_PRINT(len);
WS_DEBUG_PRINTLN(" bytes.");
// zero-out current buffer
memset(WS._buffer, 0, sizeof(WS._buffer));
// copy mqtt data into buffer
memcpy(WS._buffer, data, len);
WS.bufSize = len;
// Zero-out existing servo message
wippersnapper_signal_v1_ServoRequest msgServo =
wippersnapper_signal_v1_ServoRequest_init_zero;
// Set up the payload callback, which will set up the callbacks for
// each oneof payload field once the field tag is known
WS.msgServo.cb_payload.funcs.decode = cbDecodeServoMsg;
// Decode servo message from buffer
pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize);
if (!pb_decode(&istream, wippersnapper_signal_v1_ServoRequest_fields,
&WS.msgServo))
WS_DEBUG_PRINTLN("ERROR: Unable to decode servo message");
}
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Called when i2c signal sub-topic receives a new message and @brief Called when i2c signal sub-topic receives a new message and
@ -1125,18 +1200,28 @@ bool Wippersnapper::buildWSTopics() {
sizeof(char) * strlen(WS._username) + strlen("/wprsnpr/") + sizeof(char) * strlen(WS._username) + strlen("/wprsnpr/") +
strlen(_device_uid) + strlen(TOPIC_SIGNALS) + strlen("broker") + 1); strlen(_device_uid) + strlen(TOPIC_SIGNALS) + strlen("broker") + 1);
// Topic for i2c signals from device to broker // Topic for i2c signals from broker to device
WS._topic_signal_i2c_brkr = (char *)malloc( WS._topic_signal_i2c_brkr = (char *)malloc(
sizeof(char) * strlen(WS._username) + +strlen("/") + strlen(_device_uid) + sizeof(char) * strlen(WS._username) + +strlen("/") + strlen(_device_uid) +
strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + strlen("broker") + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + strlen("broker") +
strlen(TOPIC_I2C) + 1); strlen(TOPIC_I2C) + 1);
// Topic for i2c signals from broker to device // Topic for i2c signals from device to broker
WS._topic_signal_i2c_device = (char *)malloc( WS._topic_signal_i2c_device = (char *)malloc(
sizeof(char) * strlen(WS._username) + +strlen("/") + strlen(_device_uid) + sizeof(char) * strlen(WS._username) + +strlen("/") + strlen(_device_uid) +
strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + strlen("device") + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + strlen("device") +
strlen(TOPIC_I2C) + 1); strlen(TOPIC_I2C) + 1);
// Topic for servo messages from broker->device
WS._topic_signal_servo_brkr = (char *)malloc(
sizeof(char) * strlen(WS._username) + strlen("/") + strlen(_device_uid) +
strlen("/wprsnpr/signals/broker/servo") + 1);
// Topic for servo messages from device->broker
WS._topic_signal_servo_device = (char *)malloc(
sizeof(char) * strlen(WS._username) + strlen("/") + strlen(_device_uid) +
strlen("/wprsnpr/signals/device/servo") + 1);
// Create global registration topic // Create global registration topic
if (WS._topic_description != NULL) { if (WS._topic_description != NULL) {
strcpy(WS._topic_description, WS._username); strcpy(WS._topic_description, WS._username);
@ -1228,6 +1313,28 @@ bool Wippersnapper::buildWSTopics() {
is_success = false; is_success = false;
} }
// Create device-to-broker servo signal topic
if (WS._topic_signal_i2c_device != NULL) {
strcpy(WS._topic_signal_i2c_device, WS._username);
strcat(WS._topic_signal_i2c_device, TOPIC_WS);
strcat(WS._topic_signal_i2c_device, _device_uid);
strcat(WS._topic_signal_i2c_device, TOPIC_SIGNALS);
strcat(WS._topic_signal_i2c_device, "broker/servo");
} else { // malloc failed
is_success = false;
}
// Create broker-to-device i2c signal topic
if (WS._topic_signal_i2c_device != NULL) {
strcpy(WS._topic_signal_i2c_device, WS._username);
strcat(WS._topic_signal_i2c_device, TOPIC_WS);
strcat(WS._topic_signal_i2c_device, _device_uid);
strcat(WS._topic_signal_i2c_device, TOPIC_SIGNALS);
strcat(WS._topic_signal_i2c_device, "device/servo");
} else { // malloc failed
is_success = false;
}
return is_success; return is_success;
} }
@ -1249,6 +1356,12 @@ void Wippersnapper::subscribeWSTopics() {
WS._mqtt->subscribe(_topic_signal_i2c_sub); WS._mqtt->subscribe(_topic_signal_i2c_sub);
_topic_signal_i2c_sub->setCallback(cbSignalI2CReq); _topic_signal_i2c_sub->setCallback(cbSignalI2CReq);
// Subscribe to servo sub-topic
_topic_signal_servo_sub =
new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_servo_brkr, 1);
WS._mqtt->subscribe(_topic_signal_servo_sub);
_topic_signal_servo_sub->setCallback(cbServoMsg);
// Subscribe to registration status topic // Subscribe to registration status topic
_topic_description_sub = _topic_description_sub =
new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_description_status, 1); new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_description_status, 1);
@ -1600,11 +1713,24 @@ void Wippersnapper::connect() {
runNetFSM(); runNetFSM();
publishPinConfigComplete(); publishPinConfigComplete();
WS_DEBUG_PRINTLN("Hardware configured successfully!"); WS_DEBUG_PRINTLN("Hardware configured successfully!");
statusLEDFade(GREEN, 3);
WS_DEBUG_PRINTLN("Configuring WS Components...");
#ifdef ARDUINO_ARCH_ESP32
WS_DEBUG_PRINT("[ESP32-Only] LEDC Controller: ");
WS._ledc = new WipperSnapper_Component_LEDC();
WS_DEBUG_PRINTLN("OK!");
#endif
WS_DEBUG_PRINT("Servo: ");
WS._servoComponent = new ws_servo();
WS_DEBUG_PRINTLN("OK!");
// Run application // Run application
WS_DEBUG_PRINTLN( WS_DEBUG_PRINTLN(
"Registration and configuration complete!\nRunning application..."); "Registration and configuration complete!\nRunning application...");
statusLEDFade(GREEN, 3);
} }
/**************************************************************************/ /**************************************************************************/

View file

@ -40,6 +40,13 @@
#include "components/digitalIO/Wippersnapper_DigitalGPIO.h" #include "components/digitalIO/Wippersnapper_DigitalGPIO.h"
#include "components/i2c/WipperSnapper_I2C.h" #include "components/i2c/WipperSnapper_I2C.h"
// ESP32-Specific Driver(s)
#ifdef ARDUINO_ARCH_ESP32
#include "components/ledc/ws_ledc.h"
#endif
#include "components/servo/ws_servo.h"
// External libraries // External libraries
#include "Adafruit_MQTT.h" // MQTT Client #include "Adafruit_MQTT.h" // MQTT Client
#include "Arduino.h" // Wiring #include "Arduino.h" // Wiring
@ -162,6 +169,11 @@ class Wippersnapper_FS;
class WipperSnapper_LittleFS; class WipperSnapper_LittleFS;
class WipperSnapper_Component_I2C; class WipperSnapper_Component_I2C;
#ifdef ARDUINO_ARCH_ESP32
class WipperSnapper_Component_LEDC;
#endif
class ws_servo;
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Class that provides storage and functions for the Adafruit IO @brief Class that provides storage and functions for the Adafruit IO
@ -267,6 +279,7 @@ public:
Wippersnapper_FS *_fileSystem; ///< Instance of Filesystem (native USB) Wippersnapper_FS *_fileSystem; ///< Instance of Filesystem (native USB)
WipperSnapper_LittleFS WipperSnapper_LittleFS
*_littleFS; ///< Instance of LittleFS Filesystem (non-native USB) *_littleFS; ///< Instance of LittleFS Filesystem (non-native USB)
ws_servo *_servoComponent; ///< instance of servo component
uint8_t _macAddr[6]; /*!< Unique network iface identifier */ uint8_t _macAddr[6]; /*!< Unique network iface identifier */
char sUID[13]; /*!< Unique network iface identifier */ char sUID[13]; /*!< Unique network iface identifier */
@ -291,7 +304,11 @@ public:
char *_topic_signal_device = NULL; /*!< Device->Wprsnpr messages */ char *_topic_signal_device = NULL; /*!< Device->Wprsnpr messages */
char *_topic_signal_i2c_brkr = NULL; /*!< Topic carries messages from a device char *_topic_signal_i2c_brkr = NULL; /*!< Topic carries messages from a device
to a broker. */ to a broker. */
char *_topic_signal_i2c_device = NULL; /*!< Topic carries messages from a char *_topic_signal_i2c_device = NULL; /*!< Topic carries messages from a
broker to a device. */
char *_topic_signal_servo_brkr = NULL; /*!< Topic carries messages from a
device to a broker. */
char *_topic_signal_servo_device = NULL; /*!< Topic carries messages from a
broker to a device. */ broker to a device. */
wippersnapper_signal_v1_CreateSignalRequest wippersnapper_signal_v1_CreateSignalRequest
@ -302,12 +319,20 @@ public:
wippersnapper_signal_v1_I2CRequest_init_zero; ///< I2C request wrapper wippersnapper_signal_v1_I2CRequest_init_zero; ///< I2C request wrapper
///< message ///< message
// servo message
wippersnapper_signal_v1_ServoRequest msgServo;
char *throttleMessage; /*!< Pointer to throttle message data. */ char *throttleMessage; /*!< Pointer to throttle message data. */
int throttleTime; /*!< Total amount of time to throttle the device, in int throttleTime; /*!< Total amount of time to throttle the device, in
milliseconds. */ milliseconds. */
bool pinCfgCompleted = false; /*!< Did initial pin sync complete? */ bool pinCfgCompleted = false; /*!< Did initial pin sync complete? */
// enable LEDC if esp32
#ifdef ARDUINO_ARCH_ESP32
WipperSnapper_Component_LEDC *_ledc = nullptr;
#endif
private: private:
void _init(); void _init();
@ -347,6 +372,8 @@ protected:
*_topic_signal_brkr_sub; /*!< Subscription for C2D signal topic. */ *_topic_signal_brkr_sub; /*!< Subscription for C2D signal topic. */
Adafruit_MQTT_Subscribe Adafruit_MQTT_Subscribe
*_topic_signal_i2c_sub; /*!< Subscribes to signal's I2C topic. */ *_topic_signal_i2c_sub; /*!< Subscribes to signal's I2C topic. */
Adafruit_MQTT_Subscribe
*_topic_signal_servo_sub; /*!< Subscribes to device's servo topic. */
Adafruit_MQTT_Subscribe Adafruit_MQTT_Subscribe
*_err_sub; /*!< Subscription to Adafruit IO Error topic. */ *_err_sub; /*!< Subscription to Adafruit IO Error topic. */
@ -356,7 +383,6 @@ protected:
wippersnapper_signal_v1_CreateSignalRequest wippersnapper_signal_v1_CreateSignalRequest
_outgoingSignalMsg; /*!< Outgoing signal message from device */ _outgoingSignalMsg; /*!< Outgoing signal message from device */
}; };
extern Wippersnapper WS; ///< Global member variable for callbacks extern Wippersnapper WS; ///< Global member variable for callbacks
#endif // ADAFRUIT_WIPPERSNAPPER_H #endif // ADAFRUIT_WIPPERSNAPPER_H

View file

@ -0,0 +1 @@
These files are drivers that interface directly with WipperSnapper's ESP32 LEDC peripheral manager, `ws_ledc`.

View file

@ -0,0 +1,113 @@
/*!
* @file ws_ledc_servo.cpp
*
* Driver for ESP32 servo control using the WipperSnapper
* LEDC peripheral manager API.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section author Author
*
* Written by Brent Rubell for Adafruit Industries, 2022.
*
* writeMicroseconds calculation from ESP32Servo
* https://github.com/madhephaestus/ESP32Servo/blob/master/src/ESP32Servo.cpp
* Copyright (c) 2017 John K. Bennett.
*
* @section license License
*
* GNU Lesser General Public License, all text here must be included in any
* redistribution.
*
*/
#include "ws_ledc_servo.h"
/**************************************************************************/
/*!
@brief Constructor.
*/
/**************************************************************************/
ws_ledc_servo::ws_ledc_servo() {}
/**************************************************************************/
/*!
@brief Destructor
*/
/**************************************************************************/
ws_ledc_servo::~ws_ledc_servo() {
detach(); // detach the active pin
}
/**************************************************************************/
/*!
@brief Attaches a servo object to a pin.
@param pin Desired GPIO pin.
@param minPulseWidth Minimum pulsewidth, in uS.
@param maxPulseWidth Maximum pulsewidth, in uS.
@returns Channel number if a servo is successfully attached to a pin,
otherwise 255.
*/
/**************************************************************************/
uint8_t ws_ledc_servo::attach(int pin, int minPulseWidth, int maxPulseWidth,
int servoFreq) {
// Attempt to attach a pin to ledc channel
uint8_t chan;
// chan = WS._ledc->attachPin((uint8_t)pin, (double)servoFreq);
if (chan == 255) // error!
return chan;
// configure the servo object and assign it to a pin
_servo.Pin.nbr = pin;
_servo.Pin.isActive = true;
_minPulseWidth = minPulseWidth;
_maxPulseWidth = maxPulseWidth;
return chan;
}
/**************************************************************************/
/*!
@brief Detaches the servo (ledc timer) and de-allocates a servo
object.
*/
/**************************************************************************/
void ws_ledc_servo::detach() {
// WS._ledc->detachPin(_servo.Pin.nbr);
_servo.Pin.isActive = false;
}
/**************************************************************************/
/*!
@brief Returns if the servo is attached to a ledc timer
@returns True if the servo is attached to a timer, False otherwise.
*/
/**************************************************************************/
bool ws_ledc_servo::attached() { return _servo.Pin.isActive; }
/**************************************************************************/
/*!
@brief Writes the pulse width to the connected servo pin.
@param value Desired pulse width, in microseconds.
*/
/**************************************************************************/
void ws_ledc_servo::writeMicroseconds(int value) {
// are we attached to a pin?
if (!attached()) {
// Serial.println("NOT ATTACHED TO PIN!");
return;
}
// out-of-bounds check, scale value
if (value < _minPulseWidth)
value = _minPulseWidth;
if (value > _maxPulseWidth)
value = _maxPulseWidth;
// formula from
// https://github.com/madhephaestus/ESP32Servo/blob/master/src/ESP32Servo.cpp
// count = (pulse_high_width / (pulse_period/2**timer_width))
// 50Hz servo = 20ms pulse_period
// count = pulse_high_width /((20000/65536))
uint32_t count = ((double)value / 0.30517578);
// WS._ledc->setDuty(_servo.Pin.nbr, count);
}

View file

@ -0,0 +1,68 @@
/*!
* @file ws_esp32_ledc.h
*
* Driver for ESP32 servo control using the WipperSnapper
* LEDC peripheral manager API.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
*
* Brent Rubell for Adafruit Industries 2022
*
*
* MIT license, all text here must be included in any redistribution.
*
*/
#ifndef WS_ESP32_SERVO
#define WS_ESP32_SERVO
//#include "Wippersnapper.h"
#include <Arduino.h>
// from https://github.com/arduino-libraries/Servo/blob/master/src/Servo.h
#define MIN_PULSE_WIDTH 544 ///< The shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2400 ///< The longest pulse sent to a servo
#define INVALID_SERVO 255 ///< Flag indicating an invalid servo index
#define DEFAULT_SERVO_FREQ 50 ///< default servo frequency
#define MAX_SERVOS MAX_LEDC_PWMS ///< Maximum number of servo instance
/** Defines a servo attached to a pin */
typedef struct {
uint8_t nbr; ///< Servo's pin number
uint8_t isActive; ///< True if the servo is enabled
} ServoPin_t;
/** Defines a ws_ledc_servo object */
typedef struct {
ServoPin_t Pin; ///< Servo properties
} servo_t;
/************************************************************************************************/
/*!
@brief High-level driver for servos for ESP32/ESP32-Sx/ESP32-Cx. This
driver implements a subset of the functions within the Arduino
servo library,
(https://github.com/arduino-libraries/Servo/blob/master/src/Servo.h).
*/
/************************************************************************************************/
class ws_ledc_servo {
public:
ws_ledc_servo();
~ws_ledc_servo();
// The functions below are compatible with
// https://github.com/arduino-libraries/Servo/blob/master/src/Servo.h
uint8_t attach(int pin, int minPulseWidth, int maxPulseWidth, int servoFreq);
bool attached();
void detach();
void writeMicroseconds(int value);
private:
servo_t _servo; ///< ws_ledc_servo object
int _minPulseWidth; ///< Servo's minimum pulse width, in uS.
int _maxPulseWidth; ///< Servo's maximum pulse width, in uS.
};
// extern Wippersnapper WS;
#endif // WS_ESP32_SERVO

View file

@ -0,0 +1,155 @@
/*!
* @file ws_ledc.cpp
*
* This is the documentation for WipperSnapper's LEDC peripheral
* management API. It is used by drivers like ledc_servo.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section author Author
*
* Written by Brent Rubell for Adafruit Industries, 2022.
*
* @section license License
*
* MIT license, all text here must be included in any redistribution.
*
*/
#include "ws_ledc.h"
WipperSnapper_Component_LEDC::WipperSnapper_Component_LEDC() {
// reset active pins
for (int i = 0; i < MAX_LEDC_PWMS; i++) {
_ledcPins[i].isActive = false;
}
}
WipperSnapper_Component_LEDC::~WipperSnapper_Component_LEDC() {
// detach all active pins and de-allocate them
for (int i = 0; i < MAX_LEDC_PWMS; i++) {
detachPin(_ledcPins[i].pin);
_ledcPins[i].isActive = false;
}
}
/**************************************************************************/
/*!
@brief Allocates a timer + channel for a pin and attaches it.
@param pin Desired GPIO pin number.
@param freq Desired timer frequency, in Hz.
@return The channel number if the pin was successfully attached,
otherwise 255.
*/
/**************************************************************************/
uint8_t WipperSnapper_Component_LEDC::attachPin(uint8_t pin, double freq) {
// have we already attached this pin?
for (int i = 0; i < MAX_LEDC_PWMS; i++) {
if (_ledcPins[i].pin == pin)
return 255;
}
// allocate chanel
uint8_t chanNum = _allocateChannel(freq);
if (chanNum == 255)
return chanNum;
// attach pin to channel
ledcAttachPin(pin, chanNum);
// allocate pin in pool
_ledcPins[chanNum].pin = pin;
return chanNum;
}
/**************************************************************************/
/*!
@brief Detaches a pin and de-allocates it from the manager.
@param pin Desired GPIO pin number.
*/
/**************************************************************************/
void WipperSnapper_Component_LEDC::detachPin(uint8_t pin) {
// find the channel corresponding to the pin
uint8_t chan;
for (int i = 0; i < sizeof(_ledcPins); i++) {
if (_ledcPins[i].pin == pin) {
chan = _ledcPins[i].chan;
break;
}
}
// detach the pin
ledcDetachPin(pin);
// de-allocate the pin and the channel
for (int i = 0; i < sizeof(_ledcPins); i++) {
if (_ledcPins[i].pin == pin) {
_ledcPins[i].pin = 0;
_ledcPins[i].chan = 255;
_ledcPins[i].isActive = false;
break;
}
}
}
/**************************************************************************/
/*!
@brief Allocates a channel and timer.
@param freq Desired timer frequency, in Hz.
@return The channel number if the timer was successfully initialized,
otherwise 255.
*/
/**************************************************************************/
uint8_t WipperSnapper_Component_LEDC::_allocateChannel(double freq) {
// attempt to allocate an inactive channel
uint8_t chanNum = 255;
for (int i = 0; i < MAX_LEDC_PWMS; i++) {
if (_ledcPins[i].isActive == false) {
chanNum = i;
break;
}
}
// did we fail to allocate?
if (chanNum == 255)
return 255;
// attempt to set up a ledc_timer on the free channel
double rc = ledcSetup(uint8_t(chanNum), freq, 16);
if (rc == 0)
return 255;
// Assign
_ledcPins[chanNum].chan = chanNum;
_ledcPins[chanNum].isActive = true;
return chanNum;
}
/**************************************************************************/
/*!
@brief Sets the duty cycle of a pin
@param pin Desired GPIO pin to write to.
@param freq Desired duty cycle.
*/
/**************************************************************************/
void WipperSnapper_Component_LEDC::setDuty(uint8_t pin, uint32_t duty) {
// find the channel corresponding to the pin
uint8_t chan;
for (int i = 0; i < sizeof(_ledcPins); i++) {
if (_ledcPins[i].pin == pin) {
chan = _ledcPins[i].chan;
break;
}
}
// set the channel's duty cycle
// debug...
// Serial.print("Writing duty cycle: ");
// Serial.print(duty);
// Serial.print("(%) to channel#: ");
// Serial.println(chan);
ledcWrite(chan, duty);
}

View file

@ -0,0 +1,64 @@
/*!
* @file ws_ledc.h
*
* High-level interface for ESP32's LED Control (LEDC) peripheral,
* to be used by PWM and Servo drivers.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Copyright (c) Brent Rubell 2022 for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
*
*/
#ifndef WIPPERSNAPPER_COMPONENT_LEDC_H
#define WIPPERSNAPPER_COMPONENT_LEDC_H
#include "Wippersnapper.h"
#include "esp32-hal-ledc.h"
#include "esp_err.h"
#define MAX_LEDC_PWMS \
16 ///< maximum # of LEDC channels (see: LEDC Chan to Group/Channel/Timer
///< Mapping)
#define LEDC_RESOLUTION 10 ///< max LEDC resolution
#define MAX_TIMER_WIDTH 20 ///< max LEDC esp32 timer width
/** Defines a pin attached to an active LEDC timer group */
typedef struct {
uint8_t pin; // GPIO pin number
uint8_t chan; // Channel allocated to the pin
bool isActive; // True if the ledcPin's timer has been initialized
} ledcPin_t;
// forward decl.
class Wippersnapper;
/**************************************************************************/
/*!
@brief High-level interface for the ESP32/ESP32-Sx/ESP32-Cx LED
Control (LEDC) peripheral. Instead of specifying a timer or
channel, this class automatically allocates a channel and
associates it with a pin. Underlying esp32-hal-ledc performs
timer management and handles the low-level LEDC peripheral API
calls.
*/
/**************************************************************************/
class WipperSnapper_Component_LEDC {
public:
WipperSnapper_Component_LEDC();
~WipperSnapper_Component_LEDC();
uint8_t attachPin(uint8_t pin, double freq); // high-level
void detachPin(uint8_t pin); // high-level
void setDuty(uint8_t pin, uint32_t duty);
private:
uint8_t _allocateChannel(double freq);
ledcPin_t _ledcPins[MAX_LEDC_PWMS]; ///< Pool of usable LEDC pins
};
extern Wippersnapper WS;
#endif // WIPPERSNAPPER_COMPONENT_LEDC_H

View file

@ -0,0 +1,101 @@
/*!
* @file ws_servo.cpp
*
* High-level servo manager interface for WipperSnapper.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section author Author
*
* Written by Brent Rubell for Adafruit Industries, 2022.
*
*
* @section license License
*
* MIT license, all text here must be included in any redistribution.
*
*/
#include "ws_servo.h"
/**************************************************************************/
/*!
@brief Constructor
*/
/**************************************************************************/
ws_servo::ws_servo() {
for (int i = 0; i < MAX_SERVO_NUM; i++) {
_servos[i].pin = 255;
_servos[i].servoObj = nullptr;
}
// TODO: create new instance of ws_ledc_servo for ESP32, pass LEDC object?
}
/**************************************************************************/
/*!
@brief Destructor
*/
/**************************************************************************/
ws_servo::~ws_servo() {
for (int i = 0; i < MAX_SERVO_NUM; i++) {
// de-allocate servo pins, if attached
if (_servos[i].servoObj->attached())
_servos[i].servoObj->detach();
}
}
/**************************************************************************/
/*!
@brief Attaches a servo object to a pin.
@param pin Desired GPIO pin.
@param minPulseWidth Minimum pulsewidth, in uS.
@param maxPulseWidth Maximum pulsewidth, in uS.
@param freq Servo Frequency, default is 50Hz
@returns True if a servo is successfully attached to a pin,
False otherwise
*/
/**************************************************************************/
bool ws_servo::servo_attach(int pin, int minPulseWidth, int maxPulseWidth,
int freq) {
// ESP32-specific
// TODO
// ws_esp32_servo *servo = new ws_esp32_servo();
// servo->setLEDCDriver(&ledcMgr);
// generalized
uint16_t rc;
// TODO
// rc = servo->attach(pin, minPulseWidth, maxPulseWidth, freq);
if (rc == 255)
return false; // allocation or pin error
// Attempt to allocate an unused servo
int servoIdx = -1;
for (int i = 0; i < MAX_SERVO_NUM; i++) {
// Serial.println(_servos[i].pin);
if (_servos[i].pin == 255) {
servoIdx = i;
// Serial.print("Servos IDX:");
// Serial.println(servoIdx);
break;
}
}
// check if allocated
if (servoIdx == 255) {
// Serial.println("ERROR: Maximum servos reached!");
return false;
}
// create a new servo component storage struct
// TODO: add back
// _servos[servoIdx].servoObj = servo;
_servos[servoIdx].pin = pin;
// call attach pin
// TODO: add back
// _servos[servoIdx].servoObj->attach(pin, minPulseWidth, maxPulseWidth,
// freq);
return true;
}

View file

@ -0,0 +1,50 @@
/*!
* @file ws_servo.h
*
* High-level interface for wippersnapper to manage servo objects
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
*
* Brent Rubell for Adafruit Industries 2022
*
*
* MIT license, all text here must be included in any redistribution.
*
*/
#ifndef WS_SERVO
#define WS_SERVO
#include "components/ledc/drivers/ws_ledc_servo.h"
#define MAX_SERVO_NUM 16 ///< Maximum # of servo objects
struct servoComponent {
ws_ledc_servo *servoObj; ///< Servo object
uint8_t pin; ///< Servo's pin number
};
// forward decl.
class Wippersnapper;
/**************************************************************************/
/*!
@brief Interface for WipperSnapper servo control
*/
/**************************************************************************/
class ws_servo {
public:
ws_servo();
~ws_servo();
// TODO: pin, min, max all get replaced by protobuf decoded values
bool servo_attach(int pin, int minPulseWidth, int maxPulseWidth, int freq);
// void servo_detach(int pin);
// void servo_write(int pin, int value);
private:
servoComponent _servos[MAX_SERVO_NUM]; ///< Container of servo objects and
///< their associated pin #s
};
extern Wippersnapper WS;
#endif // WS_SERVO

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */ /* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.6 at Thu Jun 9 14:18:28 2022. */ /* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#include "wippersnapper/description/v1/description.pb.h" #include "wippersnapper/description/v1/description.pb.h"
#if PB_PROTO_HEADER_VERSION != 40 #if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */ /* Automatically generated nanopb header */
/* Generated by nanopb-0.4.6 at Thu Jun 9 14:18:28 2022. */ /* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#ifndef PB_WIPPERSNAPPER_DESCRIPTION_V1_WIPPERSNAPPER_DESCRIPTION_V1_DESCRIPTION_PB_H_INCLUDED #ifndef PB_WIPPERSNAPPER_DESCRIPTION_V1_WIPPERSNAPPER_DESCRIPTION_V1_DESCRIPTION_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_DESCRIPTION_V1_WIPPERSNAPPER_DESCRIPTION_V1_DESCRIPTION_PB_H_INCLUDED #define PB_WIPPERSNAPPER_DESCRIPTION_V1_WIPPERSNAPPER_DESCRIPTION_V1_DESCRIPTION_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */ /* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.6 at Thu Jun 9 14:18:28 2022. */ /* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#include "wippersnapper/i2c/v1/i2c.pb.h" #include "wippersnapper/i2c/v1/i2c.pb.h"
#if PB_PROTO_HEADER_VERSION != 40 #if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */ /* Automatically generated nanopb header */
/* Generated by nanopb-0.4.6 at Thu Jun 9 14:18:28 2022. */ /* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#ifndef PB_WIPPERSNAPPER_I2C_V1_WIPPERSNAPPER_I2C_V1_I2C_PB_H_INCLUDED #ifndef PB_WIPPERSNAPPER_I2C_V1_WIPPERSNAPPER_I2C_V1_I2C_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_I2C_V1_WIPPERSNAPPER_I2C_V1_I2C_PB_H_INCLUDED #define PB_WIPPERSNAPPER_I2C_V1_WIPPERSNAPPER_I2C_V1_I2C_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */ /* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.6 at Thu Jun 9 14:18:28 2022. */ /* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#include "wippersnapper/pin/v1/pin.pb.h" #include "wippersnapper/pin/v1/pin.pb.h"
#if PB_PROTO_HEADER_VERSION != 40 #if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */ /* Automatically generated nanopb header */
/* Generated by nanopb-0.4.6 at Thu Jun 9 14:18:28 2022. */ /* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#ifndef PB_WIPPERSNAPPER_PIN_V1_WIPPERSNAPPER_PIN_V1_PIN_PB_H_INCLUDED #ifndef PB_WIPPERSNAPPER_PIN_V1_WIPPERSNAPPER_PIN_V1_PIN_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_PIN_V1_WIPPERSNAPPER_PIN_V1_PIN_PB_H_INCLUDED #define PB_WIPPERSNAPPER_PIN_V1_WIPPERSNAPPER_PIN_V1_PIN_PB_H_INCLUDED

View file

@ -0,0 +1,21 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#include "wippersnapper/servo/v1/servo.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(wippersnapper_servo_v1_ServoAttachReq, wippersnapper_servo_v1_ServoAttachReq, AUTO)
PB_BIND(wippersnapper_servo_v1_ServoAttachResp, wippersnapper_servo_v1_ServoAttachResp, AUTO)
PB_BIND(wippersnapper_servo_v1_ServoDetachReq, wippersnapper_servo_v1_ServoDetachReq, AUTO)
PB_BIND(wippersnapper_servo_v1_ServoWriteReq, wippersnapper_servo_v1_ServoWriteReq, AUTO)

View file

@ -0,0 +1,117 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#ifndef PB_WIPPERSNAPPER_SERVO_V1_WIPPERSNAPPER_SERVO_V1_SERVO_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_SERVO_V1_WIPPERSNAPPER_SERVO_V1_SERVO_PB_H_INCLUDED
#include <pb.h>
#include "nanopb/nanopb.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Struct definitions */
/* *
ServoAttachReq represents a request to attach a servo to a pin. */
typedef struct _wippersnapper_servo_v1_ServoAttachReq {
char servo_pin[6]; /* * The name of pin to attach a servo to. */
int32_t servo_freq; /* * The overall PWM frequency, default sent by Adafruit IO is 50Hz. * */
int32_t min_pulse_width; /* * The minimum pulse length in uS. Default sent by Adafruit IO is 500uS. * */
int32_t max_pulse_width; /* * The maximum pulse length in uS. Default sent by Adafruit IO is 2500uS. * */
} wippersnapper_servo_v1_ServoAttachReq;
/* *
ServoAttachResp represents the result of attaching a servo to a pin. */
typedef struct _wippersnapper_servo_v1_ServoAttachResp {
bool attach_success; /* * True if a servo was attached successfully, False otherwise. * */
} wippersnapper_servo_v1_ServoAttachResp;
/* *
ServoDetachReq represents request to detach a servo from a pin and de-initialize the pin for other uses. */
typedef struct _wippersnapper_servo_v1_ServoDetachReq {
char servo_pin[5]; /* * The name of pin to use as a servo pin. */
} wippersnapper_servo_v1_ServoDetachReq;
/* *
ServoWriteReq represents a message to write the servo's position.
NOTE: Position is sent from Adafruit IO as a pulse width in uS between 500uS
and 2500uS. The client application must convert pulse width to duty cycle w/fixed
freq of 50Hz prior to writing to the servo pin. */
typedef struct _wippersnapper_servo_v1_ServoWriteReq {
char servo_pin[5]; /* * The name of pin we're addressing. */
int32_t pulse_width; /* * The pulse width to write to the servo, in uS * */
} wippersnapper_servo_v1_ServoWriteReq;
#ifdef __cplusplus
extern "C" {
#endif
/* Initializer values for message structs */
#define wippersnapper_servo_v1_ServoAttachReq_init_default {"", 0, 0, 0}
#define wippersnapper_servo_v1_ServoAttachResp_init_default {0}
#define wippersnapper_servo_v1_ServoDetachReq_init_default {""}
#define wippersnapper_servo_v1_ServoWriteReq_init_default {"", 0}
#define wippersnapper_servo_v1_ServoAttachReq_init_zero {"", 0, 0, 0}
#define wippersnapper_servo_v1_ServoAttachResp_init_zero {0}
#define wippersnapper_servo_v1_ServoDetachReq_init_zero {""}
#define wippersnapper_servo_v1_ServoWriteReq_init_zero {"", 0}
/* Field tags (for use in manual encoding/decoding) */
#define wippersnapper_servo_v1_ServoAttachReq_servo_pin_tag 1
#define wippersnapper_servo_v1_ServoAttachReq_servo_freq_tag 2
#define wippersnapper_servo_v1_ServoAttachReq_min_pulse_width_tag 3
#define wippersnapper_servo_v1_ServoAttachReq_max_pulse_width_tag 4
#define wippersnapper_servo_v1_ServoAttachResp_attach_success_tag 1
#define wippersnapper_servo_v1_ServoDetachReq_servo_pin_tag 1
#define wippersnapper_servo_v1_ServoWriteReq_servo_pin_tag 1
#define wippersnapper_servo_v1_ServoWriteReq_pulse_width_tag 2
/* Struct field encoding specification for nanopb */
#define wippersnapper_servo_v1_ServoAttachReq_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, servo_pin, 1) \
X(a, STATIC, SINGULAR, INT32, servo_freq, 2) \
X(a, STATIC, SINGULAR, INT32, min_pulse_width, 3) \
X(a, STATIC, SINGULAR, INT32, max_pulse_width, 4)
#define wippersnapper_servo_v1_ServoAttachReq_CALLBACK NULL
#define wippersnapper_servo_v1_ServoAttachReq_DEFAULT NULL
#define wippersnapper_servo_v1_ServoAttachResp_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, attach_success, 1)
#define wippersnapper_servo_v1_ServoAttachResp_CALLBACK NULL
#define wippersnapper_servo_v1_ServoAttachResp_DEFAULT NULL
#define wippersnapper_servo_v1_ServoDetachReq_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, servo_pin, 1)
#define wippersnapper_servo_v1_ServoDetachReq_CALLBACK NULL
#define wippersnapper_servo_v1_ServoDetachReq_DEFAULT NULL
#define wippersnapper_servo_v1_ServoWriteReq_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, servo_pin, 1) \
X(a, STATIC, SINGULAR, INT32, pulse_width, 2)
#define wippersnapper_servo_v1_ServoWriteReq_CALLBACK NULL
#define wippersnapper_servo_v1_ServoWriteReq_DEFAULT NULL
extern const pb_msgdesc_t wippersnapper_servo_v1_ServoAttachReq_msg;
extern const pb_msgdesc_t wippersnapper_servo_v1_ServoAttachResp_msg;
extern const pb_msgdesc_t wippersnapper_servo_v1_ServoDetachReq_msg;
extern const pb_msgdesc_t wippersnapper_servo_v1_ServoWriteReq_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define wippersnapper_servo_v1_ServoAttachReq_fields &wippersnapper_servo_v1_ServoAttachReq_msg
#define wippersnapper_servo_v1_ServoAttachResp_fields &wippersnapper_servo_v1_ServoAttachResp_msg
#define wippersnapper_servo_v1_ServoDetachReq_fields &wippersnapper_servo_v1_ServoDetachReq_msg
#define wippersnapper_servo_v1_ServoWriteReq_fields &wippersnapper_servo_v1_ServoWriteReq_msg
/* Maximum encoded size of messages (where known) */
#define wippersnapper_servo_v1_ServoAttachReq_size 40
#define wippersnapper_servo_v1_ServoAttachResp_size 2
#define wippersnapper_servo_v1_ServoDetachReq_size 6
#define wippersnapper_servo_v1_ServoWriteReq_size 17
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */ /* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.6 at Thu Jun 9 14:18:28 2022. */ /* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#include "wippersnapper/signal/v1/signal.pb.h" #include "wippersnapper/signal/v1/signal.pb.h"
#if PB_PROTO_HEADER_VERSION != 40 #if PB_PROTO_HEADER_VERSION != 40
@ -12,6 +12,12 @@ PB_BIND(wippersnapper_signal_v1_I2CRequest, wippersnapper_signal_v1_I2CRequest,
PB_BIND(wippersnapper_signal_v1_I2CResponse, wippersnapper_signal_v1_I2CResponse, 2) PB_BIND(wippersnapper_signal_v1_I2CResponse, wippersnapper_signal_v1_I2CResponse, 2)
PB_BIND(wippersnapper_signal_v1_ServoRequest, wippersnapper_signal_v1_ServoRequest, AUTO)
PB_BIND(wippersnapper_signal_v1_ServoResp, wippersnapper_signal_v1_ServoResp, AUTO)
PB_BIND(wippersnapper_signal_v1_CreateSignalRequest, wippersnapper_signal_v1_CreateSignalRequest, AUTO) PB_BIND(wippersnapper_signal_v1_CreateSignalRequest, wippersnapper_signal_v1_CreateSignalRequest, AUTO)

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */ /* Automatically generated nanopb header */
/* Generated by nanopb-0.4.6 at Thu Jun 9 14:18:28 2022. */ /* Generated by nanopb-0.4.6 at Thu Jul 28 12:28:13 2022. */
#ifndef PB_WIPPERSNAPPER_SIGNAL_V1_WIPPERSNAPPER_SIGNAL_V1_SIGNAL_PB_H_INCLUDED #ifndef PB_WIPPERSNAPPER_SIGNAL_V1_WIPPERSNAPPER_SIGNAL_V1_SIGNAL_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_SIGNAL_V1_WIPPERSNAPPER_SIGNAL_V1_SIGNAL_PB_H_INCLUDED #define PB_WIPPERSNAPPER_SIGNAL_V1_WIPPERSNAPPER_SIGNAL_V1_SIGNAL_PB_H_INCLUDED
@ -7,6 +7,7 @@
#include "nanopb/nanopb.pb.h" #include "nanopb/nanopb.pb.h"
#include "wippersnapper/pin/v1/pin.pb.h" #include "wippersnapper/pin/v1/pin.pb.h"
#include "wippersnapper/i2c/v1/i2c.pb.h" #include "wippersnapper/i2c/v1/i2c.pb.h"
#include "wippersnapper/servo/v1/servo.pb.h"
#if PB_PROTO_HEADER_VERSION != 40 #if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator. #error Regenerate this file with the current version of nanopb generator.
@ -59,6 +60,28 @@ typedef struct _wippersnapper_signal_v1_I2CResponse {
} payload; } payload;
} wippersnapper_signal_v1_I2CResponse; } wippersnapper_signal_v1_I2CResponse;
/* *
ServoRequest represents the broker's request across the servo sub-topic. */
typedef struct _wippersnapper_signal_v1_ServoRequest {
pb_callback_t cb_payload;
pb_size_t which_payload;
union {
wippersnapper_servo_v1_ServoAttachReq servo_attach;
wippersnapper_servo_v1_ServoDetachReq servo_detach;
wippersnapper_servo_v1_ServoWriteReq servo_write;
} payload;
} wippersnapper_signal_v1_ServoRequest;
/* *
ServoResp represents the device's response across the servo sub-topic. */
typedef struct _wippersnapper_signal_v1_ServoResp {
pb_callback_t cb_payload;
pb_size_t which_payload;
union {
wippersnapper_servo_v1_ServoAttachResp servo_attach_resp;
} payload;
} wippersnapper_signal_v1_ServoResp;
/* * /* *
Response from a signal message payload (device->broker) */ Response from a signal message payload (device->broker) */
typedef struct _wippersnapper_signal_v1_SignalResponse { typedef struct _wippersnapper_signal_v1_SignalResponse {
@ -76,10 +99,14 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define wippersnapper_signal_v1_I2CRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanRequest_init_default}} #define wippersnapper_signal_v1_I2CRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanRequest_init_default}}
#define wippersnapper_signal_v1_I2CResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanResponse_init_default}} #define wippersnapper_signal_v1_I2CResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanResponse_init_default}}
#define wippersnapper_signal_v1_ServoRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_servo_v1_ServoAttachReq_init_default}}
#define wippersnapper_signal_v1_ServoResp_init_default {{{NULL}, NULL}, 0, {wippersnapper_servo_v1_ServoAttachResp_init_default}}
#define wippersnapper_signal_v1_CreateSignalRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_pin_v1_ConfigurePinRequests_init_default}} #define wippersnapper_signal_v1_CreateSignalRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_pin_v1_ConfigurePinRequests_init_default}}
#define wippersnapper_signal_v1_SignalResponse_init_default {0, {0}} #define wippersnapper_signal_v1_SignalResponse_init_default {0, {0}}
#define wippersnapper_signal_v1_I2CRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanRequest_init_zero}} #define wippersnapper_signal_v1_I2CRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanRequest_init_zero}}
#define wippersnapper_signal_v1_I2CResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanResponse_init_zero}} #define wippersnapper_signal_v1_I2CResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanResponse_init_zero}}
#define wippersnapper_signal_v1_ServoRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_servo_v1_ServoAttachReq_init_zero}}
#define wippersnapper_signal_v1_ServoResp_init_zero {{{NULL}, NULL}, 0, {wippersnapper_servo_v1_ServoAttachResp_init_zero}}
#define wippersnapper_signal_v1_CreateSignalRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pin_v1_ConfigurePinRequests_init_zero}} #define wippersnapper_signal_v1_CreateSignalRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pin_v1_ConfigurePinRequests_init_zero}}
#define wippersnapper_signal_v1_SignalResponse_init_zero {0, {0}} #define wippersnapper_signal_v1_SignalResponse_init_zero {0, {0}}
@ -100,6 +127,10 @@ extern "C" {
#define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_deinit_tag 4 #define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_deinit_tag 4
#define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_update_tag 5 #define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_update_tag 5
#define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_event_tag 6 #define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_event_tag 6
#define wippersnapper_signal_v1_ServoRequest_servo_attach_tag 1
#define wippersnapper_signal_v1_ServoRequest_servo_detach_tag 2
#define wippersnapper_signal_v1_ServoRequest_servo_write_tag 3
#define wippersnapper_signal_v1_ServoResp_servo_attach_resp_tag 1
#define wippersnapper_signal_v1_SignalResponse_configuration_complete_tag 1 #define wippersnapper_signal_v1_SignalResponse_configuration_complete_tag 1
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
@ -133,6 +164,22 @@ X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_i2c_device_event,payload.resp_i
#define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_device_update_MSGTYPE wippersnapper_i2c_v1_I2CDeviceUpdateResponse #define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_device_update_MSGTYPE wippersnapper_i2c_v1_I2CDeviceUpdateResponse
#define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_device_event_MSGTYPE wippersnapper_i2c_v1_I2CDeviceEvent #define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_device_event_MSGTYPE wippersnapper_i2c_v1_I2CDeviceEvent
#define wippersnapper_signal_v1_ServoRequest_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_attach,payload.servo_attach), 1) \
X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_detach,payload.servo_detach), 2) \
X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_write,payload.servo_write), 3)
#define wippersnapper_signal_v1_ServoRequest_CALLBACK NULL
#define wippersnapper_signal_v1_ServoRequest_DEFAULT NULL
#define wippersnapper_signal_v1_ServoRequest_payload_servo_attach_MSGTYPE wippersnapper_servo_v1_ServoAttachReq
#define wippersnapper_signal_v1_ServoRequest_payload_servo_detach_MSGTYPE wippersnapper_servo_v1_ServoDetachReq
#define wippersnapper_signal_v1_ServoRequest_payload_servo_write_MSGTYPE wippersnapper_servo_v1_ServoWriteReq
#define wippersnapper_signal_v1_ServoResp_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_attach_resp,payload.servo_attach_resp), 1)
#define wippersnapper_signal_v1_ServoResp_CALLBACK NULL
#define wippersnapper_signal_v1_ServoResp_DEFAULT NULL
#define wippersnapper_signal_v1_ServoResp_payload_servo_attach_resp_MSGTYPE wippersnapper_servo_v1_ServoAttachResp
#define wippersnapper_signal_v1_CreateSignalRequest_FIELDLIST(X, a) \ #define wippersnapper_signal_v1_CreateSignalRequest_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MSG_W_CB, (payload,pin_configs,payload.pin_configs), 6) \ X(a, STATIC, ONEOF, MSG_W_CB, (payload,pin_configs,payload.pin_configs), 6) \
X(a, STATIC, ONEOF, MSG_W_CB, (payload,pin_events,payload.pin_events), 7) \ X(a, STATIC, ONEOF, MSG_W_CB, (payload,pin_events,payload.pin_events), 7) \
@ -154,12 +201,16 @@ X(a, STATIC, ONEOF, BOOL, (payload,configuration_complete,payload.confi
extern const pb_msgdesc_t wippersnapper_signal_v1_I2CRequest_msg; extern const pb_msgdesc_t wippersnapper_signal_v1_I2CRequest_msg;
extern const pb_msgdesc_t wippersnapper_signal_v1_I2CResponse_msg; extern const pb_msgdesc_t wippersnapper_signal_v1_I2CResponse_msg;
extern const pb_msgdesc_t wippersnapper_signal_v1_ServoRequest_msg;
extern const pb_msgdesc_t wippersnapper_signal_v1_ServoResp_msg;
extern const pb_msgdesc_t wippersnapper_signal_v1_CreateSignalRequest_msg; extern const pb_msgdesc_t wippersnapper_signal_v1_CreateSignalRequest_msg;
extern const pb_msgdesc_t wippersnapper_signal_v1_SignalResponse_msg; extern const pb_msgdesc_t wippersnapper_signal_v1_SignalResponse_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ /* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define wippersnapper_signal_v1_I2CRequest_fields &wippersnapper_signal_v1_I2CRequest_msg #define wippersnapper_signal_v1_I2CRequest_fields &wippersnapper_signal_v1_I2CRequest_msg
#define wippersnapper_signal_v1_I2CResponse_fields &wippersnapper_signal_v1_I2CResponse_msg #define wippersnapper_signal_v1_I2CResponse_fields &wippersnapper_signal_v1_I2CResponse_msg
#define wippersnapper_signal_v1_ServoRequest_fields &wippersnapper_signal_v1_ServoRequest_msg
#define wippersnapper_signal_v1_ServoResp_fields &wippersnapper_signal_v1_ServoResp_msg
#define wippersnapper_signal_v1_CreateSignalRequest_fields &wippersnapper_signal_v1_CreateSignalRequest_msg #define wippersnapper_signal_v1_CreateSignalRequest_fields &wippersnapper_signal_v1_CreateSignalRequest_msg
#define wippersnapper_signal_v1_SignalResponse_fields &wippersnapper_signal_v1_SignalResponse_msg #define wippersnapper_signal_v1_SignalResponse_fields &wippersnapper_signal_v1_SignalResponse_msg
@ -174,6 +225,8 @@ union wippersnapper_signal_v1_CreateSignalRequest_payload_size_union {char f6[(6
#define wippersnapper_signal_v1_I2CRequest_size (0 + sizeof(union wippersnapper_signal_v1_I2CRequest_payload_size_union)) #define wippersnapper_signal_v1_I2CRequest_size (0 + sizeof(union wippersnapper_signal_v1_I2CRequest_payload_size_union))
#endif #endif
#define wippersnapper_signal_v1_I2CResponse_size 725 #define wippersnapper_signal_v1_I2CResponse_size 725
#define wippersnapper_signal_v1_ServoRequest_size 42
#define wippersnapper_signal_v1_ServoResp_size 4
#define wippersnapper_signal_v1_SignalResponse_size 2 #define wippersnapper_signal_v1_SignalResponse_size 2
#if defined(wippersnapper_pin_v1_ConfigurePinRequests_size) && defined(wippersnapper_pin_v1_PinEvents_size) && defined(wippersnapper_pin_v1_ConfigurePWMPinRequests_size) && defined(wippersnapper_pin_v1_PWMPinEvents_size) #if defined(wippersnapper_pin_v1_ConfigurePinRequests_size) && defined(wippersnapper_pin_v1_PinEvents_size) && defined(wippersnapper_pin_v1_ConfigurePWMPinRequests_size) && defined(wippersnapper_pin_v1_PWMPinEvents_size)
#define wippersnapper_signal_v1_CreateSignalRequest_size (0 + sizeof(union wippersnapper_signal_v1_CreateSignalRequest_payload_size_union)) #define wippersnapper_signal_v1_CreateSignalRequest_size (0 + sizeof(union wippersnapper_signal_v1_CreateSignalRequest_payload_size_union))