Saturday, 18 December 2021

Dimming an RGB lightstrip using a Tiny2040 (Pi Pico)

 This is just a simple experimental project to try out Pimoroni's Tiny2040 for the first time.



In order to dim LEDs we have to use PWM; change the duty cycle of a square wave. The 2040 chip handles this and so this program is really simple, it just sets up PWM on one pin and handles two inputs, one for brighter, one for dimmer. 

The harder part was controlling 12v LED strip using a 3.3v output. I've used a small transistor to amplify to 5V and then a mosfet to step that up to 12v. A 7805 gives us a 5v supply to power the microcontroller and to use in the amplification circuit.

It would be possible to generate three square waves with independent duty cycles, and thus have smooth colour changing with the RGB LEDs.

Friday, 17 December 2021

PicoTerm, terminal application for Raspberry Pi Pico, supported escape codes and user-definable characters

PicoTerm is an application for the Pi Pico which provides a serial terminal with VGA output and USB keyboard input.


It was developed for the RC2014 and therefore is configured for that computer; eg 115,200 baud and the RC2014 logo at startup. However, if you'd like a custom version, please get in touch.

The Pico has resources that allow for a 640*480 output with a character mode, or 320x240 with full  32,000 colour.

I've recently added support for uploading user-defined character data. I've made this page in order to document the escape codes currently supported, along with information about the new UD character functionality.

Here is the list of supported escape codes, followed by the information about defining characters.

  • \ESC[?25l | Cursor invisible
  • \ESC[?25h | Cursor visible
  • \ESC[H | Move to 0-0
  • \ESC[s | Save the cursor position
  • \ESC[u | Move cursor to previously saved position
  • \ESC[-Row-;-Col-H | Move to -Row-,-Col-
  • \ESC[0K | Clear from cursor to the end of the line
  • \ESC[1K | Clear from the beginning of the current line to the cursor
  • \ESC[2K | Clear the whole line
  • \ESC[2J | Clear the screen and move the cursor to 0-0
  • \ESC[-n-A | Move the cursor up -n- lines
  • \ESC[-n-B | Move the cursor down -n- lines
  • \ESC[-n-C | Move the cursor forward -n- characters
  • \ESC[-n-D | Move the cursor backward -n- characters
  • \ESC[0m | normal text (should also set foreground & background colours to normal)
  • \ESC[7m | reverse text
  • \ESC[0J | clear screen from cursor
  • \ESC[1J | clear screen to cursor
  • \ESC[3J | same as \ESC[2J
  • \ESC[nS | scroll whole page up by n rows (default 1 if n missing)

40 col colour only: (sequence is ignored, no effect in 80 col b/w)

  • \ESC[38;5-n-m | Set foreground colour to -n- (0-255)
  • \ESC[48;5;-n-m | Set background colour to -n- (0-255)
  • \ESC[38;2;r;g;bm | Set foreground colour to r/g/b (values 0-255, scaled by picoterm to 0-31 to give 32,000 colours)
  • \ESC[48;2;r;g;bm | Set background colour to r/g/b (values 0-255, scaled by picoterm to 0-31 to give 32,000 colours)

User-definable characters

C/PM (which is widely used on the RC2014) uses 7-bit ascii characters, which means that there are 128 characters (128-255 inclusive) unused and available for defining by the user. In the case of the colourmode  version of Picoterm, the character data is simply stored as pixel data (foreground colour/background colour, 8 bytes per character) and drawn to the screen when needed, which means that the 'reverse graphics' doesn't rely on those reverse characters being defined, and therefore works on the default fixed characters and any that you define.

Note that this functionality is present in picoterm colour v0.2.0 onwards, which is available here.

  • \ESC[?-n-U | followed by 8 bytes, which will be inserted into the user-defined character space for character n (n can be 128-255 inclusive)

When displaying custom characters, the current foreground and background colours apply, these being reversed if reversed graphics is on.


Here is the simple basic program used in the screenshot above to display pacman: (yes, it's possible to use a loop to define the four characters, but beware of MS Basic's tendency to add a space when using STR$. It's expanded here for readability.)

10 PRINT CHR$(27);"[?128U";

20 FOR C=1TO8

30 READ A

40 PRINT CHR$(A);

50 NEXT C


60 PRINT CHR$(27);"[?129U";

70 FOR C=1TO8

80 READ A

90 PRINT CHR$(A);

100 NEXT C


110 PRINT CHR$(27);"[?130U";

120 FOR C=1TO8

130 READ A

140 PRINT CHR$(A);

150 NEXT C


160 PRINT CHR$(27);"[?131U";

170 FOR C=1TO8

180 READ A

190 PRINT CHR$(A);

200 NEXT C


205 PRINT CHR$(27);"[38;5;11m";

210 PRINT CHR$(128);CHR$(129)

220 PRINT CHR$(130);CHR$(131)


230 END


1000 DATA 15,63,127,127,255,252,224,252

1010 DATA 0,192, 224,224,128,0,0,0

1020 DATA 255,127,127,63,15,0,0,0 

1030 DATA 128,224,224,192,0,0,0,0




Thursday, 9 December 2021

Inconsistent results with Integrity

 Running the existing release alongside a potential new release is a great sanity check to make sure that any new changes haven't had any undesirable effects on the results.

Today this happened (the new Integrity Pro and existing release are showing different results):

It was a head scratcher and I had to sort the sitemap tables and carefully compare them to find the differences.

The reason is that I'd put some A/B testing in place, there are a bunch of pages with differences and A or B in the querystring. It's in an area of the site I'd normally ignore for reasons, but didn't today.

Therefore, the list of pages may feature both the A version and the B version (because the url of the page is the unique key for Integrity). So those pages may be duplicated in the results, or maybe not, and that's a matter of chance. 

Ignoring querystrings fixed the problem, and now gives consistent results every time. (Querystrings aren't used for any other reason on this site, so it's fine to ignore them).

Electronic Dice with the Pi Pico

This was my first project with the Pi Pico. It's a 'Hello World' for hardware/software.



The real reason for two buttons is that I already had the box drilled and fitted with the two buttons for a different project. It made sense to switch the power using an arcade button, because it's automatically switched off when you let go of it. The second button grounds the 'run' of the Pico, which means that it performs the shuffle and display once more. In reality, just the one power button would do, because letting go of that and pressing it again does the same thing as the 'run again' button.

I wrote the software in Micropython because this was my introduction to the Pico. More recent projects use C which suits me much better.


* That should probably be electronic die, because one die is shuffled and displayed. The pico has enough pins to shuffle and display 3 dice, and probably many more with a bit of logic to decode the binary numbers 0-6 (3 GPIO pins) to 7 LEDs.