Arduino

Introduction

The Arduino platform is based on a range of microcontroller interface boards especially designed for those new to microcontrollers or those who would not normally build electronic circuits, and those that need to do quick prototyping. The truth is that an Arduino can be used by almost anyone and in addition to its obvious uses it can serve as a learning tool, and the large amount of software available for the various Arduino boards takes away a lot of the difficulty in getting started with something new. Whatever your needs, someone else may have already tackled a similar project and you can use their work (with permission/crediting as necessary) which gives you a head start but of course you can also try yourself from scratch, which is a good learning experience. 

Arduinos are good for prototyping rather than for projects that are supposed to endure long use although they have been used successfully in semi-permanent installations. Once you have got what you set out to do working with an Arduino you can then design (or have someone else do the design) a more permanent version if that's your intention rather than just trying something out.

Please see YouTuber I Like To Make Stuff's video which goes into a bit more detail about Arduino and what it can do:

There are of course alternatives to the Arduino, with the PIC microcontrollers being very useful and versatile chips and there are evaluation boards that let you experiment with them more easily, which you could think of as a sort of equivalent of an Arduino. You may also have heard of the Raspberry Pi which, like an Arduino is great for interfacing, but the Arduino is better for real time tasks than a Raspberry Pi whereas a Raspberry Pi is more suited for networking and other complicated tasks than an Arduino. However, with the release of the Raspberry Pi Pico (see the main Raspberry Pi page) the Arduino has some serious competition, especially considering the Pico's low cost.

On this page you will find more information about the Arduino platform, various projects, and tips - please see the links to the right.

Overview

There are a number of different official Arduino boards including the Uno, Mega and Nano, which you can check out on the official page:

https://www.arduino.cc/en/hardware

There are also clones that are directly based on the official boards, as Arduino is open source so anyone can make their own version of an Arduino and sell it but it is always encouraged to buy an official Arduino board to support the original designers and the clones may have subtle differences (for example, one clone I have runs at a slower speed than the official board). You can also find Arduino boards tailored to a certain need (such as for robot projects or 3D printer), as well as boards that have some form of compatibility with Arduino but are otherwise very different in architecture - please see the Compatible boards section.

Each of the Arduino boards has different features, such as the amount of memory, the speed of the microcontroller, the size of the board and the number and type of I/O connections (for connecting lights, switches, etc.). The Arduino Uno is usually the first Arduino a beginner uses but for more complicated projects the Arduino Mega is better as it offers more I/O connections. The Arduino Nano is similar to the Uno but unlike the Uno the Nano fits into standard size breadboard thanks to the male header pins.

The programming language used with the Arduino is called Wiring and is similar to C/C++ with gives access to reading from and writing to the I/O pins as well as for configuration, and the programs you write or obtain from other people are called 'sketches'. After a sketch (program) is written on a computer, it can be uploaded to an attached Arduino and then the program will run automatically after the board resets (or at least that is the behaviour for most Arduino boards). Since an Arduino board typically can be programmed 100,000 times you can make changes as often as needed. Like with most microcontrollers, the program code for the Arduino is stored in flash memory (like what is used in SD cards) on board the microcontroller on the Arduino board; you get 32KB on the standard Arduino Uno, for example.

Going into more detail about the Arduino Uno as it's a good starting point, you can check out its official page at:

https://store.arduino.cc/products/arduino-uno-rev3

As you can see it uses an 8-bit ATmega328P microcontroller running at 16MHz, has 14 digital I/O pins (of which 6 support PWM), 6 analog inputs, 32KB flash memory, 2KB SRAM,  1KB EEPROM, and an on-board LED connected to digital pin 13, useful for debugginf. The board measures 68.6 x 53.4 mm, weighs 25g, and it has two rows of connectors which provide power, and interface in the form of digital I/O lines that can be programmed as either inputs or outputs, and a number of analogue inputs. You can plug wires into theses sockets, although it's best to use the type with pins either end so that the wires stay in place. You can also plug in a circuit board known as a shield which has a number of headers for connecting with the Arduino. You can buy these shields ready made designed for a set task (for example wireless communications) or there are ones available with a matrix of holes for soldering your own components. You could make up a shield yourself using stripboard although I found that some connections didn't quite line up so I had to bend the header pins somewhat. If you do buy a shield then make sure it's compatible with your Arduino.

Whereas most of the Arduino boards use an 8-bit Atmel microcontroller, the Arduino Due breaks with that tradition as it uses a 32-bit ARM microcontroller. It has an impressive spec but its logic level is at 3.3V (as opposed to the 5V logic level of the 8-bit Arduinos). This means that interfacing with non 3.3V devices-including non Due Arduinos-can harm an Arduino Due. The workaround is by using a logic level shifting circuit to make sure the Arduino Due is interfaced only with 3.3V logic.

While the Arduino is great for taking away some of the difficulty of interfacing microcontrollers with input and output devices, you pay a price for that convenience; I'll explain why. Microcontrollers, like other processors run on machine language, which are the binary values (0's and 1's) that make up the low-level instructions that form the microcontroller's program. You can program a microcontroller in assembly language, which consists of a number of instructions that represent the machine language values, and are more readable than a bunch of 0's and 1's, or even the hexadecimal equivalents (i.e. 5F, CE, etc.). Assembly language gives you great control over the microcontroller as well as optimum speed but assembly language is more difficult to use and not recommended for beginners.

So, the Arduino team went with a more high level programming language (Wiring) that is more easier to use than assembly language but the Wiring code gets converted into machine language before being uploaded to the Arduino. It's this converting that can cause programs written for the Arduino to run slower than if the chip had been programmed directly in assembly language. The conversion process is optimised, that is, the assembly language instructions are chosen to give as high speed as possible. What introduces slow down is that some Wiring commands, such as the digitalWrite() function, have to do error checking, which means more assembly language instructions are required, slowing down how fast the program runs.

Fortunately, the Wiring programming language provides a way to more directly access the Arduino ports, giving greater speed at the expense of getting closer to the hardware level of the Arduino which may be confusing to those new to the Arduino or microcontrollers in general. In summary, if you are doing something simple such as flashing an LED, digitalWrite() and similar functions will give you all the speed you need. But if you need greater speed, such as to update a large display frequently, if may be that you will have to use a more low-level means of accessing the Arduino's ports. If you do use the low level commands your program will likely take up less space than if you had used the high level functions.

The process of building an Arduino circuit is writing the Wiring code using a PC and then transferring the code to the Arduino (usually using USB). Lights, switches, and so on can then be connected to the Arduino to complete the circuit but do so after removing power to the Arduino. Also, before powering up the Arduino again, check and double check you have wired it up correctly. It's a good idea to use coloured wires to help prevent mistakes such as red for positive power supply line, black for a ground connection, for example.

Build Your Own Arduino Kits

This section is dedicated to Arduino development boards that you can build in kit form which require soldering and are a rewarding way of not only practicing soldering but also learning how an Arduino works.

OLIMEXINO-85-KIT

I came across this through-hole Arduino-like kit from Olimex for £2.80 on Mouser in 2023, based on an ATTINY85 8-bit microcontroller (hence the name), so I bought it thinking it would be fun to put together and good value for money since the microcontroller alone is almost the same cost as the kit. The OLIMEXINO-85-KIT is inspired by and somewhat similar to the Digispark development board.

You can find the OLIMEXINO-85-KIT product page at:

https://www.olimex.com/Products/Soldering-Kits/OLIMEXINO-85-KIT/open-source-hardware

There you will find links including the soldering guide:

https://www.olimex.com/Products/Soldering-Kits/OLIMEXINO-85-KIT/resources/Olimexino-85_KIT_guide.pdf

And user manual:

https://www.olimex.com/Products/Duino/AVR/OLIMEXINO-85-ASM/resources/OLIMEXINO-85_manual.pdf

There is also an assembled version OLIMEXINO-85-ASM which you can read about at:

https://www.olimex.com/Products/Duino/AVR/OLIMEXINO-85-ASM/open-source-hardware

The manual has the schematic for rev B but as indicated in the manual there is a link for the current schematics:

https://github.com/OLIMEX/OLIMEXINO-85/tree/master/HARDWARE/OLIMEXINO-85-ASM

There you will find schematics for all revisions, including rev. c, which is the version I have and the most recent revision. It looks like there are provisions for additional resistors and diodes which aren't normally provided in the kit, certainly there are unused pads on the PCB with the corresponding part number that would accommodate SMD components.

The kit features the following components:

x1 32mm x 20mm PCB

x1 USB-B connector

x2 1N4148 diodes

x5 resistors (x3 1.5K, x2 22R)

x1 ATtint85 in chip holder

x2 capacitors (x1 10uF, x1 100nF)

x1 8-way right angle male header

x1 momentary switch

x2 LEDs (x1 red, x1 green)

