Abusing DMA for fun and LEDs

This blog post assumes you know the basics of multiplexing and how an LED matrix works. The end result looks like this:

Let’s say you want to control an LED matrix. A plain boring 8*8 LED matrix you bought on Ebay a long time ago and is still somewhere in your desk. It’s pretty simple, after figuring out how multiplexing works you’ll have a smiley drawn on the LED matrix in no time at all. But it’s much prettier if the brightness of an LED matrix can be controlled via PWM, maybe make some nice animations as well. For an 8*8 LED matrix, 8 PWM outputs would be needed and you are good to go, something a bigger microcontroller generally has available. But what if you want a bigger LED matrix, 16*16 perhaps. And animations running smoothly at a high frame rate.

For an 8*8 LED matrix, to make it look smoothly, you need to multiplex the screen at about 100 Hertz minimum. So set a column, wait a short time, switch to the next column and set the value for this column, wait a short time etc etc. With 100Hz there is 10ms of time per screen, so about 1.2ms (10ms / 8 columns) per column. More then plenty to set some IO pins to show an image. For a 16*16 LED matrix this time halves to 0.6ms. PWM makes this a bit harder, as a whole PWM cycle must fit in this 1.2 or 0.6ms, meaning the PWM peripheral must run at 833 or 1666Hz minimum. This is all no problem for a PWM peripheral in a modern microcontroller.

But what if you don’t have 8 or 16 PWM pins? For example, an Arduino Mega has 12 PWM pins. ARM M microcontrollers like the STM32F103 have more PWM pins, but those are shared with other peripherals as well, so they might not all be available to use in a project.

An option is to bitbang PWM, toggle an IO pin quick enough to act as an PWM pin. This has the major downside of costing a massive number of CPU cycles. To get just 6 bit PWM, so 64 different levels of brightness, in the 0.6ms for an 16*16 LED matrix, the CPU must check 64 times if that IO has to be set high or not. This means that every ~10us the CPU has to handle IO. If you also want to calculate some animation to display, the CPU will be very busy.

This is where the DMA comes in. The DMA, or Direct Memory Access, is a peripheral available in many modern microcontrollers. Simply said, it’s a co-processor that can copy data from one place in the microcontroller to a different place without the CPU having to do a thing. It can be used to transfer an ADC value to a buffer in RAM and give a sign to the CPU when the buffer is full. The microcontroller I’ve used for this blog, the STM32F103, can transfer memory to memory, peripheral to memory and memory to a peripheral without the CPU doing a thing apart from setting up the DMA. Transferring data to a peripheral without costing CPU cycles. That sounds like a nice way of driving an LED matrix.

Continue Reading


Numican, a small numitron clock

I wanted a numitron clock on my desk. As, in my opinion, a decent looking enclosure is one of the hardest things to make I made the clock in the size of an altoids can so just a few holes should be made for an enclosure that looks not too ugly. It’s almost fully in SMD and can be powered using a USB port, making it a lovely clock for almost every desk.

In the end I ordered a custom enclosure from Schaeffer in Germany for a nicer looking clock.

The build process, design files and such can be found on hackaday.io as I used the project to try out hackaday io and see if it worked for me.The link is: https://hackaday.io/project/18166-numican

 


Quick GUI for MBED projects, part 2

The previous post I explained the code for the dear ImGui part of the GUI. In this part the code for the serial connection will be discussed.

This code is made up of 2 parts, the MBED code and the PC side code. The MBED code will be discussed first. The MBED code uses the excellent MODSERIAL library. The MBED code after stripping away the initialization and such looks like this:

Continue Reading


Quick GUI for MBED projects using Dear ImGui and Serial

A lot of microcontroller projects communicate with a computer using a serial connection as this is still a very simple and cheap way of communicating. Making a program on the PC to communicate with a microcontroller can however be a bit tricky. On accident I stumbled on the Dear ImGui library, a C++ library to quickly make a GUI, for debugging a C++ project for example. I really liked the look of it, it looked really simple, with a lot of usable gui objects. Dear ImGui can use OpenGL, DirectX, Vulcan and more. It is cross platform as well, as long as OpenGL is used.

