Last post I ended with a blinking LED, just to verify that uploading code to the ATtiny works. The next step was testing the software SPI routine and actually talking to the MAX7221 ICs. Nerd Ralph wrote a wonderful software SPI implementation that I wanted to give a try. And of course it didn't work. Most likely it was something I was doing wrong. The LED displays were not doing anything, so time to bring out the oscilloscope!
Sure enough I was getting some signals out of the ATtiny, but I was missing the clock signal. After some debugging I found a typo I introduced to the SPI code. After fixing that, I got the right signals on the scope:
And of course, the LED displays finally did their magic:
Okay, cool, that works!
I already had some PCBs designed and manufactured using the same schematics I had on the breadboard.
So it's basically just four MAX7221's wired to an ATtiny24a. The MAX's are daisy chained in two strings of two. I'm using software SPI here because I need the SPI hardware to communicate with the main micro of this project. The ATtiny will act as an SPI slave.
Laying out this board was a nice challenge:
The pin layout of the MAX7221 so does NOT match the pin layout of the LED displays, so there's no way of doing this without a bunch of vias.
There's four displays on the front of the board and a couple of passives for the rotary encoder.
On the back we find the ICs and some more passives. As well as a connector for the rotary encoder and an ICSP header that also doubles as a connector to the main board.
The electrolytic capacitors, displays and connectors are through hole, all the other components are surface mount. The resistors and caps are 0603's. It's tiny, but everything can be soldered by hand. Even by me. And I suck at soldering.
Oh wow, it actually works!
Final shot: the prototype on the breadboard and the completed board next to it.
Wednesday, April 27, 2016
Sunday, April 24, 2016
Prototyping
I've been working on a little project for a while now. I want to build a programmable DC load, which isn't that complicated in itself. But I also want it to have a nice user interface. I didn't want to go with the standard 4 line character displays that everybody seems to be using. Instead I want to use a couple of segment LED displays to display voltage, current, power and resistance. The main reason for that is that I believe they're easier to read than a cheap LCD. The other reason is that they look much nicer IMHO :)
I have got a nice Hammond sink box in my parts bin that I'd like to use for this project. It's a big aluminium housing that can act as a heat sink. You can just bolt TO-220 packages to it on the inside; pretty neat.
Anyway. This means the dimensions are pretty much fixed and there's not much room to work with. This is what I came up with:
I'll probably move the connectors to the bottom and the rotary encoder to the right, but this should give you an idea of the dimensions.
The user interface will have its own micro controller to handle all the input and "menu" logic. I'll use an ATtiny24A for this (2K ROM, 128 RAM, 128 EEPROM, 14 pins) and four MAX7221's.
I already did some testing with an Arduino Nano to play with the rotary encoder and two displays. That worked pretty well, time to really start prototyping:
Yeah, messy. But nothing spectacular, just scaling up the previous setup. The icky part is using a new micro.
When using a bare ATtiny on a breadboard you only need two extra components: one ceramic cap (100nF) across the power supply pins and one resistor (1K-10K) between VCC and RESET. The ATtiny has an internal oscillator which it will use as a clock by default, so no need for a crystal.
Now for programming these micros. I always like to start of easy, just to make sure the programmer is wired correctly and I didn't mess up the clock settings. So I wrote a small program that toggles a specific pin every second, compiled that and uploaded it using avr-dude and a cheap USBASP dongle. And then all hell broke loose.
For starters, Windows 10 doesn't like the unsigned USBASP drivers, so I had to jump through some hoops to get that done. Then I managed to upload a program, once. After that I got all sorts of verification errors. Thinking the programmer was at fault, (since it was spewing out some warnings), I attempted to upgrade its firmware, bricking it in the process. Yay.
Plan B. Use an Arduino Nano as ISP programmer. That's simply a matter of uploading the AruinoISP sketch and wiring it to the ATtiny.
Still, no success. I could download the existing program from the ATtiny, but uploading a new one resulted in verification errors: it wouldn't write the new program.
Double checking the avr-dude configuration for the ATtiny with the datasheet didn't bring up any errors; that seemed to be okay. Then I attempted to write a custom binary file of all zeroes. That worked! But writing anything else didn't :/
Final step: swapping the ATtiny for a new one. Surprisingly, I was able to upload my program and finally got a blinking LED! But it was blinking too slow, so I probably got the speed wrong. After fixing my code the upload failed again! Comparing the uploaded code to the code read from the micro it finally hit me: bits were only being set to zero! Meaning the memory wasn't cleared before writing! Double checking the flags being passed to avr-dude I noticed the -D flag. Removing that fixed the problem! That only took an entire afternoon :/
So, next problem. The LED was only blinking every 8 seconds, instead of every second. The ATtiny is supposed to run at 8 MHz, but apparently it was only running at 1 MHz. A quick peek in the datasheet revealed the cause: CKDIV8 was enabled in one of the fuses, causing the clock to be divided by 8. All this setting does is set the default value of the clock prescaler to 8 instead of 1. This can either be fixed by burning new fuse values, or by setting the prescaler in code. I opted for the latter, because (a) that's easier to do than googling how to burn fuses, (b) I'm lazy and (c) it will work for new ICs with default fuses.
Two lines of code later, the LED is finally blinking at the right speed :)
Next: porting the existing code...
I have got a nice Hammond sink box in my parts bin that I'd like to use for this project. It's a big aluminium housing that can act as a heat sink. You can just bolt TO-220 packages to it on the inside; pretty neat.
Anyway. This means the dimensions are pretty much fixed and there's not much room to work with. This is what I came up with:
I'll probably move the connectors to the bottom and the rotary encoder to the right, but this should give you an idea of the dimensions.
The user interface will have its own micro controller to handle all the input and "menu" logic. I'll use an ATtiny24A for this (2K ROM, 128 RAM, 128 EEPROM, 14 pins) and four MAX7221's.
I already did some testing with an Arduino Nano to play with the rotary encoder and two displays. That worked pretty well, time to really start prototyping:
Yeah, messy. But nothing spectacular, just scaling up the previous setup. The icky part is using a new micro.
When using a bare ATtiny on a breadboard you only need two extra components: one ceramic cap (100nF) across the power supply pins and one resistor (1K-10K) between VCC and RESET. The ATtiny has an internal oscillator which it will use as a clock by default, so no need for a crystal.
Now for programming these micros. I always like to start of easy, just to make sure the programmer is wired correctly and I didn't mess up the clock settings. So I wrote a small program that toggles a specific pin every second, compiled that and uploaded it using avr-dude and a cheap USBASP dongle. And then all hell broke loose.
For starters, Windows 10 doesn't like the unsigned USBASP drivers, so I had to jump through some hoops to get that done. Then I managed to upload a program, once. After that I got all sorts of verification errors. Thinking the programmer was at fault, (since it was spewing out some warnings), I attempted to upgrade its firmware, bricking it in the process. Yay.
Plan B. Use an Arduino Nano as ISP programmer. That's simply a matter of uploading the AruinoISP sketch and wiring it to the ATtiny.
Still, no success. I could download the existing program from the ATtiny, but uploading a new one resulted in verification errors: it wouldn't write the new program.
Double checking the avr-dude configuration for the ATtiny with the datasheet didn't bring up any errors; that seemed to be okay. Then I attempted to write a custom binary file of all zeroes. That worked! But writing anything else didn't :/
Final step: swapping the ATtiny for a new one. Surprisingly, I was able to upload my program and finally got a blinking LED! But it was blinking too slow, so I probably got the speed wrong. After fixing my code the upload failed again! Comparing the uploaded code to the code read from the micro it finally hit me: bits were only being set to zero! Meaning the memory wasn't cleared before writing! Double checking the flags being passed to avr-dude I noticed the -D flag. Removing that fixed the problem! That only took an entire afternoon :/
So, next problem. The LED was only blinking every 8 seconds, instead of every second. The ATtiny is supposed to run at 8 MHz, but apparently it was only running at 1 MHz. A quick peek in the datasheet revealed the cause: CKDIV8 was enabled in one of the fuses, causing the clock to be divided by 8. All this setting does is set the default value of the clock prescaler to 8 instead of 1. This can either be fixed by burning new fuse values, or by setting the prescaler in code. I opted for the latter, because (a) that's easier to do than googling how to burn fuses, (b) I'm lazy and (c) it will work for new ICs with default fuses.
Two lines of code later, the LED is finally blinking at the right speed :)
Next: porting the existing code...
Tuesday, April 19, 2016
Fun with MAX7221 chips
Just a quick, short post here to show some stuff. I've been playing around with some seven-segment LED's and MAX7221 IC's; great fun. In collaboration with a colleague I've built a build monitor for our Jenkins CI server.
If you're interested in the source code: you can download it here
I'm using Atmel Studio 7 this time instead of the Arduino IDE. I had to roll my own UART interrupt handler in order to get everything to work correctly. The HardwareSerial class of Arduino just didn't cut it. I'm using AVRDude to upload the resulting HEX file to the Arduino.
It's three custom PCB's with a MAX7221 and seven segment display. The PCB's can be daisy chained. You can order the PCB's here. The bottom unit connects to an Arduino Nano. Vcc and Gnd connect to the 5V and Gnd pins. CLK to pin 13 (SCK). DIN to pin 11 (MOSI). CS to pin 9.
This is the schematic for a single PCB:
The PCB layout:
And a 3D render:
Yay, boards!
Doing some debugging:
It's working!
Combined with our CI Traffic light:
If you're interested in the source code: you can download it here
I'm using Atmel Studio 7 this time instead of the Arduino IDE. I had to roll my own UART interrupt handler in order to get everything to work correctly. The HardwareSerial class of Arduino just didn't cut it. I'm using AVRDude to upload the resulting HEX file to the Arduino.
It's three custom PCB's with a MAX7221 and seven segment display. The PCB's can be daisy chained. You can order the PCB's here. The bottom unit connects to an Arduino Nano. Vcc and Gnd connect to the 5V and Gnd pins. CLK to pin 13 (SCK). DIN to pin 11 (MOSI). CS to pin 9.
This is the schematic for a single PCB:
The PCB layout:
And a 3D render:
Yay, boards!
Doing some debugging:
It's working!
Combined with our CI Traffic light:
Subscribe to:
Posts (Atom)