diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/8-gpio-pins.mdx b/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/8-gpio-pins.mdx new file mode 100644 index 00000000..03e0d1b2 --- /dev/null +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/8-gpio-pins.mdx @@ -0,0 +1,157 @@ +--- +title: Raspberry Pi GPIO Pins +sidebar: + attrs: + class: pi +--- + +**G**eneral **P**urpose **I**nput/**O**utput pins let your Raspberry Pi sense or control simple electronic components. Each pin can be configured as an input (to read a signal) or an output (to send a signal). + +SplashKit provides a variety of useful functionality and special data types to make it easier to work with the Raspberry Pi's GPIO pins. + +## Working with GPIO Pins + +### Pin Numbering + +SplashKit's GpioPin data type refers to the physical header numbers, shown in the pinout diagram in [Understandingthe GPIO Pins](/book/part-0-getting-started/2-computer-use/1-tour/3-2-setup-raspberry#understanding-the-gpio-pins). + +The [`GpioPin`](https://splashkit.io/api/types/#gpio-pin) table shows the code values for each pin on the left, and a description of the pin on the right. e.g. `GpioPin.Pin11` refers to "GPIO 17". + +The interactive [Raspberry Pi Pinout](https://pinout.xyz/) page is a useful resource if you want to learn more about the different GPIO pins. + +### Pin Modes + +GPIO pins need their "mode" (input/output) configured before using them in your code. You can set the input/output mode of a GPIO Pin using SplashKit's [`RaspiSetMode`](https://splashkit.io/api/raspberry/#raspi-set-mode) method. The second argument given to this method will use the values shown in the first two rows of the [`GpioPinMode`](https://splashkit.io/api/types/#gpio-pin-mode) table (`GpioPinMode.GpioInput` and `GpioPinMode.GpioOutput`). + +### Pull Resistors (Input Mode) + +When configuring a GPIO pin for **digital *input*** devices such as a push button, the input signal can “float” if nothing is connected (such as when a button is not pressed), which will cause unexpected behaviour in your program. To prevent this issue, you can use SplashKit's [`RaspiSetPullUpDown`](https://splashkit.io/api/raspberry/#raspi-set-pull-up-down) method to enable an internal pull‑up (default high) or pull‑down (default low) resistor. + +In the example below, the button pin has been configured to enable an internal pull‑down resistor using the `PullUpDown.PudDown` value from the [`PullUpDown`](https://splashkit.io/api/types/#pull-up-down) table. + +### Pin Values + +The GPIO pins use **digital** signals when writing to, or reading from, a GPIO pin. A digital signal is either low (0) or high (1). This connects with the [Machine Code](/book/part-0-getting-started/1-digital-realities/2-trailside/4-machine-code) ideas: the CPU ultimately deals in ones and zeroes, and GPIO lets you see and set those bits in the real world. + +:::caution[Digital "high" signal voltage] + +On the Raspberry Pi, a digital high signal is 3.3 volts. + +*Never feed 5 volts into a GPIO pin!* + +::: + +:::tip[SplashKit's Pin Values] + +When reading button inputs in the example below, the [`RaspiRead`](https://splashkit.io/api/raspberry/#raspi-read) method will return a [`GpioPinValue`](https://splashkit.io/api/types/#gpio-pin-value) of `GpioLow` (0) or `GpioHigh` (1). + +To convert these values into raw binary values (0 or 1) to use in calculations, you can use SplashKit's [`ToInt`](https://splashkit.io/api/raspberry/#to-int) method. +::: + +### The usual GPIO workflow + +Once you have wired up your circuit and connected it to the relevant GPIO pins: + +1. Start the pigpiod daemon in the shell if you have just rebooted. +2. In your code, call `RaspiInit` at the start. +3. Create `GpioPin` variables for each pin you want to use. +4. Set each pin’s mode (and pull for inputs) +5. Read or write as needed +6. Then call `RaspiCleanup` before the program exits. + +## GPIO "pre‑flight checklist" + +### 1. Hardware and wiring + +- Power to the Pi is off while you wire components (or just connect the voltage pin last). +- LED polarity is correct: long leg to GPIO via resistor, short leg to Ground (GND). +- A current‑limiting resistor (≈220–330 Ω) is in series with any LEDs. +- Buttons are wired between the chosen GPIO pin and 3.3 V or GND (match this to your pull‑up or pull‑down choice). +- Ground connection is solid (all components share a GND with the Pi). +- No 5V wire is touching a GPIO pin (GPIOs are 3.3 V tolerant only). + +### 2. Pin choices and naming + +- You know which physical header pins you are using (for example `GpioPin.Pin11`). +- You are not mixing physical pin numbers with Broadcom (BCM) numbers. + +### 3. System services + +- `pigpiod` is running (start it after a reboot): + + ```shell + sudo pigpiod + +## Example + +To get started with using the Raspberry functions to write and read GPIO pin values, you can use the following wiring diagram to connect an LED to Pin 11 and connect a button to Pin 13. + +:::note +You can check out [Step 2 - Initialise GPIO Pin](/book/part-1-instructions/1-sequence-and-data/1-tour/03-01-prepare-gpio-pins) from the guided activity for more information about setting up the button. +::: + +![Image showing wiring diagram using an LED and a button](./images/read-button-circuit.png) +
Image created with Fritzing
+ +The following program uses methods in the [Raspberry](https://splashkit.io/api/raspberry/) category of the SplashKit library to "write" data to Pin 11 (GPIO 17), and "read" data from Pin 13 (GPIO 27) on the Raspberry Pi (as shown in the wiring diagram above). + +```cs +using SplashKitSDK; +using static SplashKitSDK.SplashKit; + +// Initialise the GPIO system +RaspiInit(); + +// Define the LED pin (using physical Pin 11) +GpioPin ledPin = GpioPin.Pin11; +// Define the button pin (using physical Pin 13) +GpioPin buttonPin = GpioPin.Pin13; + +// Set the button pin to input mode +RaspiSetMode(buttonPin, GpioPinMode.GpioInput); +// Set the led pin to output mode +RaspiSetMode(ledPin, GpioPinMode.GpioOutput); + +// Set the button pin to use an internal pull-down resistor +RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + +// Reading 1 with button pressed +WriteLine("Press and hold your button down, then hit Enter to record the reading:"); +ReadLine(); // Wait for user to press Enter +GpioPinValue reading1 = RaspiRead(buttonPin); + +// Output of button being pressed +WriteLine("Button Gpio value: " + reading1); +RaspiWrite(ledPin, reading1); + +// Reading 2 with button released +WriteLine("Now release your button now so it is not pressed, then hit Enter:"); +ReadLine(); // Wait for another press +GpioPinValue reading2 = RaspiRead(buttonPin); + +// Output of button not being pressed +WriteLine("Button Gpio value: " + reading2); +RaspiWrite(ledPin, reading2); + +// Clean up the GPIO system +RaspiCleanup(); +``` + +## Activities + +Here are some lines from the code above. What do you think these lines of code do? + +1. `GpioPin ledPin = GpioPin.Pin11;` +2. `RaspiSetMode(ledPin, GpioPinMode.GpioOutput);` +3. `GpioPinValue reading1 = RaspiRead(buttonPin);` +4. `RaspiWrite(ledPin, reading1);` + +
+ Answers + +
diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/9-raspberry-gpio-methods.md b/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/9-raspberry-gpio-methods.md new file mode 100644 index 00000000..4ebebd38 --- /dev/null +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/9-raspberry-gpio-methods.md @@ -0,0 +1,97 @@ +--- +title: Raspberry methods to use +sidebar: + attrs: + class: pi +--- + +Interacting with the GPIO pins on a Raspberry Pi can be a fun way to explore how software and hardware interact. The following methods will give you a start building programs using your Raspberry Pi. + +To create programs that use the GPIO pins on your Raspberry Pi, you will need the following using directives: + +```cs +using SplashKitSDK; +using static SplashkitSDK.SplashKit; +``` + +The `using SplashKitSDK;` line allows you to create variables using SplashKit's data types, such as [`GpioPin`](https://splashkit.io/api/types/#gpio-pin) for your GPIO pins and [`GpioPinValue`](https://splashkit.io/api/types/#gpio-pin-value) for the values received from the GPIO pins. + +With the `using static SplashkitSDK.SplashKit;` line, you have access to the following methods to interact with the Raspberry Pi GPIO Pins: + +```cs +// Initialise the GPIO system +public static void RaspiInit(); + +// Set the Mode for a GPIO Pin on the Raspberry Pi +public static void RaspiSetMode(GpioPin pin, GpioPinMode mode); + +// Set the Pull up/down mode for a pin to set it's default state (down = 0 and up = 1) +public static void RaspiSetPullUpDown(GpioPin pin, PullUpDown pud); + +// Write data (0 or 1) to the Raspberry Pi GPIO pin +public static void RaspiWrite(GpioPin pin, GpioPinValue value); + +// Read data (0 or 1) from the Raspberry Pi GPIO pin +public static GpioPinValue RaspiRead(GpioPin pin); + +// Reset the GPIO system before exiting the program +public static void RaspiCleanup(); + +// Convert the "GpioPinValue" type to an integer +public static int ToInt(GpioPinValue value); + +// Delay - waiting for a number of milliseconds before continuing +public static void Delay(int milliseconds); +``` + +*What do the different arguments represent?* + +When you interact with the GPIO pins on your Raspberry Pi, it first needs to know which GPIO pin is being used, and how. This is done using the `RaspiSetMode` method. The `pin` argument determines which GPIO pin to set up, and the `mode` argument determines how it will be used, such as using `GpioPinMode.GpioOutput` to write data to a GPIO pin, or `GpioPinMode.GpioInput` to read data from a GPIO pin. + +The `RaspiWrite` method allows you to write data to a given GPIO pin, using the `pin` argument. The data written to the pin is determined by the `value` argument, which could be `GpioPinValue.GpioLow` (0), or `GpioPinValue.GpioHigh` (1). + +The `RaspiRead` method allows you to read data from a given GPIO pin, using the `pin` argument. The data read from the pin, which could be `GpioPinValue.GpioLow` (0), or `GpioPinValue.GpioHigh` (1), is returned when the method is called. + +## Example + +The following example reads whether the button connected to Pin 11 was pressed, and then turns the LED connected to Pin 13 "ON" if the button was pressed, and "OFF" if not pressed. + +```cs +using SplashKitSDK; +using static SplashKitSDK.SplashKit; + +// Initialise the GPIO system +RaspiInit(); + +// Define the button and LED pins +GpioPin buttonPin = GpioPin.Pin13; +GpioPin ledPin = GpioPin.Pin11; + +// Set the button pin to input mode, and the led pin to output mode +RaspiSetMode(buttonPin, GpioPinMode.GpioInput); +RaspiSetMode(ledPin, GpioPinMode.GpioOutput); + +// Set the button pin to use an internal pull-down resistor +RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + +// Button pressed +WriteLine("Press and hold your button down, then hit Enter to record the reading:"); +ReadLine(); // Wait for user to press Enter +GpioPinValue reading1 = RaspiRead(buttonPin); + +// Output result +WriteLine("Button Gpio value: " + reading1); +RaspiWrite(ledPin, reading1); + +// Button released +WriteLine("Now release your button now so it is not pressed, then hit Enter:"); +ReadLine(); // Wait for another press +GpioPinValue reading2 = RaspiRead(buttonPin); + +// Output result +WriteLine("Button Gpio value: " + reading2); +RaspiWrite(ledPin, reading2); + +// Clean up the GPIO system +RaspiCleanup(); +``` diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/images/read-button-circuit.png b/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/images/read-button-circuit.png new file mode 100644 index 00000000..c0558502 Binary files /dev/null and b/src/content/docs/book/part-1-instructions/1-sequence-and-data/0-panorama/images/read-button-circuit.png differ diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-00-button-press-counter.mdx b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-00-button-press-counter.mdx new file mode 100644 index 00000000..b1571b9b --- /dev/null +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-00-button-press-counter.mdx @@ -0,0 +1,107 @@ +--- +title: Button Press Counter +sidebar: + attrs: + class: pi +--- + +import { Accordion, AccordionItem } from "accessible-astro-components"; + +In this guided activity, you'll learn how you can use SplashKit to read a **digital** value from a GPIO pin on your Raspberry Pi, using a simple circuit with a push button. + +When you run the program, you will be prompted 3 times to press your button (or you can choose not to press it), and then hit Enter to record the value of the pin connected to the button. The pin value will then be converted to an integer to print the number of times the button was pressed. + +Here is an example of the terminal output for when the button is pressed only for readings 1 and 3: + +```txt +Welcome to the button press counter! + +You will be prompted to read the value of the button pin 3 times. +Press the button when prompted to increase the button counter. + +Button Press - Reading 1 +Press Enter to record the button reading: + +Button Press - Reading 2 +Press Enter to record the button reading: + +Button Press - Reading 3 +Press Enter to record the button reading: + +Results: + +Reading 1: 1 +Reading 2: 0 +Reading 3: 1 + +The button was pressed 2 times! +​ +``` + +--- + +For this activity, we'll be using a **tactile push button switch** (sometimes called a "momentary" push button switch) to provide input to the Raspberry Pi, as shown in the wiring diagram below: + +![Image showing circuit with push button connected to pin 13](./images/button-counter-circuit.png) +
Image created with Fritzing
+ +Here are the steps to create the circuit shown above: + +1. **Put the push button onto the breadboard:** + + Place the button across the center channel of the breadboard. + + :::note[Internal button connections] + The 4 pins on the button are connected internally into two sets. The image below shows each set of connected pins circled in red: + + ![Image showing circuit with push button connected to pin 13](./images/button-internal-connections.png) + ::: + +2. **Connect the power using the 3.3V GPIO pin:** + + Attach a jumper wire from one side of the button to the 3.3V pin. + *(This is the red wire connected to pin 1 in the diagram above.)* + +3. **Connect the button to the GPIO Pin:** + + Attach a jumper wire from the diagonally opposiste pin on the buttton to GPIO Pin 13. + *(This is the yellow wire connected to pin 13 in the diagram above.)* + +--- + +Once you have completed the circuit above, create a new folder, and a dotnet project called ButtonCounter on your Raspberry Pi computer. + +1. Open your terminal on your Raspberry Pi, and set up your project: + + ```zsh + # Move you your code projects folder + cd ~/Documents/Code # or cd /c/Users/andrew/Documents/Code + + # Create and move into a folder for the project + mkdir ButtonCounter + cd ButtonCounter + + # Create a blank dotnet project + dotnet new console + + # Add the SplashKit library + dotnet add package splashkit + + # Open in VS Code + code . + ``` + +2. Add the [using directives](/book/part-1-instructions/1-sequence-and-data/0-panorama/1-method-library) to access the SplashKit code and GPIO types: + + + + + At this point you should just have these two lines of code. + + ```csharp + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + ``` + + + diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-01-prepare-gpio-pins.mdx b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-01-prepare-gpio-pins.mdx new file mode 100644 index 00000000..30415e15 --- /dev/null +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-01-prepare-gpio-pins.mdx @@ -0,0 +1,94 @@ +--- +title: Step 2 - Initialise GPIO Pin +sidebar: + label: "- Initialise GPIO Pin" +--- + +import { Accordion, AccordionItem } from "accessible-astro-components"; + +The first step when writing a program to communicate with the Raspberry Pi GPIO Pins is to initialise the GPIO system, and set up the GPIO pins that will be used. + +1. To prepare the GPIO pins to be used, we need to initialise the GPIO system using SplashKit's [RaspiInit](https://splashkit.io/api/raspberry/#raspi-init) method. This method needs to be called before any other GPIO methods. + + + + + ```cs {3-5} + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + + // Initialise the GPIO system + RaspiInit(); + ``` + + + + +2. Next, you will need to set up the GPIO pin to use for reading the button inputs. + + - Create a variable for the "button pin" using SplashKit's [`GpioPin`](https://splashkit.io/api/types/#gpio-pin) data type, and assign it the value for pin 13 (which is `GpioPin.Pin13`). + - To set the button pin to **input** mode, call the `RaspiSetMode` method and pass it the variable you created for the button pin and the value for *input mode* (which is `GpioPinMode.GpioInput`). + - The last part of setting up the button pin is to ensure the button pin defaults to a digital low (0) value when the button is not pressed. + + You can do this by calling the `RaspiSetPullUpDown` method and passing it the button pin variable and the value to use an internally-connected pull-down resistor (which is `PullUpDown.PudDown`). + + :::note + *Using SplashKit's `RaspiSetPullUpDown` method, with `PullUpDown.PudDown` as the second argument, is equivalent to connecting a 10kΩ "pull-down" resistor between the button pin connected to GPIO pin 13 and a GND pin.* + ::: + + + + + ```cs {7-14} + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + + // Initialise the GPIO system + RaspiInit(); + + // Define the button pin (using physical Pin 13) + GpioPin buttonPin = GpioPin.Pin13; + + // Set the button pin to input mode + RaspiSetMode(buttonPin, GpioPinMode.GpioInput); + + // Set the button pin to use an internal pull-down resistor + RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + ``` + + + + +3. Before we get to reading the GPIO pin value for the button, it is important to ensure that the GPIO system is reset before exiting the program. + + At the end of your code, call `RaspiCleanup()` to clean up the GPIO memory. This method call should always be called at the end of your code when using the GPIO system. + + + + + ```cs {20-21} + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + + // Initialise the GPIO system + RaspiInit(); + + // Define the button pin (using physical Pin 13) + GpioPin buttonPin = GpioPin.Pin13; + + // Set the button pin to input mode + RaspiSetMode(buttonPin, GpioPinMode.GpioInput); + + // Set the button pin to use an internal pull-down resistor + RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + + // + // Button reading code will go here... + // + + // Clean up the GPIO system + RaspiCleanup(); + ``` + + + diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-02-read-gpio-pin.mdx b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-02-read-gpio-pin.mdx new file mode 100644 index 00000000..bd74e717 --- /dev/null +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-02-read-gpio-pin.mdx @@ -0,0 +1,113 @@ +--- +title: Step 3 - Read GPIO Pin Value +sidebar: + label: "- Read GPIO Pin Value" +--- + +import { Accordion, AccordionItem } from "accessible-astro-components"; + +Let's start by recording a single button press. This step will focus on the "Reading 1" sections of the output from the first page of this activity: + +```txt {6-8, 15-17} +Welcome to the button press counter! + +You will be prompted to read the value of the button pin 3 times. +Press the button when prompted to increase the button counter. + +Button Press - Reading 1 +Press Enter to record the button reading: + +Button Press - Reading 2 +Press Enter to record the button reading: + +Button Press - Reading 3 +Press Enter to record the button reading: + +Results: + +Reading 1: 1 +Reading 2: 0 +Reading 3: 1 + +The button was pressed 2 times! +​ +``` + +1. Start by creating a variable for the "button value", using SplashKit's [`GpioPinValue`](https://splashkit.io/api/types/#gpio-pin-value) data type. + +2. Now prompt the user to press the button for "Reading 1". + *Make sure to include a message telling the user to press Enter to record the button reading*. + +3. You can then call `ReadLine()` to pause the program and wait for the user to press Enter. After the program continues again, you will need to record the button pin value using the "button value" variable you just created above. + + Assign this variable with the result of calling the `RaspiRead` method with the "button pin" variable as the argument. + +4. The `RaspiRead` method returns a `GpioPinValue` type, rather than an integer of **0** or **1** as shown in the terminal output above. Therefore, you will need to convert this value to an integer using the `ToInt` method and store it in an integer variable. + +5. Lastly, add some code to print out the result of the button press. + + + + + ```cs {16-29} + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + + // Initialise the GPIO system + RaspiInit(); + + // Define the button pin (using physical Pin 13) + GpioPin buttonPin = GpioPin.Pin13; + + // Set the button pin to input mode + RaspiSetMode(buttonPin, GpioPinMode.GpioInput); + + // Set the button pin to use an internal pull-down resistor + RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + + // Define variable for reading button value + GpioPinValue buttonValue; + + // First button reading + WriteLine("Button Press - Reading 1:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading1 = ToInt(buttonValue); + + // Output results + WriteLine("Results:"); + WriteLine(); + WriteLine("Reading 1: " + reading1); + + // Clean up the GPIO system + RaspiCleanup(); + ``` + + + + +6. Compile and run your program: + + ```shell + dotnet run + ``` + + Check the output matches the highlighted lines above, and test what happens when the button is pressed and when it is not pressed. + + :::tip + Don't forget to [Start the “pigpiod” Daemon](/book/part-0-getting-started/3-building-programs/1-tour/4-led-blink/#start-the-pigpiod-daemon) if you haven't already. + + To start the `pigpiod` daemon, run the following command: + + ```shell + sudo pigpiod + ``` + + *The `pigpiod` daemon only needs to started "again" when you restart your Raspberry Pi.* + + ::: + + :::note[Button press not showing?] + The button reading will depend on whether the button is being pressed when you hit Enter. + ::: diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-03-multiple-readings.mdx b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-03-multiple-readings.mdx new file mode 100644 index 00000000..07b1140f --- /dev/null +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-03-multiple-readings.mdx @@ -0,0 +1,177 @@ +--- +title: Step 4 - Multiple Button presses +sidebar: + label: "- Multiple button presses" +--- + +import { Accordion, AccordionItem } from "accessible-astro-components"; + +Now that you've got the first button press working, you can add in the second and third button press readings. + +1. Add in the code to read the **second button press** using the same steps as you did for the first reading. + + ```txt {9-11, 18} + Welcome to the button press counter! + + You will be prompted to read the value of the button pin 3 times. + Press the button when prompted to increase the button counter. + + Button Press - Reading 1 + Press Enter to record the button reading: + + Button Press - Reading 2 + Press Enter to record the button reading: + + Button Press - Reading 3 + Press Enter to record the button reading: + + Results: + + Reading 1: 1 + Reading 2: 0 + Reading 3: 1 + + The button was pressed 2 times! + ​ + ``` + + :::tip + You can reuse the `buttonValue` variable you created in the last step. + ::: + + + + + ```cs {26-31,37} + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + + // Initialise the GPIO system + RaspiInit(); + + // Define the button pin (using physical Pin 13) + GpioPin buttonPin = GpioPin.Pin13; + + // Set the button pin to input mode + RaspiSetMode(buttonPin, GpioPinMode.GpioInput); + + // Set the button pin to use an internal pull-down resistor + RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + + // Define variable for reading button value + GpioPinValue buttonValue; + + // First button reading + WriteLine("Button Press - Reading 1:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading1 = ToInt(buttonValue); + + // Second button reading + WriteLine("Button Press - Reading 2:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading2 = ToInt(buttonValue); + + // Output results + WriteLine("Results:"); + WriteLine(); + WriteLine("Reading 1: " + reading1); + WriteLine("Reading 2: " + reading2); + + // Clean up the GPIO system + RaspiCleanup(); + ``` + + + + +2. Compile and run your program. Check that both button presses are working as expected. + +3. Add in the code to read the third button presses. + + ```txt {12-14, 19} + Welcome to the button press counter! + + You will be prompted to read the value of the button pin 3 times. + Press the button when prompted to increase the button counter. + + Button Press - Reading 1 + Press Enter to record the button reading: + + Button Press - Reading 2 + Press Enter to record the button reading: + + Button Press - Reading 3 + Press Enter to record the button reading: + + Results: + + Reading 1: 1 + Reading 2: 0 + Reading 3: 1 + + The button was pressed 2 times! + ​ + ``` + + + + + ```cs {33-38,45} + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + + // Initialise the GPIO system + RaspiInit(); + + // Define the button pin (using physical Pin 13) + GpioPin buttonPin = GpioPin.Pin13; + + // Set the button pin to input mode + RaspiSetMode(buttonPin, GpioPinMode.GpioInput); + + // Set the button pin to use an internal pull-down resistor + RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + + // Define variable for reading button value + GpioPinValue buttonValue; + + // First button reading + WriteLine("Button Press - Reading 1:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading1 = ToInt(buttonValue); + + // Second button reading + WriteLine("Button Press - Reading 2:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading2 = ToInt(buttonValue); + + // Third button reading + WriteLine("Button Press - Reading 3:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading3 = ToInt(buttonValue); + + // Output results + WriteLine("Results:"); + WriteLine(); + WriteLine("Reading 1: " + reading1); + WriteLine("Reading 2: " + reading2); + WriteLine("Reading 3: " + reading3); + + // Clean up the GPIO system + RaspiCleanup(); + ``` + + + + +4. Compile and run your program again. Check that all three button presses are working as expected. diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-04-count-presses.mdx b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-04-count-presses.mdx new file mode 100644 index 00000000..ba855846 --- /dev/null +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/03-04-count-presses.mdx @@ -0,0 +1,170 @@ +--- +title: Step 5 - Counting button presses +sidebar: + label: "- Counting button presses" +--- + +import { Accordion, AccordionItem } from "accessible-astro-components"; + +Now that you've got multiple button press readings, you will be able to calculate how many times the button was pressed. + +1. Calculate the *button press count* by storing the **sum** of the (integer) "reading" variables in a variable for the "count". + + + + + ```cs {48-49} + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + + // Initialise the GPIO system + RaspiInit(); + + // Define the button pin (using physical Pin 13) + GpioPin buttonPin = GpioPin.Pin13; + + // Set the button pin to input mode + RaspiSetMode(buttonPin, GpioPinMode.GpioInput); + + // Set the button pin to use an internal pull-down resistor + RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + + // Define variable for reading button value + GpioPinValue buttonValue; + + // First button reading + WriteLine("Button Press - Reading 1:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading1 = ToInt(buttonValue); + + // Second button reading + WriteLine("Button Press - Reading 2:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading2 = ToInt(buttonValue); + + // Third button reading + WriteLine("Button Press - Reading 3:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading3 = ToInt(buttonValue); + + // Output results + WriteLine("Results:"); + WriteLine(); + WriteLine("Reading 1: " + reading1); + WriteLine("Reading 2: " + reading2); + WriteLine("Reading 3: " + reading3); + + // Count the button presses + int count = reading1 + reading2 + reading3; + + // Clean up the GPIO system + RaspiCleanup(); + ``` + + + + +2. Finish off the program by adding the remaining outputs and testing that your terminal displays the expected output. + + ```txt {1-5, 20-22} + Welcome to the button press counter! + + You will be prompted to read the value of the button pin 3 times. + Press the button when prompted to increase the button counter. + + Button Press - Reading 1 + Press Enter to record the button reading: + + Button Press - Reading 2 + Press Enter to record the button reading: + + Button Press - Reading 3 + Press Enter to record the button reading: + + Results: + + Reading 1: 1 + Reading 2: 0 + Reading 3: 1 + + The button was pressed 2 times! + ​ + ``` + + + + + ```cs + using SplashKitSDK; + using static SplashKitSDK.SplashKit; + + // Initialise the GPIO system + RaspiInit(); + + // Define the button pin (using physical Pin 13) + GpioPin buttonPin = GpioPin.Pin13; + + // Set the button pin to input mode + RaspiSetMode(buttonPin, GpioPinMode.GpioInput); + + // Set the button pin to use an internal pull-down resistor + RaspiSetPullUpDown(buttonPin, PullUpDown.PudDown); + + // Define variable for reading button value + GpioPinValue buttonValue; + + WriteLine("Welcome to the button press counter!"); + WriteLine(); + WriteLine("You will be prompted to read the value of the button pin 3 times."); + WriteLine("Press the button when prompted to increase the button counter."); + WriteLine(); + + // First button reading + WriteLine("Button Press - Reading 1:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading1 = ToInt(buttonValue); + + // Second button reading + WriteLine("Button Press - Reading 2:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading2 = ToInt(buttonValue); + + // Third button reading + WriteLine("Button Press - Reading 3:"); + WriteLine("Press Enter to record the button reading."); + ReadLine(); // Wait for user to press Enter + buttonValue = RaspiRead(buttonPin); + int reading3 = ToInt(buttonValue); + + // Output results + WriteLine("Results:"); + WriteLine(); + WriteLine("Reading 1: " + reading1); + WriteLine("Reading 2: " + reading2); + WriteLine("Reading 3: " + reading3); + + // Count the button presses + int count = reading1 + reading2 + reading3; + + WriteLine(); + WriteLine("The button was pressed " + count + " times!"); + WriteLine(); + + // Clean up the GPIO system + RaspiCleanup(); + ``` + + + + +When you have this working you should feel confident that you can start working with Raspberry Pi GPIO programs to record pin value inputs for calculations. diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/images/button-counter-circuit.png b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/images/button-counter-circuit.png new file mode 100644 index 00000000..2d15594d Binary files /dev/null and b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/images/button-counter-circuit.png differ diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/images/button-internal-connections.png b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/images/button-internal-connections.png new file mode 100644 index 00000000..4a2394a6 Binary files /dev/null and b/src/content/docs/book/part-1-instructions/1-sequence-and-data/1-tour/images/button-internal-connections.png differ diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/3-explore/03-0-explore.mdx b/src/content/docs/book/part-1-instructions/1-sequence-and-data/3-explore/03-0-explore.mdx index d5b5da09..36809958 100644 --- a/src/content/docs/book/part-1-instructions/1-sequence-and-data/3-explore/03-0-explore.mdx +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/3-explore/03-0-explore.mdx @@ -8,3 +8,4 @@ Having explored this leg of the journey you are now approaching a rest stop and - A [saving targets calculator](/book/part-1-instructions/1-sequence-and-data/3-explore/03-1-calculator). - A [music player](/book/part-1-instructions/1-sequence-and-data/3-explore/03-2-media-player) to load and play audio. - [Draw a scene](/book/part-1-instructions/1-sequence-and-data/3-explore/03-3-drawing) using SplashKit graphics. +- A [Binary Converter](/book/part-1-instructions/1-sequence-and-data/3-explore/03-4-binary-converter/) using a physical button connected to a Raspberry Pi. diff --git a/src/content/docs/book/part-1-instructions/1-sequence-and-data/3-explore/03-4-binary-converter.md b/src/content/docs/book/part-1-instructions/1-sequence-and-data/3-explore/03-4-binary-converter.md new file mode 100644 index 00000000..0cdadebd --- /dev/null +++ b/src/content/docs/book/part-1-instructions/1-sequence-and-data/3-explore/03-4-binary-converter.md @@ -0,0 +1,74 @@ +--- +title: Binary Converter +sidebar: + attrs: + class: pi + label: " - Binary Converter" +--- + +For this task you can build on the ideas from the [Button Press Counter](/book/part-1-instructions/1-sequence-and-data/1-tour/03-00-button-press-counter) tour. You may also find it useful to read about [Raspberry Pi GPIO Pins](/book/part-1-instructions/1-sequence-and-data/0-panorama/8-gpio-pins) and [Raspberry methods to use](/book/part-1-instructions/1-sequence-and-data/0-panorama/9-raspberry-gpio-methods) for this task. + +--- + +Build a program that will calculate the decimal value using binary inputs from 4 sequential button presses. The final output should look similar to what is shown below (but with a different final decimal value). + +```txt +Welcome to the 4-bit Binary to Decimal (Integer) Converter! + +Press Enter to record the button reading for the Most Significant Bit: +Button Reading 1: 1 + +Press Enter to record the button reading for the next Bit: +Button Reading 2: 0 + +Press Enter to record the button reading for the next Bit: +Button Reading 3: 1 + +Press Enter to record the button reading for the Least Significant Bit: +Button Reading 4: 0 + +The binary value is: 1010 +The converted decimal value is: 10 +``` + +:::tip[Binary Addition Logic] + +In binary, each digit has a **weight**. + +The weight of each bit in a 4-digit binary number (from left to right): + +- **M**ost **S**ignificant **B**it (MSB): 2³ = **8** +- Next bit: weight = 2² = **4** +- Next bit: weight = 2¹ = **2** +- **L**east **S**ignificant **B**it (LSB): 2⁰ = **1** + +To calculate the decimal value from the 4 binary values, you need to multiply the bit value by the corresponding weight, and then add them together. + +![Image showing binary calculation for decimal value of 10](https://www.geeksforgeeks.org/wp-content/uploads/binary2decimal.png) +
Image from GeeksForGeeks
+ +::: + +:::note[How many push buttons?] + +You will only need a single push button for this activity, just like with the [Button Press Counter](/book/part-1-instructions/1-sequence-and-data/1-tour/03-00-button-press-counter) activity. + +You can try it with multiple buttons, but make sure you can build a program that is using a single button first. + +::: + +:::caution[Pigpio Daemon] + +If you see an error message in your terminal similar to the following: + +```shell +ERROR [default] Pigpio error: bad connect. +``` + +This means the Pigpio Daemon is not running. To start the `pigpiod` daemon, run the following command: + +```shell +sudo pigpiod +``` + +:::