Arduino RP2040 Connect Nano Setup

This is to document the setup instructions for flashing an Arduino RP2040 Connect Nano from a RPi4 using the command line tool ‘picotool’ and the pico-sdk. Not only to publish but for my own reference 😀

As a side note, I am using a RPi4 as a host because I like the Linux interface and would prefer it for situations of CI and things that may come in future projects.

Helpful Links

Getting the tools

These are to be executed on the RPi4 over SSH:

  1. Install picotool
    • See here for instructions
    • Make sure that running ‘picotool’ doesn’t give you a ‘cannot be found’ sort of error.
  2. Get the pico-sdk
    • See here for instructions

Setting up the project

With the tools downloaded and installed we should be ready to get started creating our project directories.

mkdir blink
cd blink
touch blink.c
touch CMakeLists.txt
# Insert the data below into your CMakeLists.txt files with vim here
cp ~/pico/pico-examples/pico_sdk_import.cmake ./ 
mkdir build
cd build
cmake -D"PICO_BOARD=arduino_nano_rp2040_connect" ..

In CMakeLists.txt add:

cmake_minimum_required(VERSION 3.12)

include(pico_sdk_import.cmake)

project(blink)

pico_sdk_init()

add_executable(blink
    blink.c
)

pico_add_extra_outputs(blink)

target_link_libraries(blink pico_stdlib)

And in your blink.c file:

#include "pico/stdlib.h"
#include "pico/binary_info.h"

const uint LED_PIN = PICO_DEFAULT_LED_PIN;

int main() {

    bi_decl(bi_program_description("First Blink"));
    bi_decl(bi_1pin_with_name(LED_PIN, "On-board LED"));

    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    while (1) {
        gpio_put(LED_PIN, 0);
        sleep_ms(250);
        gpio_put(LED_PIN, 1);
        sleep_ms(1000);
    }
}

Now with both those files populated execute the following from your build directory:

make

After the program has been compiled you should see in your build folder a blink.uf2 file, this is what we will use for flashing the board.

Flashing the Board

Your board should be setup as follows:

Notice the wire on the RP2040 Nano Connect, when you press the reset button on the board this will put the board in a state that allows flashing.

Once you have pressed the reset and entered the flashing state the wire must be disconnected before flashing. Once disconnected run the following from your build folder:

sudo picotool load ./blink.uf2

Once this flashes you should be able to hit the reset button once again to reboot and run the code we just flashed to the board. If all went well the integrated LED on the board should now be flashing!

Paper Boy Progress Report #4

This week was busy preparing at work for the holiday break, but I still managed to get some things done on the game. The following are the changes for this week and I am very excited for the future of this game, it is getting to the point now where I almost feel comfortable sharing an APK here on the site for people to download and try. Thank you for checking in!

Change Log

  • Added Hand Break
    • Pull trigger to increase decay on slowdown
  • Added Sound, and Music
    • This will expand as we go it is a minimal implementation at this point
  • Added a room for the lobby
  • Added persistent game data for round saving across app restarts
  • Fixed mesh placement and spawning system
  • Fixed paper throw, you can now hit red targets

Paper Boy Progress Report #3

This week I would say we had a bit of a regression (Meshes), and a couple big moves forward. Thank you for coming to this progress report, please leave a comment with feedback/encouragement if you have it, and enjoy the update!

Change Log

  • Added a main menu
  • Added game modes
  • Added game results display in main menu
  • Added dampening function to bike movement speed to prevent motion sickness when bike stops
  • Changed house meshes
    • Reduced poly count on houses by importing a new unity asset set
    • Lower quality but definitely made a difference with frame rate
    • This also allowed us to dress up the scene a lot more, with hopes to procedurally generate the house surroundings in the future
  • Changed to a multi-scene work flow
    • In addition we reorganized code to allow for better future expansion (this still needs work)
  • Changed targets to a cube area as apposed to an orb

Demo

Paper Boy Progress Report #2

This weeks update was awesome! Huge milestone hit, WE GOT THE HEADSET CONNECTED TO THE BIKE! I didn’t have as much time this week to work on the app but getting the headset to connect to the bike was a huge win! Also this week I added an intro to the demo, along with overlaid narration to explain the changes.

Change Log

  • In-Game speed adjusted by real world bike cadence
  • Mirrored Houses to ‘fill-out’ the neighborhood
    • Increases immersion
  • Added a sound for the paper hitting the ground (not audible in the demo)

