mservo-device

prplkn/mservo/mservo-device

No description
mservo-device
@/mservo-device
PORTport
The Multiservo shield port (0-17) the servo is connected to
Pminnumber
The minimal rated pulse width (in µS)
Pmaxnumber
The maximal rated pulse width (in µS)
mservo-device
DEV
PORT
Pmin
Pmax
DEV@/mservo-device
The servo device
To use the node in your project you should have the prplkn/mservo library installed. Use the “File → Add Library” menu item in XOD IDE if you don’t have it yet. See Using libraries for more info.

C++ implementation

#pragma XOD require "https://github.com/prplkn/Multiservo/"

#include <Wire.h>
#include <Multiservo.h>

node {
    meta {
        /*
        A wrapper around the stock Servo object because we need to keep some details
        which the original object hides in private fields. This over-protection leads
        to increased RAM usage to duplicate the data. A pull request to the original
        library asking to add field read methods would be nice.
        */
        class XServo : public Multiservo {
          protected:
            // Here are the duplicates
            uint8_t port;
            int pulseMin;
            int pulseMax;

          public:
            // Set pulse duration according the given `value` and set pulseMin, pulseMax
            // The value is clipped to the [0; 1] range
            void write01(Number value) {
                ensureAttached();
                int pseudoAngle = constrain((int)(value * 180), 0, 180);
                this->write(pseudoAngle);
            }

            // Performs Servo::attach with the parameters set previously
            void ensureAttached() {
                if (this->attached())
                    return;

                this->attach(port, pulseMin, pulseMax);
            }

            Number read01() {
                int us = this->readMicroseconds();
                return (Number)(us - pulseMin) / (Number)(pulseMax - pulseMin);
            }

            void reattach(uint8_t port, int pulseMin, int pulseMax) {
                this->port = port;
                this->pulseMin = pulseMin;
                this->pulseMax = pulseMax;
                if (this->attached())
                    this->attach(port, pulseMin, pulseMax);
            }
        };

        using Type = XServo*;
    }

    XServo mservo;

    void evaluate(Context ctx) {
        static_assert(isValidDigitalPort(constant_input_PORT), "must be a valid digital port");

        mservo.reattach(
            constant_input_PORT,
            getValue<input_Pmin>(ctx),
            getValue<input_Pmax>(ctx)
        );

        emitValue<output_DEV>(ctx, &mservo);
    }
}