Servo library support (#1343)

* ateempt at bringin servos

* basic plumbing

* avoid math map duplicate

* missing parts annontation

* pretify parts

* extend appcompat layer

* updated strings

* more compat layer

* annotations

* don't rely on webmidi

* updated pxt ref

* bump pxt

* adding whenUsed

* updated v1 readme

* more pins

* more pins

* compress the parts definition

* update common packages
This commit is contained in:
Peli de Halleux 2018-10-05 11:09:08 -07:00 committed by GitHub
parent fd954ed6f8
commit 9002edbb22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 333 additions and 43 deletions

View File

@ -31,30 +31,38 @@ npm install
npm run build
cd ..
```
5. Clone the `v1` branch of this repository.
5. Clone the pxt-common-packages repository
```
git clone https://github.com/microsoft/pxt-common-packages
cd pxt-common-packages
npm install
cd ..
```
6. Clone the `v1` branch of this repository.
```
git clone https://github.com/microsoft/pxt-microbit --branch v1
cd pxt-microbit
```
6. Install the PXT command line (add `sudo` for Mac/Linux shells).
7. Install the PXT command line (add `sudo` for Mac/Linux shells).
```
npm install -g pxt
```
7. Install the pxt-microbit dependencies.
8. Install the pxt-microbit dependencies.
```
npm install
```
8. Link pxt-microbit back to base pxt repo (add `sudo` for Mac/Linux shells).
```
npm link ../pxt
npm link ../pxt-common-packages
```
Note the above command assumes the folder structure of
```
makecode
|
-----------------
| |
pxt pxt-microbit
----------------------------------
| | |
pxt pxt-common-packages pxt-microbit
```
### Running
@ -73,17 +81,13 @@ pxt serve --localbuild
### Updates
To update your PXT version and make sure you're running the latest tools, run:
```
pxt update
```
More instructions are at https://github.com/Microsoft/pxt#running-a-target-from-localhost
Make sure to pull changes from all repos regularly. More instructions are at https://github.com/Microsoft/pxt#running-a-target-from-localhost
## Repos
The pxt-microbit target depends on several other repos. The main ones are:
- https://github.com/Microsoft/pxt, the PXT framework
- https://github.com/Microsoft/pxt-commmon-packages, common APIs accross various MakeCode editors
- https://github.com/lancaster-university/microbit, basic wrapper around the DAL
- https://github.com/lancaster-university/microbit-dal

BIN
docs/static/libs/servo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -109,20 +109,31 @@
"Math.atan|param|x": "A number",
"Math.ceil": "Returns the smallest number greater than or equal to its numeric argument.",
"Math.ceil|param|x": "A numeric expression.",
"Math.constrain": "Constrains a number to be within a range",
"Math.cos": "Returns the cosine of a number.",
"Math.cos|param|x": "An angle in radians",
"Math.exp": "Returns returns ``e^x``.",
"Math.exp|param|x": "A number",
"Math.floor": "Returns the greatest number less than or equal to its numeric argument.",
"Math.floor|param|x": "A numeric expression.",
"Math.icos": "Returns the cosine of an input angle. This is an 8-bit approximation.",
"Math.icos|param|theta": "input angle from 0-255",
"Math.idiv": "Returns the value of integer signed 32 bit division of two numbers.",
"Math.idiv|param|x": "The first number",
"Math.idiv|param|y": "The second number",
"Math.imul": "Returns the value of integer signed 32 bit multiplication of two numbers.",
"Math.imul|param|x": "The first number",
"Math.imul|param|y": "The second number",
"Math.isin": "Returns the sine of an input angle. This is an 8-bit approximation.",
"Math.isin|param|theta": "input angle from 0-255",
"Math.log": "Returns the natural logarithm (base e) of a number.",
"Math.log|param|x": "A number",
"Math.map": "Re-maps a number from one range to another. That is, a value of ``from low`` would get mapped to ``to low``, a value of ``from high`` to ``to high``, values in-between to values in-between, etc.",
"Math.map|param|fromHigh": "the upper bound of the value's current range, eg: 1023",
"Math.map|param|fromLow": "the lower bound of the value's current range",
"Math.map|param|toHigh": "the upper bound of the value's target range, eg: 4",
"Math.map|param|toLow": "the lower bound of the value's target range",
"Math.map|param|value": "value to map in ranges",
"Math.max": "Returns the larger of two supplied numeric expressions.",
"Math.min": "Returns the smaller of two supplied numeric expressions.",
"Math.pow": "Returns the value of a base expression taken to a specified power.",
@ -402,6 +413,25 @@
"parseFloat": "Convert a string to a number.",
"parseInt": "Convert a string to an integer.",
"pins": "Control currents in Pins for analog/digital signals, servos, i2c, ...",
"pins.P0": "Pin P0",
"pins.P1": "Pin P1",
"pins.P10": "Pin P10",
"pins.P11": "Pin P3",
"pins.P12": "Pin P12",
"pins.P13": "Pin P13",
"pins.P14": "Pin P14",
"pins.P15": "Pin P15",
"pins.P16": "Pin P16",
"pins.P19": "Pin P19",
"pins.P2": "Pin P2",
"pins.P20": "Pin P19",
"pins.P3": "Pin P3",
"pins.P4": "Pin P4",
"pins.P5": "Pin P5",
"pins.P6": "Pin P6",
"pins.P7": "Pin P7",
"pins.P8": "Pin P8",
"pins.P9": "Pin P9",
"pins.analogPitch": "Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.",
"pins.analogPitch|param|frequency": "frequency to modulate in Hz.",
"pins.analogPitch|param|ms": "duration of the pitch in milli seconds.",

View File

@ -143,6 +143,8 @@
"LedSpriteProperty.Direction|block": "direction",
"LedSpriteProperty.X|block": "x",
"LedSpriteProperty.Y|block": "y",
"Math.constrain|block": "constrain %value|between %low|and %high",
"Math.map|block": "map %value|from low %fromLow|high %fromHigh|to low %toLow|high %toHigh",
"Math.randomBoolean|block": "pick random true or false",
"Math.randomRange|block": "pick random %min|to %limit",
"Math|block": "Math",
@ -208,6 +210,10 @@
"Note.GSharp4|block": "G#4",
"Note.GSharp5|block": "G#5",
"Note.GSharp|block": "G#",
"PinEvent.Fall|block": "fall",
"PinEvent.PulseHigh|block": "pulse high",
"PinEvent.PulseLow|block": "pulse low",
"PinEvent.Rise|block": "rise",
"PinEventType.Edge|block": "edge",
"PinEventType.None|block": "none",
"PinEventType.Pulse|block": "pulse",
@ -349,6 +355,8 @@
"serial.writeString|block": "serial|write string %text",
"serial.writeValue|block": "serial|write value %name|= %value",
"serial|block": "serial",
"{id:category}AnalogInPin": "AnalogInPin",
"{id:category}AnalogOutPin": "AnalogOutPin",
"{id:category}Array": "Array",
"{id:category}Arrays": "Arrays",
"{id:category}Basic": "Basic",
@ -356,6 +364,7 @@
"{id:category}Buffer": "Buffer",
"{id:category}Console": "Console",
"{id:category}Control": "Control",
"{id:category}DigitalInOutPin": "DigitalInOutPin",
"{id:category}Game": "Game",
"{id:category}Helpers": "Helpers",
"{id:category}Image": "Image",
@ -363,9 +372,11 @@
"{id:category}Input": "Input",
"{id:category}Led": "Led",
"{id:category}Math": "Math",
"{id:category}MicrobitPin": "MicrobitPin",
"{id:category}Music": "Music",
"{id:category}Number": "Number",
"{id:category}Pins": "Pins",
"{id:category}PwmOnlyPin": "PwmOnlyPin",
"{id:category}Serial": "Serial",
"{id:category}String": "String",
"{id:category}Text": "Text"

View File

@ -1,16 +0,0 @@
namespace Math {
export const E = 2.718281828459045;
export const LN2 = 0.6931471805599453;
export const LN10 = 2.302585092994046;
export const LOG2E = 1.4426950408889634;
export const LOG10E = 0.4342944819032518;
export const PI = 3.141592653589793;
export const SQRT1_2 = 0.7071067811865476;
export const SQRT2 = 1.4142135623730951;
}
namespace Number {
export const EPSILON = 2.220446049250313e-16;
}

View File

@ -13,7 +13,7 @@ namespace pins {
* @param toHigh the upper bound of the value's target range, eg: 4
*/
//% help=pins/map weight=23
//% blockId=math_map block="map %value|from low %fromLow|from high %fromHigh|to low %toLow|to high %toHigh"
//% blockId=pin_map block="map %value|from low %fromLow|from high %fromHigh|to low %toLow|to high %toHigh"
export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number {
return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow;
}

231
libs/core/pinscompat.ts Normal file
View File

@ -0,0 +1,231 @@
const enum PinEvent {
//% block="pulse high"
PulseHigh = DAL.MICROBIT_PIN_EVT_PULSE_HI, // DEVICE_PIN_EVT_PULSE_HI
//% block="pulse low"
PulseLow = DAL.MICROBIT_PIN_EVT_PULSE_LO, // DEVICE_PIN_EVT_PULSE_LO
//% block="rise"
Rise = DAL.MICROBIT_PIN_EVT_RISE, // DEVICE_PIN_EVT_RISE
//% block="fall"
Fall = DAL.MICROBIT_PIN_EVT_FALL, // DEVICE_PIN_EVT_FALL
}
//% noRefCounting fixedInstances
interface DigitalInOutPin {
digitalRead(): boolean;
digitalWrite(value: boolean): void;
onPulsed(pulse: PulseValue, body: () => void): void;
onEvent(event: PinEvent, body: () => void): void;
pulseIn(value: PulseValue, maxDuration?: number): number;
setPull(pull: PinPullMode): void;
}
//% noRefCounting fixedInstances
interface AnalogInPin extends DigitalInOutPin {
analogRead(): number;
}
//% noRefCounting fixedInstances
interface AnalogOutPin extends DigitalInOutPin {
analogWrite(value: number): void;
}
//% noRefCounting fixedInstances
interface AnalogInOutPin extends AnalogInPin, AnalogOutPin {
}
//% noRefCounting fixedInstances
interface PwmOnlyPin extends DigitalInOutPin, AnalogOutPin {
//% parts=microservo trackArgs=0
analogSetPeriod(period: number): void;
//% parts=microservo trackArgs=0
servoWrite(value: number): void;
//% parts=microservo trackArgs=0
servoSetPulse(duration: number): void;
}
//% noRefCounting fixedInstances
interface PwmPin extends PwmOnlyPin, DigitalInOutPin, AnalogInPin {
}
//% noRefCounting fixedInstances
class MicrobitPin implements AnalogInPin, AnalogOutPin, AnalogInOutPin, PwmOnlyPin {
public id: number;
constructor(id: number) {
this.id = id;
}
protected digitalId(): DigitalPin {
return <DigitalPin>this.id;
}
protected analogId(): AnalogPin {
return <AnalogPin>this.id;
}
digitalRead(): boolean {
return pins.digitalReadPin(this.digitalId()) != 0;
}
digitalWrite(value: boolean): void {
pins.digitalWritePin(this.digitalId(), value ? 1 : 0);
}
onPulsed(pulse: PulseValue, body: () => void): void {
pins.onPulsed(this.digitalId(), pulse, body);
}
onEvent(event: PinEvent, body: () => void): void {
// TODO
}
pulseIn(value: PulseValue, maxDuration?: number): number {
return pins.pulseIn(this.digitalId(), value, maxDuration);
}
setPull(pull: PinPullMode): void {
pins.setPull(this.digitalId(), pull);
}
analogRead(): number {
return pins.analogReadPin(this.analogId());
}
analogWrite(value: number): void {
pins.analogWritePin(this.analogId(), value);
}
analogSetPeriod(period: number): void {
pins.analogSetPeriod(this.analogId(), period);
}
servoWrite(value: number): void {
pins.servoWritePin(this.analogId(), value);
}
servoSetPulse(duration: number): void {
pins.servoSetPulse(this.analogId(), duration);
}
}
namespace pins {
/**
* Pin P0
*/
//% fixedInstance whenUsed
export const P0: PwmPin = new MicrobitPin(DigitalPin.P0);
/**
* Pin P1
*/
//% fixedInstance whenUsed
export const P1: PwmPin = new MicrobitPin(DigitalPin.P1);
/**
* Pin P2
*/
//% fixedInstance whenUsed
export const P2: PwmPin = new MicrobitPin(DigitalPin.P2);
/**
* Pin P3
*/
//% fixedInstance whenUsed
export const P3: AnalogInPin = new MicrobitPin(DigitalPin.P3);
/**
* Pin P4
*/
//% fixedInstance whenUsed
export const P4: AnalogInPin = new MicrobitPin(DigitalPin.P4);
/**
* Pin P5
*/
//% fixedInstance whenUsed
export const P5: DigitalInOutPin = new MicrobitPin(DigitalPin.P5);
/**
* Pin P6
*/
//% fixedInstance whenUsed
export const P6: DigitalInOutPin = new MicrobitPin(DigitalPin.P6);
/**
* Pin P7
*/
//% fixedInstance whenUsed
export const P7: DigitalInOutPin = new MicrobitPin(DigitalPin.P7);
/**
* Pin P8
*/
//% fixedInstance whenUsed
export const P8: DigitalInOutPin = new MicrobitPin(DigitalPin.P8);
/**
* Pin P9
*/
//% fixedInstance whenUsed
export const P9: DigitalInOutPin = new MicrobitPin(DigitalPin.P9);
/**
* Pin P10
*/
//% fixedInstance whenUsed
export const P10: AnalogInPin = new MicrobitPin(DigitalPin.P10);
/**
* Pin P3
*/
//% fixedInstance whenUsed
export const P11: DigitalInOutPin = new MicrobitPin(DigitalPin.P11);
/**
* Pin P12
*/
//% fixedInstance whenUsed
export const P12: DigitalInOutPin = new MicrobitPin(DigitalPin.P12);
/**
* Pin P13
*/
//% fixedInstance whenUsed
export const P13: DigitalInOutPin = new MicrobitPin(DigitalPin.P13);
/**
* Pin P14
*/
//% fixedInstance whenUsed
export const P14: DigitalInOutPin = new MicrobitPin(DigitalPin.P14);
/**
* Pin P15
*/
//% fixedInstance whenUsed
export const P15: DigitalInOutPin = new MicrobitPin(DigitalPin.P15);
/**
* Pin P16
*/
//% fixedInstance whenUsed
export const P16: DigitalInOutPin = new MicrobitPin(DigitalPin.P16);
/**
* Pin P19
*/
//% fixedInstance whenUsed
export const P19: DigitalInOutPin = new MicrobitPin(DigitalPin.P19);
/**
* Pin P19
*/
//% fixedInstance whenUsed
export const P20: DigitalInOutPin = new MicrobitPin(DigitalPin.P20);
}

View File

@ -13,10 +13,11 @@
"dal.d.ts",
"enums.d.ts",
"shims.d.ts",
"pxt-core.d.ts",
"pxt-core.d.ts",
"core.cpp",
"pxt-helpers.ts",
"helpers.ts",
"pinscompat.ts",
"codal.cpp",
"images.cpp",
"basic.cpp",

View File

@ -111,16 +111,18 @@
"orientation": "+Z"
}
],
"instantiation": {
"kind": "function",
"fullyQualifiedName": "pins.servoWritePin",
"argumentRoles": [
{
"pinInstantiationIdx": 0,
"partParameter": "name"
}
]
},
"instantiations": [
{
"kind": "function",
"fullyQualifiedName": "pins.servoWritePin,pins.servoSetPulse,PwmOnlyPin.servoWrite,PwmOnlyPin.servoSetPulse,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse",
"argumentRoles": [
{
"pinInstantiationIdx": 0,
"partParameter": "name"
}
]
}
],
"assembly": [
{
"part": true,

View File

@ -0,0 +1,5 @@
{
"servos.Servo.run": "Set the throttle on a continuous servo",
"servos.Servo.run|param|speed": "the throttle of the motor from -100% to 100%",
"servos.Servo.setAngle": "set the servo angle"
}

View File

@ -0,0 +1,10 @@
{
"servos.P0|block": "servo P0",
"servos.P1|block": "servo P1",
"servos.P2|block": "servo P2",
"servos.Servo.run|block": "continuous %servo run at %speed=speedPicker \\%",
"servos.Servo.setAngle|block": "set %servo angle to %degrees=protractorPicker °",
"servos.Servo.setPulse|block": "set %servo pulse to %micros μs",
"{id:category}Servos": "Servos",
"{id:group}Servos": "Servos"
}

3
libs/servo/pxt.json Normal file
View File

@ -0,0 +1,3 @@
{
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/servo"
}

View File

@ -0,0 +1,8 @@
namespace servos {
//% block="servo P0" fixedInstance whenUsed
export const P0 = new servos.PinServo(pins.P0);
//% block="servo P1" fixedInstance whenUsed
export const P1 = new servos.PinServo(pins.P1);
//% block="servo P2" fixedInstance whenUsed
export const P2 = new servos.PinServo(pins.P2);
}

View File

@ -41,7 +41,7 @@
"@types/node": "8.0.53"
},
"dependencies": {
"pxt-common-packages": "0.23.57",
"pxt-core": "4.1.17"
"pxt-common-packages": "0.24.2",
"pxt-core": "4.1.18"
}
}

View File

@ -9,7 +9,8 @@
"libs/core",
"libs/radio",
"libs/devices",
"libs/bluetooth"
"libs/bluetooth",
"libs/servo"
],
"cloud": {
"workspace": false,