Compare commits

...

10 Commits

Author SHA1 Message Date
32783f38ba 4.0.26 2022-06-30 10:01:52 -07:00
fa34fe5fd2 Beta v4 updates (#195)
* fix simulator

- fix buttons
- fix analog max value

* BLE Set max table size

* reset defaults

* add coding4coconut/pxt-lcd128x160-st7735s

* add coding4coconut/pxt-oled128x128-sh1107

* enable partial flashing
2022-06-30 10:01:19 -07:00
5aba020bb3 Microsoft mandatory file (#189)
Co-authored-by: microsoft-github-policy-service[bot] <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com>
2022-05-25 09:56:20 -07:00
3838b46f1d 4.0.25 2022-05-25 09:51:01 -07:00
5188a57927 Updates for v4 (#187)
* decrease default gatt table size

* update simulator size

* update simulator buttons

* Add shake animation & gradients for edge pins
2022-05-25 09:49:55 -07:00
3fd2c31481 4.0.24 2022-05-09 10:10:55 -07:00
2457725e0c V4updates (#185)
* update 32KB

* reorder buttonEvents to have clicked as default

* update event block documentation file path

* remove on pin released documentation

* update shims, enums and package-lock
2022-05-09 10:10:17 -07:00
75d7bfb7c2 4.0.23 2022-05-03 17:30:02 -07:00
36ee2958e1 4.0.22 2022-05-03 17:06:58 -07:00
0b6b882b7d 4.0.21 2022-05-03 16:56:45 -07:00
20 changed files with 7168 additions and 178 deletions

41
SECURITY.md Normal file
View File

@ -0,0 +1,41 @@
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
## Preferred Languages
We prefer all communications to be in English.
## Policy
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->

View File

@ -1,4 +1,4 @@
# On Button Pressed
# On Button Event
Start an [event handler](/reference/event-handler) (part of the program that will run when something happens, like when a button is pressed).
This handler works when button `A` or `B` is pressed, or `A` and `B` together.

View File

@ -1,4 +1,4 @@
# On Pin Pressed
# On Pin Event
Start an [event handler](/reference/event-handler) (part of the
program that will run when something happens, like when a button is

View File

@ -1,48 +0,0 @@
# On Pin Released
Start an [event handler](/reference/event-handler) (part of the
program that will run when something happens, like when a button is
pressed). This handler works when you release pin `0`, `1`, or `2`
together with `GND`. When you are using this function in a web
browser, click and release the pins on the screen instead of the ones on the
@boardname@.
If you hold the `GND` pin with one hand and touch pin `0`, `1`, or `2`
with the other, a very small (safe) amount of electricity will flow
through your body and back into the @boardname@. This is called
**completing a circuit**. It's like you're a big wire!
```sig
input.onPinTouchEvent(TouchPin.P0, ButtonEvent.Up, () => {
})
```
## ~hint
This function works best when the @boardname@ is using batteries for power,
instead of the USB cable.
## ~
## Parameters
* ``name`` means the pin that is being released, either `P0`, `P1`, or `P2`
## Example: pin pressed counter
This program counts how many times you release the `P0` pin.
Every time you release the pin, the program shows the number of times on the screen.
```blocks
let count = 0
basic.showNumber(count, 100)
input.onPinTouchEvent(TouchPin.P0, ButtonEvent.Up, () => {
count = count + 1
basic.showNumber(count, 100)
})
```
## See also
[@boardname@ pins](/device/pins), [pin is pressed](/reference/input/pin-is-pressed), [analog read pin](/reference/pins/analog-read-pin), [analog write pin](/reference/pins/analog-write-pin), [digital read pin](/reference/pins/digital-read-pin), [digital write pin](/reference/pins/digital-write-pin)

View File

@ -268,7 +268,7 @@
"basic.showCompass|param|interval": "the amount of time (milliseconds) to show the needle. Default is 600.",
"basic.showIcon": "Draws the selected icon on the LED screen",
"basic.showIcon|param|icon": "the predefined icon id",
"basic.showIcon|param|interval": "the amount of time (milliseconds) to block the LED Matrix for showing the icon. Default is 200.",
"basic.showIcon|param|interval": "the amount of time (milliseconds) to block the LED Matrix for showing the icon. Default is 600.",
"basic.showLeds": "Draws an image on the LED screen.",
"basic.showLeds|param|interval": "time in milliseconds to pause after drawing",
"basic.showLeds|param|leds": "the pattern of LED to turn on/off",
@ -442,9 +442,18 @@
"input.onButtonEvent|param|body": "code to run when event is raised",
"input.onButtonEvent|param|button": "the button",
"input.onButtonEvent|param|eventType": "event Type",
"input.onButtonPressed": "Do something when a button (A, B or both A+B) is pushed down and released again.",
"input.onButtonPressed|param|body": "code to run when event is raised",
"input.onButtonPressed|param|button": "the button that needs to be pressed",
"input.onGesture": "Do something when when a gesture is done (like shaking the micro:bit).",
"input.onGesture|param|body": "code to run when gesture is raised",
"input.onGesture|param|gesture": "the type of gesture to track, eg: Gesture.Shake",
"input.onPinPressed": "Do something when a pin is touched and released again (while also touching the GND pin).",
"input.onPinPressed|param|body": "the code to run when the pin is pressed",
"input.onPinPressed|param|name": "the pin that needs to be pressed, eg: TouchPin.P0",
"input.onPinReleased": "Do something when a pin is released.",
"input.onPinReleased|param|body": "the code to run when the pin is released",
"input.onPinReleased|param|name": "the pin that needs to be released, eg: TouchPin.P0",
"input.onPinTouchEvent": "Do something when a pin receives an touch event (while also touching the GND pin).",
"input.onPinTouchEvent|param|body": "the code to run when event is fired on pin",
"input.onPinTouchEvent|param|name": "the pin, eg: TouchPin.P0",

View File

@ -345,7 +345,10 @@
"input.lightLevel|block": "light level",
"input.magneticForce|block": "magnetic force (µT)|%NAME",
"input.onButtonEvent|block": "on button %NAME| %eventType=control_button_event_value_id",
"input.onButtonPressed|block": "on button|%NAME|pressed",
"input.onGesture|block": "on |%NAME",
"input.onPinPressed|block": "on pin %name|pressed",
"input.onPinReleased|block": "on pin %NAME|released",
"input.onPinTouchEvent|block": "on pin %name| %eventType=control_button_event_value_id",
"input.pinIsPressed|block": "pin %NAME|is pressed",
"input.rotation|block": "rotation (°)|%NAME",
@ -484,8 +487,10 @@
"{id:category}String": "String",
"{id:category}Text": "Text",
"{id:category}_py": "_py",
"{id:group}Analog": "Analog",
"{id:group}Configuration": "Configuration",
"{id:group}Control": "Control",
"{id:group}Digital": "Digital",
"{id:group}Events": "Events",
"{id:group}Get": "Get",
"{id:group}LED matrix": "LED matrix",
@ -493,15 +498,20 @@
"{id:group}Melody Advanced": "Melody Advanced",
"{id:group}Modify": "Modify",
"{id:group}Operations": "Operations",
"{id:group}Pitch": "Pitch",
"{id:group}Pulse": "Pulse",
"{id:group}Put": "Put",
"{id:group}RGB LED": "RGB LED",
"{id:group}Read": "Read",
"{id:group}Remove": "Remove",
"{id:group}Sensors": "Sensors",
"{id:group}Servo": "Servo",
"{id:group}Silence": "Silence",
"{id:group}States": "States",
"{id:group}System": "System",
"{id:group}Tempo": "Tempo",
"{id:group}Tone": "Tone",
"{id:group}Volume": "Volume"
"{id:group}Volume": "Volume",
"{id:group}i2c": "i2c",
"{id:group}spi": "spi"
}

View File

@ -35,9 +35,9 @@ namespace basic {
//% parts="ledmatrix"
//% text.shadowOptions.toString=true
//% expandableArgumentMode="toggle"
//% interval.defl=80
//% interval.defl=150
//% group="LED matrix"
void showString(String text, int interval = 80) {
void showString(String text, int interval = 150) {
if (interval <= 0)
interval = 1;
int l = text ? text->getUTF8Size() : 0;

View File

@ -52,7 +52,7 @@ namespace basic {
//% async
//% parts="ledmatrix"
//% expandableArgumentMode="toggle"
//% interval.defl=80
//% interval.defl=150
//% group="LED matrix"
export function showNumber(value: number, interval?: number) {
showString(Math.roundWithPrecision(value, 2).toString(), interval);

12
libs/core/enums.d.ts vendored
View File

@ -41,17 +41,17 @@ declare namespace basic {
declare const enum ButtonEvent {
//% blockIdentity="input.buttonEventValueId"
//% block="pressed down"
Down = 1, // MICROBIT_BUTTON_EVT_DOWN
//% blockIdentity="input.buttonEventValueId"
//% block="released up"
Up = 2, // MICROBIT_BUTTON_EVT_UP
//% blockIdentity="input.buttonEventValueId"
//% block="clicked"
Click = 3, // MICROBIT_BUTTON_EVT_CLICK
//% blockIdentity="input.buttonEventValueId"
//% block="long clicked"
LongClick = 4, // MICROBIT_BUTTON_EVT_LONG_CLICK
//% blockIdentity="input.buttonEventValueId"
//% block="pressed down"
Down = 1, // MICROBIT_BUTTON_EVT_DOWN
//% blockIdentity="input.buttonEventValueId"
//% block="released up"
Up = 2, // MICROBIT_BUTTON_EVT_UP
}

View File

@ -196,7 +196,7 @@ namespace basic {
/**
* Draws the selected icon on the LED screen
* @param icon the predefined icon id
* @param interval the amount of time (milliseconds) to block the LED Matrix for showing the icon. Default is 200.
* @param interval the amount of time (milliseconds) to block the LED Matrix for showing the icon. Default is 600.
*/
//% weight=90 blockGap=8
//% blockId=basic_show_icon
@ -208,9 +208,9 @@ namespace basic {
//% icon.fieldOptions.width="380"
//% icon.fieldOptions.maxRows=4
//% expandableArgumentMode="toggle"
//% interval.defl=200
//% interval.defl=600
//% group="LED matrix"
export function showIcon(icon: IconNames, interval = 200) {
export function showIcon(icon: IconNames, interval = 600) {
let res = images.iconImage(icon)
res.showImage(0, interval)
}

View File

@ -8,18 +8,18 @@ enum class Button {
};
enum class ButtonEvent {
//% blockIdentity="input.buttonEventValueId"
//% block="pressed down"
Down = MICROBIT_BUTTON_EVT_DOWN,
//% blockIdentity="input.buttonEventValueId"
//% block="released up"
Up = MICROBIT_BUTTON_EVT_UP,
//% blockIdentity="input.buttonEventValueId"
//% block="clicked"
Click = MICROBIT_BUTTON_EVT_CLICK,
//% blockIdentity="input.buttonEventValueId"
//% block="long clicked"
LongClick = MICROBIT_BUTTON_EVT_LONG_CLICK,
//% blockIdentity="input.buttonEventValueId"
//% block="pressed down"
Down = MICROBIT_BUTTON_EVT_DOWN,
//% blockIdentity="input.buttonEventValueId"
//% block="released up"
Up = MICROBIT_BUTTON_EVT_UP,
};
enum class Dimension {
@ -187,7 +187,7 @@ namespace input {
//% parts="buttonpair"
//% group="Events"
void onButtonEvent(Button button, int eventType, Action body) {
registerWithDal((int)button, eventType, body);
registerWithDal((int)button, (int)eventType, body);
}
/**
@ -230,7 +230,7 @@ namespace input {
* @param name the pin, eg: TouchPin.P0
* @param body the code to run when event is fired on pin
*/
//% help=input/on-pin-touch weight=99 blockGap=16
//% help=input/on-pin-event weight=99 blockGap=16
//% blockId=device_pin_custom_event block="on pin %name| %eventType=control_button_event_value_id"
//% group="Events"
void onPinTouchEvent(TouchPin name, int eventType, Action body) {
@ -239,7 +239,7 @@ namespace input {
// Forces the PIN to switch to makey-makey style detection.
pin->isTouched();
registerWithDal((int)name, eventType, body);
registerWithDal((int)name, (int)eventType, body);
}
/**
@ -262,6 +262,57 @@ namespace input {
return false;
}
/**
* Do something when a button (A, B or both A+B) is pushed down and released again.
* @param button the button that needs to be pressed
* @param body code to run when event is raised
*/
//% help=input/on-button-pressed weight=85 blockGap=16
//% blockId=device_button_event block="on button|%NAME|pressed"
//% parts="buttonpair"
//% deprecated=true
//% group="Events"
void onButtonPressed(Button button, Action body) {
registerWithDal((int)button, MICROBIT_BUTTON_EVT_CLICK, body);
}
/**
* Do something when a pin is touched and released again (while also touching the GND pin).
* @param name the pin that needs to be pressed, eg: TouchPin.P0
* @param body the code to run when the pin is pressed
*/
//% help=input/on-pin-pressed weight=83 blockGap=16
//% blockId=device_pin_event block="on pin %name|pressed"
//% group="Events"
//% deprecated=true
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);
}
/**
* Do something when a pin is released.
* @param name the pin that needs to be released, eg: TouchPin.P0
* @param body the code to run when the pin is released
*/
//% help=input/on-pin-released weight=6 blockGap=16
//% blockId=device_pin_released block="on pin %NAME|released"
//% advanced=true
//% group="Events"
//% deprecated=true
void onPinReleased(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_UP, body);
}
/**
* Get the pin state (pressed or not). Requires to hold the ground to close the circuit.
* @param name pin used to detect the touch, eg: TouchPin.P0

View File

@ -124,6 +124,7 @@ namespace pins {
//% blockId=device_get_digital_pin block="digital read|pin %name" blockGap=8
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Digital"
int digitalReadPin(DigitalPin name) {
PINREAD(getDigitalValue());
}
@ -138,6 +139,7 @@ namespace pins {
//% value.min=0 value.max=1
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Digital"
void digitalWritePin(DigitalPin name, int value) {
PINOP(setDigitalValue(value));
}
@ -150,6 +152,7 @@ namespace pins {
//% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8"
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Analog"
int analogReadPin(AnalogPin name) {
PINREAD(getAnalogValue());
}
@ -164,6 +167,7 @@ namespace pins {
//% value.min=0 value.max=1023
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Analog"
void analogWritePin(AnalogPin name, int value) {
PINOP(setAnalogValue(value));
}
@ -178,6 +182,7 @@ namespace pins {
//% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros"
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false"
//% group="Analog"
void analogSetPeriod(AnalogPin name, int micros) {
PINOP(setAnalogPeriodUs(micros));
}
@ -191,6 +196,7 @@ namespace pins {
//% blockId=pins_on_pulsed block="on|pin %pin|pulsed %pulse"
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250"
//% group="Pulse"
void onPulsed(DigitalPin name, PulseValue pulse, Action body) {
MicroBitPin* pin = getPin((int)name);
if (!pin) return;
@ -205,6 +211,7 @@ namespace pins {
//% help=pins/pulse-duration advanced=true
//% blockId=pins_pulse_duration block="pulse duration (µs)"
//% weight=21 blockGap=8
//% group="Pulse"
int pulseDuration() {
return pxt::lastEvent.timestamp;
}
@ -220,6 +227,7 @@ namespace pins {
//% help=pins/pulse-in
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Pulse"
int pulseIn(DigitalPin name, PulseValue value, int maxDuration = 2000000) {
MicroBitPin* pin = getPin((int)name);
if (!pin) return 0;
@ -275,6 +283,7 @@ namespace pins {
//% value.min=0 value.max=180
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Servo"
void servoWritePin(AnalogPin name, int value) {
PINOP(setServoValue(value));
}
@ -283,6 +292,7 @@ namespace pins {
* Specifies that a continuous servo is connected.
*/
//%
//% group="Servo"
void servoSetContinuous(AnalogPin name, bool value) {
// handled in simulator
}
@ -296,6 +306,7 @@ namespace pins {
//% blockId=device_set_servo_pulse block="servo set pulse|pin %value|to (µs) %micros"
//% value.fieldEditor="gridpicker" value.fieldOptions.columns=4
//% value.fieldOptions.tooltips="false" value.fieldOptions.width="250"
//% group="Servo"
void servoSetPulse(AnalogPin name, int micros) {
fixMotorIssue(name);
PINOP(setServoPulseUs(micros));
@ -316,6 +327,7 @@ namespace pins {
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% blockHidden=true
//% group="Pitch"
void analogSetPitchPin(AnalogPin name) {
pitchPin = getPin((int)name);
pitchPin2 = NULL;
@ -339,6 +351,7 @@ namespace pins {
//% help=pins/analog-set-pitch-volume weight=3 advanced=true
//% volume.min=0 volume.max=255
//% blockHidden=true
//% group="Pitch"
void analogSetPitchVolume(int volume) {
pitchVolume = max(0, min(0xff, volume));
@ -355,6 +368,7 @@ namespace pins {
//% blockId=device_analog_pitch_volume block="analog pitch volume"
//% help=pins/analog-pitch-volume weight=3 advanced=true
//% blockHidden=true
//% group="Pitch"
int analogPitchVolume() {
return pitchVolume;
}
@ -367,6 +381,7 @@ namespace pins {
//% blockId=device_analog_pitch block="analog pitch %frequency|for (ms) %ms"
//% help=pins/analog-pitch weight=4 async advanced=true blockGap=8
//% blockHidden=true
//% group="Pitch"
void analogPitch(int frequency, int ms) {
// init pins if needed
if (NULL == pitchPin) {
@ -402,6 +417,7 @@ namespace pins {
//% blockId=device_set_pull block="set pull|pin %pin|to %pull"
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250"
//% group="Digital"
void setPull(DigitalPin name, PinPullMode pull) {
#if MICROBIT_CODAL
codal::PullMode m = pull == PinPullMode::PullDown
@ -428,6 +444,7 @@ namespace pins {
//% blockId=device_set_pin_events block="set pin %pin|to emit %type|events"
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250"
//% group="Digital"
void setEvents(DigitalPin name, PinEventType type) {
getPin((int)name)->eventOn((int)type);
}
@ -467,6 +484,7 @@ namespace pins {
* Read `size` bytes from a 7-bit I2C `address`.
*/
//%
//% group="i2c"
Buffer i2cReadBuffer(int address, int size, bool repeat = false)
{
Buffer buf = createBuffer(size);
@ -478,6 +496,7 @@ namespace pins {
* Write bytes to a 7-bit I2C `address`.
*/
//%
//% group="i2c"
int i2cWriteBuffer(int address, Buffer buf, bool repeat = false)
{
return uBit.i2c.write(address << 1, (BUFFER_TYPE)buf->data, buf->length, repeat);
@ -496,6 +515,7 @@ namespace pins {
*/
//% help=pins/spi-write weight=5 advanced=true
//% blockId=spi_write block="spi write %value"
//% group="spi"
int spiWrite(int value) {
auto p = allocSPI();
return p->write(value);
@ -507,6 +527,7 @@ namespace pins {
* @param response Data received from the SPI slave (can be null)
*/
//% help=pins/spi-transfer argsNullable
//% group="spi"
void spiTransfer(Buffer command, Buffer response) {
if (!command && !response)
target_panic(PANIC_INVALID_ARGUMENT);
@ -531,6 +552,7 @@ namespace pins {
*/
//% help=pins/spi-frequency weight=4 advanced=true
//% blockId=spi_frequency block="spi frequency %frequency"
//% group="spi"
void spiFrequency(int frequency) {
auto p = allocSPI();
p->frequency(frequency);
@ -543,6 +565,7 @@ namespace pins {
*/
//% help=pins/spi-format weight=3 advanced=true
//% blockId=spi_format block="spi format|bits %bits|mode %mode"
//% group="spi"
void spiFormat(int bits, int mode) {
auto p = allocSPI();
p->format(bits, mode);
@ -566,6 +589,7 @@ namespace pins {
//% miso.fieldOptions.tooltips="false" miso.fieldOptions.width="250"
//% sck.fieldEditor="gridpicker" sck.fieldOptions.columns=4
//% sck.fieldOptions.tooltips="false" sck.fieldOptions.width="250"
//% group="spi"
void spiPins(DigitalPin mosi, DigitalPin miso, DigitalPin sck) {
if (NULL != spi) {
delete spi;
@ -578,6 +602,7 @@ namespace pins {
* Mounts a push button on the given pin
*/
//% help=pins/push-button advanced=true
//% group="Digital"
void pushButton(DigitalPin pin) {
new MicroBitButton((PinName)getPin((int)(pin))->name, (int)pin, MICROBIT_BUTTON_ALL_EVENTS, PinMode::PullUp);
}
@ -592,6 +617,7 @@ namespace pins {
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% weight=1
//% blockHidden=true
//% group="Pitch"
void setAudioPin(AnalogPin name) {
#if MICROBIT_CODAL
uBit.audio.setPin(*getPin((int)name));

View File

@ -3,6 +3,8 @@
*/
//% color=#A80000 weight=30 icon="\uf140"
//% advanced=true
//% groups=['Analog', 'Digital', 'Servos', 'Pulse', 'Pitch', 'i2c', 'spi']
namespace pins {
/**
* Map 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.
@ -14,6 +16,7 @@ namespace pins {
*/
//% help=pins/map weight=23
//% blockId=pin_map block="map %value|from low %fromLow|from high %fromHigh|to low %toLow|to high %toHigh"
//% deprecated=true
export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number {
return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow;
}
@ -23,6 +26,7 @@ namespace pins {
*/
//% help=pins/i2c-read-number blockGap=8 advanced=true
//% blockId=pins_i2c_readnumber block="i2c read number|at address %address|of format %format|repeated %repeat" weight=7
//% group="i2c"
export function i2cReadNumber(address: number, format: NumberFormat, repeated?: boolean): number {
let buf = pins.i2cReadBuffer(address, pins.sizeOf(format), repeated)
return buf.getNumber(format, 0)
@ -33,6 +37,7 @@ namespace pins {
*/
//% help=pins/i2c-write-number blockGap=8 advanced=true
//% blockId=i2c_writenumber block="i2c write number|at address %address|with value %value|of format %format|repeated %repeat" weight=6
//% group="i2c"
export function i2cWriteNumber(address: number, value: number, format: NumberFormat, repeated?: boolean): void {
let buf = createBuffer(pins.sizeOf(format))
buf.setNumber(format, 0, value)

View File

@ -116,6 +116,7 @@
"pairing_mode": 1,
"private_addressing": 0,
"open": 1,
"partial_flashing": 1,
"security_level": null,
"whitelist": 1,
"advertising_timeout": 0,
@ -125,7 +126,7 @@
"device_info_service": 0
},
"stack_size": 1280,
"gatt_table_size": "0x600",
"gatt_table_size": "0x200",
"panic_on_heap_full": 0,
"debug": 0,
"heap_debug": 0,
@ -139,8 +140,9 @@
"config": {
"microbit-dal": {
"stack_size": 2048,
"gatt_table_size": "0x700",
"sram_end": "0x20008000",
"RAM_SIZE": "\"16K\""
"RAM_SIZE": "\"32K\""
}
}
},
@ -149,6 +151,7 @@
"config": {
"microbit-dal": {
"stack_size": 1280,
"gatt_table_size": "0x200",
"sram_end": "0x20004000",
"RAM_SIZE": "\"16K\""
}

117
libs/core/shims.d.ts vendored
View File

@ -160,7 +160,7 @@ declare namespace basic {
//% text.shadowOptions.toString=true
//% expandableArgumentMode="toggle"
//%
//% group="LED matrix" interval.defl=80 shim=basic::showString
//% group="LED matrix" interval.defl=150 shim=basic::showString
function showString(text: string, interval?: int32): void;
/**
@ -277,7 +277,7 @@ declare namespace input {
* @param name the pin, eg: TouchPin.P0
* @param body the code to run when event is fired on pin
*/
//% help=input/on-pin-touch weight=99 blockGap=16
//% help=input/on-pin-event weight=99 blockGap=16
//% blockId=device_pin_custom_event block="on pin %name| %eventType=control_button_event_value_id"
//% group="Events" shim=input::onPinTouchEvent
function onPinTouchEvent(name: TouchPin, eventType: int32, body: () => void): void;
@ -294,6 +294,41 @@ declare namespace input {
//% group="States" shim=input::buttonIsPressed
function buttonIsPressed(button: Button): boolean;
/**
* Do something when a button (A, B or both A+B) is pushed down and released again.
* @param button the button that needs to be pressed
* @param body code to run when event is raised
*/
//% help=input/on-button-pressed weight=85 blockGap=16
//% blockId=device_button_event block="on button|%NAME|pressed"
//% parts="buttonpair"
//% deprecated=true
//% group="Events" shim=input::onButtonPressed
function onButtonPressed(button: Button, body: () => void): void;
/**
* Do something when a pin is touched and released again (while also touching the GND pin).
* @param name the pin that needs to be pressed, eg: TouchPin.P0
* @param body the code to run when the pin is pressed
*/
//% help=input/on-pin-pressed weight=83 blockGap=16
//% blockId=device_pin_event block="on pin %name|pressed"
//% group="Events"
//% deprecated=true shim=input::onPinPressed
function onPinPressed(name: TouchPin, body: () => void): void;
/**
* Do something when a pin is released.
* @param name the pin that needs to be released, eg: TouchPin.P0
* @param body the code to run when the pin is released
*/
//% help=input/on-pin-released weight=6 blockGap=16
//% blockId=device_pin_released block="on pin %NAME|released"
//% advanced=true
//% group="Events"
//% deprecated=true shim=input::onPinReleased
function onPinReleased(name: TouchPin, body: () => void): 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, eg: TouchPin.P0
@ -783,7 +818,8 @@ declare namespace pins {
//% help=pins/digital-read-pin weight=30
//% blockId=device_get_digital_pin block="digital read|pin %name" blockGap=8
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250" shim=pins::digitalReadPin
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Digital" shim=pins::digitalReadPin
function digitalReadPin(name: DigitalPin): int32;
/**
@ -795,7 +831,8 @@ declare namespace pins {
//% blockId=device_set_digital_pin block="digital write|pin %name|to %value"
//% value.min=0 value.max=1
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250" shim=pins::digitalWritePin
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Digital" shim=pins::digitalWritePin
function digitalWritePin(name: DigitalPin, value: int32): void;
/**
@ -805,7 +842,8 @@ declare namespace pins {
//% help=pins/analog-read-pin weight=25
//% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8"
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250" shim=pins::analogReadPin
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Analog" shim=pins::analogReadPin
function analogReadPin(name: AnalogPin): int32;
/**
@ -817,7 +855,8 @@ declare namespace pins {
//% blockId=device_set_analog_pin block="analog write|pin %name|to %value" blockGap=8
//% value.min=0 value.max=1023
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250" shim=pins::analogWritePin
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Analog" shim=pins::analogWritePin
function analogWritePin(name: AnalogPin, value: int32): void;
/**
@ -829,7 +868,8 @@ declare namespace pins {
//% help=pins/analog-set-period weight=23 blockGap=8
//% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros"
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false" shim=pins::analogSetPeriod
//% pin.fieldOptions.tooltips="false"
//% group="Analog" shim=pins::analogSetPeriod
function analogSetPeriod(name: AnalogPin, micros: int32): void;
/**
@ -840,7 +880,8 @@ declare namespace pins {
//% help=pins/on-pulsed weight=22 blockGap=16 advanced=true
//% blockId=pins_on_pulsed block="on|pin %pin|pulsed %pulse"
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250" shim=pins::onPulsed
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250"
//% group="Pulse" shim=pins::onPulsed
function onPulsed(name: DigitalPin, pulse: PulseValue, body: () => void): void;
/**
@ -848,7 +889,8 @@ declare namespace pins {
*/
//% help=pins/pulse-duration advanced=true
//% blockId=pins_pulse_duration block="pulse duration (µs)"
//% weight=21 blockGap=8 shim=pins::pulseDuration
//% weight=21 blockGap=8
//% group="Pulse" shim=pins::pulseDuration
function pulseDuration(): int32;
/**
@ -861,7 +903,8 @@ declare namespace pins {
//% weight=20 advanced=true
//% help=pins/pulse-in
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250" maxDuration.defl=2000000 shim=pins::pulseIn
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Pulse" maxDuration.defl=2000000 shim=pins::pulseIn
function pulseIn(name: DigitalPin, value: PulseValue, maxDuration?: int32): int32;
/**
@ -874,13 +917,15 @@ declare namespace pins {
//% parts=microservo trackArgs=0
//% value.min=0 value.max=180
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250" shim=pins::servoWritePin
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% group="Servo" shim=pins::servoWritePin
function servoWritePin(name: AnalogPin, value: int32): void;
/**
* Specifies that a continuous servo is connected.
*/
//% shim=pins::servoSetContinuous
//%
//% group="Servo" shim=pins::servoSetContinuous
function servoSetContinuous(name: AnalogPin, value: boolean): void;
/**
@ -891,7 +936,8 @@ declare namespace pins {
//% help=pins/servo-set-pulse weight=19
//% blockId=device_set_servo_pulse block="servo set pulse|pin %value|to (µs) %micros"
//% value.fieldEditor="gridpicker" value.fieldOptions.columns=4
//% value.fieldOptions.tooltips="false" value.fieldOptions.width="250" shim=pins::servoSetPulse
//% value.fieldOptions.tooltips="false" value.fieldOptions.width="250"
//% group="Servo" shim=pins::servoSetPulse
function servoSetPulse(name: AnalogPin, micros: int32): void;
/**
@ -902,7 +948,8 @@ declare namespace pins {
//% help=pins/analog-set-pitch-pin weight=3 advanced=true
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% blockHidden=true shim=pins::analogSetPitchPin
//% blockHidden=true
//% group="Pitch" shim=pins::analogSetPitchPin
function analogSetPitchPin(name: AnalogPin): void;
/**
@ -912,7 +959,8 @@ declare namespace pins {
//% blockId=device_analog_set_pitch_volume block="analog set pitch volume $volume"
//% help=pins/analog-set-pitch-volume weight=3 advanced=true
//% volume.min=0 volume.max=255
//% blockHidden=true shim=pins::analogSetPitchVolume
//% blockHidden=true
//% group="Pitch" shim=pins::analogSetPitchVolume
function analogSetPitchVolume(volume: int32): void;
/**
@ -920,7 +968,8 @@ declare namespace pins {
*/
//% blockId=device_analog_pitch_volume block="analog pitch volume"
//% help=pins/analog-pitch-volume weight=3 advanced=true
//% blockHidden=true shim=pins::analogPitchVolume
//% blockHidden=true
//% group="Pitch" shim=pins::analogPitchVolume
function analogPitchVolume(): int32;
/**
@ -930,7 +979,8 @@ declare namespace pins {
*/
//% blockId=device_analog_pitch block="analog pitch %frequency|for (ms) %ms"
//% help=pins/analog-pitch weight=4 async advanced=true blockGap=8
//% blockHidden=true shim=pins::analogPitch
//% blockHidden=true
//% group="Pitch" shim=pins::analogPitch
function analogPitch(frequency: int32, ms: int32): void;
/**
@ -941,7 +991,8 @@ declare namespace pins {
//% help=pins/set-pull weight=3 advanced=true
//% blockId=device_set_pull block="set pull|pin %pin|to %pull"
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250" shim=pins::setPull
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250"
//% group="Digital" shim=pins::setPull
function setPull(name: DigitalPin, pull: PinPullMode): void;
/**
@ -953,7 +1004,8 @@ declare namespace pins {
//% help=pins/set-events weight=4 advanced=true
//% blockId=device_set_pin_events block="set pin %pin|to emit %type|events"
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250" shim=pins::setEvents
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250"
//% group="Digital" shim=pins::setEvents
function setEvents(name: DigitalPin, type: PinEventType): void;
/**
@ -980,13 +1032,15 @@ declare namespace pins {
/**
* Read `size` bytes from a 7-bit I2C `address`.
*/
//% repeat.defl=0 shim=pins::i2cReadBuffer
//%
//% group="i2c" repeat.defl=0 shim=pins::i2cReadBuffer
function i2cReadBuffer(address: int32, size: int32, repeat?: boolean): Buffer;
/**
* Write bytes to a 7-bit I2C `address`.
*/
//% repeat.defl=0 shim=pins::i2cWriteBuffer
//%
//% group="i2c" repeat.defl=0 shim=pins::i2cWriteBuffer
function i2cWriteBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;
/**
@ -994,7 +1048,8 @@ declare namespace pins {
* @param value Data to be sent to the SPI slave
*/
//% help=pins/spi-write weight=5 advanced=true
//% blockId=spi_write block="spi write %value" shim=pins::spiWrite
//% blockId=spi_write block="spi write %value"
//% group="spi" shim=pins::spiWrite
function spiWrite(value: int32): int32;
/**
@ -1002,7 +1057,8 @@ declare namespace pins {
* @param command Data to be sent to the SPI slave (can be null)
* @param response Data received from the SPI slave (can be null)
*/
//% help=pins/spi-transfer argsNullable shim=pins::spiTransfer
//% help=pins/spi-transfer argsNullable
//% group="spi" shim=pins::spiTransfer
function spiTransfer(command: Buffer, response: Buffer): void;
/**
@ -1010,7 +1066,8 @@ declare namespace pins {
* @param frequency the clock frequency, eg: 1000000
*/
//% help=pins/spi-frequency weight=4 advanced=true
//% blockId=spi_frequency block="spi frequency %frequency" shim=pins::spiFrequency
//% blockId=spi_frequency block="spi frequency %frequency"
//% group="spi" shim=pins::spiFrequency
function spiFrequency(frequency: int32): void;
/**
@ -1019,7 +1076,8 @@ declare namespace pins {
* @param mode the mode, eg: 3
*/
//% help=pins/spi-format weight=3 advanced=true
//% blockId=spi_format block="spi format|bits %bits|mode %mode" shim=pins::spiFormat
//% blockId=spi_format block="spi format|bits %bits|mode %mode"
//% group="spi" shim=pins::spiFormat
function spiFormat(bits: int32, mode: int32): void;
/**
@ -1033,13 +1091,15 @@ declare namespace pins {
//% miso.fieldEditor="gridpicker" miso.fieldOptions.columns=4
//% miso.fieldOptions.tooltips="false" miso.fieldOptions.width="250"
//% sck.fieldEditor="gridpicker" sck.fieldOptions.columns=4
//% sck.fieldOptions.tooltips="false" sck.fieldOptions.width="250" shim=pins::spiPins
//% sck.fieldOptions.tooltips="false" sck.fieldOptions.width="250"
//% group="spi" shim=pins::spiPins
function spiPins(mosi: DigitalPin, miso: DigitalPin, sck: DigitalPin): void;
/**
* Mounts a push button on the given pin
*/
//% help=pins/push-button advanced=true shim=pins::pushButton
//% help=pins/push-button advanced=true
//% group="Digital" shim=pins::pushButton
function pushButton(pin: DigitalPin): void;
/**
@ -1051,7 +1111,8 @@ declare namespace pins {
//% name.fieldEditor="gridpicker" name.fieldOptions.columns=4
//% name.fieldOptions.tooltips="false" name.fieldOptions.width="250"
//% weight=1
//% blockHidden=true shim=pins::setAudioPin
//% blockHidden=true
//% group="Pitch" shim=pins::setAudioPin
function setAudioPin(name: AnalogPin): void;
}

6803
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "pxt-calliopemini",
"version": "4.0.20",
"version": "4.0.26",
"description": "calliope mini target for Microsoft MakeCode (PXT)",
"keywords": [
"JavaScript",
@ -46,6 +46,6 @@
},
"dependencies": {
"pxt-common-packages": "9.0.1",
"pxt-core": "7.0.16"
"pxt-core": "7.0.17"
}
}

View File

@ -165,9 +165,9 @@
"simulator": {
"autoRun": true,
"streams": false,
"aspectRatio": 1.13,
"aspectRatio": 0.94,
"parts": false,
"partsAspectRatio": 0.69,
"partsAspectRatio": 0.7,
"boardDefinition": {
"visual": "calliope",
"gpioPinBlocks": [

View File

@ -1,5 +1,25 @@
namespace pxsim.visuals {
const MB_STYLE = `
.simEventBtn {
font-size: 1.4rem;
font-weight: 900;
padding: 1.25rem 1.75rem;
border-radius: 3.5rem / 100%;
border: 0;
cursor: pointer;
text-transform: uppercase;
letter-spacing: 0.07em;
color: white;
background: #42c9c9;
font-family: 'Roboto Mono', monospace;
}
button:hover {
opacity: .7;
}
button:active {
background: #e6007d;
}
svg.sim {
margin-bottom:1em;
}
@ -28,15 +48,16 @@ namespace pxsim.visuals {
.sim-button-nut:hover {
stroke:1px solid #704A4A;
}
.sim-pin {
cursor: pointer;
}
.sim-pin:hover {
stroke:#D4AF37;
stroke-width:2px;
}
.sim-pin-touch.touched:hover {
stroke:darkorange;
}
.sim-led-back:hover {
stroke:#fff;
stroke-width:3px;
@ -64,16 +85,16 @@ namespace pxsim.visuals {
}
.sim-text {
font-family:"Lucida Console", Monaco, monospace;
font-family: 'Roboto Mono', monospace;
font-size:14px;
fill:#fff;
pointer-events: none; user-select: none;
}
.sim-text-pin {
font-family:"Lucida Console", Monaco, monospace;
font-family: 'Roboto Mono', monospace;
pointer-events: none; user-select: none;
fill:#3cb5b5;
fill:#000;
font-size:24px;
stroke:#fff;
stroke-alignment: outside;
@ -187,10 +208,34 @@ namespace pxsim.visuals {
-webkit-user-select: none;
-ms-user-select: none;
}
.shake_animation {
animation: shake 0.42s cubic-bezier(.36,.07,.19,.97) both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
}
@keyframes shake {
10%, 90% {
transform: translate3d(-1px, 0, 0);
}
20%, 80% {
transform: translate3d(2px, 0, 0);
}
30%, 50%, 70% {
transform: translate3d(-4px, 0, 0);
}
40%, 60% {
transform: translate3d(4px, 0, 0);
}
}
`;
const BOARD_SVG = `<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 530 530" style="enable-background:new 0 0 530 530;" xml:space="preserve">
y="0px" viewBox="0 0 530 630" style="enable-background:new 0 0 530 630;" xml:space="preserve">
<style type="text/css">
.st0{fill:#044854;}
.st1{fill:none;stroke:#989899;stroke-width:0.5;stroke-linecap:square;stroke-miterlimit:10;}
@ -211,6 +256,7 @@ namespace pxsim.visuals {
.st16{fill:#E6007D;}
.st17{fill:#000000;}
</style>
<g id="calliope_mini">
<path id="mini_Board" class="st0" d="M552.7,263.2c-0.8-12-8.7-22.4-20.1-26.3c-4.4-1.5-8.8-3.3-13-5.4c-4.6-2.3-9.1-4.9-13.4-7.7
l0,0c-16.3-10.7-35.1-27.7-55.4-54.2c-29.5-38.6-28.6-86.6-25.7-117c0.8-2.9,1.3-6,1.3-9c0-18.5-15-33.5-33.5-33.5
c-10.3,0-20.1,4.8-26.4,12.9c-0.2,0.3-0.5,0.6-0.7,0.9C343.1,39.3,319.6,50,295,54.8c-1.9,0.4-3.7,0.8-5.6,1.2l0,0
@ -647,18 +693,18 @@ namespace pxsim.visuals {
</g>
</g>
<g id="EDGE_PINS">
<path id="EDGE_P3" class="st11" d="M520.9,231.4c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5
<path id="EDGE_P3" class="" d="M520.9,231.4c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5
c18.5,0,33.5-14.9,33.5-33.4c0.1-18.5-14.9-33.5-33.3-33.6C521,231.4,521,231.4,520.9,231.4z M520.9,280.6c-8.7,0-15.7-7-15.7-15.7
c0-8.7,7-15.7,15.7-15.7c8.7,0,15.7,7,15.7,15.7c0,0,0,0,0,0C536.6,273.5,529.6,280.6,520.9,280.6
C520.9,280.6,520.9,280.6,520.9,280.6L520.9,280.6z"/>
<path id="EDGE_P2" class="st11" d="M392.7,452c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5c18.5,0,33.5-15,33.5-33.5
<path id="EDGE_P2" class="" d="M392.7,452c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5c18.5,0,33.5-15,33.5-33.5
c0,0,0,0,0,0C426.2,467,411.2,452,392.7,452C392.7,452,392.7,452,392.7,452z M392.7,501.1c-8.7,0-15.7-7-15.7-15.7
c0-8.7,7-15.7,15.7-15.7c8.7,0,15.7,7,15.7,15.7c0,0,0,0,0,0c0.1,8.7-6.9,15.7-15.6,15.8C392.8,501.2,392.7,501.2,392.7,501.1
L392.7,501.1z"/>
<path id="EDGE_P1" class="st11" d="M137.1,452c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5c18.5,0,33.5-15,33.5-33.5
<path id="EDGE_P1" class="" d="M137.1,452c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5c18.5,0,33.5-15,33.5-33.5
c0,0,0,0,0,0C170.6,467,155.6,452,137.1,452L137.1,452z M137.1,501.1c-8.7,0-15.7-7-15.7-15.7c0-8.7,7-15.7,15.7-15.7
c8.7,0,15.7,7,15.7,15.7c0,0,0,0,0,0c0.1,8.7-6.9,15.7-15.6,15.8C137.2,501.2,137.1,501.2,137.1,501.1L137.1,501.1z"/>
<path id="EDGE_P0" class="st11" d="M8.1,231.4c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5c18.4,0,33.4-14.9,33.5-33.4
<path id="EDGE_P0" class="" d="M8.1,231.4c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5c18.4,0,33.4-14.9,33.5-33.4
c0.1-18.5-14.9-33.5-33.3-33.6C8.2,231.4,8.1,231.4,8.1,231.4z M8.1,280.6c-8.7,0-15.7-7-15.7-15.7c0-8.7,7-15.7,15.7-15.7
c8.7,0,15.7,7,15.7,15.7c0,0,0,0,0,0C23.8,273.5,16.8,280.6,8.1,280.6C8.1,280.6,8.1,280.6,8.1,280.6L8.1,280.6z"/>
<path id="EDGE_VCC" class="st11" d="M392.7,10c-18.5,0-33.5,15-33.5,33.5c0,18.5,15,33.5,33.5,33.5c18.5,0,33.5-15,33.5-33.5
@ -668,11 +714,14 @@ namespace pxsim.visuals {
c0,0,0,0,0,0C170.6,25,155.6,10,137.1,10L137.1,10z M137.1,59.2c-8.7,0-15.7-7-15.7-15.7c0-8.7,7-15.7,15.7-15.7
c8.7,0,15.7,7,15.7,15.7c0,0,0,0,0,0C152.8,52.1,145.8,59.2,137.1,59.2C137.1,59.2,137.1,59.2,137.1,59.2z"/>
</g>
</g>
</svg>`;
const pinNames = [
"BTN_A", "BTN_B",
"EDGE_P0", "EDGE_P1", "EDGE_P2", "EDGE_P3", "EDGE_GND", "EDGE_VCC",
"BTN_A", "BTN_B",
"C_GND1", "C_GND2", "C_GND3", "C_GND4", "C_VCC1", "C_VCC2",
"C_P0", "C_P2", "C_P4", "C_P6", "C_P8", "C_P10", "C_P12", "C_P14", "C_P16", "C_P18",
"C_P1", "C_P3", "C_P5", "C_P7", "C_P9", "C_P11", "C_P13", "C_P15", "C_P17", "C_P19",
@ -681,8 +730,9 @@ namespace pxsim.visuals {
"G_A1_RX", "G_A1_TX", "G_A1_VCC", "G_A1_GND"
];
const pinTitles = [
"Button A", "Button B",
"P0", "P1, ANALOG IN", "P2, ANALOG IN", "P3", "GND", "+3v3",
"Button A", "Button B",
"GND", "GND", "GND", "GND", "+3v3", "+3v3",
"C0", "C2", "C4", "C6", "C8", "C10", "C12", "C14", "C16", "C18",
"C1", "C3", "C5", "C7", "C9", "C11", "C13", "C15", "C17", "C19",
@ -691,7 +741,7 @@ namespace pxsim.visuals {
"C16, Serial - RX", "C17, Serial - TX", "+3v3", "GND"
];
const MB_WIDTH = 530;
const MB_HEIGHT = 530;
const MB_HEIGHT = 630;
export interface IBoardTheme {
accent?: string;
display?: string;
@ -715,9 +765,9 @@ namespace pxsim.visuals {
export var themes: IBoardTheme[] = ["#3ADCFE"].map(accent => {
return {
accent: accent,
pin: "#EFDA48",
pin: "#F6C426",
pinTouched: "#FFA500",
pinActive: "#FF5500",
pinActive: "#E6007D",
ledOn: "#ff5555",
ledOff: "#e0e1e2",
buttonOuter: "#979797",
@ -760,7 +810,7 @@ namespace pxsim.visuals {
private display: SVGElement;
private buttons: SVGElement[];
private buttonsOuter: SVGElement[];
private buttonABText: SVGTextElement;
// private buttonABText: SVGTextElement;
private pins: SVGElement[];
private pinGradients: SVGLinearGradientElement[];
private pinTexts:{ [key: number]: SVGTextElement };
@ -781,7 +831,7 @@ namespace pxsim.visuals {
private soundLevelText: SVGTextElement;
private soundLevelIcon: SVGTextElement;
private shakeButton: SVGElement;
private shakeText: SVGTextElement;
// private shakeText: SVGTextElement;
public board: pxsim.DalBoard;
private domHardwareVersion = 1;
private rgbLed: SVGElement;
@ -1041,7 +1091,7 @@ namespace pxsim.visuals {
svg.fills(this.leds, theme.ledOn);
svg.fills(this.ledsOuter, theme.ledOff);
svg.fills(this.buttonsOuter.slice(0, 2), theme.buttonOuter);
svg.fills(this.buttonsOuter.slice(6, 8), theme.buttonOuter);
svg.fill(this.buttons[0], theme.buttonUps[0]);
svg.fill(this.buttons[1], theme.buttonUps[1]);
svg.fill(this.buttonsOuter[2], theme.virtualButtonOuter);
@ -1135,21 +1185,28 @@ namespace pxsim.visuals {
private updateGestures() {
let state = this.board;
if (state.accelerometerState.useShake && !this.shakeButton) {
let shake = this.mkBtn(280, MB_HEIGHT - 45);
let shake = this.mkBtn(240, MB_HEIGHT - 75, 'Schütteln');
this.shakeButton = shake.inner;
svg.fill(this.shakeButton, this.props.theme.virtualButtonUp)
let board = this.element.getElementById("calliope_mini")
console.log(board)
// svg.fill(this.shakeButton, this.props.theme.virtualButtonUp)
svg.buttonEvents(shake.outer,
ev => { },
(ev) => {
svg.fill(this.shakeButton, this.props.theme.virtualButtonDown)
svg.fill(this.shakeButton, this.props.theme.virtualButtonDown);
board.classList.remove("shake_animation");
setTimeout(()=>{
board.classList.add("shake_animation");
}, 1)
},
(ev) => {
svg.fill(this.shakeButton, this.props.theme.virtualButtonUp);
this.board.bus.queue(DAL.MICROBIT_ID_GESTURE, 11); // GESTURE_SHAKE
}
)
let shakeText = svg.child(shake.outer, "text", { x: 280, y: MB_HEIGHT - 5, class: "sim-text big inverted centered" }) as SVGTextElement;
shakeText.textContent = "SHAKE"
// let shakeText = svg.child(shake.outer, "text", { x: 280, y: MB_HEIGHT - 5, class: "sim-text big inverted centered" }) as SVGTextElement;
// shakeText.textContent = "SHAKE"
}
}
@ -1236,7 +1293,7 @@ namespace pxsim.visuals {
if (!this.thermometer) {
let gid = "gradient-thermometer";
this.thermometerGradient = svg.linearGradient(this.defs, gid);
const ty = MB_HEIGHT - 200;
const ty = MB_HEIGHT - 270;
this.thermometer = <SVGRectElement>svg.child(this.g, "rect", {
class: "sim-thermometer",
x: 0,
@ -1309,7 +1366,7 @@ namespace pxsim.visuals {
const level = state.microphoneState.getLevel();
let gid = "gradient-soundlevel";
this.soundLevelGradient = svg.linearGradient(this.defs, gid);
const ty = MB_HEIGHT - 200;
const ty = MB_HEIGHT - 270;
this.soundLevel = <SVGRectElement>svg.child(this.g, "rect", {
class: "sim-thermometer",
x: 490,
@ -1669,10 +1726,10 @@ namespace pxsim.visuals {
// ].map(p => <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin", x: p[0], y: p[1] }));
this.pinTexts = {
[DigitalPin.P0]: <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin big centered", x: 20, y: 315 }),
[DigitalPin.P1]: <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin big centered", x: 135, y: 530 }),
[DigitalPin.P2]: <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin big centered", x: 395, y: 530 }),
[DigitalPin.P3]: <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin big centered", x: 535, y: 315 })
[DigitalPin.P0]: <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin big centered", x: 20, y: 325 }),
[DigitalPin.P1]: <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin big centered", x: 135, y: 540 }),
[DigitalPin.P2]: <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin big centered", x: 395, y: 540 }),
[DigitalPin.P3]: <SVGTextElement>svg.child(this.g, "text", { class: "sim-text-pin big centered", x: 540, y: 325 })
}
// BTN A, B
@ -1684,39 +1741,52 @@ namespace pxsim.visuals {
// BTN A+B
const outerBtn = (left: number, top: number) => {
const button = this.mkBtn(left, top);
const button = this.mkBtn(left, top, 'A + B');
this.buttonsOuter.push(button.outer);
this.buttons.push(button.inner);
return button;
}
let ab = outerBtn(210, MB_HEIGHT - 45);
let abtext = svg.child(ab.outer, "text", { x: 210, y: MB_HEIGHT - 5, class: "sim-text big inverted centered" }) as SVGTextElement;
abtext.textContent = "A+B";
let ab = outerBtn(100, MB_HEIGHT - 75);
// let abtext = svg.child(ab.outer, "text", { x: 210, y: MB_HEIGHT - 5, class: "sim-text big inverted centered" }) as SVGTextElement;
// abtext.textContent = "A+B";
(<any>this.buttonsOuter[2]).style.visibility = "hidden";
(<any>this.buttons[2]).style.visibility = "hidden";
}
private mkBtn(left: number, top: number): { outer: SVGElement, inner: SVGElement } {
private mkBtn(left: number, top: number, text: string): { outer: SVGElement, inner: SVGElement } {
const btnr = 2;
const btnw = 20;
const btnn = 1.6;
const btnnm = 2;
const btnb = 5;
let btng = svg.child(this.g, "g", { class: "sim-button-group" });
svg.child(btng, "rect", { class: "sim-button-outer", x: left, y: top, rx: btnr, ry: btnr, width: btnw, height: btnw });
svg.child(btng, "circle", { class: "sim-button-nut", cx: left + btnnm, cy: top + btnnm, r: btnn });
svg.child(btng, "circle", { class: "sim-button-nut", cx: left + btnnm, cy: top + btnw - btnnm, r: btnn });
svg.child(btng, "circle", { class: "sim-button-nut", cx: left + btnw - btnnm, cy: top + btnw - btnnm, r: btnn });
svg.child(btng, "circle", { class: "sim-button-nut", cx: left + btnw - btnnm, cy: top + btnnm, r: btnn });
// var fo = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
var fo = svg.child(btng, "foreignObject");
fo.setAttribute("id", "y");
fo.setAttribute("x", left+'');
fo.setAttribute("y", top+'');
fo.setAttribute("width", "300");
fo.setAttribute("height", "100");
fo.innerHTML = `<body xmlns="http://www.w3.org/1999/xhtml">
<button class="simEventBtn">${text}</button>
</body>`;
// var ta = document.createElement("button");
// ta.innerText = text;
// fo.appendChild(ta);
// svg.child(btng, "rect", { class: "sim-button-outer", x: left, y: top, rx: btnr, ry: btnr, width: btnw, height: btnw });
// svg.child(btng, "circle", { class: "sim-button-nut", cx: left + btnnm, cy: top + btnnm, r: btnn });
// svg.child(btng, "circle", { class: "sim-button-nut", cx: left + btnnm, cy: top + btnw - btnnm, r: btnn });
// svg.child(btng, "circle", { class: "sim-button-nut", cx: left + btnw - btnnm, cy: top + btnw - btnnm, r: btnn });
// svg.child(btng, "circle", { class: "sim-button-nut", cx: left + btnw - btnnm, cy: top + btnnm, r: btnn });
const outer = btng;
const inner = svg.child(btng, "circle", {
class: "sim-button",
cx: left + btnw / 2,
cy: top + btnw / 2,
r: btnb
r: 0
});
return { outer, inner };
@ -1798,12 +1868,12 @@ namespace pxsim.visuals {
}
private attachPinsIOEvents() {
this.pins.slice(2, 6).forEach((pin, index) => {
this.pins.slice(0, 4).forEach((pin, index) => {
// var index = i + 2;
if (!this.board.edgeConnectorState.pins[index]) return;
let pt = this.element.createSVGPoint();
let xpos = (index === 0 || index === 3) ? 300 : 520;
let vMax = (index === 0 || index === 3) ? 1 : 1032;
let vMax = (index === 0 || index === 3) ? 1 : 1023;
svg.buttonEvents(pin,
// move
ev => {
@ -1863,8 +1933,8 @@ namespace pxsim.visuals {
}
private attachPinsTouchEvents() {
this.pins.slice(2, 6).forEach((btn, i) => {
var index = i + 2;
this.pins.slice(0, 4).forEach((btn, i) => {
var index = i;
let state = this.board;
let pressedTime: number;
pointerEvents.down.forEach(evid => btn.addEventListener(evid, ev => {
@ -1908,8 +1978,8 @@ namespace pxsim.visuals {
private attachABEvents() {
const bpState = this.board.buttonPairState;
const stateButtons: Button[] = [bpState.aBtn, bpState.bBtn];
const elButtonOuters = this.buttonsOuter.slice(0, 2);
const elButtons = this.buttons.slice(0, 2);
const elButtonOuters = this.buttonsOuter.slice(0,2);
const elButtons = this.buttons.slice(0,2);
elButtonOuters.forEach((btn, index) => {
let pressedTime: number;
@ -1945,6 +2015,7 @@ namespace pxsim.visuals {
private attachAPlusBEvents() {
const bpState = this.board.buttonPairState;
const stateButtons: Button[] = [bpState.aBtn, bpState.bBtn];
let pressedTime: number;
// A+B
pointerEvents.down.forEach(evid => this.buttonsOuter[2].addEventListener(evid, ev => {
@ -1954,6 +2025,8 @@ namespace pxsim.visuals {
svg.fill(this.buttons[0], this.props.theme.buttonDown);
svg.fill(this.buttons[1], this.props.theme.buttonDown);
svg.fill(this.buttons[2], this.props.theme.buttonDown);
this.board.bus.queue(stateButtons[0].id, DAL.MICROBIT_BUTTON_EVT_DOWN);
this.board.bus.queue(stateButtons[1].id, DAL.MICROBIT_BUTTON_EVT_DOWN);
this.board.bus.queue(bpState.abBtn.id, DAL.MICROBIT_BUTTON_EVT_DOWN);
pressedTime = runtime.runningTime()
}));
@ -1973,6 +2046,8 @@ namespace pxsim.visuals {
svg.fill(this.buttons[1], this.props.theme.buttonUps[1]);
svg.fill(this.buttons[2], this.props.theme.virtualButtonUp);
this.board.bus.queue(stateButtons[0].id, DAL.MICROBIT_BUTTON_EVT_UP);
this.board.bus.queue(stateButtons[1].id, DAL.MICROBIT_BUTTON_EVT_UP);
this.board.bus.queue(bpState.abBtn.id, DAL.MICROBIT_BUTTON_EVT_UP);
const currentTime = runtime.runningTime()
if (currentTime - pressedTime > DAL.DEVICE_BUTTON_LONG_CLICK_TIME)

View File

@ -5,6 +5,8 @@
"51bit/SFC",
"51bit/SmartTools",
"51bit/dfplayermini",
"coding4coconut/pxt-lcd128x160-st7735s",
"coding4coconut/pxt-oled128x128-sh1107",
"Freenove/Makecode-Extension-Starter-Kit",
"joernalraun/pxt-remember-int",
"KitronikLtd/pxt-kitronik-I2C-16-servo",