Xiao ESP32S3 Media Device Prototype

I use a lot of ESP32 modules in my projects, mainly because of the integrated WiFi and BT, but also due to their small size. There are however usually quite a few external components required, and sometimes, that can be a bit of a turn-off.

Having access to quite a few XIAO modules from SEEED studio, and with support for the ESP32S3 recently being added to ESPHome, my other goto for projects, I decided to create a simple prototype based on the SEEED XIAO ESP32S3. this module offers several attractive features, of which its small size is definitely a big plus. Add to that that it also has battery charging circuitry and quite a lot of flash memory, and it seemed like a winner…

Not that it doesn’t have issues of its own, the biggest being that you have to power it from 5v, and the absolutely super tiny flash and reset buttons.

Cost-wise, they are only slightly more expensive than the native ESP32 module, which, by the time you have added the external components, does not amount to any difference anymore.

I also wanted to test out some power-supply circuitry, so this seemed like a good project to combine those in as well.

What exactly is the project about?

It is a testbed for three(3) different things, with the first being the XIAO ESP32S3, with I2S sound as an ESPHome media device. That part, while working, is in my view not perfect yet, as ESPHome does not seem to be able to utilise the 8mb of PSRam available on the XIAO for use with the I2S Audio, yet anyway…

The second is having my, by now almost common, dc buck converter circuit directly on the PCB. I want to test that, in order to make sure that there are not too much noise being generated that could influence the ESP32S3, or, most importantly, the I2S module. A while ago, I built a custom I2S shield, and unfortunately, the power capabilities, or let’s be frank, the lack of sufficient power, turned that project into a big disappointment at any volume other than almost below 2%…

This will thus also serve as a way to revamp that idea, but with better power capabilities and more available current.

The third part is a direct result of the XIAO’s 5v power requirement. I reused my LM317G variable voltage circuit to provide power to the module. In my view, it would have been so much nicer if I could just supply 3v directly to the XIAO…

This also brings us to the battery charging capability. I would have loved to use that, but,
1) It seems that the battery voltage is internally stepped up to 5v and then back to 3.3v for the ESP32S3. comment anyone?
2) The available output (3.3v) does not provide a lot of current – surely not enough to drive an I2S module, does it? more comments, anyone?
3) I am unsure of any internal isolation in above mentioned charging circuit, thus, I was not willing to connect my own boost converter to the battery and use that to power external components…

So, until I get definite answers on these three, I won’t be bothering with powering the circuit from the battery… unless it is a big 12v one

So what is on the PCB?

3D Render of the PCB

As mentioned above, I had a few goals with this prototype. Let us take a quick look at the board and its components.

Starting bottom left, we have the DC input area. Here I chose to provide both a DC Barrel Jack, as well as a screw Terminal. Both can be used, but I believe the screw terminal will add a bit more flexibility in an actual installation inside an enclosure.

To the right of those, we have a 7-way header. This provides access to D7 to D10 on the XIAO, and, in my case, is labelled for use with the I2S module and a DHT11 sensor. ( you can of course use it for something else as well). The DHT11 header is on the far right in this picture.

At the centre-left, the components around U1 forms the DC-DC buck converter. This is set to supply 3.3v at a maximum current of 3A.

To the right of that, around TP1, is a jumper to that supplies the XIAO with 5v from U2 ( the LM317G ). It is important to note that you should leave this jumper disconnected at first power-up, and then adjust R9 while measuring between GND and TP1 to get a voltage of exactly 5v on TP1. This will prevent you from damaging the XIAO module. Once that is set, power down, and place a jumper on the center and right side pins. Make sure to NOT adjust R9 again with this jumper in place.

Center-right is the star of the board. The XIAO ESP32S3 Module ( marked U3)
Note the cutout for the USB-C connector at its top.

A reset button, marked RST, and two headers, one for I2C and another with additional GPIO pins completes the PCB.

Note that the XIAO ESP32S3 makes use of an external antenna on a short UFL connected cable. Make sure to attach this BEFORE you power up the board for the first time.

Manufacturing

Since I have made use of a SEEED Module, I sent this to SEEED Studio for manufacturing.

Seeed Studio’s Fusion service seamlessly marries convenience with full-feature capabilities in one simple platform. Whether you are prototyping or looking for a mass production partner or based on open source product customization requirements and other design manufacturing services, Seeed Studio Fusion service is catered to your needs starting with a simple online platform. https://www.seeedstudio.com/fusion.html

Assembly and Testing

I chose to assemble this project on my own. There was some issue with component availability, and since I have most in stock myself, decided to save time and do it myself.

Little did I know that I will be severely handicapped by a broken wrist a few weeks later. That little incident forced me to use my non-dominant hand, and resulted in an almost 3-hour-long assembly operation! All did however go well, and everything works as expected.

Testing went well, and after verifying all the voltages and connections, I uploaded some previously prepared ESPHome code to the board.

Due to the fact that this is still an early prototype, as well as some issues with ESPHome, I wont be releasing the firmware just yet. That will however happen in the near future.

Multi-Purpose IO Card

When we are working on a prototype, we always need access to pushbuttons, encoders and even displays to test our ideas in the real world. This Multi-Purpose IO Card was designed to help me do just that…

What is on the PCB?

This PCB was designed with my particular work style in mind. I use a lot of I2C devices, IO Expanders, Displays and sensors. It would thus make sense to have I2C on the PCB, to control an OLED display, as well as a PCF8574 IO expander, that is used to drive a 4×4 Matrix Keypad. Two Rotary encoders, as well as another 4 standard push buttons completes the PCB…

The features, summarised is as follows:

1x Matrix Keypad (4×4) Controlled via an PCF8574 IO expander with selectable addressing.
1x SSD1306 OLED I2C Display
4x Momentary pushbuttons, configured to be used with internal pullups – i.e pushing the button pulls the GPIO LOW
2x Rotary Encoders, with integrated Pushbutton, also configured as Active LOW

The board has all of the connectors and jumpers on the back, making it possible to mount it to an enclosure as a control panel.

I have also provided an additional I2C header to make it possible to add additional devices to the I2C bus easily

The PCB in Detail

PCB Top

Starting from left to right, we have two push-buttons, an OLED display, with two rotary encoders below the display, and another two momentary push buttons. On the Right, we have a 4×4 matrix keypad, and various pin headers for connection to a microcontroller of your choice.

On the back, we have the PCF8574 IO expander for the Matric keypad, addressing Jumpers for the IO expander, as well as the two pin headers for connections to and from a microcontroller…

The Pinouts of these are as follows:
Horizontal 15 pin 2.54mm connector
SDA I2C Data
SCA I2C Clock

GND

SW4 Momentary Push Button 4
SW3 Momentary Push Button 3
SW2 Momentary Push Button 2
SW1 Momentary Push Button 1

RE2-D Rotary Encoder 2 Push Button
RE2-B Rotary Encoder 2 Pin B
RE2-A Rotary Encoder 2 Pin A

RE1-D Rotary Encoder 1 Push Button
RE1-B Rotary Encoder 1 Pin B
RE1-A Rotary Encoder 1 Pin A

GND
VCC 3.3v to 5v DC

The Expansion header extends the I2C Bus, as well as proved access to the interrupt pin on the PCF8574. VCC and GND are also provided.

The Schematic


Manufacturing the PCB

I choose PCBWay for my PCB manufacturing. Why? What makes them different from the rest?