Lessons/Funny Story

  • This week I learned how to package our game into and APK and side load it onto our headset, this allowed me to use the Bluetooth device in the headset to connect to the bike.
  • The sound used for the paper hitting the ground is actually extracted from a very random YouTube video here.

Assets Used

Demo

Paper Boy Progress Report #1

This week marks a big change to the project started last weekend, see the previous post for more details on where we left off. Short recap, last week I got a bicycle to move forward across a blank plane. Along with this I created a goal for the user to throw an object into an orb, which triggered the goal to be moved.

Additions This Week

  • Added house meshes
  • Added road meshes
  • Added spawning system for roads and houses
  • Goals now
    • Fade in and out to better indicate as a goal
    • Go transparent when struck
    • Have different colors for different point counts
      • Red – 3 points
      • Yellow – 2 points
      • Green – 1 point

Lessons Learned

Building on this mechanic I learned a couple lessons about Unity’s execution flow and how things are spawned into the world.

  1. If there is an error in the console, don’t assume the things you see on screen are unrelated
    • I had errors in the console, but assumed the execution was only halted for part of game setup. Because of these assumptions I spent a lot of time debugging my logic when the problem was the script had halted at the location of the error preventing the logic I was debugging from ever being executed.
  2. Meshes and Renderers are tricky, don’t assume their coordinates or their bounding box coordinates are what you expect.
    • I wanted to spawn houses based on the left and right sides of the house on the X axis, I assumed I could get these positions by cycling through each meshes renderer and getting the left most x boundary. This turned out to be way difficult because coordinates are with respect to some origin, I still don’t fully understand why I couldn’t get this to work
    • I ended up using empty’s as children to the parent empty to mark left and right positions of the object.

Demo

There are clearly still some mesh and collision box issues but I am very happy with the progression here.

Next weekend I would like to add some sound to the game and do a better job of hiding the empty void surrounding the player with fog or something. Along, with this I would like to add a feature to have all of the goals for a house to be disabled when one of them is disabled from a hit.

Thank you for reading! See you next week!

First Multi-Weekend Game

This weekend I started a bigger project than what can be encapsulated in a single weekend, so I fully expect to be posting about this for at least the next 2 weekends of work (if holidays allow, if not I will continue work at some point).

The mechanics I am going to share from this weekend are just the start, with a few more this will be a bit more of a complete game.

Mechanic #1 “Inventory”

For the game I have in mind you must have an ‘inventory’, it only needs to contain a single type of item but must contain many of them. For this I used an integer to represent the number remaining in the inventory and a GameObject object in the class to hold a prefab for instantiation each time the inventory object is ‘grabbed’.

So in short:

  1. Player hovers over inventory cube
  2. Player tries to grab
  3. This instantiates an instance of the prefab used
  4. Player is forced to grab the instantiated prefab

In the demo you might ask, where is the inventory cube? The answer to this is that it is actually a flat large cube behind the players head to give the impression they are grabbing it from their back.

Mechanic #2 “Goal Throw Point”

In this game you are going to be pulling objects out of an inventory and throwing them at goal points, think of basket ball for this mechanic. I needed a way to signify a point the player was supposed to throw an object, for this I used a sphere that was see through. For bonus points I added the ability for this sphere to be randomly spawned after being hit with the prefab from mechanic #1 in the area represented by a cube.

Mechanic #3 “Scoreboard”

In previous small projects for the scoreboard I would simply add a public variable for the UI.Text object in a script attached to whatever object I wanted to control the score. In this one I needed something new, something that allowed me to have multiple ‘reporters’ for score. For this I decided to use events, thus each of the goals have ‘scored’ events and the inventory has a ‘grabbed’ event. This allows us to show the user how many of the prefabs they have left and how many shots they have scored.

In the demo below you will see this on the handle bars of the bike the user is placed behind.

Demo

Some explanation is needed here… In the beginning I am trying to show the score board and object count on the handlebars of the bicycle. Once I grab the first cube from behind my head the bike starts moving forward and I have to throw the cubes at the orbs. Once struck the orbs move to new locations for a new challenge.

Anyway, that is where I end the weekend, and start the work week. Thank you for reading 🙂

First Unity Game

This weekend I knew I needed to produce something of my own, and like the Echelon Bicycle Monitor I wanted it to be a standalone ‘thing’ — meaning that once the weekend was over I wanted to be ‘done’ with it. I quote done because nothing is ever done, well I guess until you say it is, so forget the quotes this is done :D.