A gui is just half of the issues solved, a good library for serial communication is also needed. After a quick look Serial popped up. Except for the annoyingly generic name it is a very nice looking library. Cross platform and simple to use, being made to look and feel like PySerial.

With these two libraries it is possible to make a C++ cross platform GUI for all kinds of microcontroller projects. I decided to make a simple project first that can read and write to some IO ports, set the DAC and read in two ADC’s.

And the result looks like this:

Selection_009

Continue Reading


Ebay headphone amplifier kit

A while ago I bought the following headphone amp on Ebay as it looked like a nice small project. The included case and battery are also quite nice and the price was very affordable. A few weeks later the parts arrived in a very recognizable china envelope. In the package I found, exactly as pictured on Ebay, A nice looking PCB, a bunch of parts, a battery and a case. The first downside is the lack of documentation. There are no build instructions, making it a bit less nice for beginners.

All the values of the parts are printed on the PCB silkscreen and written on the parts whenever needed. So building it takes a bit of figuring out but is very doable. 2 issues arise fairly quickly though. The diodes have no anode or cathode marked on the PCB and the IC that is surrounded with diodes has the marking removed. I think it’s clear where this is going, I soldered all three diodes incorrectly and after correcting the IC got insanely hot in less then a second. Lovely.

WP_20160123_15_48_37_Raw_LI WP_20160123_15_09_23_Raw_LI

The rest of the PCB went OK to build, the parts are from a good quality brand and the PCB looks nice with the gold plating on it. The only issue where the diodes.

WP_20160124_13_20_41_Raw_LI

But now I’m stuck with a non working PCB as the IC that generates the voltages for the opamps is well, dead. After emailing the seller they couldn’t give me the schematic. So well, time to reverse engineer the schematic :)

Continue Reading


Tinycortex, part 3. Offline compiling

The MBED IDE is an online IDE, which is less pleasant if you want to work without internet or prefer your own editor. Luckily it is possible to export an MBED project and use an offline compiler. It can export to KEIL, GCC and a few others.

KEIL is a well known IDE now owned by ARM. They offer a free 32KB limited version and with the Tinycortex having 32KB of flash memory that limit is no issue. KEIL is Windows only and the unlimited version is quite expensive. A guide on exporting to KEIL can be found here. Because KEIL just works it’s the recommended way for offline compiling.

It is also possible to export to a GCC makefile which is especially nice for people using Linux or OS X.  An ARM compiler is required, the most used and free one being GCC ARM Embedded, which is being maintained by ARM employees. On a Linux system with make and the ARM compiler installed compiling the code is just typing “make” in the terminal. After a few seconds the output for the Blinkaled project you can find on my github is:
Selection_020

Sadly enough it’s not possible to just copy the generated .bin file on the tinycortex. With just the makefile the binary file isn’t checksummed. A small script in the “Tools” folder called checksum is used to checksum the file. Place it in the folder with the binary and run it with the command “./checksum filename.bin”. The checksum script is compiled for Linux, OS-X or Windows users need to recompile it using the command “gcc -o checksum checksum.c”.

Linux and OS-X users have to use the dd command to place the binary on the Tinycortex.


Tinycortex, part 2.

The last post described the dev board now called the Tinycortex. In this post I’m going to explain how to use it. All files can be found on the following github page. On this page you can find the hardware design files, a few scripts to make using them in Linux easier, a blink a led project that can be compiled offline and the pinout. The pinout of the Tinycortex is the following:

pinout

It has 32 IO pins, 3 UART, 2 SPI, 1 I2C and 8 analog inputs. It also has 1 LED and 1 button on the PCB for small tests and projects.

To use the Tinycortex in the MBED online compiler the MBED LPC11U24 can be selected. One header file needs to be included. It can be found on the github page or in the example blink a led project on the MBED website. After the header is added the pin names IC1 to IC33 and LED1 can be used in the code. Or you can import the blink a led example and modify that.

