Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
498b5ec095 | |||
912be2ddfd | |||
6d7f8c5841 | |||
a782f4731a | |||
6e067bffd5 | |||
4a4007ba41 | |||
c9db08a2c6 | |||
5ec303b95c | |||
3d0523a298 | |||
d791738d84 | |||
355c341d36 | |||
1adb4a2bac | |||
03c0339e9a | |||
1649811015 | |||
14f16f9b2c | |||
66d3c6c7e8 | |||
7f27432222 | |||
870b26a85a | |||
aa6cb58dca | |||
6398a42dad | |||
21473f5b9b | |||
c85b6f9507 | |||
019b00209e | |||
6c11dbcdf4 | |||
91197c5cec | |||
9e5d9787c7 | |||
1c11a4823b | |||
d457c3e8d0 | |||
2ae21efb7b | |||
485a42758c | |||
0da5a5a349 | |||
41ce2f66fa | |||
9393fc166e | |||
cfb4382941 | |||
aaca24ff5b | |||
0ce9be1a2b | |||
a88eb7fe02 | |||
06e4f7fb5c | |||
1b36485208 | |||
3b54cefa95 | |||
52857c9541 | |||
d10c2a20bd |
@ -7,6 +7,10 @@ PXT ([Microsoft Programming Experience Toolkit](https://github.com/Microsoft/pxt
|
||||
|
||||
[](https://travis-ci.org/Microsoft/pxt-microbit)
|
||||
|
||||
## Issue tracking
|
||||
|
||||
All issue tracking for this repo happens at https://github.com/Microsoft/pxt, see you there!
|
||||
|
||||
## Local server
|
||||
|
||||
The local server allows to run the editor and the documentation from your computer.
|
||||
|
60
cmds/cmds.ts
60
cmds/cmds.ts
@ -1,60 +0,0 @@
|
||||
/// <reference path="../node_modules/pxt-core/typings/node/node.d.ts"/>
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtlib.d.ts" />
|
||||
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as child_process from "child_process";
|
||||
|
||||
let writeFileAsync: any = Promise.promisify(fs.writeFile)
|
||||
let execAsync: (cmd: string, options?: { cwd?: string }) => Promise<Buffer> = Promise.promisify(child_process.exec)
|
||||
let readDirAsync = Promise.promisify(fs.readdir)
|
||||
|
||||
|
||||
export function deployCoreAsync(res: ts.pxtc.CompileResult) {
|
||||
return getBitDrivesAsync()
|
||||
.then(drives => {
|
||||
if (drives.length == 0) {
|
||||
console.log("cannot find any drives to deploy to");
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
|
||||
console.log(`copy ${ts.pxtc.BINARY_HEX} to ` + drives.join(", "));
|
||||
|
||||
let writeHexFile = (filename: string) => {
|
||||
return writeFileAsync(filename + ts.pxtc.BINARY_HEX, res.outfiles[ts.pxtc.BINARY_HEX])
|
||||
.then(() => console.log("wrote hex file to " + filename));
|
||||
};
|
||||
|
||||
return Promise.map(drives, d => writeHexFile(d))
|
||||
.then(() => drives.length);
|
||||
});
|
||||
}
|
||||
|
||||
function getBitDrivesAsync(): Promise<string[]> {
|
||||
if (process.platform == "win32") {
|
||||
const rx = new RegExp("^([A-Z]:).* " + pxt.appTarget.compile.deployDrives)
|
||||
return execAsync("wmic PATH Win32_LogicalDisk get DeviceID, VolumeName, FileSystem")
|
||||
.then(buf => {
|
||||
let res: string[] = []
|
||||
buf.toString("utf8").split(/\n/).forEach(ln => {
|
||||
let m = rx.exec(ln)
|
||||
if (m) {
|
||||
res.push(m[1] + "/")
|
||||
}
|
||||
})
|
||||
return res
|
||||
})
|
||||
}
|
||||
else if (process.platform == "darwin") {
|
||||
const rx = new RegExp(pxt.appTarget.compile.deployDrives)
|
||||
return readDirAsync("/Volumes")
|
||||
.then(lst => lst.filter(s => rx.test(s)).map(s => "/Volumes/" + s + "/"))
|
||||
} else if (process.platform == "linux") {
|
||||
const rx = new RegExp(pxt.appTarget.compile.deployDrives)
|
||||
const user = process.env["USER"]
|
||||
return readDirAsync(`/media/${user}`)
|
||||
.then(lst => lst.filter(s => rx.test(s)).map(s => `/media/${user}/${s}/`))
|
||||
} else {
|
||||
return Promise.resolve([])
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
/// <reference path="../node_modules/pxt-core/typings/node/node.d.ts"/>
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtlib.d.ts" />
|
||||
|
||||
import * as path from "path";
|
||||
export let pxtCore = require("pxt-core");
|
||||
// require.resolve() gives path to [pxt dir]/built/pxt.js, so move up twice to get pxt root dir
|
||||
|
@ -10,12 +10,10 @@ Welcome! This guided tutorial will show you how to program a script that display
|
||||
|
||||
### ~
|
||||
|
||||
|
||||
## Step 1
|
||||
|
||||
Create a loop that will continuously update the reading of the compass.
|
||||
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
Use the LEDs to display a flashing heart, and then create
|
||||
an animation of a broken heart. :(
|
||||
Use the LEDs to display a flashing heart!
|
||||
|
||||
### ~
|
||||
|
||||
@ -38,19 +37,19 @@ basic.clearScreen();
|
||||
|
||||
## Step 3
|
||||
|
||||
Put a [forever loop](/reference/basic/forever) around it.
|
||||
Put a [forever loop](/reference/basic/forever) around it to repeat the animation.
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# # # # #
|
||||
# # # # #
|
||||
. # # # .
|
||||
. . # . .`
|
||||
);
|
||||
basic.pause(500);
|
||||
basic.clearScreen();
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# # # # #
|
||||
# # # # #
|
||||
. # # # .
|
||||
. . # . .`
|
||||
);
|
||||
basic.pause(500);
|
||||
basic.clearScreen();
|
||||
})
|
||||
```
|
||||
|
||||
@ -60,45 +59,50 @@ Add a [pause](/reference/basic/pause) to wait after clearing the screen.
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# # # # #
|
||||
# # # # #
|
||||
. # # # .
|
||||
. . # . .`
|
||||
);
|
||||
basic.pause(500);
|
||||
basic.clearScreen();
|
||||
basic.pause(500);
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# # # # #
|
||||
# # # # #
|
||||
. # # # .
|
||||
. . # . .`
|
||||
);
|
||||
basic.pause(500);
|
||||
basic.clearScreen();
|
||||
basic.pause(500);
|
||||
})
|
||||
```
|
||||
|
||||
## Step 5
|
||||
## Send your heartbeats over radio!
|
||||
|
||||
Add a second image of a broken heart.
|
||||
Do you have a second @boardname@ at hand? You could use radio and send your heartbeats to other
|
||||
@boardname@ and show a heart when you receive one.
|
||||
|
||||
* move the code in the **forever** inside
|
||||
a [on data packet received](/reference/radio/on-data-packet-received) handler.
|
||||
The handler will run whenever a message is received from another @boardname@.
|
||||
* use [send number](/reference/radio/send-number) and [pause](/reference/basic/pause)
|
||||
to broadcast a packet of data every second.
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# # # # #
|
||||
# # # # #
|
||||
. # # # .
|
||||
. . # . .`
|
||||
);
|
||||
basic.pause(500);
|
||||
basic.clearScreen();
|
||||
basic.pause(500);
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# . # # #
|
||||
# . . . #
|
||||
. # # # .
|
||||
. . # . .`
|
||||
);
|
||||
basic.pause(500);
|
||||
basic.clearScreen();
|
||||
basic.pause(500);
|
||||
radio.sendNumber(0)
|
||||
basic.pause(1000)
|
||||
})
|
||||
radio.onDataPacketReceived(({receivedNumber}) => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# # # # #
|
||||
# # # # #
|
||||
. # # # .
|
||||
. . # . .`);
|
||||
basic.pause(500)
|
||||
basic.clearScreen()
|
||||
basic.pause(500)
|
||||
})
|
||||
```
|
||||
|
||||
Download the .hex file onto both @boardname@ and try it out!
|
||||
|
||||
```package
|
||||
radio
|
||||
```
|
@ -12,8 +12,8 @@ Use [show leds](/reference/basic/show-leds) to make a smiley face:
|
||||
|
||||
```blocks
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. # . # .
|
||||
# # . # #
|
||||
# # . # #
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .`
|
||||
@ -22,56 +22,93 @@ basic.showLeds(`
|
||||
|
||||
## Step 2
|
||||
|
||||
Add an input block for when [button A is pressed](/reference/input/button-is-pressed), and put a
|
||||
frowny face inside it:
|
||||
Add an input block for when [button A is pressed](/reference/input/button-is-pressed),
|
||||
and **move** the smiley face inside it:
|
||||
|
||||
```blocks
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .`
|
||||
);
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. # . # .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #`
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
## Step 3
|
||||
|
||||
Now add blocks so that when [button B is pressed](/reference/input/button-is-pressed), a smiley appears:
|
||||
|
||||
```blocks
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .`
|
||||
);
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. # . # .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #`
|
||||
);
|
||||
});
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. # . # .
|
||||
# # . # #
|
||||
# # . # #
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .`
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
Try pressing button A!
|
||||
|
||||
## Step 3
|
||||
|
||||
Now add blocks so that when [button B is pressed](/reference/input/on-button-pressed),
|
||||
a frowney appears:
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
basic.showLeds(`
|
||||
# # . # #
|
||||
# # . # #
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .`
|
||||
);
|
||||
});
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
basic.showLeds(`
|
||||
# # . # #
|
||||
# # . # #
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #`
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
Try pressing ``A`` or ``B``!
|
||||
|
||||
## Send your smileys over radio
|
||||
|
||||
Do you have a second @boardname@ at hand? You could use radio and send your smileys or frownies to other
|
||||
@boardname@.
|
||||
|
||||
Since radio can send numbers, we decide that ``0`` is the code for displaying a smiley
|
||||
and ``1`` is the code for a frowney.
|
||||
|
||||
Change your code as follows:
|
||||
* [radio send number](/reference/radio/send-number) sends a number
|
||||
to any other @boardname@ in range
|
||||
* [radio on data packet received](/reference/radio/on-data-packet-received) runs code
|
||||
when data is received over radio
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
radio.sendNumber(0)
|
||||
})
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
radio.sendNumber(1)
|
||||
})
|
||||
radio.onDataPacketReceived(({receivedNumber}) => {
|
||||
if (receivedNumber == 0) {
|
||||
basic.showLeds(`
|
||||
# # . # #
|
||||
# # . # #
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
} else {
|
||||
basic.showLeds(`
|
||||
# # . # #
|
||||
# # . # #
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #
|
||||
`)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
```package
|
||||
radio
|
||||
```
|
||||
|
@ -19,6 +19,7 @@ bluetooth.startMagnetometerService();
|
||||
bluetooth.startTemperatureService();
|
||||
bluetooth.onBluetoothConnected(() => {});
|
||||
bluetooth.onBluetoothDisconnected(() => {});
|
||||
bluetooth.setTransmitPower(7);
|
||||
```
|
||||
|
||||
## UART
|
||||
|
@ -18,7 +18,7 @@ Read more at https://lancaster-university.github.io/microbit-docs/ble/eddystone/
|
||||
## ~
|
||||
|
||||
```sig
|
||||
bluetooth.advertiseUrl("https://pxt.microbit.org/", 7);
|
||||
bluetooth.advertiseUrl("https://pxt.microbit.org/", 7, true);
|
||||
```
|
||||
|
||||
### Parameters
|
||||
@ -29,7 +29,7 @@ bluetooth.advertiseUrl("https://pxt.microbit.org/", 7);
|
||||
### Example: Broadcast a secret code
|
||||
|
||||
```blocks
|
||||
bluetooth.advertiseUrl("https://pxt.io?secret=42", 7);
|
||||
bluetooth.advertiseUrl("https://pxt.io?secret=42", 7, true);
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
26
docs/reference/bluetooth/set-transmit-power.md
Normal file
26
docs/reference/bluetooth/set-transmit-power.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Bluetooth Set Transmit Power
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the @boardname@ has, it must first be [paired with the @boardname@](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the @boardname@ and exchange data relating to many of the @boardname@'s features.
|
||||
|
||||
### ~
|
||||
|
||||
Change the output power level of the transmitter to the given value.
|
||||
|
||||
```sig
|
||||
bluetooth.setTransmitPower(7);
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
* `power`: a [number](/reference/types/number) in the range ``0..7``, where ``0`` is the lowest power and ``7`` is the highest.
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [@boardname@ Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [@boardname@ Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on @boardname@ resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
bluetooth
|
||||
```
|
28
docs/reference/serial/read-until.md
Normal file
28
docs/reference/serial/read-until.md
Normal file
@ -0,0 +1,28 @@
|
||||
# Serial Read Until
|
||||
|
||||
Read a text from the serial port until a delimiter is found.
|
||||
|
||||
```sig
|
||||
serial.readUntil(",");
|
||||
```
|
||||
|
||||
### Returns
|
||||
|
||||
* a [string](/reference/types/string) containing input from the serial port, such as a response typed by a user
|
||||
|
||||
### Example
|
||||
|
||||
The following example reads strings separated by commands (``,``).
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
let answer = serial.readUntil(",");
|
||||
serial.writeLine(answer);
|
||||
});
|
||||
```
|
||||
|
||||
### See also
|
||||
|
||||
[serial](/device/serial),
|
||||
[serial write line](/reference/serial/write-line),
|
||||
[serial write value](/reference/serial/write-value)
|
@ -38,7 +38,7 @@ That's it!
|
||||
|
||||
### Installation Instructions
|
||||
|
||||
* Download the [Microsoft.Uploader.Microbit.zip](https://pxt.microbit.org/microbit-uploader.zip) file to your local computer.
|
||||
* Download the [Microsoft.Uploader.Microbit.zip](https://www.touchdevelop.com/microbituploader.zip) file to your local computer.
|
||||
* Unzip the .zip file to your desktop.
|
||||
* Launch the Microsoft.Uploader.exe file before working on your @boardname@.
|
||||
|
||||
|
@ -1,12 +1,15 @@
|
||||
{
|
||||
"bluetooth": "Support for additional Bluetooth services.",
|
||||
"bluetooth.advertiseUrl": "Advertise an Eddystone URL",
|
||||
"bluetooth.advertiseUrl|param|power": "power level between 0 and 7, e.g.: 7",
|
||||
"bluetooth.advertiseUrl|param|url": "the url to transmit. Must be no longer than the supported eddystone url length",
|
||||
"bluetooth.advertiseUrl|param|connectable": "true to keep bluetooth connectable for other services, false otherwise.",
|
||||
"bluetooth.advertiseUrl|param|power": "power level between 0 and 7, eg: 7",
|
||||
"bluetooth.advertiseUrl|param|url": "the url to transmit. Must be no longer than the supported eddystone url length, eg: \"https://pxt.io/\"",
|
||||
"bluetooth.onBluetoothConnected": "Register code to run when the micro:bit is connected to over Bluetooth",
|
||||
"bluetooth.onBluetoothConnected|param|body": "Code to run when a Bluetooth connection is established",
|
||||
"bluetooth.onBluetoothDisconnected": "Register code to run when a bluetooth connection to the micro:bit is lost",
|
||||
"bluetooth.onBluetoothDisconnected|param|body": "Code to run when a Bluetooth connection is lost",
|
||||
"bluetooth.setTransmitPower": "Sets the bluetooth transmit power between 0 (minimal) and 7 (maximum).",
|
||||
"bluetooth.setTransmitPower|param|power": "power level between 0 (minimal) and 7 (maximum), eg: 7.",
|
||||
"bluetooth.startAccelerometerService": "Starts the Bluetooth accelerometer service",
|
||||
"bluetooth.startButtonService": "Starts the Bluetooth button service",
|
||||
"bluetooth.startIOPinService": "Starts the Bluetooth IO pin service.",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"bluetooth.advertiseUrl|block": "bluetooth advertise url %url|with power %power",
|
||||
"bluetooth.advertiseUrl|block": "bluetooth advertise url %url|with power %power|connectable %connectable",
|
||||
"bluetooth.onBluetoothConnected|block": "on bluetooth connected",
|
||||
"bluetooth.onBluetoothDisconnected|block": "on bluetooth disconnected",
|
||||
"bluetooth.setTransmitPower|block": "bluetooth set transmit power %power",
|
||||
"bluetooth.startAccelerometerService|block": "bluetooth accelerometer service",
|
||||
"bluetooth.startButtonService|block": "bluetooth button service",
|
||||
"bluetooth.startIOPinService|block": "bluetooth io pin service",
|
||||
|
@ -121,18 +121,30 @@ namespace bluetooth {
|
||||
}
|
||||
|
||||
const int8_t CALIBRATED_POWERS[] = {-49, -37, -33, -28, -25, -20, -15, -10};
|
||||
|
||||
/**
|
||||
* Advertise an Eddystone URL
|
||||
* @param url the url to transmit. Must be no longer than the supported eddystone url length
|
||||
* @param power power level between 0 and 7, e.g.: 7
|
||||
* @param url the url to transmit. Must be no longer than the supported eddystone url length, eg: "https://pxt.io/"
|
||||
* @param power power level between 0 and 7, eg: 7
|
||||
* @param connectable true to keep bluetooth connectable for other services, false otherwise.
|
||||
*/
|
||||
//% blockId=eddystone_advertise_url block="bluetooth advertise url %url|with power %power"
|
||||
//% blockId=eddystone_advertise_url block="bluetooth advertise url %url|with power %power|connectable %connectable"
|
||||
//% parts=bluetooth weight=11 blockGap=8
|
||||
//% help=bluetooth/advertise-url
|
||||
void advertiseUrl(StringData* url, int power) {
|
||||
int8_t level = CALIBRATED_POWERS[min(7, max(0, power))];
|
||||
uBit.bleManager.advertiseEddystoneUrl(ManagedString(url), level);
|
||||
//% help=bluetooth/advertise-url blockExternalInputs=1
|
||||
void advertiseUrl(StringData* url, int power, bool connectable) {
|
||||
power = min(MICROBIT_BLE_POWER_LEVELS-1, max(0, power));
|
||||
int8_t level = CALIBRATED_POWERS[power];
|
||||
uBit.bleManager.advertiseEddystoneUrl(ManagedString(url), level, connectable);
|
||||
uBit.bleManager.setTransmitPower(power);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bluetooth transmit power between 0 (minimal) and 7 (maximum).
|
||||
* @param power power level between 0 (minimal) and 7 (maximum), eg: 7.
|
||||
*/
|
||||
//% parts=bluetooth weight=5 help=bluetooth/set-transmit-power advanced=true
|
||||
//% blockId=bluetooth_settransmitpower block="bluetooth set transmit power %power"
|
||||
void setTransmitPower(int power) {
|
||||
uBit.bleManager.setTransmitPower(min(MICROBIT_BLE_POWER_LEVELS-1, max(0, power)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,7 +152,7 @@ namespace bluetooth {
|
||||
*/
|
||||
//% blockId=eddystone_stop_advertising block="bluetooth stop advertising"
|
||||
//% parts=bluetooth weight=10
|
||||
//% help=bluetooth/stop-advertising
|
||||
//% help=bluetooth/stop-advertising advanced=true
|
||||
void stopAdvertising() {
|
||||
uBit.bleManager.stopAdvertising();
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
"microbit-dal": {
|
||||
"bluetooth": {
|
||||
"private_addressing": 0,
|
||||
"whitelist": 1,
|
||||
"advertising_timeout": 0,
|
||||
"tx_power": 6,
|
||||
"dfu_service": 1,
|
||||
@ -32,8 +31,9 @@
|
||||
"device_info_service": 1,
|
||||
"eddystone_url": 1,
|
||||
"eddystone_uid": 0,
|
||||
"pairing_mode": 1,
|
||||
"open": 0,
|
||||
"pairing_mode": 1,
|
||||
"whitelist": 1,
|
||||
"security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM"
|
||||
}
|
||||
},
|
||||
@ -41,39 +41,39 @@
|
||||
},
|
||||
"userConfigs": [
|
||||
{
|
||||
"description": "No pairing: Anyone can connect via Bluetooth.",
|
||||
"description": "Unsecure: Anyone can connect via Bluetooth.",
|
||||
"config": {
|
||||
"microbit-dal": {
|
||||
"bluetooth": {
|
||||
"open": 1,
|
||||
"pairing_mode": 0,
|
||||
"white_list": 0,
|
||||
"whitelist": 0,
|
||||
"security_level": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "JustWorks pairing (default): Button press to pair via Bluetooth.",
|
||||
"description": "JustWorks pairing (default): Button press to pair.",
|
||||
"config": {
|
||||
"microbit-dal": {
|
||||
"bluetooth": {
|
||||
"open": null,
|
||||
"pairing_mode": null,
|
||||
"white_list": null,
|
||||
"whitelist": null,
|
||||
"security_level": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Passkey pairing: Button press and 6 digit key to pair via Bluetooth.",
|
||||
"description": "Passkey pairing: Button press and 6 digit key to pair.",
|
||||
"config": {
|
||||
"microbit-dal": {
|
||||
"bluetooth": {
|
||||
"open": 0,
|
||||
"pairing_mode": 1,
|
||||
"white_list": 1,
|
||||
"whitelist": 1,
|
||||
"security_level": "SECURITY_MODE_ENCRYPTION_WITH_MITM"
|
||||
}
|
||||
}
|
||||
|
21
libs/bluetooth/shims.d.ts
vendored
21
libs/bluetooth/shims.d.ts
vendored
@ -83,20 +83,29 @@ declare namespace bluetooth {
|
||||
|
||||
/**
|
||||
* Advertise an Eddystone URL
|
||||
* @param url the url to transmit. Must be no longer than the supported eddystone url length
|
||||
* @param power power level between 0 and 7, e.g.: 7
|
||||
* @param url the url to transmit. Must be no longer than the supported eddystone url length, eg: "https://pxt.io/"
|
||||
* @param power power level between 0 and 7, eg: 7
|
||||
* @param connectable true to keep bluetooth connectable for other services, false otherwise.
|
||||
*/
|
||||
//% blockId=eddystone_advertise_url block="bluetooth advertise url %url|with power %power"
|
||||
//% blockId=eddystone_advertise_url block="bluetooth advertise url %url|with power %power|connectable %connectable"
|
||||
//% parts=bluetooth weight=11 blockGap=8
|
||||
//% help=bluetooth/advertise-url shim=bluetooth::advertiseUrl
|
||||
function advertiseUrl(url: string, power: number): void;
|
||||
//% help=bluetooth/advertise-url blockExternalInputs=1 shim=bluetooth::advertiseUrl
|
||||
function advertiseUrl(url: string, power: number, connectable: boolean): void;
|
||||
|
||||
/**
|
||||
* Sets the bluetooth transmit power between 0 (minimal) and 7 (maximum).
|
||||
* @param power power level between 0 (minimal) and 7 (maximum), eg: 7.
|
||||
*/
|
||||
//% parts=bluetooth weight=5 help=bluetooth/set-transmit-power advanced=true
|
||||
//% blockId=bluetooth_settransmitpower block="bluetooth set transmit power %power" shim=bluetooth::setTransmitPower
|
||||
function setTransmitPower(power: number): void;
|
||||
|
||||
/**
|
||||
* Stops advertising Eddystone end points
|
||||
*/
|
||||
//% blockId=eddystone_stop_advertising block="bluetooth stop advertising"
|
||||
//% parts=bluetooth weight=10
|
||||
//% help=bluetooth/stop-advertising shim=bluetooth::stopAdvertising
|
||||
//% help=bluetooth/stop-advertising advanced=true shim=bluetooth::stopAdvertising
|
||||
function stopAdvertising(): void;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@
|
||||
"game.setLife": "Sets the current life value",
|
||||
"game.setLife|param|value": "TODO",
|
||||
"game.setScore": "Sets the current score value",
|
||||
"game.setScore|param|value": "TODO",
|
||||
"game.setScore|param|value": "new score value.",
|
||||
"game.showScore": "Displays the score on the screen.",
|
||||
"game.startCountdown": "Starts a game countdown timer",
|
||||
"game.startCountdown|param|ms": "countdown duration in milliseconds, eg: 10000",
|
||||
|
@ -110,6 +110,7 @@
|
||||
"game.createSprite|block": "create sprite at|x: %x|y: %y",
|
||||
"game.gameOver|block": "game over",
|
||||
"game.score|block": "score",
|
||||
"game.setScore|block": "set score %points",
|
||||
"game.startCountdown|block": "start countdown|(ms) %duration",
|
||||
"game|block": "game",
|
||||
"images.createBigImage|block": "create big image",
|
||||
|
@ -40,7 +40,7 @@ namespace game {
|
||||
* @param x sprite horizontal coordinate, eg: 2
|
||||
* @param y sprite vertical coordinate, eg: 2
|
||||
*/
|
||||
//% weight=60
|
||||
//% weight=60 blockGap=8
|
||||
//% blockId=game_create_sprite block="create sprite at|x: %x|y: %y"
|
||||
//% parts="ledmatrix"
|
||||
export function createSprite(x: number, y: number): LedSprite {
|
||||
@ -146,8 +146,9 @@ namespace game {
|
||||
|
||||
/**
|
||||
* Sets the current score value
|
||||
* @param value TODO
|
||||
* @param value new score value.
|
||||
*/
|
||||
//% blockId=game_set_score block="set score %points" blockGap=8
|
||||
//% weight=10 help=game/set-score
|
||||
export function setScore(value: number): void {
|
||||
_score = Math.max(0, value);
|
||||
@ -589,7 +590,7 @@ namespace game {
|
||||
|
||||
/**
|
||||
* Turns on the sprite (on by default)
|
||||
* @param this TODO
|
||||
* @param this the sprite
|
||||
*/
|
||||
public on(): void {
|
||||
this.setBrightness(255);
|
||||
@ -597,7 +598,7 @@ namespace game {
|
||||
|
||||
/**
|
||||
* Turns off the sprite (on by default)
|
||||
* @param this TODO
|
||||
* @param this the sprite
|
||||
*/
|
||||
public off(): void {
|
||||
this.setBrightness(0);
|
||||
@ -605,8 +606,8 @@ namespace game {
|
||||
|
||||
/**
|
||||
* Set the ``brightness`` of a sprite
|
||||
* @param this TODO
|
||||
* @param brightness TODO
|
||||
* @param this the sprite
|
||||
* @param brightness the brightness from 0 (off) to 255 (on), eg: 255.
|
||||
*/
|
||||
//% parts="ledmatrix"
|
||||
public setBrightness(brightness: number): void {
|
||||
@ -616,8 +617,9 @@ namespace game {
|
||||
|
||||
/**
|
||||
* Reports the ``brightness` of a sprite on the LED screen
|
||||
* @param this TODO
|
||||
* @param this the sprite
|
||||
*/
|
||||
//% parts="ledmatrix"
|
||||
public brightness(): number {
|
||||
let r: number;
|
||||
return this._brightness;
|
||||
@ -625,8 +627,8 @@ namespace game {
|
||||
|
||||
/**
|
||||
* Changes the ``y`` position by the given amount
|
||||
* @param this TODO
|
||||
* @param value TODO
|
||||
* @param this the sprite
|
||||
* @param value the value to change brightness
|
||||
*/
|
||||
public changeBrightnessBy(value: number): void {
|
||||
this.setBrightness(this._brightness + value);
|
||||
@ -643,10 +645,12 @@ namespace game {
|
||||
|
||||
/**
|
||||
* Deletes the sprite from the game engine. All further operation of the sprite will not have any effect.
|
||||
* @param sprite TODO
|
||||
* @param this sprite to delete
|
||||
*/
|
||||
public delete(sprite: LedSprite): void {
|
||||
sprites.removeElement(sprite);
|
||||
//% weight=59
|
||||
//% blockId="game_delete_sprite" block="delete %this"
|
||||
public delete(): void {
|
||||
sprites.removeElement(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,7 +79,7 @@ namespace pxt {
|
||||
|
||||
intcheck(vtable->methods[0] == &RefRecord_destroy, ERR_SIZE, 3);
|
||||
intcheck(vtable->methods[1] == &RefRecord_print, ERR_SIZE, 4);
|
||||
|
||||
|
||||
void *ptr = ::operator new(vtable->numbytes);
|
||||
RefRecord *r = new (ptr) RefRecord(PXT_VTABLE_TO_INT(vtable));
|
||||
memset(r->fields, 0, vtable->numbytes - sizeof(RefRecord));
|
||||
@ -117,7 +117,6 @@ namespace pxt {
|
||||
|
||||
void RefObject::destroy() {
|
||||
((RefObjectMethod)getVTable()->methods[0])(this);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void RefObject::print() {
|
||||
@ -132,6 +131,9 @@ namespace pxt {
|
||||
if (refmask[i]) decr(r->fields[i]);
|
||||
r->fields[i] = 0;
|
||||
}
|
||||
//RefRecord is allocated using placement new
|
||||
r->~RefRecord();
|
||||
::operator delete(r);
|
||||
}
|
||||
|
||||
void RefRecord_print(RefRecord *r)
|
||||
@ -242,6 +244,7 @@ namespace pxt {
|
||||
this->data[i] = 0;
|
||||
}
|
||||
this->data.resize(0);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void RefCollection::print()
|
||||
@ -258,6 +261,9 @@ namespace pxt {
|
||||
decr(fields[i]);
|
||||
fields[i] = 0;
|
||||
}
|
||||
//RefAction is allocated using placement new
|
||||
this->~RefAction();
|
||||
::operator delete(this);
|
||||
}
|
||||
|
||||
void RefAction::print()
|
||||
@ -272,6 +278,7 @@ namespace pxt {
|
||||
|
||||
void RefLocal::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
PXT_VTABLE_CTOR(RefLocal) {
|
||||
@ -290,6 +297,7 @@ namespace pxt {
|
||||
void RefRefLocal::destroy()
|
||||
{
|
||||
decr(v);
|
||||
delete this;
|
||||
}
|
||||
|
||||
PXT_VTABLE_BEGIN(RefMap, 0, RefMapMarker)
|
||||
@ -304,6 +312,7 @@ namespace pxt {
|
||||
data[i].val = 0;
|
||||
}
|
||||
data.resize(0);
|
||||
delete this;
|
||||
}
|
||||
|
||||
int RefMap::findIdx(uint32_t key) {
|
||||
@ -328,7 +337,7 @@ namespace pxt {
|
||||
for(std::set<RefObject*>::iterator itr = allptrs.begin();itr!=allptrs.end();itr++)
|
||||
{
|
||||
(*itr)->print();
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#else
|
||||
@ -341,16 +350,16 @@ namespace pxt {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
map<pair<int, int>, Action> handlersMap;
|
||||
|
||||
|
||||
MicroBitEvent lastEvent;
|
||||
|
||||
// We have the invariant that if [dispatchEvent] is registered against the DAL
|
||||
// for a given event, then [handlersMap] contains a valid entry for that
|
||||
// event.
|
||||
void dispatchEvent(MicroBitEvent e) {
|
||||
|
||||
|
||||
lastEvent = e;
|
||||
|
||||
|
||||
Action curr = handlersMap[{ e.source, e.value }];
|
||||
if (curr)
|
||||
runAction1(curr, e.value);
|
||||
@ -383,7 +392,7 @@ namespace pxt {
|
||||
create_fiber((void(*)(void*))runAction0, (void*)a, fiberDone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void error(ERROR code, int subcode)
|
||||
{
|
||||
@ -435,10 +444,10 @@ namespace pxt {
|
||||
|
||||
// unique group for radio based on source hash
|
||||
// ::touch_develop::micro_bit::radioDefaultGroup = programHash();
|
||||
|
||||
|
||||
// repeat error 4 times and restart as needed
|
||||
microbit_panic_timeout(4);
|
||||
|
||||
|
||||
int32_t ver = *pc++;
|
||||
checkStr(ver == 0x4209, ":( Bad runtime version");
|
||||
|
||||
@ -467,6 +476,6 @@ namespace pxt {
|
||||
{
|
||||
exec_binary((int32_t*)functionsAndBytecode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=2 sw=2 expandtab
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pxt-microbit",
|
||||
"version": "0.6.29",
|
||||
"version": "0.6.35",
|
||||
"description": "micro:bit target for PXT",
|
||||
"keywords": [
|
||||
"JavaScript",
|
||||
@ -34,6 +34,6 @@
|
||||
"semantic-ui-less": "^2.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"pxt-core": "0.5.90"
|
||||
"pxt-core": "0.5.98"
|
||||
}
|
||||
}
|
||||
|
@ -23,15 +23,15 @@ namespace pxsim.input {
|
||||
}
|
||||
|
||||
export function rotation(kind: number): number {
|
||||
let b = board().accelerometerState;
|
||||
let acc = b.accelerometer;
|
||||
const b = board().accelerometerState;
|
||||
const acc = b.accelerometer;
|
||||
acc.activate();
|
||||
let x = acc.getX(MicroBitCoordinateSystem.NORTH_EAST_DOWN);
|
||||
let y = acc.getX(MicroBitCoordinateSystem.NORTH_EAST_DOWN);
|
||||
let z = acc.getX(MicroBitCoordinateSystem.NORTH_EAST_DOWN);
|
||||
const x = acc.getX(MicroBitCoordinateSystem.NORTH_EAST_DOWN);
|
||||
const y = acc.getY(MicroBitCoordinateSystem.NORTH_EAST_DOWN);
|
||||
const z = acc.getZ(MicroBitCoordinateSystem.NORTH_EAST_DOWN);
|
||||
|
||||
let roll = Math.atan2(y, z);
|
||||
let pitch = Math.atan(-x / (y * Math.sin(roll) + z * Math.cos(roll)));
|
||||
const roll = Math.atan2(y, z);
|
||||
const pitch = Math.atan(-x / (y * Math.sin(roll) + z * Math.cos(roll)));
|
||||
|
||||
let r = 0;
|
||||
switch (kind) {
|
||||
|
@ -177,7 +177,8 @@ namespace pxsim.bluetooth {
|
||||
export function onBluetoothDisconnected(a: RefAction) {
|
||||
// TODO
|
||||
}
|
||||
export function advertiseUrl(url: string, power: number) { }
|
||||
export function advertiseUrl(url: string, power: number, connectable: boolean) { }
|
||||
export function stopAdvertising() { }
|
||||
export function setTransmitPower(power: number) {}
|
||||
}
|
||||
|
||||
|
@ -556,12 +556,12 @@ namespace pxsim.visuals {
|
||||
|
||||
private updateTilt() {
|
||||
if (this.props.disableTilt) return;
|
||||
let state = this.board;
|
||||
const state = this.board;
|
||||
if (!state || !state.accelerometerState.accelerometer.isActive) return;
|
||||
|
||||
let x = state.accelerometerState.accelerometer.getX();
|
||||
let y = state.accelerometerState.accelerometer.getY();
|
||||
let af = 8 / 1023;
|
||||
const x = state.accelerometerState.accelerometer.getX();
|
||||
const y = -state.accelerometerState.accelerometer.getY();
|
||||
const af = 8 / 1023;
|
||||
|
||||
this.element.style.transform = "perspective(30em) rotateX(" + y * af + "deg) rotateY(" + x * af + "deg)"
|
||||
this.element.style.perspectiveOrigin = "50% 50% 50%";
|
||||
@ -704,7 +704,7 @@ namespace pxsim.visuals {
|
||||
}
|
||||
let tiltDecayer = 0;
|
||||
this.element.addEventListener(pointerEvents.move, (ev: MouseEvent) => {
|
||||
let state = this.board;
|
||||
const state = this.board;
|
||||
if (!state.accelerometerState.accelerometer.isActive) return;
|
||||
|
||||
if (tiltDecayer) {
|
||||
@ -712,14 +712,14 @@ namespace pxsim.visuals {
|
||||
tiltDecayer = 0;
|
||||
}
|
||||
|
||||
let bbox = this.element.getBoundingClientRect();
|
||||
let ax = (ev.clientX - bbox.width / 2) / (bbox.width / 3);
|
||||
let ay = (ev.clientY - bbox.height / 2) / (bbox.height / 3);
|
||||
const bbox = this.element.getBoundingClientRect();
|
||||
const ax = (ev.clientX - bbox.width / 2) / (bbox.width / 3);
|
||||
const ay = (ev.clientY - bbox.height / 2) / (bbox.height / 3);
|
||||
|
||||
let x = - Math.max(- 1023, Math.min(1023, Math.floor(ax * 1023)));
|
||||
let y = Math.max(- 1023, Math.min(1023, Math.floor(ay * 1023)));
|
||||
let z2 = 1023 * 1023 - x * x - y * y;
|
||||
let z = Math.floor((z2 > 0 ? -1 : 1) * Math.sqrt(Math.abs(z2)));
|
||||
const x = - Math.max(- 1023, Math.min(1023, Math.floor(ax * 1023)));
|
||||
const y = - Math.max(- 1023, Math.min(1023, Math.floor(ay * 1023)));
|
||||
const z2 = 1023 * 1023 - x * x - y * y;
|
||||
const z = Math.floor((z2 > 0 ? -1 : 1) * Math.sqrt(Math.abs(z2)));
|
||||
|
||||
state.accelerometerState.accelerometer.update(x, y, z);
|
||||
this.updateTilt();
|
||||
|
@ -2,7 +2,7 @@
|
||||
User Variable Overrides
|
||||
*******************************/
|
||||
|
||||
@invertedBackground: #525A67;
|
||||
@invertedBackground: #3454D1;
|
||||
|
||||
/*******************************
|
||||
PXT Theme Overrides
|
||||
|
@ -9,7 +9,7 @@
|
||||
@emSize : 14px;
|
||||
@fontSize : 13px;
|
||||
|
||||
@primaryColor: @teal;
|
||||
@primaryColor: @purple;
|
||||
|
||||
@teal: #3891A6;
|
||||
@blue: #456990;
|
||||
|
@ -18,8 +18,7 @@
|
||||
}
|
||||
|
||||
.download-button.download-button-full {
|
||||
&:extend(.ui.inverted.button all);
|
||||
&:extend(.purple all);
|
||||
&:extend(.ui.inverted.purple.button all);
|
||||
}
|
||||
|
||||
.download-button:hover {
|
||||
@ -45,8 +44,8 @@
|
||||
*******************************/
|
||||
|
||||
.blocklyTreeRow {
|
||||
border-bottom: 1px solid #ecf0f1;
|
||||
margin-bottom: 0px;
|
||||
border-bottom: 1px solid #ecf0f1 !important;
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
|
||||
/* Blockly toolbox font size same as the page font */
|
||||
@ -55,12 +54,14 @@
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.blocklyToolboxDiv {
|
||||
.blocklyToolboxDiv, .monacoToolboxDiv {
|
||||
background-color: white !important;
|
||||
border-left: 1px solid #ecf0f1 !important;
|
||||
}
|
||||
|
||||
.blocklyFlyoutBackground {
|
||||
fill: #525A67;
|
||||
fill: #525A67 !important;
|
||||
fill-opacity: 0.5 !important;
|
||||
}
|
||||
|
||||
/* Remove shadow around blockly blocks */
|
||||
@ -72,6 +73,17 @@
|
||||
top: 1.6em;
|
||||
}
|
||||
|
||||
/* Blockly Toolbox Buttons */
|
||||
#blocklyToolboxButtons .blocklyAddPackageButton {
|
||||
&:extend(.ui.inverted.pink.button all);
|
||||
&:extend(.circular all);
|
||||
}
|
||||
|
||||
#blocklyToolboxButtons .blocklyUndoButton {
|
||||
&:extend(.ui.inverted.blue.button all);
|
||||
&:extend(.circular all);
|
||||
}
|
||||
|
||||
/*******************************
|
||||
Monaco
|
||||
*******************************/
|
||||
@ -84,6 +96,10 @@
|
||||
background: #ecf0f1;
|
||||
}
|
||||
|
||||
.monacoFlyout {
|
||||
background: rgba(82, 90, 103, 0.8);
|
||||
}
|
||||
|
||||
|
||||
/* Mobile */
|
||||
@media only screen and (max-width: @largestMobileScreen) {
|
||||
@ -100,6 +116,11 @@
|
||||
.organization {
|
||||
top: auto;
|
||||
}
|
||||
/* Blockly Toolbox buttons */
|
||||
#blocklyToolboxButtons {
|
||||
margin-right: 0.5rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small Monitor */
|
||||
@ -107,6 +128,11 @@
|
||||
.organization {
|
||||
top: auto;
|
||||
}
|
||||
/* Blockly Toolbox buttons */
|
||||
#blocklyToolboxButtons {
|
||||
margin-right: 1rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Large Monitor */
|
||||
@ -115,4 +141,9 @@
|
||||
width: 230px;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
/* Blockly Toolbox buttons */
|
||||
#blocklyToolboxButtons {
|
||||
margin-right: 2rem;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user