Warning: I have no idea what I'm doing here, so don't use this unless you know what you're doing.
Recently, I started experimenting a bit with electronics, using Arduino, ICs and a ton of LEDs amongst other things. This repository contains information on various projects I did, also including code, as well as a curated list of resources I found useful.
Here are the projects I did and plan to do.
The morse Arduino code was my very first project, I wrote the code even before my Arduino arrived, it requires no wiring as it works with the built-in LED when the Arduino is connected to a computer via USB. It reads ASCII from the serial, converts to morse code, and then makes an LED blink accordingly. Of course you could hook this up to a relay to drive an even bigger light.
After some time I decided to write a test suite for this sketch in test.cpp
inspired by rfielding/octaveRounder
's tests which allows me to write new features without having to connect an Arduino.
My second project creates a smooth marquee of LEDs using PWM, and also uses an input from a poti for speed control. This showcases the analog capabilities of the Arduino unit. The code in fadeLedArray.ino
might require some fine-tuning depending on the exact LED you use. The wiring is also very easy, just connect the LEDs to the PWP pins and ground with a resistor in series, and the middle pin from the poti to an analog pin. To smooth out the analog readings I used the code from readAnalogVoltageSmooth.ino
.
The LED piano is a fun and debugging project. The Arduino code is reading messages from the serial port like H4
, L1
etc. to toggle pins high and low. You could just send those from the serial monitor in Arduino IDE, but it's way faster and fun to do it from a browser. This way you can also do it on a phone, or some other computer in the same network. For that, there is a server written with node.js, express, ws and serialport libraries that will accept messages from a websocket connection and forward them to a serial port. It also serves a basic client file in plain JS that displays some buttons for control, and also accepts touch and keyboard input. Aside from driving LEDs, this can also be used to fiddle with ICs without having to wire many things and debouncing buttons and so on.
After using basic LEDs only I wanted to try out the bargraphs and some ICs and started with the 74HC595 8-bit shift register, creating shiftRegisters.ino
. It can control two shift registers which in turn control bargrahps and show some nice visuals. The project is a bit like this shift out example) except that it generates some patterns and also accepts some commands form serial port to control:
I
: toggle wether to show intermediate register states or only latch once all bits are in placeD0
,D1
,D2
: control delay when shifting out the bits, so you can watch either the sendout or the resultsR000
–R999
: control how long each "image" is shown after the serial transmission is complete
The wiring is a bit more elaborate for this one, so I have a higher-res image showing how to wire things up on a breadboard. White is the serial clock, blue is the output latch clock, yellow is the data and a small piece for cascading into the second shift register.
When I got my hands on a 1588BS
8x8 pixel LED matrix, I wanted to use the Arduino as a driver. Luckily it has more then 16 I/O pins available, so you can directly connect the 8 anodes and 8 cathodes (with a resistor). I my wiring is quite a mess, I had to test the matrix with the diode setting in the multimeter to even find out how the ports are laid out. I then wrote ledMatrix.ino
first to test if everything is hooked up correctly and working, but then proceeded to add a dozen effects. I used a struct and function pointers to make it easy to configure the effects, otherwise the code is rather unspectacular.
Since the nano has two analog pins that can not be used as digital pins anyway, I hooked up two potentiometers to those which can control two "paddles" on the LED matrix and created a small Pong-like game for it in ledMatrixPong.ino
. I found myself having so many global variables for the state of the ball, the paddles and more, that I refreshed my C++ knowledge and used classes and an enum to make things a little bit more elegant. I spend most of the time on displaying the score nicely in the end. It's quite playable, even tough 8x8 pixel resolution is somewhat limiting. As the game progresses, the ball gets a bit faster over time to keep it challenging.
Another two components from the starter kit that go nicely together are the DHT 11 temperature and humidity sensor and the LCD screen. At this place I actually found the wiring and programming not so rewarding, it was mostly an exercise in wiring up all the pins correctly and embedding some libraries, as documented in temperatureDisplay.ino
. I took a cheap powerbank that I won on the Southside festival and brought the breadboard with the whole installation into the blistering cold outside to see if it works. Instead of just displaying the values on the LCD I also designed a set of icons for temperature (sun, cloud, snowflake) and humidity (droplet in 3 sizes) which change depending on the sensor values to give this project a least a small creative edge.
Next I tested the HC-SR04 ultrasonic sensor and the passive buzzer. Again, it felt straightforward to set it up, the buzzer can be connected to any digital pin (and ground) and the HC-SR04 gets voltage supplies, a trigger pin to start a measurement and an echo pin which can be read with the pulseIn
Arduino function. I build a contraption that works like parking sensor and modifies the buzzer frequency based on the distance in parkHelper.ino
, however, I found the readings were all over the place, and I don't even own a car, so I gave up on this. At some place I might build a radar with the servo and Processing...
With the same circuit I also coded elfenlied.ino
which will play the Lilium melody on the buzzer. I put in a small resistor so that the buzzer is not so loud during debugging. I think the buzzer might be a good addition to some of the games to provide a multimedial experience. The Arduino with the Tone
library can only play one frequency on a square wave, so it's really limited in its current form.
The number 2048 is not only 211 but also the name of a well-known arcade game. It only needs 4x4 tiles, 4 buttons for the 4 directions and maybe a bit of score and highscore display. And it's a lot of fun. So I picked it as a candidate to develop a more complex game on the 128x64 Pixel OLED screen. The screen is connected with I2C and the buttons with pull-ups, so the hardware can be constructed in no time. However, for the software in 2048.ino
and other files I ventured into some new areas. I looked at this Arduino code and this JS code to understand the game logic, but in the end I developed it myself again, as I didn't quite understand their code.
What's so cool about it? The highscore is saved in the EEPROM. There are individual desings for the tiles which were exported from a sprite image with a small Go script transformSprite.go
– they look artsy, but are hard to read, maybe I'll change tham. And then there's even a 3D animation when reaching the 2048 tile, rendered from the Blender3D file animation.blend
and exported into bitmap frames using transformFrames.go
. It fills almost the whole flash memory. Welp! But I think it was worth it.
Maybe I'll turn this into a hardware project at some place again, The buttons are a bit annoying to press, put it in a nice case with a battery, ...?
I saw the video Arduino LED Memory Game featured on YouTube, where someone built this Simon Says game from sparkfun (without their custom PCB) and I thought this is easy to build based on my breadboard from the 2048 game. In addition to the 4 buttons, I added 4 LEDs and a buzzer. And since the OLED screen was also attached, I used it to display some instructions and the score, the code is in ledBrainz.ino
. I actually really enjoy doing these pixel graphics, and I also added transformBitmap.go
which is a generic command line tool to transform PNGs into C arrays. I later found out that this Simon game has actually a longer history, see this video and the linked resources.
Another game idea I found was a word sorting game. The MCU gives you a random permutation of a word and you have to rearrange the letters to build the original word. The code is in wrodShuflfe.ino
(the name of the game is the 0st level already) and I also added a list of 78 basic German words, that you can guess. Even though I knew the words, it was still challenging, e.g. PFLAE
is formed from a perfectly normal German word, but it took me some time to figure it out. As a bit of nostalgia I used C strings with strlen
and strcmp
as well as the in-place-XOR-swap trick. And now I know why people avoid those. And ofc I built some "pixel art" as decorations.
I almost forgot how fun snake as a game was. Back in the Nokia 3310 days it was my favorite pastime for some time, so I had to re-implement it as well. And what can I say – it's still addictive. The code is in snek.ino
. I had to limit the field size to 21x12 to make the the maximum snake length fit into a uint8_t
and thus not fill the 2 KB memory of the Nano so quickly, while still allowing to fill the whole field with snake.
For some time I thought about a way to store not only my 2048 high score, but also my snake high score in the EEPROM at the same time, and I came up with some basic file system. But then I realized that my idea is the same that the "Overly Simplified File System" from charlesbaynham/OSFS
already implements so I migrated my storage to this system using initOsfsEeprom.ino
and some migration code for 2048.
I was also curious how fast the various code bits actually run so I wrote some timing code and while my game code is taking less than 2ms, sending the buffer to the OLED via I2C/TWI takes a whopping 37ms, so I guess one way of optimization would be only sending the changed regions, which would be possible from the screen's protocol, but the graphics library I'm using does not support that. Maybe some time in the future, I'll roll my own.
I also finally took the time to replace the jumper wires with some 22 AWG solid wire, because the jumpers kept hanging over the OLED. I also found when you enter "snake" into Goolge you can actually play the game, a graphically polished version of it with animations and more game modes, like multiple mice, swiss-cheese-snake and so on.
After I got my hands on a 5m long LED strip, I was eager to test what could be done with it. My first experiments were to turn on/off single LEDs, which resulted in a sketch for sending out "worms", one in each color red, green and blue which is in ledStripWorms.ino
. You can use a button to re-spawn a worm. I also tried a typical rainbow pattern in ledStripRainbow.ino
because it's really easy to do with FastLED. I was actually surprised that the Arduino seems to have no problem driving and powering the 300 LEDs at a decent performance if you don't increase the brightness too much.
Then I wanted to start something bigger, and I did a game inspired by curling, ledStripCurling.ino
. Aside from the 300 RGB LEDs it only uses a button and a buzzer. You hold down the button, the longer you hold the farther on the strip you "shoot", and the buzzer frequency gives you a hint how long you're holding. You'll try to hit a target area. If you land where another player has already landed, you displace their stone. After 3 shots, you get a score by how many of your stones are closer than any other player's stone. After a few rounds ("ends") whoever has accumulated the most points wins and a celebration animation in their respective color is displayed. There are a few differences to regular curling: I do also count stones landed outside the target area ("house") and since the LED strip is only 1-dimensional, you always pass through other player's stones en route. Also there's no strict limits on how many players/teams there are. And unfortunately sweeping is not possible.
- Game similar to froggy on the LED Matrix
- More games on the LED Matrix? Jump & Run, Breakout, maze, snake...
- More games on the OLED? Jump & Run, Breakout, maze, adinfinitvm...
- RGB LED controller?
- Kitchen timer set with poti, counting on 4 segments, and flashing RGB-LED and Buzzer when done. (Maybe Wifi tmp & and a clock as well?)
- Game controlled with remote control, maybe tic tac toe?
- Programming an EEPROM to drive the shift registers, so no Arduino is needed
- Well, the 8 bit CPU...
- As well as the "reliable data transmissions" series
- Maybe: Using Ardiuno as a general purpose debugger / controller via firmata and some node / React app, basically the "LED piano" in fancy
- Maybe: Some kind of keyboard matrix like this Mini Macro Keyboard or this SparkFun Cherry MX Chorded Keyer or this sawed off keyboard using the Cherry MX switch. Parts maybe form this switch tester or switches individually (with click, without click, smooth or from digikey) and caps (getdigital or digikey or from old keyboard?) and breakout board or custom PCB? See also: very good instructions, full keyboard project)
- Maybe: hack a gamepad, e.g. the mini NES ones with something like
WiiAccessoryToUSB
or a USB one or just buy a fitting one - Try out some various more-or-less Arduino compatible hardware and related software, like Teensy, Blue/Black Pill, Witty cloud, ESP8266, ESP32, TTGO, NodeMCU...
Over time, I collected some useful resources like instructional videos, references, a glossary and german translations, info about sourcing components.
- A simple guide to electronic components.: pretty cool recap of the vary basics, like what are resistors, capacitors, LEDs, diodes, transistors, explaining Ohm's law, ...
- Datasheets: 16x2 LCD By Hand (No microcontroller): good example with basic information on breadboard & IC basics, how to read datasheets, pull down/up resistors, button debounce.
- Ben Eater (channel): This has a lot of great info, as you can tell from the playlist titles «Building an 8-bit breadboard computer!», «Networking tutorial», «Build a 65c02-based computer from scratch ».
- Don't Take Capacitors for Granted: how to get polarity right.
- Beginner's Guide to Soldering Electronics: explaining the various options and how poisonous they are.
- Inside a Small Chinese Electronics Factory - From the Archives: How SMD components were printed on in a factory.
- Ben Eater's website with the parts list and the schematics for the 8 bit computer amongst many other things
- /r/beneater with lordmonoxide's posts containing and CalliGuy's post containing lots of gotchas
- «7400-series integrated circuits» on Wikipedia and the list explain numbers like
SN74LS08
, as does bigger-hammer's post and the futurlec IC74LS00 Series shop page - Logic Signal Voltage Levels cool comparison between TTL and CMOS / LS and HC from this post, see also this answer
- A high-res picture of a finished build
- Arduino Foundations portal into most documentation
- Arduino Built-In Examples, the codes form the examples menu but with circuits and explanations
- Arduino "language" reference: with the API and yeah also C++ if you want
- Arduino nano, page about the board type I'm using, check the tech specs, docs and FAQ tabs as well
- JOY-IT nano V3, the actual "Arduino-compatible" board I'm using, check the driver download and "ATmega328P (Old Bootloader)" instructions
- PROGMEM and AVR PGM Program Space Utilities
- There's the Arduino memory page, but really think: Flash ~ CD with program, SRAM ~ RAM – duh, EEPROM ~ hard disk.
- ASCII table for converting bits / numbers to letters and back manually
- Wikipedia articles about ICs
- How to Use a Breadboard comprehensive tutorial about the very basics
- Also in the shopping list below you can usually find the data sheets about the particular components
V
/ Voltage in volt, de: Spannung in VoltI
/ Current in amps / amperes, de: Strom / Stromstärke in AmpereR
/ Resistor in ohms, de: Wiederstand in Ohm- Capacitor, de: Kondensator
- Resistor, de: Widerstand
- Solderless THT / through-hole technology / Breadboard / dual-in-line / DIP packaging / 0.1 inch, de: Steckboard, 2,54 mm
- THT (not Solderless but also DIP sized hole distances), de: Lochrasterplatine
- SMD / Surface-mounted device / PCP / "the very small chips", de: Platine, Leiterplatte
- VCC / VDD / "5V", de: Pluspol, Spannungsquelle
- GND / Ground / VSS / 0V, de: Minuspol, Masse
- Serial:
- I2C / I²C / Inter-Integrated Circuit / I-Squared-C / TWI / Two-Wire-Interface: Bus with 2 wires (SDA, SCL), 1 controller and N peripherals with 7-bit addresses (often hardcoded)
- SPI / Serial Peripheral Interface, Bus with 4 wires (SCK/SCLK, SS/Slave-/chip-select, and 2 duplexed data wires. They are called MOSI/MISO or SDO/SDI (then cross connected). 1 Controller and N peripherals with SS.
- UART / Universal Asynchronous Receiver Transmitter: Bus with 2 wires for sending and retrieving, synced via start/stop bits.
Reichelt, Mouser, Conrad, Pollin, Amazon, Digi-Key...
You can just buy the kit from Ben directly which I would recommend. But I was not sure about shipping to Germany (especially with taxes) and I wanted some extra / custom parts, so I procured everything individually. I'm not sure whether I have everything, and also some things are not 100% compatible and will require some tinkering, but for me it's useful to have a list of the exact parts in my inventory and maybe someone else can buy similar things.
- USB power supply, Screwdriver, wire cutters, pilers, and box cutter I already had
- Wire stripper from Jokari
- Digital Multimeter from Crenova
- 22 AWG solid wire kit
- Jumper wire kit, Bus jumper wires
- Breadboards: 4k7v, BB830, BB830T
- Header pins
- ESD-15 tweezers, screwdriver, ...
- Soldering station: is on my wishlist
- Resistors
- Electrolytic capacitors
- Ceramic capacitors and 0.01µF ones
- 1MΩ potentiometer
- Slide switch
- DIP switch 4-position, 8-position
- Momentary tact pushbutton/switch: ordered various, will pick one to list later
- Mosfet: is on my whishlist
- 3,7V 1100mAh Lipo
- LEDs sortiment
- 7-segment LED displays, common cathode
- Bargraph yellow, green, green/red
- 5V LEDs with resistor: green, yellow, red
- 128x64 OLED screen (SBC-OLED01, Adafruit_SSD1306, GFX)
- LED matrix: 1588BS from starter kit, pinout
- Addressable LED strip: BTF-LIGHTING WS2812B 5M * 60/m = 300LEDs RGB
- Arduino nano clone
- "74189 64-bit RAM" (I only got a bigger one, maybe this post and links there help)
- 28C16 EEPROMs and mount (the 16K ones are unavailable, so I got 64K)
- LM-555 Timer ICs and mount
- Arduino UNO R3 clone with starter kit
- TTGO Display
- 74LS04 Hex inverter 5×
- 74LS08 Quad 2-input AND gate 3×
- 74LS00 quad NAND gate 2×
- 74LS02 quad NOR gate 1×
- 74LS32 Quad 2-input OR gate 1×
- 74LS86 Quad XOR gate 2×
- 74LS157 quad 2-1 line mux 4×
- 74LS107 dual J-K flip-flop 1×
- 74LS138 3-to-8 line decoder 1×
- 74LS139 2-to-4 line decoder 1×
- 74LS161 4-bit binary counter 2× (I only got the 163 with slightly different specs)
- 74LS173 4-bit D register 8×
- 74LS273 8-bit D register 1×
- 74HC595 8-bit shift register 2×
- 74LS245 8-bit bus transceiver 6×
- 74LS283 4-bit binary adder 2×