After compiling the MBED environment will generate a .bin file. To place this file on the Tinycortex connect it to the USB port with the ISP button pressed. Release the button after plugging it in and you should see a 32KB flash drive with one file, firmware.bin, on it. Remove this file and place the new .bin file on it. After that press the reset button (labeled RST) and the new code will be executed.


A tiny MBED compatible dev board

I like the MBED boards, they are small, fast and the libraries and community are great. The only downside is the price. The cheapest official MBED board is around 50 euro’s and some cheaper supported boards like the ST nucleo boards don’t fit in a breadboard. I wanted to make a small MBED compatible dev board that fits in my breadboard and costs a lot less then the real MBED boards so I can just leave them in a project without caring too much.

I decided to use the LPC11U24 as this is one of the two microcontrollers that is also used for the real MBED boards. I have had some bad experiences with the MBED libraries for the ST microcontrollers so I’ll stick to the well supported NXP one.  For the rest a SMPS 5V to 3.3V was something I’d wanted. A linear regulator would get a little bit too hot if more then 250mA of current would be requested from the 3.3V line. I also made everything SMD, including the pinheaders. It just feels a bit cleaner for me to have zero through hole parts :)

The end product looks like this and I shall call it: the Tinycortex, because I suck at making names:

WP_20150805_009

It is even a bit smaller then the real MBED, has 32 IO pins and looks cute. What more to wish for :)

In the next post I will show the pinout and how to use it in case anyone makes one and for the people I gave one as a reference.


Measurement gear

After building a few project and with some of them actually working, always a pleasant suprise, I though it was time to invest in some gear to measure the stuff I build. Just listening is only so good of an indication if a project works like it should. After some searching online I found a second hand Creative E-mu Tracker pre USB sound interface.

E-Mu_tracker_pre

Continue Reading


Weekend project, an oldschool preamp/headphone amp

My current power amplifier is very simple. It has 1 input, 1 output and 1 LED to show it’s on. Which was fine until I got a record player. This required me switching cables and without a volume control between the record player and the power amplifier the only volume I had was well, deafening. Time to build a small preamp with the following features:

  • 3 inputs, PC, record player and an extra one.
  • Volume control
  • Buffer build in so a headphone or low impedance amp can be connected.
  • 1 rca output to go to my power amp and 1 3.5mm output to connect a headphone, switch able.

I had almost everything laying around, a pre-build PCB for a headphone amp based on an LME49710 opamp and a LME49600, an enclosure that should just fit the components and a 2*12V transformer for powering the thing. Sadly enough the enclosure was just too small, the pre-build amplifier oscillated and got way too hot to be usable.

After a some cursing and a look in my random parts bin I found 2 OP07 opamps, precision opamps with specs more then good enough for a simple audio application. It’s a bit old and a bit slow compared to newer opamps but it should do the trick. I also found 2 perhaps older buffers. The burr brown 3329/03, now replaced by the, still manufactured OPA633 buffer. The specs are overkill compared to the OP07 but hey, 100mA output current, short circuit protected and a full power bandwidth response of 1Mhz. And that in 1988. The datasheet can be found here.

First step, breadboard it:

Breadboard1

Well, that worked, no oscillations but it does look like spaghetti, luckily I had a PCB breadboard from Adafruit laying around.

PCB1

PSB2

Well isn’t that much tidier :-)

To make this a pre amplifier some things still have to be added, an input selector, a volume potentiometer, an output switch and of course a power supply. Fast forward a weekend and it’s finished. And I again got reminded that I should order enclosures instead of doing it myself as everything is as straight as the gay parade :-(

WP_20150113_003

WP_20150113_005

WP_20150113_006

Ah well, at least I did a half decent cable job I’d say. The schematic is the one from the datasheet of the buffer, a simple non inverting opamp, in my case with a gain of about 4. Power supply is a simple 7812/7912 build. I was missing a few RCA plugs and will probably make a new back for it as the RCA plugs are way too close to each other. I still need to drill mounting holes for the PCB. The amplifier sounds nice and very clean and it has more than enough power for my 250 ohm headphones.

And an action show:

WP_20150115_003

Now time to finish my tube headphone amplifier and see what sound I prefer :-)


Pages:12