Book Image

Creative DIY Microcontroller Projects with TinyGo and WebAssembly

By : Tobias Theel
Book Image

Creative DIY Microcontroller Projects with TinyGo and WebAssembly

By: Tobias Theel

Overview of this book

While often considered a fast and compact programming language, Go usually creates large executables that are difficult to run on low-memory or low-powered devices such as microcontrollers or IoT. TinyGo is a new compiler that allows developers to compile their programs for such low-powered devices. As TinyGo supports all the standard features of the Go programming language, you won't have to tweak the code to fit on the microcontroller. This book is a hands-on guide packed full of interesting DIY projects that will show you how to build embedded applications. You will learn how to program sensors and work with microcontrollers such as Arduino UNO and Arduino Nano IoT 33. The chapters that follow will show you how to develop multiple real-world embedded projects using a variety of popular devices such as LEDs, 7-segment displays, and timers. Next, you will progress to build interactive prototypes such as a traffic lights system, touchless hand wash timer, and more. As you advance, you'll create an IoT prototype of a weather alert system and display those alerts on the TinyGo WASM dashboard. Finally, you will build a home automation project that displays stats on the TinyGo WASM dashboard. By the end of this microcontroller book, you will be equipped with the skills you need to build real-world embedded projects using the power of TinyGo.
Table of Contents (13 chapters)

Lighting an LED when a button is pressed

Until now, we have only used code to directly control hardware components. Let's now try to read the state of a button in order to control an LED. We will need the following components:

  • At least 6 jumper wires
  • One LED (the color does not matter)
  • One 220 Ohm resistor
  • One 4-pinned-button (push down button)
  • One 10K Ohm resistor

Now let's go on to build the circuit.

Building the circuit

The following circuit extends the one we previously built. So, if you still have the previous circuit assembled, you just have to add the button part. The next circuit consists of two component groups. The first group is used to control an LED, and the second group is used to read the button state.

Adding the LED component

We start off with the LED circuit:

  1. Place an LED with the cathode in G12 and the anode in G13.
  2. Use a 220 Ohm resistor to connect F13 with D13.
  3. Connect port D13 from the GPIO ports with A13 using a jumper wire.
  4. Connect F12 with the ground lane of the power bus using a jumper wire.

Adding the button component

Now we are going to add a button:

  1. Use a jumper wire to connect A31 with the positive lane of the power bus.
  2. Use a 10K Ohm resistor to connect the ground lane of the power bus with B29.
  3. Connect D29 with port D2.
  4. Place the push button with one pin in E29, one in E31, one in F29, and the last pin in F31.

Our circuit should now look similar to the following:

Figure 2.4 – The circuit – image taken from Fritzing

Figure 2.4 – The circuit – image taken from Fritzing


Before we start to write the code for this circuit, we need to learn how these buttons work.

As the button will not work if you place it incorrectly onto the breadboard, let's have a look at the button again.

The 4 pins on the button are grouped into two pins each. So, two pins are connected to each other. Looking at the back of the button, we should be able to see that two opposing pins are connected to each other. So, the button won't work as expected when you place it rotated by 90°.

Programming the logic

Before diving into the code, we will create a new folder named light-button inside the Chapter02 folder and create a main.go file in it, with an empty main function, using the following:

Figure 2.5 – The folder structure for the logic

Figure 2.5 – The folder structure for the logic

Let's now look at the main function and the pull-up resistor.

The main function

We want to light the LED when the button is pressed. To achieve this, we need to read from a pin and check for its state using the following steps:

  1. Initialize the outPutConfig variable with PinConfig in PinOutput mode. This config is going to be used to control the LED pin:
    outputConfig := machine.PinConfig{Mode: machine.
  2. Initialize the inputConfig variable with PinConfig in PinInput mode. This config is being used for the pin that reads the button state and therefore needs to be an input:
    inputConfig := machine.PinConfig{Mode: machine.PinInput}
  3. Initialize the led variable with a value of machine.D13, which is the pin we have connected to led:
    led := machine.D13
  4. Configure led as output by passing outputConfig as the parameter, which is the pin that is connected to the button:
  5. Initialize the buttonInput variable with a value of machine.D2:
    buttonInput := machine.D2
  6. Configure buttonInput as an input by passing inputConfig as the parameter:
  7. As we do not want the program to be terminated after checking the button state a single time, we use an endless loop to repeat and check forever:
    for {
  8. Check the current state of the button. It will be true if the button is pressed:
      if buttonInput.Get() {
  9. If the button is pressed, we light up the LED:
  10. We are calling continue here, so we do not execute the led.Low() call:
  11. If the button is not pressed, we turn the LED off:


    Do not forget to import the machine package, otherwise the code will not compile.

Now flash the program using the tinygo flash command:

tinygo flash –target=arduino Chapter02/light-button/main.go

After successfully flashing, the LED should light up when you press the button.

The pull-up resistor

You may have wondered why we need a 10K Ohm resistor in the button circuit. The 10K Ohm resistor is used to prevent the signal/pin from floating. Floating pins are bad, as an input pin in a floating state is indeterminate. When trying to read a value from a pin, we expect to get a digital value – 1 or 0, or true or false. Floating means that the value can change rapidly between 1 and 0, which happens without pull-up or pull-down resistors. Here's some further reading on floating pins:

As an alternative to the 10K Ohm external resistor, an internal resistor can be used.

Configuring an input pin to use an internal resistor is done as follows:

inputConfig := machine.PinConfig{
               Mode: machine.PinInputPullup

We have now learned how to control an LED using an input signal, which was given by a button. The next step is to build the traffic lights flow to control three LEDs.