The myDuinoMini project is my attempt to make my own Arduino board based around the ATmega328P microcontroller, the name being a reference to Arduino and Arduino Mini bootloader. If you are unfamiliar with Arduino then please see my Arduino page. Intended to be a minimum prototype board, the myDuinoMini is similar to an Arduino Uno but lacks a USB controller so is actually closer to an Arduino Pro Mini or Arduino Mini. This has the advantage that the board is smaller than if it had on-board USB and the associated circuitry.
For reference, you can view information about the Arduino Pro Mini at:
https://docs.arduino.cc/retired/boards/arduino-pro-mini/
As the Pro Mini has the same I/O connection layout as the Arduino Nano it can be thought of as an Arduino Nano without USB.
The Arduino Mini page can be viewed at:
https://docs.arduino.cc/retired/getting-started-guides/ArduinoMini/
Please read on to learn more about the myDuinoMini project, which serves as an introduction to the ATmega328P and presents a worthwhile exercise in soldering.
Note that the images on this page can be downloaded from the bottom of this page for better viewing.
This project came about not just because of wanting to make my own Arduino board but also because I had acquired a number of ATmega328P ICs with labels on them saying 'ARDUINO MINI BOOTLOADER'. It wasn't clear whether the bootloader on the chips was for the Arduino Mini or Arduino Pro Mini, both boards use a SMD version of the ATmega328P, so that doesn't provide a clue. Since I used the DIP version of the ATmega328P, the myDuinoMini is much larger than the Arduino Pro Mini and Arduino Mini but it has some bonus features, which will be specified later. Note that the SMD version of the ATmega328P has a different pinout to the DIP version.
A brief summary of the ATmega328P's features is as follows:
32KB flash memory
2KB SRAM
1KB EEPROM
14 digital pins (I/O)
6 analog inputs
To learn more about the ATmega328P you can view the datasheet:
https://web.mit.edu/6.111/volume2/www/f2018/handouts/ATmega328P.pdf
Also, as a handy reference, the pinout of the DIP ATmega328P with Arduino pin number mapping can be seen at:
Since I was making my own Arduino I thought about the features I would like to add in the amount of space available on the perfboard - see the Soldering section for more information. I also wanted to use components I already had rather than buy ones especially for the project.
In addition to the ATmega328P and the basic components for it to work I added:
Six user switches with common connection - handy for testing inputs to the MCU/making selections that the program can respond to.
Six user LEDs with common connection - useful for indicating status, errors, etc.
Six additional GND and 5V header pins - convenient for use with the on-board switches, LEDs.
Additionally, the MCU crystal/ceramic resonator can easily be removed and the MCU's internal oscillator used instead, or the crystal/ceramic resonator can be changed for a different one as required. Note that a different frequency component may require different settings to be made in the Arduino IDE or other changes be made.
The user 'L' LED can easily be disconnected from the circuit.
Before soldering, I breadboarded the ATmega328P so I could test to see if the chip even worked, since I got it second hand in a job lot. So I connected the minimum - power, reset (with 10K pull up resistor), and a 16Mhz ceramic resonator to XTAL1 and XTAL2. I also connected an LED and limiting resistor to PB5, which is what many of the Arduino boards have the 'L' LED connected to. I applied 5V power and took reset low briefly, the LED blinked three times rapidly, which is a 'I'm alive' feature built in to the bootloader to signal it's running. Note that you must have a crystal/resonator connected for the LED to blink when reset is taken low.
For programming a sketch into the ATmega328P I found this guide:
https://www.gammon.com.au/breadboard
I started at the 'Test the chip' section. As you can see, an Arduino Uno was used to power, test and program the ATmega328P. I used a DCCcduino Uno (Arduino Uno compatible), uploaded the board detector sketch and it successful detected the breadboarded ATmega328P although oddly it showed the bootloader as consisting of all 0xFFs except toward the end, which the site suggests that means it doesn't have a bootloader (with hindsight I know it did actually have a bootloader).
Even though at the time I wasn't actually sure whether the ATmega328P had a bootloader or not I decided to try programming a sketch using a so-called FTDI cable/adapter, or in my case, a so-called USB to TTL adapter (a.k.a. UART adapter), which uses the CP2102 IC and has the necessary pins; RST, 5V, TXD, RXD, & GND. In Arduino IDE I opened the example Blink sketch, set the board to Arduino Pro or Pro Mini and Processor to ATmega328P (5V, 16 MHz). I then plugged the USB to TTL adapter into my Surface Pro, selected the port and clicked upload. However, it got stuck uploading with the PB5 LED rapidly blinking every few moments, suggesting that it's being reset multiple times.
So I went to the section 'Programming the Bootloader' on the previously linked to site and as instructed, opened the Atmega_Board_Programmer sketch and set the board to Arduino Uno. After uploading, I entered the serial monitor. I thought that I could try the Arduino Uno firmware (I later realised that the ATmega328P likely had the Arduino Mini firmware on it, which seems to be similar to the Uno firmware) so I entered 'U' and pressed enter, and then 'G' and enter to program, which was successful.
Returning to the Blink example sketch I set the board type in the Arduino IDE to Arduino Uno (since that was the bootloader the ATmega328P was programmed with). However, it still failed to upload. I noticed that the DATA LED on the USB to TTL adapter didn't light when you click upload so I tried my Waveshare PL2303 serial adapter and after clicking upload the TXD LED blinked a couple of times. This suggested the CP2102 adapter was faulty (I'm sure I've had issues with it before). Unfortunately, the Waveshare adapter doesn't have RTS, however, we can manually reset the ATmega328P to enable programming.
So I connected the Waveshare adapter to the ATmega328P, note that I put the shunt on the 5V side of VCCIO on the adapter. I held the ATmega328P's reset to GND, clicked upload in the Arduino IDE and when it said 'uploading..' I disconnected reset from GND. After a few moments the ATmega328P PB5 LED was flashing, showing it had been successfully programmed with the Blink sketch. Oddly, the Waveshare adapter chip got extremely hot (I've noticed this behaviour before and seems to be a fault with the adapter which otherwise works).
I tried another ATmega328P that supposedly already has the Arduino Mini bootloader and without programming any bootloader on it I tried the Blink sketch (with the board set to 'Arduino Pro or Pro Mini') using the Waveshare adapter using the same technique as before with manually taking reset low and it programmed successfully. So indeed the first ATmega328P did have the bootloader already programmed.
However, when I attempted uploading again I couldn't get it to upload, so I tried a different UART adapter in placed of the Waveshare one, which was an FT232RL adapter with the jumper set to 5V - this adapter is handy as it has DTR, RTS, etc., as well as the usual TXD and RXD, so I could try using DTR/RTS with a 0.1uf series capacitor connected to the ATmega328P's reset pin to automatically reset the MCU when uploading but it wouldn't upload. Even the manual reset method wouldn't allow me to upload - it just kept saying 'Uploading...'.
Through experimentation it turns out the ATmega328P chips I have with the 'Arduino Mini' firmware on are actually for the Arduino Mini and not the Arduino Pro Mini. I'm sure I had selected 'Arduino Pro or Pro Mini' as the board type in the Arduino IDE and it had worked, however, I think it reverted to Arduino Uno (which works with the Arduino Mini bootloader) as I have found that if you select the board type before selecting the port number it may return to the previously selected board type. So likely the ATmega328P ICs I have contain the Arduino Mini bootloader. Of course, I could put any compatible bootloader on the ATmega328P if desired.
If you do have trouble uploading a sketch using the manual reset approach and you're sure it's not a problem with the bootloader or the selected board type, make sure you release reset from GND a second or so after you see Uploading... appear in the Arduino IDE, if you release reset too soon the upload may fail. After you release reset the PB5 LED should rapidly flash three times and then uploading should complete - 'Done uploading' will appear in the Arduino IDE output window.
Although I hadn't fully tested the ATmega328P on breadboard I was confident that I could solder the circuit, having put together a final circuit diagram, which you can view below (and is downloadable from the bottom of the page as myDuinoMini_sch.jpg):
Notice how, as part of the main circuit, I've put the placement of the various headers (J1-J8) roughly in relation to each other and the ATmega328P (U1). The location of the crystal/ceramic resonator (Y1) on the diagram isn't significant (but in reality is located close to the MCU), the main thing is to show that it plugs into J6. Of course you're free to place the components whether you want but ideally the crystal/ceramic resonator and capacitors (C1 and C2) should be as close to the ATmega328P as possible.
I used a 6x8cm perfboard with conductive pads both sides, as well as metal 'fingers' along the edges of the two short sides (not necessary but could be useful). Of course you could plan more and draw out the layout of components on the board but I planned 'on the fly' as I soldered, thinking carefully about placement of components before soldering.
Here is a summary of the main steps of how I soldered the circuit and how the components are used:
28 pin chip holder in the centre of the board for the ATmega328P so that the chip can be removed if it becomes faulty.
14-way male header both sides of the chip holder (J1 and J2) along the long edges, allowing easy access to every pin of the MCU. I placed the headers as close as possible to the chip holder to minimize soldering (since you can just solder across the pins) but does makes it more difficult to remove the ATmega328P, although I purposely kept the short edges of the chip holder clear of components to help with removing/inserting the IC. I checked that 'DuPont' wires will fit on the headers just about.
Capacitors C1 and C2, placing them as close to the chip holder as possible.
The reset switch (SW1) with pull up resistor (R1), as well as resetting the MCU, it allows for uploading code to the ATmega328P by pressing the button instead of using a wire to GND.
3-way male header J6 for the crystal/ceramic resonator. Ceramic resonators typically have the necessary capacitors built in but if you are using a crystal then you will need to include them, around 20pF each should be sufficient. What you could do is solder the capacitors to the legs of the crystal and form a middle pin for the GND connection on pin 2 of J6.
The 'L' LED (LED1), connected to PB5 with 330R limiting resistor (R2), has a header and jumper (JP1) in series so the LED can be easily disconnected as to not interfere with anything else that you want to connect to PB5.
Power LED2 with 330R limiting resistor (R3).
At this point it would be best to do a power on test before soldering anything else but first, thoroughly check for continuity and shorts before inserting the ATmega328P, and then power can be applied, 5V to VCC and 0V to GND. If the power LED doesn't come on immediately then power off and check your soldering. If the power LED was illuminated then the 'L' LED should flash if the Blink sketch was previously written to it. Pressing the reset switch should cause the 'L' LED to blink rapidly three times. After about nine seconds the LED should be blinking again if programmed with the Blink sketch.
Continuing with the soldering (with power disconnected, of course) ...
6-way male header for additional GND points (J7) and 6-way male header for extra VCC connections (J8).
The six user switches (SW2-SW7), which I had in SIP (Single In-Line Package) form, with a common connection, so it takes up little space. You could instead use a DIP (Dual in-line Package) switch array and common up the connections on one side.
7-way male header (J3) for the six user switches (SW2-SW7) including the common connection.
Resistor network (RN1) to act as pull-up or pull-down resistors for the six user switches. I used a SIP resistor network which contains eight resistors with a common connection as I didn't have a package that had six resistors with a common connection that had high enough resistance.
3-way male header (J4) providing the common and the two spare resistors for the resistor network RN1.
Six user LEDs (LED3-LED8) of different colours, although I used individual rectangular LEDs you could use a bar graph display. I only had 5 colours - red, green, yellow, blue, and white, so I used two yellow LEDs. The most difficult part was keeping the LEDs roughly level since I had them raised somehwat above the board. I could have cut/3D printed some form of holder but I would still need to protect the LEDs from excessive heat during soldering and a holder would get in the way. Of course you cold cut the LED leads to a set length but without a holder the LED could slip during soldering.
Resistor network (RN2) limiting current to LED3-LED8.
7-way male header (J5) for the six user LEDs (LED3-LED8) including the LED common cathode connection.
With everything soldered and checked we can do a number of tests to make sure it's working. Firstly, to test the LEDs I wrote a simple Arduino sketch, available from the bottom of the page as DigitalWriteMulti.ino, which turns digital pins D2 to D7 on/off in turn. Before uploading the sketch, you need to connect wires from LED3-LED8 to D2 to D7 (ATmega328P PD2-PD7), and LED3-8_COM to GND. After uploading the sketch you should see the LEDs turn on/off in sequence and then repeat.
Before uploading I tried connecting a 0.01uF capacitor between DTR of the FT232RL adapter and RESET of the ATmega328P so I wouldn't have to press the RESET button to upload. However, during uploading I got an error:
avrdude: stk500_recv(): programmer is not responding
Yet, the sketch was successfully uploaded as the LEDs turned on/off as programmed. It's also possible to use the adapter's RST connection instead but I favoured DTR as it already had a pin soldered to it.
For testing the switches, you can find the DigitalReadMulti.ino sketch at the bottom of the page. With the switches (SW2-SW7) in the off position, connect them to D2-D7 (ATmega328P PD2-PD7), the switch common (SW2-SW7_COM) to VCC, and RN1 common (RN_COM) to GND.
After uploading the sketch, open the serial monitor set to 9600 and you should see:
2=0, 3=0, 4=0, 5=0, 6=0, 7=0,
Note: 0=switch off, 1=switch on.
Turn each switch on in turn and you should see a ‘1’ next to the digital pin number, turn the switch off and the value will become 0 again.
Keeping the digital pins connected to the switches, connect the switch common (SW2-SW7_COM) to GND and RN1 common (RN_COM) to to 5V. Turning a switch on should trigger a ‘0’, and off a '1'.
The last thing to test was the analog inputs, fortunately there is a suitable example sketch built into the Arduino IDE, ReadAnalogVoltage (File->Examples->Basics->ReadAnalogVoltage). A potentiometer of 10K needs to be connected with its centre connection to A0 (ATmega328P PC0) and the other two connections to VCC and GND respectively. After uploading, open the serial monitor set to 9600 and you should see values continually displayed. Adjust the pot wiper toward one end and value should decrease toward 0, the other way and the value should increase toward 5. You can test the other analog inputs either by connecting the pot centre connection to the other analog inputs A1-A5 (ATmega328P PC1-PC5) or adapting the sketch to read and output to the serial monitor all the analog values.
This time when I uploaded the sketch, even though I again used a 0.01uf capacitor between DTR of the FT232RL adapter and RESET of the ATmega328P it uploaded without error. I noticed that when the capacitor is connected between DTR and RESET it takes nine seconds from opening the serial monitor before the analog values are displayed, without the capacitor the values show instantly. When opening the serial monitor it resets the MCU so perhaps the capacitor holds the reset longer?
Of course there are other tests you could do but at this point it should be clear whether the board is behaving as it should.
This section covers thoughts I had about improving the myDuinoMini that you may like to carry out:
On-board potentiometer, useful for testing analog inputs and for input control to a sketch.
Alternate means to provide power to the board, such as barrel jack or USB.
Ability to switch the user LEDs around so they have either common cathode or common anode.
7-segment LED display to provide decimal/hex readout.
More spacing between headers and other components. I placed them as close as possible to minimize soldering since I could just solder across the connections. Unfortunately, the LEDs get a bit obscured because of wires hanging over them.
More decoupling, perhaps an electrolytic capacitor for power input.
Professionally made PCB.
All content of this and related pages is copyright (c) James S. 2024