PCBWay‘s business goal is to be the most professional PCB manufacturer for prototyping and low-volume production work in the world. With more than a decade in the business, they are committed to meeting the needs of their customers from different industries in terms of quality, delivery, cost-effectiveness and any other demanding requests. As one of the most experienced PCB manufacturers and SMT Assemblers in China, they pride themselves to be our (the Makers) best business partners, as well as good friends in every aspect of our PCB manufacturing needs. They strive to make our R&D work easy and hassle-free.

How do they do that?

PCBWay is NOT a broker. That means that they do all manufacturing and assembly themselves, cutting out all the middlemen, and saving us money.

PCBWay’s online quoting system gives a very detailed and accurate picture of all costs upfront, including components and assembly costs. This saves a lot of time and hassle.

PCBWay gives you one-on-one customer support, that answers you in 5 minutes ( from the Website chat ), or by email within a few hours ( from your personal account manager). Issues are really resolved very quickly, not that there are many anyway, but, as we are all human, it is nice to know that when a gremlin rears its head, you have someone to talk to that will do his/her best to resolve your issue as soon as possible.

Find out more here

Assembly and Testing

The assembly of this PCB was relatively easy, as it contains only a single SMD component. I do however have to alert you to a certain caveat…

On the PCB, the I2C OLED display pinout is, from left to right,

VCC GND SDC SDA

I have however come across similar displays that swap the GND and VCC pins… and some that even have SCL and SDA swapped…

It is thus quite important that you check your display BEFORE soldering it to this PCB…

Addressing the PCF8574 is also quite easy, with the jumper towards the top is a high, and towards the bottom is a low… They are marked A2 A1 A0 and thus, counting in binary, all low will be 0x20h and all high will be ox27h

Also, note that there are NO I2C Pullup resistors on the board. My microcontroller PCB’s usually have these already, and most I2C Sensors, including the OLED Display that we use, already include as well…
You should thus check what you have on your own hardware, as it is quite impossible to cater for every situation… In a future version, I may add selectable pullup resistors onto this board as well…

Coding and Firmware

The possible uses of this board is quite broad, and the code possibilities are thus also quite extensive. Since I mainly use ESPHome or the Arduino IDE with most of my projects, I wont be including any specialised code here. I think it is enough to say that almost all of the available PCF8574 Matrix Keypad libraries available for the Arduino IDE will fork with this board…

The pinouts are important, and thus :

Row 0 – P0
Row 1 – P1
Row 2 – P2
Row 4 – P3

Col 0 – P7
Col 1 – P6
Col 2 – P5
Col 3 – P4

As far as ESPHome goes, you will need to
1) Add an I2c bus for your device
2)Add a PCF8574 component
3)Add a Matrix Keypad component, and refer the rows and columns to the pins on the PCF8574 – See below for an example of how I have done that in a previous project.

#I2C bus

i2c:

sda: 4

scl: 5

scan: true

id: I2C_Bus

#
# In my case, SDA is on GPIO4 and SCL is on GPIO5
# This is similar to the standard configuration on a NodeMCU v2 Dev board
#

#
# The next step is to configure the actual IO Expander, which in my case is located 
# at address 0x27
#

#PCF8574

pcf8574:

- id: 'pcf8574_hub'

address: 0x27

pcf8575: false


#
# Now we can add the actual keypad interface to the YAML file
# Take note of the difference from the ESP32 file above.
#
#

#KEYPAD

matrix_keypad:

id: mykeypad

rows:

- pin:

pcf8574: pcf8574_hub

# Use pin number 0

number: 0

# In the ESP32 file, we wHereould specify a pin directly like:
#
# -pin: 17
#
# That approach will not work for us.
# The reason for that is that we have to redirect the GPIO to a 
# physical pin on the PCF8574 IO expander.
#
# That is done with the following syntax
#
# - pin:
#pcf8574: pcf8574_hub -- This is the ID of the PCF8574 device -
#number: 0 -- The actual pin number

- pin:

pcf8574: pcf8574_hub

# Use pin number 0

number: 1

- pin:

pcf8574: pcf8574_hub

# Use pin number 0

number: 2

- pin:

pcf8574: pcf8574_hub

# Use pin number 0

number: 3

columns:

- pin:

pcf8574: pcf8574_hub

# Use pin number 0

number: 7

- pin:

pcf8574: pcf8574_hub

# Use pin number 0

number: 6

- pin:

pcf8574: pcf8574_hub

# Use pin number 0

number: 5

- pin:

pcf8574: pcf8574_hub

# Use pin number 0

number: 4

keys: "123A456B789C*0#D"

has_diodes: false

The Rotary encoders and momentary push-buttons can be handled in the same manner, using standard libraries in the Arduino IDE, or a rotary encoder component in ESPHome…

The OLED display would also be handled as above, with a DISPLAY component in ESPHome…

Summary and next steps

The next steps, for me at least, would be to design and CNC cut a suitable enclosure for the IO panel/Control panel in order to make it easier to use…

The panel was designed to be a tool to aid me while designing, and part of my never-ending battle getting rid of breadboards.

It does its job well, at least so far, and works as I have intended it to.

Variable Voltage Power Module

Powering electronics projects are always challenging. This Variable voltage Power Module was designed to solve such a problem for a specific project that I am working on.

The ESP32 and their smaller cousin the ESP8266 are pretty well known for their high power requirements. Having used quite a few of these in various projects over the years, I wanted a power module that can supply me with enough current to keep these hungry little chips satisfied. I also needed variable voltages with more modest current capabilities, to drive LED COB modules for example.

The idea thus came to me to combine two recent projects, that I have been using together on the bench with great effect. These two are the Variable Breadboard Power Module, based on the LM317G, and the DC-DC Buck Converter that I designed a short time ago. Between these two devices, I can deliver up to 3A at 3v or 5v, or a variable voltage at up to 1.5A.

Let us take a look at what exactly was done here.

Variable Power Module

What is on the PCB?

The PCB consists of 3 independent power circuits, the first of which is a DC-to-DC Buck module, based on the MP9943 from MPS. This chip can source up to 3A at a preset voltage. In my case, I chose 3.3v and 5v, as I use those the most.

The second and third parts are a mirrored section, with the humble LM317G at their hearts. These are set up as variable voltage regulators, with their outputs adjustable via R10 and R13. These two can source two independent voltages, from about 1.0v right up to about 11.5v ( if VCC is 12V) at a respectable 1.5A or current.

All of this is powered by a single 12v Power supply. Note that the 12v supply should be capable of sourcing at least 3A of its own…

Variable voltage Power Module


The stepped-down voltages are provided via 3 2-way headers at the top of the PCB.

How do you use the board?

Using the module is easy. Power it from 12v DC ( or up to 24v if you really want to)

The 3.3v or 5v output is selected using jumper J1 ( Please switch the power off first, BEFORE you change this). The selected voltage will be available at H1

H2 and H3 provide variable voltages, that can be set using R10 for H2 and R13 for H3. Turning the potentiometer anti-clockwise will reduce the voltage, clockwise to increase.

Test points ( TP1 and TP2) can be probed with a multimeter while adjusting the voltages.

The Schematic

Manufacturing the PCB

I choose PCBWay for my PCB manufacturing. Why? What makes them different from the rest?

PCBWay‘s business goal is to be the most professional PCB manufacturer for prototyping and low-volume production work in the world. With more than a decade in the business, they are committed to meeting the needs of their customers from different industries in terms of quality, delivery, cost-effectiveness and any other demanding requests. As one of the most experienced PCB manufacturers and SMT Assemblers in China, they pride themselves to be our (the Makers) best business partners, as well as good friends in every aspect of our PCB manufacturing needs. They strive to make our R&D work easy and hassle-free.

