Bump V3.0.22 (#110)

* change simulator svg

* change radio image

* Remove google fonts cdn

* change color of 'advanced' button

* font fix

* font fix 2

* display fix

* change fullsceen simulator bg

* Continuous servo

* handle continuous state

* adding shims

* update rendering for continuous servos

* fixing sim

* fix sig

* typo

* fix sim

* bump pxt

* bump pxt

* rerun travis

* Input blocks revision

- add Button and Pin event types
- merge onPinPressed & onPinReleased in new onPinEvent function
- create new onButtonEvent function

* update input blocks in docs and tests

* remove device_pin_release block

* Hide DAL.x behind Enum

* bring back deprecated blocks, but hide them

* shims and locales files

* fix input.input. typing

* remove buildpr

* bump V3

* update simulator aspect ratio

* add Loudness Block

* revoke loudness block

* Adds soundLevel

To be replaced by pxt-common-packages when DAL is updated.

* Remove P0 & P3 from AnalogPin

Co-authored-by: Juri <gitkraken@juriwolf.de>
This commit is contained in:
Amerlander
2020-09-08 11:04:25 +02:00
committed by GitHub
parent 98d8b2977b
commit 918af4f3ac
233 changed files with 9391 additions and 2739 deletions

View File

@ -35,7 +35,7 @@ Put a ``||Math:pick random||`` block in the ``||basic:show number||`` block to p
```blocks
input.onGesture(Gesture.Shake, () => {
basic.showNumber(Math.randomRange(0, 10))
basic.showNumber(randint(0, 10))
})
```
@ -45,7 +45,7 @@ A typical dice shows values from `1` to `6`. So, in ``||Math:pick random||``, do
```blocks
input.onGesture(Gesture.Shake, () => {
basic.showNumber(Math.randomRange(1, 6))
basic.showNumber(randint(1, 6))
})
```

View File

@ -0,0 +1,18 @@
# Escape Room
Projects used to create escape room experiences.
## Radio
```codecard
[{
"name": "Rotary Dial Radio",
"url":"/projects/rotary-dial-radio",
"description": "Turn an antique rotary dial phone into a radio transmitter",
"imageUrl":"/static/mb/projects/rotary-dial-radio.png"
}]
```
## Acknowledgments
Escape room ideas are gathered from a great discussion with [Pauline Maas](https://twitter.com/4pip) and [Peter Heldens](https://twitter.com/PeterHeldens) at https://microbit101.nl/.

View File

@ -21,7 +21,7 @@ Using ``||basic:show number||`` and ``||Math:pick random||`` blocks, show a rand
```blocks
input.onPinPressed(TouchPin.P0, () => {
basic.showNumber(Math.randomRange(0, 100));
basic.showNumber(randint(0, 100));
});
```
## Step 3
@ -35,7 +35,7 @@ Show ``"LOVE METER"`` on the screen when the @boardname@ starts.
```blocks
basic.showString("LOVE METER");
input.onPinPressed(TouchPin.P0, () => {
basic.showNumber(Math.randomRange(0, 100));
basic.showNumber(randint(0, 100));
});
```

View File

@ -0,0 +1,98 @@
# Name Badge
![Name badge project](/static/mb/projects/name-badge/header.png)
Make yourself known with a fancy name badge powered by your @boardname@!
## Code
First, let's get your name to display on the screen.
### Button press
From the ``||input:Input||`` Toolbox drawer, drag an ``||input:on button A pressed||`` block onto the Workspace.
```blocks
input.onButtonPressed(Button.A, function () {
})
```
### Show a string
From the ``||basic:Basic||`` Toolbox drawer drag a ``||basic:show string||`` block into the ``||input:on button A pressed||`` block.
```blocks
input.onButtonPressed(Button.A, function () {
basic.showString("Hello!")
})
```
### Show my name
In the ``||basic:show string||`` block, type your name.
```blocks
input.onButtonPressed(Button.A, function () {
basic.showString("My Name")
})
```
### Test the badge
Go to the simulator and test your name badge by pressing button **A**.
```sim
input.onButtonPressed(Button.A, function () {
basic.showString("My Name")
})
```
### Download
Download the program to your @boardname@:
1. Make sure your @boardname@ is plugged into the computer.
2. Click the `|Download|` button.
## Make
Now that you have your name showing on the @boardname@, let's make a proper badge to wear and display it on.
Cut out a badge shape from a piece of colored construction paper.
![Construction paper and scisssors](/static/mb/projects/name-badge/picture1.png)
Loop a piece of duct tape and stick it on the back of your @boardname@.
![Roll of tape with the other materials](/static/mb/projects/name-badge/picture2.png)
Stick your @boardname@ onto the front of your badge.
![Board attached to the paper](/static/mb/projects/name-badge/picture3.png)
Using a hole-punch, punch out 2 holes in the top of your badge.
![Holes punched in the paper](/static/mb/projects/name-badge/picture4.png)
Attach the battery pack to the @boardname@.
![Battery pack connected to the board](/static/mb/projects/name-badge/picture5.png)
Tape battery pack onto the back of the badge.
![Battery pack taped on](/static/mb/projects/name-badge/picture6.png)
Thread a shoelace through the top 2 holes of your badge.
![Shoelace threaded through a hole](/static/mb/projects/name-badge/picture7.png)
Tie a knot at the end of your shoelace
![Ends of shoelace tied together](/static/mb/projects/name-badge/picture8.png)
Decorate your badge with colored paper, markers, stickers, glitter.
![Completed name badge](/static/mb/projects/name-badge/picture9.png)
It's now finished! your badge is ready let others know who you are.

View File

@ -0,0 +1,200 @@
# Robot Unicorn
## by [Helen Leigh](https://twitter.com/helenleigh)
Hey, I made a herd of very silly gesture controlled robot unicorns I did this because I was bored with those personality-free robots that only move in a straight line. This is a cheap, unreliable, hilarious robot unicorn project suitable for total beginners. You'll learn about LEDs, gesture control, radio, and servo control.
On this project page, I've written up what you'll need to make your own Robot Unicorn, with all the steps you'll need to follow and the code you'll need to write. I've even have videos for each of the steps to help guide you through this project. Happy making and have fun!
![Robot Unicorn](/static/mb/projects/robot-unicorn/robotunicorn.jpg)
## Ingredients
Here's what you'll need. The links telling where to get parts are just examples - with a bit of searching you will be able to find any of these parts cheaper in whatever shop you normally use to get parts like this: eBay, Amazon, Rapid, Digikey, Kitronik, etc.
- Two @boardname@s plus a AAA battery pack for each of them.
- Two 360 continuous rotation servos with wheels (I used FS90R servos with wheels [like this](https://www.kitronik.co.uk/2574-wheel-for-fs90r-60mmx8mm.html)). 360 servos are super cheap, super unreliable and super easy to hook up, which is exactly why I chose them. Remember, the unicorn not going exactly where you expect it to go is kind of the point.
- One small swivelling castor wheel plus the nuts and bolts to fix it to the base (something [like this](https://www.amazon.co.uk/dp/B074WP1QJN/)). You can use a marble like castor wheel designed for robots but if you use the cheaper ones designed for furniture you can figure out a special way to get your robot unicorn to rear up like She Ra's flying unicorn Swift Wind. Or sometimes it will just fall over. Either way, it's funny.
- One 3XAA battery pack with on off switch and leads (something [like this](https://www.amazon.com/x1-5V-Battery-Holder-Switch-Wires/dp/B01C5J4K3Q/)).
- Three crocodile clips, or alligator clips as Americans apparently call them. Cute.
- One unicorn horn. Obviously. I modified an old ``stl`` from Adafruit at [Thingverse](https://www.thingiverse.com/thing:956359) to make it smaller and give it a solid base so it stuck securely onto my unicorn's head. I've included my revised ``stl`` file in the project files at the bottom of this project page if you want to 3D print your own, or you can make a horn from whatever kind of material you like!
- Something shiny for the tail. I used tinsel for some and tiny disco balls for some others.
- Three sheets of A4 card, the sparklier the better. I've made pdf templates for the shape of the body and head which you can either use as a printed template or as a lasercutting file. You'll find the pdfs in the project files at the bottom of this project page. If you want to experiment with using other materials for your Robot Unicorn, go for it! I've used a card base and a furry body, my friend made a leather version and I've also lasercut semi transparent polypropylene for the head, putting LEDs, jelly beans, copper tape and glitter inside. (The glitter was a total pain. 0/10 do not recommend.)
- Some wire strippers and some electrical tape.
- Some double sided sticky tape, some sellotape and/or some decent glue. Those double sided sticky pads work really well for fixing the servos to the cardboard chassis.
![micro:bits and Unicorn Horn](/static/mb/projects/robot-unicorn/microbitsunicorn.jpg)
### Instructions
**1. Make the unicorn body!** I've made the video below to show how to put your unicorn together using the templates in the project files at the bottom of this project page. Not feeling crafty? That's okay! You can experiment with cutting wheel holes in a small box instead.
https://www.youtube.com/watch?v=CKqrMxuZ6gQ
<br/>
**2. Add in the electronics!** Put on the wheels, then wire up the servos and the battery and the first @boardname@. Just watch my video to see how.
https://youtu.be/CKqrMxuZ6gQ?t=178
<br/>
**3. Code it!** I've supplied my code below, but I'd recommend that you watch the videos I've made so that you understand what is going on. The first video gets you started with one @boardname@, and the second helps you take the next step: gesture controlling your robot unicorn with two @boardname@s. **Pro tip**: there are lots of ways to get the same results using different code, so it's totaslly fine if your code works but doesn't match mine.
**Getting started with @boardname@**
https://www.youtube.com/watch?v=OBcVMPdAIoE
<br/>
**Using gesture control and radio to control your Robot Unicorn with @boardname@**
https://www.youtube.com/watch?v=qAakgfNouOI
<br/>
**4. Play!** Make an obstacle course! Make another one and have a race or a dance off with a friend! Once you've mastered the basics of making your unicorn move around you might want to think about how to make improvements.
**5. Tell me about it!** It brings me joy to know other people make my silly inventions. You can say hi [on Twitter](https://twitter.com/helenleigh), follow me [on Insta](https://www.instagram.com/helenleigh_makes/) or [subscribe to my channel on YouTube](https://youtube.com/c/HelenLeigh).
## Code
**MakeCode blocks for the body of the Robot Unicorn**
```blocks
radio.onReceivedNumberDeprecated(function (receivedNumber) {
received = receivedNumber
})
let received = 0
radio.setGroup(1)
received = 4
basic.forever(function () {
if (received == 0) {
basic.showLeds(`
. . # . .
. # # # .
# . # . #
. . # . .
. . # . .
`)
pins.analogWritePin(AnalogPin.P0, 100)
pins.analogWritePin(AnalogPin.P1, 10)
} else if (received == 1) {
basic.showLeds(`
. . # . .
. . # . .
# . # . #
. # # # .
. . # . .
`)
pins.analogWritePin(AnalogPin.P0, 10)
pins.analogWritePin(AnalogPin.P1, 100)
} else if (received == 2) {
pins.analogWritePin(AnalogPin.P0, 20)
pins.analogWritePin(AnalogPin.P1, 20)
basic.showLeds(`
. . # . .
. # . . .
# # # # #
. # . . .
. . # . .
`)
} else if (received == 3) {
pins.analogWritePin(AnalogPin.P0, 80)
pins.analogWritePin(AnalogPin.P1, 80)
basic.showLeds(`
. . # . .
. . . # .
# # # # #
. . . # .
. . # . .
`)
} else if (received == 4) {
pins.analogWritePin(AnalogPin.P0, 0)
pins.analogWritePin(AnalogPin.P1, 0)
basic.showLeds(`
# . . . #
. # . # .
. . # . .
. # . # .
# . . . #
`)
}
})
```
**MakeCode blocks for the Robot Unicorn controller**
```blocks
input.onButtonPressed(Button.AB, function () {
radio.sendNumber(4)
basic.showLeds(`
# . . . #
. # . # .
. . # . .
. # . # .
# . . . #
`)
})
input.onGesture(Gesture.Shake, function () {
radio.sendNumber(1)
basic.showLeds(`
. . # . .
. . # . .
# . # . #
. # # # .
. . # . .
`)
})
input.onGesture(Gesture.LogoDown, function () {
radio.sendNumber(0)
basic.showLeds(`
. . # . .
. # # # .
# . # . #
. . # . .
. . # . .
`)
})
input.onGesture(Gesture.TiltRight, function () {
radio.sendNumber(2)
basic.showLeds(`
. . # . .
. . . # .
# # # # #
. . . # .
. . # . .
`)
})
input.onGesture(Gesture.TiltLeft, function () {
radio.sendNumber(3)
basic.showLeds(`
. . # . .
. # . . .
# # # # #
. # . . .
. . # . .
`)
})
radio.setGroup(1)
radio.setTransmitPower(7)
basic.showLeds(`
. . # . .
. # # # .
# # # # #
# # # # #
. # . # .
`)
```
## Everythin Else
Here's where you can find all the templates you need to make the Robot Unicorn.
- Template for the main part of the body: [pdf file here](https://github.com/helenleigh/robot-unicorn/blob/master/unicorn%20chassis%20A4.pdf) and [ai file here](https://github.com/helenleigh/robot-unicorn/blob/master/unicorn%20chassis%20A4.ai).
- Template for the top part of the body: [pdf file here](https://github.com/helenleigh/robot-unicorn/blob/master/unicorn%20lid%20a4.pdf) and [ai file here](https://github.com/helenleigh/robot-unicorn/blob/master/unicorn%20lid%20a4.ai).
- Template for the head: [pdf file here](https://github.com/helenleigh/robot-unicorn/blob/master/unicorn%20head%20A4.pdf) and [ai file here](https://github.com/helenleigh/robot-unicorn/blob/master/unicorn%20head%20A4.ai).
- STL file for 3D printing your Robot Unicorn horn [is here](https://github.com/helenleigh/robot-unicorn/blob/master/unicorn%20horn%20solid%20base.stl).
![Robot Unicorn Tail](/static/mb/projects/robot-unicorn/robotunicorntail.jpg)
```package
radio
```

View File

@ -0,0 +1,232 @@
# Rotary Dial Radio
Rotary dial phones may not be one of the latest tech fashions but they've still got some wings if you pair them with a @boardname@. If you are lucky enough to still own one of these antiques, follow this guide and you can bring it into the 21st century.
![A rotary dial phone connected to a @boardname@](/static/mb/projects/rotary-dial-radio/final.jpg)
This guide is mainly a journal of notes and techniques used to convert a 1945 rotary dial into a @boardname@ radio encoder. This is an example of **reverse engineering**, a treasure hunt for engineers if you wish.
### ~ hint
### Stay safe
Opening and handling any electrical device can be very dangerous. Make sure to unplug all sources of power. Unless you know what you are doing, stay away from wall power outlets (AC).
### ~
## What is Pulse dialing?
The phone below is a Belgium rotary dial phone from 1945. It's really heavy and the dial makes a wonderful clicking noise when it turns.
![Antique rotary dial phone](/static/mb/projects/rotary-dial-radio/oldphone.jpg)
If you skim through the WikiPedia on "rotary dial phones", you'll quickly learn that they operated by using something called **pulse dialing** (https://en.wikipedia.org/wiki/Pulse_dialing). In a nutshell, the dialing mechanism opens and closes a circuit while it rotates which sends a series of electrical pulses on the phone line. One pulse for number 1, two pulses for number 2, and so on. (Hey, what about 0?)
## Digging into the phone
Fortunately for us, the bottom of the phone is easily removed by pressing lever. It reveals the internals of the phone. One can see the two massive bells to ring the phone and some other capacitors and circuitery.
![Inside of a rotary phone](/static/mb/projects/rotary-dial-radio/guts.jpg)
Most interestingly, there are 8 terminals near the 2 holes in the case for wires.
* The 2 terminals on each side are connected by a black wire. This is most likely the ground wire.
* The phone line was missing but there is still a hole for it. Since phone lines carry a bit of electrical current, we'll inject electricity on those terminals.
* Three (3) terminals seem to be used by the handset so they must be carrying some kind of microphone/speaker signal. We'll try each of them.
At this point, we have enough information to start "scoping" the lines and hopefully get lucky and see the pulses. (Did I mention treasure hunting?)
## Scoping the lines
Electrical engineers use tools called "scopes" to "see" the eletrical signals on the line. In our case, we'd like to see the pulses generated when the phone is dialing. We don't have a scope so we'll use the @boardname@ instead.
We connect the @boardname@ to the phone using 3 croc clips:
* **GND** pin goes to the ground terminal
* **3v** pin connects at the positive terminal on the phone line
* **P0** is attacned to one of the headset lines (not **GND**)
![Wiring](/static/mb/projects/rotary-dial-radio/wired.jpg)
In the MakeCode, we upload a program that reads the analog input on **P0** and plots it on the screen. If you pair your @boardname@, you can also see the data in the console view.
```blocks
basic.forever(function () {
led.plotBarGraph(
pins.analogReadPin(AnalogPin.P0),
1023
)
})
```
Try moving the dial slowly...click, click and you should see the pulses, e.g. the signal going high and low. If you don't see anything, keep trying other cables. Be patient, don't give up.
https://youtu.be/po9o77IEDaI
## Detecting the pulses
The @boardname@ can raise an event when an electrical signal on **P0** goes low or high. This is the most important step as it allows us to precisely detect and count pulses. Try the following program with the phone. When you move the dial, you see the first LED turn on and off as the line goes high and low.
```blocks
pins.onPulsed(DigitalPin.P0, PulseValue.High, function () {
led.plot(0, 0)
})
pins.onPulsed(DigitalPin.P0, PulseValue.Low, function () {
led.unplot(0, 0)
})
```
## Counting the pulses
Now that we are detecting pulses, we can use a variable to count them too. In this test program, we increment the **pulseCount** variable by one on each high pulse and we display the number when pressing the **A** button. Try dialing a number; then press A.
```blocks
let pulseCount = 0
input.onButtonPressed(Button.A, function () {
basic.showNumber(pulseCount)
pulseCount = 0
})
pins.onPulsed(DigitalPin.P0, PulseValue.High, function () {
led.plot(0, 0)
})
pins.onPulsed(DigitalPin.P0, PulseValue.Low, function () {
led.unplot(0, 0)
pulseCount += 1
})
```
## Digits and Numbers
Our next task is to detect that the pulses for a digit have finished and we should then record the final number. The phone generates a train of pulses (typically 10 per second) per digit; the user might then move the dial back to start the next digit. This leaves a window of time when nothing happens on the line. If our decoder detects that nothing happens on the line for a long time, say 200ms, we assume that the train is done and save the digit.
Instead of using button **A**, we add a **forever** loop that monitors the elapsed time since the last pulse.
If we have had a pulse (``pulseCount > 0``) **and** the last pulse was more than 200ms ago, we have a digit and we can send it.
```blocks
let pulseCount = 0
let lastPulseMs = 0
pins.onPulsed(DigitalPin.P0, PulseValue.High, function () {
led.plot(0, 0)
})
pins.onPulsed(DigitalPin.P0, PulseValue.Low, function () {
led.unplot(0, 0)
pulseCount += 1
lastPulseMs = input.runningTime()
})
basic.forever(function () {
if (pulseCount > 0 && lastPulseMs - input.runningTime() > 200) {
radio.sendNumber(pulseCount)
basic.showNumber(pulseCount)
pulseCount = 0
}
})
```
## What about 0?
Great question! ``0`` is a special case and is represented by 10 pulses, so we need to update our decoder to take this into account.
```blocks
let pulseCount = 0
let lastPulseMs = 0
pins.onPulsed(DigitalPin.P0, PulseValue.High, function () {
led.plot(0, 0)
})
pins.onPulsed(DigitalPin.P0, PulseValue.Low, function () {
led.unplot(0, 0)
pulseCount += 1
lastPulseMs = input.runningTime()
})
basic.forever(function () {
if (pulseCount > 0 && lastPulseMs - input.runningTime() > 200) {
if(pulseCount == 10) {
pulseCount = 0
}
radio.sendNumber(pulseCount)
basic.showNumber(pulseCount)
pulseCount = 0
}
})
```
## Numbers and more
Improving the program is left as a challenge for you (treasure hunt). The following program was the result of the initial investigation; it waits 3 seconds between digits to send the entire number over radio and uses the screen to display how many digits were entered. This is just an example, you can come up with your own twist on this too!
https://youtu.be/gW6rLH7qH5Q
```blocks
pins.onPulsed(DigitalPin.P0, PulseValue.High, function () {
led.plot(0, 0)
})
function plotIndex (i: number, on: boolean) {
row = Math.idiv(i, 5)
col = i % 5
if (on) {
led.plot(col, row)
} else {
led.unplot(col, row)
}
}
function codeDots () {
for (let index = 0; index <= 4; index++) {
led.plot(index, 2)
}
for (let index2 = 0; index2 <= 9; index2++) {
plotIndex(15 + index2, index2 < code.length)
}
}
pins.onPulsed(DigitalPin.P0, PulseValue.Low, function () {
led.unplot(0, 0)
if (lastPulseMs == 0) {
pulseCount = 0
lastPulseMs = input.runningTime()
} else if (input.runningTime() - lastPulseMs > 85) {
pulseCount += 1
lastPulseMs = input.runningTime()
}
})
let codeNumber = 0
let lastDigitMs = 0
let col = 0
let row = 0
let pulseCount = 0
let code = ""
let lastPulseMs = 0
radio.setGroup(1)
lastPulseMs = 0
code = ""
pulseCount = 0
basic.forever(function () {
if (lastPulseMs > 0 && input.runningTime() - lastPulseMs >= 250) {
led.plot(1, 0)
if (pulseCount == 10) {
pulseCount = 0
}
code = "" + code + convertToText(pulseCount)
lastPulseMs = 0
lastDigitMs = input.runningTime()
} else if (lastPulseMs == 0 && (code.length > 0 && (code.length == 10 || input.runningTime() - lastDigitMs >= 3000))) {
led.plot(2, 0)
codeNumber = parseFloat(code)
for (let index = 0; index < 1; index++) {
radio.sendNumber(codeNumber)
basic.pause(10)
}
basic.clearScreen()
basic.showNumber(codeNumber)
basic.clearScreen()
code = ""
lastPulseMs = 0
} else {
led.unplot(1, 0)
led.unplot(2, 0)
}
codeDots()
})
```
```package
radio
```