Skip to content

Here’s the link to the group assignment.

Key learnings

In the group assignment we compared 2 different architectures - Arduino and ESP32- and 2 different toolchains - Arduino IDE and PlatformIO.
As an extra, in my own work I also tested the Pico W board with both toolchains and also made it work with Rust. I also tried and failed to use a faulty ESP33-CAM module.
My main personal learnings are:
- Both platforms hide away some complexity, like dealing with boot loaders
- Using C++ as a high level language abstracts away the different instruction set of each board and make the code mostly shareable across architectures, with some minor pin changes
- Arduino IDE is the most beginner friendly. It links to plenty of examples and libraries and does a 2 pass on the code, which means that a referenced function can be declared later than it is used
- Despite the name, Arduino IDE is not just for Arduino’s and supported all the boards that we had
- PlatformIO as extension to VSCode is more convenient if you’re past the absolute beginner phase.
- Boards that speak directly to USB save you the trouble of connecting other modules like a FTDI one, and reduce the chance of something being wrong.
- Likewise, the Grove connector system make it very convenient to experiment with different sensors and actuators

Success

This worked out pretty well

Already described in the group page Arduino IDE Section

Failure

This didn’t work

This module has no USB connection but features a camera and a SD card slot, which is interesting for my final project.
I needed to connect a sparkfun 5V FTDI Basic to convert from USB to the UART connections this board uses.
Every time the programming failed.
Guided by Gemini AI, I debugged the connections, connected the FTDI board RX to TX to make sure I could see the echo and conclude the FTDI board was OK.
However when checking the 3.3V voltage pin, with a multimeter, on the ESP32, this was at 5V and it was concluded the voltage regulator was not working. Also it was concluded that the flickering LED is was seeing was another hint that the regulator was burned and leaking power to the led.

Success

This worked out pretty well

Nothing interesting to report here. I just replaced the Arduino with the Pico W board, changed the target to the new board and everything worked.

Success

This worked out pretty well

For PlatformIO on can use the Visual Studio Code which I already had installed.
This is a modern IDE with plenty of extensions. To install PlatformIO one has to go to View -> Extenstions and search for PlatformIO IDE and install it

Because most of the code of this platform is done in python, I had to install an additional package to have it working:

sudo apt install python3-venv

Once installed I loaded the blink example, but for some reason, despite having my user in the dialout group that should have permissions to access the serial port, it still didn’t work.
So I followed the installation instructions, copied some new udev rules and restarted udev

curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules

sudo service udev restart

And now I was able to successfully upload and run the blink example.

Danger

Here be dragons. And AI !
Not for the faint of heart.
This worked, but I will not be pursuing this further.

Once I had established the 2 working boards and main development environments, I wanted to try something new. Not being a fan of Python and having being reading a lot about Rust replacing C/C++ due to more advanced features and memory safety, I wanted to give it a shot.
Sadly, at this point the language is not directly supported by the previous toolchains and documentation about this is very sparse.
So I tried using AI to have something working.

I followed Gemini instructions to install Rust toolchain:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add thumbv6m-none-eabi

cargo install flip-link
cargo install elf2uf2-rs

It even suggested some sample blink code, which I asked it to help me upload.
What followed was a multi hour long session that always ran into some problem that I had to report back and try to fix.
I got tired of all the copying and pasting, and decide to try the CLI tool that can handle the fixing without me being just a copy-paste operator 😅
So I gave the following prompt:

create a rust project, that is meant to be uploaded to a Rasperry Pi Pico W, and it should just blink the internal LED.

It started cranking and solving problems on its own, with me just watching and approving installs and changes to the system.
Eventually the suggestions to fix the problem ran into a loop that I couldn’t get out of, so I gave up on Gemini altogether.

Not wanting to give up, I tried another AI - OpenAI’s codex.

I installed and run OpenAI’s codex:

npm install @openai/codex
npx @openai/codex

I then gave it the following prompt:

create a rust project, that is meant to be uploaded to a Rasperry Pi Pico W, and it should just blink the internal LED. The Pico W is currently connected. Once the program is ready, upload to it

What followed was another multi hour long session, with me approving (less) commands, but eventually reaching a working solution.
Interestingly when I pointed out that I had a blink example done with platformIO working with the board, the codex tool searched for it and used it as base to do further work. Impressive, I would say.
At some point there was a long loop where several experiments were done and codex tried to zoom in on the problem and finally after many interactions found the problem and concluded:

The key issue was linker layout: .boot2 had to be explicitly placed at 0x10000000. I added link-rp.x and wired it in via .cargo/config.toml, then rebuilt/flashed the GPIO16 Morse-style blink app.

All in all, I’m quite impressed at what these agents can achieve, specially in setting things up that are accessory to thing one is trying to achieve.

Studying the output produced, however, I think I’ll stick with the mainstream option, since it will be less of a pain fixing issues.
Another problem is that there aren’t many readily available libraries in Rust. It is possible to link to C/C++ libraries, through FFI (Foreign Function Interface), but this requires some setup and you loose Rust’s safety guarantees.

The final sample rust project is here

Pico W + PlatformIO + Sensors

Success

This worked out pretty well

Next I returned to PlatformIO, but impressed with the results of Codex, I decided to try another agent and see how far it went.
This time installed the debian package for OpenCode and gave it this prompt:

Build me a platformIO project to connect a Pico W, with a Groove shield and a Buzzer v1.2. Make the buzzer sound 440 Hz if possible.

I adjusted the Pin number and it was working.
To speed up development I also instructed it to upload directly to the board and removed myself from having to go to platformIO IDE and compiling and uploading, which it did.

Next I plugged in a sparkfun Ultrasonic distance sensor v2.0 and a Tower pro SG-5010 servo motor and asked it to map the measured distance to a sound and to an angle of the motor which it did.

Here’s the code:

#include <Arduino.h>
#include <Servo.h>
#include <Ultrasonic.h>

#define BUZZER_PIN 18
#define SERVO_PIN 16

Ultrasonic ultrasonic(20);
Servo servo;

void setup() {
    pinMode(BUZZER_PIN, OUTPUT);
    servo.attach(SERVO_PIN);
    Serial.begin(115200);
}

void loop() {
    long distance = ultrasonic.MeasureInCentimeters();
    Serial.println(distance);

    if (distance > 2 && distance < 400) {
        int frequency = map(distance, 2, 400, 2000, 200);
        tone(BUZZER_PIN, frequency);
        int angle = map(distance, 2, 400, 0, 180);
        servo.write(angle);
    } else {
        noTone(BUZZER_PIN);
    }
    delay(100);
}

Here is the full code of the project and the result can be seen here:


NuEval

Group assignment

  • Demonstrate and compare the toolchains and development workflows for available embedded architectures
  • Document your work to the group work page and reflect on your individual page what you learned

Individual assignment

  • Browse through the datasheet for a microcontroller
  • Write and test a program for an embedded system using a microcontroller to interact (with local input &/or output devices) and communicate (with remote wired or wireless connections)

Check list

  • [ ] Linked to the group assignment page
  • [ ] Browsed and documented some information from a microcontroller’s datasheet
  • [ ] Programmed a board to interact and communicate
  • [ ] Described the programming process(es) you used
  • [ ] Included your source code
  • [ ] Included ‘hero shot(s)’