From 1a34ef3a2fe8c3d5f17c65bd13c29d1ca351d41b Mon Sep 17 00:00:00 2001 From: ganicke Date: Wed, 6 Sep 2017 17:48:41 -0700 Subject: [PATCH] Add multiple coding activities. --- docs/projects/watch.md | 5 + docs/projects/watch/code.md | 270 ++++----------------------- docs/projects/watch/digital-watch.md | 269 ++++++++++++++++++++++++++ docs/projects/watch/timer.md | 110 +++++++++++ 4 files changed, 417 insertions(+), 237 deletions(-) create mode 100644 docs/projects/watch/digital-watch.md create mode 100644 docs/projects/watch/timer.md diff --git a/docs/projects/watch.md b/docs/projects/watch.md index 96d593e9..c1572b94 100644 --- a/docs/projects/watch.md +++ b/docs/projects/watch.md @@ -29,6 +29,11 @@ Let's get started! ### ~ +### Additional coding activities + +* [Countdown timer](/projects/watch/timer) +* [Digital watch](/projects/watch/digital-watch) + ### Acknowledgements Artistic design by Melinda Hoeneisen. diff --git a/docs/projects/watch/code.md b/docs/projects/watch/code.md index 1892e56c..41e4c718 100644 --- a/docs/projects/watch/code.md +++ b/docs/projects/watch/code.md @@ -2,268 +2,64 @@ ### ~avatar avatar -Put the power of time into your watch. Let's code up a real digital watch for your @boardname@! +Let's make a counter for your watch to remember all the motions you make when you walk or move your arm. ### ~ -## Duration: ~20 minutes +## Duration: ~5 minutes + +## Make a count variable + +We need a variable to keep track of how many motions you make. -## Make the time variables -We need to make some variables to keep track of the time and for a few other things. 1. Go into **Basic** in the toolbox and pull an ``||basic:on start||`` on to the workspace. -2. Ok, in **Variables** click on `Make a Variable`. Name the variable as `hours`. Drag out a ``||variables:set to||`` block and change the name with the dropdown to `hours`. Place the variable into the ``||basic:on start||`` block. -3. Repeat this 4 more times to make variables named `minutes`, `time`, `adjust`, and `ampm`. -4. Now, for the ``||variables:set to||`` block for `time`, go to **Text** and drag a `" "` in and replace the `0`. -5. For the `ampm` variable, change the `0` there to a `false` from the **Logic** catagory. +2. Ok, in **Variables** click on `Make a Variable`. Name the variable as `motions`. Drag out a ``||variables:set to||`` block and change the name with the dropdown to `motions`. Place the variable into the ``||basic:on start||`` block. +3. Let's show that there are no motions counted yet. Get a ``||basic:show number||`` from **Basic** and put it after the variable. Now, change the `0` to the `motions` variable from the **Variables** category in the toolbox. ```blocks -let hours = 0 -let minutes = 0 -let adjust = 0 -let time = "" -let ampm = false +let motions = 0; +motions = 0; +basic.showNumber(motions); ``` -## Display the time, kind of +## Count your movements -So, let's try showing the time on the display. We aren't keeping time yet but we'll just see if we can make our watch show something. +Ok, now we'll count and show all of your movements. -1. Get in the **Input** catagory and pull out an ``||input:on shake||``. We'll have our watch show the time when it's shaken. -2. Get another ``||variables:set to||`` and put it into the ``||input:on shake||``. Change the name to `time`. -3. Replace the `0` with a ``||text:join||`` from **Text**. Get another ``||text:join||`` and put it into the second slot of the first ``||text:join||`` you pulled out. -4. Change the `" "` in the first ``||text:join||`` to the `hours` variable. Change the text in the first slot of the second ``||text:join||`` to `":"`. And, change the last slot in the second ``||text:join||`` to the `minutes` variable. -5. Finally, stick in a ``||basic:show string||`` below the ``||variables:set to||``. Switch the text inside to the variable `time`. -6. Download the code to you @boardname@ and give it a shake. Did you see the time of "0:0" go by on the LEDs? +1. Get an ``||input:on shake||`` block from **Input** and place it in the workspace. +2. To count each of your movements, get a ``||variables:change by||`` and place it in the ``||input:on shake||``. Change the variable from `item` to `motions`. +3. Grab another ``||basic:show number||`` and put it at the bottom of the ``||input:on shake||``. Find `motions` again back over in **Variables** and replace the `0` with it. ```blocks -let time = "" -let minutes = 0 -let hours = 0 +let motions = 0; input.onGesture(Gesture.Shake, () => { - time = hours + (":" + minutes); - basic.showString(time); + motions += 1; + basic.showNumber(motions); }) ``` -## Set the time with buttons -There has to be a way to set the time on your watch. We'll use the buttons to set the current time. One button is for setting the hours and another button is for the minutes. -### Set the hours -Let's make a way to set the hours for the watch. +## Reset! -1. In **Input**, find an ``||input:on button pressed||`` an put it somewhere on the workspace. -2. Get an ``||logic:if then else||`` block from **Logic** and put it in the ``||input:on button pressed||``. -3. From the same **Logic** category, get a ``||logic:0 < 0||`` and relpace the `false` condition with it. -4. Change the left `0` in the condtion to the `hours` variable. Change `0` on the right to `23`. This limits our hour count to 23 hours. -5. In the ``||logic:then||`` section, put a ``||variables:change by||`` there. Select the `hours` variable name from the dropdown. -6. In the ``||logic:else||`` section, put a ``||variables:set to||`` there. Select the `hours` variable name from the dropdown and leave the `0`. +If we want to start over from zero, then we need to have a way to reset the motion count. Let's use one of the buttons to do it. + +1. Go over to **Input** and get an ``||input:on button pressed||``. Place a ``||variables:set to||`` inside. Change the variable name to `motions`. +2. Grab another ``||basic:show number||`` and change the `0` to the a `motions` variable. ```blocks -let hours = 0; +let motions = 0; input.onButtonPressed(Button.A, () => { - if (hours < 23) { - hours += 1; - } else { - hours = 0; - } + motions = 0; + basic.showNumber(motions); }) ``` -### Set the minutes +## Finished! -Setting minutes is almost the same as setting hours but with just a few changes. -1. To make things easy, right click on ``||input:on button pressed||`` block and select the **Duplicate** option in the menu. This makes a copy of the original block. -2. In the new ``||input:on button pressed||``, change the button to `B`. -3. Change every variable name from `hours` to `minutes`. Change the `23` in the ``||logic:if||`` condition to ``59``. This is the limit of minutes we count. +Yeah! You're ready to count your movements. Press the ``|Download|`` button to move the code to the @boardname@. Walk around, move you arm, and watch it count! Press the **A** button if you want to start over. -```blocks -let minutes = 0; -input.onButtonPressed(Button.B, () => { - if (minutes < 59) { - minutes += 1; - } else { - minutes = 0; - } -}) -``` +## More watch coding projects -### Select 24 hour or 12 hour time +Are you up for a bigger challenge? How about making your watch turn into a countdown timer or even a real digital watch? Take a look at some other coding projects for the @boardname@ watch: -Time is shown in either 24 hour or 12 hour format. We'll use one more button to choose which format to show. Using the 12 hour format adds an 'AM' or 'PM' at the end. - -1. In **Input**, get an ``||input:on button pressed||`` an put it on the workspace. Change the button to `A+B`. -2. Grab a ``||variables:set to||``, put it in the block and change the variable to `ampm`. Put a ``||logic:not||`` from **Logic** in where the `0` is. -3. Pick up a `ampm` from **Variables** and connect it on the right of the ``||logic:not||``. This switches our 24 hour format to 12 hour and back. - -```blocks -let ampm = false; -input.onButtonPressed(Button.AB, () => { - ampm = !(ampm); -}) -``` - -## Make the timer tick - -A watch really has three parts: the display, settings, and timer. We need a way to make the minutes and hours count up at the right time. Let's code the timer. - -1. In **Basic**, get a ``||basic:forever||`` loop out to the workspace. -2. Also in **Basic**, take out a ``||basic:pause||`` an put it into the loop. Change the time from `100` to `60000`. The time is in milliseconds so we want to count each minute every 60000 milliseconds. -3. Below the ``||basic:pause||``, put a ``||logic:if then else||`` block. Change the condition in the ``||logic:if||`` to use a ``||logic:0 < 0||``. -4. Replace the `0` on the left with the `minutes` variable. Change the `0` on the right to `59`. -5. Put a ``||variables:change by||`` into the ``||logic:then||``. Change the variable to `minutes`. -6. Get a ``||variables:set to||`` and put it in the ``||logic:else||``. Again, change the variable to `minutes`. - -```blocks -let minutes = 0; -basic.forever(() => { - basic.pause(60000) - if (minutes < 59) { - minutes += 1; - } else { - minutes = 0; - } -}) -``` - -**Keep on coding...** - -1. Now, take another ``||logic:if then else||`` and put it just below the ``||variables:set to||`` inside the first ``||logic:else||``. -2. In the second ``||logic:if||``, put in a ``||logic:0 < 0||`` as the condition. Replace the left `0` with the `hours` variable. Change the right `0` to `23`. We count hours up to 23 until we go back to 0 (midnight). -3. Put a ``||variables:change by||`` into the second ``||logic:then||``. Change the variable to `hours`. -4. Get a ``||variables:set to||`` and put it in the second ``||logic:else||``. Again, change the variable to `hours`. Ok, the timer's ready to tick. - -```blocks -let minutes = 0 -let hours = 0 -basic.forever(() => { - basic.pause(60000) - if (minutes < 59) { - minutes += 1 - } else { - minutes = 0 - if (hours < 23) { - hours += 1 - } else { - hours = 0 - } - } -}) -``` - -## Shake and show...the time! - -We're going back to the display code we made earlier. We'll now make it show the real time! This step is going to be busy but we'll get it done. - -First, we have to code an adjustment for the hours number when we're using the 12 hour format. - -1. Find the ``||input:on shake||`` block we coded earlier. Pull out and drag to the trash the blocks inside. We're starting fresh. -2. Pull out a ``||variables:set to||`` an put it inside the ``||input:on shake||``. Change the variable to `adjust`. Change the `0` on the right to the `hours` variable. -3. Get a ``||logic:if then||`` and put it under the ``||variables:set to||``. Replace the condition with the `ampm ` variable. -4. Grab a ``||logic:if then else||`` and put it in the ``||logic:then||`` part of the first ``||logic:if then||``. Change the condition to ``||logic:0 < 0||``. Replace the `0` on the left with the `hours` variable. Change the `0` on the right to `12`. Switch the `<` to a `>`. -5. Go get another ``||variables:set to||`` and put it in the ``||logic:then||`` of the second ``||logic:if then else||``. Change the variable to `adjust`. In **Math** take a ``||math:0 - 0||`` and replace the `0` in the ``||variables:set to||``. Change the `0` on the left to the `hours` variable and the `0` on the right to `12`. -6. Take one more ``||logic:if then||`` and put it in the ``||logic:else||``. Change its condition to ``||logic:0 = 0||``. Put the `hours` variable in place of the `0` on the left. -7. Inside this last ``||logic:if then||`` place a ``||variables:set to||``. Change the variable name to `adjust` and set the value to `12`. - -```blocks -let hours = 0; -let adjust = 0; -let ampm = false; -input.onGesture(Gesture.Shake, () => { - adjust = hours; - if (ampm) { - if (hours > 12) { - adjust = hours - 12 - } else { - if (hours == 0) { - adjust = 12 - } - } - } -}) -``` - -**Keep on coding...** - -Now, we have to join up the hours and minutes to make text that will display on the watch. - -1. At the bottom of the ``||input:on shake||``, insert a ``||variables:set to||``. Change the variable name to `time`. Connect it to a ``||text:join||`` from **Text**. -2. Make 3 copies of this last ``||variables:set to||`` using the **Duplicate** option in the menu when you right click on the block. Put the copies underneath each other so that all 4 are stacked together. -3. In the first ``||variables:set to||``, replace the second `""` in the ``||text:join||`` with the `adjust` variable. -4. With the second copy, change the first `""` in the ``||text:join||`` to the variable `time`. Change the second string in the ``||text:join||`` to `":"`. -5. In the fourth copy, change the first `""` in the ``||text:join||`` to the variable `time`. Change the second string in the ``||text:join||`` to division operator from **Math**. Set the left `0` to the `minutes` variable and the right `0` to `10`. -6. In the fourth copy, change the first `""` in the ``||text:join||`` to the variable `time`. Change the second string in the ``||text:join||`` to a ``||Math:remainder of||`` in **Math**. Set the left `0` to the `minutes` variable and the right `0` to `10`. - -```blocks -let minutes = 0; -let hours = 0; -let adjust = 0; -let time = ""; -let ampm = false; -input.onGesture(Gesture.Shake, () => { - adjust = hours; - if (ampm) { - if (hours > 12) { - adjust = hours - 12; - } else { - if (hours == 0) { - adjust = 12; - } - } - } - time = "" + adjust; - time = time + ":"; - time = time + minutes / 10; - time = time + minutes % 10; -}) -``` - -**Keep on coding...** - -Ok, we're getting close to finishing now. Here we need to add the 'AM' or 'PM' if we are in 12 hour format. Then, finally, display the complete time string. - -1. Put an ``||logic:if then||`` block at the end of the ``||input:on shake||``. Replace the `true` condition with the variable `ampm`. -2. Insert a ``||logic:if then else||`` into this ``||logic:if then||``. Use a ``||logic:0 < 0||`` as the condition. Change the left `0` to the `hours` variable. Change the right `0` to `11`. Switch the `<` to a `>`. -3. Place a ``||variables:set to||`` in the ``||logic:then||``. Change the variable to `time` and attach a ``||text:join||``. Make the first part of the ``||text:join||`` be the variable `time` and the second part to the text `"PM"`. -4. Do the exact same thing as in the last step but put the ``||variables:set to||`` block in the ``||logic:else||`` underneath. Make the second part of the ``||text:join||`` be `"AM"` this time. -5. Finally, at the very bottom of ``||input:on shake||``, go get a ``||basic:show string||`` from **Basic** and put it there. Change the string `"Hello!"` to the `time` variable. - -```blocks -let minutes = 0; -let hours = 0; -let adjust = 0; -let time = ""; -let ampm = false; -input.onGesture(Gesture.Shake, () => { - adjust = hours; - if (ampm) { - if (hours > 12) { - adjust = hours - 12 - } else { - if (hours == 0) { - adjust = 12 - } - } - } - time = "" + adjust; - time = time + ":" - time = time + minutes / 10 - time = time + minutes % 10 - if (ampm) { - if (hours > 11) { - time = time + "PM" - } else { - time = time + "AM" - } - } - basic.showString(time) -}) -``` - -## Complete! - -Wow, so awesome! You've got your watch coded and ready to try. Go press the ``|Download|`` button and put your code on the @boardname@. When you shake it, it shows the current time. - -Right now, it's showing 24 hour format: hours go from `0` to `23` and back to `0`. Press the **A+B** buttons together to change to 12 hour format: hours go from `12` to `12` with `1` through `11` in between. It has either `"AM"` or `"PM"` at the end. - -To set it to the current time, you use the **A** and **B** buttons. The **A** button moves the current hour up by one each time it's pressed. The **B** button moves the minutes up by one every time it's pressed. - -Now that you can tell time on your @boardname@ who knows what you will accomplish next. Only, time will tell! \ No newline at end of file +* [Countdown timer](/projects/watch/timer) +* [Digital watch](/projects/watch/digital-watch) \ No newline at end of file diff --git a/docs/projects/watch/digital-watch.md b/docs/projects/watch/digital-watch.md new file mode 100644 index 00000000..74a1973d --- /dev/null +++ b/docs/projects/watch/digital-watch.md @@ -0,0 +1,269 @@ +# Digital watch + +### ~avatar avatar + +Put the power of time into your watch. Let's code up a real digital watch for your @boardname@! + +### ~ + +## Duration: ~20 minutes + +## Make the time variables +We need to make some variables to keep track of the time and for a few other things. +1. Go into **Basic** in the toolbox and pull an ``||basic:on start||`` on to the workspace. +2. Ok, in **Variables** click on `Make a Variable`. Name the variable as `hours`. Drag out a ``||variables:set to||`` block and change the name with the dropdown to `hours`. Place the variable into the ``||basic:on start||`` block. +3. Repeat this 4 more times to make variables named `minutes`, `time`, `adjust`, and `ampm`. +4. Now, for the ``||variables:set to||`` block for `time`, go to **Text** and drag a `" "` in and replace the `0`. +5. For the `ampm` variable, change the `0` there to a `false` from the **Logic** catagory. + +```blocks +let hours = 0 +let minutes = 0 +let adjust = 0 +let time = "" +let ampm = false +``` + +## Display the time, kind of + +So, let's try showing the time on the display. We aren't keeping time yet but we'll just see if we can make our watch show something. + +1. Get in the **Input** catagory and pull out an ``||input:on shake||``. We'll have our watch show the time when it's shaken. +2. Get another ``||variables:set to||`` and put it into the ``||input:on shake||``. Change the name to `time`. +3. Replace the `0` with a ``||text:join||`` from **Text**. Get another ``||text:join||`` and put it into the second slot of the first ``||text:join||`` you pulled out. +4. Change the `" "` in the first ``||text:join||`` to the `hours` variable. Change the text in the first slot of the second ``||text:join||`` to `":"`. And, change the last slot in the second ``||text:join||`` to the `minutes` variable. +5. Finally, stick in a ``||basic:show string||`` below the ``||variables:set to||``. Switch the text inside to the variable `time`. +6. Download the code to you @boardname@ and give it a shake. Did you see the time of "0:0" go by on the LEDs? + +```blocks +let time = "" +let minutes = 0 +let hours = 0 +input.onGesture(Gesture.Shake, () => { + time = hours + (":" + minutes); + basic.showString(time); +}) +``` +## Set the time with buttons +There has to be a way to set the time on your watch. We'll use the buttons to set the current time. One button is for setting the hours and another button is for the minutes. + +### Set the hours +Let's make a way to set the hours for the watch. + +1. In **Input**, find an ``||input:on button pressed||`` an put it somewhere on the workspace. +2. Get an ``||logic:if then else||`` block from **Logic** and put it in the ``||input:on button pressed||``. +3. From the same **Logic** category, get a ``||logic:0 < 0||`` and relpace the `false` condition with it. +4. Change the left `0` in the condtion to the `hours` variable. Change `0` on the right to `23`. This limits our hour count to 23 hours. +5. In the ``||logic:then||`` section, put a ``||variables:change by||`` there. Select the `hours` variable name from the dropdown. +6. In the ``||logic:else||`` section, put a ``||variables:set to||`` there. Select the `hours` variable name from the dropdown and leave the `0`. + +```blocks +let hours = 0; +input.onButtonPressed(Button.A, () => { + if (hours < 23) { + hours += 1; + } else { + hours = 0; + } +}) +``` + +### Set the minutes + +Setting minutes is almost the same as setting hours but with just a few changes. +1. To make things easy, right click on ``||input:on button pressed||`` block and select the **Duplicate** option in the menu. This makes a copy of the original block. +2. In the new ``||input:on button pressed||``, change the button to `B`. +3. Change every variable name from `hours` to `minutes`. Change the `23` in the ``||logic:if||`` condition to ``59``. This is the limit of minutes we count. + +```blocks +let minutes = 0; +input.onButtonPressed(Button.B, () => { + if (minutes < 59) { + minutes += 1; + } else { + minutes = 0; + } +}) +``` + +### Select 24 hour or 12 hour time + +Time is shown in either 24 hour or 12 hour format. We'll use one more button to choose which format to show. Using the 12 hour format adds an 'AM' or 'PM' at the end. + +1. In **Input**, get an ``||input:on button pressed||`` an put it on the workspace. Change the button to `A+B`. +2. Grab a ``||variables:set to||``, put it in the block and change the variable to `ampm`. Put a ``||logic:not||`` from **Logic** in where the `0` is. +3. Pick up a `ampm` from **Variables** and connect it on the right of the ``||logic:not||``. This switches our 24 hour format to 12 hour and back. + +```blocks +let ampm = false; +input.onButtonPressed(Button.AB, () => { + ampm = !(ampm); +}) +``` + +## Make the timer tick + +A watch really has three parts: the display, settings, and timer. We need a way to make the minutes and hours count up at the right time. Let's code the timer. + +1. In **Basic**, get a ``||basic:forever||`` loop out to the workspace. +2. Also in **Basic**, take out a ``||basic:pause||`` an put it into the loop. Change the time from `100` to `60000`. The time is in milliseconds so we want to count each minute every 60000 milliseconds. +3. Below the ``||basic:pause||``, put a ``||logic:if then else||`` block. Change the condition in the ``||logic:if||`` to use a ``||logic:0 < 0||``. +4. Replace the `0` on the left with the `minutes` variable. Change the `0` on the right to `59`. +5. Put a ``||variables:change by||`` into the ``||logic:then||``. Change the variable to `minutes`. +6. Get a ``||variables:set to||`` and put it in the ``||logic:else||``. Again, change the variable to `minutes`. + +```blocks +let minutes = 0; +basic.forever(() => { + basic.pause(60000) + if (minutes < 59) { + minutes += 1; + } else { + minutes = 0; + } +}) +``` + +**Keep on coding...** + +1. Now, take another ``||logic:if then else||`` and put it just below the ``||variables:set to||`` inside the first ``||logic:else||``. +2. In the second ``||logic:if||``, put in a ``||logic:0 < 0||`` as the condition. Replace the left `0` with the `hours` variable. Change the right `0` to `23`. We count hours up to 23 until we go back to 0 (midnight). +3. Put a ``||variables:change by||`` into the second ``||logic:then||``. Change the variable to `hours`. +4. Get a ``||variables:set to||`` and put it in the second ``||logic:else||``. Again, change the variable to `hours`. Ok, the timer's ready to tick. + +```blocks +let minutes = 0 +let hours = 0 +basic.forever(() => { + basic.pause(60000) + if (minutes < 59) { + minutes += 1 + } else { + minutes = 0 + if (hours < 23) { + hours += 1 + } else { + hours = 0 + } + } +}) +``` + +## Shake and show...the time! + +We're going back to the display code we made earlier. We'll now make it show the real time! This step is going to be busy but we'll get it done. + +First, we have to code an adjustment for the hours number when we're using the 12 hour format. + +1. Find the ``||input:on shake||`` block we coded earlier. Pull out and drag to the trash the blocks inside. We're starting fresh. +2. Pull out a ``||variables:set to||`` an put it inside the ``||input:on shake||``. Change the variable to `adjust`. Change the `0` on the right to the `hours` variable. +3. Get a ``||logic:if then||`` and put it under the ``||variables:set to||``. Replace the condition with the `ampm ` variable. +4. Grab a ``||logic:if then else||`` and put it in the ``||logic:then||`` part of the first ``||logic:if then||``. Change the condition to ``||logic:0 < 0||``. Replace the `0` on the left with the `hours` variable. Change the `0` on the right to `12`. Switch the `<` to a `>`. +5. Go get another ``||variables:set to||`` and put it in the ``||logic:then||`` of the second ``||logic:if then else||``. Change the variable to `adjust`. In **Math** take a ``||math:0 - 0||`` and replace the `0` in the ``||variables:set to||``. Change the `0` on the left to the `hours` variable and the `0` on the right to `12`. +6. Take one more ``||logic:if then||`` and put it in the ``||logic:else||``. Change its condition to ``||logic:0 = 0||``. Put the `hours` variable in place of the `0` on the left. +7. Inside this last ``||logic:if then||`` place a ``||variables:set to||``. Change the variable name to `adjust` and set the value to `12`. + +```blocks +let hours = 0; +let adjust = 0; +let ampm = false; +input.onGesture(Gesture.Shake, () => { + adjust = hours; + if (ampm) { + if (hours > 12) { + adjust = hours - 12 + } else { + if (hours == 0) { + adjust = 12 + } + } + } +}) +``` + +**Keep on coding...** + +Now, we have to join up the hours and minutes to make text that will display on the watch. + +1. At the bottom of the ``||input:on shake||``, insert a ``||variables:set to||``. Change the variable name to `time`. Connect it to a ``||text:join||`` from **Text**. +2. Make 3 copies of this last ``||variables:set to||`` using the **Duplicate** option in the menu when you right click on the block. Put the copies underneath each other so that all 4 are stacked together. +3. In the first ``||variables:set to||``, replace the second `""` in the ``||text:join||`` with the `adjust` variable. +4. With the second copy, change the first `""` in the ``||text:join||`` to the variable `time`. Change the second string in the ``||text:join||`` to `":"`. +5. In the fourth copy, change the first `""` in the ``||text:join||`` to the variable `time`. Change the second string in the ``||text:join||`` to division operator from **Math**. Set the left `0` to the `minutes` variable and the right `0` to `10`. +6. In the fourth copy, change the first `""` in the ``||text:join||`` to the variable `time`. Change the second string in the ``||text:join||`` to a ``||Math:remainder of||`` in **Math**. Set the left `0` to the `minutes` variable and the right `0` to `10`. + +```blocks +let minutes = 0; +let hours = 0; +let adjust = 0; +let time = ""; +let ampm = false; +input.onGesture(Gesture.Shake, () => { + adjust = hours; + if (ampm) { + if (hours > 12) { + adjust = hours - 12; + } else { + if (hours == 0) { + adjust = 12; + } + } + } + time = "" + adjust; + time = time + ":"; + time = time + minutes / 10; + time = time + minutes % 10; +}) +``` + +**Keep on coding...** + +Ok, we're getting close to finishing now. Here we need to add the 'AM' or 'PM' if we are in 12 hour format. Then, finally, display the complete time string. + +1. Put an ``||logic:if then||`` block at the end of the ``||input:on shake||``. Replace the `true` condition with the variable `ampm`. +2. Insert a ``||logic:if then else||`` into this ``||logic:if then||``. Use a ``||logic:0 < 0||`` as the condition. Change the left `0` to the `hours` variable. Change the right `0` to `11`. Switch the `<` to a `>`. +3. Place a ``||variables:set to||`` in the ``||logic:then||``. Change the variable to `time` and attach a ``||text:join||``. Make the first part of the ``||text:join||`` be the variable `time` and the second part to the text `"PM"`. +4. Do the exact same thing as in the last step but put the ``||variables:set to||`` block in the ``||logic:else||`` underneath. Make the second part of the ``||text:join||`` be `"AM"` this time. +5. Finally, at the very bottom of ``||input:on shake||``, go get a ``||basic:show string||`` from **Basic** and put it there. Change the string `"Hello!"` to the `time` variable. + +```blocks +let minutes = 0; +let hours = 0; +let adjust = 0; +let time = ""; +let ampm = false; +input.onGesture(Gesture.Shake, () => { + adjust = hours; + if (ampm) { + if (hours > 12) { + adjust = hours - 12 + } else { + if (hours == 0) { + adjust = 12 + } + } + } + time = "" + adjust; + time = time + ":" + time = time + minutes / 10 + time = time + minutes % 10 + if (ampm) { + if (hours > 11) { + time = time + "PM" + } else { + time = time + "AM" + } + } + basic.showString(time) +}) +``` + +## Complete! + +Wow, so awesome! You've got your watch coded and ready to try. Go press the ``|Download|`` button and put your code on the @boardname@. When you shake it, it shows the current time. + +Right now, it's showing 24 hour format: hours go from `0` to `23` and back to `0`. Press the **A+B** buttons together to change to 12 hour format: hours go from `12` to `12` with `1` through `11` in between. It has either `"AM"` or `"PM"` at the end. + +To set it to the current time, you use the **A** and **B** buttons. The **A** button moves the current hour up by one each time it's pressed. The **B** button moves the minutes up by one every time it's pressed. + +Now that you can tell time on your @boardname@ who knows what you will accomplish next. Only, time will tell! \ No newline at end of file diff --git a/docs/projects/watch/timer.md b/docs/projects/watch/timer.md new file mode 100644 index 00000000..3f0b42ea --- /dev/null +++ b/docs/projects/watch/timer.md @@ -0,0 +1,110 @@ +# Countdown timer + +### ~avatar avatar + +Let's make a countdown timer and see the seconds tick by on your @boardname@ watch. + +### ~ + +## Duration: ~10 minutes + +## Make the time variable + +We need a variable to keep track of how many seconds are left on the watch. + +1. Go into **Basic** in the toolbox and pull an ``||basic:on start||`` on to the workspace. +2. Ok, in **Variables** click on `Make a Variable`. Name the variable as `seconds`. Drag out a ``||variables:set to||`` block and change the name with the dropdown to `seconds`. Place the variable into the ``||basic:on start||`` block. + +```blocks +let seconds = 0 +``` + +## Set the time with buttons +There has to be a way to set the time on your watch. We'll use the buttons to set the amount of time by adding both 10 seconds and single seconds. We'll use one button for adding `10` seconds and another button for adding just `1` second. + +### Set seconds by ten + +We'll use button `A` to add `10` seconds to our time count. The time count of `seconds` will increase by `10` each time the button is pressed. + +1. In **Input**, find an ``||input:on button pressed||`` an put it somewhere on the workspace. +2. Get an ``||logic:if then||`` block from **Logic** and put it in the ``||input:on button pressed||``. +3. From the same **Logic** category, get a ``||logic:0 < 0||`` and relpace the `false` condition with it. +4. Change the left `0` in the condtion to the `seconds` variable. Change `0` on the right to `50`. This limits time to just one minute. +5. In the ``||logic:then||`` section, put a ``||variables:change by||`` there. Select the `seconds` variable name from the dropdown and change the `0` on the right to `10'. +6. Add a ``||basic:show number||`` below the ``||variables:change by||``. Change the value to the `seconds` variable. Then, put a ``||basic:clear screen||`` under that. + +```blocks +let seconds = 0; +input.onButtonPressed(Button.A, () => { + if (seconds < 50) { + seconds += 1; + basic.showNumber(seconds) + basic.clearScreen() + } +}) +``` + +### Set seconds by one + +Now, we'll use the `B` button to add just `1` second the time count. The time count in `seconds` will only increase by `1` when this button is pressed. + +1. In **Input**, find an ``||input:on button pressed||`` an put it somewhere on the workspace. +2. Get an ``||logic:if then||`` block from **Logic** and put it in the ``||input:on button pressed||``. +3. From the same **Logic** category, get a ``||logic:0 < 0||`` and relpace the `false` condition with it. +4. Change the left `0` in the condtion to the `seconds` variable. Change `0` on the right to `60`. Again, this limits the time to just one minute. +5. In the ``||logic:then||`` section, put a ``||variables:change by||`` there. Select the `seconds` variable name from the dropdown. +6. Add a ``||basic:show number||`` below the ``||variables:change by||``. Change the value to the `seconds` variable. Then, put a ``||basic:clear screen||`` under that. + +```blocks +let seconds = 0; +input.onButtonPressed(Button.B, () => { + if (seconds < 60) { + seconds += 1; + basic.showNumber(seconds) + basic.clearScreen() + } +}) +``` + +## Shake off the time + +Ok, now we'll get the timer going and show how many seconds are left. This will happen when the watch is shaken! + +1. Get an ``||input:on shake||`` block and place it in the workspace. +2. Pull out a ``||loops:while||`` from **Loops** and put it in the ``||input:on shake||``. Replace the `true` condition with the ``||logic:0 < 0||`` conditon from **Logic**. Make the `<` go to `>`. Change the `0` on the left to the `seconds` variable. +3. Take out another ``||basic:show number||`` and put it inside the ``||loops:while||``. Change the `0` to the `seconds` variable. Put a ``||basic:pause||`` under that and set the time to `1000` milliseconds. This means our timer will count down by **1000** milliseconds, which is actually one second, each time through the loop. +4. To change the number of seconds left, get a ``||variables:change by||`` and place it below the ``||loops:pause||``. Find the ``||math:0 - 0||`` block in **Math** and put it in the ``||variables:change by||``. Set the `0` on the right of the minus to be a `1`. + +```blocks +let seconds = 0; +input.onGesture(Gesture.Shake, () => { + while (seconds > 0) { + basic.showNumber(seconds); + basic.pause(1000); + seconds -= 1; + } +}) +``` +## Be alarming! + +Add a few ``||basic:show icon||`` blocks at the bottom of the ``||loops:while||`` to make an alarm to show that the time is up! We have some diamonds and the 'X' symbol for ours right now. + +```blocks +let seconds = 0; +input.onGesture(Gesture.Shake, () => { + while (seconds > 0) { + basic.showNumber(seconds); + basic.pause(1000); + seconds -= 1; + } + basic.showIcon(IconNames.Diamond) + basic.showIcon(IconNames.SmallDiamond) + basic.showIcon(IconNames.No) +}) +``` + +## All Done! + +Nice! You've got your timer coded now. Go press the ``|Download|`` button and put your code on the @boardname@. When you shake it, it counts down from the time you have set. + +At first, there are zero seconds set. To add ten seconds to the count, press the **A** button. To increase the count by one second, press the **B** button. \ No newline at end of file