STM32 Microcontrollers & Arduino

I love Arduinos as much as the next (nerdy) guy, but let’s face it, they are no powerhouses (DUE and ZERO excluded, but they discontinued the former.. go figure..).

The Atmel AVR series is 8-bit and its clock is ridiculously slow by today’s standards.

Sure, you can get it to do some things with impressive speed if you are willing to do some low-level programming but I myself do this as a hobby and thus don’t really want to deal with assembly-level code.

If only there was a fast and cheap microcontroller that was easy to program..

Enter the ST STM32F103C family of microcontrollers.

These little wonders are:

  • Friggin’ fast. 32bit ARM architecture running at 72MHz.
  • Very well equipped in the I/O department.. 2 x UARTs, 2 x SPI busses, 2 x I2C ports, etc.
  • Easy to program using the familiar Arduino IDE, thanks to the work done by the wonderful people at www.stm32duino.com
  • Dirt cheap. You can get an Arduino Nano – sized board for less than 3€ shipped.

It’s pretty easy to get started using these microcontrollers. All you have to do is buy a tiny board from Ebay. You will also need a USB to Serial adapter that works with 3.3V voltage levels (you probably already have one of those lying around already..).

These tiny boards are known as “Blue Pills” or “Red Pills”, according to the colour of the PCB. There are other variations as well, but the red and blue variants are the most commonplace. They have relatively minor differences.

This is the pinout for either one of them:

To get started, you have to connect your USB to serial port adapter to the STM32’s RX1, TX1 and GND pins. RX from USB adapter goes to TX1 (PA9 pin) and TX goes to RX1 (PA10 pin).

To make the Arduino IDE compatible with these boards, you have to download the necessary files from here: https://github.com/rogerclarkmelbourne/Arduino_STM32

You then unzip the libary to C:\users\\Documents\Arduino\hardware\ or C:\Program Files (x86)\Arduino\hardware\

At the time of this posting, IDE 1.8.0 (latest available edition) is properly supported. You will also need to install support for the Arduino DUE or ZERO from the Boards Manager, otherwise you will get a “/bin/arm-none-eabi-g++: no such file or directory” error.

If everything went fine, you should see in your IDE a number of new available boards:

You select “Generic STM32F103C series”, the 128k variant, 72MHz speed, and Serial upload method:

You are now ready to try your first code upload.

The classic test is the Blink sketch:


// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin PC13 as an output.
pinMode(PC13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
digitalWrite(PC13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(PC13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}

In case of the STM32 uCs, the only necessary modification is changing the pin number of the LED to one compatible with the Blue (or Red) Pill (PC13).

Pin numbers for this family of uCs are not just numbers like they are for the Arduino boards (like 1,2,3….,A1,A2,…) but are named as they are described in the uC’s datasheet (PC13, PC14, etc.).

The procedure for uploading code is a little different than the one for the Arduinos. The STM32s come with 2 built-in bootloaders. One of them boots from system memory and the other from program memory. These different bootloaders are selected by changing the position of the BOOT0 jumper. You set it to 1 to boot from system memory or to 0 to boot from program memory.

To upload our code, we do the following:

  1. Set ‘BOOT0‘ to 1. This way we will boot from system memory which contains a UART to flash uploader.
  2. Press the RESET button.
  3. In the Arduino IDE, choose ‘Upload‘. On the board, the blue LED will start to flash.

After the upload is completed, our sketch will start. We should see the blinking LED.

If we want our uploaded sketch to boot automatically after the next power-on/reset, we need to set ‘BOOT0‘ back to 0 (so that on next powerup we will boot from program memory).

That’s pretty much it. Your next step should be to go to STM32duino’s forum and check out the libraries that have already been ported to the STM32duino environment.

Troubleshooting

If your sketch fails to compile, giving you a “/bin/arm-none-eabi-g++: no such file or directory” error, make sure that you have installed support for the Arduino DUE or ZERO from the Boards Manager.

If you get an error on the IDE that it “Failed to erase memory”, that means that your STM32 chip is locked. No worries, all you have to do is go here and get ST’s Flash Loader Demonstrator utility. It will unlock the chip with minimum effort.

st_flash_loader_demonstrator_1

st_flash_loader_demonstrator_2

Blue Pill reference: http://wiki.stm32duino.com/index.php?title=Blue_Pill

Controlling an AK4490 DAC with an Arduino

These days I’m co-developing an AK4490 based DAC. The aim is to end up with a no-compromise dual mono design, one that would perform at the very least on par with my Buffalo III.

Of course, to do that one has to run the 4490s in software mode.

As a matter of fact, it is generally preferred to run a 4490 in software versus hardware mode, for several reasons.

To begin with, in software mode the 4490 supports DSD decoding. It goes as far as to support a “Volume Bypass” feature which bypasses most of the processing done on the DSD signal (a.k.a. “the ΔΣ modulator”), resulting in more pure sound. But of course we do lose the ability to do volume control in software.

Software mode also allows us to try out all of the supported SQ features, like the different “Sound Setting” modes.

At last but not least, we get digital hardware volume control.

This is the prototype that we designed, getting I2S input from an Amanero and being controlled by my custom STM32 controller (more on that in the near future).

I searched the Net for any ready-made code that would control the 4490, but I couldn’t find anything worthwhile, so I began virtually from scratch.

So, my Arduino code (a.k.a. “aKduino”) enables:

  • Controlling an AK4490 through the I2C bus.
  • Automatic switching between PCM and DSD. It does rely on getting a “DSD type signal” from our USB-to-I2S interface of choice. The 4490 by itself is not capable of determining whether its input is PCM or DSD.
  • Setting the volume (in 9 steps.. just to confirm that volume control does indeed work).
  • Selecting “Volume Bypass” for direct DSD processing.
  • Selecting the internal DSD filter’s cutoff frequency (50KHz or 150KHz).
  • Selecting one of the 4 available PCM filters.
  • Enabling or disabling the Super Slow filter.
  • Selecting one of the 3 available “Sound Quality” settings.
  • Displaying all of the registers’ settings (for troubleshooting purposes).

Software Requirements:

  • Nothing (for now)

Basic Hardware Requirements:

  • Any Arduino (*)

(*) I should note here that the AK4490’s datasheet states that all of its I/O pins are expecting 3.3V logic levels but there has been a large number of reported cases of 5V Arduinos working without problems. I’m too much of a coward to try that myself so I used level converters for my initial testing and eventually a custom STM32 board that uses 3.3V logic but you may want to try your luck with 5V logic levels. Just don’t blame me if your 4490 gets damaged in the process.

Currently the code is at v1.35: aKduino Code (343 downloads)

Here is the revision history:

v1.35 20/12/2016:

  • Code cleanup for first public release.

v1.33 19/12/2016:

  • Added full control of sound parameters through serial port.

v1.27 18/12/2016:

  • First functional version.
  • Automatic switching between PCM and DSD by monitoring DSDPIN.

Fixing startup issues with Arduino DUEs

If you’ve had a lot of Arduino DUEs go through your hands (or if you are just unlucky), chances are you’ve come across at least one that does not start-up properly.

The symptom is simple: you power up the Arduino but it doesn’t appear to “boot”. Your code simply doesn’t start running.

You might have noticed that resetting the board (by pressing the reset button) causes the board to start-up normally.

I had come across such a board a while back, and had thought to myself “cheap generic, probably faulty” and had just put it aside. At ~13€ it was no big loss.

A few days ago a fellow tinkerer (thank you Alex!) alerted me to a fix for this problem.

It appears that the problem was first spotted on Freetronics’ forum and was dealt with swiftly.

The problem occurs only on some DUE boards and is due to some undocumented behaviour of the ATSAM3X8E processor combined with the behaviour of some MOSFETS installed on the DUE boards. So its occurence is largely a matter of luck.

The fix is simple: you just solder a 10K resistor across the top of this mosfet:

DUE-Fix-culprit

This is a 10K 0805 resistor that is about to be soldered:

DUE-Fix-1

..and after soldering:

DUE-Fix-2

The discovery of the problem prompted a new revision of the reference design by the Arduino team.

This is what the Rev 2’s relevant part of the schematic looks like:

Arduino_DUE_Rev.2_sch

and the PCB:

Arduino_DUE_Rev.2

And this is what Rev 3 looks like:

Arduino_DUE_Rev.3_sch

Arduino_DUE_Rev.3

You will notice a new component, R99, plus the mosfet is now mounted vertically.

So, if you are shopping for a DUE, look for one with this mosfet mounted vertically, just to be on the safe side.

Universal Signal Isolator Shield: Rev. 1.2

Since there has been a lot of interest in my Isolator shield these past few months, I have been optimizing its design.

The result of this optimization is this PCB:
Rev.-1.2-pic
It’s called “the Rev. 1.2”.

Nothing major has changed. The pinouts are still the same, the major components are the same, the functionality is essentially the same.

The changes are as follows:

  • New SPI header. It just passes through the SPI signals, nothing more. It does not connect to anything on the board.
  • New SPI_CS header. Useful only if / when connecting SPI peripherals.
  • Reset button. Because you never know..
  • New circuitry for the POWER_RELAY header. It now uses a MOSFET and it includes a diode for the reverse current coming back from the relay’s coil.
  • Decoupling cap for the IR receiver. Not absolutely necessary, but good to have.
  • More decoupling for the DC_UNR input.
  • Ground planes. Lower Arduino noise, at least in theory.

Here is the updated parts placement:
USI-parts-placement-rev1.2

And this is the updated BoM:

USI Bill of Materials, Rev. 1.2
PCB Part Value Notes
U1 24LC256 SO-08 EEPROM chip
U2 Si8605 SOIC-16 I2C Isolator
U3 MCP23008 SO-18W 8 input/output port expander
U4 Si8642 QSOP-16 Serial port isolator
U5 ADUM1250 SOIC-8 I2C Isolator
Q1 BC856, BC808 or other equivalent PNP SOT-23 TFT backlight control
Q2 BC856, BC808 or other equivalent PNP SOT-23 port expander transistor
Q3 BC856, BC808 or other equivalent PNP SOT-23 port expander transistor
Q4 BC856, BC808 or other equivalent PNP SOT-23 port expander transistor
Q5 AO3400 or other equivalent N-Channel MOSFET SOT-23 power relay mosfet
B1 Bridge rectifier 1A DB107 DIP-4
C1 1000uF 16V
C2 100n 1206
C3 100n 1206
C4 100n 1206
C5 100n 1206
C6 100n 1206
C7 100n 1206
C8 100n 0805
C9 100n 0805
C10 100n 1206
C11 100n 1206
R1 8.2K 1206
R2 2K 1206 pull-up resistor (optional)
R3 2K 1206 pull-up resistor (optional)
R4 5.1K 1206
R5 5.1K 1206
R6 5.1K 1206
R7 2K 0805 pull-up resistor (optional)
R8 2K 0805 pull-up resistor (optional)
R9 8.2K 1206
R10 10K 1206
D1 1N9001 DO214BA
L1 Ferrite Bead, low DC resistance, 3216
L2 Ferrite Bead, low DC resistance, 3216
Reset PCB-mount momentary switch

Soon I will update the shield’s page with the new info.

New page: Universal Signal Isolator shield for the Arduino DUE

My Universal Signal Isolator shield now has its own page, complete with the board’s schematic and PCB.

USI_bare_slanted

I have tried to document the shield as best I could but feel free to comment if you see something that is not clear or is missing.

They’re here!

I’m talking about my new Universal Signal Isolator PCBs:

USI_bare_slanted USIs_bunch

IMG_0320_res

I built one to test it out and everything seems to be working as it should. Next step is a page for the project, with schematics, a BoM and build instructions.

It is compatible with the current versions of both the ArDAM1021 and TFT HiFiDuino projects.

For now you can find more info in this post.

 

Update: TFT HiFiDuino v2.13

I did a little work on the TFT HiFiDuino code, incorporating most of the enhancements I made to the ArDAM1021 code.

v2.13_1

v2.13_4

v2.13_2

v2.13_5

v2.13_3

v2.13_6

These are the enhancements:

  • Option of displaying white text & graphics on black background as well as the “original” look.
  • New encoder code (it requires a new library).

Plus a few minor bugfixes here and there.

The new version of the code is here (v2.13): TFT_HiFiDuino_v2.xx (1232 downloads) (Note: As always, the code on this page may not be the current one, i.e. there may be a newer version available. The latest version is always up at the project’s official page.)

I will also update the code’s official page with the new version of the code.

Soekris dam1021 ArDAM Project update

Three weeks back I released the first public alpha of the ArDAM code, stating that it was very very alpha. I was meaning every word of that sentence.

Since then, Soren has released the new firmware for the DAM and I have resumed work on the project. Today I am happy to release the first usable version of the code (v0.74):  ArDAM1021 Code (1032 downloads)

ArDAM1021-v0.74-2

Changes include but are not limited to:

  • Tons of bugfixes (volume control, source selection, etc etc).
  • Filter selection either by remote or via rotary encoder (in the settings).
  • Option of displaying white text & graphics on black background as well as the “original” look.
  • New encoder code (it requires a new library).

The download now also includes all the necessary fonts. Let me know what you think.

The project’s page will be edited later today.

Universal Signal Isolator shield for Arduino DUE & MEGA

A few years back I designed a little Arduino shield who’s main function was to provide electrical isolation between an Arduino and a DAC (specifically a TPA Buffalo III).

The years have passed and my needs have changed with the introduction of the dam1021 DAC and its serial interface. My first though was to design a new shield specific to the dam but then I said “why not design a universal isolator shield?”. It would provide electrical isolation for both I2C as well as serial signalling.

Thus was born the Universal Signal Isolator shield for Arduino DUE & MEGA:

v0.97_crop

OK, it does look a lot more complicated than my first shield but remember, you only need to solder in the parts that your DAC actually needs.

So, what does this thing do?

1) Electrical isolation of I2C signals, complete with support of 8 isolated inputs or outputs (via an MCP23008 IC). Three of the MCP’s pins are high current outputs (up to 100mA).

2) Electrical isolation of up to 2 serial ports (implemented with an Si8642).

3) Electrical isolation of the second I2C interface of the DUE (implemented with an ADUM1250).

4) Powered either by 5VDC, 8-15VDC (non-regulated) or 7-12VAC (includes support for on-board rectification and filtering).

5) Support of a 5VDC power relay (up to 100mA).

6) Header for connecting a Nextion display.

7) On-board EEPROM memory (24LC256).

8) And of course full compatibility with the previous shield (same pinouts for the encoders, IR, TFT, etc.).

I will release the Eagle files once I have confirmed that the shield works as expected (I’m waiting for the first (and hopefully last) batch of PCBs).