element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi
  • Products
  • More
Raspberry Pi
Blog Pico: Using VS Code and the new Raspberry Pi Pico extension to develop an I2C driver application in C with the help of an AI LLM
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi to participate - click to join for free!
Featured Articles
Announcing Pi
Technical Specifications
Raspberry Pi FAQs
Win a Pi
GPIO Pinout
Raspberry Pi Wishlist
Comparison Chart
Quiz
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: BigG
  • Date Created: 25 Mar 2025 3:43 PM Date Created
  • Views 3867 views
  • Likes 10 likes
  • Comments 8 comments
Related
Recommended
  • RP2350
  • pico
  • pico c sdk
  • vscode

Pico: Using VS Code and the new Raspberry Pi Pico extension to develop an I2C driver application in C with the help of an AI LLM

BigG
BigG
25 Mar 2025
Pico: Using VS Code and the new Raspberry Pi Pico extension to develop an I2C driver application in C with the help of an AI LLM

Table of Contents

  • Introduction
  • Setup
  • Create a C application using an example
  • Developing a simple driver for the MCP23017 I2C chip using AI
    • Initial Arduino firmware
    • Switching to VS Code and the Pico SDK

Introduction

After many years of blood, sweat and tears I can finally say that I have figured out how to use Visual Studio Code to compile C/C++ code for embedded devices. I've almost always been a late starter, or a laggard when it comes to trying out new things and VS Code is no different. So, I'm rather happy with this achievement.

