usbxbm is a USB device / Python control script combo to transfer raw XBM image data over USB to a display connected to an ATmega328. The Python script converts images or video frames into XBM data and sends them via USB to the matching device. The device then reads the data and dumps it straight to its connected display. usbxbm itself is based on (and a showcase for) RUDY, adjusted as a standalone project.
See also hackaday.io project page.
The ATmega328 USB device currently supports two displays:
- the good old Nokia 5110 LCD connected via SPI
- the ubiquitous SSD1306 128x64 OLED connected via I2C
The latter one is specifically meant for the 4-pin version (VCC, GND, SCL, SDA) of it, but combining the code of both displays could adjust it for SPI as well, which would (presumably) increase the frame rate significantly.
On a side note, ST7789 based TFTs will generally work as well, but requires modifications to get all the pixels transferred and will have a pretty useless frame rate, so I decided to scrap that. Plus, as a color display, it kinda defeats the purpose and simplicity of XBM anyway. However, there's some incomplete code available in another branch.
The Python script supports several input sources to convert and send:
- any video input file supported by OpenCV, including animated GIFs
- a camera source supported by OpenCV
- a series of JPG images, for example a video split into individual frames
- simply one static image
In addition, some of these operation modes support features like
- looping the video, which is great for short animated GIFs
- adding delay between each frame to either slow down a low-frame-rate video, or create a slide show
- setting the threshold value when converting the source image to black and white pixels
Note that all instructions from here on forward are mainly valid for Linux.
As mentioned, usbxbm is built using the RUDY board, but since that's just a generic ATmega328 development board, using a regular ATmega328 microcontroller will do, too - just remember to add the V-USB wiring to it then. Other than that, you'll obviously need to connect a display to it.
| ATmega328 | LCD | Comment |
|---|---|---|
14 PB0 |
1 #RST |
Display reset |
16 PB2 |
2 CE |
SPI chip select |
15 PB1 |
3 D/#C |
Data / Command mode |
17 PB3 |
4 SDIN |
SPI data in |
19 PB5 |
5 SCK |
SPI clock |
7 VCC |
6 VCC |
Supply voltage |
8 / 22 GND |
7 LIGHT |
Backlight |
8 / 22 GND |
8 GND |
Ground |
| ATmega328 | OLED | Comment |
|---|---|---|
7 VCC |
1 VCC |
Supply voltage (3.3V) |
8 / 22 GND |
2 GND |
Ground |
28 SCL |
3 SCL |
I2C clock |
27 SDA |
4 SDA |
I2C Data |
(These should certainly be accompanied by a picture of this..)
Again, as this is using the RUDY board, the general build information for RUDY apply here. Summarized, you'll need the AVR GCC toolchain, AVRDUDE, and a programmer (by default USBasp is used).
If the toolchain is set up and all, you should be able to simply run make with the desired target to compile the firmware. While the device could support both displays at once, the build system is layed out to assume only one display will be used at the time. Therefore, the firmware will be built based on the display in use.
The firmware itself is inside the device/ directory, so enter it before you proceed.
$ make nokia5110
$ make ssd1306
Again, check the RUDY documentation for setting it all up. But essentially, you'll need a programmer, and if you're not using USBasp, adjust the AVRDUDE_FLAGS line in the Makefile for the one you are using.
Once the programmer is connected, just run make once more with the program target:
$ make program
That's it, if all went well and your display is properly hooked up, you should see the usbxbm splash screen on it.
If you connect the device via USB, your syslog should print something along the lines of this:
[663945.031111] usb 2-3.3: new low-speed USB device number 23 using xhci_hcd
[663945.126326] usb 2-3.3: New USB device found, idVendor=1209, idProduct=b00b, bcdDevice= 1.00
[663945.126332] usb 2-3.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[663945.126335] usb 2-3.3: Product: RUDY
[663945.126338] usb 2-3.3: Manufacturer: CrapLab
[663945.126341] usb 2-3.3: SerialNumber: usbxbm
Congrats, you're ready to go.
As the firmware implements a custom USB device, you most likely have to set up a udev rule for it in order to have access to it as a regular user. Once again, RUDY has the answer. Alternatively, you can use sudo, but setting up a udev rule is still the recommended way.
With the device connected, the Python script in the host/ directory will do the rest.
To play a video and send it to the USB device, run:
$ ./usbxbm.py -v /path/to/video.xyz
To open up a webcam and stream it to the device:
$ ./usbxbm.py -c
or, in case you have more than one camera attached, change the video id by passing it along:
$ ./usbxbm.py -c 2
To simply display one static image:
$ ./usbxbm.py -i /path/to/image.jpg
The full documentation of the usbxbm Python script can be found in the host directory README.