As the title declares, this is a Unity Game, its not anything crazy, but it did force me to use a large set of tools that I haven’t touched in a while. Those tools are Blender, and the Unity Game Engine. This project serves as a warm up to get reacquainted with the tools in preparation for more ambitious projects.

Blender

I started with a tutorial on modelling a low poly car in blender, I just needed a prop to control in Unity, so why not a car? I followed this tutorial, and ended up with:

Low Poly Car Model

As with anything I am bound to explore more than necessary and I rather enjoyed modeling things in Blender, I desire to get more proficient with materials and shaders though. Shaders were outside of the scope of the goal for the weekend so I moved on with the bare minimum, though I did model more than the car (couldn’t help myself).

Construction Scene Models

Unity Engine

With the low poly car created it was time to start figuring out the control mechanisms in Unity using the Oculus Quest 2 headset. For this I followed this tutorial for the physics of the car controller. For the input though I had to refer to the Unity API for XR Controllers, which isn’t nearly as easy as the old ‘Input’ object I was used to for mouse and key board, but was doable. Ill only explain the input here as more than that would just be reiterating what is in the linked tutorials.

Unity Controller Code

First you have to get the controller, to do this I used the following code:

private void GetRightHand()
    {
        var rightHandDevices = new List<UnityEngine.XR.InputDevice>();
        UnityEngine.XR.InputDevices.GetDevicesAtXRNode(UnityEngine.XR.XRNode.RightHand, rightHandDevices);
        if (rightHandDevices.Count < 1) return;
        device = rightHandDevices[0];
    }

I call this once on ‘Start’ and in a check in ‘FixedUpdate’, the check is to ensure that if we don’t get the controller on game start we get it when it does finally connect.

Once we have the controller we need to get the trigger value, this code handles that:

// Get Accelerator Input
        device.TryGetFeatureValue(UnityEngine.XR.CommonUsages.trigger, out VerticalInput);

Left right control will be done with the joystick on the right hand with this code:

// Get Left Right Input
        device.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primary2DAxis, out joyStickValue);
        HorizontalInput = joyStickValue.x;

Finally, we need to get one button to handle resetting the cars position

device.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primaryButton, out bool reset);
        resetCarPosition = reset;

Unity Scene Setup

To get started with Unity XR setup I followed this tutorial. Once setup it is just moving assets around and getting a game scene setup which for me looks like this:

Low Poly Weekend Car Game Scene View

In the above photo you can see this black box with a car in it and a white track. On the plane infront of the user you can see the goal of the game and when you complete the challenge you are notified with ‘You Won’ on that same screen.

Conclusion

I am pretty sure this meets the criterion for a ‘game’ though it isn’t the most polished thing. I really enjoyed this process and though the number of options available when building games can feel overwhelming going into this process with a clear goal and limited expectations proved to make this a satisfying experience. The files for you to play this locally on your unity instance are below. Thank you for reading 🙂

Echelon Bike Monitor

Background

This weekend I set out to connect to my new Echelon Connect stationary exercise bike with an ESP8266 or ESP32 and display the stats on a small OLED. This turned out to be surprisingly easy thanks to the open source nature of things these days. Huge thanks to snowzach’s github where I found the details of how to connect to the bike using a ESP32 board that I didn’t have. But I did and do have a set of ESP32 Devkit V1 boards and a few SSD1306 Oled screens that would do the trick. Below are the details of what I did and the files that are related to it. Hope you enjoy!

Requirements

Main Components

Secondary Components

  • Soldering Iron
  • Hot Glue Gun (If using my basic case)
  • Micro USB Cable (for power)
  • Spare Wire

Setup

Schematic

Below you can see how the ESP32 Should be wired to the Oled screen.

To flash the firmware plug the ESP32 board into your computer and load the provided Arduino Firmware from my Github page in the Arduino editor. You will need to hold the button on the board labeled ‘en’ when the Arduino terminal shows it is trying to connect to the board.

Case

The case is all slip fitting, and to keep it shut put a dab of hot glue in a couple of corners before closing (be sure to flash the firmware before hand as the case will not allow for pressing of the chip enable button). The ESP32 Chip slips into the bottom square which holds it in place. On the top part it is important that the ‘lip’ of the opening is on the pin side of the SSD1306.

Conclusion and Results

This was a really simple setup and went way smoother with the help of SnowZachs research and code. I would like to remind all readers — this is the most basic setup possible to get the data from the bike, and the UI (at the time of this post) can be seen below.

‘Pow’ == Power

‘Res’ == Resistance

‘Cad’ == Cadence