How do they do that?

PCBWay is NOT a broker. That means that they do all manufacturing and assembly themselves, cutting out all the middlemen, and saving us money.

PCBWay’s online quoting system gives a very detailed and accurate picture of all costs upfront, including components and assembly costs. This saves a lot of time and hassle.

PCBWay gives you one-on-one customer support, that answers you in 5 minutes ( from the Website chat ), or by email within a few hours ( from your personal account manager). Issues are really resolved very quickly, not that there are many anyway, but, as we are all human, it is nice to know that when a gremlin rears its head, you have someone to talk to that will do his/her best to resolve your issue as soon as possible.

Find out more here

Assembly

This PCB uses some very tiny components, so a stencil is highly recommended.


The Buck Converter IC is especially tiny.

Most of the other components can be soldered by hand, but I chose to do the entire assembly on a hotplate to reflow everything at the same time.

Testing


After assembly, I tested everything, measuring voltages with a multimeter, as well as adjusted H2 and H3 down to 6v, as I would be using the module on another project. I also tested the ripple on the Buck converter with an Oscilloscope, and it was well within the specs stated by the datasheet, at about +/- 100mV.

The entire module draws about 650mA at no load, and up to 3A when powering 2 6v LED COB modules and an ESP32 with I2S Audio modules connected as well.
Most of the current actually being drawn by the LM317G chips. The Buck converter is actually quite economical, drawing a modest 500mA at full load
( tested with a separate module that only contains a single buck converter module).

Conclusion

The power module works exactly as expected. It will perform well for its intended purpose, i.e powering an ESP12-E (8266) ESPHome device with two 6v LED COB modules in PWM mode, as well as an I2C display and various other sensors. In that application, I have successfully tested the entire project with a modest 12v at 1A wall-brick transformer, with no overheating or power shortage on any of the components. That is thus a win, in my books at least.

An I2C Matrix Keypad

The completed I2C Matrix Keypad

In a previous post this month I introduced my 4×4 matrix keypad. That keypad was designed to be directly interfaced to a microcontroller’s GPIO pins or alternatively to an IO expander chip like the PCF8574. That design, while working very well had the problem of requiring 8 GPIO pins to function correctly.

GPIO pins on a microcontroller can be considered very precious resources, and it should then be logical to assume that we should find a way to use these GPIO pins in a more conservative way, to allow us to interface more peripherals.

I solved this problem by integrating the keypad with an IO Expander on the same PCB. That will allow us to get away with using only 2 GPIO pins, and also open up the option of adding more keypads to the I2C bus, in the event that we need that many keys for a particular project.

The Schematic

I2C 4×4 Matrix Keypad Schematic

Looking closely at the schematic, we can see that it is exactly the same basic keypad circuit that I used in the initial design. The only difference is that in this design, I have integrated a PCF8574 directly onto the PCB.

Some additional features include selectable I2C Pullup resistors ( usually my microcontroller development boards already include those) that can be activated with a jumper when needed. There are also a set of address selection jumpers, making it possible to stack keypads together into a bigger keyboard if you require something like that. Note that, in this version of the hardware, I did not include headers for stacking.

The keypad can be powered by a DC power source of 3.3v to 5v.

The PCB

I2C Keypad PCB
3D Render of the I2C Keypad

The PCB is a double-layer board of 68.8mm x 50.8mm. Male header pins provide access to the connections as well as address and pullup resistor jumpers. In my build, I have mounted these male headers on the back of the PCB. That makes it possible to mount the Keypad in an enclosure without having the jumpers “stick out” and get in the way.

The top layer of the I2C Keypad PCB
Bottom Layer

Manufacturing

I choose PCBWay for my PCB manufacturing.
This month, PCBWay is also celebrating its 9th anniversary, and that means that there are quite a lot of very special offers available.

Why?
What makes them different from the rest?

PCBWay‘s business goal is to be the most professional PCB manufacturer for prototyping and low-volume production work in the world. With more than a decade in the business, they are committed to meeting the needs of their customers from different industries in terms of quality, delivery, cost-effectiveness and any other demanding requests. As one of the most experienced PCB manufacturers and SMT Assemblers in China, they pride themselves to be our (the Makers) best business partners, as well as good friends in every aspect of our PCB manufacturing needs. They strive to make our R&D work easy and hassle-free.

How do they do that?

PCBWay is NOT a broker. That means that they do all manufacturing and assembly themselves, cutting out all the middlemen, and saving us money.

PCBWay’s online quoting system gives a very detailed and accurate picture of all costs upfront, including components and assembly costs. This saves a lot of time and hassle.

PCBWay gives you one-on-one customer support, that answers you in 5 minutes ( from the Website chat ), or by email within a few hours ( from your personal account manager). Issues are really resolved very quickly, not that there are many anyway, but, as we are all human, it is nice to know that when a gremlin rears its head, you have someone to talk to that will do his/her best to resolve your issue as soon as possible.

Find out more here

Assembly

The assembly of this PCB was quite easy and quick. A stencil is not required. All SMD components are 0805 or bigger. It would thus be quite easy to solder them all by hand with a fine-tipped soldering iron.

I have however used soldering paste and hot air to reflow the components, as it is the fastest, in my opinion, and definitely looks neater than hand soldering.

After placing SMD components onto solder paste – ready for reflow soldering
After Reflow soldering with Hot Air

The board is now ready to solder the switches and header pins in place. As already mentioned above, I chose to assemble the headers on the back of the PCB to prevent them from interfering with any enclosure that I may later use with the keypad.

Final Assembly
Note that I assembled the headers onto the back of the PCB.

Testing and Coding

Testing the keypad consisted of a few steps, the first of which was ensuring that there were no short circuits, as well as that all the momentary switches worked.
This was done with a multimeter in continuity as well as diode mode, with probes alternatively on each column and row in turn, while pressing the buttons.

The next stage was testing the I2C IO Expander. This was done with a simple I2C Scanning sketch on an Arduino Uno. It did not do a lot, but, I could see that the PCF8574 is responding to its address and that the pullup resistors work when enabled. This test was repeated with my own ESP8266 and ESP32 boards, this time with pullup resistors disabled, as these boards already have them onboard.

Coding came next, and it was another case of perspectives. It seems like all commercial keypads do not have diodes. This affects the way that they work with a given library. It seems that software developers and hardware developers have different understandings of what a row and a column is.

This meant that, due to the fact that I have diodes on each switch, and the way that the library work – which pins are pulled high and which are set as inputs -, I had to swap around my rows and columns in the software to get everything to work. On a keypad with the diodes replaced with 0-ohm links, that was not needed.

A short test sketch follows below:

Note that with was run on an ESP8266-12E, therefore the Wire.begin() function was changed to Wire.begin(4,5); in order to use GPIO 4 and GPIO 5 for I2C

Another point to note is that the keypad Layout will seem strange. Remember that this is due to the diodes in series on each switch. That forces us to swap around the Rows and the Columns in the software, resulting in a mirrored and rotated left representation of the keypad. It looks funny, but believe me, it actually still works perfectly.

#include <Wire.h>
#include "Keypad.h"
#include <Keypad_I2C.h>

const byte n_rows = 4;
const byte n_cols = 4;

char keys[n_rows][n_cols] = {
    {'1', '4', '7', '*'},
    {'2', '5', '8', '0'},
    {'3', '6', '9', '#'},
    {'A', 'B', 'C', 'D'}};

byte rowPins[n_rows] = {4, 5, 6, 7};
byte colPins[n_cols] = {0, 1, 2, 3};

