From 650fe61dcdc16c4f2c490d2ca6c198de763ab680 Mon Sep 17 00:00:00 2001 From: Michal Moskal Date: Fri, 1 Apr 2016 21:26:06 -0700 Subject: [PATCH] Move more stuff to C++ --- libs/microbit/basic.cpp | 6 +- libs/microbit/control.cpp | 2 +- libs/microbit/enums.d.ts | 46 +++++++-- libs/microbit/images.cpp | 2 +- libs/microbit/input.cpp | 198 +++++++++++++++++++++++++++++++++-- libs/microbit/input.ts | 141 ------------------------- libs/microbit/kind.json | 3 +- libs/microbit/ksbit.h | 10 ++ libs/microbit/pins.cpp | 181 ++++++++++++++++++++++++++++++++ libs/microbit/pins.ts | 139 ------------------------- libs/microbit/shims.d.ts | 210 +++++++++++++++++++++++++++++++++++++- 11 files changed, 637 insertions(+), 301 deletions(-) create mode 100644 libs/microbit/ksbit.h create mode 100644 libs/microbit/pins.cpp diff --git a/libs/microbit/basic.cpp b/libs/microbit/basic.cpp index 719465a8..26a2a0d3 100644 --- a/libs/microbit/basic.cpp +++ b/libs/microbit/basic.cpp @@ -1,4 +1,4 @@ -#include "BitVM.h" +#include "ksbit.h" /** @@ -80,7 +80,7 @@ namespace basic { * @param leds TODO * @param interval TODO */ - //% help=basic/show-animation shim=micro_bit::showAnimation imageLiteral=1 async + //% help=basic/show-animation imageLiteral=1 async void showAnimation(ImageLiteral leds, int interval = 400) { uBit.display.animate(MicroBitImage(getbytes(leds)), interval, 5, 0); } @@ -89,7 +89,7 @@ namespace basic { * Draws an image on the LED screen. * @param leds TODO */ - //% help=basic/plot-leds weight=80 shim=micro_bit::plotLeds + //% help=basic/plot-leds weight=80 void plotLeds(ImageLiteral leds) { MicroBitImage i(getbytes(leds)); uBit.display.print(i, 0, 0, 0, 0); diff --git a/libs/microbit/control.cpp b/libs/microbit/control.cpp index 66da90e0..40bfe2e1 100644 --- a/libs/microbit/control.cpp +++ b/libs/microbit/control.cpp @@ -1,4 +1,4 @@ -#include "BitVM.h" +#include "ksbit.h" /** * How to create the event. diff --git a/libs/microbit/enums.d.ts b/libs/microbit/enums.d.ts index 6566e0c6..14c6b4b5 100644 --- a/libs/microbit/enums.d.ts +++ b/libs/microbit/enums.d.ts @@ -34,12 +34,9 @@ declare namespace basic { declare enum TouchPin { - //% enumval=micro_bit::ioP0 - P0 = 0, - //% enumval=micro_bit::ioP1 - P1 = 1, - //% enumval=micro_bit::ioP2 - P2 = 2, + P0 = 7, // MICROBIT_ID_IO_P0 + P1 = 8, // MICROBIT_ID_IO_P1 + P2 = 9, // MICROBIT_ID_IO_P2 } @@ -109,6 +106,8 @@ declare namespace basic { //% block="free fall" FreeFall = 7, // GESTURE_FREEFALL } +declare namespace input { +} /** @@ -224,4 +223,39 @@ declare namespace basic { declare namespace control { } + + declare enum DigitalPin { + P0 = 7, // MICROBIT_ID_IO_P0 + P1 = 8, // MICROBIT_ID_IO_P1 + P2 = 9, // MICROBIT_ID_IO_P2 + P3 = 10, // MICROBIT_ID_IO_P3 + P4 = 11, // MICROBIT_ID_IO_P4 + P5 = 12, // MICROBIT_ID_IO_P5 + P6 = 13, // MICROBIT_ID_IO_P6 + P7 = 14, // MICROBIT_ID_IO_P7 + P8 = 15, // MICROBIT_ID_IO_P8 + P9 = 16, // MICROBIT_ID_IO_P9 + P10 = 17, // MICROBIT_ID_IO_P10 + P11 = 18, // MICROBIT_ID_IO_P11 + P12 = 19, // MICROBIT_ID_IO_P12 + P13 = 20, // MICROBIT_ID_IO_P13 + P14 = 21, // MICROBIT_ID_IO_P14 + P15 = 22, // MICROBIT_ID_IO_P15 + P16 = 23, // MICROBIT_ID_IO_P16 + P19 = 24, // MICROBIT_ID_IO_P19 + P20 = 25, // MICROBIT_ID_IO_P20 + } + + + declare enum AnalogPin { + P0 = 7, // MICROBIT_ID_IO_P0 + P1 = 8, // MICROBIT_ID_IO_P1 + P2 = 9, // MICROBIT_ID_IO_P2 + P3 = 10, // MICROBIT_ID_IO_P3 + P4 = 11, // MICROBIT_ID_IO_P4 + P10 = 17, // MICROBIT_ID_IO_P10 + } +declare namespace pins { +} + // Auto-generated. Do not edit. Really. diff --git a/libs/microbit/images.cpp b/libs/microbit/images.cpp index 0d9bc057..c58e4e76 100644 --- a/libs/microbit/images.cpp +++ b/libs/microbit/images.cpp @@ -1,4 +1,4 @@ -#include "BitVM.h" +#include "ksbit.h" typedef ImageData* Image; diff --git a/libs/microbit/input.cpp b/libs/microbit/input.cpp index c64f0ab0..b47d14d1 100644 --- a/libs/microbit/input.cpp +++ b/libs/microbit/input.cpp @@ -1,4 +1,4 @@ -#include "BitVM.h" +#include "ksbit.h" enum class Button { A = MICROBIT_ID_BUTTON_A, @@ -26,12 +26,9 @@ enum class Rotation { }; enum class TouchPin { - //% enumval=micro_bit::ioP0 - P0, - //% enumval=micro_bit::ioP1 - P1, - //% enumval=micro_bit::ioP2 - P2, + P0 = MICROBIT_ID_IO_P0, + P1 = MICROBIT_ID_IO_P1, + P2 = MICROBIT_ID_IO_P2, }; enum class AcceleratorRange { @@ -99,3 +96,190 @@ enum class Gesture { //% block="free fall" FreeFall = GESTURE_FREEFALL }; + +//% color=300 weight=99 +namespace input { + /** + * Do something when a button (``A``, ``B`` or both ``A+B``) is pressed + * @param button TODO + * @param body TODO + */ + //% help=input/on-button-pressed weight=85 + //% blockId=device_button_event + //% block="on button|%NAME|pressed" + //% icon="\uf192" + void onButtonPressed(Button button, Action body) { + registerWithDal((int)button, MICROBIT_BUTTON_EVT_CLICK, body); + } + + /** + * Attaches code to run when the screen is facing up. + * @param body TODO + */ + //% help=input/on-gesture weight=84 + //% blockId=device_gesture_event block="on |%NAME" icon="\uf135" + void onGesture(Gesture gesture, Action body) { + registerWithDal(MICROBIT_ID_GESTURE, (int)gesture, body); + } + + /** + * Do something when a pin(``P0``, ``P1`` or both ``P2``) is pressed. + * @param name TODO + * @param body TODO + */ + //% help=input/on-pin-pressed weight=83 shim=micro_bit::onPinPressed + //% blockId=device_pin_event block="on pin|%NAME|pressed" icon="\uf094" + void onPinPressed(TouchPin name, Action body) { + auto pin = getPin((int)name); + if (!pin) return; + + // Forces the PIN to switch to makey-makey style detection. + pin->isTouched(); + registerWithDal((int)name, MICROBIT_BUTTON_EVT_CLICK, body); + } + + /** + * Get the button state (pressed or not) for ``A`` and ``B``. + */ + //% help=input/button-is-pressed weight=57 + //% shim=micro_bit::isButtonPressed + //% block="button|%NAME|is pressed" + //% blockId=device_get_button2 + //% icon="\uf192" blockGap=8 + bool buttonIsPressed(Button button) { + if (button == Button::A) + return uBit.buttonA.isPressed(); + else if (button == Button::B) + return uBit.buttonB.isPressed(); + else if (button == Button::AB) + return uBit.buttonAB.isPressed(); + return false; + } + + + /** + * Get the current compass compass heading in degrees. + */ + //% help=input/compass-heading + //% weight=56 icon="\uf14e" + //% shim=micro_bit::compassHeading + //% blockId=device_heading block="compass heading (°)" blockGap=8 + int compassHeading() { + return uBit.compass.heading(); + } + + + /** + * Gets the temperature in Celsius degrees (°C). + */ + //% weight=55 icon="\uf06d" + //% help=input/temperature shim=micro_bit::temperature + //% blockId=device_temperature block="temperature (°C)" blockGap=8 + int temperature() { + return uBit.thermometer.getTemperature(); + } + + int getAccelerationStrength() { + double x = uBit.accelerometer.getX(); + double y = uBit.accelerometer.getY(); + double z = uBit.accelerometer.getZ(); + return (int)sqrt(x*x+y*y+z*z); + } + + /** + * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up, x=0, y=0 and z=-1024) + * @param dimension TODO + */ + //% help=input/acceleration weight=54 icon="\uf135" + //% shim=micro_bit::getAcceleration + //% blockId=device_acceleration block="acceleration (mg)|%NAME" blockGap=8 + int acceleration(Dimension dimension) { + switch (dimension) { + case Dimension::X: return uBit.accelerometer.getX(); + case Dimension::Y: return uBit.accelerometer.getY(); + case Dimension::Z: return uBit.accelerometer.getZ(); + case Dimension::Strength: return getAccelerationStrength(); + } + return 0; + } + + + /** + * Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright. In the simulator, the ``acceleration y`` is used to emulate this value. + */ + //% help=input/light-level weight=53 shim=micro_bit::lightLevel + //% blockId=device_get_light_level block="light level" blockGap=8 icon="\uf185" + int lightLevel() { + return uBit.display.readLightLevel(); + } + + /** + * The pitch of the device, rotation along the ``x-axis``, in degrees. + * @param kind TODO + */ + //% help=/input/rotation weight=52 shim=micro_bit::getRotation + //% blockId=device_get_rotation block="rotation (°)|%NAME" blockGap=8 icon="\uf197" + int rotation(Rotation kind) { + switch (kind) { + case Rotation::Pitch: return uBit.accelerometer.getPitch(); + case Rotation::Roll: return uBit.accelerometer.getRoll(); + } + return 0; + } + + /** + * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator. + * @param dimension TODO + */ + //% help=input/magnetic-force weight=51 shim=micro_bit::getMagneticForce + //% blockId=device_get_magnetic_force block="magnetic force (µT)|%NAME" blockGap=8 icon="\uf076" + int magneticForce(Dimension dimension) { + if (!uBit.compass.isCalibrated()) + uBit.compass.calibrate(); + + switch (dimension) { + case Dimension::X: return uBit.compass.getX() / 1000; + case Dimension::Y: return uBit.compass.getY() / 1000; + case Dimension::Z: return uBit.compass.getZ() / 1000; + case Dimension::Strength: return uBit.compass.getFieldStrength() / 1000; + } + return 0; + } + + /** + * Gets the number of milliseconds elapsed since power on. + */ + //% help=input/running-time shim=micro_bit::getCurrentTime weight=50 + //% blockId=device_get_running_time block="running time (ms)" icon="\uf017" + int runningTime() { + return uBit.systemTime(); + } + + /** + * Obsolete, compass calibration is automatic. + */ + //% help=input/calibrate weight=0 shim=TD_NOOP + void calibrate() { } + + /** + * Get the pin state (pressed or not). Requires to hold the ground to close the circuit. + * @param name pin used to detect the touch + */ + //% help=input/pin-is-pressed weight=58 shim=micro_bit::isPinTouched block="pin|%NAME|is pressed" icon="\uf094" + bool pinIsPressed(TouchPin name) { + auto pin = getPin((int)name); + return pin && pin->isTouched(); + } + + /** + * Sets the accelerometer sample range in gravities. + * @param range a value describe the maximum strengh of acceleration measured + */ + //% help=input/set-accelerator-range + //% blockId=device_set_accelerometer_range block="set accelerometer|range %range" icon="\uf135" + //% weight=5 + //% shim=micro_bit::setAccelerometerRange + void setAccelerometerRange(AcceleratorRange range) { + uBit.accelerometer.setRange((int)range); + } +} diff --git a/libs/microbit/input.ts b/libs/microbit/input.ts index 8a63191e..d5f385bf 100644 --- a/libs/microbit/input.ts +++ b/libs/microbit/input.ts @@ -1,134 +1,5 @@ //% color=300 weight=99 namespace input { - /** - * Do something when a button (``A``, ``B`` or both ``A+B``) is pressed - * @param button TODO - * @param body TODO - */ - //% help=input/on-button-pressed weight=85 - //% shim=micro_bit::onButtonPressed - //% blockId=device_button_event - //% block="on button|%NAME|pressed" - //% icon="\uf192" - export function onButtonPressed(button: Button, body: Action): void { } - - /** - * Attaches code to run when the screen is facing up. - * @param body TODO - */ - //% help=input/on-gesture shim=micro_bit::onGesture weight=84 - //% blockId=device_gesture_event block="on |%NAME" icon="\uf135" - export function onGesture(gesture: Gesture, body: Action): void { } - - /** - * Do something when a pin(``P0``, ``P1`` or both ``P2``) is pressed. - * @param name TODO - * @param body TODO - */ - //% help=input/on-pin-pressed weight=83 shim=micro_bit::onPinPressed - //% blockId=device_pin_event block="on pin|%NAME|pressed" icon="\uf094" - export function onPinPressed(name: TouchPin, body: Action): void { } - - /** - * Get the button state (pressed or not) for ``A`` and ``B``. - */ - //% help=input/button-is-pressed weight=57 - //% shim=micro_bit::isButtonPressed - //% block="button|%NAME|is pressed" - //% blockId=device_get_button2 - //% icon="\uf192" blockGap=8 - export function buttonIsPressed(button: Button): boolean { - return false; - } - - - /** - * Get the current compass compass heading in degrees. - */ - //% help=input/compass-heading - //% weight=56 icon="\uf14e" - //% shim=micro_bit::compassHeading - //% blockId=device_heading block="compass heading (°)" blockGap=8 - export function compassHeading(): number { - return 0; - } - - - /** - * Gets the temperature in Celsius degrees (°C). - */ - //% weight=55 icon="\uf06d" - //% help=input/temperature shim=micro_bit::temperature - //% blockId=device_temperature block="temperature (°C)" blockGap=8 - export function temperature(): number { - return 0; - } - - /** - * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up, x=0, y=0 and z=-1024) - * @param dimension TODO - */ - //% help=input/acceleration weight=54 icon="\uf135" - //% shim=micro_bit::getAcceleration - //% blockId=device_acceleration block="acceleration (mg)|%NAME" blockGap=8 - export function acceleration(dimension: Dimension): number { - return 0; - } - - - /** - * Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright. In the simulator, the ``acceleration y`` is used to emulate this value. - */ - //% help=input/light-level weight=53 shim=micro_bit::lightLevel - //% blockId=device_get_light_level block="light level" blockGap=8 icon="\uf185" - export function lightLevel(): number { - return 0; - } - - /** - * The pitch of the device, rotation along the ``x-axis``, in degrees. - * @param kind TODO - */ - //% help=/input/rotation weight=52 shim=micro_bit::getRotation - //% blockId=device_get_rotation block="rotation (°)|%NAME" blockGap=8 icon="\uf197" - export function rotation(kind: Rotation): number { - return 0; - } - - /** - * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator. - * @param dimension TODO - */ - //% help=input/magnetic-force weight=51 shim=micro_bit::getMagneticForce - //% blockId=device_get_magnetic_force block="magnetic force (µT)|%NAME" blockGap=8 icon="\uf076" - export function magneticForce(dimension: Dimension): number { - return 0; - } - - /** - * Gets the number of milliseconds elapsed since power on. - */ - //% help=input/running-time shim=micro_bit::getCurrentTime weight=50 - //% blockId=device_get_running_time block="running time (ms)" icon="\uf017" - export function runningTime(): number { - return 0; - } - - /** - * Obsolete, compass calibration is automatic. - */ - //% help=input/calibrate weight=0 shim=TD_NOOP - export function calibrate(): void { } - - /** - * Get the pin state (pressed or not). Requires to hold the ground to close the circuit. - * @param name pin used to detect the touch - */ - //% help=input/pin-is-pressed weight=58 shim=micro_bit::isPinTouched block="pin|%NAME|is pressed" icon="\uf094" - export function pinIsPressed(name: TouchPin): boolean { - return false; - } - /** * Attaches code to run when the screen is facing up. * @param body TODO @@ -173,16 +44,4 @@ namespace input { export function onLogoDown(body: Action): void { onGesture(Gesture.LogoDown, body); } - - /** - * Sets the accelerometer sample range in gravities. - * @param range a value describe the maximum strengh of acceleration measured - */ - //% help=input/set-accelerator-range - //% blockId=device_set_accelerometer_range block="set accelerometer|range %range" icon="\uf135" - //% weight=5 - //% shim=micro_bit::setAccelerometerRange - export function setAccelerometerRange(range : AcceleratorRange) : void { - - } } diff --git a/libs/microbit/kind.json b/libs/microbit/kind.json index 9c64616b..df526aab 100644 --- a/libs/microbit/kind.json +++ b/libs/microbit/kind.json @@ -8,6 +8,7 @@ "enums.d.ts", "shims.d.ts", "core.d.ts", + "ksbit.h", "mbit.ts", "images.cpp", "basic.cpp", @@ -18,7 +19,7 @@ "game.ts", "led.ts", "music.ts", - "pins.ts", + "pins.cpp", "serial.ts" ], "public": true, diff --git a/libs/microbit/ksbit.h b/libs/microbit/ksbit.h new file mode 100644 index 00000000..1b45fa9a --- /dev/null +++ b/libs/microbit/ksbit.h @@ -0,0 +1,10 @@ +#include "BitVM.h" + +namespace bitvm { + namespace bitvm_micro_bit { + void registerWithDal(int id, int event, Action a); + } +} + +MicroBitPin *getPin(int id); +using namespace bitvm::bitvm_micro_bit; diff --git a/libs/microbit/pins.cpp b/libs/microbit/pins.cpp new file mode 100644 index 00000000..251d47f6 --- /dev/null +++ b/libs/microbit/pins.cpp @@ -0,0 +1,181 @@ +#include "ksbit.h" + +enum class DigitalPin { + P0 = MICROBIT_ID_IO_P0, + P1 = MICROBIT_ID_IO_P1, + P2 = MICROBIT_ID_IO_P2, + P3 = MICROBIT_ID_IO_P3, + P4 = MICROBIT_ID_IO_P4, + P5 = MICROBIT_ID_IO_P5, + P6 = MICROBIT_ID_IO_P6, + P7 = MICROBIT_ID_IO_P7, + P8 = MICROBIT_ID_IO_P8, + P9 = MICROBIT_ID_IO_P9, + P10 = MICROBIT_ID_IO_P10, + P11 = MICROBIT_ID_IO_P11, + P12 = MICROBIT_ID_IO_P12, + P13 = MICROBIT_ID_IO_P13, + P14 = MICROBIT_ID_IO_P14, + P15 = MICROBIT_ID_IO_P15, + P16 = MICROBIT_ID_IO_P16, + P19 = MICROBIT_ID_IO_P19, + P20 = MICROBIT_ID_IO_P20, +}; + +enum class AnalogPin { + P0 = MICROBIT_ID_IO_P0, + P1 = MICROBIT_ID_IO_P1, + P2 = MICROBIT_ID_IO_P2, + P3 = MICROBIT_ID_IO_P3, + P4 = MICROBIT_ID_IO_P4, + P10 = MICROBIT_ID_IO_P10, +}; + +MicroBitPin *getPin(int id) { + switch (id) { + case MICROBIT_ID_IO_P0: return &uBit.io.P0; + case MICROBIT_ID_IO_P1: return &uBit.io.P1; + case MICROBIT_ID_IO_P2: return &uBit.io.P2; + case MICROBIT_ID_IO_P3: return &uBit.io.P3; + case MICROBIT_ID_IO_P4: return &uBit.io.P4; + case MICROBIT_ID_IO_P5: return &uBit.io.P5; + case MICROBIT_ID_IO_P6: return &uBit.io.P6; + case MICROBIT_ID_IO_P7: return &uBit.io.P7; + case MICROBIT_ID_IO_P8: return &uBit.io.P8; + case MICROBIT_ID_IO_P9: return &uBit.io.P9; + case MICROBIT_ID_IO_P10: return &uBit.io.P10; + case MICROBIT_ID_IO_P11: return &uBit.io.P11; + case MICROBIT_ID_IO_P12: return &uBit.io.P12; + case MICROBIT_ID_IO_P13: return &uBit.io.P13; + case MICROBIT_ID_IO_P14: return &uBit.io.P14; + case MICROBIT_ID_IO_P15: return &uBit.io.P15; + case MICROBIT_ID_IO_P16: return &uBit.io.P16; + case MICROBIT_ID_IO_P19: return &uBit.io.P19; + case MICROBIT_ID_IO_P20: return &uBit.io.P20; + default: return NULL; + } +} + + +//% color=351 weight=30 +namespace pins { + #define PINOP(op) \ + MicroBitPin *pin = getPin((int)name); \ + if (!pin) return; \ + pin->op + + #define PINREAD(op) \ + MicroBitPin *pin = getPin((int)name); \ + if (!pin) return 0; \ + return pin->op + + /** + * Read the specified pin or connector as either 0 or 1 + * @param name pin to read from + */ + //% help=pins/digital-read-pin weight=30 shim=micro_bit::digitalReadPin + //% blockId=device_get_digital_pin block="digital read|pin %name" blockGap=8 + int digitalReadPin(DigitalPin name) { + PINREAD(getDigitalValue()); + } + + /** + * Set a pin or connector value to either 0 or 1. + * @param name pin to write to + * @param value value to set on the pin, 1 eg,0 + */ + //% help=pins/digital-write-pin weight=29 shim=micro_bit::digitalWritePin + //% blockId=device_set_digital_pin block="digital write|pin %name|to %value" + void digitalWritePin(DigitalPin name, int value) { + PINOP(setDigitalValue(value)); + } + + /** + * Read the connector value as analog, that is, as a value comprised between 0 and 1023. + * @param name pin to write to + */ + //% help=pins/analog-read-pin weight=25 shim=micro_bit::analogReadPin + //% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8" + int analogReadPin(AnalogPin name) { + PINREAD(getAnalogValue()); + } + + /** + * Set the connector value as analog. Value must be comprised between 0 and 1023. + * @param name pin name to write to + * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0 + */ + //% help=pins/analog-write-pin weight=24 shim=micro_bit::analogWritePin + //% blockId=device_set_analog_pin block="analog write|pin %name|to %value" blockGap=8 + void analogWritePin(AnalogPin name, int value) { + PINOP(setAnalogValue(value)); + } + + /** + * Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds. + * If this pin is not configured as an analog output (using `analog write pin`), the operation has no effect. + * @param name analog pin to set period to + * @param micros period in micro seconds. eg:20000 + */ + //% shim=micro_bit::setAnalogPeriodUs help=pins/analog-set-period weight=23 + //% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros" + void analogSetPeriod(AnalogPin name, int micros) { + PINOP(setAnalogPeriodUs(micros)); + } + + /** + * Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement). + * @param name pin to write to + * @param value angle or rotation speed, eg:180,90,0 + */ + //% help=pins/servo-write-pin weight=20 shim=micro_bit::servoWritePin + //% blockId=device_set_servo_pin block="servo write|pin %name|to %value" blockGap=8 + void servoWritePin(AnalogPin name, int value) { + PINOP(setServoValue(value)); + } + + /** + * Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds. + * @param name pin name + * @param micros pulse duration in micro seconds, eg:1500 + */ + //% shim=micro_bit::setServoPulseUs help=pins/serial-set-pulse weight=19 + //% blockId=device_set_servo_pulse block="servo set pulse|pin %value|to (µs) %micros" + void servoSetPulse(AnalogPin name, int micros) { + PINOP(setServoPulseUs(micros)); + } + + + MicroBitPin* pitchPin = NULL; + + /** + * Sets the pin used when using `pins->analog pitch`. + * @param name TODO + */ + //% shim=micro_bit::enablePitch help=pins/analog-set-pitch weight=12 + void analogSetPitchPin(AnalogPin name) { + pitchPin = getPin((int)name); + } + + /** + * Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin. + * @param frequency TODO + * @param ms TODO + */ + //% shim=micro_bit::pitch help=pins/analog-pitch weight=14 async + void analogPitch(int frequency, int ms) { + if (pitchPin == NULL) return; + if (frequency <= 0) { + pitchPin->setAnalogValue(0); + } else { + pitchPin->setAnalogValue(512); + pitchPin->setAnalogPeriodUs(1000000/frequency); + } + + if (ms > 0) { + uBit.sleep(ms); + pitchPin->setAnalogValue(0); + wait_ms(5); + } + } +} diff --git a/libs/microbit/pins.ts b/libs/microbit/pins.ts index f30c0773..f631d1df 100644 --- a/libs/microbit/pins.ts +++ b/libs/microbit/pins.ts @@ -1,129 +1,5 @@ -enum DigitalPin { - //% enumval=micro_bit::ioP0 - P0, - //% enumval=micro_bit::ioP1 - P1, - //% enumval=micro_bit::ioP2 - P2, - //% enumval=micro_bit::ioP3 - P3, - //% enumval=micro_bit::ioP4 - P4, - //% enumval=micro_bit::ioP5 - P5, - //% enumval=micro_bit::ioP6 - P6, - //% enumval=micro_bit::ioP7 - P7, - //% enumval=micro_bit::ioP8 - P8, - //% enumval=micro_bit::ioP9 - P9, - //% enumval=micro_bit::ioP10 - P10, - //% enumval=micro_bit::ioP11 - P11, - //% enumval=micro_bit::ioP12 - P12, - //% enumval=micro_bit::ioP13 - P13, - //% enumval=micro_bit::ioP14 - P14, - //% enumval=micro_bit::ioP15 - P15, - //% enumval=micro_bit::ioP16 - P16, - //% enumval=micro_bit::ioP19 - P19, - //% enumval=micro_bit::ioP20 - P20, -} - -enum AnalogPin { - //% enumval=micro_bit::ioP0 - P0, - //% enumval=micro_bit::ioP1 - P1, - //% enumval=micro_bit::ioP2 - P2, - //% enumval=micro_bit::ioP3 - P3, - //% enumval=micro_bit::ioP4 - P4, - //% enumval=micro_bit::ioP10 - P10, -} - - //% color=351 weight=30 namespace pins { - /** - * Read the specified pin or connector as either 0 or 1 - * @param name pin to read from - */ - //% help=pins/digital-read-pin weight=30 shim=micro_bit::digitalReadPin - //% blockId=device_get_digital_pin block="digital read|pin %name" blockGap=8 - export function digitalReadPin(name: DigitalPin): number { - - return 0; - } - - /** - * Set a pin or connector value to either 0 or 1. - * @param name pin to write to - * @param value value to set on the pin, eg: 1,0 - */ - //% help=pins/digital-write-pin weight=29 shim=micro_bit::digitalWritePin - //% blockId=device_set_digital_pin block="digital write|pin %name|to %value" - export function digitalWritePin(name: DigitalPin, value: number): void { } - - /** - * Read the connector value as analog, that is, as a value comprised between 0 and 1023. - * @param name pin to write to - */ - //% help=pins/analog-read-pin weight=25 shim=micro_bit::analogReadPin - //% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8" - export function analogReadPin(name: AnalogPin): number { - return 0; - } - - /** - * Set the connector value as analog. Value must be comprised between 0 and 1023. - * @param name pin name to write to - * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0 - */ - //% help=pins/analog-write-pin weight=24 shim=micro_bit::analogWritePin - //% blockId=device_set_analog_pin block="analog write|pin %name|to %value" blockGap=8 - export function analogWritePin(name: AnalogPin, value: number): void { } - - /** - * Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds. - * If this pin is not configured as an analog output (using `analog write pin`), the operation has no effect. - * @param pin analog pin to set period to - * @param micros period in micro seconds. eg:20000 - */ - //% shim=micro_bit::setAnalogPeriodUs help=pins/analog-set-period weight=23 - //% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros" - export function analogSetPeriod(pin: AnalogPin, micros: number): void { } - - /** - * Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement). - * @param name pin to write to - * @param value angle or rotation speed, eg:180,90,0 - */ - //% help=pins/servo-write-pin weight=20 shim=micro_bit::servoWritePin - //% blockId=device_set_servo_pin block="servo write|pin %name|to %value" blockGap=8 - export function servoWritePin(name: AnalogPin, value: number): void { } - - /** - * Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds. - * @param pin pin name - * @param micros pulse duration in micro seconds, eg:1500 - */ - //% shim=micro_bit::setServoPulseUs help=pins/serial-set-pulse weight=19 - //% blockId=device_set_servo_pulse block="servo set pulse|pin %value|to (µs) %micros" - export function servoSetPulse(pin: AnalogPin, micros: number): void { } - /** * 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. * @param value value to map in ranges @@ -137,19 +13,4 @@ namespace pins { export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number { return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow; } - - /** - * Sets the pin used when using `pins->analog pitch`. - * @param name TODO - */ - //% shim=micro_bit::enablePitch help=pins/analog-set-pitch weight=12 - export function analogSetPitchPin(name: AnalogPin): void { } - - /** - * Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin. - * @param frequency TODO - * @param ms TODO - */ - //% shim=micro_bit::pitch help=pins/analog-pitch weight=14 async - export function analogPitch(frequency: number, ms: number): void { } } diff --git a/libs/microbit/shims.d.ts b/libs/microbit/shims.d.ts index f7f062a0..62848ea9 100644 --- a/libs/microbit/shims.d.ts +++ b/libs/microbit/shims.d.ts @@ -117,14 +117,14 @@ declare namespace basic { * @param leds TODO * @param interval TODO */ - //% help=basic/show-animation shim=micro_bit::showAnimation imageLiteral=1 async interval.defl=400 shim=basic::showAnimation + //% help=basic/show-animation imageLiteral=1 async interval.defl=400 shim=basic::showAnimation function showAnimation(leds: string, interval?: number): void; /** * Draws an image on the LED screen. * @param leds TODO */ - //% help=basic/plot-leds weight=80 shim=micro_bit::plotLeds imageLiteral=1 shim=basic::plotLeds + //% help=basic/plot-leds weight=80 imageLiteral=1 shim=basic::plotLeds function plotLeds(leds: string): void; /** @@ -147,6 +147,129 @@ declare namespace basic { + //% color=300 weight=99 +declare namespace input { + + /** + * Do something when a button (``A``, ``B`` or both ``A+B``) is pressed + * @param button TODO + * @param body TODO + */ + //% help=input/on-button-pressed weight=85 + //% blockId=device_button_event + //% block="on button|%NAME|pressed" + //% icon="\uf192" shim=input::onButtonPressed + function onButtonPressed(button: Button , body: () => void): void; + + /** + * Attaches code to run when the screen is facing up. + * @param body TODO + */ + //% help=input/on-gesture weight=84 + //% blockId=device_gesture_event block="on |%NAME" icon="\uf135" shim=input::onGesture + function onGesture(gesture: Gesture , body: () => void): void; + + /** + * Do something when a pin(``P0``, ``P1`` or both ``P2``) is pressed. + * @param name TODO + * @param body TODO + */ + //% help=input/on-pin-pressed weight=83 shim=micro_bit::onPinPressed + //% blockId=device_pin_event block="on pin|%NAME|pressed" icon="\uf094" shim=input::onPinPressed + function onPinPressed(name: TouchPin , body: () => void): void; + + /** + * Get the button state (pressed or not) for ``A`` and ``B``. + */ + //% help=input/button-is-pressed weight=57 + //% shim=micro_bit::isButtonPressed + //% block="button|%NAME|is pressed" + //% blockId=device_get_button2 + //% icon="\uf192" blockGap=8 shim=input::buttonIsPressed + function buttonIsPressed(button: Button ): boolean; + + /** + * Get the current compass compass heading in degrees. + */ + //% help=input/compass-heading + //% weight=56 icon="\uf14e" + //% shim=micro_bit::compassHeading + //% blockId=device_heading block="compass heading (°)" blockGap=8 shim=input::compassHeading + function compassHeading(): number; + + /** + * Gets the temperature in Celsius degrees (°C). + */ + //% weight=55 icon="\uf06d" + //% help=input/temperature shim=micro_bit::temperature + //% blockId=device_temperature block="temperature (°C)" blockGap=8 shim=input::temperature + function temperature(): number; + + /** + * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up, x=0, y=0 and z=-1024) + * @param dimension TODO + */ + //% help=input/acceleration weight=54 icon="\uf135" + //% shim=micro_bit::getAcceleration + //% blockId=device_acceleration block="acceleration (mg)|%NAME" blockGap=8 shim=input::acceleration + function acceleration(dimension: Dimension ): number; + + /** + * Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright. In the simulator, the ``acceleration y`` is used to emulate this value. + */ + //% help=input/light-level weight=53 shim=micro_bit::lightLevel + //% blockId=device_get_light_level block="light level" blockGap=8 icon="\uf185" shim=input::lightLevel + function lightLevel(): number; + + /** + * The pitch of the device, rotation along the ``x-axis``, in degrees. + * @param kind TODO + */ + //% help=/input/rotation weight=52 shim=micro_bit::getRotation + //% blockId=device_get_rotation block="rotation (°)|%NAME" blockGap=8 icon="\uf197" shim=input::rotation + function rotation(kind: Rotation ): number; + + /** + * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator. + * @param dimension TODO + */ + //% help=input/magnetic-force weight=51 shim=micro_bit::getMagneticForce + //% blockId=device_get_magnetic_force block="magnetic force (µT)|%NAME" blockGap=8 icon="\uf076" shim=input::magneticForce + function magneticForce(dimension: Dimension ): number; + + /** + * Gets the number of milliseconds elapsed since power on. + */ + //% help=input/running-time shim=micro_bit::getCurrentTime weight=50 + //% blockId=device_get_running_time block="running time (ms)" icon="\uf017" shim=input::runningTime + function runningTime(): number; + + /** + * Obsolete, compass calibration is automatic. + */ + //% help=input/calibrate weight=0 shim=TD_NOOP shim=input::calibrate + function calibrate(): void; + + /** + * Get the pin state (pressed or not). Requires to hold the ground to close the circuit. + * @param name pin used to detect the touch + */ + //% help=input/pin-is-pressed weight=58 shim=micro_bit::isPinTouched block="pin|%NAME|is pressed" icon="\uf094" shim=input::pinIsPressed + function pinIsPressed(name: TouchPin ): boolean; + + /** + * Sets the accelerometer sample range in gravities. + * @param range a value describe the maximum strengh of acceleration measured + */ + //% help=input/set-accelerator-range + //% blockId=device_set_accelerometer_range block="set accelerometer|range %range" icon="\uf135" + //% weight=5 + //% shim=micro_bit::setAccelerometerRange shim=input::setAccelerometerRange + function setAccelerometerRange(range: AcceleratorRange ): void; +} + + + //% weight=1 color="#333333" declare namespace control { @@ -182,4 +305,87 @@ declare namespace control { function onEvent(src: number, value: number, handler: () => void): void; } + + + //% color=351 weight=30 +declare namespace pins { + + /** + * Read the specified pin or connector as either 0 or 1 + * @param name pin to read from + */ + //% help=pins/digital-read-pin weight=30 shim=micro_bit::digitalReadPin + //% blockId=device_get_digital_pin block="digital read|pin %name" blockGap=8 shim=pins::digitalReadPin + function digitalReadPin(name: DigitalPin ): number; + + /** + * Set a pin or connector value to either 0 or 1. + * @param name pin to write to + * @param value value to set on the pin, 1 eg,0 + */ + //% help=pins/digital-write-pin weight=29 shim=micro_bit::digitalWritePin + //% blockId=device_set_digital_pin block="digital write|pin %name|to %value" shim=pins::digitalWritePin + function digitalWritePin(name: DigitalPin , value: number): void; + + /** + * Read the connector value as analog, that is, as a value comprised between 0 and 1023. + * @param name pin to write to + */ + //% help=pins/analog-read-pin weight=25 shim=micro_bit::analogReadPin + //% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8" shim=pins::analogReadPin + function analogReadPin(name: AnalogPin ): number; + + /** + * Set the connector value as analog. Value must be comprised between 0 and 1023. + * @param name pin name to write to + * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0 + */ + //% help=pins/analog-write-pin weight=24 shim=micro_bit::analogWritePin + //% blockId=device_set_analog_pin block="analog write|pin %name|to %value" blockGap=8 shim=pins::analogWritePin + function analogWritePin(name: AnalogPin , value: number): void; + + /** + * Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds. + * If this pin is not configured as an analog output (using `analog write pin`), the operation has no effect. + * @param name analog pin to set period to + * @param micros period in micro seconds. eg:20000 + */ + //% shim=micro_bit::setAnalogPeriodUs help=pins/analog-set-period weight=23 + //% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros" shim=pins::analogSetPeriod + function analogSetPeriod(name: AnalogPin , micros: number): void; + + /** + * Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement). + * @param name pin to write to + * @param value angle or rotation speed, eg:180,90,0 + */ + //% help=pins/servo-write-pin weight=20 shim=micro_bit::servoWritePin + //% blockId=device_set_servo_pin block="servo write|pin %name|to %value" blockGap=8 shim=pins::servoWritePin + function servoWritePin(name: AnalogPin , value: number): void; + + /** + * Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds. + * @param name pin name + * @param micros pulse duration in micro seconds, eg:1500 + */ + //% shim=micro_bit::setServoPulseUs help=pins/serial-set-pulse weight=19 + //% blockId=device_set_servo_pulse block="servo set pulse|pin %value|to (µs) %micros" shim=pins::servoSetPulse + function servoSetPulse(name: AnalogPin , micros: number): void; + + /** + * Sets the pin used when using `pins->analog pitch`. + * @param name TODO + */ + //% shim=micro_bit::enablePitch help=pins/analog-set-pitch weight=12 shim=pins::analogSetPitchPin + function analogSetPitchPin(name: AnalogPin ): void; + + /** + * Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin. + * @param frequency TODO + * @param ms TODO + */ + //% shim=micro_bit::pitch help=pins/analog-pitch weight=14 async shim=pins::analogPitch + function analogPitch(frequency: number, ms: number): void; +} + // Auto-generated. Do not edit. Really.