Mind you, things have got a heck of lot easier since the trail blazing days of Platform IO for Arduino (something I've still not used in anger). In fact, Raspberry Pi have jumped in too and have started to develop their own extension for the Raspberry Pi Pico (current version of this extension is 0.17.5.), which is the topic of this blog.

In this blog, I am just going to cover the basics and demonstrate just how easy it is to get set up and use VS Code for Pico C/C++ code development. I am also going to try something new by using an Artificial Intelligence derived Large Language model (or AI LLM) to generate the driver library for my project by just specifying the chip I wish to use and the platform where the code will be used.

In my case I simply used Google's Gemini AI tool and I must say, I was pleasantly surprised by the result.

Setup

Getting started with Rasberry Pi Pico-series

I'm using the official Raspberry Pi Pico Getting started document as my guide.

Chapter 2 covers the installation process for Visual Studio Code. I'm skipping that.

Chapter 3 is the interesting part. This covers how to install the Raspberry Pi Pico VS Code Extension and the required dependencies. This only takes a minute or two.

Now the fun can begin.

image

Create a C application using an example

What you may have noticed, if doing this for the first time, is that nothing much happened when you installed the extension. I discovered that the SDK only gets installed on your computer when you create your first project. To illustrate, I've captured the process on video.

The first video is has no audio and simply captures the steps taken to compile one of the Raspberry Pico examples. I've sped it up in parts but it should still give you an indication of the time taken to get your first hello work type application up and running.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

The second video demonstrates the flash process and also shows that the standard blink example works on a Pico W board without any code modification

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Developing a simple driver for the MCP23017 I2C chip using AI

The next part of this blog actually originated from me not reading the product manuals for the RP2350.

I wanted to see if I could expand my RP2040 capacitive sensing project by porting it across to RP2350. I had assumed this would be straightforward and so went straight into developing a custom prototype board for this.

image

The schematic and the PCB board design did not take long, and so I dived in further and ordered a couple of PCB's using a low cost PCBA service. A week later I had two base boards (minus the Pico dev boards) on my desk.

image

The reason for using the MCP23017 on this design was that I had run out of RP2350 GPIO's to drive some LED's (one for each touch pad).

image

Initial Arduino firmware

As the original RP2040 capacitance touch sensing software was all developed using the Arduino IDE I decided to start with this.

But I quickly discovered that the RP2350 could not be used with the official Arduino Core library for the RP2040. I had to use the alternative Raspberry Pi Pico Arduino core software from Earle F. Philhower, III.

This meant adapting different parts of my original code and this didn't too long, but it was fiddly through a bit of trial and error.

I still did not have any firmware for the MCP23017. Thankfully there was already two Arduino libraries (DFRobot and Adafruit) available for the MCP23017, but it was not immediately obvious which was the more suitable. This meant quite a bit of reading to figure out how it worked and plenty of trial and error testing.

Eventually, I had the DFRobot library working and I was able to blink the LED's on the PCB using a Pico W board. At least this proved that the board design for MCP23017 worked.

I was also able to use my original RP2040 software to detect when I touched any of the pads. Of course, with the RP2040 architecture the max number of touchpads I could use was 8 (4 for each PIO).

I then switched to the Pico 2 W (RP2350) dev board but I couldn't get the capacitance touch sensing to work.

After a fair bit of attempts I gave up and went to the Raspberry Pi forum to seek answers. It turns out that there's a hardware flaw found in the RP2350 chip. This is referenced as Errata-E9 (https://forums.raspberrypi.com/viewtopic.php?t=385560). So, I'm having to shelve this project for now.

Switching to VS Code and the Pico SDK

But the experience got me thinking.

Although I could not get touch pads to work using my Pico 2 W board, I wanted to play with the MCP23017 chip using something other than the Arduino IDE. There had to be a quick way to develop of my firmware, especially if I wanted to use the Pico SDK.

Then I remembered an Adafruit video I had seen on YouTube where they have been using Claude 3.7 to develop base level code for many of their new IC's. They were amazed by the speed at which you could generate some initial code.

So, I thought to give this a go just, but as I did not know anything about Claude 3.7 I decided to use Google's Gemini AI tool, as that is what I had available on my computer.

And this is what happened...

Within seconds of asking Gemini for code, I had a template driver that I could copy into a Pico C application.

Don't believe me... well I had captured my first time VS Code experience using the Pico SDK on video and here it is (apologies for poor audio quality and all the rambling, mumbling and plenty of ers n ums, but this was unscripted).

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

I was able to get just the right amount of code in a format that was compatible with the Pico SDK, and flash it onto my Pico 2 W in only a couple of minutes, having spent little to no time understanding how the MCP23017 worked - all I had was the Arduino experience and that took considerably longer.

And, here is the code:

// I2C Code Template as automatically generated by the official VS Code extension for Raspberry Pi Pico development
// This example will use I2C0 on GPIO8 (SDA) and GPIO9 (SCL) running at 400KHz.
// Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
// Code modified for the MCP23017 using functions automatically generated by Google Gemini AI tool


#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/uart.h"

#define I2C_PORT i2c0
#define I2C_SDA 0
#define I2C_SCL 1

// UART defines
// By default the stdout UART is `uart0`, so we will use the second one
#define UART_ID uart1
#define BAUD_RATE 115200

// Use pins 4 and 5 for UART1
// Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
#define UART_TX_PIN 4
#define UART_RX_PIN 5

// ********* Google's Gemini Code generated functions ***************

// I2C defines
#define I2C_PORT i2c0
#define MCP23017_ADDR 0x27 // Default address (A0, A1, A2 grounded)
#define MCP23017_IODIRA 0x00 // I/O direction register A
#define MCP23017_IODIRB 0x01 // I/O direction register B
#define MCP23017_GPIOA 0x12 // Port A register
#define MCP23017_GPIOB 0x13 // Port B register


// Function to write to MCP23017 register
void mcp23017_write_reg(uint8_t reg, uint8_t value) {
    uint8_t buf[] = {reg, value};
    i2c_write_blocking(I2C_PORT, MCP23017_ADDR, buf, 2, false);
}

// Function to read from MCP23017 register
uint8_t mcp23017_read_reg(uint8_t reg) {
    uint8_t value;
    i2c_write_blocking(I2C_PORT, MCP23017_ADDR, &reg, 1, true); // true to keep master control
    i2c_read_blocking(I2C_PORT, MCP23017_ADDR, &value, 1, false);
    return value;
}

// Function to initialize MCP23017
void mcp23017_init() {
    // Set all pins as outputs
    mcp23017_write_reg(MCP23017_IODIRA, 0x00);
    mcp23017_write_reg(MCP23017_IODIRB, 0x00);
}

// Function to set a pin's output state
void mcp23017_set_pin(uint8_t pin, bool state) {
    uint8_t port;
    uint8_t reg;
    uint8_t bit;

    if (pin < 8) {
        port = MCP23017_GPIOA;
        bit = pin;
    } else {
        port = MCP23017_GPIOB;
        bit = pin - 8;
    }

    uint8_t current_state = mcp23017_read_reg(port);
    if (state) {
        current_state |= (1 << bit);
    } else {
        current_state &= ~(1 << bit);
    }
    mcp23017_write_reg(port, current_state);
}

// ********* End of  Google's Gemini Code generated functions ***************


int main()
{
    stdio_init_all();

    // I2C Initialisation. Using it at 400Khz.
    i2c_init(I2C_PORT, 400*1000);
    
    gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
    gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
    gpio_pull_up(I2C_SDA);
    gpio_pull_up(I2C_SCL);

    // For more examples of I2C use see https://github.com/raspberrypi/pico-examples/tree/master/i2c

    // Initialize MCP23017
    mcp23017_init();

    // Set up our UART
    uart_init(UART_ID, BAUD_RATE);
    // Set the TX and RX pins by using the function select on the GPIO
    // Set datasheet for more information on function select
    gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
    
    // Use some the various UART functions to send out data
    // In a default system, printf will also output via the default UART
    
    // Send out a string, with CR/LF conversions
    uart_puts(UART_ID, " Hello, UART!\n");
    
    // For more examples of UART use see https://github.com/raspberrypi/pico-examples/tree/master/uart

    while (true) {
        printf("Hello, let's set pin 10 (Port B, bit 2) high!\n");
        // Example: Set pin 10 (Port B, bit 2) high, then low
        mcp23017_set_pin(3, false);
        mcp23017_set_pin(10, true);
        sleep_ms(1000);
        printf("Now, setting pin 3 (Port A, bit 3) high!\n");
        mcp23017_set_pin(10, false);
        mcp23017_set_pin(3, true);
        sleep_ms(1000);

    }
}

And here is another video showing it working on the custom PCB:

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

  • Sign in to reply
  • shabaz
    shabaz 5 months ago in reply to BigG

    I suspect that will work extremely well! I'm using a Copilot extension, which is probably smilar-ish in the way it integrates with VS Code. Copilot also works with Jetbrains IDEs, but I've just noticed Gemini is now supported too.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • BigG
    BigG 5 months ago in reply to shabaz

    Thanks Shabaz. Yes, I'm pleased too that I event got this working, although not perfect. I noticed a little incompatibility warning when I added the NRF Connect extension. Based on Raspberry Pi's documentation, setting up a VS Code profile helps in these cases.

    I just discovered, only this morning, that Google Gemini actually has its own VS Code extension. So, it's quickly becoming more embedded in the dev process. Aiming to try this out shortly.

    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • BigG
    BigG 5 months ago in reply to ralphjy

    There's no rush, IMHO. The way I see AI tools at the moment, is that they often give you an incorrect answer in a convincing well structured format. These tools know no better. A bit like the saying "there's nothing more dangerous than knowing a bit about something and being confident that your answers correct".

    But things are moving fast in the space, so it can only get better. I see Google has just released a new version of Gemini, as of yesterday... Nice timing Grinning

    https://blog.google/technology/google-deepmind/gemini-model-thinking-updates-march-2025/

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • BigG
    BigG 5 months ago in reply to robogary

    Thanks. That's what I keep telling myself too Grinning

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB 5 months ago

    Well done, thanks.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube