Last time on this blog, I made an ATTINY85 flash an LED
This time I made it turn on two different LEDās with a simple push of a button! (Warning; video has pulsing LEDās)
[VIDEO ID: a breadboard with a PDIP8 ATTINY85 microcontroller on it. There is a button next to it, and two LED'S connecting away from it; A yellow and a green. When the video starts, the yellow turns on, but every time a white human finger pushes and holds the switch, the yellow turns off and the green turns on. END ID]
This program will turn one LED on, but if you push the button it will turn it off and activate the other LED. The LEDās will alternate whoās on and off, and this is directly controlled by the tact switch
This one took a bit to code because I forgot how computers count!! And I knew better too!! I had all the bytes coded for 1,2,3,4 counting when computers count as 0,1,2,3. Very embarrassing š Alas, hereās the assembly code I made for it :)
My next step is to make it count two pulses based on a toggled input. While one switch is pushed, count the other switch to see how many pushes it has before the first switch is released. Then, once it gets the count, flash an LED the same number of times.
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
ā Live Streamingā Interactive Chatā Private Showsā HD Quality
Anya is LIVE right now
FREE
Free to watch ⢠No registration required ⢠HD streaming
I didnāt think Iād need to say this, but apparently I do:
Donāt use the Raspberry Pi 2040 to build a DCC decoder.
Itās not really wrong, of course, and it gives you ridiculous amounts of computing power, but to get that you need miles and miles of extra components. Like a dozen of decoupling capacitors, an external oscillator, and of course an external flash memory. You can maybe do that sort of thing in H0, but for real model trains, itās just not ideal. Pick something like an ATTiny or STM32C0 (Iāve done both for different projects): Cheap, just one or two decoupling capacitors, no external oscillator required and no external flash memory needed either.
The versions of the RP2350 with built in memory may be a better idea, once they fix the GPIO issues anyway, but still, thereās the oscillator and just way too many capacitors.
(Some of these concerns may be different if you want to add sound support, which requires more memory anyway. But Iād argue that sound in model railroads is a mistake anyway. Iāve never seen an N scale locomotive that sounds good, itās all just an annoying expensive gimmick.)
Also while weāre at it, donāt use a cheap standard bridge rectifier. The steep slopes of the DCC signal mandate a really fast rectifier, typically Schottky diodes. This is particularly important when you have RailCom on your layout. You may need four individual diodes instead of one rectifier, but since you wonāt need all the capacitors of the RP2040, you still win out in the end (itās also typically smaller than the rather large SMD standard rectifiers).
This is a call-out post for https://github.com/gab-k/RP2040-Decoder . Itās a useful project, but itās also far from ideal.
Two weeks ago I posted about my experiment with the ATTiny10. A 12Mhz 8-bit micro controller small enough to be confused with an obese ant. Unfortunately I didn't succeed in programming this tiny guy, so this week I continue my small scale flashing quest.
My first guess was that the tiny wires I used to connect the ATTiny10 to my USBasp flasher weren't working, or I damaged the ATTiny10 in my amateur micro soldering attempts.
To test if these were the causes, I soldered an ATTiny10 and a WS2812 2020 to SOP16 breakout board. This allows me to do some testing on a breadboard. It also made the soldering much simpler, lowering the risk of overheating the components.
Unfortunately, this didn't solve the issue. I still wasn't able to upload firmware to the ATTiny. Time to shift the focus to the next suspect: the USBasp flasher.
To program the ATTiny10 I tried using the USBasp flasher I bought from AliExpress. I used this Flasher to program my Electrocards, so I know it works. The only difference between the electrocard's ATTiny85 and the ATTiny10 is that the latter uses TPI protocol in stead of the ISP protocol to be programmed.
After a small Google session, I found the USBasp project website. Besides some interesting technical details, this website also offers the Firmware downloads. And that's where I noticed that TPI support was only available in the newest firmware. Maybe my cheap chinese USBasp included some old firmware? Time for an update!
To allow the USBasp to be updated, JP2 needs to be closed. In this case, the JP2 is on the back of the PCB. Soldering a short wire between these connection points is enough to enable self programming mode.
Next, I used an Arduino Uno as the programmer. To do so, I uploaded the ArduinoISP sketch to the Uno. This sketch is available in the Examples sketches section of the Arduino IDE. Next I connected the USBasp to the Arduino using the following pin configuration:
avrdude is a utility to download/upload/manipulate the ROM and EEPROM contents of AVR microcontrollers.
The -c flag specifies which programmer whe are using. In this case the Arduino usni which is configured as an avrisp programmer.
Using -P I specify to which port the Arduino Uno is connected. In my case this is the /dev/cu.usbmodem14201 port, but in your case it might have a different name/path.
Next, I specify the communication speed using the -b flag. In this case 19200 baud.
To get some feedback, I enable the verbose mode using -v.
And last but not least, I specify the type of AVR I want to program. Since my USBasp has a ATMEGA8A, I specify part m8 using the -p. If you omit the -p flag you'll get a list of all supported AVRs.
After running this command, avrdude will try to communicate with the USBasp's microcontroller using the Arduino avrisp.
Great! This works! Time to do the real work: flashing the USBasp with the new firmware. First I downloaded the latest firmware at: http://www.fischl.de/usbasp. In this case the latest firmware was usbasp.2011-05-28.tar.gz. After downloading and extracting the file (by simply double clicking it in the macOS finder) I navigated to the usbasp.2011-05-28/bin/firmware folder which includes the firmware I need: usbasp.atmega8.2011-05-28.hex.
Uploading the firmware to the USBasp is almost the same command as before:
In this case I've added the -U flag to do a memory operation:
I want to do an operation on the flash part of the micro controller.
I want to write, so I specify the write flash with the w flag.
And most important: I define the filename of the flash hex file (which is in the current folder)
Let's press enter, and hope for the best ...
Yes! It seems it has worked! :) Since the blue led has turned on after flashing, it really feels like something good has happened. LEDs always make thing better, right?!
Now, most important ... don't be like me: don't forget to open/disconnect that self programming jumper JP2 on the back of the USBasp! When it's connected/closed, the ESPasp won't be able to function.
So, after reconnecting the ATTIny10 to the USBasp, it's time for the most exciting part. Will the Arduino IDE, be able to flash the ATTiny10 using the ATTiny10Core?
How about we just select the USBasp programmer and smash that Upload button?
YEAH! It worked! :)
If you want to read more about this flashing process, make sure to read Roger Clark's great post on this subject...
For me it's time to start working the firmware to get that WS2812 2020 LED working. Don't miss it, so make sure to keep an eye on my blog or follow me on Twitter or Instagram.
Saturday night project! Setting up my #Arduino as an ISP programmer to program my new ATtiny chip with @arghuino! . . . @arduino.cc #arduino #attiny #microcontroller #saturdayproject #podpi #korea #codingheroes #stem #stemedu #stemeducation #electronics #breadboard #attiny84 #arduinouno #comic #edtech #led #21stcenturyskills (at Busan, South Korea)
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
ā Live Streamingā Interactive Chatā Private Showsā HD Quality
Anya is LIVE right now
FREE
Free to watch ⢠No registration required ⢠HD streaming
In the past few weeks Iāve built a model railroad signal for garden railways with a custom DCC decdoder. Hereās what it looks like:
Iāve heard from a number of people that they thought this was interesting, but they didnāt really understand what I was doing. So today Iāll try to explain the core of it all, this circuit board:
And hereās the associated circuit diagram:
Iāll try to explain why this is the way it is and what it does.
(This whole explanation is aimed at people who have never done anything with electronics before. If thatās not you, then this may be a bit boring. Also, I didnāt come up with any of the parts of this. Most of this is based on things I learned by reading OpenDCC and Mikrocontroller.net. Iām sure I still made a lot of mistakes, though, and theyāre definitely all mine and not the fault of anyone on these sites.)
The goal
First letās talk about requirements. My goal was to build an american signal type āSearchlightā. Such a signal has between one and three lamps. Thanks to a clever electromechanic design that moves different color filters around, each lamp can show different colors - up to three from a total selection of four.
Replicating this system for a model railroad is not practical. I need something else. Having multiple colored LEDs next to each other wouldnāt work; theyāre too big and I want it to all look like one light source. There are LEDs that contain red, blue and green in one housing, but that would require a lot of wires quickly that all have to be put in the mast. The solution is this:
This is an āadressableā LED, better known under the name āNeopixelā used by a large american online store. There are many variations from different manufacturers. The key thing is that each LED has a tiny control circuit built right in. It takes four wires: Plus five volts, minus, data in and data out. If you have more than one, you can connect the data out of the first directly to the data in of the second and so on. Connect the plus and minus as well, and you can control almost unlimited amounts of LEDs with just three wires.
The data line has a special protocol that you need to generate. Basically you need to switch it from 0 to 5 to 0 volts again and again at a certain rate; the time it stays at 5 volts (āhighā) determines whether youāre sending a 0 or a 1. From these bits you form bytes, which tell each LED what specific color value to send.
Due to this dataformat, you definitely need some electronic circuit controlling the signal, and the first requirements for this are:
Provide five volts DC power
Generate the data for the LEDs in the correct format
The Input
There are a lot of options for designing the input side of things. In my case, Iām assuming the signal is electrically connected to the rails of a model railroad that is controlled digitally. With digital command control (DCC), the voltage at the rails has a constant value of about 15 to 25 volts, larger for larger scales. This voltage constantly flips polarity; first plus is on the left rail, then it goes to the right rail (and minus vice versa), and then back. Itās like AC in normal wall outlets, but with very abrupt changes instead of a smooth sine wave.
This voltage has two tasks. First it supplies the locomotives with power, but it also transmits information. If one of these change-and-back sequences is long, it transmits a ā0ā; if itās short, it transmits a ā1ā. These bits together then form the bytes that form the messages that say things like, āLocomotive three run at speed step 64ā or āswitch 10 switch to direction leftā.
This decoder uses both features. The digital voltage provides both the data and the power. For a locomotive, that is required since the only conductors you have are the rails. This is a stationary decoder, so I could have designed it so that it only uses digital commands, and gets the power from an external power supply. However, I wanted to use the least amount of cables, so Iām using the simple version.
With that, the requirements are fixed. The circuit has to:
Turn the digital power (15-25 Volts, AC-ish) into 5 Volts DC
Read and understand the digital data signal (decode it, hence the name ādecoderā) and calculate the colors for the LEDs.
Computation
This calculation is the real key here. The digital signal has a completely different fromat than what the LEDs expect. Itās slower, but also has completely different meaning. At best it transmits āset switch or signal 10 to state 0ā. Which color values are associated with that, let alone any blending to make it look nice, are things the signal has to decide for itself. There is no way to build a simple stupid adapter here; I need a complete computer.
Luckily, you can get those for cheap and in really tiny.
The ATtiny85 costs about 1⬠depending on how many you order, and itās smaller than one cent coin (I think in basically any currency), but from a technical point of view, it is essentially a full computer. It has all the important parts anyway. There is a CPU that can run at (depending on the version) up to 20 MHz; half a kilobyte of RAM and eight kilobyte of internal storage for the program. Multiple programs is a bit of a challenge. If you know Arduinos, the ATtiny85 is related to the ATmega328p in the Arduino Uno and Nano. Far less powerful, but cheaper and significantly smaller.
What it lacks are all the surroundings like keyboard and screen for input and output. The chip is designed for applications where this isnāt needed, or at least only minimal things. The software that you write can assign each pin (okay, five out of eight) freely for different tasks: The pin can work as an input, telling the software whether thereās a low or high level of voltage at it (meaning 0 or 5 Volts), or it can work as an output and write high or low values, meaning setting the pin explicitly to 0 or 5 Volts.
There are other options for the Pins as well; among other things it can also read analog voltages and generate them to some extent. But for this task I only need the simple digital high-low inputs and outputs.
These types of chips, known as microcontrollers, exist in thousands of variations by different manufacturers with very different performance characteristics. They are the key part of basically everything thatās digitally controlled these days. Washing machines, everything that plugs into a computer including every single Apple lightning cable, TVs, TV remotes, amazing amounts of parts in cars and so on are all the realm of microcontrollers. The ATtiny85 is, as the name implies, very much at the low end of the scale (though there are smaller ones), and even here, it is a bit out of date. But it is very easy to program and very forgiving of mistakes, which makes it great in hobby situations.
To run, this chip needs around 3-5 Volts DC (some versions like the one here can also run on a bit less) and exactly one capacitor. Iām already generating 5 Volts DC for the LEDs anyway, so this chip will get them as well. That means for all the calculation, only two pieces of hardware are required.
There is some more associated hardware, though, for getting the program (which Iāve written myself) on the chip. For that you need a programmer, a device that you can buy for some money, or make yourself astonishingly easily from an Arduino. It needs to be connected with six wires to the chip. The standard for this is with a six-pin plug, which Iāve thus included here as well. There are standard six-wire cables for this.
You could connect the cables differently, for example with some sort of spring-loaded contacts on some programming circuit board youād have to build for that, or in the worst case, just temporarily solder the cables in there. But the plug version is both simple and convenient, with the only downside that it makes the circuit a bit more pointy.
(Due to the Tumblr image limit, the next part will have to be in a reblog)
If you are a regular visitor of my blog, you might know that (with a few exceptions) I've been posting a new blog posts every two weeks. Unfortunately I skipped this regular update last week, because I've been a little bit sick. Nothing major, but I didn't want to contaminate my boxes of SMD components with germs. So after a few days of sleep it's time to get back to business and start with something small. Literally.
Due to my mandatory rest, I haven't had the time to work on something interesting to blog about. Of course this happens every once in a while, and so my usual solution is to just go through my recent Ali Express deliveries, to see if there is something I can either get up and running, or kill with some magic smoke.
Soon I found a suitable candidate: the ATTiny10. This tiny guy contains a 12Mhz 8-bit micro controller with 1024 bytes of flash memory and 32 bytes of ram. Of course a micro controller is a bit boring without any in- or output, so i wanted to combine it with an other recent delivery: A WS2812B addressable RGB led in a 2020 package. Together with some 0.2mm enameled wire this can be a pretty fascinating micro-project.
To make the soldering a bit doable, I put some kapton-tape on my workbench, sticky side up. This allows me to keep both component in place while I try to reach the limit of my soldering skills.
First, let's connect some wires to the ATTiny10. With a macro lens in front of my iPhone's camera, it looks like it's huge. Unfortunately it's still roughly the size of my soldering iron's tip.
Let's start the surgery. Please be quiet, and don't breath to much or else we need to start all over again.
After a few burned fingers, too much soldering flux and to my own surprise I managed to connect wires to all six pins.
And a few minutes later, I managed to solder the WS2812 as well. Just a few more soldering joints and the programming header will be connected as well. This should allow me to program the ATTiny10 using the USBasp programmer.
And here it is! The end result! An illuminated led! Great isn't it?! OK! See you next time!
Ok, ok. I'm going to be honest here. The reason the LED is illuminated is just because I managed to add some "noise" data on the data line when I touched the micro controller while it was powered on. So nothing more than a lucky shot.
Of course I still need to program the ATTiny. But here's the catch: It turns out the ATTiny isn't supported by PlatformIO. So I had to revert back to the dreadful Arduino IDE.
David Johnson-Davies wrote a nice post on how to program the ATTiny10 and even supplied the necessary files needed to do so using the Arduino IDE. But as you can see, in the screenshot above, I ran into an error.
Now, to be honest I don't know what causes this issue. It might be one of the following:
The USBasp I'm using is damaged or doesn't support the necessary TPI protocol. (Unlikely)
The ATTiny isn't connected correctly, maybe do to a bad soldering connection. (Still a bit unlikely)
I overheated and damaged the ATTiny when I soldered the connections. (Sounds a bit more likely)
I'm doing something wrong with the software. (Sounds likely)
I'm still not fully recovered and missing something completely obvious. (99% sure this is it)
Of course I could have spent a week trying to solve this. But that would mean yet an other quiet week on my blog. So, instead I just end this write-up with a big anti-climax.
If I'm able to solve this issue in the coming two weeks, I'll report back in my next blog. If you have any suggestions or pointers to a solution, leave them in the comments down below.
PS. Still looking for something awesome? Make sure to check this.
Now that the hardware part of my Electrocard is done, it's time to start working on the software side of my electronic business card.
This is a 3 part story. Check out the previous parts here:
Part 1: Designing the PCB.
Part 2: Soldering the board.
First of all, it's good to make a list of the desired functionalities. Of course, the OLED screen combined with the 3 push buttons give me a lot of nice opportunities, so most of all, the display will be used to display the important company information for as far as it isn't already printed on the PCB's.
Secondary, it would be nice to display some debug information regarding the battery, the memory and the software version.
And last but not least, it's mandatory to add a nice easter egg to a business card like this. But more about that later.
The controls
Since I have three buttons, and have both primary and secondary functionalities, I want to add a short press and long press feature to the buttons. This is easily done with the help of the clickButton library. It gives me a simple way to add 6 desired modes:
Button A, Short press: Power on / Display the startup screen.
Button B, Short press: Display my company's address.
Button C, Short press: Display my company's & blog's url.
Button A, Long press: Standby mode (also initiated after 30 seconds of inactivity).
Button B, Long press: Debug mode.
Button C, Long press: Start the easter egg.
With the help of the earlier mentioned button library and a simple state machine the user can switch between the various modes, without the need of an complicated user interface.
Controlling the display
Controlling the display isn't particular difficult, especially since there are a lot of example codes and libraries available to control the SSD1306 OLED controlled I've used. I've tried a few of them, and most of them run fine on the ATTiny85 processor. But during the process I found out there are actually two separate challenges.
Control the display by sending an image to the OLED controller.
Drawing realtime graphics onto the screen.
The first challenge isn't extremely difficult. Most of the available libraries allow you to send a 128x32 pixel monochrome image (a BPM converted to a HEX values stored in the micro controller's flash memory) to the OLED controller. It took a while to figure out how to convert the BPM to the correct values, since it depends a bit on how the library reads and writes the data. But after some googling I found a working combination of the TinyOLED library and the LCD Assistant image converter.
This is the same method as used for writing text to the OLED. In stead of one complete stream of image data, every letter has a small portion of data (6 bytes) which is read from the micro controller's flash memory.
The second part is a bit more complicated, and that is mostly due to the limited available memory (RAM) of the ATTiny85 micro controller.
The OLED expects a sequential stream of bytes to control 8 vertical pixels per byte. The 128x32 pixel oled is built up by four rows (called pages) of 8 vertical pixels (1 byte). Each 128 bytes width. In total that adds up to 512 bytes.
If you want to draw lines and shapes on any position on the screen, you'll need to create a buffer for those 4096 pixels (512 bytes) in the micro controller's memory, to which you can draw. After drawing to the buffer, you send the full buffer to the OLED and your lines and shapes are displayed on the screen. That's how most OLED libraries work (for example, the popular Adafruit SSD1306 library).
The problem is, that you'll need to allocate 512 bytes of memory in you micro controller as the buffer. Since the ATTiny85 I used only has 512 bytes of RAM in total, there isn't enough memory to allocate this buffer.
In other words: I can't allocate a buffer. I need to render the drawing while I'm writing all the graphics data to the OLED controller. This turned out to be a BIG challenge. And while I only needed this for incorporating the easter egg, it's something I wanted to solve.
The Easter Egg: Horizontal Micro Tetris!
So, as told, I wanted to add a nice easter egg. I already programmed Pong once. But with the 3 push switches and the width 128x32 pixel screen, i reckon Tetris was better suited. Or to be more precise: horizontal Tetris. The added benefit of tetris is that it doesn't need a high frame rate. And honestly, seeing such a cute little Tetris game on a business card, brings a smile to most people's faces.
Due to the size of the screen, I opted to go for Tetris blocks of 4x4 pixel squares. This way, 8 blocks will fit vertically, and there is room for 32 horizontal blocks. In total there will be room for 256 blocks.
The blocks that are already on screen will be stored in an array called the arenaMatrix. And since each vertical row has 8 blocks, this array will consist of 32 bytes.
unsigned char arenaMatrix [32] = {};
The currently falling piece will be stored in a 4x4 block matrix, called the userMatrix. And since since we only need 16 bits of data, we can easily store this in an integer.
unsigned int playerMatrix = 0;
In other words, for storing all the blocks, we only need 34 bytes of data. Leaving us 478 bytes for additional variables (like the score and the user's piece position) but of course also a lot of other objects and pieces of code that's loaded in to memory.
Since the two matrixes matrices contain every piece of information I want to display on screen during a game of tetris, the render function can "simply" lookup and calculate the bytes of data for the OLED controller on the fly. This solves the lack of the graphics buffer. Or, if you look at it from a different perspecitve: this is an alternative graphics buffer with a 1/16th resolution (since the blocks are made of of 4x4 pixels).
In any way: it allowed me to render tetris without the use of any helper methods like drawLine() or drawSquare(). It all comes down to flipping bits one by one. Which isn't the most convenient, but did teach me A LOT about bit manipulation.
Now, of course, drawing a few matrices to the screen isn't enough to make a playable tetris. It needs some timers to drop the pieces. It needs collision detection to check if the blocks hit an other block. It needs a way to check if a fill line is filled with blocks, and it needs a way to remove the fully filled lines.
The Code
I'd love to run you thru the code, but that would probably account for a full year of blog posts. So to make things easier, I put all my code on GitHub so you can take a look at everything that's in there. Feel free to take a look at the Electrocard Repository.
If you're not familiar with the PlatformIO folder structure, you might want to start at the entrance point of the firmware in the main.cpp file. If you're mainly curious for the Tetris code, check out the Tetris.cpp file.
Fun fact: the full code used almost every byte of flash available in the the ATTiny85 (8KB). Of course, I could work on making the code more efficient, but everything I wanted to be in there is in the code.
Game Over
And with this information, I think this project is a wrap. It was an extremely satisfying and fun project to work on. Both the electronics and the code.
Although I'm extremely satisfied with the end product, there are some things to reconsider if I start a similar product:
Consider a different micro controller. Finding a solution for the limited amount of memory of the ATTiny85 was fun, but having a little bit more memory would probably allow me to add a few nice effects.
If I did have an other micro controller, I'd probably have more GPIO pins, which allowed me to add more buttons, and a nice colorful LED. Every project is better with a LED.
In the future, I'll definitely check EVERY footprint before I order my PCB's.
Work on the software on the breadboard prototype before you finish up the PCB. This would have showed me the limiting factor of the ATTiny85. I would have given me a heads up before I pulled out all my hairs during the search for a solution.
If you have any question or suggestions about this project, feel free to leave them in the comments down below.