Keypad_I2C myKeypad = Keypad_I2C(makeKeymap(keys), rowPins, colPins, n_rows, n_cols, 0x20);

String swOnState(KeyState kpadState)
{
    switch (kpadState)
    {
    case IDLE:
        return "IDLE";
        break;
    case PRESSED:
        return "PRESSED";
        break;
    case HOLD:
        return "HOLD";
        break;
    case RELEASED:
        return "RELEASED";
        break;
    } // end switch-case
    return "";
} // end switch on state function

void setup()
{
    // This will be called by App.setup()
    Serial.begin(115200);
    while (!Serial)
    { /*wait*/
    }
    Serial.println("Press any key...");
    Wire.begin(4,5);
    myKeypad.begin(makeKeymap(keys));
}

char myKeyp = NO_KEY;
KeyState myKSp = IDLE;
auto myHold = false;

void loop()
{

    char myKey = myKeypad.getKey();
    KeyState myKS = myKeypad.getState();

    if (myKSp != myKS && myKS != IDLE)
    {
        Serial.print("myKS: ");
        Serial.println(swOnState(myKS));
        myKSp = myKS;
        if (myKey != NULL)
            myKeyp = myKey;
        String r;
        r = myKeyp;
        Serial.println("myKey: " + String(r));
        if (myKS == HOLD)
            myHold = true;
        if (myKS == RELEASED)
        {
            if (myHold)
                r = r + "+";
            Serial.println(r.c_str());
            myHold = false;
        }
        Serial.println(swOnState(myKS));
        myKey == NULL;
        myKS = IDLE;
    }
}

Conclusion

This project once again delivered what I set out to achieve. It has some quirks, but nothing serious. Everything works as expected, both in the Arduino IDE/platform IO realm, as well as in ESPHome. It is worth noting that in ESPHome, we do not need to swap the rows and columns to use the Keypad component. Do remember to leave the has_diodes flag to false though…

ESP32-S DEV Board – Rev 2.0

A few months ago, I started to work on an ESP32-S SOC module in Arduino Uno form factor. This is Revision 2.0 – the ESP32-S Dev Board – Rev 2.0

During the time since I designed, and ultimately had the Rev 1.0 PCB manufactured, It has quickly become one of my go-to development platforms, something that I hoped it would become. It also seemed to be gaining popularity online, with quite a few of them being ordered.

Problems did however arise, as the manufacturer discontinued the SOC module, the AI-Thinker ESP32-S, but, as this was based on the ESP32 WROOM32 from Espressif, which, while still old, was still in production, it was not a serious problem.

Using the Rev 1.0 device was easy enough, but I soon started to experience some irritation, as in my attempts to build a very streamlined device, I left out some add-on components, that now seemed to be a very good idea to have on board…
Let me explain:

