diff --git a/.gitignore b/.gitignore index 34cfeb96..8dab8bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ clients/electron/projects .DS_Store .idea *.iml +.vscode/.BROWSE.VC.DB-shm +.vscode/.BROWSE.VC.DB-wal diff --git a/clients/chrome/background.ts b/clients/chrome/background.ts index 8925a363..049889f7 100644 --- a/clients/chrome/background.ts +++ b/clients/chrome/background.ts @@ -61,7 +61,7 @@ function findNewDevices() { function main() { // Register new clients in the [ports] global variable. chrome.runtime.onConnectExternal.addListener(function (port) { - if (/^(micro:bit|touchdevelop|yelm|pxt|codemicrobit|codethemicrobit)$/.test(port.name)) { + if (/^(micro:bit|touchdevelop|yelm|pxt|codemicrobit|codethemicrobit|pxt.microbit.org)$/.test(port.name)) { ports.push(port); port.onDisconnect.addListener(function () { ports = ports.filter(function (x) { return x != port }); diff --git a/clients/chrome/manifest.json b/clients/chrome/manifest.json index a94c62a6..18daf0f6 100644 --- a/clients/chrome/manifest.json +++ b/clients/chrome/manifest.json @@ -11,8 +11,8 @@ "author": "Microsoft Corporation", "short_name": "code the micro:bit", - "description": "Extension for https://codethemicrobit.com.", - "homepage_url": "https://codethemicrobit.com", + "description": "Extension for https://pxt.microbit.org.", + "homepage_url": "https://pxt.microbit.org", "offline_enabled": "true", "icons": { "48": "logo48.png", @@ -25,6 +25,6 @@ ], "externally_connectable": { - "matches": [ "*://localhost/*", "https://codethemicrobit.com/*", "https://*.codethemicrobit.com/*" ] + "matches": [ "*://localhost/*", "https://pxt.microbit.org/*", "https://*.microbit.org/*" ] } } diff --git a/clients/macuploader/Microbit Uploader/AppDelegate.m b/clients/macuploader/Microbit Uploader/AppDelegate.m index 3d62dc45..3f07a9ed 100644 --- a/clients/macuploader/Microbit Uploader/AppDelegate.m +++ b/clients/macuploader/Microbit Uploader/AppDelegate.m @@ -124,7 +124,7 @@ } - (void)launchEditor:(id)sender { - [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://codethemicrobit.com/"]]; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://pxt.microbit.org/"]]; } @end diff --git a/clients/macuploader/README.md b/clients/macuploader/README.md index 732d87fd..de3205f4 100644 --- a/clients/macuploader/README.md +++ b/clients/macuploader/README.md @@ -3,10 +3,10 @@ ![](Microbit Uploader/Assets.xcassets/AppIcon.appiconset/icon_256x256.png) This project is a clone of the [Windows -uploader](https://codethemicrobit.com/uploader), but for OS X. Once launched, +uploader](https://pxt.microbit.org/uploader), but for OS X. Once launched, the app runs in your menu bar and will automatically deploy any HEX files to your `micro:bit`. Like the Windows version, it is compatible with any browser -that can run [codethemicrobit.com](http://codethemicrobit.com). +that can run [pxt.microbit.org](http://pxt.microbit.org). ## Install the built version diff --git a/clients/win10/app.sln b/clients/win10/app.sln deleted file mode 100644 index 7d514686..00000000 --- a/clients/win10/app.sln +++ /dev/null @@ -1,48 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "m.pxt.io", "app\m.pxt.io.jsproj", "{39122940-AB16-4CD4-A0CE-79A3EB863ECF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.ActiveCfg = Debug|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.Build.0 = Debug|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.Deploy.0 = Debug|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.ActiveCfg = Debug|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.Build.0 = Debug|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.Deploy.0 = Debug|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.ActiveCfg = Debug|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.Build.0 = Debug|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.Deploy.0 = Debug|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.Build.0 = Release|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.Deploy.0 = Release|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.ActiveCfg = Release|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.Build.0 = Release|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.Deploy.0 = Release|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.ActiveCfg = Release|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.Build.0 = Release|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.Deploy.0 = Release|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.ActiveCfg = Release|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.Build.0 = Release|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.Deploy.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.ps1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.ps1 deleted file mode 100644 index 9b620977..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.ps1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/Add-AppDevPackage.psd1 deleted file mode 100644 index e2fe6f3f..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/cs-CZ/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/cs-CZ/Add-AppDevPackage.psd1 deleted file mode 100644 index d973be27..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/cs-CZ/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/de-DE/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/de-DE/Add-AppDevPackage.psd1 deleted file mode 100644 index 19238225..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/de-DE/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/en-US/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/en-US/Add-AppDevPackage.psd1 deleted file mode 100644 index e2fe6f3f..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/en-US/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/es-ES/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/es-ES/Add-AppDevPackage.psd1 deleted file mode 100644 index aca49f4e..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/es-ES/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/fr-FR/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/fr-FR/Add-AppDevPackage.psd1 deleted file mode 100644 index 41c39b86..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/fr-FR/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/it-IT/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/it-IT/Add-AppDevPackage.psd1 deleted file mode 100644 index 6098731f..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/it-IT/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ja-JP/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ja-JP/Add-AppDevPackage.psd1 deleted file mode 100644 index 0fd1ae55..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ja-JP/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ko-KR/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ko-KR/Add-AppDevPackage.psd1 deleted file mode 100644 index ddf71404..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ko-KR/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/pl-PL/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/pl-PL/Add-AppDevPackage.psd1 deleted file mode 100644 index 191b915a..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/pl-PL/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/pt-BR/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/pt-BR/Add-AppDevPackage.psd1 deleted file mode 100644 index e8cc86c2..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/pt-BR/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ru-RU/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ru-RU/Add-AppDevPackage.psd1 deleted file mode 100644 index 2c1dd5b3..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/ru-RU/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/tr-TR/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/tr-TR/Add-AppDevPackage.psd1 deleted file mode 100644 index 4fb2b071..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/tr-TR/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/zh-CN/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/zh-CN/Add-AppDevPackage.psd1 deleted file mode 100644 index dd32ec36..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/zh-CN/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/zh-TW/Add-AppDevPackage.psd1 b/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/zh-TW/Add-AppDevPackage.psd1 deleted file mode 100644 index 162d7078..00000000 Binary files a/clients/win10/app/AppPackages/latest/Add-AppDevPackage.resources/zh-TW/Add-AppDevPackage.psd1 and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/m.pxt.io_0.1.4.0_AnyCPU_Debug.appxbundle b/clients/win10/app/AppPackages/latest/m.pxt.io_0.1.4.0_AnyCPU_Debug.appxbundle deleted file mode 100644 index 70a1ae51..00000000 Binary files a/clients/win10/app/AppPackages/latest/m.pxt.io_0.1.4.0_AnyCPU_Debug.appxbundle and /dev/null differ diff --git a/clients/win10/app/AppPackages/latest/m.pxt.io_0.1.4.0_AnyCPU_Debug.cer b/clients/win10/app/AppPackages/latest/m.pxt.io_0.1.4.0_AnyCPU_Debug.cer deleted file mode 100644 index 29bd9676..00000000 Binary files a/clients/win10/app/AppPackages/latest/m.pxt.io_0.1.4.0_AnyCPU_Debug.cer and /dev/null differ diff --git a/clients/win10/app/BundleArtifacts/neutral.txt b/clients/win10/app/BundleArtifacts/neutral.txt deleted file mode 100644 index dec77c29..00000000 --- a/clients/win10/app/BundleArtifacts/neutral.txt +++ /dev/null @@ -1 +0,0 @@ -MainPackage=C:\gh\pxt-microbit\win10\app\bin\Debug\m.pxt.io_0.1.4.0_AnyCPU_Debug.appx diff --git a/clients/win10/app/codethemicrobitapp.jsproj b/clients/win10/app/codethemicrobitapp.jsproj deleted file mode 100644 index 5d230f3a..00000000 --- a/clients/win10/app/codethemicrobitapp.jsproj +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Debug - AnyCPU - - - Debug - ARM - - - Debug - x64 - - - Debug - x86 - - - Release - AnyCPU - - - Release - ARM - - - Release - x64 - - - Release - x86 - - - - 39122940-ab16-4cd4-a0ce-79a3eb863ecf - - - - 14.0 - - - - - UAP - 10.0.10586.0 - 10.0.10240.0 - $(VersionNumberMajor).$(VersionNumberMinor) - en-US - pxtwinapp_TemporaryKey.pfx - True - Always - neutral - - - - Designer - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/clients/win10/app/codethemicrobitapp.sln b/clients/win10/app/codethemicrobitapp.sln deleted file mode 100644 index ae487bac..00000000 --- a/clients/win10/app/codethemicrobitapp.sln +++ /dev/null @@ -1,48 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "codethemicrobitapp", "codethemicrobitapp.jsproj", "{39122940-AB16-4CD4-A0CE-79A3EB863ECF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.ActiveCfg = Debug|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.Build.0 = Debug|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.Deploy.0 = Debug|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.ActiveCfg = Debug|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.Build.0 = Debug|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.Deploy.0 = Debug|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.ActiveCfg = Debug|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.Build.0 = Debug|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.Deploy.0 = Debug|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.Build.0 = Release|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.Deploy.0 = Release|Any CPU - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.ActiveCfg = Release|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.Build.0 = Release|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.Deploy.0 = Release|ARM - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.ActiveCfg = Release|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.Build.0 = Release|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.Deploy.0 = Release|x64 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.ActiveCfg = Release|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.Build.0 = Release|x86 - {39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.Deploy.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/clients/win10/app/images/LockScreenLogo.scale-200.png b/clients/win10/app/images/LockScreenLogo.scale-200.png deleted file mode 100644 index ed9a4ef5..00000000 Binary files a/clients/win10/app/images/LockScreenLogo.scale-200.png and /dev/null differ diff --git a/clients/win10/app/images/SplashScreen.scale-200.png b/clients/win10/app/images/SplashScreen.scale-200.png deleted file mode 100644 index 9fdfc904..00000000 Binary files a/clients/win10/app/images/SplashScreen.scale-200.png and /dev/null differ diff --git a/clients/win10/app/images/Square150x150Logo.scale-200.png b/clients/win10/app/images/Square150x150Logo.scale-200.png deleted file mode 100644 index c879f5f6..00000000 Binary files a/clients/win10/app/images/Square150x150Logo.scale-200.png and /dev/null differ diff --git a/clients/win10/app/images/Square44x44Logo.scale-200.png b/clients/win10/app/images/Square44x44Logo.scale-200.png deleted file mode 100644 index 339d7e1b..00000000 Binary files a/clients/win10/app/images/Square44x44Logo.scale-200.png and /dev/null differ diff --git a/clients/win10/app/images/Square44x44Logo.targetsize-24_altform-unplated.png b/clients/win10/app/images/Square44x44Logo.targetsize-24_altform-unplated.png deleted file mode 100644 index 285bf05c..00000000 Binary files a/clients/win10/app/images/Square44x44Logo.targetsize-24_altform-unplated.png and /dev/null differ diff --git a/clients/win10/app/images/StoreLogo.png b/clients/win10/app/images/StoreLogo.png deleted file mode 100644 index fffe2f1a..00000000 Binary files a/clients/win10/app/images/StoreLogo.png and /dev/null differ diff --git a/clients/win10/app/images/Wide310x150Logo.scale-200.png b/clients/win10/app/images/Wide310x150Logo.scale-200.png deleted file mode 100644 index 816b48e1..00000000 Binary files a/clients/win10/app/images/Wide310x150Logo.scale-200.png and /dev/null differ diff --git a/clients/win10/app/msapp-error.css b/clients/win10/app/msapp-error.css deleted file mode 100644 index baefb056..00000000 --- a/clients/win10/app/msapp-error.css +++ /dev/null @@ -1,17 +0,0 @@ -body { - margin: 10px; -} - -.tip { - font-size: 90%; - padding-left: 20px; -} - -.paramName { - font-size: 100%; - color: black; -} - -.paramValue { - color: black; -} diff --git a/clients/win10/app/msapp-error.html b/clients/win10/app/msapp-error.html deleted file mode 100644 index 054a8554..00000000 --- a/clients/win10/app/msapp-error.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - Navigation Error - - - - -

Navigation Error

-
- -failureUrl= - - (indicates the url where the error occurred)
-

-
- -httpStatus= - - (available when the error has an http status code)
-

-
- -failureName= - - (available only when the error does not have a http status code)
-
- - diff --git a/clients/win10/app/msapp-error.js b/clients/win10/app/msapp-error.js deleted file mode 100644 index d9051e8b..00000000 --- a/clients/win10/app/msapp-error.js +++ /dev/null @@ -1,22 +0,0 @@ -(function () { - var validParameterNames = [ "httpStatus", "failureName", "failureUrl" ]; - - function parseQueryParameters() { - var query = location.search.slice(1); - return query.split("&").reduce(function (queryParameters, rawPair) { - var pair = rawPair.split("=").map(decodeURIComponent); - queryParameters[pair[0]] = pair[1]; - return queryParameters; - }, {}); - } - - function initialize() { - var queryParameters = parseQueryParameters(); - validParameterNames.forEach(function (parameterName) { - var parameterValue = queryParameters[parameterName] || "N/A"; - document.getElementById(parameterName + "Value").textContent = parameterValue; - }); - } - - document.addEventListener("DOMContentLoaded", initialize); -}()); diff --git a/clients/win10/app/package.appxmanifest b/clients/win10/app/package.appxmanifest deleted file mode 100644 index 8eee874c..00000000 --- a/clients/win10/app/package.appxmanifest +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - codethemicrobit - Microsoft - images\storelogo.png - - - - - - - - - - - - - - - - - - - - - - - BBC micro:bit binary file - - .hex - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/clients/win10/app/pxtwinapp_TemporaryKey.pfx b/clients/win10/app/pxtwinapp_TemporaryKey.pfx deleted file mode 100644 index 613b5574..00000000 Binary files a/clients/win10/app/pxtwinapp_TemporaryKey.pfx and /dev/null differ diff --git a/clients/win10/store/desktopblocks1366x768.png b/clients/win10/store/desktopblocks1366x768.png deleted file mode 100644 index 3ce40fd0..00000000 Binary files a/clients/win10/store/desktopblocks1366x768.png and /dev/null differ diff --git a/clients/win10/store/desktopjavascript1366x768.png b/clients/win10/store/desktopjavascript1366x768.png deleted file mode 100644 index 997e99fa..00000000 Binary files a/clients/win10/store/desktopjavascript1366x768.png and /dev/null differ diff --git a/clients/win10/store/mobileblocks480x800.png b/clients/win10/store/mobileblocks480x800.png deleted file mode 100644 index 0ad1ced6..00000000 Binary files a/clients/win10/store/mobileblocks480x800.png and /dev/null differ diff --git a/clients/winuploader/Microbit.Uploader/MainForm.cs b/clients/winuploader/Microbit.Uploader/MainForm.cs index 3a2fbf52..11eecb33 100644 --- a/clients/winuploader/Microbit.Uploader/MainForm.cs +++ b/clients/winuploader/Microbit.Uploader/MainForm.cs @@ -32,7 +32,7 @@ namespace Microsoft.MicroBit private void openEditor() { // lanch editor - try { Process.Start("https://codethemicrobit.com#uploader"); } catch (Exception) { } + try { Process.Start("https://pxt.microbit.org#uploader"); } catch (Exception) { } } private void initializeFileWatch() @@ -236,7 +236,7 @@ namespace Microsoft.MicroBit { try { - Process.Start("https://codethemicrobit.com/uploader"); + Process.Start("https://pxt.microbit.org/uploader"); } catch (IOException) { } } diff --git a/docs/about.md b/docs/about.md index 2562578c..ebf451ff 100644 --- a/docs/about.md +++ b/docs/about.md @@ -79,7 +79,7 @@ When code is compiled to ARM machine code, the calls to JavaScript micro:bit fun ## [Command Line Tools](/cli) -Looking to use codethemicrobit.com in your favorite editor? Install the [command line tools](/cli) and get rolling! +Looking to use pxt.microbit.org in your favorite editor? Install the [command line tools](/cli) and get rolling! ## [Packages](/packages) diff --git a/docs/browsers.md b/docs/browsers.md index e3ae501a..fab7ebb7 100644 --- a/docs/browsers.md +++ b/docs/browsers.md @@ -1,6 +1,6 @@ # Unsupported configuration -[codethemicrobit.com](https://codethemicrobit.com) doesn't currently support +[pxt.microbit.org](https://pxt.microbit.org) doesn't currently support your browser or operating system. The following configurations are supported: ## Windows diff --git a/docs/browsers/technical.md b/docs/browsers/technical.md index 5dac2f0f..adc4dbe4 100644 --- a/docs/browsers/technical.md +++ b/docs/browsers/technical.md @@ -1,12 +1,12 @@ # Technical information about browser support -[codethemicrobit.com][] requires that you use a recent version of a modern +[pxt.microbit.org][] requires that you use a recent version of a modern browser, such as Microsoft Edge, Google Chrome, Mozilla Firefox, Safari, Opera, or IE11. This is because the editor uses modern web technologies such as [web workers][] to enable compiling [TypeScript][] in the browser, or the using the same [Monaco][] editor that powers [Visual Studio Code][]. -[codethemicrobit.com]: https://codethemicrobit.com +[pxt.microbit.org]: https://pxt.microbit.org [web workers]: http://www.w3.org/TR/workers/ [typescript]: http://www.typescriptlang.org [monaco]: https://microsoft.github.io/monaco-editor/ diff --git a/docs/cli.md b/docs/cli.md index aa3b3544..d27d7810 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -6,7 +6,7 @@ basic.forever(() => { }) ``` -It is possible to use the codethemicrobit tools from a command line interface (CLI). The PXT CLI allows to +It is possible to use the tools from a command line interface (CLI). The PXT CLI allows to * edit, compile or deploy JavaScript programs * can easily be integrated in most IDEs. It comes with built-in support for [Visual Studio Code](/code)! * run a local web server for the web editor diff --git a/docs/device/serial.md b/docs/device/serial.md index 1598a260..7daacf8d 100644 --- a/docs/device/serial.md +++ b/docs/device/serial.md @@ -29,7 +29,7 @@ Unfortunately, using the serial library requires quite a bit of a setup. If you are using the Google Chrome browser, you can use our extension to get serial data streaming in the editor. * Install the [Extension for BBC micro:bit](https://chrome.google.com/webstore/detail/extension-for-bbc-microbi/cihhkhnngbjlhahcfmhekmbnnjcjdbge?hl=en-US) on the Chrome Web Store. -* Restart Chrome and open the [web editor](https://codethemicrobit.com) +* Restart Chrome and open the [web editor](https://pxt.microbit.org) * The serial data will show below the simulator ### Windows diff --git a/docs/device/usb/mac-chrome.md b/docs/device/usb/mac-chrome.md index 349472f3..14e7143a 100644 --- a/docs/device/usb/mac-chrome.md +++ b/docs/device/usb/mac-chrome.md @@ -34,7 +34,7 @@ it appears as a new drive under Devices. ## Step 2: Download your program -1. Open your project on [codethemicrobit.com](https://codethemicrobit.com) +1. Open your project on [pxt.microbit.org](https://pxt.microbit.org) 2. Click **Download** 3. When prompted, choose to **save** the compiled file onto your computer. The prompt will be different depending on which browser you are using, or diff --git a/docs/device/usb/mac-firefox.md b/docs/device/usb/mac-firefox.md index c3b9b1af..79b39a9b 100644 --- a/docs/device/usb/mac-firefox.md +++ b/docs/device/usb/mac-firefox.md @@ -34,7 +34,7 @@ it appears as a new drive under Devices. ## Step 2: Download your program -1. Open your project on [codethemicrobit.com](https://codethemicrobit.com) +1. Open your project on [pxt.microbit.org](https://pxt.microbit.org) 2. Click **Download** 3. When prompted, choose to **save** the compiled file onto your computer. The prompt will be different depending on which browser you are using, or diff --git a/docs/device/usb/mac-safari.md b/docs/device/usb/mac-safari.md index c2a5e12c..104e364a 100644 --- a/docs/device/usb/mac-safari.md +++ b/docs/device/usb/mac-safari.md @@ -34,7 +34,7 @@ it appears as a new drive under Devices. ## Step 2: Download your program -1. Open your project on [codethemicrobit.com](https://codethemicrobit.com) +1. Open your project on [pxt.microbit.org](https://pxt.microbit.org) 2. Click **Download** 3. When prompted, choose to **save** the compiled file onto your computer. The prompt will be different depending on which browser you are using, or diff --git a/docs/device/usb/windows-chrome.md b/docs/device/usb/windows-chrome.md index 9964c836..b19e48ae 100644 --- a/docs/device/usb/windows-chrome.md +++ b/docs/device/usb/windows-chrome.md @@ -41,7 +41,7 @@ it appears as a new drive under Devices. ## Step 2: Download your program -1. Open your project on [codethemicrobit.com](https://codethemicrobit.com) +1. Open your project on [pxt.microbit.org](https://pxt.microbit.org) 2. Click **Download** 3. When prompted, choose to **save** the compiled file onto your computer. The prompt will be different depending on which browser you are using, or diff --git a/docs/device/usb/windows-edge.md b/docs/device/usb/windows-edge.md index fb9bbd15..e72eea0c 100644 --- a/docs/device/usb/windows-edge.md +++ b/docs/device/usb/windows-edge.md @@ -43,7 +43,7 @@ it appears as a new drive under Devices. ## Step 2: Download your program -1. Open your project on [codethemicrobit.com](https://codethemicrobit.com) +1. Open your project on [pxt.microbit.org](https://pxt.microbit.org) 2. Click **Download** 3. When prompted, choose to **save** the compiled file onto your computer. The prompt will be different depending on which browser you are using, or diff --git a/docs/device/usb/windows-firefox.md b/docs/device/usb/windows-firefox.md index d0371c53..473d6322 100644 --- a/docs/device/usb/windows-firefox.md +++ b/docs/device/usb/windows-firefox.md @@ -43,7 +43,7 @@ it appears as a new drive under Devices. ## Step 2: Download your program -1. Open your project on [codethemicrobit.com](https://codethemicrobit.com) +1. Open your project on [pxt.microbit.org](https://pxt.microbit.org) 2. Click **Download** 3. When prompted, choose to **save** the compiled file onto your computer. The prompt will be different depending on which browser you are using, or diff --git a/docs/device/usb/windows-ie.md b/docs/device/usb/windows-ie.md index 71bffab6..786a998e 100644 --- a/docs/device/usb/windows-ie.md +++ b/docs/device/usb/windows-ie.md @@ -41,7 +41,7 @@ it appears as a new drive under Devices. ## Step 2: Download your program -1. Open your project on [codethemicrobit.com](https://codethemicrobit.com) +1. Open your project on [pxt.microbit.org](https://pxt.microbit.org) 2. Click **Download** 3. When prompted, choose to **save** the compiled file onto your computer. The prompt will be different depending on which browser you are using, or diff --git a/docs/faq.md b/docs/faq.md index 74bb5828..a95b7ee7 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -2,33 +2,4 @@ ### @description Frequently asked questions and answers from our users. -### Where can I get a BBC micro:bit? - -More information at [http://uk.farnell.com/bbc-microbit](http://uk.farnell.com/bbc-microbit). - -### How do I send feedback? - -Find the small bubble icon on the bottom of the editor and -post your feedback from there! - -### How do I save my code? - -The web editor automatically saves your code in the browser cache. Simply reopen the browser and navigate to the web editor -to reopen your latest project. You can also open previous project stored locally through **More -> Open Project**. - -The project source is also stored in each compiled ``.hex`` file. Drag and drop the ``.hex`` file into the web editor to load the project. - -To share your project with others, you can use the [Embed Project...](/share). -It stores your project in the cloud and creates a URL that you can share with others. - -If you are using [Visual Studio Code](/code), all your programs are stored as files on your computer and you can use your favorite source control system as needed. - -## Is the web site available in other languages? - -You can [help us translate](/translate) the web site, documentation and blocks via our crowd-source translations! - -## Troubleshooting - -### My micro:bit does not show up as a drive when I connect it to my computer. - -A common cause for this is a broken cable. Pick another USB cable and try it. Otherwise, try another computer as well. \ No newline at end of file +Please search for solutions or open a ticket at [support.microbit.org](https://support.microbit.org)! diff --git a/docs/favicon.ico b/docs/favicon.ico index 9e681b2e..31a7f124 100644 Binary files a/docs/favicon.ico and b/docs/favicon.ico differ diff --git a/docs/js/sequence.md b/docs/js/sequence.md index de0364dc..acfd93b3 100644 --- a/docs/js/sequence.md +++ b/docs/js/sequence.md @@ -41,8 +41,8 @@ In JavaScript, there is the concept of an *empty statement*, which is whitespace a semicolon in the context where a statement is expected. So, the following code is an infinite loop followed by a call to `showNumber` that will never execute: -```typescript -while(true) ; +```typescript-ignore +while(true) ; basic.showNumber(1); ``` diff --git a/docs/js/types.md b/docs/js/types.md index 597a19e9..81cf1c65 100644 --- a/docs/js/types.md +++ b/docs/js/types.md @@ -51,6 +51,8 @@ I'll be ${ age + 1 } years old next month.` This is equivalent to declaring `sentence` like so: ```ts +let fullName: string = `Bob Bobbington`; +let age: number = 37; let sentence: string = "Hello, my name is " + fullName + ".\n\n" + "I'll be " + (age + 1) + " years old next month." ``` @@ -82,7 +84,7 @@ A helpful addition to the standard set of datatypes from JavaScript is the `enum As in languages like C#, an enum is a way of giving more friendly names to sets of numeric values. ```ts -enum Color {Red, Green, Blue}; +enum Color {Red, Green, Blue} let c: Color = Color.Green; ``` @@ -91,14 +93,14 @@ You can change this by manually setting the value of one of its members. For example, we can start the previous example at `1` instead of `0`: ```ts -enum Color {Red = 1, Green, Blue}; +enum Color {Red = 1, Green, Blue} let c: Color = Color.Green; ``` Or, even manually set all the values in the enum: ```ts -enum Color {Red = 1, Green = 2, Blue = 4}; +enum Color {Red = 1, Green = 2, Blue = 4} let c: Color = Color.Green; ``` diff --git a/docs/lessons/bop-it/activity.md b/docs/lessons/bop-it/activity.md index 75f932a3..44d3093d 100644 --- a/docs/lessons/bop-it/activity.md +++ b/docs/lessons/bop-it/activity.md @@ -6,43 +6,43 @@ a game similar to "Simon Says" with the BBC micro:bit. Complete the following guided tutorial. Your code should look like this: -```blocks -newAction() // *** +```typescript +let action = 0; +function newAction() {} input.onButtonPressed(Button.A, () => { if (action == 0) { - game.addScore(1) // *** - newAction() // *** + game.addScore(1); + newAction(); } -}) // *** +}) input.onLogoDown(() => { if (action == 1) { - game.addScore(1) // *** - newAction() + game.addScore(1); + newAction(); } }) input.onGesture(Gesture.Shake, () => { if (action == 2) { - game.addScore(1) - newAction() + game.addScore(1); + newAction(); } }) input.onButtonPressed(Button.B, () => { - basic.showNumber(game.score(), 150) // *** - basic.pause(2000) // *** - newAction() // *** + basic.showNumber(game.score(), 150); + basic.pause(2000); + newAction(); }) ``` ### Challenge 1 -Now let's add some more types of instructions for the player to follow. Let's add `PRESS PIN 0`. Change the global variable `action` to `math->random(4)` so that we can add a new **IF** statement that checks if `action=3`. If it does, display instructions to press pin 0. +Now let's add some more types of instructions for the player to follow. Let's add `PRESS PIN 0`. +Change the global variable `action` to `math->random(4)` so that we can add a new **IF** statement that checks if `action=3`. If it does, display instructions to press pin 0. -```blocks -/** - * {highlight} - */ +```typescript +let action = 0; export function newAction() { - action = Math.random(4) // *** + action = Math.random(4) if (action == 0) { basic.showString("PUSH A", 150) // *** } @@ -62,19 +62,22 @@ export function newAction() { Now let's implement `PRESS PIN 0` in the main. Create a condition of `input->on pin pressed("P0")` that will add one to the score and calls the method `new action`. -```blocks -// **. . .** +```typescript +let action = 0; +export function newAction() { + // ... +} input.onButtonPressed(Button.B, () => { - basic.showNumber(game.score(), 150) // *** - basic.pause(2000) // *** - newAction() // *** -}) // *** + basic.showNumber(game.score(), 150) + basic.pause(2000) + newAction() +}) input.onPinPressed(TouchPin.P0, () => { if (action == 3) { - game.addScore(1) // *** - newAction() // *** + game.addScore(1) + newAction() } -}) // *** +}) ``` ### Challenge 3 diff --git a/docs/lessons/charting/challenge.md b/docs/lessons/charting/challenge.md index 660a10c0..58944c31 100644 --- a/docs/lessons/charting/challenge.md +++ b/docs/lessons/charting/challenge.md @@ -88,5 +88,5 @@ Have fun reviewing your simulation and analyze the acceleration by chart the Exc * Display acceleration with y or z using plot bar graph by changing acceleration from "x" to "y" or "z" ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/lessons/headbands/quiz-answers.md b/docs/lessons/headbands/quiz-answers.md index 7d0ed86c..792892c3 100644 --- a/docs/lessons/headbands/quiz-answers.md +++ b/docs/lessons/headbands/quiz-answers.md @@ -29,6 +29,7 @@ Write the line of code that will display the string "puppy" using `data->coll`.
```blocks +let coll: string[] = [] basic.showString(coll[0], 150) ``` @@ -46,6 +47,7 @@ Write the line of code that will display the string "cat" using `data->coll`.
```blocks +let coll: string[] = [] basic.showString(coll[2], 150) ``` diff --git a/docs/lessons/pogo.md b/docs/lessons/pogo.md index 928a9612..cc8ce154 100644 --- a/docs/lessons/pogo.md +++ b/docs/lessons/pogo.md @@ -44,5 +44,5 @@ radio.onDataReceived(() => { }) * learn how to pause your code for the specified number of milliseconds ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/lessons/pogo/activity.md b/docs/lessons/pogo/activity.md index 8e85a649..53ca5121 100644 --- a/docs/lessons/pogo/activity.md +++ b/docs/lessons/pogo/activity.md @@ -164,5 +164,5 @@ Connect the second micro:bit to your computer using your USB cable and run the p The first person and second person take turns jumping in the “y” direction while the other player uses the micro:bit to track the results on the micro:bit! ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/lessons/seismograph.md b/docs/lessons/seismograph.md index 53a14e38..24088fa1 100644 --- a/docs/lessons/seismograph.md +++ b/docs/lessons/seismograph.md @@ -35,5 +35,5 @@ radio.receiveNumber(); * learn how to read the connector value as analog as a value comprised between 0 and 1023 ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/lessons/seismograph/challenge.md b/docs/lessons/seismograph/challenge.md index 426b5ba9..df0e6895 100644 --- a/docs/lessons/seismograph/challenge.md +++ b/docs/lessons/seismograph/challenge.md @@ -196,5 +196,5 @@ Let's select Style 10 as an example. * Review and analyze the actual micro:bit device acceleration data on Excel ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/lessons/spinner/quiz-answers.md b/docs/lessons/spinner/quiz-answers.md index 10f7d4bc..86b1ecd4 100644 --- a/docs/lessons/spinner/quiz-answers.md +++ b/docs/lessons/spinner/quiz-answers.md @@ -25,8 +25,9 @@ let randomArrow = Math.random(4)
```blocks +let randomArrow = Math.random(4); if (randomArrow == 1) { - basic.plotImage(` + basic.showLeds(` . . # . . . . # . . # # # # # @@ -43,8 +44,9 @@ if (randomArrow == 1) {
```blocks +let randomArrow = Math.random(4); if (randomArrow == 2) { - basic.plotImage(` + basic.showLeds(` . . # . . . . # # . # # # # # diff --git a/docs/offline.md b/docs/offline.md index 402fa521..449b6f20 100644 --- a/docs/offline.md +++ b/docs/offline.md @@ -2,7 +2,7 @@ ## Web application -**https://codethemicrobit.com is an HTML5 web application** that automatically gets cached locally by your browser. +**https://pxt.microbit.org is an HTML5 web application** that automatically gets cached locally by your browser. Once the web app is loaded and you have compiled at least once, you will have all the code needed to work without an internet connection. ## Command line interface diff --git a/docs/projects.md b/docs/projects.md index 675717aa..3d98e3b9 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -70,6 +70,19 @@ Fun games to build with your micro:bit. }] ``` +## From the community + +Projects contributed by the micro:bit community + +```codecard +[{ + "name": "Magic Button Trick", + "url":"/projects/magic-button-trick", + "imageUrl":"/static/mb/projects/magic-button-trick.png" +}] +``` + + ### See Also [Flashing Heart](/projects/flashing-heart), [Smiley Buttons](/projects/smiley-buttons), [Love Meter](/projects/love-meter), [Rock Paper Scissors](/projects/rock-paper-scissors), [Compass](/projects/compass), [Hack your headphones](/projects/hack-your-headphones), [Banana keyboard](/projects/banana-keyboard), [Telegraph](/projects/telegraph), [Radio](/projects/radio), [Guitar](/projects/guitar), [Watch](/projects/the-watch) \ No newline at end of file diff --git a/docs/projects/guitar/displaybuttons.md b/docs/projects/guitar/displaybuttons.md index 1cf4d344..1021af19 100644 --- a/docs/projects/guitar/displaybuttons.md +++ b/docs/projects/guitar/displaybuttons.md @@ -43,7 +43,7 @@ music.beat(BeatFraction.Quarter) ``` ## Step 1: Make a Smiley -Open [codethemicrobit.com](https://codethemicrobit.com) in your web browser +Open [pxt.microbit.org](https://pxt.microbit.org) in your web browser ```blocks basic.showLeds(` . # . # . diff --git a/docs/projects/hack-your-headphones.md b/docs/projects/hack-your-headphones.md index 1d5bef04..a57329d3 100644 --- a/docs/projects/hack-your-headphones.md +++ b/docs/projects/hack-your-headphones.md @@ -21,7 +21,7 @@ Build your own music player micro:bit from headphones. ## Activities -* [Connect your headphone](/projects/hack-your-headphone/making) +* [Connect your headphone](/projects/hack-your-headphones/making) * [Play sounds!]() # ~hint diff --git a/docs/projects/magic-button-trick.md b/docs/projects/magic-button-trick.md new file mode 100644 index 00000000..ce032966 --- /dev/null +++ b/docs/projects/magic-button-trick.md @@ -0,0 +1,101 @@ +# magic button trick + +Perform a magic trick where you appear to make the **A** and **B** button of your micro:bit swap over just by moving a sticky label. + +### ~avatar avatar + +Welcome! This activity will teach you how to use the micro:bit's compass to detect a nearby magnet + +### ~ +This is a simple magic trick you can perform to amaze your friends, where by moving the sticky labels on your micro:bit's **A** and **B** button you appear to make the buttons really switch over. To see the trick performed watch the video below. + +https://youtu.be/-9KvmPopov8 + +## How the trick works + +Unfortunately, the only magic here is in the code. This trick uses a magnet, hidden in your hand, to tell the micro:bit to swap over the buttons so that when the magnet is near the microbit the **A** button starts working like the **B** button and the **B** button starts working like the **A** button. + +## What you need + +The only things you need for this trick are your micro:bit and any magnet that is small enough to fit in your hand, even a fridge magnet will work. + +![](/static/mb/projects/magic-button-trick/magnets.jpg "Magnets") + + +## Step 1: getting the buttons to display **A** and **B** + +Before we code the trick itself, we need to get the buttons working as you would expect them to so that pressing button **A** displays 'A' and pressing button **B** displays 'B': + +```blocks +input.onButtonPressed(Button.A, () => { + basic.showString("A") +}) +input.onButtonPressed(Button.B, () => { + basic.showString("B") +}) +``` + +## Step 2: measuring magnetic force + +We will use the micro:bit's compass to detect the magnet. Compass's tell us what direction we are pointing by detecting the Earth's magnetic field but they can also detect any other magnet nearby. We will use that to check if our magnet is next to the micro:bit by using the [magnetic force](/reference/input/magnetic-force) block found in the input menu's 'more' section. As we only want to measure the strength we change the drop down to select 'strength': + +```blocks +input.magneticForce(Dimension.Strength) +``` + +## Step 3: checking if the magnetic is nearby + +Now we can measure the magnetic force near the microbit, we can check if the value we measure is so big that it means there must be a strong magnet nearby. + +If you have ever played with magnets you know they have two ends, often called a north and south 'pole'. Depending on which end of the magnet is pointing at the microbit the magnetic force measurement will either be a negative number like -100 or a positive number like 100. We just want to know if the strength is at least 100 we don't care if its negative or positive so we also use the 'absolute value of' block from the maths menu to tell our code to ignore the negative sign and just treat -100 as if its 100. + +So in the code below we will check if the absolute value of our magnetic field strength reading is more than 100 and save the result of that check in a new variable called 'isSwitched': + +```blocks +let isSwitched = Math.abs(input.magneticForce(Dimension.Strength)) > 100 +``` +## Step 4: running our 'magnet nearby' check all the time + +At the moment our code to detect the magnet being nearby will only run once so we need to put it into a [forever](/reference/basic/forever) block so that it keeps getting run again and again checking for the magnet to come near to the micro:bit. We should also make sure 'isSwitched' is false when our program starts. + +```blocks +let isSwitched = false; +basic.forever(() => { + let isSwitched = Math.abs(input.magneticForce(Dimension.Strength)) > 100 +}) +``` + +## Step 5: swapping the buttons when we know the magnet is nearby + +Now we can check the value of our variable 'isSwitched' whenever we want and we will know that the magnet is nearby if it's value is 'true'. Let's use that to change how the buttons work and complete the code for our trick. We will add an 'if, else' block to each button's code and check if we should swap over what each button displays because 'isSwitched' is equal to true: + +```blocks + +let isSwitched = false; +basic.forever(() => { + isSwitched = Math.abs(input.magneticForce(Dimension.Strength)) > 100 +}) + +input.onButtonPressed(Button.A, () => { + if (isSwitched) { + basic.showString("B") + } else { + basic.showString("A") + } +}) +input.onButtonPressed(Button.B, () => { + if (isSwitched) { + basic.showString("A") + } else { + basic.showString("B") + } +}) + +``` + +## step 5: practice your performance +Now you just need to program your own micro:bit and practice the trick a few times before performing to friends. Try asking your friends to click the buttons after you have switched the labels and the trick won't work for them as they don't have a hidden magnet in their hand. + + +## about the authors +This project was contributed by Brian and Jasmine Norman, aka [@MicroMonstersUK](https://twitter.com/MicroMonstersUK). You can chekout their [micro:bit tutorials chanel on youtube](https://www.youtube.com/channel/UCK2DviDexh_Er2QYZerZyZQ) for more projects. \ No newline at end of file diff --git a/docs/projects/messenger.md b/docs/projects/messenger.md index dfe68064..a4cd488a 100644 --- a/docs/projects/messenger.md +++ b/docs/projects/messenger.md @@ -61,5 +61,5 @@ radio.onDataReceived(() => { ```package -microbit-radio +radio ``` diff --git a/docs/projects/radio-challenges.md b/docs/projects/radio-challenges.md index 15cb8b01..d401274a 100644 --- a/docs/projects/radio-challenges.md +++ b/docs/projects/radio-challenges.md @@ -90,5 +90,5 @@ Have fun reviewing your simulation and analyze the acceleration by chart the Exc * Display acceleration with y or z using plot bar graph by changing acceleration from "x" to "y" or "z" ```package -microbit-radio +radio ``` diff --git a/docs/projects/telegraph/manual-telegraph.md b/docs/projects/telegraph/manual-telegraph.md index 71896043..7244fb3d 100644 --- a/docs/projects/telegraph/manual-telegraph.md +++ b/docs/projects/telegraph/manual-telegraph.md @@ -8,7 +8,6 @@ We now need to digitally write to pin ``P0`` as **high** (1). ```blocks pins.digitalWritePin(DigitalPin.P0, 1) - ``` ### Step 2 @@ -19,7 +18,6 @@ So insert the appropriate LED plot x, y. ```blocks pins.digitalWritePin(DigitalPin.P0, 1) led.plot(2, 2) - ``` ### Step 3 @@ -31,9 +29,7 @@ Then add a condition that occurs if we do not turn on a LED with plot x, y. We a if (input.buttonIsPressed(Button.A)) { pins.digitalWritePin(DigitalPin.P0, 1) led.plot(2, 2) -} else { - -} +} else { } ``` @@ -63,7 +59,8 @@ basic.forever(() => { } else { pins.digitalWritePin(DigitalPin.P0, 0) led.unplot(2, 2) - }) + } +}) ``` ### Step 6 @@ -87,9 +84,6 @@ basic.forever(() => { basic.clearScreen(); } }); - - - ``` Your telegraph is ready! diff --git a/docs/projects/timing-gates.md b/docs/projects/timing-gates.md index ddfbf997..cda09f1c 100644 --- a/docs/projects/timing-gates.md +++ b/docs/projects/timing-gates.md @@ -87,7 +87,7 @@ The gate is ready to use! Your circuit should look like the picture below: ## Detecting the car with code -The micro:bit provides an event [on pin pressed](/reference/pins/on-pin-pressed) +The micro:bit provides an event [on pin pressed](/reference/input/on-pin-pressed) that is raised when a circuit between ``GND`` and a pin is detected. The circuit conductor could be a wire or even your body! We will attach a foil to the bottom of the car. When it passes over the gate, it connect both foil strips, close the circuit and trigger the event. @@ -146,7 +146,7 @@ Connect the crocodile plugs to the ``GND`` and ``P1`` pins on the micro:bit. ## Detecting the second gate -Since the second gate is connected to pin ``P1``, we add a second [on pin pressed](/reference/pins/on-pin-pressed) event +Since the second gate is connected to pin ``P1``, we add a second [on pin pressed](/reference/input/on-pin-pressed) event that display 2 columns of LEDs. ```blocks diff --git a/docs/raspberry-pi.md b/docs/raspberry-pi.md index 134423b4..6b7a603d 100644 --- a/docs/raspberry-pi.md +++ b/docs/raspberry-pi.md @@ -5,7 +5,7 @@ with [Raspbian Jessie with Pixel](https://www.raspberrypi.org/downloads/raspbian ## Web editor -Starting with **Raspbian Pixel**, Raspbian comes with Chromium. Simply open [](https://codethemicrobit.com). +Starting with **Raspbian Pixel**, Raspbian comes with Chromium. Simply open [](https://pxt.microbit.org). ## Command line diff --git a/docs/reference.md b/docs/reference.md index 4482a39b..c5bdd08e 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -37,9 +37,9 @@ bluetooth.onBluetoothConnected(() => {}); ``` ```package -microbit-radio -microbit-devices -microbit-bluetooth +radio +devices +bluetooth ``` ### See Also diff --git a/docs/reference/basic.md b/docs/reference/basic.md index 3a755857..27fe8fba 100644 --- a/docs/reference/basic.md +++ b/docs/reference/basic.md @@ -35,4 +35,6 @@ basic.showAnimation(` ### See Also -[showNumber](/reference/basic/show-number), [showLeds](/reference/basic/show-leds), [showString](/reference/basic/show-string), [clearScreen](/reference/basic/clear-screen), [forever](/reference/basic/forever), [pause](/reference/basic/pause), [plotLeds](/reference/basic/plot-leds), [showAnimation](/reference/basic/show-animation) +[showNumber](/reference/basic/show-number), [showLeds](/reference/basic/show-leds), [showString](/reference/basic/show-string), +[clearScreen](/reference/basic/clear-screen), [forever](/reference/basic/forever), [pause](/reference/basic/pause), +[showAnimation](/reference/basic/show-animation) diff --git a/docs/reference/bluetooth.md b/docs/reference/bluetooth.md index 5fd0543e..f631f4b4 100644 --- a/docs/reference/bluetooth.md +++ b/docs/reference/bluetooth.md @@ -32,7 +32,7 @@ bluetooth.uartWriteValue("", 0); ``` ```package -microbit-bluetooth +bluetooth ``` ### Advanced diff --git a/docs/reference/bluetooth/about-bluetooth.md b/docs/reference/bluetooth/about-bluetooth.md index b2fd820a..c695f164 100755 --- a/docs/reference/bluetooth/about-bluetooth.md +++ b/docs/reference/bluetooth/about-bluetooth.md @@ -95,5 +95,5 @@ https://www.youtube.com/watch?v=aep_GVowKfs [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` \ No newline at end of file diff --git a/docs/reference/bluetooth/bluetooth-pairing.md b/docs/reference/bluetooth/bluetooth-pairing.md index 976f8c07..8e5247cf 100755 --- a/docs/reference/bluetooth/bluetooth-pairing.md +++ b/docs/reference/bluetooth/bluetooth-pairing.md @@ -96,5 +96,5 @@ If you do find yourself needing to pair again you will first need to remove the ```package -microbit-bluetooth +bluetooth ``` \ No newline at end of file diff --git a/docs/reference/bluetooth/on-bluetooth-connected.md b/docs/reference/bluetooth/on-bluetooth-connected.md index 81fda9c6..963a236c 100755 --- a/docs/reference/bluetooth/on-bluetooth-connected.md +++ b/docs/reference/bluetooth/on-bluetooth-connected.md @@ -33,5 +33,5 @@ http://www.youtube.com/watch?v=HyBcsD9Eh6I [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` \ No newline at end of file diff --git a/docs/reference/bluetooth/on-bluetooth-disconnected.md b/docs/reference/bluetooth/on-bluetooth-disconnected.md index e0d64fcc..2406f8df 100755 --- a/docs/reference/bluetooth/on-bluetooth-disconnected.md +++ b/docs/reference/bluetooth/on-bluetooth-disconnected.md @@ -33,5 +33,5 @@ http://www.youtube.com/watch?v=HyBcsD9Eh6I [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/start-accelerometer-service.md b/docs/reference/bluetooth/start-accelerometer-service.md index 9c14de9e..59305b0e 100755 --- a/docs/reference/bluetooth/start-accelerometer-service.md +++ b/docs/reference/bluetooth/start-accelerometer-service.md @@ -38,5 +38,5 @@ For more advanced information on the micro:bit Bluetooth accelerometer service i [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/start-button-service.md b/docs/reference/bluetooth/start-button-service.md index 5ada6740..a0bc14fe 100755 --- a/docs/reference/bluetooth/start-button-service.md +++ b/docs/reference/bluetooth/start-button-service.md @@ -42,5 +42,5 @@ For more advanced information on the micro:bit Bluetooth button service includin [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/start-io-pin-service.md b/docs/reference/bluetooth/start-io-pin-service.md index a32d5ca9..5f9cc599 100755 --- a/docs/reference/bluetooth/start-io-pin-service.md +++ b/docs/reference/bluetooth/start-io-pin-service.md @@ -36,5 +36,5 @@ For more advanced information on the micro:bit Bluetooth IO pin service includin [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/start-led-service.md b/docs/reference/bluetooth/start-led-service.md index e01073d7..cd7bef1b 100755 --- a/docs/reference/bluetooth/start-led-service.md +++ b/docs/reference/bluetooth/start-led-service.md @@ -38,5 +38,5 @@ For more advanced information on the micro:bit Bluetooth LED service including i [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/start-magnetometer-service.md b/docs/reference/bluetooth/start-magnetometer-service.md index f86f295f..c65c094e 100755 --- a/docs/reference/bluetooth/start-magnetometer-service.md +++ b/docs/reference/bluetooth/start-magnetometer-service.md @@ -39,5 +39,5 @@ For more advanced information on the micro:bit Bluetooth magnetometer service in ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/start-temperature-service.md b/docs/reference/bluetooth/start-temperature-service.md index ba5c3c41..59d95dc3 100755 --- a/docs/reference/bluetooth/start-temperature-service.md +++ b/docs/reference/bluetooth/start-temperature-service.md @@ -39,6 +39,6 @@ For more advanced information on the micro:bit Bluetooth temperature service inc ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/start-uart-service.md b/docs/reference/bluetooth/start-uart-service.md index 41e180b8..dffab6d7 100755 --- a/docs/reference/bluetooth/start-uart-service.md +++ b/docs/reference/bluetooth/start-uart-service.md @@ -40,5 +40,5 @@ For more advanced information on the micro:bit Bluetooth UART service including [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/uart-read-until.md b/docs/reference/bluetooth/uart-read-until.md index 189e9afd..3f52b4b7 100644 --- a/docs/reference/bluetooth/uart-read-until.md +++ b/docs/reference/bluetooth/uart-read-until.md @@ -7,7 +7,7 @@ For another device like a smartphone to use any of the Bluetooth "services" whic ### ~ -The [Bluetooth UART service](start-uart-service.md) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks. +The [Bluetooth UART service](/reference/bluetooth/start-uart-service) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks. With the Bluetooth UART service running, this block allows a micro:bit to read data which has been received from a Bluetooth connected device, terminating reading and returning the value obtained as soon as a specified delimiter character is encountered. This means that connected devices can send data to the micro:bit and indicate that the complete message has been sent by appending the message with the delimiter character. @@ -48,5 +48,5 @@ For more advanced information on the micro:bit Bluetooth UART service including [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/uart-write-number.md b/docs/reference/bluetooth/uart-write-number.md index 8ee099aa..4fc12928 100644 --- a/docs/reference/bluetooth/uart-write-number.md +++ b/docs/reference/bluetooth/uart-write-number.md @@ -7,7 +7,7 @@ For another device like a smartphone to use any of the Bluetooth "services" whic ### ~ -The [Bluetooth UART service](/reference/bluetooth/start-uart-service.md) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks. +The [Bluetooth UART service](/reference/bluetooth/start-uart-service) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks. With the Bluetooth UART service running, this block allows a micro:bit to send data to a Bluetooth connected device. @@ -24,5 +24,5 @@ For more advanced information on the micro:bit Bluetooth UART service including [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/uart-write-string.md b/docs/reference/bluetooth/uart-write-string.md index ffd10579..e4d4ecd9 100644 --- a/docs/reference/bluetooth/uart-write-string.md +++ b/docs/reference/bluetooth/uart-write-string.md @@ -7,7 +7,7 @@ For another device like a smartphone to use any of the Bluetooth "services" whic ### ~ -The [Bluetooth UART service](/reference/bluetooth/start-uart-service.md) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks. +The [Bluetooth UART service](/reference/bluetooth/start-uart-service) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks. With the Bluetooth UART service running, this block allows a micro:bit to send data to a Bluetooth connected device. @@ -47,5 +47,5 @@ For more advanced information on the micro:bit Bluetooth UART service including [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/bluetooth/uart-write-value.md b/docs/reference/bluetooth/uart-write-value.md index f3e86816..a47398b1 100644 --- a/docs/reference/bluetooth/uart-write-value.md +++ b/docs/reference/bluetooth/uart-write-value.md @@ -7,7 +7,7 @@ For another device like a smartphone to use any of the Bluetooth "services" whic ### ~ -The [Bluetooth UART service](/reference/bluetooth/start-uart-service.md) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks. +The [Bluetooth UART service](/reference/bluetooth/start-uart-service) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks. With the Bluetooth UART service running, this block allows a micro:bit to send data to a Bluetooth connected device. @@ -24,5 +24,5 @@ For more advanced information on the micro:bit Bluetooth UART service including [About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com) ```package -microbit-bluetooth +bluetooth ``` diff --git a/docs/reference/devices.md b/docs/reference/devices.md index 236a5029..01d8be15 100644 --- a/docs/reference/devices.md +++ b/docs/reference/devices.md @@ -19,7 +19,7 @@ devices.onSignalStrengthChanged(() => { ``` ```package -microbit-devices +devices ``` ### See Also diff --git a/docs/reference/devices/on-gamepad-button.md b/docs/reference/devices/on-gamepad-button.md index 4388eeeb..baba8246 100644 --- a/docs/reference/devices/on-gamepad-button.md +++ b/docs/reference/devices/on-gamepad-button.md @@ -23,5 +23,5 @@ devices.onGamepadButton(MesDpadButtonInfo.ADown, () => {}) [tell remote control to](/reference/devices/tell-remote-control-to), [raise alert to](/reference/devices/raise-alert-to), [signal strength](/reference/devices/signal-strength), [on signal strength changed](/reference/devices/on-signal-strength-changed) ```package -microbit-devices +devices ``` \ No newline at end of file diff --git a/docs/reference/devices/on-notified.md b/docs/reference/devices/on-notified.md index 9c30e153..693e0b41 100644 --- a/docs/reference/devices/on-notified.md +++ b/docs/reference/devices/on-notified.md @@ -34,5 +34,5 @@ devices.onNotified(MesDeviceInfo.IncomingCall, () => { [tell remote control to](/reference/devices/tell-remote-control-to), [raise alert to](/reference/devices/raise-alert-to), [signal strength](/reference/devices/signal-strength) ```package -microbit-devices +devices ``` \ No newline at end of file diff --git a/docs/reference/devices/on-signal-strength-changed.md b/docs/reference/devices/on-signal-strength-changed.md index 8584a497..f0894c50 100644 --- a/docs/reference/devices/on-signal-strength-changed.md +++ b/docs/reference/devices/on-signal-strength-changed.md @@ -34,5 +34,5 @@ devices.onSignalStrengthChanged(() => { [tell remote control to](/reference/devices/tell-remote-control-to), [raise alert to](/reference/devices/raise-alert-to), [signal strength](/reference/devices/signal-strength) ```package -microbit-devices +devices ``` \ No newline at end of file diff --git a/docs/reference/devices/raise-alert-to.md b/docs/reference/devices/raise-alert-to.md index 5477442b..a226ac1f 100644 --- a/docs/reference/devices/raise-alert-to.md +++ b/docs/reference/devices/raise-alert-to.md @@ -62,5 +62,5 @@ devices.raiseAlertTo("ring alarm") [tell remote control to](/reference/devices/tell-remote-control-to), [tell camera to](/reference/devices/tell-camera-to) ```package -microbit-devices +devices ``` \ No newline at end of file diff --git a/docs/reference/devices/signal-strength.md b/docs/reference/devices/signal-strength.md index 064b1aa3..a60a710d 100644 --- a/docs/reference/devices/signal-strength.md +++ b/docs/reference/devices/signal-strength.md @@ -33,5 +33,5 @@ devices.onSignalStrengthChanged(() => { [tell remote control to](/reference/devices/tell-remote-control-to), [raise alert to](/reference/devices/raise-alert-to), [on signal strength changed](/reference/devices/on-signal-strength-changed) ```package -microbit-devices +devices ``` \ No newline at end of file diff --git a/docs/reference/devices/tell-camera-to.md b/docs/reference/devices/tell-camera-to.md index ed8efcc4..81edb728 100644 --- a/docs/reference/devices/tell-camera-to.md +++ b/docs/reference/devices/tell-camera-to.md @@ -73,5 +73,5 @@ devices.tellCameraTo("stop video mode") [tell remote control to](/reference/devices/tell-remote-control-to), [raise alert to](/reference/devices/raise-alert-to) ```package -microbit-devices +devices ``` diff --git a/docs/reference/devices/tell-remote-control-to.md b/docs/reference/devices/tell-remote-control-to.md index 77f11a1b..fa141892 100644 --- a/docs/reference/devices/tell-remote-control-to.md +++ b/docs/reference/devices/tell-remote-control-to.md @@ -86,5 +86,5 @@ devices.tellRemoteControlTo("volume down") ```package -microbit-devices +devices ``` diff --git a/docs/reference/input.md b/docs/reference/input.md index 9b0c48ff..bc186bd4 100644 --- a/docs/reference/input.md +++ b/docs/reference/input.md @@ -42,4 +42,4 @@ input.onShake(() => { ### See Also -[onButtonPressed](/reference/input/on-button-pressed), [onGesture](/reference/input/on-gesture), [onPinPressed](/reference/input/on-pin-pressed), [buttonIsPressed](/reference/input/button-is-pressed), [compassHeading](/reference/input/compass-heading), [pinIsPressed](/reference/input/pin-is-pressed), [temperature](/reference/input/temperature), [acceleration](/reference/input/acceleration), [lightLevel](/reference/input/light-level), [rotation](/reference/input/rotation), [magneticForce](/reference/input/magnetic-force), [runningTime](/reference/input/running-time), [setAccelerometerRange](/reference/input/set-accelerometer-range), [calibrate](/reference/input/calibrate), [onLogoDown](/reference/input/on-logo-down), [onLogoUp](/reference/input/on-logo-up), [onScreenDown](/reference/input/on-screen-down), [onScreenUp](/reference/input/on-screen-up), [onShake](/reference/input/on-shake) +[onButtonPressed](/reference/input/on-button-pressed), [onGesture](/reference/input/on-gesture), [onPinPressed](/reference/input/on-pin-pressed), [buttonIsPressed](/reference/input/button-is-pressed), [compassHeading](/reference/input/compass-heading), [pinIsPressed](/reference/input/pin-is-pressed), [temperature](/reference/input/temperature), [acceleration](/reference/input/acceleration), [lightLevel](/reference/input/light-level), [rotation](/reference/input/rotation), [magneticForce](/reference/input/magnetic-force), [runningTime](/reference/input/running-time), [setAccelerometerRange](/reference/input/set-accelerometer-range) diff --git a/docs/reference/input/temperature.md b/docs/reference/input/temperature.md index 9eaee1e7..f0b234bf 100644 --- a/docs/reference/input/temperature.md +++ b/docs/reference/input/temperature.md @@ -33,12 +33,12 @@ basic.forever(() => { This program measures the temperature using Fahrenheit degrees. Fahrenheit is a way of measuring temperature that is commonly used in the United States. To make a Celsius temperature into a Fahrenheit one, multiply the Celsius temperature by -1.8 and add 32. +``18``, divide by ``10`` and add ``32``. ```blocks basic.forever(() => { let c = input.temperature() - let f = (c * 1.8) + 32 + let f = (c * 18) / 10 + 32 basic.showNumber(f) }) ``` diff --git a/docs/reference/music.md b/docs/reference/music.md index b770dbcd..c75c0320 100644 --- a/docs/reference/music.md +++ b/docs/reference/music.md @@ -6,7 +6,6 @@ Generation of music tones through pin ``P0``. music.playTone(0, 0); music.ringTone(0); music.rest(0); -music.noteFrequency(Note.C); music.beat(BeatFraction.Whole); music.tempo(); music.changeTempoBy(20); @@ -15,4 +14,4 @@ music.setTempo(120); ### See Also -[playTone](/reference/music/play-tone), [ringTone](/reference/music/ring-tone), [rest](/reference/music/rest), [noteFrequency](/reference/music/note-frequency), [beat](/reference/music/beat), [tempo](/reference/music/tempo), [changeTempoBy](/reference/music/change-tempo), [setTempo](/reference/music/set-tempo) +[playTone](/reference/music/play-tone), [ringTone](/reference/music/ring-tone), [rest](/reference/music/rest), [beat](/reference/music/beat), [tempo](/reference/music/tempo), [changeTempoBy](/reference/music/change-tempo-by), [setTempo](/reference/music/set-tempo) diff --git a/docs/reference/music/beat.md b/docs/reference/music/beat.md new file mode 100644 index 00000000..993fa7dd --- /dev/null +++ b/docs/reference/music/beat.md @@ -0,0 +1,30 @@ +# Beat + +Returns the duration of a beat in milli-seconds + +## Simulator + +This function only works on the micro:bit and in some browsers. + +```sig +music.beat(BeatFraction.Whole) +``` + +### Parameters + +* ``BeatFraction`` means fraction of a beat (BeatFraction.Whole, BeatFraction.Sixteenth etc) + +### Returns + +* a [number](/reference/types/number) that means the amount of milli-seconds a beat fraction represents. + + +## Example + +```blocks +music.playTone(Note.C, music.beat(BeatFraction.Quarter)) +``` + +### See also + +[play tone](/reference/music/play-tone), [ring tone](/reference/music/ring-tone), [rest](/reference/music/rest), [set tempo](/reference/music/set-tempo), [change tempo by](/reference/music/change-tempo-by) \ No newline at end of file diff --git a/docs/reference/pins.md b/docs/reference/pins.md index d9a9e1f5..d3696892 100644 --- a/docs/reference/pins.md +++ b/docs/reference/pins.md @@ -26,4 +26,4 @@ pins.analogSetPitchPin(AnalogPin.P0); ### See Also -[digitalReadPin](/reference/pins/digital-read-pin), [digitalWritePin](/reference/pins/digital-write-pin), [analogReadPin](/reference/pins/analog-read-pin), [analogWritePin](/reference/pins/analog-write-pin), [analogSetPeriod](/reference/pins/analog-set-period), [map](/reference/pins/map), [onPulsed](/reference/pins/on-pulsed), [pulseDuration](/reference/pins/pulse-duration), [pulseIn](/reference/pins/pulse-in), [servoWritePin](/reference/pins/servo-write-pin), [servoSetPulse](/reference/pins/servo-set-pulse), [i2cReadNumber](/reference/pins/i2c-read-number), [i2cWriteNumber](/reference/pins/i2c-write-number), [setPull](/reference/pins/set-pull), [analogPitch](/reference/pins/analog-pitch), [analogSetPitchPin](/reference/pins/analog-set-pitch), [spiWrite](/reference/pins/spi-write) +[digitalReadPin](/reference/pins/digital-read-pin), [digitalWritePin](/reference/pins/digital-write-pin), [analogReadPin](/reference/pins/analog-read-pin), [analogWritePin](/reference/pins/analog-write-pin), [analogSetPeriod](/reference/pins/analog-set-period), [map](/reference/pins/map), [onPulsed](/reference/pins/on-pulsed), [pulseDuration](/reference/pins/pulse-duration), [pulseIn](/reference/pins/pulse-in), [servoWritePin](/reference/pins/servo-write-pin), [servoSetPulse](/reference/pins/servo-set-pulse), [i2cReadNumber](/reference/pins/i2c-read-number), [i2cWriteNumber](/reference/pins/i2c-write-number), [setPull](/reference/pins/set-pull), [analogPitch](/reference/pins/analog-pitch), [analogSetPitchPin](/reference/pins/analog-set-pitch-pin), [spiWrite](/reference/pins/spi-write) diff --git a/docs/reference/radio.md b/docs/reference/radio.md index f65a0f78..2d86a4cc 100644 --- a/docs/reference/radio.md +++ b/docs/reference/radio.md @@ -20,9 +20,9 @@ radio.writeValueToSerial(); ``` ```package -microbit-radio +radio ``` ### See Also -[sendNumber](/reference/radio/send-number), [sendValue](/reference/radio/send-value), [sendString](/reference/radio/send-string), [onDataReceived](/reference/radio/on-data-received), [receiveNumber](/reference/radio/receive-number), [receivedNumberAt](/reference/radio/received-number-at), [receiveString](/reference/radio/receive-string), [receivedSignalStrength](/reference/radio/received-signal-strength), [setGroup](/reference/radio/set-group), [setTransmitPower](/reference/radio/set-transmit-power), [setTransmitSerialNumber](/reference/radio/set-transmit-serial-number), [writeValueToSerial](/reference/radio/write-value-to-serial) +[sendNumber](/reference/radio/send-number), [sendValue](/reference/radio/send-value), [sendString](/reference/radio/send-string), [onDataReceived](/reference/radio/on-data-received), [receiveNumber](/reference/radio/receive-number), [receiveString](/reference/radio/receive-string), [receivedSignalStrength](/reference/radio/received-signal-strength), [setGroup](/reference/radio/set-group), [setTransmitPower](/reference/radio/set-transmit-power), [setTransmitSerialNumber](/reference/radio/set-transmit-serial-number), [writeValueToSerial](/reference/radio/write-value-to-serial) diff --git a/docs/reference/radio/on-data-received.md b/docs/reference/radio/on-data-received.md index 8006ecc3..e4bd466d 100644 --- a/docs/reference/radio/on-data-received.md +++ b/docs/reference/radio/on-data-received.md @@ -34,5 +34,5 @@ radio.onDataReceived(() => { [send number](/reference/radio/send-number), [set group](/reference/radio/set-group) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/receive-number.md b/docs/reference/radio/receive-number.md index 61e72ee9..eded21f4 100644 --- a/docs/reference/radio/receive-number.md +++ b/docs/reference/radio/receive-number.md @@ -65,5 +65,5 @@ basic.forever(() => { [send number](/reference/radio/send-number), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/receive-string.md b/docs/reference/radio/receive-string.md index 0633fd07..0ecc24c4 100644 --- a/docs/reference/radio/receive-string.md +++ b/docs/reference/radio/receive-string.md @@ -91,5 +91,5 @@ radio.onDataReceived(() => { [send string](/reference/radio/send-string), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/received-signal-strength.md b/docs/reference/radio/received-signal-strength.md index 257fcaa0..2f70e4e4 100644 --- a/docs/reference/radio/received-signal-strength.md +++ b/docs/reference/radio/received-signal-strength.md @@ -40,5 +40,5 @@ basic.forever(() => { [receive number](/reference/radio/receive-number), [send number](/reference/radio/send-number), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/send-number.md b/docs/reference/radio/send-number.md index c97ba919..fadc539b 100644 --- a/docs/reference/radio/send-number.md +++ b/docs/reference/radio/send-number.md @@ -45,5 +45,5 @@ basic.forever(() => { [receive number](/reference/radio/receive-number), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/send-string.md b/docs/reference/radio/send-string.md index cd8576c6..2ebeef45 100644 --- a/docs/reference/radio/send-string.md +++ b/docs/reference/radio/send-string.md @@ -42,5 +42,5 @@ A radio that can both transmit and receive is called a _transceiver_. [receive string](/reference/radio/receive-string), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/send-value.md b/docs/reference/radio/send-value.md index f690f668..f8df277f 100644 --- a/docs/reference/radio/send-value.md +++ b/docs/reference/radio/send-value.md @@ -45,5 +45,5 @@ radio.onDataReceived(() => { [receive number](/reference/radio/receive-number), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/set-group.md b/docs/reference/radio/set-group.md index a088d044..17d50085 100644 --- a/docs/reference/radio/set-group.md +++ b/docs/reference/radio/set-group.md @@ -35,5 +35,5 @@ radio.setGroup(128) [receive number](/reference/radio/receive-number), [send number](/reference/radio/send-number), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/set-transmit-power.md b/docs/reference/radio/set-transmit-power.md index 64509aa3..a1fe5a47 100644 --- a/docs/reference/radio/set-transmit-power.md +++ b/docs/reference/radio/set-transmit-power.md @@ -40,5 +40,5 @@ radio.setTransmitPower(7) [receive number](/reference/radio/receive-number), [send number](/reference/radio/send-number), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/set-transmit-serial-number.md b/docs/reference/radio/set-transmit-serial-number.md index 12c9af96..bbdd7b42 100644 --- a/docs/reference/radio/set-transmit-serial-number.md +++ b/docs/reference/radio/set-transmit-serial-number.md @@ -27,5 +27,5 @@ radio.setTransmitSerialNumber(true); [receive number](/reference/radio/receive-number), [send number](/reference/radio/send-number), [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/radio/write-value-to-serial.md b/docs/reference/radio/write-value-to-serial.md index 59bb8c85..252267db 100644 --- a/docs/reference/radio/write-value-to-serial.md +++ b/docs/reference/radio/write-value-to-serial.md @@ -53,5 +53,5 @@ Sample output to serial when ``A`` button pressed: [on data received](/reference/radio/on-data-received) ```package -microbit-radio +radio ``` \ No newline at end of file diff --git a/docs/reference/toc.md b/docs/reference/toc.md index d2aac836..7df807db 100644 --- a/docs/reference/toc.md +++ b/docs/reference/toc.md @@ -22,7 +22,7 @@ change change-score-by -change-tempo +change-tempo-by change-var diff --git a/docs/reference/types/boolean.md b/docs/reference/types/boolean.md index b6a6d8e0..b538ddc9 100644 --- a/docs/reference/types/boolean.md +++ b/docs/reference/types/boolean.md @@ -13,4 +13,4 @@ false; ### See Also -[boolean (blocks)](/blocks/logic/boolean.md) +[boolean (blocks)](/blocks/logic/boolean) diff --git a/docs/share.md b/docs/share.md index d7038d9b..7dfb9a04 100644 --- a/docs/share.md +++ b/docs/share.md @@ -13,7 +13,7 @@ Once you've made your project, you can save it the cloud, share it, or embed it ## Sharing the URL -You can share the URL for the project ([https://codethemicrobit.com/httuftrbtg](https://codethemicrobit.com/httuftrbtg) above) with other people, and they will be able to visit that page to see your project, download it, or edit it: +You can share the URL for the project ([https://pxt.microbit.org/httuftrbtg](https://pxt.microbit.org/httuftrbtg) above) with other people, and they will be able to visit that page to see your project, download it, or edit it: ![Project page](/static/embed/project-page.png) @@ -36,12 +36,12 @@ Open the HTML editor for your blog or website and paste it with your content ### Wordpress -[wordpress.com][] blogs do not support embedding content from most websites, so you will need to link to your project instead. Alternatively, if you have a Wordpress VIP account you can follow [these instructions][wordpress-vip] to embed an `iframe` into your blog. The URL that you need to add is like `https://codethemicrobit.com/?sandbox=1#pub:httuftrbtg`, but replace `httuftrbtg` with your project's unique identifier. +[wordpress.com][] blogs do not support embedding content from most websites, so you will need to link to your project instead. Alternatively, if you have a Wordpress VIP account you can follow [these instructions][wordpress-vip] to embed an `iframe` into your blog. The URL that you need to add is like `https://pxt.microbit.org/?sandbox=1#pub:httuftrbtg`, but replace `httuftrbtg` with your project's unique identifier. If you self host a Wordpress blog you can install the [iframe-plugin][] and then write the following in your blog-post (again, replacing the `httuftrbtg` with your project's identifier): ``` -[iframe src="https://codethemicrobit.com/?sandbox=1#pub:httuftrbtg"] +[iframe src="https://pxt.microbit.org/?sandbox=1#pub:httuftrbtg"] ``` ### Blogger diff --git a/docs/static/icons/browserconfig.xml b/docs/static/icons/browserconfig.xml index fe44cae8..7e8a26a6 100644 --- a/docs/static/icons/browserconfig.xml +++ b/docs/static/icons/browserconfig.xml @@ -6,7 +6,11 @@ +<<<<<<< HEAD #da532c +======= + #9f00a7 +>>>>>>> microbit/master diff --git a/docs/static/icons/favicon.ico b/docs/static/icons/favicon.ico new file mode 100644 index 00000000..31a7f124 Binary files /dev/null and b/docs/static/icons/favicon.ico differ diff --git a/docs/static/logo.portrait.black.svg b/docs/static/logo.portrait.black.svg new file mode 100644 index 00000000..642175ae --- /dev/null +++ b/docs/static/logo.portrait.black.svg @@ -0,0 +1,61 @@ + +BBC micro:bitBBC micro:bit logoimage/svg+xmlimage/svg+xmlBBC micro:bit \ No newline at end of file diff --git a/docs/static/logo.portrait.white.svg b/docs/static/logo.portrait.white.svg new file mode 100644 index 00000000..d955ce94 --- /dev/null +++ b/docs/static/logo.portrait.white.svg @@ -0,0 +1,65 @@ + +BBC micro:bitBBC micro:bit logoimage/svg+xmlimage/svg+xmlBBC micro:bitLayer 1 \ No newline at end of file diff --git a/docs/static/logo.square.black.svg b/docs/static/logo.square.black.svg new file mode 100644 index 00000000..780773d9 --- /dev/null +++ b/docs/static/logo.square.black.svg @@ -0,0 +1,61 @@ + +BBC micro:bitBBC micro:bit logoimage/svg+xmlimage/svg+xmlBBC micro:bit \ No newline at end of file diff --git a/docs/static/logo.square.white.svg b/docs/static/logo.square.white.svg new file mode 100644 index 00000000..12a998bd --- /dev/null +++ b/docs/static/logo.square.white.svg @@ -0,0 +1,61 @@ + +BBC micro:bitBBC micro:bit logoimage/svg+xmlimage/svg+xmlBBC micro:bit \ No newline at end of file diff --git a/docs/static/mb/projects/magic-button-trick.png b/docs/static/mb/projects/magic-button-trick.png new file mode 100644 index 00000000..6e19d321 Binary files /dev/null and b/docs/static/mb/projects/magic-button-trick.png differ diff --git a/docs/static/mb/projects/magic-button-trick/magnets.jpg b/docs/static/mb/projects/magic-button-trick/magnets.jpg new file mode 100644 index 00000000..4b146bef Binary files /dev/null and b/docs/static/mb/projects/magic-button-trick/magnets.jpg differ diff --git a/docs/translate.md b/docs/translate.md index 5d978662..e4addbe2 100644 --- a/docs/translate.md +++ b/docs/translate.md @@ -5,13 +5,13 @@ and you can volunteer to translate parts of the web site. ## Translating the editor interface -The project below contains the resources from https://www.pxt.io and the menu items of https://codethemicrobit.com. +The project below contains the resources from https://www.pxt.io and the menu items of https://pxt.microbit.org. * [https://crowdin.com/project/kindscript](https://crowdin.com/project/kindscript) You will find two files in that project: -* ``string.json``: text contained in the menu items of https://codethemicrobit.com +* ``string.json``: text contained in the menu items of https://pxt.microbit.org * ``website.json``: text contained in the pages served by https://www.pxt.io ## Translating the blocks and reference documentation diff --git a/docs/uploader.md b/docs/uploader.md index a16595dc..7bf8d602 100644 --- a/docs/uploader.md +++ b/docs/uploader.md @@ -38,7 +38,7 @@ That's it! ### Installation Instructions -* Download the [Microsoft.Uploader.Microbit.zip](/microbit-uploader.zip) file to your local computer. +* Download the [Microsoft.Uploader.Microbit.zip](https://pxt.microbit.org/microbit-uploader.zip) file to your local computer. * Unzip the .zip file to your desktop. * Launch the Microsoft.Uploader.exe file before working on your BBC micro:bit. diff --git a/faviconDescription.json b/faviconDescription.json new file mode 100644 index 00000000..d4eb3879 --- /dev/null +++ b/faviconDescription.json @@ -0,0 +1,54 @@ +{ + "masterPicture": "docs/static/microbit.simplified.svg", + "iconsPath": "/docs/static/icons", + "design": { + "ios": { + "pictureAspect": "backgroundAndMargin", + "backgroundColor": "#ffffff", + "margin": "14%", + "assets": { + "ios6AndPriorIcons": true, + "ios7AndLaterIcons": true, + "precomposedIcons": true, + "declareOnlyDefaultIcon": true + } + }, + "desktopBrowser": {}, + "windows": { + "pictureAspect": "noChange", + "backgroundColor": "#da532c", + "onConflict": "override", + "assets": { + "windows80Ie10Tile": true, + "windows10Ie11EdgeTiles": { + "small": true, + "medium": true, + "big": true, + "rectangle": true + } + } + }, + "androidChrome": { + "pictureAspect": "noChange", + "themeColor": "#ffffff", + "manifest": { + "display": "standalone", + "orientation": "notSet", + "onConflict": "override", + "declared": true + }, + "assets": { + "legacyIcon": false, + "lowResolutionIcons": false + } + }, + "safariPinnedTab": { + "pictureAspect": "silhouette", + "themeColor": "#5bbad5" + } + }, + "settings": { + "scalingAlgorithm": "Mitchell", + "errorOnImageTooSmall": false + } +} \ No newline at end of file diff --git a/libs/bluetooth/_locales/bluetooth-jsdoc-strings.json b/libs/bluetooth/_locales/bluetooth-jsdoc-strings.json index 1c243821..ca3ba8ef 100644 --- a/libs/bluetooth/_locales/bluetooth-jsdoc-strings.json +++ b/libs/bluetooth/_locales/bluetooth-jsdoc-strings.json @@ -1,4 +1,5 @@ { + "bluetooth": "Support for additional Bluetooth services.", "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", @@ -10,6 +11,10 @@ "bluetooth.startMagnetometerService": "Starts the Bluetooth magnetometer service", "bluetooth.startTemperatureService": "Starts the Bluetooth temperature service", "bluetooth.startUartService": "Starts the Bluetooth UART service", - "bluetooth.uartRead": "Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.", - "bluetooth.uartWrite": "Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device." + "bluetooth.uartReadUntil": "Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.", + "bluetooth.uartWriteNumber": "Prints a numeric value to the serial", + "bluetooth.uartWriteString": "Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device.", + "bluetooth.uartWriteValue": "Writes a ``name: value`` pair line to the serial.", + "bluetooth.uartWriteValue|param|name": "name of the value stream, eg: x", + "bluetooth.uartWriteValue|param|value": "to write" } \ No newline at end of file diff --git a/libs/bluetooth/_locales/bluetooth-strings.json b/libs/bluetooth/_locales/bluetooth-strings.json index 0fc2a04e..ad894e0c 100644 --- a/libs/bluetooth/_locales/bluetooth-strings.json +++ b/libs/bluetooth/_locales/bluetooth-strings.json @@ -8,7 +8,10 @@ "bluetooth.startMagnetometerService|block": "bluetooth magnetometer service", "bluetooth.startTemperatureService|block": "bluetooth temperature service", "bluetooth.startUartService|block": "bluetooth uart service", - "bluetooth.uartRead|block": "bluetooth uart read %del=bluetooth_uart_delimiter_conv", - "bluetooth.uartWrite|block": "bluetooth uart write %data", - "bluetooth|block": "bluetooth" + "bluetooth.uartReadUntil|block": "bluetooth uart|read until %del=serial_delimiter_conv", + "bluetooth.uartWriteNumber|block": "bluetooth uart|write number %value", + "bluetooth.uartWriteString|block": "bluetooth uart|write string %data", + "bluetooth.uartWriteValue|block": "bluetooth uart|write value %name|= %value", + "bluetooth|block": "bluetooth", + "{id:category}Bluetooth": "Bluetooth" } \ No newline at end of file diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 98e24602..58b2fd26 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -161,6 +161,8 @@ "pins.spiWrite|param|value": "Data to be sent to the SPI slave", "serial": "Reading and writing data over a serial connection.", "serial.readLine": "Reads a line of text from the serial port.", + "serial.readUntil": "Reads a line of text from the serial port and returns the buffer when the delimiter is met.", + "serial.readUntil|param|delimiter": "text delimiter that separates each text chunk", "serial.redirect": "Dynamically configuring the serial instance to use pins other than USBTX and USBRX.", "serial.redirect|param|rx": "the new reception pin", "serial.redirect|param|tx": "the new transmission pins", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index ddd6ab34..c51caf1a 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -70,11 +70,22 @@ "pins.setPull|block": "set pull|pin %pin|to %pull", "pins.spiWrite|block": "spi write %value", "pins|block": "pins", - "serial.readLine|block": "serial read line", - "serial.redirect|block": "serial redirect to|TX %tx|RX %rx|at baud rate %rate", + "serial.readLine|block": "serial|read line", + "serial.readUntil|block": "serial|read until %delimiter=serial_delimiter_conv", + "serial.redirect|block": "serial|redirect to|TX %tx|RX %rx|at baud rate %rate", "serial.writeLine|block": "serial|write line %text", "serial.writeNumber|block": "serial|write number %value", - "serial.writeString|block": "serial write string %text", + "serial.writeString|block": "serial|write string %text", "serial.writeValue|block": "serial|write value %name|= %value", - "serial|block": "serial" + "serial|block": "serial", + "{id:category}Basic": "Basic", + "{id:category}Control": "Control", + "{id:category}Game": "Game", + "{id:category}Images": "Images", + "{id:category}Input": "Input", + "{id:category}Led": "Led", + "{id:category}Math": "Math", + "{id:category}Music": "Music", + "{id:category}Pins": "Pins", + "{id:category}Serial": "Serial" } \ No newline at end of file diff --git a/libs/core/music.ts b/libs/core/music.ts index 84b3a3f9..9c3e43fb 100644 --- a/libs/core/music.ts +++ b/libs/core/music.ts @@ -211,7 +211,7 @@ namespace music { * Change the tempo by the specified amount * @param bpm The change in beats per minute to the tempo, eg: 20 */ - //% help=music/change-tempo weight=39 + //% help=music/change-tempo-by weight=39 //% blockId=device_change_tempo block="change tempo by (bpm)|%value" blockGap=8 export function changeTempoBy(bpm: number): void { init(); diff --git a/libs/devices/_locales/devices-strings.json b/libs/devices/_locales/devices-strings.json index de547f3a..8b24b7aa 100644 --- a/libs/devices/_locales/devices-strings.json +++ b/libs/devices/_locales/devices-strings.json @@ -6,5 +6,6 @@ "devices.signalStrength|block": "signal strength", "devices.tellCameraTo|block": "tell camera to|%property", "devices.tellRemoteControlTo|block": "tell remote control to|%property", - "devices|block": "devices" + "devices|block": "devices", + "{id:category}Devices": "Devices" } \ No newline at end of file diff --git a/libs/radio/_locales/radio-jsdoc-strings.json b/libs/radio/_locales/radio-jsdoc-strings.json index 808dd5cc..9b04a86b 100644 --- a/libs/radio/_locales/radio-jsdoc-strings.json +++ b/libs/radio/_locales/radio-jsdoc-strings.json @@ -15,5 +15,6 @@ "radio.setTransmitPower": "Change the output power level of the transmitter to the given value.", "radio.setTransmitPower|param|power": "a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7", "radio.setTransmitSerialNumber": "Set the radio to transmit the serial number in each message.", + "radio.setTransmitSerialNumber|param|transmit": "value indicating if the serial number is transmitted, eg: true", "radio.writeValueToSerial": "Reads a value sent with `stream value` and writes it\nto the serial stream as JSON" } \ No newline at end of file diff --git a/libs/radio/_locales/radio-strings.json b/libs/radio/_locales/radio-strings.json index f0385d86..1364cff0 100644 --- a/libs/radio/_locales/radio-strings.json +++ b/libs/radio/_locales/radio-strings.json @@ -2,7 +2,6 @@ "radio.onDataReceived|block": "radio on data received", "radio.receiveNumber|block": "radio receive number", "radio.receiveString|block": "radio receive string", - "radio.receivedNumberAt|block": "radio receive number|at %VALUE", "radio.receivedSignalStrength|block": "radio received signal strength", "radio.sendNumber|block": "radio send number %value", "radio.sendString|block": "radio send string %msg", @@ -11,5 +10,6 @@ "radio.setTransmitPower|block": "radio set transmit power %power", "radio.setTransmitSerialNumber|block": "radio set transmit serial number %transmit", "radio.writeValueToSerial|block": "radio write value to serial", - "radio|block": "radio" + "radio|block": "radio", + "{id:category}Radio": "Radio" } \ No newline at end of file diff --git a/pxtarget.json b/pxtarget.json index d645475e..1acb4f89 100644 --- a/pxtarget.json +++ b/pxtarget.json @@ -80,12 +80,12 @@ "microbit-pins": "", "microbit-serial": "" } - }, + }, { "type": "api", "map": { - "bluetooth\\.uartRead\\((.*?)\\)" : "bluetooth.uartReadUntil($1)", - "bluetooth\\.uartWrite\\((.*?)\\)" : "bluetooth.uartWriteUntil($1)" + "bluetooth\\.uartRead\\((.*?)\\)": "bluetooth.uartReadUntil($1)", + "bluetooth\\.uartWrite\\((.*?)\\)": "bluetooth.uartWriteUntil($1)" } } ] @@ -286,7 +286,7 @@ "name": "Hardware", "path": "/device" } - ], + ], "sideDoc": "getting-started", "usbDocs": "/device/usb", "usbHelp": [ diff --git a/tests/wg-canoe-polo-timer.ts b/tests/wg-canoe-polo-timer.ts new file mode 100644 index 00000000..3960be0b --- /dev/null +++ b/tests/wg-canoe-polo-timer.ts @@ -0,0 +1,222 @@ +let AWasPressed: boolean +let BWasPressed: boolean +let ABWasPressed: boolean +let wasShake: boolean +let scoreA: number +let scoreB: number + +scoreA = 0 +scoreB = 0 +startIOMonitor() +let gameTime = getGameTime() +basic.showLeds(` + . . # . . + . . # . . + . . # # # + . . . . . + . . . . . + `) +while (!BWasPressed) { + basic.pause(100) +} +BWasPressed = false +playOneGame(gameTime) +showFinalScores(scoreA, scoreB) + +function startIOMonitor() { + input.onButtonPressed(Button.A, () => { + AWasPressed = true + }) + input.onButtonPressed(Button.B, () => { + BWasPressed = true + }) + input.onButtonPressed(Button.AB, () => { + ABWasPressed = true + AWasPressed = false + BWasPressed = false + }) + input.onShake(() => { + wasShake = true + }) + AWasPressed = false + BWasPressed = false + ABWasPressed = false + wasShake = false +} + +/** + * display score for A and B on same screen as a graphic + * this shows a tug of war line, in the middle if scores the same, + * Can cope with differences +/-10 + * @param scoreA1 TODO + * @param scoreB1 TODO + */ +function showScore(scoreA1: number, scoreB1: number) { + let img = images.createImage(` + # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # + # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # + # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # + # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # + # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # + `) + let diff = Math.clamp(-10, 10, scoreB1 - scoreA1) + diff = diff + 10 + img.plotFrame(diff) +} + +/** + * show digits 0..10 + * @param digits TODO + */ +function showDigits(digits: number) { + digits = Math.clamp(0, 10, digits) + let img = images.createImage(` + . . # . . . . # . . . # # . . . # # . . . # . . . . # # # . . . # # . . # # # . . . # . . . . # . . # . . # . + . # . # . . # # . . . . . # . . . . # . . # . . . . # . . . . # . . . . . . # . . # . # . . # . # . # . # . # + . # . # . . . # . . . . # . . . . # . . . # # # . . . # # . . # # . . . . # . . . . # . . . . # # . # . # . # + . # . # . . . # . . . # . . . . . . # . . . # . . . . . # . . # . # . . # . . . . # . # . . . . # . # . # . # + . . # . . . # # # . . # # # . . # # . . . . # . . . # # . . . . # . . . # . . . . . # . . . # # . . # . . # . + `) + img.plotFrame(digits) +} + +/** + * show time graphic for time remaining + * @param gameTime TODO + */ +function showTime(gameTime: number) { + let minutes = Math.clamp(0, 10, gameTime / 60) + let seconds = gameTime % 60 + // divide seconds into 10 second stripes + let stripes = seconds / 10 + let img = images.createImage(` + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # + . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # + `) + img.plotFrame(stripes) + // leave middle row blank + // display up to 10 dots in raster on top two rows + if (minutes > 0) { + for (let i = 0; i < minutes; i++) { + let y = i / 5 + let x = i % 5 + led.plot(x, y) + } + } +} + +function getGameTime(): number { + let chosenGameTime = 7 + showDigits(chosenGameTime) + while (!BWasPressed) { + if (AWasPressed) { + if (chosenGameTime < 10) { + chosenGameTime = chosenGameTime + 1 + } else { + chosenGameTime = 1 + } + showDigits(chosenGameTime) + AWasPressed = false + } else { + basic.pause(100) + } + } + BWasPressed = false + return chosenGameTime +} + +function playOneGame(gameTime: number) { + let gameStartTime = input.runningTime() + let gameElapsedTime = 0 + let gameTimeRemaining = gameTime * 60 + let timeout = 0 + let lastDisplayedTime = 0 + showScore(scoreA, scoreB) + let state = "TIME" + while (gameTimeRemaining >= 0) { + // Tick the game time + gameElapsedTime = (input.runningTime() - gameStartTime) / 1000 + gameTimeRemaining = gameTime * 60 - gameElapsedTime + // Handle any global events such as point buttons + if (AWasPressed) { + AWasPressed = false + scoreA = scoreA + 1 + if (state != "LAST10") { + showScore(scoreA, scoreB) + state = "SCORE" + } + } else if (BWasPressed) { + BWasPressed = false + scoreB = scoreB + 1 + if (state != "LAST10") { + showScore(scoreA, scoreB) + state = "SCORE" + } + } + // Handle global transitions + if (gameTimeRemaining <= 10 && state != "LAST10") { + state = "LAST10" + } + // Handle game states + if (state == "SCORE") { + if (wasShake) { + wasShake = false + showTime(gameTimeRemaining) + lastDisplayedTime = gameTimeRemaining + timeout = input.runningTime() + 5 * 1000 + state = "TIME" + } + } else if (state == "TIME") { + if (input.runningTime() > timeout) { + showScore(scoreA, scoreB) + state = "SCORE" + } + } else if (state == "LAST10") { + if (gameTimeRemaining != lastDisplayedTime) { + showDigits(gameTimeRemaining) + lastDisplayedTime = gameTimeRemaining + } + } + basic.pause(100) + } +} + +function showFinalScores(scoreA1: number, scoreB1: number) { + basic.showLeds(` + # . . . # + . # . # . + . . # . . + . # . # . + # . . . # + `) + while (true) { + if (AWasPressed) { + basic.showString("A", 150) + basic.showNumber(scoreA1, 150) + basic.showLeds(` + # . . . # + . # . # . + . . # . . + . # . # . + # . . . # + `) + AWasPressed = false + } else if (BWasPressed) { + basic.showString("B", 150) + basic.showNumber(scoreB1, 150) + basic.showLeds(` + # . . . # + . # . # . + . . # . . + . # . # . + # . . . # + `) + BWasPressed = false + } else { + basic.pause(100) + } + } +} diff --git a/tests/wg-catching-raindrops.ts b/tests/wg-catching-raindrops.ts new file mode 100644 index 00000000..937abf67 --- /dev/null +++ b/tests/wg-catching-raindrops.ts @@ -0,0 +1,248 @@ +let speed: number +let cupCapacity: number +let maxMisses: number +let autoEmpty: boolean +let movement: boolean +let sensitivity: number +let cupX: number +let cupInverted: boolean + +let highscore = 0 +while (true) { + // configure game settings + // ##CHALLENGE1: reconfigure game + cupCapacity = 5 + speed = 6 + maxMisses = 3 + autoEmpty = false + movement = true + sensitivity = 400 + cupX = 2 + // show the spash screen + // ##CHALLENGE 2: CHANGE SPLASH SCREEN + basic.showAnimation(` + . . . . . . . . . . + . . . . . . # . # . + . . . . . . . . . . + . # . # . . # . # . + . # # # . . # # # . + `, 400) + // Decide what to do based on which button is pressed + if (input.buttonIsPressed(Button.A)) { + let finalScore = playGame() + // ##CHALLENGE 3 ADD HIGH SCORE + if (finalScore > highscore) { + basic.showString("HIGH", 150) + highscore = finalScore + } + basic.showNumber(finalScore, 150) + } else if (input.buttonIsPressed(Button.B)) { + testMovement() + } else { + basic.pause(100) + } +} + +function playGame(): number { + let cup = images.createImage(` + . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . + . . . . . . # . # . . . . . . + . . . . . . # # # . . . . . . + `) + let score = 0 + let dropsInCup = 0 + let misses = 0 + let dropX = 0 + let dropY = 0 + let prevDropY = -1 + let cupX1 = 2 + let prevCupX = -1 + let state = "NEWDROP" + startGame() + while (true) { + if (state == "NEWDROP") { + // create a new drop at a random position + dropX = Math.random(5) + dropY = 0 + state = "RAINING" + } else if (state == "RAINING") { + // calculate new positions + cupX1 = getCupPosition() + let thisDropY = dropY / speed + // Only redraw the screen if something has changed (prevent flashing) + if (cupX1 != prevCupX || thisDropY != prevDropY) { + basic.clearScreen() + // draw cup + cup.showImage(7 - cupX1) + if (dropsInCup == cupCapacity) { + // a full cup + led.plot(cupX1, 3) + } + // draw drop + led.plot(dropX, thisDropY) + prevCupX = cupX1 + prevDropY = thisDropY + } + basic.pause(100) + if (thisDropY >= 4) { + state = "ATCUP" + } else { + dropY = dropY + 1 + } + if (cupInverted && dropsInCup >= cupCapacity) { + state = "EMPTYING" + } + } else if (state == "ATCUP") { + if (dropX == cupX1) { + state = "CATCH" + } else { + state = "MISS" + } + } else if (state == "MISS") { + // ##CHALLENGE: long beep on miss + beep(500) + misses = misses + 1 + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . + . . . . . . # . # . . . . . . . . . . . + . . . . . . # # # . . # . # . . . . . . + . # . # . . . . . . . # # # . . # . # . + . # # # . . . # . . . . . . . . # # # . + `, 400) + if (misses > maxMisses) { + state = "GAMEOVER" + } else { + state = "NEWDROP" + } + } else if (state == "CATCH") { + // ##CHALLENGE: short beep on catch + beep(200) + dropsInCup = dropsInCup + 1 + basic.showAnimation(` + . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . + . # # # . # . # . # . # . # . + . # # # . # # # # # . # # # . + `, 400) + if (dropsInCup == cupCapacity) { + state = "FULL" + score = score + 1 + } else if (dropsInCup > cupCapacity) { + state = "OVERFLOW" + } else { + score = score + 1 + state = "NEWDROP" + } + } else if (state == "FULL") { + basic.showAnimation(` + . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . + . . . . . . # # # . . . . . . + . # # # . . # # # . . # # # . + . # # # . . # # # . . # # # . + `, 400) + if (autoEmpty) { + state = "EMPTYING" + } else { + state = "NEWDROP" + } + } else if (state == "EMPTYING") { + if (cupInverted) { + basic.showAnimation(` + . . . . . . . . . . . . . . . . . # . . . . . . . + . . . . . . . . . . . . # . . . . . . . . . . . . + . . . . . . . # . . . . . . . . . . . . . . . . . + . # # # . . # . # . . # . # . . # . # . . # . # . + . # # # . . # # # . . # # # . . # # # . . # # # . + `, 400) + } else { + basic.showAnimation(` + . . . . . . . . . . . # # # . . # # # . . # # # . . # # # . . # # # . . . . . . . . . . . + . . . . . . # # . . . # # # . . # . # . . # . # . . # . # . . # . # . . # # . . . . . . . + . . . . . . # # . . . . . . . . . # . . . . . . . . . . . . . . . . . . # . . . . . . . . + . # # # . . # # . . . . . . . . . . . . . . # . . . . . . . . . . . . . # # . . . # . # . + . # # # . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . # # # . + `, 400) + } + dropsInCup = 0 + // ##CHALLENGE: Speed up on every level change + if (speed > 1) { + speed = speed - 1 + } + state = "NEWDROP" + } else if (state == "OVERFLOW") { + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . # # # . . # . # . . . . . . . . . . . . . . . . + . # # # . . # # # . # # # # # # # # # # . # # # . . # # # . + . # # # . . # # # . . # # # . . # # # . # # # # # . # # # . + `, 400) + state = "GAMEOVER" + } else if (state == "GAMEOVER") { + // ##CHALLENGE: Make a sound on game over + beep(700) + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . # # # # # . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . # # # # # . # . # . . . . . . . . . . . . # . # . . . . . . + . . . . . . . . . . . . . . . . . . . . . # # # . # # # # # . # . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . # . # . . . . . . . # # # . # # # # # . # . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . # # # . # # # # # . # . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + `, 400) + break + } + } + return score +} + +function testMovement() { + while (!input.buttonIsPressed(Button.A)) { + // ##CHALLENGE 5: Add accelerometer test mode + let x = getCupPosition() + basic.clearScreen() + led.plot(x, 2) + basic.pause(200) + } +} + +function getCupPosition(): number { + if (movement) { + let acc = input.acceleration(Dimension.X) / sensitivity + cupX = Math.clamp(0, 4, acc + 2) + return cupX + } + if (input.buttonIsPressed(Button.A)) { + if (cupX > 0) { + cupX = cupX - 1 + } + } else if (input.buttonIsPressed(Button.B)) { + if (cupX < 4) { + cupX = cupX + 1 + } + } + return cupX +} + +function startGame() { + basic.clearScreen() + // If button still held from start-game, wait until it is released + while (input.buttonIsPressed(Button.A)) { + // wait for button to be released + } + // handlers that work out if cup is turned upside down or not + input.onLogoDown(() => { + cupInverted = true + }) + input.onLogoUp(() => { + cupInverted = false + }) +} + +function beep(p: number) { + pins.digitalWritePin(DigitalPin.P0, 1) + basic.pause(p) + pins.digitalWritePin(DigitalPin.P0, 0) +} diff --git a/tests/wg-dr-who.ts b/tests/wg-dr-who.ts new file mode 100644 index 00000000..39dca079 --- /dev/null +++ b/tests/wg-dr-who.ts @@ -0,0 +1,716 @@ +let AWasPressed: boolean +let BWasPressed: boolean +let ABWasPressed: boolean +let wasShake: boolean + +startIOMonitor() +let gameNo = 0 +while (true) { + // select a new game + if (AWasPressed) { + gameNo = (gameNo + 1) % 4 + AWasPressed = false + } + // show selected game + if (gameNo == 0) { + basic.showLeds(` + # # # # # + # . . . # + . # . # . + . . . . . + . # # # . + `) + } else if (gameNo == 1) { + basic.showLeds(` + # # # . . + # . . . . + # # # # # + # # . . . + # # # . . + `) + } else if (gameNo == 2) { + basic.showLeds(` + . . . . . + # . . . . + # # # # # + # . . . . + . . . . . + `) + } else if (gameNo == 3) { + basic.showLeds(` + # . # # # + # # # # # + . . . # # + # # # # # + # # # # # + `) + } + // start selected game + if (BWasPressed) { + // Play the selected game + basic.clearScreen() + waitBReleased() + resetButtons() + let finalScore = 0 + basic.clearScreen() + if (gameNo == 0) { + finalScore = playCybermen() + } else if (gameNo == 1) { + finalScore = playDalek() + } else if (gameNo == 2) { + finalScore = playSonicScrewdriver() + } else if (gameNo == 3) { + finalScore = playJudoonLanguage() + } + flashDigit(finalScore, 3) + resetButtons() + waitBPressed() + basic.clearScreen() + waitBReleased() + resetButtons() + } else { + basic.pause(100) + } +} + +/** + * Game parameters + * Percentage chance that cyberman will move left/right to line up with you + */ +function playCybermen(): number { + let maxGameTime = 60 + let cybermanMoveXProbability = 20 + // How long (in 100ms ticks) cyberman must line up before moving forward + let cybermanMoveYCount = 10 + // Game variables + let startTime = input.runningTime() + let gameTime = 0 + let playerX = 2 + let cybermanX = 1 + let cybermanY = 0 + let cybermanLineupCount = 0 + let redraw = true + while (gameTime < maxGameTime) { + if (redraw) { + basic.clearScreen() + led.plot(playerX, 4) + led.plot(cybermanX, cybermanY) + redraw = false + } + // Handle Player Movement + if (AWasPressed) { + if (playerX > 0) { + playerX = playerX - 1 + redraw = true + } + AWasPressed = false + } else if (BWasPressed) { + if (playerX < 4) { + playerX = playerX + 1 + redraw = true + } + BWasPressed = false + } + // Handle Cyberman line-of-sight checking + if (cybermanX == playerX) { + cybermanLineupCount = cybermanLineupCount + 1 + if (cybermanLineupCount >= cybermanMoveYCount) { + if (cybermanY == 4) { + // Cyberman caught you, game over + break + } else { + cybermanY = cybermanY + 1 + redraw = true + cybermanLineupCount = 0 + } + } + } else { + cybermanLineupCount = 0 + // Move Cyberman closer to player, slowly + if (Math.random(100) < cybermanMoveXProbability) { + if (cybermanX > playerX) { + cybermanX = cybermanX - 1 + } else if (cybermanX < playerX) { + cybermanX = cybermanX + 1 + } + redraw = true + } + } + basic.pause(100) + gameTime = (input.runningTime() - startTime) / 1000 + } + return convertSurvivalTimeToScore(gameTime) +} + +/** + * Game parameters, all probabilities as a percentage + */ +function playDalek(): number { + let maxGameTime = 60 + let userMoveSensitivity = 40 + let dalekMoveSensitivity = 20 + let dalekShootChance = 10 + let dalekHitChance = 10 + // Game variables + let gameTime = 0 + let startTime = input.runningTime() + let dalekY = 2 + let userY = 1 + let redraw = true + while (gameTime < maxGameTime) { + // Redraw screen if necessary + if (redraw) { + basic.clearScreen() + led.plot(0, dalekY) + led.plot(4, userY) + redraw = false + } + // Work out if the user has moved, and move them + let tilt = getTilt() + if (tilt > 2) { + // Moving up, slowly + if (userY < 4) { + if (Math.random(100) < userMoveSensitivity) { + userY = userY + 1 + redraw = true + } + } + } else if (tilt < 2) { + // Moving down (slowly) + if (userY > 0) { + if (Math.random(100) < userMoveSensitivity) { + userY = userY - 1 + redraw = true + } + } + } + // Move the Dalek to line up with user + if (dalekY < userY) { + if (Math.random(100) < dalekMoveSensitivity) { + dalekY = dalekY + 1 + redraw = true + } + } else if (dalekY > userY) { + if (Math.random(100) < dalekMoveSensitivity) { + dalekY = dalekY - 1 + redraw = true + } + } else { + // Dalek lines up + if (Math.random(100) < dalekShootChance) { + // Shoot a raygun at the user + for (let i = 0; i < 3; i++) { + led.plot(i + 1, dalekY) + basic.pause(100) + } + if (Math.random(100) < dalekHitChance) { + // User has been hit, game over + break + } + redraw = true + } + } + gameTime = (input.runningTime() - startTime) / 1000 + basic.pause(100) + } + return convertSurvivalTimeToScore(gameTime) +} + +/** + * Set this in steps of 60 + */ +function playSonicScrewdriver(): number { + let maxGameTime = 120 + let gameTime = 0 + // @=0, A=1 etc + // bit0=N, bit1=E, bit2=S, bit3=W + // bit=0 means it is a wall (can not be opened) + // bit=1 means it is a door (can be opened) + let mazestr = "BLFL@GOIFIGLCJIA" + let maze = ([] as number[]) + // Locks use same number encoding (bits 0,1,2,3) + // bit=0 means door is locked (cannot be walked through) + // bit=1 means door is open (can be walked through) + let doorOpen = ([] as number[]) + for (let i = 0; i < 16; i++) { + doorOpen.push(0) + maze.push(mazestr.charCodeAt(i) - 64) + } + let redraw = true + let cellno = 0 + let direction = "N" + let startTime = input.runningTime() + while (gameTime < maxGameTime) { + // Draw the screen + if (redraw) { + basic.clearScreen() + // Always draw the maze with N at the top + drawMazeCell(doorOpen[cellno]) + // draw user standing next to selected wall + if (direction == "N") { + led.plot(2, 1) + } else if (direction == "E") { + led.plot(3, 2) + } else if (direction == "S") { + led.plot(2, 3) + } else if (direction == "W") { + led.plot(1, 2) + } + redraw = false + } + // Sense any button presses + if (AWasPressed) { + if (direction == "N") { + direction = "E" + } else if (direction == "E") { + direction = "S" + } else if (direction == "S") { + direction = "W" + } else if (direction == "W") { + direction = "N" + } + redraw = true + AWasPressed = false + } else if (BWasPressed) { + // Try to walk through an open door + if (isDoorOpen(doorOpen[cellno], direction)) { + cellno = mazeForward(cellno, 4, 4, direction) + redraw = true + } + BWasPressed = false + } else if (wasShake) { + // energise sonic screwdriver + if (isDoorOpen(maze[cellno], direction)) { + // It is a door, but is the door open or closed? + if (!(isDoorOpen(doorOpen[cellno], direction))) { + // Open the door in front of us + doorOpen[cellno] = openDoor(doorOpen[cellno], direction) + // Also open the return door for when we walk through this door + let forwardCellno = mazeForward(cellno, 4, 4, direction) + doorOpen[forwardCellno] = openDoor(doorOpen[forwardCellno], opposite(direction)) + } + } else { + // Not a door + basic.showLeds(` + . . . . . + . # . # . + . . # . . + . # . # . + . . . . . + `) + basic.pause(500) + } + redraw = true + wasShake = false + } + if (cellno == 15) { + // Have reached the exit cell + break + } + basic.pause(100) + gameTime = (input.runningTime() - startTime) / 1000 + } + return convertPenaltyTimeToScore(gameTime / maxGameTime / 60) +} + +function playJudoonLanguage(): number { + let maxGameTime = 60 + let gameTime = 0 + let startTime = input.runningTime() + let font = images.createImage(` + # . # # # # . # . # . . . . # # # . . . # # # # # # . # . # # # # . . . . . # # # . . . # # # # # # + # # # # # # # # # # . . . # # . # # # # . # . . . # # # # # # # # # # # # # # . # # # # # . . # . . + . . . . # # # # . . . . # # # . . . . # . # . . . . . . . # . . . # # . . # # # . . # . . # # # # # + # # # # # # # # # # . . # . . # # # # # # # # # # # # # # # # # # # . # # # # # # # # # # # # # . . + # # # # # # # # # # # # # # # # . . . . # . . . # # . . . . . . . # # # # # . . # # # # # # # # # # + `) + let answers = images.createImage(` + # # # # # # # # . . . # # # . . . # . . # . # . # + # . . . # # . . . . # # # # # . . . . . . . . . . + . # . # . # # # # . # . # . # . # . # . # . # . # + . . . . . # # # . . # . # . # . . . . . . . . . . + . # # # . # # # . . # . # . # # # # # # # . . . # + `) + let pages = "029 041 167 208 283" + let actualAnswer = Math.random(5) + let pos = 0 + let redraw = true + while (gameTime < maxGameTime) { + // Draw the current frame from pos (0,1,2 codeword, 3,4,5,6,7 answers) + if (redraw) { + if (pos <= 2) { + // Draw codeword symbol for this choice and this position + let digit = parseInt(pages[actualAnswer * 4 + pos]) + font.plotFrame(digit) + } else { + // Draw answer + let item = pos - 3 + answers.plotFrame(item) + } + redraw = false + } + // Process button presses + if (AWasPressed) { + // Move left, unless at far left already + AWasPressed = false + if (pos > 0) { + pos = pos - 1 + redraw = true + } + } else if (BWasPressed) { + // Move right, unless already at far right + BWasPressed = false + if (pos < 7) { + pos = pos + 1 + redraw = true + } + } else if (wasShake) { + // User trying to select an answer, are we at an answer position? + wasShake = false + if (pos >= 3) { + // Is it the right answer? + let userChoice = pos - 3 + if (userChoice == actualAnswer) { + // CORRECT + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . # + . . . . . . . . . . . . . . . . . . # . . . . # . + # . . . . # . . . . # . # . . # . # . . # . # . . + . . . . . . # . . . . # . . . . # . . . . # . . . + `, 400) + basic.pause(1000) + break + } else { + // WRONG + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . . . # # . . . # # . . . # # . . . # # . . . # + . . . . . . . . . . . . . . . . . . # . . . . # . . . . # . . # . # . . # . # . . # . # . + . . . . . . . . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . + . . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . # . . # . # . + # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . # + `, 400) + basic.pause(1000) + redraw = true + } + } + } + gameTime = (input.runningTime() - startTime) / 1000 + basic.pause(100) + } + return convertPenaltyTimeToScore(gameTime) +} + +function getDirection(): string { + let bearing = input.compassHeading() + if (bearing < 45 || bearing > 315) { + return "N" + } else if (bearing < 135) { + return "E" + } else if (bearing < 225) { + return "S" + } else { + return "W" + } +} + +function calibrateCompass() { + if (input.compassHeading() == -4) { + input.calibrate() + } +} + +function waitBReleased() { + while (input.buttonIsPressed(Button.B)) { + basic.pause(100) + } +} + +function waitBPressed() { + while (!input.buttonIsPressed(Button.B)) { + basic.pause(100) + } +} + +/** + * Show the score 0..9 + * @param digit TODO + * @param times TODO + */ +function flashDigit(digit: number, times: number) { + digit = Math.clamp(0, 9, digit) + for (let i = 0; i < times; i++) { + basic.showNumber(digit, 0) + basic.pause(500) + basic.clearScreen() + basic.pause(500) + } + basic.showNumber(digit, 0) +} + +/** + * score is calculated as the amount of time you lasted + * @param gameTime TODO + */ +function convertSurvivalTimeToScore(gameTime: number): number { + if (gameTime <= 4) { + return 0 + } else if (gameTime <= 9) { + return 1 + } else if (gameTime <= 14) { + return 2 + } else if (gameTime <= 19) { + return 3 + } else if (gameTime <= 24) { + return 4 + } else if (gameTime <= 29) { + return 5 + } else if (gameTime <= 39) { + return 6 + } else if (gameTime <= 49) { + return 7 + } else if (gameTime <= 59) { + return 8 + } else { + return 9 + } +} + +function convertPenaltyTimeToScore(penaltyTime: number): number { + if (penaltyTime <= 4) { + return 9 + } else if (penaltyTime <= 9) { + return 8 + } else if (penaltyTime <= 14) { + return 7 + } else if (penaltyTime <= 19) { + return 6 + } else if (penaltyTime <= 24) { + return 5 + } else if (penaltyTime <= 29) { + return 4 + } else if (penaltyTime <= 39) { + return 3 + } else if (penaltyTime <= 49) { + return 2 + } else if (penaltyTime <= 59) { + return 1 + } else { + return 0 + } +} + +function startIOMonitor() { + input.onButtonPressed(Button.A, () => { + AWasPressed = true + }) + input.onButtonPressed(Button.B, () => { + BWasPressed = true + }) + input.onButtonPressed(Button.AB, () => { + ABWasPressed = true + }) + input.onShake(() => { + wasShake = true + }) + AWasPressed = false + BWasPressed = false + ABWasPressed = false + wasShake = false +} + +/** + * maze is always drawn with north at top + * @param cell TODO + */ +function drawMazeCell(cell: number) { + let n = !(isNorth(cell)) + let e = !(isEast(cell)) + let s = !(isSouth(cell)) + let w = !(isWest(cell)) + // Draw any visible walls + if (n) { + for (let i = 0; i < 5; i++) { + led.plot(i, 0) + } + } + if (e) { + for (let l = 0; l < 5; l++) { + led.plot(4, l) + } + } + if (s) { + for (let k = 0; k < 5; k++) { + led.plot(k, 4) + } + } + if (w) { + for (let j = 0; j < 5; j++) { + led.plot(0, j) + } + } +} + +/** + * work out the cell number in front of this cell + * given the direction N E S W (N points to button B) + * returns the forward cell number, -1 if outside of maze + * Turn cellno into an x and y based on width and height + * @param cellno TODO + * @param width TODO + * @param height TODO + * @param direction TODO + */ +function mazeForward(cellno: number, width: number, height: number, direction: string): number { + let y = cellno / width + let x = cellno % width + // Work out change in x/y and therefore change in cellno + // But bounds-check against width and height + // as user cannot walk outside of the maze + if (direction == "N") { + // sub 1 from y + if (y > 0) { + return cellno - width + } + } else if (direction == "E") { + // Add 1 to x + if (x < width - 1) { + return cellno + 1 + } + } else if (direction == "S") { + // add 1 to y + if (y < height - 1) { + return cellno + width + } + } else if (direction == "W") { + // sub 1 from x + if (x > 0) { + return cellno - 1 + } + } + // Not allowed to move in this direction, it will go outside of maze + return - 1 +} + +/** + * A door is open if the lock bit is 1 + * A door is present if the maze bit is 1 + * @param cell TODO + * @param direction TODO + */ +function isDoorOpen(cell: number, direction: string): boolean { + if (direction == "N") { + return isNorth(cell) + } else if (direction == "E") { + return isEast(cell) + } + if (direction == "S") { + return isSouth(cell) + } else if (direction == "W") { + return isWest(cell) + } + return false +} + +function getTilt(): number { + let tilt: number + tilt = input.acceleration(Dimension.Y) + tilt = Math.clamp(-1024, 1023, tilt) + tilt = (tilt + 1024) / 512 + return tilt +} + +function waitAReleased() { + while (input.buttonIsPressed(Button.A)) { + basic.pause(100) + } +} + +function waitNoButtons() { + while (input.buttonIsPressed(Button.A) || input.buttonIsPressed(Button.B) || input.buttonIsPressed(Button.AB)) { + basic.pause(100) + } +} + +function resetButtons() { + AWasPressed = false + BWasPressed = false + ABWasPressed = false +} + +/** + * The appropriate bit (0,1,2,3) is set, which unlocks the door + * @param cell TODO + * @param direction TODO + */ +function openDoor(cell: number, direction: string): number { + if (direction == "N") { + return cell | 1 + } else if (direction == "E") { + return cell | 2 + } else if (direction == "S") { + return cell | 4 + } else if (direction == "W") { + return cell | 8 + } + return cell +} + +/** + * is the north bit set in the cell? + * @param cell TODO + */ +function isNorth(cell: number): boolean { + if ((cell & 1) != 0) { + return true + } + return false +} + +/** + * is the east bit set in the cell? + * @param cell TODO + */ +function isEast(cell: number): boolean { + if ((cell & 2) != 0) { + return true + } + return false +} + +/** + * is the south bit set in the cell? + * @param cell TODO + */ +function isSouth(cell: number): boolean { + if ((cell & 4) != 0) { + return true + } + return false +} + +/** + * is the west bit set in the cell? + * @param cell TODO + */ +function isWest(cell: number): boolean { + if ((cell & 8) != 0) { + return true + } + return false +} + +function opposite(direction: string): string { + if (direction == "N") { + return "S" + } else if (direction == "E") { + return "W" + } else if (direction == "S") { + return "N" + } else if (direction == "W") { + return "E" + } + return direction +} + +function isSount() { } diff --git a/tests/wg-flood-monitor.ts b/tests/wg-flood-monitor.ts new file mode 100644 index 00000000..bf152d3a --- /dev/null +++ b/tests/wg-flood-monitor.ts @@ -0,0 +1,165 @@ +let sensorType: string + +// ANALOG or TILT +sensorType = "TILT" +while (true) { + // splash screen (flood monitor) + basic.showLeds(` + # # # . . + # . . . . + # # . # . + # . . # . + # . . # # + `) + while (true) { + if (input.buttonIsPressed(Button.A)) { + // test that the sensor works + testMode() + break + } else if (input.buttonIsPressed(Button.B)) { + // run the real flood monitor + floodMonitor() + break + } else { + basic.pause(100) + } + } +} + +/** + * test mode - test that the monitor and buzzer work + * no filtering in this mode, direct screen update + */ +function testMode() { + basic.showLeds(` + # # # # # + . . # . . + . . # . . + . . # . . + . . # . . + `) + waitNoButtons() + let img = images.createImage(` + . . . . . . . . . . . . . . . . . . . . # # # # # + . . . . . . . . . . . . . . . # # # # # . . . . . + . . . . . . . . . . # # # # # . . . . . . . . . . + . . . . . # # # # # . . . . . . . . . . . . . . . + # # # # # . . . . . . . . . . . . . . . . . . . . + `) + while (!input.buttonIsPressed(Button.A)) { + // Show live reading on display + let value = readSensor() + img.showImage(value * 5) + // Turn beeper on only if maximum value seen + if (value >= 4) { + pins.digitalWritePin(DigitalPin.P1, 1) + } else { + pins.digitalWritePin(DigitalPin.P1, 0) + } + basic.pause(50) + } + waitNoButtons() +} + +function floodMonitor() { + basic.showLeds(` + # . . . # + # # . # # + # . # . # + # . . . # + # . . . # + `) + waitNoButtons() + let line = images.createImage(` + . . . . . . . . . . . . . . . . . . . . # # # # # + . . . . . . . . . . . . . . . # # # # # . . . . . + . . . . . . . . . . # # # # # . . . . . . . . . . + . . . . . # # # # # . . . . . . . . . . . . . . . + # # # # # . . . . . . . . . . . . . . . . . . . . + `) + let state = "SAFE" + let averagedValue = 0 + while (!input.buttonIsPressed(Button.A)) { + let value = readSensor() + // Apply some 'lag' filtering to the value, so that 'bobbing' doesn't set off alarm + // i.e. to go from 0 to 4 takes 4 times round the loop + if (value > averagedValue) { + // On the way up, changes in reading are slowed down + averagedValue = averagedValue + 1 + } else if (value < averagedValue) { + // On the way down, changes in reading happen immediately + averagedValue = value + } + // Work out what to do based on the averaged value (non bobbing value) + if (state == "SAFE") { + if (averagedValue >= 4) { + pins.digitalWritePin(DigitalPin.P1, 1) + state = "ALARMING" + } else { + // Display raw value as a line + line.showImage(value * 5) + // fill in based on averaged value (long term reading) + for (let i = 0; i < averagedValue; i++) { + led.plot(2, 4 - i) + } + } + } else if (state == "ALARMING") { + if (input.buttonIsPressed(Button.B)) { + pins.digitalWritePin(DigitalPin.P1, 0) + state = "SAFE" + } else { + basic.showAnimation(` + # # # # # . . . . . + # # # # # . . . . . + # # # # # . . . . . + # # # # # . . . . . + # # # # # . . . . . + `, 400) + } + } + basic.pause(300) + } + waitNoButtons() +} + +/** + * Read a value 0,1,2,3,4 from either ANALOG or TILT + */ +function readSensor(): number { + let value = 0 + // Produce a sensor value in range 0..1023 + if (sensorType == "ANALOG") { + // Input range is 0..1023 + value = pins.analogReadPin(AnalogPin.P0) + } else if (sensorType == "TILT") { + // Input range is -1024 (pads highest)..1023 (pads lowest) + value = input.acceleration(Dimension.Y) + // Emulator sometimes returns out of range values, so clamp to expected range + value = Math.clamp(-1024, 1023, value) + // Convert to an entirely positive range from 0 pads full up to 2047 pads full down + // (hinged at the 'eyes' end) + value = value + 1024 + // Invert the direction, so that "pads up" is largest, "pads down" is smallest + value = 2047 - value + // We want the same range as the analog, so halve the range + value = value / 2 + } + // 5 possible values (0,1,2,3,4) based on sensible thresholds + // We do this by thresholds, so that we have more control over the 5 levels + if (value < 200) { + return 0 + } else if (value < 400) { + return 1 + } else if (value < 600) { + return 2 + } else if (value < 800) { + return 3 + } + return 4 +} + +function waitNoButtons() { + while (input.buttonIsPressed(Button.A) || input.buttonIsPressed(Button.B)) { + basic.pause(100) + } +} diff --git a/tests/wg-operation.ts b/tests/wg-operation.ts new file mode 100644 index 00000000..b349c6aa --- /dev/null +++ b/tests/wg-operation.ts @@ -0,0 +1,529 @@ +let opMaxTime: number +let procMaxTime: number +let procsToDo: number +let recoveryTriesMax: number +let tenseTime: number +let flatlineTimeMax: number +let recoveryProbability: number +let aWasPressed: boolean +let bWasPressed: boolean +let digitsImg: Image +let tweezerCount_: number +let wasTweezers: boolean +let wasNose: boolean +let isTweezers: boolean + +// P0 blue wire, tweezers (active high) +// P1, green wire nose button/LED (active high) +// P2/red speaker (not a self toned beeper, but a piezo or a speaker) +opMaxTime = 120 * 1000 +procsToDo = 3 +procMaxTime = 60 * 1000 +tenseTime = 4000 +flatlineTimeMax = 15 * 1000 +recoveryTriesMax = 3 +recoveryProbability = 60 +let highScore = 0 +digitsImg = images.createImage(` + . . # . . . . # . . . # # . . . # # . . . # . . . . # # # . . . # # . . # # # . . . # . . . . # . . + . # . # . . # # . . . . . # . . . . # . . # . . . . # . . . . # . . . . . . . . . # . # . . # . # . + . # . # . . . # . . . . # . . . . # . . . # # # . . . # . . . # # . . . . # . . . . # . . . . # # . + . # . # . . . # . . . # . . . . . . # . . . # . . . . . # . . # . # . . # . . . . # . # . . . . # . + . . # . . . # # # . . # # # . . # # . . . . # . . . # # . . . . # . . . # . . . . . # . . . # # . . + `) +startIOMonitor() +while (true) { + splashScreen() + if (buttonB()) { + basic.showAnimation(` + . . . . . # # . . . . # . . . . # . . . . . . # . . . . . . + . . . . # . . . . # # # . . # . # . . # . . # . # . . . . # + . . . . # . . . . # . . . . # # # . . # # # . . # # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # . . . # # . . . # # . . . # # . . . # # . . . # # . . . # + `, 400) + let finalScore = surgery() + if (game.score() > highScore) { + basic.showString("HI", 150) + highScore = finalScore + } + flashDigit(finalScore) + waitButtonB() + } else if (buttonA()) { + testMode() + } else { + basic.pause(100) + } +} + +function surgery(): number { + let score = 0 + let speed = 150 + let opStartTime = input.runningTime() + let procStartTime = -1 + let procNumber = -1 + let procsDone = 0 + let recoveryTry = 0 + let timer = 0 + let state = "CHOOSE PROC" + resetButtons() + while (true) { + basic.pause(10) + let event = getEvent(state) + if (event == "CUT") { + state = "ARREST" + } + // CHECK TIMERS + if (!(procStartTime == -1)) { + if (input.runningTime() - procStartTime > procMaxTime) { + state = "LOST" + } else { + // TODO add code here to speed up near end of proc + } + } + if (input.runningTime() - opStartTime > opMaxTime) { + state = "LOST" + } else { + // TODO add code here to speed up near end of op + } + // PROCESS SPECIFIC STATES + if (state == "CHOOSE PROC") { + if (procNumber == -1) { + procNumber = 1 + showDigit(procNumber) + } else if (event == "SCROLL") { + procNumber = procNumber + 1 + if (procNumber > 9) { + procNumber = 1 + } + showDigit(procNumber) + } else if (event == "SELECT") { + procStartTime = input.runningTime() + state = "HEALTHY" + speed = 100 + } + } else if (state == "HEALTHY") { + speed = 100 + ecg(speed) + if (event == "TWINGE") { + state = "TENSE" + timer = input.runningTime() + } else if (event == "DONE") { + state = "PROC DONE" + } + } else if (state == "TENSE") { + speed = 25 + ecg(speed) + if (event == "TWINGE") { + state = "ARREST" + } else if (input.runningTime() - timer > tenseTime) { + state = "HEALTHY" + } + } else if (state == "ARREST") { + timer = input.runningTime() + recoveryTry = recoveryTriesMax + state = "FLATLINE" + } else if (state == "FLATLINE") { + basic.showLeds(` + . . . . . + . # . # . + . . . . . + . . . . . + # # # # # + `) + beepOn() + if (event == "SHOCK") { + state = "SHOCKING" + } else if (input.runningTime() - timer > flatlineTimeMax) { + state = "LOST" + } + } else if (state == "SHOCKING") { + charging() + basic.showAnimation(` + . . . . # . . . . # . . . . . . . . . . + . . . # . . . . # . . . . # . . . . . . + . . . . . . . # . . . . # . . . . # . . + . . . . . . . . . . . # . . . . # . . . + . . . . . . . . . . . . . . . . # . . . + `, 150) + beepNTimesFor(15, 500) + basic.showAnimation(` + . . . . . . . . . . . . . . . # . . . # + . . . . . . . . . . # . . # . . . . . . + . . . . . # . # . . . . . . . . . . . . + . # . . . . # . . . . . . . . . . . . . + . # . . . . # . . . . # . . . . # . . . + `, 150) + state = "SHOCKED" + } else if (state == "SHOCKED") { + let recover = Math.random(100) + if (recover >= recoveryProbability) { + state = "RECOVERED" + } else { + state = "FAILED" + } + } else if (state == "RECOVERED") { + beepOff() + basic.pause(500) + beep() + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . . . . + . # . # . . . . . . . # . # . . . . . . . # . # . + . . . . . . . . . . . . . . . . . . . . . . . . . + # . . . # . . . . . # . . . # . . . . . # . . . # + . # # # . . . . . . . # # # . . . . . . . # # # . + `, 400) + state = "HEALTHY" + } else if (state == "FAILED") { + recoveryTry = recoveryTry - 1 + if (recoveryTry > 0) { + state = "FLATLINE" + } else { + state = "LOST" + } + } else if (state == "PROC DONE") { + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . # + . . . . . . . . . . . . . . . . . . # . . . . # . + # . . . . # . . . . # . # . . # . # . . # . # . . + . . . . . . # . . . . # . . . . # . . . . # . . . + `, 400) + score = score + pointsForProc(procNumber) + procsDone = procsDone + 1 + procStartTime = -1 + if (procsDone == procsToDo) { + state = "OP DONE" + } else { + procNumber = -1 + state = "CHOOSE PROC" + } + } else if (state == "OP DONE") { + basic.showAnimation(` + . . . . . . . . # . . # . . . . . # . . . . . # . . . . . # . . # . . . . # . . . . . . . . . . . . . . . . . + . . . . # . . # . # . # . . # . . # . . . . . # . . . . . # . . # . . . . # . . . # . . . # . . . . . . . . . + # # # # # # # . . # # # . . # . # # . . . . # # . . . . # # . # # . . . . # . . . # . . . # . . . . . . . . . + # # # # # # # # # # # # # # # . # # # # . . # # # . . . # # . . . # # . . # # # . # . # # # . . # # . . . # # + # . . . # # . . . # # . . . # . # . . . . . # . . . . . # . . . . # . . . . # . . # . # . # . . # . . . . # . + `, 400) + return score + } else if (state == "LOST") { + beepOn() + basic.showLeds(` + . # . # . + . . # . . + . # . # . + . . . . . + # # # # # + `) + basic.pause(3000) + beepOff() + basic.showAnimation(` + . . . . . . . . . . # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . # # # # # # . . . . # . . . . # . . . . # # . # . # . . . . # # . # . # . . . . # + # # # # # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # . . . # # . . . # # . . . # # . . . # # . . . # # . . . # # . . . # # . . . # # . . . # + `, 400) + return score + } + } +} + +/** + * if any button pressed, terminate the animation immediately + */ +function splashScreen() { + let img = images.createImage(` + . # . # . . # . # . . # . # . . # . # . . . # . . . # # . . + # # # # # # . # . # # # # # # # . # . # . # . # . . # . # . + # # # # # # . . . # # # # # # # . . . # . # . # . . # # . . + . # # # . . # . # . . # # # . . # . # . . # . # . . # . . . + . . # . . . . # . . . . # . . . . # . . . . # . . . # . . . + `) + let x = 0 + while (!aWasPressed && !bWasPressed) { + img.showImage(x) + basic.pause(500) + x = x + 5 + if (x >= img.width()) { + x = 0 + } + } +} + +/** + * Test sensing and buzzing + * I/O at moment is (assuming self toning beeper) + * P0 is beeper and nose LED + * P1 is the tweezer sense wire + * P2 is possibly the nose button + * If we want amplification, might have to use piezo library + * which means using extra pins + */ +function testMode() { + while (!(buttonA())) { + if (pins.digitalReadPin(DigitalPin.P1) == 1) { + pins.digitalWritePin(DigitalPin.P0, 1) + basic.showLeds(` + . . . . . + . . . . # + . . . # . + # . # . . + . # . . . + `) + } else { + pins.digitalWritePin(DigitalPin.P0, 0) + basic.showLeds(` + # # # # # + . . # . . + . . # . . + . . # . . + . . # . . + `) + } + basic.pause(100) + } +} + +/** + * SENSE TWINGE/CUT FROM TWEEZERS (10ms per sample) + * @param state TODO + */ +function getEvent(state: string): string { + if (wasTweezers) { + if (tweezerCount_ > 20) { + wasTweezers = false + tweezerCount_ = 0 + return "CUT" + } else if (!isTweezers) { + wasTweezers = false + tweezerCount_ = 0 + return "TWINGE" + } + } + // SENSE A OR B BUTTON PRESSES + if (state == "CHOOSE PROC") { + if (buttonA()) { + return "SCROLL" + } else if (buttonB()) { + return "SELECT" + } + } else if (state == "FLATLINE") { + if (buttonB()) { + return "SHOCK" + } else if (nose()) { + return "SHOCK" + } + } else if (state == "HEALTHY") { + if (buttonB()) { + return "DONE" + } + } + // Clear any flags for unnecessary events in a given state to prevent latching + aWasPressed = false + bWasPressed = false + return "NONE" +} + +function flashDigit(digit: number) { + for (let i = 0; i < 4; i++) { + showDigit(digit) + basic.pause(200) + basic.clearScreen() + basic.pause(200) + } + showDigit(digit) + basic.pause(1000) +} + +/** + * Make a short beep sound + */ +function beep() { + beepOn() + basic.pause(200) + beepOff() +} + +/** + * work out score for a procedure + * @param procNumber TODO + */ +function pointsForProc(procNumber: number): number { + if (procNumber < 4) { + return 1 + } else if (procNumber < 7) { + return 2 + } else { + return 3 + } +} + +/** + * beep n times, for a total duration of m + * @param times TODO + * @param duration TODO + */ +function beepNTimesFor(times: number, duration: number) { + let halfCycle = duration / (times * 2) + for (let i = 0; i < times; i++) { + beepOn() + basic.pause(halfCycle) + beepOff() + basic.pause(halfCycle) + } +} + +function startIOMonitor() { + aWasPressed = false + input.onButtonPressed(Button.A, () => { + aWasPressed = true + }) + bWasPressed = false + input.onButtonPressed(Button.B, () => { + bWasPressed = true + }) + wasTweezers = false + isTweezers = false + tweezerCount_ = 0 + control.inBackground(() => { + let buzzCount = 0 + while (true) { + if (pins.digitalReadPin(DigitalPin.P0) == 1) { + wasTweezers = true + isTweezers = true + tweezerCount_ = tweezerCount_ + 1 + if (buzzCount == 0) { + pins.analogWritePin(AnalogPin.P2, 512) + pins.analogSetPeriod(AnalogPin.P2, 5000) + } + buzzCount = 10 + } else { + isTweezers = false + } + if (buzzCount > 0) { + buzzCount = buzzCount - 1 + if (buzzCount == 0) { + pins.analogWritePin(AnalogPin.P2, 0) + } + } + basic.pause(10) + } + }) +} + +/** + * Shows a single digit, with a nicer font than the standard micro:bit font + * @param digit TODO + */ +function showDigit(digit: number) { + digit = Math.clamp(0, 9, digit) + digitsImg.showImage(digit * 5) +} + +/** + * check to see if button A was pressed recently + */ +function buttonA(): boolean { + if (aWasPressed) { + aWasPressed = false + return true + } + return false +} + +function waitButtonA() { + while (!(buttonA())) { + basic.pause(100) + } +} + +function buttonB(): boolean { + if (bWasPressed) { + bWasPressed = false + return true + } + return false +} + +function waitButtonB() { + while (!(buttonB())) { + basic.pause(100) + } +} + +function beepOn() { + pins.analogWritePin(AnalogPin.P2, 512) + pins.analogSetPeriod(AnalogPin.P2, 2272) +} + +function beepOff() { + pins.analogWritePin(AnalogPin.P2, 0) +} + +function resetButtons() { + aWasPressed = false + bWasPressed = false +} + +function ecg(speed: number) { + beepOn() + pins.digitalWritePin(DigitalPin.P1, 1) + basic.pause(50) + beepOff() + basic.showAnimation(` + . . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . . + . . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . . + . . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . . + . . . . # . . . # # . . # # . . # # . . # # . . . # . . . . . . . . . + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + `, speed) + pins.digitalWritePin(DigitalPin.P1, 0) + basic.pause(speed * 10) +} + +function nose(): boolean { + if (wasNose) { + wasNose = false + return true + } + return false +} + +/** + * start period in microseconds + */ +function charging() { + let period = 2000 + let dec = 500 + pins.analogWritePin(AnalogPin.P2, 512) + pins.analogSetPeriod(AnalogPin.P2, period) + basic.showLeds(` + . # # . . + . . . # . + . . # . . + . . . # . + . # # . . + `) + basic.pause(500) + pins.analogSetPeriod(AnalogPin.P2, period - dec) + basic.showLeds(` + . # # . . + . . . # . + . . # . . + . # . . . + . # # # . + `) + basic.pause(500) + pins.analogSetPeriod(AnalogPin.P2, period - dec * 2) + basic.showLeds(` + . . # . . + . # # . . + . . # . . + . . # . . + . # # # . + `) + basic.pause(500) + beepOff() +} diff --git a/tests/wg-operator-reaction-test.ts b/tests/wg-operator-reaction-test.ts new file mode 100644 index 00000000..ef9bb265 --- /dev/null +++ b/tests/wg-operator-reaction-test.ts @@ -0,0 +1,178 @@ +let wasShake: boolean + +input.onShake(() => { + wasShake = true +}) +wait_6Hours() +timeForTest() +alertnessTest() +wait_2Hours() +timeForTest() +alertnessTest() +wait_2Hours() +timeForTest() +alertnessTest() + +/** + * animate back to work + * animate take a rest + */ +function animations() { } + +/** + * wait 6 hours + * because this is a test program, we only wait for a short time + */ +function wait_6Hours() { + basic.showAnimation(` + . . # . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . + . . # . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . + . . # . . . . # . . . . # # # . . # . . . . # . . . . # . . # # # . . . . # . . + . . . . . . . . . . . . . . . . . . # . . . # . . . # . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . # . . # . . # . . . . . . . . . . . . . . + `, 500) +} + +/** + * wait for 2 hours + * because this is test code, we only wait a few seconds + */ +function wait_2Hours() { + basic.showAnimation(` + . . # . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . + . . # . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . + . . # . . . . # . . . . # # # . . # . . . . # . . . . # . . # # # . . . . # . . + . . . . . . . . . . . . . . . . . . # . . . # . . . # . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . # . . # . . # . . . . . . . . . . . . . . + `, 500) +} + +function alertnessTest() { + let goodResponse = 1000 + let threshold = 5 + let score = 0 + // Start test on button press + let x = 0 + let start = images.createImage(` + . . # . . . . # . . + . . # . . . # . # . + . . # . . . . . # . + . . . . . . . # . . + . . # . . . . # . . + `) + while (!input.buttonIsPressed(Button.B)) { + start.showImage(x) + x = x + 5 + if (x >= start.width()) { + x = 0 + } + basic.pause(300) + } + // Wait for button(s) to be released + while (input.buttonIsPressed(Button.A) || input.buttonIsPressed(Button.B)) { + basic.pause(100) + } + // Run 10 random cognition response tests + for (let i = 0; i < 9; i++) { + // Choose random delay and random outcome + let delay = Math.random(5) + 5 + let outcome = Math.random(2) + // Draw moving dots on screen until delay expires + basic.clearScreen() + for (let j = 0; j < delay; j++) { + led.plot(j % 5, 2) + basic.pause(200) + basic.clearScreen() + } + // Show shake or button icon + if (outcome == 0) { + // Press the button! + basic.showLeds(` + . . . . . + . # # # . + . # # # . + . # # # . + . . . . . + `) + } else { + // Shake the bit! + basic.showLeds(` + # . # . . + # . . # . + # # # # # + # . . # . + # . # . . + `) + } + // Wait up to 3 seconds for button, shake, or timeout + wasShake = false + let timer = input.runningTime() + let timeout = 3000 + while (input.runningTime() < timer + timeout) { + if (wasShake) { + break + } else if (input.buttonIsPressed(Button.B)) { + break + } else { + basic.pause(100) + } + } + // Assess the response and the response time + let response = input.runningTime() - timer + if (outcome == 0 && input.buttonIsPressed(Button.B) && response <= goodResponse) { + score = score + 1 + } else if (outcome == 1 && wasShake && response <= goodResponse) { + score = score + 1 + } + } + // Show final score flashing 5 times (0..9) + for (let k = 0; k < 5; k++) { + basic.showNumber(score, 0) + basic.pause(250) + basic.clearScreen() + basic.pause(250) + } + basic.showNumber(score, 0) + basic.pause(500) + if (score < threshold) { + // Time for a break, show coffee cup animation + for (let l = 0; l < 3; l++) { + basic.showAnimation(` + . . . . . . . . . . . # . . . . # . . . . . . . . . . # . . . . # . . . . . . . + . . . . . . # . . . . # . . . . . . . . . . # . . . . # . . . . . . . . . . . . + # . . # . # # . # . # . . # . # . . # . # . # # . # . . # . # . . # . # . . # . + # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # + # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . + `, 400) + } + } else { + // All ok, back to work, show digging animation + for (let m = 0; m < 3; m++) { + basic.showAnimation(` + # . # . . # . . . . # . . . . + . # # . . . # . # . . # . . . + # # # . . . . # # . . . # . # + . . . . . . # # # . . . . # # + . . . . . . . . . . . . # # # + `, 400) + } + } + // Wait for any button press to finish test + while (!input.buttonIsPressed(Button.A) && !input.buttonIsPressed(Button.B)) { + basic.pause(100) + } +} + +/** + * alert the user it is time to take the test + * in a real system, this might give them 5 1 minute warnings + */ +function timeForTest() { + basic.showAnimation(` + . # # # . . # . . . . # # . . . # # . . . . # . . + . # . . . . # . . . . . . # . . . . # . . # # . . + . . # . . . # # # . . # # . . . . # . . . . # . . + . . . # . . . # . . . . . # . . # . . . . . # . . + . # # . . . . # . . . # # . . . # # # . . # # # . + `, 700) +} diff --git a/tests/wg-paintroller.ts b/tests/wg-paintroller.ts new file mode 100644 index 00000000..918bdd3e --- /dev/null +++ b/tests/wg-paintroller.ts @@ -0,0 +1,157 @@ +let maxGameTime: number +let wasShake: boolean + +maxGameTime = 60000 +input.onShake(() => { + wasShake = true +}) +while (true) { + splashScreen() + if (input.buttonIsPressed(Button.B)) { + basic.showAnimation(` + # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # # # + # # # . . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # . . # . . . . # . . . . # . . . . # . . . . # # # # # # # # # # + # # # . . # # # . . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # . . # # # . . # # # . . # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # # . . # # # . # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + `, 400) + let score = playOneGame() + flashDigit(score, 5) + waitButtonB() + basic.showAnimation(` + # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . # . # . . . . . . . # . # . . . . . . + # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . + `, 400) + } else if (input.buttonIsPressed(Button.A)) { + calibrate() + } +} + +function playOneGame(): number { + let countDots = 0 + let x = 2 + let y = 2 + let xdir = true + let canvas = images.createImage(` + . . . . . + . . . . . + . . . . . + . . . . . + . . . . . + `) + wasShake = false + let bearing = input.compassHeading() + let startTime = input.runningTime() + while (countDots < 25 && input.runningTime() - startTime < maxGameTime) { + if (wasShake) { + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . # # # . . . # . . . # # # . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . # # # . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . . . . . . + . . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . + . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . . . . . . + `, 50) + let pos = Math.random(5) + if (xdir) { + if (!canvas.pixel(pos, y)) { + canvas.setPixel(pos, y, true) + countDots = countDots + 1 + } + } else if (!canvas.pixel(x, pos)) { + canvas.setPixel(x, pos, true) + countDots = countDots + 1 + } + wasShake = false + canvas.showImage(0) + } else if (Math.abs(input.compassHeading() - bearing) > 60) { + xdir = !xdir + bearing = input.compassHeading() + if (xdir) { + x = Math.random(5) + } else { + y = Math.random(5) + } + } else { + basic.pause(100) + } + } + return dotsToScore(countDots) +} + +function splashScreen() { + let img = images.createImage(` + # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . # # . . # # # . # # # # . # # # # . . # # # . . . # # . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . # # # # . # # # # . # # # # . # # # # . # # # # . + # . . . # # . . . # # . . . # # . . . # # . . . # . # # # . . . # . . . # # # . . . . . . . . . . . . . . . . . . . . . # . . . . . # . . . . . # . . . . . # . . . . . # . . . # # . . # . # . # . . # # . . . # # . . . # # . . . # # . . . # . # . . # . . # . # . . . # # . . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . . . . . . . . . . . . . # # # . . . # . . . # # # . # . . . # # . . . # # . . . # # . . . # + # # # # . # # # # . # # # # . # # # # . . # # # . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # # # # # # . # # # . . # # . . . # . . . . . . . . . . . . . . . . . . . . # # # . . . # . . . . # . . . . # . . . # # # . # # # # . # # # # . # # # # . + # . . . . # . . . . # . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . # . . . . . # . . . . . # . . . . . # . . . . . # . . . # . . . # # . . # . # . # . . # . # . . # . # . . # . # . . # . . # . # . . . # # . . . . # . . . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . # . . . . # . . . . + # . . . . # . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # . . . . # . . . . # # . . . # # . . . # . . . . # . . . . # . . . . # . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . # . . . . + `) + let x = 0 + while (!input.buttonIsPressed(Button.A) && !input.buttonIsPressed(Button.B)) { + img.showImage(x) + basic.pause(200) + x = x + 5 + if (x >= img.width()) { + x = 0 + } + } +} + +/** + * rotate canvas + */ +function rotateImage() { } + +function flashDigit(digit: number, times: number) { + for (let i = 0; i < times; i++) { + basic.showNumber(digit, 0) + basic.pause(500) + basic.clearScreen() + basic.pause(500) + } + basic.showNumber(digit, 0) +} + +function waitButtonB() { + while (!input.buttonIsPressed(Button.B)) { + basic.pause(100) + } +} + +function dotsToScore(dots: number): number { + if (dots == 25) { + return 9 + } else if (dots >= 22) { + return 8 + } else if (dots >= 19) { + return 7 + } else if (dots >= 16) { + return 6 + } else if (dots >= 13) { + return 5 + } else if (dots >= 10) { + return 4 + } else if (dots >= 7) { + return 3 + } else if (dots >= 4) { + return 2 + } else if (dots >= 1) { + return 1 + } else { + return 0 + } +} + +function calibrate() { + basic.showString("CAL", 150) + if (input.compassHeading() == -4) { + input.calibrate() + } + while (!input.buttonIsPressed(Button.B)) { + let h = input.compassHeading() + basic.showNumber(h, 150) + } +} diff --git a/tests/wg-perfect-pancakes.ts b/tests/wg-perfect-pancakes.ts new file mode 100644 index 00000000..067c67dd --- /dev/null +++ b/tests/wg-perfect-pancakes.ts @@ -0,0 +1,267 @@ +let state: string +let timer: number +let gesturesRunning: boolean +let wasShake: boolean +let wasLogoUp: boolean +let wasLogoDown: boolean +let wasScreenUp: boolean +let wasScreenDown: boolean + +while (true) { + splashScreen() + if (input.buttonIsPressed(Button.B)) { + // animate: add pancake + basic.showAnimation(` + # # # # # # . . . # . . . . . . . . . . . . . . . + . . . . . . # # # . . # # # . . . . . . . . . . . + . . . . . . . . . . # . . . # # . . . # . . . . . + . . . . . . . . . . . . . . . . # # # . . # # # . + . . . . . . . . . . . . . . . . . . . . # . . . # + `, 250) + runGameOnce() + // animate: pancake done + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . # . . . # # # # # # # . . . # . . . . . . . . . . . # . # . . . . . . . # . # . . . . . . + . . . . . . . . . . . # # # . # # # # # . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + # . . . # # # # # # # . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + `, 250) + } else if (input.buttonIsPressed(Button.A)) { + testShake() + } +} + +/** + * Runs one complete game from start to end + */ +function runGameOnce() { + let score = 0 + let cooks = 0 + let target_time = 0 + // make sure no gestures are outstanding from last game + wasShake = false + wasLogoUp = false + wasLogoDown = false + wasScreenUp = false + wasScreenDown = false + state = "NEWSIDE" + while (true) { + // Handle any gestures that can happen at any time + let gesture = getGesture() + if (gesture == "FLOOR") { + state = "DROPPED" + } + // Run code appropriate to the present state of the game + if (state == "NEWSIDE") { + target_time = 5 + Math.random(5) + state = "COOKING" + startTimer() + } else if (state == "COOKING") { + // animate: cooking + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . + . . . . . # . . . . . . . . . . . . . # + # # # # # . # # # # # # # # # # # # # . + `, 100) + + if (gesture == "FLIP") { + state = "FLIPPING" + } else if (getTimerSec() >= target_time) { + state = "READY" + score = score + 1 + startTimer() + } + } else if (state == "READY") { + // animate: ready + basic.showAnimation(` + . . . . . + . . . . . + . . . . . + # . . . # + . # # # . + `, 100) + if (getTimerSec() > 2) { + state = "BURNING" + score = score - 1 + startTimer() + } else if (gesture == "FLIP") { + state = "FLIPPING" + } + } else if (state == "BURNING") { + // animate: burning + basic.showAnimation(` + . . . . . . . . . . . . . # . . . . # . + . . . . . . . . # . . # . # . . # . . . + . . . . . . # . # . . # . . . . . . . . + . . . . . . # . . . . . . . . . . . . . + # # # # # # # # # # # # # # # # # # # # + `, 100) + if (gesture == "SKY") { + state = "NEWSIDE" + } else if (getTimerSec() > 2) { + state = "BURNT" + } + } else if (state == "FLIPPING") { + // animate: flipping + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . # . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . # # # # # . # # . . . # # # . . . # # . # # # # # . . . . . . . . . . + . . . . . . . . . . # # # # # . . . . . . . . # # . # # # . # # . . . . . . . . # # # # # . . . . . + . . . . . # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # # # + # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + `, 100) + // Prevent a spurious double-flip from happening + wasShake = false + cooks = cooks + 1 + if (cooks == 5) { + state = "GAMEOVER" + } else { + state = "NEWSIDE" + } + } else if (state == "DROPPED") { + // animate: dropped + basic.showAnimation(` + # . . . # . . . . . # . . . # . . . . . + . # . # . . . . . . . # . # . . . . . . + . . # . . . . . . . . . # . . . . . . . + . # . # . . . . . . . # . # . . . . . . + # . . . # . . . . . # . . . # . . . . . + `, 250) + score = 0 + state = "GAMEOVER" + } else if (state == "BURNT") { + // animate: burnt + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . # . # . . . . . . . # # # . + . . . . . . . . . . . . . . . . . # . . . . . . . . # . # . . . . . . . # # # . . . . . . + . . . . . . . . . . . . . . . . . . . . . # . # . . . . . . . # # # . . . . . . . . . . . + . . . . . . # . # . . # # # . . # . # . . . . . . . # # # . . . . . . . . . . . . . . . . + # # # # # . # # # . . # # # . . # # # . . # # # . . . . . . . . . . . . . . . . . . . . . + `, 250) + score = 0 + state = "GAMEOVER" + } else if (state == "GAMEOVER") { + animateScore(score) + state = "WAITEJECT" + } else if (state == "WAITEJECT") { + if (gesture == "UPSIDEDOWN") { + return + } + } + } +} + +/** + * show score (0..9) flashing + * @param score TODO + */ +function animateScore(score: number) { + score = Math.clamp(0, 9, score) + for (let i = 0; i < 5; i++) { + basic.showNumber(score, 0) + basic.pause(500) + basic.clearScreen() + basic.pause(500) + } + basic.showNumber(score, 0) +} + +/** + * NOTE: Eventually this will move into a gesture library + * It hides all the nasty detail of detecting gestures + */ +function getGesture(): string { + if (!gesturesRunning) { + input.onShake(() => { + wasShake = true + }) + input.onLogoUp(() => { + wasLogoUp = true + }) + input.onLogoDown(() => { + wasLogoDown = true + }) + input.onScreenUp(() => { + wasScreenUp = true + }) + input.onScreenDown(() => { + wasScreenDown = true + }) + gesturesRunning = true + } + // work out which of a possible set of gestures has occurred: + // Button gestures and movement gestures both handled + // This is so that it is easy to also use this on the simulator too + // Generally, B is used for normal OK, A is used for abnormal RECOVERY + // (flip is a normal action, touch sky to turn off smoke alarm is recovery) + let a = input.buttonIsPressed(Button.A) + let b = input.buttonIsPressed(Button.B) + if (state == "COOKING" || state == "READY") { + if (b || wasShake) { + wasShake = false + return "FLIP" + } + } else if (state == "FLIPPING") { + if (a || wasLogoDown) { + wasLogoDown = false + return "FLOOR" + } + } else if (state == "BURNING") { + if (a || wasLogoUp) { + wasLogoUp = false + return "SKY" + } + } else if (state == "GAMEOVER" || state == "WAITEJECT") { + if (b || wasScreenDown) { + wasScreenDown = false + return "UPSIDEDOWN" + } + } + return "NONE" +} + +/** + * start timer by sampling runningtime and storing into starttime + */ +function startTimer() { + timer = input.runningTime() +} + +/** + * get the elapsed time from the global starttime with ref to running time + * in seconds. + */ +function getTimerSec(): number { + let t = (input.runningTime() - timer) / 1000 + return t +} + +/** + * Show a splash screen "Perfect Pancakes >>>" + * Splash screen "PP" with little arrow pointing to the start button + */ +function splashScreen() { + let splash = images.createImage(` + # # # # . . . . . . # # # # . . . . . . . . . . . . . . . . . . . . . + # . . . # . . . . . # . . . # # . . . . . # . . . . . # . . . . . # . + # # # # . . . . . . # # # # . . # . . . . . # . . . . . # . . . . . # + # . . . . . . . . . # . . . . # . . . . . # . . . . . # . . . . . # . + # . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . + `) + // use show image (not show animation) so that button press is more responsive + let index = 0 + // Any button press finishes the splash screen + while (!input.buttonIsPressed(Button.B) && !input.buttonIsPressed(Button.A)) { + splash.showImage(index * 5) + index = index + 1 + if (index > splash.width() / 5) { + index = 0 + } + basic.pause(250) + } +} + +function testShake() { } diff --git a/tests/wg-right-sugar.ts b/tests/wg-right-sugar.ts new file mode 100644 index 00000000..1f2e653d --- /dev/null +++ b/tests/wg-right-sugar.ts @@ -0,0 +1,242 @@ +let sugarThreshold: number +let ketoneThreshold: number + +// Important parameters +sugarThreshold = 14 +ketoneThreshold = 6 +while (true) { + // splash screen sugar cube (just the right sugar) + basic.showAnimation(` + # # # . . . . . . . . . . . . . . . . . + # # # . . . # # # . . . . . . . . . . . + # # # . . . # # # . . . # # # . . # # # + . . . . . . # # # . . . # # # . . # # # + . . . . . . . . . . . . # # # . . # # # + `, 400) + // ask questions and give advice + quiz() + // wait for button press before restart + waitAnyButton() +} + +function getSugar(): string { + waitNoButtons() + let selection = "MID" + while (!input.buttonIsPressed(Button.B)) { + // high, low, normal? + basic.showAnimation(` + . . . . . # . # . . . . # . . + . # # # . # . # . . . # . # . + . # # # . # . # # # . . . # . + . # # # . # . . # . . . # . . + . . . . . # . . # . . . # . . + `, 400) + // show low, mid, or high as a bar + selection = getLowMidHigh(selection) + } + return selection +} + +function getKetone(): string { + waitNoButtons() + let selection = "MID" + while (!input.buttonIsPressed(Button.B)) { + // high, low, normal? + basic.showAnimation(` + . . . . . . . . # . . . # . . + # # . . . . . # . . . # . # . + # # # # # . . # # . . . . # . + # # . . # . . # . # . . # . . + . . . . . # . . # . . . # . . + `, 400) + // show low, mid, or high as a bar + selection = getLowMidHigh(selection) + } + return selection +} + +function getIll(): boolean { + waitNoButtons() + let selection = false + while (!input.buttonIsPressed(Button.B)) { + // ask question 'happy or sad' + basic.showAnimation(` + . . . . . . . . . . . . # . . . . # . . + . # . # . . # . # . . # . # . . # . # . + . . . . . . . . . . . . . # . . . . # . + # . . . # . # # # . . . # . . . . # . . + . # # # . # . . . # . . # . . . . # . . + `, 400) + // get answer from user + selection = getHappySad(selection) + } + // if we are happy, we are not ill + return !selection +} + +function getLowMidHigh(selection: string): string { + let timeout = 2000 + let timer = input.runningTime() + while (true) { + // show the present level as a line + if (selection == "LOW") { + basic.showLeds(` + . . . . . + . . . . . + . . . . . + . . . . . + # # # # # + `) + } else if (selection == "HIGH") { + basic.showLeds(` + # # # # # + . . . . . + . . . . . + . . . . . + . . . . . + `) + } else { + basic.showLeds(` + . . . . . + . . . . . + # # # # # + . . . . . + . . . . . + `) + } + // process any user input + if (input.buttonIsPressed(Button.A)) { + // cycle round the 3 possible levels + if (selection == "LOW") { + selection = "MID" + } else if (selection == "MID") { + selection = "HIGH" + } else { + selection = "LOW" + } + // This is the 'hold repeat' time if you hold the A button + basic.pause(300) + // restart timer, 2 seconds of inactivity before return to main + timer = input.runningTime() + } else if (input.buttonIsPressed(Button.B)) { + // user is selecting so better return quickly + return selection + } else if (input.runningTime() > timer + timeout) { + // timeout, so return to main to re-prompt user + return selection + } else { + // This slows the loop down to stop the emulator being busy + // and also preserves battery life on the micro:bit + // it also affects the worst case response time + // it also affects the response time + basic.pause(100) + } + } +} + +/** + * Wait for all buttons to be released + * This prevents spurious selection in next question + */ +function waitNoButtons() { + while (input.buttonIsPressed(Button.A) || input.buttonIsPressed(Button.B)) { + basic.pause(100) + } +} + +function getHappySad(selection: boolean): boolean { + let timeout = 2000 + let timer = input.runningTime() + while (!input.buttonIsPressed(Button.B)) { + // Show present selection + if (selection) { + basic.showLeds(` + . . . . . + . # . # . + . . . . . + # . . . # + . # # # . + `) + } else { + basic.showLeds(` + . . . . . + . # . # . + . . . . . + . # # # . + # . . . # + `) + } + // Wait for any change in the selection + if (input.buttonIsPressed(Button.A)) { + selection = !selection + // This is the repeat time if button A held down + basic.pause(500) + timer = input.runningTime() + } else if (input.runningTime() > timer + timeout) { + return selection + } else { + // Preserve battery life on micro:bit and prevent emulator being busy + // This is also the response time to a button press + basic.pause(100) + } + } + return selection +} + +/** + * Button A changes value, Button B selects value + */ +function quiz() { + let sugar = getSugar() + if (sugar != "HIGH") { + // All is ok (tick) + basic.showAnimation(` + . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . # + . . . . . . . . . . . . . . . . . . # . . . . # . + # . . . . # . . . . # . # . . # . # . . # . # . . + . . . . . . # . . . . # . . . . # . . . . # . . . + `, 400) + } else { + // Button A changes value, Button B selects value + let ketone = getKetone() + if (ketone != "HIGH") { + // Button A changes value, Button B selects value + let ill = getIll() + if (!ill) { + // Time to rest (jump into bed) + basic.showAnimation(` + . . . . . # # . . . . # . . . . # . . . . . . # . . . . . . + . . . . # . . . . # # # . . # . # . . # . . # . # . . . . # + . . . . # . . . . # . . . . # # # . . # # # . . # # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # . . . # # . . . # # . . . # # . . . # # . . . # # . . . # + `, 400) + } else { + // Test more often (clock shows 2 hour interval) + basic.showAnimation(` + . . # . . . . . . . . . . . . . . . . . . # # . . . . . . . . # # . . . . . . . . # # . . + . . # . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . # . . . . . . . . . # . + . . # . . . . # # # . . # . . # # # . . . . # . . . . . . . . . # . . . . . . . . . # . . + . . . . . . . . . . . . # . . . . . . . . # . . . . . . . . . # . . . . . . . . . # . . . + . . . . . . . . . . . . # . . . . . . . . # # # . . . . . . . # # # . . . . . . . # # # . + `, 400) + } + } else { + // Get some help (call the diabetes care team on the phone) + basic.showAnimation(` + . . . . . . . . . . # # # # # # # . . . # # . . . # # . . . # # . . . # # # . . # # . # . # # . . # + . . . . . # # # # # # . . . # # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . + # # # # # # . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . + # . # . # . . # . . . . # . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . + . # # # . . # # # . . # # # . # # . . . # # . . # # # . # . # # # . . # # . . . # # . . . # # . . . + `, 400) + } + } +} + +function waitAnyButton() { + while (!input.buttonIsPressed(Button.A) && !input.buttonIsPressed(Button.B)) { + basic.pause(100) + } +} diff --git a/tests/wg-user-confidance.ts b/tests/wg-user-confidance.ts new file mode 100644 index 00000000..d03df848 --- /dev/null +++ b/tests/wg-user-confidance.ts @@ -0,0 +1,488 @@ +let AWasPressed: boolean +let BWasPressed: boolean +let wasShake: boolean +let dots025: Image + +dots025 = images.createImage(` + . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # + `) +let tests = "DABPXYZSCT" +let test = 0 +let prevTest = -1 +startIOMonitor() +while (true) { + let testLetter = tests[test] + let autoRun = false + if (testLetter == "D" || testLetter == "A" || testLetter == "B") { + autoRun = true + } + if (!(test == prevTest)) { + basic.showString(tests[test], 200) + prevTest = test + } + if (AWasPressed || autoRun) { + AWasPressed = false + if (testLetter == "D") { + testDisplay() + test = test + 1 + } else if (testLetter == "A") { + testButtonA() + test = test + 1 + } else if (testLetter == "B") { + testButtonB() + test = test + 1 + } else if (testLetter == "P") { + testPads() + } else if (testLetter == "X") { + testTiltX() + } else if (testLetter == "Y") { + testTiltY() + } else if (testLetter == "Z") { + testTiltZ() + } else if (testLetter == "S") { + testShake() + } else if (testLetter == "C") { + testCompass() + } else if (testLetter == "T") { + testTemperature() + } else { + // end of tests + basic.showLeds(` + . . . . . + . . . . # + . . . # . + # . # . . + . # . . . + `, 400) + } + prevTest = -1 + AWasPressed = false + BWasPressed = false + } else if (BWasPressed) { + BWasPressed = false + if (test < tests.length - 1) { + test = test + 1 + } else { + test = 3 + } + } else { + basic.pause(100) + } +} + +/** + * flash all LEDs 5 times + */ +function testDisplay() { + for (let i = 0; i < 5; i++) { + basic.plotLeds(` + # # # # # + # # # # # + # # # # # + # # # # # + # # # # # + `) + basic.pause(200) + basic.clearScreen() + basic.pause(200) + } + // cycle all LEDs from 1 to 25 + basic.showAnimation(` + # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # + `, 400) +} + +function testButtonA() { + basic.plotLeds(` + . . # . . + . # . # . + . # # # . + . # . # . + . # . # . + `) + // wait for A pressed + while (!input.buttonIsPressed(Button.A)) { + basic.pause(100) + } + basic.plotLeds(` + . # . . . + # . # . . + # # # . . + # . # . . + # . # . . + `) + // wait for A released + while (input.buttonIsPressed(Button.A)) { + basic.pause(100) + } + basic.plotLeds(` + . . # . . + . # . # . + . # # # . + . # . # . + . # . # . + `) + basic.pause(1000) +} + +function testTiltX() { + basic.clearScreen() + let prevx = 0 + while (!AWasPressed && !BWasPressed) { + basic.pause(100) + let x = input.acceleration(Dimension.X) + let x2 = x / 512 + 2 + let x3 = Math.clamp(0, 4, x2) + // sticky trace + led.plot(x3, 0) + // middle line is actual/live + if (x3 != prevx) { + led.unplot(prevx, 2) + prevx = x3 + } + led.plot(x3, 2) + // bottom line is -4G, -2G, 1G, +2G, +4G + if (x <= -2048) { + led.plot(0, 4) + } else if (x <= -1024) { + led.plot(1, 4) + } else if (x <= 1024) { + led.plot(2, 4) + } else if (x <= 2048) { + led.plot(3, 4) + } else { + led.plot(4, 4) + } + } +} + +function testShake() { + wasShake = false + basic.plotLeds(` + . . . . . + . . . . . + . . # . . + . . . . . + . . . . . + `) + while (!AWasPressed && !BWasPressed) { + if (wasShake) { + wasShake = false + basic.plotLeds(` + # # # # # + # # # # # + # # # # # + # # # # # + # # # # # + `) + basic.pause(500) + basic.plotLeds(` + . . . . . + . . . . . + . . # . . + . . . . . + . . . . . + `) + } else { + basic.pause(100) + } + } +} + +function testCompass() { + if (input.compassHeading() < 0) { + input.calibrate() + } + basic.clearScreen() + while (!AWasPressed && !BWasPressed) { + let d = input.compassHeading() + d = d / 22 + d = Math.clamp(0, 15, d) + d = (d + 2) % 16 + if (d < 4) { + led.plot(d, 0) + } else if (d < 8) { + led.plot(4, d - 4) + } else if (d < 12) { + led.plot(4 - d - 8, 4) + } else { + led.plot(0, 4 - d - 12) + } + basic.pause(100) + } +} + +function testPads() { + let TESTSPEED = 500 + AWasPressed = false + BWasPressed = false + // Make sure all pins are inputs, before test starts + let p0 = pins.digitalReadPin(DigitalPin.P0) + let p1 = pins.digitalReadPin(DigitalPin.P1) + let p2 = pins.digitalReadPin(DigitalPin.P2) + let ok0 = 0 + let ok1 = 0 + let ok2 = 0 + while (!AWasPressed && !BWasPressed) { + basic.clearScreen() + // ## P0 out low, read from P1 and P2 + ok0 = 0 + pins.digitalWritePin(DigitalPin.P0, 0) + basic.pause(TESTSPEED) + p1 = pins.digitalReadPin(DigitalPin.P1) + p2 = pins.digitalReadPin(DigitalPin.P2) + if (p1 == 0) { + led.plot(0, 0) + ok0 = ok0 + 1 + } + if (p2 == 0) { + led.plot(1, 0) + ok0 = ok0 + 1 + } + // ## P0 out high, read from P1 and P2 + pins.digitalWritePin(DigitalPin.P0, 1) + basic.pause(TESTSPEED) + p1 = pins.digitalReadPin(DigitalPin.P1) + p2 = pins.digitalReadPin(DigitalPin.P2) + if (p1 == 1) { + led.plot(2, 0) + ok0 = ok0 + 1 + } + if (p2 == 1) { + led.plot(3, 0) + ok0 = ok0 + 1 + } + // set back to an input + p0 = pins.digitalReadPin(DigitalPin.P0) + // ## P1 out low, read from P0 and P2 + ok1 = 0 + pins.digitalWritePin(DigitalPin.P1, 0) + basic.pause(TESTSPEED) + p0 = pins.digitalReadPin(DigitalPin.P0) + p2 = pins.digitalReadPin(DigitalPin.P2) + if (p0 == 0) { + led.plot(0, 1) + ok1 = ok1 + 1 + } + if (p2 == 0) { + led.plot(1, 1) + ok1 = ok1 + 1 + } + // ## P1 out high, read from P0 and P2 + pins.digitalWritePin(DigitalPin.P1, 1) + basic.pause(TESTSPEED) + p0 = pins.digitalReadPin(DigitalPin.P0) + p2 = pins.digitalReadPin(DigitalPin.P2) + if (p0 == 1) { + led.plot(2, 1) + ok1 = ok1 + 1 + } + if (p2 == 1) { + led.plot(3, 1) + ok1 = ok1 + 1 + } + // set back to an input + p0 = pins.digitalReadPin(DigitalPin.P1) + // ## P2 out low, read from P0 and P1 + ok2 = 0 + pins.digitalWritePin(DigitalPin.P2, 0) + basic.pause(TESTSPEED) + p0 = pins.digitalReadPin(DigitalPin.P0) + p1 = pins.digitalReadPin(DigitalPin.P1) + if (p0 == 0) { + led.plot(0, 2) + ok2 = ok2 + 1 + } + if (p1 == 0) { + led.plot(1, 2) + ok2 = ok2 + 1 + } + // ## P2 out high, read from P0 and P1 + pins.digitalWritePin(DigitalPin.P2, 1) + basic.pause(TESTSPEED) + p0 = pins.digitalReadPin(DigitalPin.P0) + p1 = pins.digitalReadPin(DigitalPin.P1) + if (p0 == 1) { + led.plot(2, 2) + ok2 = ok2 + 1 + } + if (p1 == 1) { + led.plot(3, 2) + ok2 = ok2 + 1 + } + p2 = pins.digitalReadPin(DigitalPin.P2) + // ## Assess final test status + if (ok0 == 4) { + led.plot(4, 0) + } + basic.pause(TESTSPEED) + if (ok1 == 4) { + led.plot(4, 1) + } + basic.pause(TESTSPEED) + if (ok2 == 4) { + led.plot(4, 2) + } + basic.pause(TESTSPEED) + if (ok0 + ok1 + ok2 == 12) { + // all tests passed + led.plot(4, 4) + } + // ## Test cycle finished + basic.pause(1000) + } + // intentionally don't clear A and B flags, so main loop can process them. +} + +/** + * - show number of dots on screen (0..25) to represent temperature in celcius + */ +function testTemperature() { + while (!AWasPressed && !BWasPressed) { + let temp = input.temperature() - 10 + temp = Math.clamp(0, 25, temp) + dots025.plotFrame(temp) + basic.pause(500) + } +} + +function testButtonB() { + basic.plotLeds(` + . # # . . + . # . # . + . # # . . + . # . # . + . # # . . + `) + // wait for B pressed + while (!input.buttonIsPressed(Button.B)) { + basic.pause(100) + } + basic.plotLeds(` + . . # # . + . . # . # + . . # # . + . . # . # + . . # # . + `) + // wait for B released + while (input.buttonIsPressed(Button.B)) { + basic.pause(100) + } + basic.plotLeds(` + . # # . . + . # . # . + . # # . . + . # . # . + . # # . . + `) + basic.pause(1000) +} + +function testTiltY() { + basic.clearScreen() + let prevy = 0 + while (!AWasPressed && !BWasPressed) { + basic.pause(100) + let y = input.acceleration(Dimension.Y) + let y2 = y / 512 + 2 + let y3 = Math.clamp(0, 4, y2) + // sticky trace + led.plot(0, y3) + // middle line is actual/live + if (y3 != prevy) { + led.unplot(2, prevy) + prevy = y3 + } + led.plot(2, y3) + // bottom line is -4G, -2G, 1G, +2G, +4G + if (y <= -2048) { + led.plot(4, 0) + } else if (y <= -1024) { + led.plot(4, 1) + } else if (y <= 1024) { + led.plot(4, 2) + } else if (y <= 2048) { + led.plot(4, 3) + } else { + led.plot(4, 4) + } + } +} + +function testTiltZ() { + basic.clearScreen() + while (!AWasPressed && !BWasPressed) { + let z = input.acceleration(Dimension.Z) + if (z < -2000) { + basic.plotLeds(` + # . . . # + # . . . # + # . . . # + # . . . # + # . . . # + `) + } else if (z <= -1030) { + basic.plotLeds(` + . # . # . + . # . # . + . # . # . + . # . # . + . # . # . + `) + } else if (z <= 1000) { + basic.plotLeds(` + . . # . . + . . # . . + . . # . . + . . # . . + . . # . . + `) + } else if (z <= 1030) { + basic.plotLeds(` + . . . . . + . . . . . + # # # # # + . . . . . + . . . . . + `) + } else if (z <= 2000) { + basic.plotLeds(` + . . . . . + # # # # # + . . . . . + # # # # # + . . . . . + `) + } else { + basic.plotLeds(` + # # # # # + . . . . . + . . . . . + . . . . . + # # # # # + `) + } + basic.pause(100) + } +} + +function startIOMonitor() { + input.onButtonPressed(Button.A, () => { + AWasPressed = true + }) + input.onButtonPressed(Button.B, () => { + BWasPressed = true + }) + input.onShake(() => { + wasShake = true + }) +}