Main Content

Just two weeks ago, the pico, a new microcontroller, the pico, was released by the Raspberry Pi Foundation, well known for the incredibly successful series of Raspberry Pi single-board computers. The new microcontroller uses a brand new chip, designed in-house, the RP2040. It has two 32-bit cores running by default at 125MHz. It has been criticised for not having Wifi or Bluetooth, and no hardware floating point math. But it has a very fast internal bus and powerful peripherals. It has been designed for makers and has very strong support: it was released with 6 detailed datasheets and a beginners guide book, which is available free of charge as pdf. Best of all, it is cheap at $4. I got 5 for under 30EUR including shipping.
As a test I wanted to see if any of my previous projects based on the Arduino Uno/Nano could benefit from a remake with this much more powerful board: After all it has 4x the bus width, 8x the clock frequency, 130x the RAM, and is more than a decade more modern. My choice fell on the Arbitrary waveform generator (AWG). With the Arduino, I managed to squeeze out 381ksps, since every sample update took 42 instruction cycles, mostly because updating a 32-bit phase counter takes a quadruple loop with an 8-bit CPU. My expectation was that it should be possible to improve this by a factor 8 just from clock speed and maybe another factor 2 because the new board is 32-bit. However, after reading selected parts of the 637-page datasheet of the new RP2040 chip, I realised it might update every single clock cycle. Just by initialising 2 peripherals, the DMA (Direct Memory Access) and the PIO (programmable Input/Output), an array can be cyclically streamed to the output pins.
Indeed, it works, and the increase in speed with the Arduino is more than a factor 300, from 381ksps to 125Msps. That is similar to serious lab-AWGs, which cost ~100EUR for budget models. There is no attempt here to provide a buffer or amplifier for the produced signal, it is beyond my skills and my equipment to come up with a buffer/amplifier beyond the 10MHz range. The produced signal is thus rather weak, with an output impedance of ~1kOhm, and a maximum current draw of ~1mA. Suggestions for a buffer/amplifier are welcome in the comments! There is no attempt either to provide a dedicated user interface in terms of a screen, buttons, rotary encoders etc. That adds cost and complexity. I found it is much more convenient and much more powerful to set the requested waveform in the micropython code itself!
For comparison, several instructables (e.g. here, here and here) describe how to make a function generator based on the dedicated AD9833 chip. This chip runs at 25Msps and can generate only 3 predefined waveforms: sine, triangle and square. The pico is 5x faster and can generate any possible wave that fits in an array, up to many thousands of points.

Required materials:

Raspberry pi pico microcontroller with male pin headers
1 5x7cm prototype board
2 20-pin female pin headers
23 resistors of identical value, near 2kOhm”

Link to article