It’s a servo, innit!
import Thing from '../../../src/lib/thing'
import Serializers from '../../../src/lib/osapjs/utils/serializers'
export default class servo extends Thing {
// calibrated-angle-bounds,
private pulseBounds = [500, 2500] // pulse-width bounds
private angleBounds = [0, 180] // angular bounds
async setRGB(r, g, b) {
let datagram = new Uint8Array(3);
datagram[0] = r * 255;
datagram[1] = g * 255;
datagram[2] = b * 255;
await this.send("setRGB", datagram);
}
async setLED(state) {
let datagram = new Uint8Array([state > 0]);
await this.send("setLED", datagram);
}
async writeMicroseconds(us: number){
try {
us = Math.round(us);
console.log(us)
let datagram = new Uint8Array(2);
Serializers.writeUint16(datagram, 0, us);
await this.send("writeMicroseconds", datagram);
} catch (err) {
throw err
}
}
async writeAngle(angle: number){
try {
// constrain to as-specified bounds,
if (angle < this.angleBounds[0]) angle = this.angleBounds[0]
if (angle > this.angleBounds[1]) angle = this.angleBounds[1]
// interpolate with microseconds-bounds match,
let interp = (angle - this.angleBounds[0]) / (this.angleBounds[1] - this.angleBounds[0])
interp = interp * (this.pulseBounds[1] - this.pulseBounds[0]) + this.pulseBounds[0]
// and sendy
await this.writeMicroseconds(interp)
} catch (err) {
throw err
}
}
setCalibration(_pulseBounds, _angleBounds){
if (!Array.isArray(_pulseBounds) || !Array.isArray(_angleBounds)) {
throw new Error(`input args for setCalibration are both arrays`)
}
this.pulseBounds = _pulseBounds
this.angleBounds = _angleBounds
}
public api = [
{
name: "writeMicroseconds",
args: [
"us: 0 to 2^16"
]
},
{
name: "writeAngle",
args: [
"angle: num"
]
},
{
name: "setCalibration",
args: [
"pulseBounds: [minMicros, maxMicros]",
"angleBounds: [minAngle, maxAngle]"
]
}
]
}
#include <osap.h>
#include <Servo.h>
#define PIN_SERVO 29
Servo servo;
OSAP_Runtime osap;
OSAP_Gateway_USBSerial serLink(&Serial);
OSAP_Port_DeviceNames namePort("servo");
uint8_t rgb[3] = {0, 0, 255};
boolean ledState = false;
void writeMicroseconds(uint8_t* data, size_t len) {
uint16_t pulse_us = data[1] * 256 + data[0];
servo.writeMicroseconds(pulse_us);
}
void updateRGB() {
if (ledState) {
analogWrite(PIN_LED_R, 255-rgb[0]);
analogWrite(PIN_LED_G, 255-rgb[1]);
analogWrite(PIN_LED_B, 255-rgb[2]);
} else {
analogWrite(PIN_LED_R, 255);
analogWrite(PIN_LED_G, 255);
analogWrite(PIN_LED_B, 255);
}
}
void onRGBPacket(uint8_t* data, size_t len){
rgb[0] = data[0];
rgb[1] = data[1];
rgb[2] = data[2];
ledState = true;
updateRGB();
}
void onLEDPacket(uint8_t* data, size_t len){
ledState = data[0] > 0;
updateRGB();
}
OSAP_Port_Named setRGB("setRGB", onRGBPacket);
OSAP_Port_Named setLED("setLED", onLEDPacket);
OSAP_Port_Named writeMicroseconds_port("writeMicroseconds", writeMicroseconds);
void setup() {
osap.begin();
analogWriteResolution(8);
pinMode(PIN_LED_R, OUTPUT);
pinMode(PIN_LED_G, OUTPUT);
pinMode(PIN_LED_B, OUTPUT);
updateRGB();
servo.attach(PIN_SERVO, 500, 2500);
}
void loop() {
osap.loop();
}