In the initial design, I did not include a DC barrel connector, as well as no USB port with a USB-to-serial converter, my argument being that the USB port is usually only used a few times, or at most once, as I usually upload firmware to ESP32’s OTA. Power ( on the bench that is, is usually supplied via a pair of wires, so no dedicated connector seemed to be necessary.

As I proceeded to design addon shields for the device, it became clear that that power connector, at minimum, as well as the standard 2-transistor reset/flash circuit, would be a very very welcome addition to this PCB.

See the pictures below for a comparison of the two boards…

ESP32-S Dev Board Rev 1.0
ESP32-S Dev Board Rev 1.0
ESP32-S Dev board Rev 2.0
ESP32-S Dev Board Rev 2.0

I have also decided to use male header pins on this build, as I sort of like to use them more than the female ones ( which seem to develop connectivity issues after a while – this could be due to the quality of the connector strips that I bought)

What changed, and how?

I made quite a few changes, most of them quite subtle.
The most obvious would be the addition of a DC Barrel connector, to allow the device to be powered easier when used as a permanent project. In addition to this, a 6-pin programming header was added, in order to make flashing the device with an external USB-to-serial adapter easier than usual. ( This means that the standard 2-transistor reset/flash circuit was also added). That meant a slight increase in the component count. Additional decoupling capacitors were also added to add voltage stability to the ESP32-S. The routing of the entire board was also changed, with more attention being paid to the heat dissipation of the ESP32-S module, which tended to get a bit hot.

Power is provided by a 3.3v LDO regulator, the same as in the Rev 1.0 hardware.
I do plan to change this to a small buck converter in the near future, as the 800mA provided by the LDO regulator can get a bit limited, especially when using I2S Audio devices, something which I am doing quite a lot over the last few months.

Manufacturing

I choose PCBWay for my PCB manufacturing.
This month, PCBWay is also celebrating its 9th anniversary, and that means that there are quite a lot of very special offers available.

Why?
What makes them different from the rest?

PCBWay‘s business goal is to be the most professional PCB manufacturer for prototyping and low-volume production work in the world. With more than a decade in the business, they are committed to meeting the needs of their customers from different industries in terms of quality, delivery, cost-effectiveness and any other demanding requests. As one of the most experienced PCB manufacturers and SMT Assemblers in China, they pride themselves to be our (the Makers) best business partners, as well as good friends in every aspect of our PCB manufacturing needs. They strive to make our R&D work easy and hassle-free.

How do they do that?

PCBWay is NOT a broker. That means that they do all manufacturing and assembly themselves, cutting out all the middlemen, and saving us money.

PCBWay’s online quoting system gives a very detailed and accurate picture of all costs upfront, including components and assembly costs. This saves a lot of time and hassle.

PCBWay gives you one-on-one customer support, that answers you in 5 minutes ( from the Website chat ), or by email within a few hours ( from your personal account manager). Issues are really resolved very quickly, not that there are many anyway, but, as we are all human, it is nice to know that when a gremlin rears its head, you have someone to talk to that will do his/her best to resolve your issue as soon as possible.

Find out more here

Assembly

This PCB will definitely benefit from using a stencil, but it is not strictly necessary. I did however get one, as I prefer the uniform solder-paste application and speed that they give me.

Stencil for SMD assembly

Component placing took only about 10 minutes in total, including the time needed to place and use the stencil, apply solder paste, select components and place them in their correct positions.

After Solder paste application – Before reflow soldering

The board was then reflow soldered on a hotplate at 223 degrees Centigrade.

After Reflow soldering

The board was inspected for solder bridges and bad joints, and I then proceeded with through-hole component assembly, which took about another 10 minutes.

ESP32-S Dev board Rev 2.0
The completed PCB

Conclusion

This was definitely a very worthwhile revision on a very useful piece of equipment. The addition of the programming header, in particular, already saves quite a bit of time, and the DC Barrel connector opens up new possibilities for the use of the device outside of the “bench” environment.

A quick P-MOS MOSFET Driver Board

Introduction

A driver is needed to switch a P-Channel MOSFET because the gate of a P-Channel MOSFET needs to be driven to a voltage that is more negative than the source in order to turn it on. This can be difficult to do with low-voltage logic, such as 5V or 3.3V. A driver can provide the necessary voltage and current to turn on the P-Channel MOSFET, even when the logic voltage is low.

Here are some of the benefits of using a driver to switch a P-Channel MOSFET:

  • Increased switching speed: A driver can provide the necessary current to charge and discharge the gate capacitance of the P-Channel MOSFET quickly, which results in faster switching speeds.
  • Reduced power consumption: A driver can help to reduce power consumption by providing the necessary current in a short pulse, rather than a continuous stream of current.
  • Improved noise immunity: A driver can help to improve noise immunity by providing a clean and isolated signal to the gate of the P-Channel MOSFET.

If you are using a P-Channel MOSFET in your circuit, it is a good idea to use a driver to switch it. This will help to ensure that the MOSFET is switched quickly and efficiently and that it is protected from noise.

Here are some of the different types of drivers that can be used to switch P-Channel MOSFETs:

  • Logic level drivers: These drivers are designed to work with low-voltage logic, such as 5V or 3.3V. They typically have a high output voltage, which can be used to drive the gate of a P-Channel MOSFET.
  • High-side drivers: These drivers are designed to provide a high voltage to the gate of a P-Channel MOSFET. They are often used in circuits where the P-Channel MOSFET is used to switch a high-voltage rail.
  • Isolated drivers: These drivers provide an isolated signal to the gate of the P-Channel MOSFET. This is useful in circuits where it is important to prevent noise from entering the circuit.

Why did I decide to design this prototype?

The Story behind the prototype

This driver PCB is part of a solution for a project involving a set of 6v LED lights.
Each of the LED lights requires +/- 300mA @ 6v to operate efficiently.
I want to control these from a Microcontroller, either an ESP32 or even the XIAO RP2040 or similar. The current sink capability of an individual GPIO pin on these microcontrollers is limited, in the case of the RP2040 it is limited to 3mA per pin.

This prototype is an attempt to test out some basic driver ideas that might perform correctly for my particular needs, being

  • To stay within the limitations of the particular microcontroller GPIO current specifications
  • To be able to use any of the particular microcontrollers, without having to design a specific solution tailored to a specific device

The Schematic

I decided to keep things extremely simple to start with, using a very simple circuit consisting of only 4 components per channel. These are :
– an S9013 NPN BJT Transistor, capable of switching up to 500mA of current
– a SI2301 P-Channel Logic Level MOSFET, capable of switching up to 2.3A
– 10k pullup-resitor
– 1k resistor on the base of the BJT


The theory of operation is as follows:
The pullup resistor, R8, keeps the gate of the MOSFET (Q4) positive, thus ensuring that Q4 stays turned off when T4 is turned off. A HIGH signal at B4 will turn on T4, which will in turn pull the gate of Q4 to ground, turning Q4 on in the process.
That will in turn turn on the load ( connected at 4+ and 4- ).

It is important to note here that the value of R8, 10K at the moment, is not finalised, and may change to increase the performance of the circuit.

The PCB

The board was made to fit on a standard breadboard or be used as a standalone module, depending on the position of the male header pins.


Manufacturing


I choose PCBWay for my PCB manufacturing.
This month, PCBWay is also celebrating its 9th anniversary, and that means that there are quite a lot of very special offers available.


Why? What makes them different from the rest?
PCBWay‘s business goal is to be the most professional PCB manufacturer for prototyping and low-volume production work in the world. With more than a decade in the business, they are committed to meeting the needs of their customers from different industries in terms of quality, delivery, cost-effectiveness and any other demanding requests. As one of the most experienced PCB manufacturers and SMT Assemblers in China, they pride themselves to be our (the Makers) best business partners, as well as good friends in every aspect of our PCB manufacturing needs. They strive to make our R&D work easy and hassle-free.

How do they do that?

PCBWay is NOT a broker. That means that they do all manufacturing and assembly themselves, cutting out all the middlemen, and saving us money.

PCBWay’s online quoting system gives a very detailed and accurate picture of all costs upfront, including components and assembly costs. This saves a lot of time and hassle.

PCBWay gives you one-on-one customer support, that answers you in 5 minutes ( from the Website chat ), or by email within a few hours ( from your personal account manager). Issues are really resolved very quickly, not that there are many anyway, but, as we are all human, it is nice to know that when a gremlin rears its head, you have someone to talk to that will do his/her best to resolve your issue as soon as possible.

Find out more here

Assembly

The assembly of the PCB does not require any special tools, and can be done completely by hand if you choose. A very fine-tipped soldering iron should be perfect.

I chose to go the hot-air and solder-paste route, as it is faster, and looks neater in the end. The use of a stencil was not required.

The total assembly took about 5 minutes in total.

Testing

Testing the completed PCB module was performed with one of the LED light modules connected to each MOSFET Channel in turn, and then applying a voltage signal, or ground, to the control pin ( marked A to D on the picture above)

That was followed by connecting an Oscilloscope and Signal Generator to the control pins, as well as the outputs, and observing the waveforms during operation. A square wave output from the signal generator provided the switching signal.

Conclusion

The module works as expected, but the pullup resistor value needs to be fine-tuned to provide a better switching response on the MOSFET at high frequency.
I am however happy with the initial performance, and can now move on to improving the circuit to perform to my specifications.


A Reliable Matrix Keypad

What is a matrix keypad?

A matrix keypad is a type of keypad that uses a matrix of wires to connect the keys to the microcontroller. This allows for a smaller and more compact keypad than a traditional keypad, which uses a single row and column of wires for each key. Matrix keypads are also more reliable than conventional keypads, as they are less susceptible to damage from dirt and moisture.

How does a matrix keypad work?

A matrix keypad is made up of a number of rows and columns of keys. Each key is connected to two wires, one for the row and one for the column. When a key is pressed, it completes a circuit between the row and column wires. The microcontroller can then determine which key is pressed by checking which row and column wires are connected.

Why use a matrix keypad?

There are a number of reasons why you might want to use a matrix keypad in your project. Here are a few of the most common reasons:

  • Smaller size and footprint.
  • Reliability.
  • Cost savings.

What makes my design different from most others out there?

While the matrix keypad in its simplest form is constructed from only wires and switches, that simple approach can sometimes have some unwanted effects, especially when pressing multiple keys at the same time – a phenomenon called ghosting – where you get phantom keypresses. This is easily eliminated by adding a diode in series with each switch, usually on the row connection.

That single component fixes ghosting reliably but does not come without its own problems, the most important of these being that a keypad with diodes becomes “polarised” – current can only flow in a single direction through a switch. This can cause problems with some third-party libraries, as the designer of the keypad and the designer of the library very often has quite different ideas of what a row and a column mean in a keypad.

This is important, – here we go down the rabbit hole; in my understanding of the keypad scanning routine, a column runs from top to bottom, and a row from left to right. Keeping this in mind, the microcontroller will alternatively set each column HIGH, and configure each row as an input. When a key is pressed, current will flow from the specific column GPIO, through the switch, and into the Row GPIO, sending the input pin HIGH…

It is also possible to configure the columns as inputs, with internal pullups enabled, and have each Row pin as an output, configured to sink ( pull current to ground). This will cause the specific column to go low – thus identifying the pressed key…

These different ways of handling the problem of reading a key, and believe me, there are actually more variations, create a few unique problems. We may have to swap rows and columns as far as pin connections and firmware are concerned, as well as define a custom “keymap” to assign values to each key.

The Schematic

As we can see above, the schematic is very basic. 16 switches, 16 diodes and a single 8-way header pin. Pin 1 to 4 on the header is connected to Columns 1 to 4, and Pin 5 to 8 is connected to Rows 1 to 4.

The diodes prevent “ghosting currents from flowing into other keys in a row when multiple keys are pressed together. They also seem to help with other stray signals and interference.

The PCB

The PCB is a simple double-layer board. All components are mounted on the top layer.

To limit interference from stray signals, I have routed rows and columns on opposite sides of the PCB where possible.

Manufacturing

I choose PCBWay for my PCB manufacturing.
This month, PCBWay is also celebrating its 9th anniversary, and that means that there are quite a lot of very special offers available.


Why? What makes them different from the rest?
PCBWay‘s business goal is to be the most professional PCB manufacturer for prototyping and low-volume production work in the world. With more than a decade in the business, they are committed to meeting the needs of their customers from different industries in terms of quality, delivery, cost-effectiveness and any other demanding requests. As one of the most experienced PCB manufacturers and SMT Assemblers in China, they pride themselves to be our (the Makers) best business partners, as well as good friends in every aspect of our PCB manufacturing needs. They strive to make our R&D work easy and hassle-free.

How do they do that?

PCBWay is NOT a broker. That means that they do all manufacturing and assembly themselves, cutting out all the middlemen, and saving us money.

PCBWay’s online quoting system gives a very detailed and accurate picture of all costs upfront, including components and assembly costs. This saves a lot of time and hassle.

PCBWay gives you one-on-one customer support, that answers you in 5 minutes ( from the Website chat ), or by email within a few hours ( from your personal account manager). Issues are really resolved very quickly, not that there are many anyway, but, as we are all human, it is nice to know that when a gremlin rears its head, you have someone to talk to that will do his/her best to resolve your issue as soon as possible.

Find out more here

Assembly

This project does not require a lot of specialised equipment to assemble. The SMD diodes can easily be soldered by hand, the same with the switches and 8-way header. In my case, I chose to solder the header pins on the back of the PCB, that way, I can later use the keypad in a suitable enclosure without having wires in the way.

Testing and Coding

Testing a matric keypad can sometimes be a challenge. In my case, a multimeter with clip leads, set to diode mode, with the leads connected to each column and row in turn, while minding the polarity, and pressing each key in that row in turn, verified continuity.

With that done, it was time to put my trusted Cytron Maker Uno to work, as this Arduino Clone has the added benefit of having LEDs on each of the GPIO lines, thus making it very easy to see what is happening.

I made use of a Keypad library in the Arduino IDE, mainly to cut down on the amount of coding, but also because it is easier to use a working piece of code, and then adapt that to my keypad.

Detailed Code examples for ESPHome are available on Patreon

/* @file CustomKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Demonstrates changing the keypad size and key values.
|| #

Edited by MakerIoT2020, with minor changes to make it function correctly with my custom keypad.
I have also added a simple LED blinking routine to show that the Arduino is “alive” and that the Keypad code seems to be NON-blocking – which is quite important to me.

*/
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the symbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{‘1′,’4′,’7′,’*’},
{‘2′,’5′,’8′,’0’},
{‘3′,’6′,’9′,’#’},
{‘A’,’B’,’C’,’D’}
};
byte rowPins[ROWS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6,7,8,9}; //connect to the column pinouts of the keypad
/*
* Due to libraries being written by different people, and our definitions about
* what a row and a column are, is different, note that the rows in the code
* is actually the columns on my PCB. This becomes true, due to the fact that my
* PCB has Diodes on each switch, and that thus makes current flow in only one
* direction///
*
* it also has the “side effect” that keys are layout in a strange “mirrored” and
* rotated way in the firmware.
* it does however NOT affect the correct operation of the Keypad Module at all
*
*/

const int LEDPin = LED_BUILTIN;
int ledState = LOW;
unsigned long prevmillis = 0;
const long interval = 1000;

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup(){
Serial.begin(115200);
pinMode(LEDPin,OUTPUT);
}

void loop(){
unsigned long currentMillis = millis();
if (currentMillis – prevmillis >= interval) {
prevmillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(LEDPin,ledState);
}
char customKey = customKeypad.getKey();

if (customKey){
Serial.println(customKey);
}
}

This code works very well and allowed me to verify the correct operation of the keypad.

In conclusion

Making my own Keypad Module is a project that is long overdue. I have purchased a few online over the years, and as they were mostly of the membrane type, they did not last very long – it must be something to do with the ultra-cheap flexible PCB ribbon connector, since a quality membrane keypad can be quite expensive, and usually lasts quite a long time.

Having my own module available to experiment with will allow me to do some long-delayed improvements to many of my IoT modules. That code, mostly YAML for ESPHome, will be made available on Patreon.

Stereo I2S Shield – The next iteration…

Last month I started working on a Stereo I2S Audio shield for my ESP32-S development board. Those of you that saw that post will remember that I made some mistakes on the initial prototype, and had to repair it with a few “greenwire” connections.


The prototype shield also required the use of commercial I2S modules to be plugged into it, making for quite a cumbersome first iteration.

Stereo I2S shield stacked onto esp32-S dev board

I decided to do something about that, as the long-term use of this particular shield, as internet radio, with a further “dream” of using it as a remote media player for use from Home Assistant, is moving along well, with progress on the firmware being made slowly but surely.


I decided that, since the Audio Chips seem to be quite easily available, and are modestly priced, getting rid of the plug-in modules, and placing the chips directly on the shield seemed like the next logical step. I also broke out the gain pins of each chip and made provision for easily changing said gain with a jumper, individually for the left and right channels of the I2S Audio shield.

I decided to keep the logic level conversion circuit, as it worked well, as well as provided another layer of protection to the ESP32-S that drives the whole shield. ( These have recently been discontinued by AI-Thinker, but the Espressif version is still begin manufactured and supported).

The power supply section of the board remains the same as the previous version, with a dedicated 5v regulator feeding the Audio section, and a 3v regulator the logic level converters. (I may change this in future, as the ESP32-S board can easily supply the 3v required without overloading the regulator on the CPU board.

Current issues that are carried over from the initial prototype still remain though. The two I2S Audion chips seem to be QUITE power-hungry, pulling almost 2A of current from a 12v supply, with a modest volume of 10 out of a possible 100. This has been reduced down from an earlier 4A to 6A when using a different pair of 4ohm 3W speakers.

This is also one of the reasons for the separate voltage regulators on the shield.

Manufacturing

I choose PCBWay for my PCB manufacturing. Why? What makes them different from the rest?

PCBWay‘s business goal is to be the most professional PCB manufacturer for prototyping and low-volume production work in the world. With more than a decade in the business, they are committed to meeting the needs of their customers from different industries in terms of quality, delivery, cost-effectiveness and any other demanding requests. As one of the most experienced PCB manufacturers and SMT Assemblers in China, they pride themselves to be our (the Makers) best business partners, as well as good friends in every aspect of our PCB manufacturing needs. They strive to make our R&D work easy and hassle-free.

How do they do that?

PCBWay is NOT a broker. That means that they do all manufacturing and assembly themselves, cutting out all the middlemen, and saving us money.

PCBWay’s online quoting system gives a very detailed and accurate picture of all costs upfront, including components and assembly costs. This saves a lot of time and hassle.

PCBWay gives you one-on-one customer support, that answers you in 5 minutes ( from the Website chat ), or by email within a few hours ( from your personal account manager). Issues are really resolved very quickly, not that there are many anyway, but, as we are all human, it is nice to know that when a gremlin rears its head, you have someone to talk to that will do his/her best to resolve your issue as soon as possible.

Find out more here

Assembly

This project once again called for a stencil, as the QFN packages of the Audio chips are super tiny, with super tiny tracks and pads. A high-quality stencil definitely goes a long way in ensuring that just the right amount of solder paste is added to each pad. This also reduces the requirements for reworking a board with hot air to fix any solder bridges that might have formed.


The quality of a stencil says a lot about your PCB manufacturer, and in my case, I am extremely happy to say that PCBWay definitely delivers quality. Having used their services for close to 3 years now, I have not received a single faulty PCB or stencil at all. Yes, some PCB’s has had errors, but those were all MY errors. Design errors, not manufacturing errors.

Let us return to the assembly of this PCB, shall we…

As usual, the PCBs arrived very well packaged, and after a quick inspection and some random tests with a multimeter, It was time for solder paste and placing components, while listening to a piece of relaxing music… my way of relaxing…


After about 20 minutes of intense concentration, we have a PCB with all of the components correctly placed onto their respective pads, ready for reflow soldering.


I did things differently this time, by placing the QFN Audio chips in their positions at the same time as all the others. ( I usually drop them in place when the solder is in a liquid state, but with these, I was confident in the stencil, and as these chips were quite a bit more expensive than my usual projects [ over 3 USD each ], I wanted them to slowly get up to temperature, and spend as little time as possible at temperature as well. )


Reflowing was a success, and after inspection, no solder bridges were found. A detailed diagnostic with a multimeter with fine-tipped needle probes confirmed that there were no short circuits or bridges, and I could thus continue with the rest of the assembly – the various through-hole components, being mostly header pins, switches and a DC barrel jack socket.

The speaker wires were soldered directly to the PCB, due to the fact that being a prototype, I did not see the need to raise the cost even more by adding connectors onto a board that may not be used very long if it turns out that there is a problem somewhere.

Testing

The next stage was testing, using the software provided in the initial Stereo I2S Shield post. All went well, but, as mentioned above, I encountered the same high current draw issue, which resolved itself ( in a manner of speaking ) after I reduced the initial startup volume of the unit, and limited the maximum volume in the software.

I can now continue with firmware development, and sort out things like the rotary encoders for the volume and station selection, as well as look at adding an i2c display, and possibly a sd-card for stored music files.

Conclusion

The project is getting along quite well, and this iteration of the prototype did not have any design faults or errors. I am extremely impressed with the reliability of my PCB manufacturer, as their consistent quality products allow me to focus on design, and trust that whatever comes back from the factory will be exactly as I designed it.

While there are still quite a few issues to sort out on this project, I am confident that in the end, it will all turn out the way that I want it to.

Stereo I2S Shield for ESP32-S Dev Board

Sound or music adds another level of complexity to any project. Having the ability to easily add it as a shield, allows for a reduced level of this complexity, and hopefully stimulates some inspiration along the way.

This was the thought process that inspired this Stereo I2S Shield, for use with my ESP32-S Dev Board. During the design process, and actually, before, many things happened that turned this project into a slightly more complicated task than I have initially accounted for.

The short and sweet is that I made a few silly mistakes on the PCB, which, for the prototype at least, has been fixed with a few jumper wires. [ I have since updated the Gerber files with the correct design, omitting these silly mistakes.]

Let us take a look at what happened.

  1. I forgot the ground connection on the 5v Regulator, and since I placed extensive ground copper pours on both sides of the PCB, I missed that one completely.
  2. I forgot to connect the 5v supply to the Max98357A breakout headers
  3. I also completely forgot to connect any signal traces to these breakouts
  4. The breakouts were placed on the wrong side of the PCB ( if looking top to bottom on the picture below, they should be towards the top)

How does this happen, and most importantly, why would I even mention my mistakes here, in public?

The most important here is that I am human. Humans make mistakes. Rushing through converting a design that works perfectly on a breadboard onto a PCB should not happen, but it does happen, and that is why the first iterations of a PCB are called prototypes. Dealing with customers, while working on a design, as well as life’s other interruptions very often results in small mistakes, which I usually catch before a board goes for manufacturing. In this case, I did not catch them until after I received the board back from the factory.

The other part of this coin is transparency. There are many many projects on the internet, some good, some excellent, and some outright terrible. Without giving a score to any of my own, my only intention is that whatever I present on this medium MUST be completely honest, my own work, and it must work. Any mistakes MUST be made public, regardless of what the public thinks of it afterwards.

With the ranting done now, let’s take a look at the board, which, after fixing the issues, actually works perfectly…

(I will make use of a rendered image showing the repaired PCB, as it will be the least confusing)


In the rendered image above, we can clearly see what it should have looked like, with the MAX98357A breakouts in their correct places, and all power and signal traces connected correctly.

Part of the reason for the mistakes on the initial prototype PCB was that I felt it necessary to add logic-level conversion to the I2S modules. The reason for that is that in order to get a bit more volume out of them, they are powered at 5v.


With the GPIO pins of the ESP32 being 3.3v, I felt that it is not warranted to take a risk and power the I2S breakouts at 5v, and send them 3.3v signals. That sparked the whole issue, with adding my standard Bss138-based logic converter circuit to the mixture.


The board contains its own Flash and Reset buttons, which are slaved to the stacked ESP32-S dev board at the bottom.
Further to that, the board provides a DC barrel connector, which will power the I2S shield, as well as the ESP32-S dev board via its Vin Pin

Since the MAX98357A breakouts seem to pull quite a bit of current ( about 500mA or more each, depending on the volume), the shield has its own voltage regulators. I have found that during the experimentation on the breadboard, the single 3.3v regulator on the ESP32-S Dev board was a bit inadequate to drive two of these modules and the ESP32 as well.

Software and Code

The code for the device is far from perfect at this stage, consisting mainly of example code that was provided by the i2s library, to which I have started making minor changes, the most significant being moving the entire audio process to an alternate core of the ESP32. This was done because the audio process seem to be blocking, and, as I plan to later add controls and displays to this device, that would result in an issue later.

/*
  Simple Internet Radio Demo
  esp32-i2s-simple-radio.ino
  Simple ESP32 I2S radio
  Uses MAX98357 I2S Amplifier Module
  Uses ESP32-audioI2S Library - https://github.com/schreibfaul1/ESP32-audioI2S

  
*/

// Include required libraries

#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#include "ESPmDNS.h"
#include "time.h"



// Define I2S connections
#define I2S_DOUT  22
#define I2S_BCLK  26
#define I2S_LRC   25



// Create audio object
Audio audio;

// Wifi Credentials
String ssid =    "<your ssid here>";
String password = "<your password here>";

void audioTask(void *pvParameters) {
  while(1) {
    audio.loop();
  }
}


void setup() {

  // Start Serial Monitor
  Serial.begin(115200);
  

  // Setup WiFi in Station mode
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid.c_str(), password.c_str());

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // WiFi Connected, print IP to serial monitor
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("");

  // Connect MAX98357 I2S Amplifier Module
  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
  
  // Set thevolume (0-100)
  audio.setVolume(10);

  // Connect to an Internet radio station (select one as desired)
  //audio.connecttohost("http://vis.media-ice.musicradio.com/CapitalMP3");
  //audio.connecttohost("mediaserv30.live-nect MAX98357 I2S Amplifier Module
  //audio.connecttohost("www.surfmusic.de/m3u/100-5-das-hitradio,4529.m3u");
  //audio.connecttohost("stream.1a-webradio.de/deutsch/mp3-128/vtuner-1a");
  //audio.connecttohost("www.antenne.de/webradio/antenne.m3u");
  //audio.connecttohost("0n-80s.radionetz.de:8000/0n-70s.mp3");
  //audio.connecttohost("http://live.webhosting4u.gr:1150/stream");
  audio.connecttohost("0n-80s.radionetz.de:8000/");
  disableCore0WDT();
  xTaskCreatePinnedToCore(audioTask,"audiotask",10000,NULL,15,NULL,0);
}


void loop()

{
  // Run audio player
  //audio.loop();
 
}


//

// Audio status functions

void audio_info(const char *info) {
  Serial.print("info        "); Serial.println(info);
}
void audio_id3data(const char *info) { //id3 metadata
  Serial.print("id3data     "); Serial.println(info);
}
void audio_eof_mp3(const char *info) { //end of file
  Serial.print("eof_mp3     "); Serial.println(info);
}
void audio_showstation(const char *info) {
  Serial.print("station     "); Serial.println(info);
}
void audio_showstreaminfo(const char *info) {
  Serial.print("streaminfo  "); Serial.println(info);
}
void audio_showstreamtitle(const char *info) {
  Serial.print("streamtitle "); Serial.println(info);
}
void audio_bitrate(const char *info) {
  Serial.print("bitrate     "); Serial.println(info);
}
void audio_commercial(const char *info) { //duration in sec
  Serial.print("commercial  "); Serial.println(info);
}
void audio_icyurl(const char *info) { //homepage
  Serial.print("icyurl      "); Serial.println(info);
}
void audio_lasthost(const char *info) { //stream URL played
  Serial.print("lasthost    "); Serial.println(info);
}
void audio_eof_speech(const char *info) {
  Serial.print("eof_speech  "); Serial.println(info);
}

Important parts of the code to note are as follows

disableCore0WDT();
  xTaskCreatePinnedToCore(audioTask,"audiotask",10000,NULL,15,NULL,0);

This code disables the Watchdog Timer on Core0 of the ESP32, as well as creates the audio task, which is defined earlier in the code

void audioTask(void *pvParameters) {
  while(1) {
    audio.loop();
  }
}

It is also important to note that the loop() in the code is essentially empty, with all code commented out. As mentioned above, I do plan to add additional functionality later, and in that case, there will either be other tasks running, or be some code in the main loop.

Another VERY important issue is the DOUT pin, which I have defined as GPIO22.
This pin is usually used as an I2C pin, but it seems that the I2S hardware on the ESP32-S does not like running the DOUT signal on another pin. This is not an issue, as you can assign another pin to I2C without any issue if you need to use that as well.

Manufacturing

I choose PCBWay for my PCB manufacturing. Why? What makes them different from the rest?

PCBWay‘s business goal is to be the most professional PCB manufacturer for prototyping and low-volume production work in the world. With more than a decade in the business, they are committed to meeting the needs of their customers from different industries in terms of quality, delivery, cost-effectiveness and any other demanding requests. As one of the most experienced PCB manufacturers and SMT Assemblers in China, they pride themselves to be our (the Makers) best business partners, as well as good friends in every aspect of our PCB manufacturing needs. They strive to make our R&D work easy and hassle-free.

How do they do that?

PCBWay is NOT a broker. That means that they do all manufacturing and assembly themselves, cutting out all the middlemen, and saving us money.

PCBWay’s online quoting system gives a very detailed and accurate picture of all costs upfront, including components and assembly costs. This saves a lot of time and hassle.

PCBWay gives you one-on-one customer support, that answers you in 5 minutes ( from the Website chat ), or by email within a few hours ( from your personal account manager). Issues are really resolved very quickly, not that there are many anyway, but, as we are all human, it is nice to know that when a gremlin rears its head, you have someone to talk to that will do his/her best to resolve your issue as soon as possible.

Find out more here

Assembly

Assembly was straightforward, with no issues, as all of the components can quite easily be soldered using a standard soldering iron, or hot air. This PCB does not require a stencil, but, you can of course have one made if you want to.

As mentioned in the introduction, I had to do a lot of after-assembly-hacking to get the board to work correctly. This will however not be needed with the second-generation PCB, as I have already fixed all those issues on the Gerber files.

Picture Gallery

Multipurpose USB UART Module

USB-to-Serial converters are some of the most used modules on my bench. I have quite a few of them, most of them are the cheap online type that can be had for a few dollars.

As part of my new project, where I am seriously looking for an alternative chip to replace the ATMEGA328, which has become almost impossible to get, and super expensive when you do get it, I needed to get hold of a UPDI programmer.

There are many available online, from cheap to more expensive, but I wanted to build my own, as it did not seem too difficult to do.

As another part of my daily tasks, I also use a lot of ESP-type chips, which have a particular procedure to upload code via an external serial adapter.

The idea was thus to design a USB UART module that has multiple purposes, as well as being easy and cheap to assemble.

  • Be able to program ATMEGA328 Chips via Serial
  • Be able to be used as a standard USB-to-UART adapter
  • Be a UPDI programmer
  • Have a selectable target voltage between 3.3v and 5v
  • Have all modem signals (RTS, CTS, DSR, DTR) broken out.
  • Be able to auto-flash and reset an ESP32 or ESP8266 device, or similar
Breadboard Prototype Multipurpose USB-to-UART/UPDI Programmer

What is on the PCB?

The PCB is powered by the PC USB port. The target device voltage is selectable between 3.3v and 5v. The device mode can be changed from UART to UPDI mode with a jumper. An additional header specifically for ESP32/ESP8266 devices is provided, giving access to the FLASH and reset signals for the ESP device.

The USB to serial conversion is taken care of by a CH340G Chip, which provides all the relevant modem signals as well.

All signals, with the exception of the “RING” signal, are broken out onto the main header.

Note that there are NO status or POWER LEDs on the board. This was on purpose, as these sometimes interfere with the UPDI programming mode.

Prototype PCB – Assembled

PCB – Top
PCB – Bottom

Connecting to different devices

ESP32 or ESP8266 Devices

When in UART mode, the device can be used to upload code to an ESP32/ESP8266 automatically, similar to a standard dev board, without requiring you to press and flash and reset buttons.

This is achieved by connecting the device as follows:

UART MODULE SET to 3v
UART VCC to ESP 3v
UART GND to ESP GND
UART RX to ESP TX
UART TX to ESP RX

(Connections for Auto Upload/Reset)
UART RST ( on ESP-Flash Header) to ESP RST
UART GPIO0 ( on ESP-Flash Header) to ESP GPIO0

It will now be possible to flash and auto reset the connected ESP device from the Arduino IDE, and possibly others as well…

Arduino (Atmega 328P)

In the current version of the prototype, you have to connect it as follows:

UART Target voltage set to 3v or 5v depending on what type of board you are uploading

UART Tx to Arduino Rx
UART Rx to Arduino Tx
UART VCC to Arduino 3v or 5v ( depending on the target voltage required by the board you are flashing)
UART GND to Arduino GND

To allow for auto flash/reset on the Arduino, a 100nf capacitor is required between the UART DTR line and the Arduino Reset pin. This capacitor has NOT yet been fitted onto the PCB, as I usually use ICSP to upload these. Future versions of the PCB shall have this included.

ATMEGA4808/4809 and or ATTiny with UPDI Interface

This device is currently an LV-only UPDI programmer. Connections are as follows:

Set Target voltage on J1 of the UART/UPDI programmer.
Set The Device mode on J2 to UPDI mode

Connect VCC and GND from the Programmer to the target chip/board
Connect Programmer UPDI pin( shared with RxD) to Target UPDI pin.

General use UART for use as Serial monitor/Terminal

Set target voltage on J1
Set device mode to UART on J2

Connect VCC, GND from UART to the target device,
UART Tx to Target Rx
Uart Rx to Target Tx

Optionally connect required modem signals, RTS, CTS, DTR, and DSR as needed

Manufacturing

The PCB for this project has been manufactured at PCBWay.
Please consider supporting them if you would like your own copy of this PCB, or if you have any PCB of your own that you need to have manufactured.

PCBWay

Some Links to things used in the project

MakerIoT SMD Prototyping Breadboard
Order this PCB from PCBWay