Note that older versions of the board used mini USB instead of full size USB-B, and the kit used to come with two clear body LEDs, which perhaps caused some confusion (not that it's hard to test them to determine the colour) whereas my kit came with a single clear body LED which lights up red, as well as a green body LED.

Since the board is very small and the various components are packed together it's perhaps not the best soldering kit for beginners but if you have experience like me you shouldn't have trouble. This was the order I soldered the components; resistors, ceramic capacitor, diodes, LEDs (green for power, red for stat), reset switch, electrolytic cap, IC socket, header, USB socket. It took me 45 minutes to solder the kit, carefully following the instructions online, note that the online manual still mentions a USB mini connector on page 8, which was used in the original design.

After finishing the soldering and before putting the microcontroller chip in the socket I plugged the board into a USB power adapter and made sure the power LED came on. I also measured the voltage between pin 8 (VCC) and 4 (GND) of the IC socket, which was 3.8V. This is correct, as there's 2 diodes in series with VCC and USB +5V, which brings the microcontroller voltage down low enough such that its I/O will operate at 3.3V, in line with USB spec, although there is no USB controller, instead the microcontroller emulates USB using V-USB.

Even with everything soldered and checked I quickly found it difficult to program the board, which unfortunately is my second experience of having trouble getting an Olimex product to work, the first being an FPGA board (but I was successful eventually). Looking online a lot of people have had trouble getting the kit to work but whether it was the same fault as me - which you can read about toward the end of this section, which led me to successfully programming the board - isn't clear. One potential problem with the OLIMEXINO-85-KIT is that it appears to originally be from 2014 and because it uses V-USB, it doesn't play nicely with modern operating systems (or Windows, at least), but again, not the issue for me once I fixed the fault.

The OLIMEXINO-85-KIT is supposedly preloaded with the "micronucleus tiny85" bootloader, which is similar to a typical Arduino bootloader but designed especially for the AVR ATtiny microcontroller family, and is meant to make it easy to upload sketches to the microcontroller using the Arduino IDE. You can find the GitHub page at:

https://github.com/micronucleus/micronucleus

Looking at the user manual for programming the board it says that we need to use a modified version of the Arduino IDE to upload code to it but because the bootloader is also used by the Digispark board we can use the same instructions. This is the link that is provided in the manual that explains how to install the drivers and set up the Arduino IDE to be able to program the board:

http://digistump.com/wiki/digispark/tutorials/connecting

Rather than a 'modified' version of the IDE, you download and install the normal Arduino IDE (if you don't already have it), and then you download and install the digistump driver. Then, in the Arduino IDE you add the Digistump AVR Boards using the Boards manager and during the installation the Device Driver Installation Wizard will pop up but for me (I'm using Windows 10) it showed an error: 'Digistump LLC (usbser) Ports' install failed. The same error can be seen here:

https://arduino.stackexchange.com/questions/30003/digispark-usb-issue

I did come across this page:

https://github.com/ArminJo/DigistumpArduino

Which has a different boards manager URL allowing access to V1.7.6:

https://raw.githubusercontent.com/ArminJo/DigistumpArduino/master/package_digistump_index.json

That was also unsuccessful but from what other people have said online it doesn't matter if one of the drivers (the top one in the Device Driver Installation Wizard) doesn't successfully install as it's a duplicate anyway. So I modified the built-in Blink example by changing LED_BUILTIN to 1, as that's what the board's stat LED's connected to, and if the driver isn't the issue I should still be able to program the board but it's not like an ordinary Arduino which you plug into your computer's USB and then click 'Upload' in the Arduino IDE. With the OLIMEXINO-85-KIT you have to first have the board disconnected from your computer's USB, click 'Upload' in the Arduino IDE and you will be prompted to plug in the board within the given time, and then the board will be programmed. However, for me (and a lot of other people) that never happens, the board is never detected it times out and Windows pops up with 'Unknown USB Device (Device Descriptor Request Failed)' error. The stat LED will flash a few times on the board, which is supposedly a sign the bootloader is running, but the Arduino IDE will not detect the board.

I've tried multiple Windows 10 computers and even a Windows 8 computer, and current and older versions of the Arduino IDE (as far back as V1.6.5., which is recommended in the OLIMEXINO-85-KIT manual, and the most recent at the time, V2.1.1), without success but unfortunately I don't have a Windows 7 computer as I wondered if the bootloader is so old it doesn't like anything newer than Windows 7. Someone online did suggest plugging the board into a hub with the reasoning being that it's a problem with USB 3 and the hub will effectively downgrade to USB 2 (so, has to be a USB 2 hub) but that didn't help me.

Another step I tried also without success: setting the programmer to micronucleus in the Arduino IDE but that made no difference and supposedly is an unnecessary step.

Before arriving at the ultimate solution I did look online and found a site which details how to program the microcontroller directly using an Arduino as an ISP (In-System Programmer) programmer along with the Attiny package:

http://dumbpcs.blogspot.com/2015/11/programming-your-attiny85-with-arduino.html

Note that writing to the microcontroller in this way wipes the bootloader from it.

To use this approach on the OLIMEXINO-85-KIT, after installing the Attiny package and programming the Arduino with the ISP sketch, we connect the Arduino Uno to the OLIMEXINO-85-KIT header pins as follows:

Arduino OLIMEXINO

5V VCC

GND GND

10 #RST

11 #0

12 #1

13 #2

Don't forget the 10uF capacitor on the Arduino reset and GND pins. Because the connection between the OLIMEXINO-85-KIT reset header pin is open (on my version of the board, at least) you need to solder a bridge across RST_E on the underside of the board so it may be easier to put the microcontroller into breadboard and wire it up as shown on the site previously linked, which is what I did.

Before uploading the blink sketch as a test I changed LED_BUILTIN to 1 to be compatible with the OLIMEXINO-85-KIT's on-board user LED.  As I was using Arduino IDE V2.1.1 I had to select Sketch->Upload Using Programmer (otherwise you get 'a programmer is required to upload' error'. This actually starts the upload process (if using the new IDE) and the IDE then reported it had written to flash, which only took a few seconds. When I put the chip back in the OLIMEXINO-85-KIT board and connected it to my PCB the LED flashed briefly as before, as if the original bootloader is still running, but when I put the chip into breadboard and connected an LED and resistor to pin 6 (output 1) with the Arduino powering the chip (all other I/O pins still connected to the Arduino ) the LED flashes rapidly unless pin 1 (reset) is taken to GND. This is odd as the LED should flash on/off every second but otherwise the code upload appears to have worked.

It seems the issue is that the internal clock needs to be set to 8MHz, which involves using the Burn bootloader option (although it doesnt actually burn a bootloader but instead sets various options in the chip). This isn't explained on the dumbpcs site but is in the page it links to:

http://highlowtech.org/?p=1695

Under 'Configuring the ATtiny to run at 8 MHz'.

Then upload the sketch and the LED will flash on/off every second. I further tested by changing the Blink sketch so that the LED turns on/off every 5 seconds (change the delay value from 1000 to 5000). I then selected the 'Upload Using Programmer' option again and it compiled and uploaded and when I reconnected the LED to pin 6 it flashed on/off every 5 seconds. Oddly, if I put the chip back in the OLIMEXINO-85-KIT, whether I connect the board's USB to my PC or a power supply, the stat LED doesn't flash as I programmed it to but the LED does blink a few times when you connect the OLIMEXINO to a PC.

Back to the original problem: after first soldering the kit I had measured the power supply pins of the microcontroller and since I had got an acceptable reading it had seemed there wasn't a fault with my soldering but it shows how important it is to visually check your soldering very carefully as well as by other means as when I checked the supply pins again the reading was too low. It turns out there was a bad solder joint on pin 4 (GND) of the IC socket, which must have been passable initially. The bad solder joint turned out to be the reason why I couldn't program the board when it had the bootloader installed and the reason that the stat LED didn't flash even after programming the microcontroller directly using an Arduino while the microcontroller was in breadboard.

Now that the solder joint was fixed, measuring again across the IC power supply pins once more I got 3.62V (this was with the chip installed in the socket) and the LED was flashing off/on as I had programmed it to via the Arduino as an ISP programmer. I also checked and indeed the board now worked whether powered over USB or through the header pins. With the board fixed I should have been able to program it over USB but as I had programmed the microcontroller directly the bootloader was wiped, one sign of which is that the when the board is powered the stat LED turns on immediately without any delay unlike if there was a bootloader present. So the next step was to put the bootloader back on, the process is explained on page 10 of the user manual and it involves downloading the required files from the OLIMEXINO-85-KIT main page, the link is called 'OLIMEXINO-85 demo examples, libraries and bootloader binaries are available at our GitHub repository'. The link is takes you to is:

https://github.com/OLIMEX/OLIMEXINO-85/tree/master/SOFTWARE

There are both hex and elf files, the elf file is better as it contains the required fuse and configuration bits, which determine various settings on the microcontroller, and if set wrong, can cause major issues with using the microcontroller but fortunately the OLIMEXINO-85-KIT gives the required fuse settings. The Micronucleus bootloader that is recommended to use is V1.06 from 8 years ago, the manual warns against using a newer version.

The manual, however, doesn't detail the hardware setup to program the bootloader but I was successful using the TL866CS MiniPro programmer, here are the steps I used:

Open the MiniPro software (I used v6.85), select ATTINY85 as Device, click on the Config tab and make these changes:

Check 'SELFPRGEN=0' under 'Extended Fuse Byte', you should see 'Extended Fuse Byte' value at the bottom of the window change to 0xFE under IC Config Information.

Check 'BODLEVEL1=0' under 'Fuse High Byte', 'Fuse High Byte' value will become 0xDD.

Uncheck 'CKSEL0' and check 'CKSEL1' under 'Fuse Low Byte', 'Fuse Low Byte' value will become 0xE1.

For reference, here are the fuse settings in visual form:

Load the hex file previously downloaded from the previously linked GitHub page, in the 'File load Options' pop-up window select 'INTEL HEX' for File Format. Then Program the chip. In the 'Chip Program' pop-up window uncheck 'LOCK Bit' (not necessary but best to be safe you don't accidentally change the lock bits). The programming should happen very quickly.

After following those steps I put the microcontroller back into the board and connected it to my PC's USB, the stat LED was off and then after 5 seconds it flashed on/off about every second, perhaps a built-in test program. I then modified the Arduino Blink sketch to flash every 5 seconds, clicked upload, connected the board and after a couple of seconds it started uploading and finished after a few seconds. The stat LED then started blinking every 5 seconds as expected, showing a successful sketch upload.

Note that the output of the Arduino window says it detected firmware version 1.6 but I'm not sure if that's actually V1.06, as I can't find V1.6 online.

Even though I had problems initially programming the OLIMEXINO-85-KIT due to a bad solder joint I did get it working as we've seen and to add, on a Windows 10 Surface Pro using its USB 3 port, so it is very much possible to use the kit with more modern computers.

Now that I was able to upload sketches to the OLIMEXINO-85-KIT using the Arduino IDE I went on to further test the microcontroller and see if I could get the remaining I/O pins working. I modified the Blink sketch and set I/O numbers 0 to 2 as outputs (the numbered I/O are written on the PCB by the header pins, preceded with a '#' symbol) and then turn each of them on and off in turn. As the on-board stat LED is connected to I/O 1 I only needed to connect an LED and resistor to I/O 0 and 2 via the headers pins. That worked as expected but also using I/O 3 and 4 was a bit more difficult as they are used for USB communication and although the board's header pins connect directly to the microcontroller pins, both I/O 3 and 4 have series 22R resistors to USB D- and D+ respectively, and D- is also pulled up to VCC using a 1.5K resistor. However, I found that although I could use I/O 3, if I also used 4 it caused the power LED to blink off periodically and the sequence to pause as if the bootloader was running again (I checked that at this point the supply voltage drops low briefly, suggesting a reset). This happens if powering the board via USB, whether connected to a PC's USB port, or power adapter, but if powering the board via the header pins the sequence runs correctly and I can use I/O 0 to 4 without problems.

It still remains the issue that using I/O 3 and 4 while the board is plugged into a PC can cause you program to behave oddly and the PC to report a bad USB device, so it's just as well the user program (sketch) runs after the bootloader when the board is plugged into USB, allowing us to program the board but it's best to not  have anything connected to I/O 3 and 4 (such as LEDs, for example), while the board is plugged into the PC. Instead, after uploading the sketch, disconnect the board, attach any components you need to, and then power it externally to check your program is running correctly.

Compatible Boards

The Arduino 'compatible' boards in this section are those that have some form of compatibility with a specific Arduino board even though they have at their heart a very different architecture. Here are some that I've covered:

chipKIT

The chipKIT boards have Arduino compatibility but are much more powerful.

Intel Galileo

The Intel Galileo is an officially certified Arduino compatible board that runs Linux.

pcDuino

The pcDuino is a Linux computer that emulates an Arduino Uno.

STM32 microcontroller boards

The STM32 microcontroller boards have Arduino compatibility.

Other Arduino Kits

This section is for kits that use an Arduino as the 'brains' of a larger device.

8BitCADE Original

The 8BitCADE Original is a build it yourself handheld game console kit which I received as a gift in late 2023, it is based around a Pro Micro Arduino-like development board, which serves as the brains of the gaming machine. The console is aimed at the age range 11+ and features a 500mAh rechargeable battery with USB micro charging, monochrome white on black OLED display, six action buttons and a reset button, and a piezoelectric speaker. Rather than playing games off a cartridge, a single game at a time can be programmed into the console via the micro USB port that is part of the Pro Micro (ATmega32U4 based), with over 200 games available and the ability to make your own using the Arduino IDE.

You can find the main product page at:

https://8bitcade.com/en-gb/products/8bitcade-original

It appears the 8BitCADE was originally a Kickstarter and the original product was called 8BitCADE Level UP, you can check out the Kickstarter page at:

https://www.kickstarter.com/projects/jackdaly/8bitcade-level-up/

You can view the official showcase video of the 8BitCADE Level UP:

The console has a more rounded design than the 8BitCADE Original that followed it.

After receiving your kit it's a good idea to check the contents before you begin the assembly process:

https://cdn.shopify.com/s/files/1/0657/0718/0248/files/Parts-List-Template_01.pdf?v=1689019095

The following video is an official 'make' guide for the 8BitCADE Original, which shows the more rectangular version, which is the version I have.

 As this video is from early 2023 it suggests the kit was made available to buy at a similar time. This is the video I followed to assemble the kit and it took me just over 2 hours to finish, but as I highlight below there are a number of things to point out about the video, some of which slowed me down.

No mention of anti-static precautions although a suitable looking mat has been used.

At 7:54 no mention of snipping the switch pins which otherwise could pierce the battery when later fitted.

Even though the battery connector is the first thing to be soldered in the video, the connector is no longer attached to the PCB later in the video. It's not mentioned but it would have been better to solder the connector after the headers as it can get in the way when soldering them. 

At 22:16 suddenly the OLED header appears soldered to the PCB with no mention of soldering it even though it's required before soldering the display to it. Also, the video should have highlighted the need to snip the header pins on the OLED side.

At 22:53 suddenly the Pro Micro board has been soldered to the headers. Because I had soldered the edge connector first (which they do at 21:11) it was tricky to solder the micro board as the connector was in the way.

At 30:35 they go on to putting together the case but it would have been better to have done a first test of the electronics, although it doesn't take too long to remove the case should there be an electronic fault.

The screws that hold in the display, although not really necessary as it shouldn't be possible to press down on the top piece of plastic enough to do harm to the screen, are completely missed out from the video, explaining why I had two screws, spacers, and nuts left over. I couldn't see the display screws on any of the images on the 8BitCADE site (doesn't help they keep showing the same 3D render which omits them) but on an Amazon page, for example, I could just about see them. Since I worked out what the leftover pieces were for later rather than sooner it was tricky to fit the spacers between the display and the PCB and then fit the M2 screws, and even when I did get the screws in the nuts wouldn't stay on when put on the end of the screws, as if the screws were too short. Note that if you don't get the screws in flush with the display the top plastic piece won't go on, so perhaps it's best to not bother with them.

DFROBOT Beginner kit for Arduino

The DFROBOT Beginner kit for Arduino is a great way to start off with using an Arduino as well as a means to top up your components, although more so if you get the kit second hand to get the best value for money. Whereas the kit will set you back around £40 ($50) I was able to get it complete but lightly used from eBay for shy of £19.

In the kit you get an Arduino Uno R3 compatible DFRduino UNO R3 microcontroller board, a number of sensors, lights, switches, wires, breadboard, and prototyping shield contained in a plastic box. Each component is packaged individually and clearly labelled, which is great for beginners to quickly locate components but not so good for the environment. As well as a Getting started card which includes links and lists of components in English and Chinese, also included are 15 project cards showing breadboard layout and the required components.

The product page can be found at:

https://www.dfrobot.com/product-345.html

Links on the site includes a link to a downloadable 'Arduino Getting Started tutorial' PDF, which introduces the Arduino platform, installing software, as well as details of the various projects that can be made with the kit, which includes explaining what the various components do and of the concepts of the microcontroller world such as I/O. Although well written, as to be expected of a Chinese product there are some less than perfect translations and some misleading text. For example, in one section it is explained that different types of variables take up different amounts of space and that the microcontroller in the Uno has 32K, which is incorrect as that 32K is for program storage, not variable storage which is stored in RAM. I also noticed mistakes in the code such as missing parentheses, semicolon, etc. which could easily cause the beginner to slip up. This brings to the other but related problem with the kit, as far as I can tell the Arduino project sketches aren't downloadable and have to be copied into the Arduino IDE text editor but that results in less that desirable formatting and comments spilling on to the next line, and multiple 'error: stray '\343' in program' and similar errors when trying to compile the sketch. Copying into Notepad and then into the IDE didn't help and copying sections at a time to the IDE wasn't a fix either although some parts copied didn't introduce errors. I ended up typing by hand into the IDE the code that wouldn't work when copied as some parts when copied didn't result in any errors.

Projects

82C54 Timer Test

I needed a timer chip for a project I was working on (see GameBird) and found I had a number of 82C54 timer IC's which each contain 3 independent 16-bit down counters. The counters can each be set to 1 of 6 modes (with binary/BCD selection) and they have their own clock inputs (maximum of 8MHz for the standard version), counter outputs, and gate inputs (enabling/disable counting). Note that depending on the manufacturer there may be 2 letters before the part name, e.g. CS82C54.

You can view the datasheet at:

http://www.intersil.com/content/dam/Intersil/documents/82c5/82c54.pdf

Let's look at the circuit for the test:

An Arduino Uno (or similar) communicates with the 82C54 via the data bus (D0 to D7), 2 address lines (A0 & A1), WR and RD; the 82C54 is always selected as CS is tied low. The 82C54 was designed with the 8086/8088 CPU in mind and that is why there are separate WR and RD inputs.

A crystal oscillator generates a square wave of 4MHz which feeds into the three clock inputs of the 82C54 (CLK0-CLK2). The 3 gate inputs (GATE0-GATE2) are always held high so that the counters always run. To check that the timer is running correctly use an oscilloscope or logic analyzer to monitor the 3 outputs (OUT0-OUT2) separately or together.

The Arduino code for this test is available to download from the bottom of this page and is called 'Timer_82C54_Test.ino'. In the setup function you will find a number of test function calls, most of which have been commented out. They are as follows:

test1()

Test counter 0 in mode 3; only write MSB of initial count

test2()

Test counter 0 in mode 3; write least significant byte first, then most significant byte

test3()

Test counter 0 in mode 2; only write MSB of initial count

test4()

Test all 3 counters in mode 3; only write MSB of initial count

To have a particular test run simply uncomment the test function and make sure the others are commented out, and then upload to the Arduino. The first test will have counter 0 output a square wave (mode 3) by specifying the most significant byte of the initial count value only. Test 2 does the same as test 1 but both the least and most significant bytes are specified. Also, there is extra code in setup() for test 2 which outputs to the serial monitor the hex 16-bit value of counter 0, 10 times. Depending on the value used for the counter and whether a different clock input to the timer is used you should see the values go lower each time. Note that if the counter timing is very short then it's possible that a value that follows will be higher than the previous. As for test 3 it puts counter 0 into mode 2, the rate generator mode, which outputs a brief pulse when the count goes to 1. Lastly, test 4 makes use of all 3 counters in square wave mode, giving the counters each their own counter value.

The program is a bit more complicated than perhaps it should be due to writing directly to the Arduino ports in setDataByte() and similar, the direct reading of the ports in readDataByte(), although the code could be simplified somewhat. The issue is that the first usable digital I/O pin of the Arduino is D2 as D0 and D1 are used for serial communication so we have to shift the data bits and split them over port D and port B. In addition, we have to combine other signals with port B. I did, however, take a shortcut with setting the data pins to input and output by using a loop (see setDataWrite() and setDataRead()). Note that there is a fair amount of code behind the various Arduino functions such as setDataWrite(), so they are quite slow. The delays I have put in using the delay() function could actually be shorter, in the microseconds.

For the repetitive signal modes you can easily work out the frequency:

output frequency (Hz) = input frequency (Hz) / count

Where input frequency is the frequency of the signal fed into CLK0, CLK1, or CLK2, and count is the initial count. The maximum count is actually 0 not 0xFFFF, when in binary mode, as the down counter will happily start on 0 and then decrease to 0xFFFF.

To calculate the pulse period:

pulse period (s) = 1 / output frequency (Hz)

I tried two different crystal oscillators for this test and experimented with different timing values as I wanted to make sure that I could get the timer to work before I used it in my project.


AT93C46 Test

The AT93C46 is a 1Kb EEPROM chip that uses a '3 wire' interface and can be configured as either 128 x 8 or 64 x 16, making it suitable for storing settings or an ID for a system. It is simple to use and can be programmed a million times and it is claimed the data will be held for 100 years. 

You can find the datasheet here:

http://ee-classes.usc.edu/ee459/library/datasheets/AT93C46.pdf

To test out the AT93C46 I wrote an Arduino program which you can find attached to the bottom of this page as 'AT93C46_EEPROM_Test.zip'. Download the file, un-zip it and upload the program to an Arduino Uno or similar.

Hardware connections to the AT93C46 can be found near the beginning of the file in the 'Hardware setup' section. The chip uses a serial interface involving DI for data input, DO for data output, and SK for the clock (maximum 2MHz). There is also the chip select (CS) input which is active high and permits the transfer of data. To read from the chip or write to it you need to send it an instruction which for reading requires a single instruction but for writing you have to enable programming first, do the write and then disable programming, so there are 3 instructions needed for writing.

In the setup function we define our inputs and outputs and set the default state for the outputs. Next we set serial port data rate and turn on the built-in LED (labelled 'L' on the Arduino Uno) to show we are about to access the EEPROM. Once that is done we enter a loop and read in 16 bytes (addresses 0 to 15), output the current memory byte to the serial port, increase the value by 1, write the new value back and then display the new value by reading it again to make sure it was actually written. The built-in LED is then turned off to show that accessing the EEPROM  has stopped.

If you have a programmer that supports the AT93C46, such as the MiniPro, you can use that to further check that the chip was written correctly. Something to be aware of is that the Arduino restarts whenever it is plugged into a computer or power source, after uploading a program to it, and when you enter or exit the serial monitor. That means if you do any of those things the EEPROM will get written with new values and that is one of the reasons why I made use of the built-in LED so it's clear when the chip is being updated.

In the main loop of setup() we call the readByte() function to read a memory location from the EEPROM by supplying the address as the input parameter and receiving the byte read as the return value. Function readByte sets CS high, outputs the opcode (binary 10 for read), sends the address to read from, reads in a dummy bit and then the actual byte and lastly takes CS low.

As for writeByte() it is a bit more difficult as we first enable writing by calling writeEnable() since the chip starts up with writing disabled. Then we call writeByteMain() with the address of the memory location to be updated and the value to be written there. The last thing to do is call writeDisable() to turn off writing. Since we are using a loop to update a number of memory locations we could have enabled programming once at the start of the loop and then disabled programming at the end of the loop.

Both writeEnable() and writeDisable() use 00 for the opcode but it is the address (more a control word than an address) that we send that signifies the type of programming instruction to use. Function writeByteMain() uses opcode 01 for write and the function is similar to readByte() but there is no dummy bit and we output a byte rather than receive one in. Note that in the main loop we wait 10ms using delay(10) to make sure programming has finished but you could probably use a shorter delay.

Other instructions are supported by the AT93C46, such as to erase or write all memory with one value, so feel free to add them if you like.

DJ-Tech Cox-115 control unit

I picked up this mixer cheaply from Cash Generator thinking I could at least make use of the two LCD's which I assumed used the HD44780 standard for character only LCD's. As I should have learnt by now, you should never assume! But before talking about that more let me first mention that the mixer has two sets of controls for operating an audio channel each. The mixer has two LCD's, lots of LED's, two sliding variable resistors, switches and more.

Fortunately I found a service manual for the mixer (referred to as the control unit in the manual) which you can view here:

http://produktinfo.conrad.de/datenblaetter/300000-324999/302584-sp-01-en-McCrypt_Doppel_CD_Player_DJ_2200A.pdf

I don't know for sure it's the right one but it seems very similar if not the same one. As well as having very useful information including circuit diagrams it reveals that the control unit is designed to be connected to a dual CD player which makes sense.

The control unit contains two almost identical circuit boards that are linked together internally. One board is labelled with model# DJ603-A.PCB-02 and the other as DJ603-A.PCB-01. The DJ603-A.PCB-01 has a 7805 regulator and various other additional components unlike the other board. DJ603-A.PCB-02 only has an extra IC (IC14) which could be a microcontroller (the actual chip has no number on it but it's called 'MCU-20' on the circuit diagram).

Looking at the circuit diagram in the service manual it looks like 9V can be supplied to either or both of the external connections of the Control unit with the 7805 on the DJ603-A.PCB-01 supplying power to both boards; thus both boards must be connected together for them both to work. This is further backed up by the fact that only one of the boards has a microcontroller which handles signals from the other board as well as the one it's on. The boards are connected to one another with a 16-way connector (CN1 and CN2) on the circuit diagram.

Both boards each contain a number of switches, LED's, a backlit LCD with specialist segments (7-seg, bars, words, etc.), a slide variable resistor with centre resting position and an unknown component (possibly a switch or variable resistor) labelled as SK1 on the board and SRGPHT3200 on the circuit diagram. The boards have slightly different model numbers on the circuit diagram as opposed to what is actually on the boards.

The boards each have a bus that connects to the external unit connections, labelled as CNP1 and CNP2 respectively. The pinout is given on the boards (but not on the circuit diagram) as (number in brackets is the connection number given on the circuit diagram):

GND (8)

9V (7)

AB (6)

SE (5)

CD (4)

CE (3)

CL (2)

DI (1)

9V is fed into the 7805 via a diode (on DJ603-A.PCB-01).

The following is how the above connections are routed between the boards:

Connection DJ603-A.PCB-01 DJ603-A.PCB-02

AB(6) Pin 11 IC14 via R4         Pin 10 IC14 via R200

SE(5) On both boards: (Pulled high) Appears to strobe IC12 (shift register) to update the LED's

CD(4) On both boards: connected to a number of switches that use a resistor ladder

CE(3) On both boards: (Pulled high) LCD controller (IC11 and IC13) chip select

CL(2)  On both boards: (Pulled high) LCD controller (IC11 and IC13) write clock and shift register (IC12) clock input

DI(1)  On both boards: (Pulled high) LCD controller (IC11 and IC13) serial data I/O and shift register (IC12) data input

I have worked out that:

SE=Strobe Enable

CE=Chip Enable

CL=CLock

DI=Data Input

As for AB and CD I don't know what they stand for.

After taking apart the control unit I tested board DJ603-A.PCB-01 by connecting just 9V and GND to connector CNP1. If you do this you should see the LCD backlight (which is blue) come on. I found that the board draws about 113mA.

Next I interfaced board DJ603-A.PCB-01 to an Arduino Uno to test just the LCD which you can see below:

Before going into detail about the circuit and code I used it would be good to have a look at the LCD layout which follows. I've done my best to make sure it's correct but it's not exact (that is, the segment design and spacing is not perfectly the same).

There are 90 segments in total out of a potential 96 as there are 24 segment & 4 common connections which are connected to the LCD controller HT1621 (IC 11 and IC13). You can view the datasheet for the HT1621 at http://reverse.0cpm.org/grandstream/datasheet/HT1621.pdf.

The HT1621 is operated using CE, CL, and DI on the DJ board which lets us send serial data to it which can be either a command (such as to turn the LCD on) or to write data to its memory (to turn a segment on or off).

Only segments 8 to 31 of the HT1621 are used by the LCD which corresponds to addresses 8 to 31; writing to other addresses has no effect. The data we write to memory is the common value and since we are limited to 4 bits we can turn on/off only 4 segments at a time. It's somewhat confusing that the segment connections act more like the common selections.

The format I have used for the LCD layout is for each segment to have the segment address (e.g. S8 is address 8) and the common bit value (e.g. C4 is bit value 4). For e.g., to turn on the plus symbol we would write 12 to address 27. This is because we add the bit value of both parts of the plus symbol: 4+8 (i.e. C4 is bit value 4 and C8 is bit value 8).

So that the Arduino can power the DJ board I did not power the board off 9V and instead connected the Arduino's 5V power direct to the output of the 7805 on board DJ603-A.PCB-01. Then I connected the following:

DJ603-A.PCB-01 'CE' (CNP1) connected to Arduino D2

DJ603-A.PCB-01 'CL' (CNP1) connected to Arduino D3

DJ603-A.PCB-01 'DI' (CNP1) connected to Arduino D4

I wrote some example code to test the LCD using the previously described set-up, which is called 'DJ_Tech_board_01_LCD_test_1V0.ino' and can be downloaded from the bottom of this page. After downloading the code to the Arduino and connecting it to the board DJ603-A.PCB-01 a zero should appear as the first digit, if not enter the Arduino's serial monitor and the zero should show up. I still have not worked out why nothing will appear on the LCD when the Arduino is first powered up yet the program works when the Arduino is reset (after programming it or when entering the serial monitor). At first sending the system enable and LCD on commands twice seemed to work but it may have been the case that the LCD controller retained some settings after unplugging and plugging the USB back in. It is something I will look into fixing for the next version of the software.

We can send to the LCD controller either a command, which is made up of 12 bits (including an extra, 'don't care bit') or we can write to display memory, which requires 14 bits (including an extra, 'don't care bit'). In the Arduino code, function LCD_sendData(dataIn, isCmd) lets us send a string of bits representing a command or display data contained in the dataIn parameter with isCmd allowing us to specify whether the data is command or display data so the correct number of bits are sent.

When the serial monitor is accessed there will be a prompt to enter an address and then a value to be written to that address. Enter an address between 8 and 31 inclusive and press return (there is no check against invalid addresses). Then enter a value representing the common(s) to turn on and press return (if a value less than 0 or greater than 15 is entered then the value zero will be used). In the serial monitor output the program will report the binary value that will be written to the chosen address (note that there are no leading zeroes).

The LCD controller starts up disabled and with the LCD outputs off; this is why at start up we send the commands LCD_SYS_EN_CMD and LCD_ON_CMD. I also send the commands LCD_RC_INT to set the LCD controller to use the on-chip RC oscillator as the system clock source and LCD_NORM_MODE to enter normal mode. Although those two settings are the default when the LCD controller powers up the datasheet recommends that it be initialized in case its power-on reset fails.

The Arduino program lets us turn on and off each of the segments but there are many things that can be added to improve the program. One of those is to clear all segments when the program begins. The LCD controller supports writing to each memory address while only specifying the start address which is ideal for clearing all segments or turning them all on.

Another problem I had with the control unit board is the contrast; the segments can only be viewed straight on. This can be fixed by using the bias and common option which improves the contrast somewhat.

DS1215 Phantom Time Chip

When I first came across the DS1215 I was very curious as to what made it a 'phantom' time chip and it turns out that it is such named because the DS1215 can exist in parallel with a RAM or ROM chip and become active when it detects a certain 64-bit value, disabling the memory chip. The advantage of this approach is that it simplifies the design of a computer-like system requiring a timer but on the down side it complicates a set-up where the DS1215's phantom ability would not be an advantage.

The DS1215 has some other useful features, such as being able to use one of two connected batteries for keeping the time when the main supply is disconnected, switching to the battery with the highest voltage. Not only does the battery keep the DS1215 going, if the timer chip is interfaced with a RAM chip it can supply power to it when the system power has been removed, effectively making the RAM chip non-volatile (that is, it will keep its data).

The time, date and settings are stored in eight 8-bit registers in the DS1215 which can be read from or written to once the DS1215 has been presented with the access code. These registers start with random values (if no battery has been used with the DS1215 or if you are using the DS1215 for the first time) so it is important to write the settings to the DS1215 as well as the starting time and date. Note that you have to read or write all 64 bits each time.

The time and date values from the DS1215 registers are stored in BCD; that is, each digit is stored separately (at most in 4 bits) ranging from 0 to 9. This is very handy when time and date values need to be shown on LED and LCD displays since they usually require each digit to be handled separately. Also, the DS1215 supports both a 12 hour and 24 hour mode and takes into account leap years up to the year 2100. Yet, because the year is stored as just two digits (00 to 99) the DS1215 is not Y2K compliant (somewhat strange as it seems the DS1215 was made in the mid-90's).

To provide timing for the DS1215 to update the date and time the chip uses a so-called watch quartz crystal of 32.768 KHz connected across two of its pins. The oscillation, however, can be disabled by writing to one of the bits in one of the DS1215's registers.

To test the DS1215 I used an Arduino uno development board since that would be the quickest way to write the code, test and make changes as needed. You can find the full code "DS1215_test.ino" attached at the bottom of the page which I wrote using the Arduino IDE, version 1.0.1. If you need the code in another format, such as in a text file, please email me.

The test code sets the timer to start on 31st December (19)87 and with the time set in 24 hour mode as 23:59:55:00. The 1987 isn't significant but the rest of the date and time is so that the timer soon moves on to the next year. This was mainly to test the day value which represents the day of the week (Sunday, Monday, etc.) but since it is just an integer value it has to be used with an array containing the days of the week as strings. You have to set the day value correctly as the timer simply increases it when required. In fact, you can even start the day value on zero just as you can put the time value to an incorrect number.

To make it easy to see the current date and time the code writes the values to the serial port which can be viewed using the Arduino IDE. If I ever pick up this project again I may add to the code so that you can change the date and time using the Arduino's serial port but please do so yourself if you want to, I only ask that you acknowledge me as the author of the original code downloadable from this page.

Below you can find the circuit for interfacing the DS1215 with the Arduino uno.

The Q, D, /OE, /WE and /CEI control lines of the DS1215 are used for communication with the Arduino. Q is the data output from the DS1215; D is the data input; /OE is the output enable; /WE is the write enable and /CEI is the chip enable input. While the DS1215 is disabled, input to /CEI goes to the /CEO, the chip enable output (so that it can drive the chip enable input of a memory chip). After the access code has been sent to the DS1215, however, /CEO becomes high, disabling any memory chip that may be connected to it; /CEO is unused in the test circuit above.

While the DS1215 has support for two batteries if you are only using one, as in the case of the test circuit, the battery is connected to the first battery input and the second battery input is connected to ground. The datasheet lists the maximum voltage of the battery should be 3.7V so a 3V battery is sufficient. For testing the DS1215 you could actually use the Arduino's 3.3V power supply in place of the battery, if you are not concerned with testing the DS1215's ability to keep its clock ticking even after the 5V supply has been removed. Either way, at least the first battery input to the DS1215 needs to have a suitable power source connected to it in addition to the 5V supply (that has its own connection) otherwise the DS1215 may not function correctly.

The DS1215 has a 5V input supply connection, VCCI, as well as an output supply connection, VCCO. When the DS1215 is supplied with 5V via VCCI, this will also feed VCCO. However, when the DS1215 is running off battery supply, that power will also be available at VCCO. In this way another chip could be powered by the VCCO connection regardless of whether the main supply was available or only a battery. For a RAM chip powered by the VCCO connection, it would effectively be made non-volatile (since it would always be powered).

The DS1215 also has a ROM /RAM input which tells the DS1215 whether it is connected to a ROM or RAM chip, since the set-up is slightly different. In the test circuit, the DS1215 is configured as being interfaced with a ROM chip (even though it's actually connected to an Arduino). I had chose the ROM mode because initially I had thought it to be easier to program the DS1215 (and ROM mode made more sense) but now I can see the RAM mode requires one less I/O line. Note that the reason the ROM /RAM input is connected to the VCCO output is so that the DS1215 is always in ROM mode even if the DS1215 is running off the battery.

Electronic Navi (Zelda: OoT)

Taking inspiration from the fairy Navi from The Legend of Zelda: Ocarina of Time I've made an electronic version which changes colour and utters one of Navi's famous lines in response to RFID cards. While it may be seen as just a bit of fun it could also be used as an educational tool if the RFID cards had illustrations on them. For e.g., an RFID card with a picture of something dangerous on it when held near Navi would cause her to change to yellow and let out "Watch out!" just as if she had seen an enemy in Ocarina of Time.

The project is based around the following items which you should be able to buy at a reasonable cost:

Arduino Uno.

RFID module RFID-RC522 with at least 3 compatible RFID cards.

Sound module WTV020-SD with micro SD card, and speaker.

Mood light GLGRG-02.

Level converter TXS0108E.

IR emitter diode with limiting resistor.

The basic idea is that after setting the mood light to manual mode and changing its colour to white using the IR diode, the Uno continually looks for an RFID card by checking the RFID module and when an RFID card has been found it checks to see if the card's UID (Unique IDentifier) matches a known value. If it does then the Uno sends a command to the mood light to change its colour and it also tells the sound module to play a short clip. After a brief delay the Arduino commands the mood light to change back to white.

For the wiring let's look at the circuit diagram:

The Arduino Uno provides power to the various modules and communicates with them but the mood light (not shown) runs off the mains supply. As both the RFID and sound modules use 3.3V logic but the Arduino Uno runs on 5V logic, to prevent harm to the modules we use a level converter (TXS0108E) to convert the signals with the exception of the MISO output of the RFID module as that is an input to the Uno. The Arduino directly drives the IR emitter diode (LED1) via current limiting resistor R1, while the sound module directly drives the speaker, SPK1, rated for 8R/0.5W.

Next, we'll study the Arduino sketch which is attached to the bottom of this page as 'Real_Navi.ino'; note that it is very rough code and could do with being tidied up. In the setup() function we open an SPI connection using 'SPI.begin()' as we communicate with the RFID module using SPI. The next 2 lines initialise the RFID module and adjust its antenna gain to increase the distance it will detect an RFID card. As you will need to put the UID values for each of your RFID cards in the array RFID_UID[] you can uncomment the 'Serial.begin(9600)' in setup() and 'mfrc522.PICC_DumpToSerial(&(mfrc522.uid))' in loop() so that when you open the serial monitor and scan an RFID card it will give you information about the card including its UID.

Back to setup() and we set our sound module signals 'sound_rst_pin', 'sound_CLK_pin', and 'sound_DI_pin' to outputs and to all start at logic 1 (high). Lastly, we send an infrared command to the mood light (which uses the NEC protocol) first to set it to manual mode (it starts up in automatic mode) and after a short delay we tell the mood light to change to white.

On to the loop() function where we wait for an RFID card to be detected using commands 'mfrc522.PICC_IsNewCardPresent()' and 'mfrc522.PICC_ReadCardSerial()'. If an RFID card is found we check all four UID values read from the card in 'mfrc522.uid.uidByte[]' against our look-up values in 'RFID_UID[]' for all of our known UID values. If we do get an UID match we check which card was detected by looking at card_i and responding by sending an infrared command to the mood light to change its colour. We also play an appropriate sound clip using 'ply_snd_clip()' and then wait 2 seconds. When no RFID card has been detected or after a card was found the mood light is told to return to white which happens at the very bottom of loop().

Looking at function 'ply_snd_clip()' it resets the sound module and then calls 'sound_out_file_val()' after a brief pause. Function 'sound_out_file_val()' simply outputs the file number bit-by-bit using the look-up table 'power_of_2[]' for the binary values. We have to clock the sound module with each bit that is sent and we do that using function 'sound_clk()' which takes 'sound_CLK_pin' low then high.

Before we test everything out let's go into some more detail about the various modules.

The sound module WTV020-SD actually comes in 2 versions; the WTV020-SD-16P and the WTV020-SD-20S. Both have 16 pins/connections but a different pinout and module package type; WTV020-SD-16P supports micro SD whereas the WTV020-SD-20S takes a regular size SD. The WTV020-SD-16P is the version that I used. The WTV020-SD is supposed to support both WAV and AD4 files with a maximum of 512 clips, accepting an SD card up to 1GB.

The sound module datasheet can be found at:

https://dlnmh9ip6v2uc.cloudfront.net/datasheets/Widgets/WTV020SD.pdf

As for the main chip used in the sound module (WTV020):

http://www.elechouse.com/elechouse/images/product/MP3%20Sound%20Mini%20SD%20Card%20Module/WTV020%20datasheet%20V1.8.pdf

For the Navi sounds I obtained them from:

http://noproblo.dayjo.org/ZeldaSounds/OOT/index.html#Navi

As I was unable to get WAV files to play correctly using the sound module I had to use AD4 files instead by following a guide to convert the 32KHz WAV files I had downloaded to AD4:

http://electronoobs.com/eng_arduino_tut8.php

Note that the sound module supports AD4 sampling rate 6 to 36KHz.

The micro SD card I used for the sound module was a 128MB card formatted to FAT and I copied the voice clips on it using these filenames:

0000.AD4 (Watch out!)

0001.AD4 (Listen!)

0002.AD4 (Hey!)

The mood light (GLGRG-02) is normally controlled by a remote allowing the user to choose from preset colours, dim the current colour and to switch between automatic (slowly changes between colours) and manual modes. The only thing to watch is that using the remote going from certain preset colours to another results in a dim version of the colour. But as Navi is normally white (well, in the game she is white with a blue aura) when not interacting with other objects there will always be a transition from white to another colour.

To operate the mood light using the Arduino I followed a tutorial to discover the values needed to be sent to simulate the remote button presses using an Arduino Uno:

http://www.instructables.com/id/The-Easiest-Way-to-Use-Any-IR-Remote-with-Ardiuno/

I was able to modify the sketch to turn an LED connected to the Arduino on/off using the mood light remote.

The next step was to control the mood light using an infrared diode connected to the Arduino. I used an example sketch, IRrecvDump (File->Examples->IRremote->IRrecvDump) that came with the IR remote library to identify the IR protocol used by the mood light which I found to be an NEC encoding that uses 32-bit codes. I was also able to get the hex values for sending commands to the mood light of which the ones used for this project are as follows:

Manual mode 0x1FE708F

White 0x1FEB04F

Green 0x1FE40BF

Blue 0x1FEC03F

Yellow 0x1FEE01F

I was then able to write a sketch which operated an infrared diode connected to an Arduino which sent the relevant codes to first put the mood light into manual mode, change to white and then switch between white and green, blue or yellow in turn. I found that I needed a delay between sending the manual mode command and changing to white (I used 100ms but could probably be shorter).

After transferring the sketch to the Arduino and then connecting all the components first turn on the mood light and then apply power to the Arduino with the IR emitter positioned facing toward the mood light which should change to white. Test by bringing each of the RFID cards near to the RFID module and you should see the mood light briefly change colour and one of the 3 sound clips should play. For reference the colours and matching sound clips are:

Yellow: "Watch out!"

Blue: "Listen!"

Green: "Hey!"

With yellow representing danger, blue someone to listen to and green being something of interest.

Note that because D13 of the Arduino is used for the SPI SCK signal for the RFID module and the Uno has a built-in LED connected to D13 it acts as a debug LED as you can see it flash whenever it's waiting for an RFID card.

To keep the electronics safe you could put the Arduino and modules into a wooden box with the mood light sat on top and the infrared emitter attached to the back of the box and facing up toward the mood light. The RFID module will need to be secured to one side of the box and the speaker can be fixed into place on a different side perhaps with some slits to help the sound out. To increase sound output an amp module can be used, however, I ditched a PAM8403 based amp module I had bought as it introduced hum and clicking sounds as well as other problems. You'll need to being power in either with a USB cable or a power cable with a barrel connector, or you could even run the Arduino off a rechargeable battery.

The RFID module used in this project is not limited to just detecting one type of RFID card since it can even be used to read Nintendo's Amiibo toys by modifying the Arduino sketch to check for a 7 byte UID instead of only 4 bytes. In fact, my original plan was to use Amiibo figures but they were too small compared to the size of the mood light.

You can check out a video I did on the project at:

LED Dot Matrix Test

As part of a larger project in which I hope to output text to a message board made up of a large number of dot matrix displays I set about testing a single dot matrix display using an Arduino Mega. The display is a CSM57121D red LED dot matrix display that is arranged as 5x7 making a total of 35 LED's. If you look on the underside of the display you should see a '1' at the bottom right corner which gives us this pinout (viewed from underneath):

14 13 12 11 10 9 8

7   6   5   4   3 2 1

1-R3

2-R1

3-C4

4-C3

5-R4

6-C1

7-R2

8-R6

9-C5

10-R4

11-C3

12-C2

13-R7

14-R5

Where R1 is row 1, C1 is column 1, etc.

The test code, which is attached to the bottom of this page as LED_dot_matrix_test.zip, turns on each LED in turn from top to bottom, with each LED staying on for 1 second. Once you have downloaded the file, unzip it and open up the INO file in the Arduino IDE, which needs to be loaded into your Arduino (I used a Mega but an Uno should also work). The hardware set up for the display is as follows:

Row 1 - 7 connected to D2 - D8

Col 1 - 5 connected to D9 - D13 via 330R resistor each

In the setup function we define the digital pins to use as outputs (D2-D13) and also set the initial state of the rows and columns. To turn on an LED in the display it is a simple matter of making a common anode high (that is, the connected digital pin is on) and the common cathode low (the digital pin is off). If you look in the loop() section of the code you will see that we keep track of the current row (cur_row) and current column (cur_col). After we have activated each column in turn we go back to the first column and move on to the next row which is done by using digitalWrite and offsetting the starting pin for the row or column by the current row or column number. By decreasing the value passed to delay() at the start of the loop function that LED's will change state quicker and if you replace delay() with delayMicroseconds(100) it should seem like all LED's are on at once.

LED Dot Matrix Test 2

In the first test we turned each LED of the display on in turn and we saw that by decreasing the update time we could give the impression that multiple LED's were on at once. Building on that first test we will give the appearance of a character being displayed by outputting values from a look-up table to specify which columns are to be turned on. Please refer to the previous test for information about the display I used but take note that this time the display is wired up differently:

Row 1 - 7 connected to D2 - D8

Col 1 - 5 connected to D53 - D50, D10  via 330R resistor each

You will find the Arduino code for this test at the bottom of this page as LED_dot_matrix_test_2.zip. So that we can change multiple digital lines at once we write directly to port B which contains digital lines 50-53 and 10-13. Because the Uno ports are different to the Mega's this sketch will only work with the Mega without altering the code. Because we have the aforementioned digital lines grouped together in port B I changed the display wiring from the first test so I could easily update all columns at once.

Toward the top of the program we have the array charTable[] which contains the bit values that make up each row (although it is a byte array only the first 5 bits are used). In setup() we do the necessary initialisation of setting up the outputs and the initial states, this time not so elegant as the digital pins we've just are not entirely in order.

In the loop() section we progress through the rows as before but the multiple columns are set based on the current row read from charTable[]. We start by clearing port B to all 0's which turns all columns on (to activate a column it must be low). After reading the character value into charRow we invert the value using '~' since we have in charTable[] used a '1' to represent a lit LED yet we need a '0' to turn a column on. Then it is a simple matter of OR'ing the resulting value with port B to update the columns.

LED Dot Matrix Test 3

For the third test we will update 2 LED dot matrix displays and illuminate a '0' on the first display and a '1' on the second display. The Arduino code is called LED_dot_matrix_test_3.zip and is located at the bottom of the page for download. With the addition of a second display the hardware wiring is now:

Display 1 row 1 - 7 connected to D2 - D8

Display 2 row 1 - 7 connected to D11 - D17

Display 1 and 2: col 1 - 5 connected to D53 - D50, D10 via 330R resistor each (only one set of resistors needed for both displays)

Because D10 was already taken I started display 12 on D11 so in setup() I put D11-D17 to outputs and turn them off. The loop() function is now much shorter because we make use of the function updateDisplay() to first display a '0' on display 1 and then a '1' on display 2. To use updateDisplay() we pass first the digital pin number of the display's first row (LED_disp_1_R1_pin for display 1 or LED_disp_2_R1_pin for display 2) and then the character number (0 for '0' and 1 for '1'). In updateDisplay() we check that charNum (character number) is valid and then enter a loop to update each row. As with test 2 we get the column values from charTable[] but this time we calculate the entry into the table based on charNum, LED_max_row, and row number (i). After updating the columns we turn on the current row, wait a bit (by calling delayMicroseconds()), turn off the current row and loop back again.

MCP3204 ADC (MIKROE-326) test

The mikroe (mikroelektronika) MCP3204 based 'ADC PROTO' breadboard friendly module, which seems to be model MIKROE-326 (there are no markings on the PCB), features four analog inputs and an SPI interface for connection to a microcontroller or computer interface. You can find the product page at:

https://www.mikroe.com/adc-proto-board

Downloadable from the page are program examples for various platforms (8051, AVR, dsPIC, and PIC) written in mikroBASIC, mikroC, and mikroPascal, as well as the user manual. Note: the user manual refers to the board as an 'additional board'.

The version featured on the product page is HW REV 1.02, I have REV 1.00, which I got from a job lot, and initially it seemed the main difference between the two versions is that REV 1.02 has two extra screw terminals for GND, in line with the four analog inputs, but as we shall see later that's not the only difference.

As mentioned, the module uses a MCP3204 ADC, which has 12-bit resolution, 100k samples/second, and draws as little as 5nA when in standby. The module also features a 4.096 voltage reference for the MCP3204, provided by the MCP1541, and there is a MCP6284 Op Amp that amplifies the analog inputs before being fed to the MCP3204.

I wanted a quick way to test the module and found someone talking about using the it with an Arduino:

https://forum.arduino.cc/t/mcp3204-readings/242956

Using the sketch this is how I connected the module to the Arduino:

Arduino ADC PROTO
10 CS#
13 SCK
12 MISO
11 MOSI
5V VCC
GND GND

Each analog input (CH0 to CH3) can then be connected to a voltage source (best not to exceed 5V or go lower than 0V). For example we can connect a potentiometer with wiper to the analog input and the other two connections to 5V and GND respectively. However, we need to make a modification to the sketch to make it suitable for general use rather than the specific one the author had. Change the following in loop() from:

 readvalue = read_adc(1);

 vout = (readvalue * 4.095) / 4095.0;

 vin = vout / (R2/(R1+R2));  

 Serial.print("RAW1: ");

 Serial.println(readvalue);

 Serial.print("VOLTS1: ");

 Serial.println(vin); 


To:

  readvalue = read_adc(1);

  vout = readvalue * (4.095 / 4095.0);

  Serial.print("RAW1: ");

  Serial.print(readvalue);

  Serial.print(" VOLTS1: ");

  Serial.println(vout);

Note the reason why 4.095 is used instead of 5.0 in the cout calculation is because of the 4.096V reference voltage on the module, however, toward 5V the voltage reading will be somewhat less accurate. Ideally, the reference voltage would be fed to the Arduino AREF pin and enabled in the sketch, unfortunately the ref volt isn't provided externally by the ADC module although we could try reproducing the voltage using a resistor divider, for example.

To read the other channels simply pass the appropriate channel number to read_adc(), remembering that the sketch uses the value 1 for CH0, 2 for CH1, etc. Oddly, when I was testing I found that the channels were mixed up and checking with my multimeter I found they were indeed connected incorrectly. Recall that I have HW Rev 1.00 so they must have fixed it in the later revisions. In Rev 1.00 CH0 is connected to CH1, CH1 to CH0, CH2 to CH3, and CH3 to CH2. So, if for example we wanted to read from CH0 using the sketch we would have to pass 2 to read_adc().

MCP41010 digital (MIKROE-198) potentiometer test

I came across the mikroe (mikroelektronika) MCP41010 based digital potentiometer module in a job lot, it appears to be model MIKROE-198 from looking online, there is no identification on the module itself as to the SKU. The board is marked as 'HW REV. 1.00' (and it appears to be the only revision so far) and can be bought online from stores such The Debug Store:

https://thedebugstore.com/products/mikroe-198-digital-potentiometer-board-uk

At the time of writing this article it was selling for £7.20 ($9.10), a lot more than what I got it for considering I paid £8 for 5 of them.

Note: I couldn't find the module on mikroe's own site.

If you are unfamiliar with digital potentiometers it would be a good idea to check out this video:

The board can be powered from 2.7 V to 5.5 V and uses SPI to interface with a microcontroller, resistance value ranges linearly from 0 to 10K with 8-bit resolution (256 wiper steps).

For more information please see the MCP41010 datasheet:

https://ww1.microchip.com/downloads/en/devicedoc/11195c.pdf

Please note the inputs are 5V tolerant so it's suitable for connecting to an Arduino Uno, for example.

The manual for the module can be found at:

https://www.mouser.co.uk/datasheet/2/272/digital-potentiometer-board-manual-v100-1485352.pdf

The manual refers to the board as an 'additional board'. Page 3 includes a schematic, which is helpful for the pinout of the 2x5 female connector for interfacing with an module Note the square outline on the PCB and in the schematic for the pin layout.

The DIP switch is used to configure the board for the type of MCU/development board its to be connected to.

I found a tutorial for using the MCP41100 with an Arduino:

https://www.instructables.com/Digital-Potentiometer-MCP41100-and-Arduino/

The MCP41100 goes up to 100K whereas the MCP41010 is limited to 10K but otherwise functionally the same.

In the tutorial they aren't using a module and are breadboarding the MCP41100 so to use the mikroe module I wired it up as follows:

Arduino MCP41010 module
5V VCC
GND GND
D10 CS0
D11 RC5_PB5
D13 RC3_RF3

This is the DIP switch settings to use:

1, 4, and 7 on. 2, 3, 5, 6, and 8 off.

Rather than use the 100R limiting resistor for the LED shown in the tutorial I used a 2K2 resistor with a green standard brightness LED. After testing that the sketch was working I modified it to always have the resistance at the lowest and thus LED at the brightest level and measured the LED current, which was 1.35mA, slightly over the quoted 1mA wiper current in the datasheet. In the comments of the first embedded YouTube video in the tutorial the author says he was using an LED with a 3.3V voltage drop, which is why he used such a low value limiting resistor

MMA7361 3-Axis Accelerometer

An accelerometer is a very useful device that detects linear motion (acceleration along an axis), as opposed to a gyroscope which detects angular velocity (how quickly the object's turning), and is useful for sensing tilt and motion, sudden drops or shocks, for example. 

Please see this video to learn more about accelerometers:

You will find different variations of 3-axis accelerometer modules for sale, I have two that I accumulated from job lots, one is from LC Studio, but has no model number on the PCB and I couldn't find a product page online, and the LC Studio website (www.lcsoft.net) was down at the time of writing this article. However, the module appears to use a MMA7361 IC (the chip is marked as 7361), so we can look at the datasheet for information:

https://www.nxp.com/docs/en/data-sheet/MMA7361L.pdf

The MMA7361 runs on 3.6V maximum and draws just 400µA, and the typical accelerometer modules that use the chip (which is what is discussed here), have an on board 3.3V regulator, and power LED, and a few passives. All three accelerometer axes have their own analog output which varies in voltage based on the acceleration on each axis. The datasheet doesn't specify the input pin signal voltage range but people online claim it to be 5V tolerant, however, if I supply 5V to the sleep (SL) pin of the LC Studio module, the MMA7361 and the on board regulator run hot. This doesn't happen if I connect 3.3V to the pin so I would advise only use 3.3V for the inputs, running the module's power off 5V is fine since it has the regulator to drop down to 3.3V to power the chip, it's just the input pins to be careful of. If you intend to control the module's inputs with a 5V GPIO pin (such as from an Arduino) I would advise to use either a series limiting resistor or a voltage level converter to drop to 3.3V.

As mentioned, the module has a sleep (SL) pin, which needs to be pulled high for normal operation, it is claimed that it has an internal pull down resistor (the datasheet doesn't specify) but it's best to treat it as if it doesn't. If you want the module to always be active then you can either connect 3.3V from an external source to the SL pin or the accelerometer module's 3.3V pin to the SL pin. The datasheet is clear, however, that the g-Select sensitivity select input has an internal pull down resistor for 1.5g operation, take the input high to select 6g.

Additionally, the module has a self test (ST) input pin, which the datasheet is a little vague, from testing I found the input to be active high with an internal pull down. If I take ST high and turn the module upside down I got a reading of 1.2V, which agrees with the datasheet specifying a value on the Z axis between 0.8V and 1.2V.

For powering the module you can supply 5V to the 5V power pin OR 3.3V to the 3.3V pin, never use both, and be sure to connect up GND also.

There is a 0g-detect (0G) output pin which goes high when it detects freefall, which happens when the module is dropped or there is sudden movement on any of the axes, which can be used to set off an alarm or to shut off a hard drive to prevent damage, to give a few examples.

Here is a tutorial for using the MMA7361 module with an Arduino:

https://electropeak.com/learn/interfacing-mma7361-accelerometer-module-with-arduino/

The MMA7361 module featured looks very similar to the LC Studio one I have. The sketch outputs the analog values read from the X,Y, and Z outputs of the accelerometer as well as the converted voltage values derived from the analog values.

When the MMA7361 module is facing up there should be roughly half the supply voltage (1.65V) output on X, Y, and Z. Tilt one way on the X or Y axis (there is a small diagram on the board showing direction) and the corresponding voltage will increase, tilt other way and it'll decrease. If you tilt more than 90 degrees the readings will wrap around. Z is the vertical acceleration and is dependent on gravity.

From testing I found that roughly X ranged from 0.75V to 2.37V, and Y from 0.99V to 2.60V.

In examples seen online you'll typically see calculations treating the ADC reference voltage as 5V, which is correct, however the accelerometer outputs a voltage on X, Y, Z that is almost the supply voltage, i.e. nearly 3.3V. Thus, to get more accurate voltage readings we should enable external ADC voltage reference in the sketch by putting the following in setup():

analogReference(EXTERNAL);

Connect 3.3V to the Arduino's AREF input, and in the sketch change the calculations to use 3.3 rather 5 to work out the voltage.

I wrote my own sketch, MMA7361_Accelerometer_Test.ino avaiable for download at the bottom of this page, which outputs the accelerometer X,Y, Z values as raw and voltages to the serial port and also announces if freefall is detected. Please read the comments in the sketch to ensure the module is connected to your Arduino correctly - I used an Arduino Uno.

Tips

Analogue inputs as digital inputs

If you need more digital inputs the analogue inputs can be used as if they are digital by using digitalRead, e.g., digitalRead(A0). Be aware that on the Arduino Nano, however, which has 8 analogue inputs, A0 to A7, only A0 to A5 can also can function as digital inputs.

Debug options

The serial port is one of the most useful means to output debug information from an Arduino sketch and it can also be used to receive debug options from the user such as to display the state of certain variables or to enter debug mode. A simpler but still very handy option is to use spare GPIO pins to output information, even if just to light an LED to say a specific point in the sketch has been reached or an undesirable condition has been met. Similar to using the serial port to get options from the user, a GPIO pin configured as an input can have a switch wired to it to enter debug mode, for example.

Serial port access resets board

With most Arduino boards, if you access the Serial monitor from the Arduino IDE or open an Arduino serial port in a different manner (such as from another program), the Arduino will reset. This is something to keep in mind as you may not want the Arduino to reset under those circumstances and if that is the case check out this site for information about disabling the auto reset:

https://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection/

Troubleshooting

This section concerns hardware and software problems (including error messages), not specific projects.

Arduino IDE gets stuck uploading or takes a very long time

The simple cause of this issue could be that you've selected the wrong board (Tools->Board); remember that there are, for example, multiple versions of the Nano and Mega so you must choose the exact board type you have.

Computer does not recognise a connected Arduino Nano

If you find that your Arduino Nano suddenly stops being recognised by your computer when plugged in it could be a problem with the on-board FTDI chip that handles USB communication. There is a known problem with the Arduino Nano that causes it to stop being detected (oddly after much use) because the FTDI's test pin has been left unconnected. The fix is to solder across the test pin (pin 26) to the GND connection next to it (pin 25), while power is off, of course. If you are not used to soldering surface mount components, like me, it's very difficult to do but I had the problem and needed to fix it. Just take your time, make sure your work area is well lit and use a magnifying glass if need be. The FTDI chip has the part number FT232RL and is on the underside of the Arduino-make sure to identify the pins correctly.

Directly manipulating the ports of an Arduino doesn't produce the expected results

There are times when we cannot get away with using digitalWrite() and must instead write directly to the ports so that we can update the I/O faster or to make it easier to change multiple outputs at once. Be aware that the official Arduino page that talks about the subject only applies to the simpler Arduino Boards, such as the Uno:

https://www.arduino.cc/en/Reference/PortManipulation

For other boards, such as the Mega, some of the I/O pins are part of different ports, which you can view here:

https://www.arduino.cc/en/Hacking/PinMapping2560

To compare, on the Uno digital pin 13 is controlled by bit 5 of PORTB but on the Mega it is handled by bit 7 of PORTB.

No response from Arduino serial port using external program

There are times when we may need to pass data to an Arduino via its serial port using an external program (e.g., a Python script running on a PC) and we may need a reply back from the Arduino and while it should be straightforward enough to implement you may find that the Arduino doesn't respond. When the Arduino serial port is opened (which includes from an external program) the microcontroller board resets and it needs time to start up again and run your script so that can explain why the Arduino doesn't reply. This is only potentially a problem if data is sent to the Arduino serial port immediately after it's opened and thus the solution is to put in a delay in the external program after opening the serial port and before sending data to it. You will need to experiment with delay values but for a Python script I was working on I needed to put in a delay of one second, as to give an example. This isn't a problem for Arduino sketches as no data can be sent or received through the serial port until the Arduino starts executing code from power up or reset so there is no danger to try to write or read from the serial port too soon.

Unable to rename '...\core.a' reason: Permission denied

When you try to compile a sketch you get the error:

unable to rename '...\core.a' reason: Permission denied

Solution: restart your computer and try again. If this does not fix the problem, try updating or re-installing Java (the Arduino IDE uses Java), restart your computer and then try again. This method may not fix the problem for everyone. If you still get the same error (as has been the case with me), one option is to use a plugin for Visual Studio called Visual Micro:

http://playground.arduino.cc/Code/VisualMicro

The plugin lets you write, compile and upload Arduino programs as if you were using the Arduino IDE but is faster and doesn't have the problem mentioned. After installing the plugin you will see in Visual Studio Arduino specific options much like with the Arduino IDE:

To compile an Arduino sketch you use the Build option. As for uploading to the Arduino you have to select either of the debug choices (Start debugging or Start without debugging) even though no debugging takes place. Don't forget to first select your Arduino board (Tools->Arduino->Boards->...) and serial port (Tools->Arduino->Serial port->...).

When you try to upload to a board you get "Error:  could not open `...\jvm.cfg'"

I had recently tried to put the Arduino bootloader on to a STM32F board but when I tried to upload code to it I got a message saying "Error: could not open `C:\ispLEVER_Classic2_0\ispcpld\lib\jvm.cfg'". This was very strange as ispLEVER is a program I use that is separate to the Arduino IDE and they are only related because they both use Java. I guessed that somehow the Arduino IDE was getting the Java path from ispLEVER even though the path was wrong. The fix was to close the Arduino IDE and install the latest version of the Java runtime from:

http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html

When I opened the Arduino IDE again and tried to upload the code to the STM32F board it worked without any issues.

All content of this and related pages is copyright (c) James S. 2012-2024