This gallery contains 6 photos.
Today I revived the anodized parts and they are beautiful. A word of advice for anyone looking to get something anodized. Don’t get the parts sand blasted because anodizing works best on smooth surfaces.
This gallery contains 6 photos.
Today I revived the anodized parts and they are beautiful. A word of advice for anyone looking to get something anodized. Don’t get the parts sand blasted because anodizing works best on smooth surfaces.
So now that I have my frame data in neat frame by frame arrays I only need to build some test hardware and write the code for my micro processor. The hardware part was easy – I simply used some stripboard to solder a classic one resistor per led matrix and since the MSP430 value line can only sink and source about 2 mA per pin I also added some npn transistor buffers to the columns for protection.
Now for the interesting part. Since I wanted to keep current consumption as low as possible I decided to drive my matrix one led at a time just like a progressive scan TV functions. With enough speed its is possible to drive a quite large display this way while keeping current consumption relatively low. This method is usually used to drive single color led matrices but I wanted at least 8 bits of color depth so instead of just scanning the whole display and either turning the led on or off accordingly I figured that I might get away with one PWM cycle per led.
My matrix was gonna be 5×10 so max brightness of it was gonna be 1/50 of the maximum brightness of the led, well at least in theory.
On to the code part. I implemented my ideas on the MSP430 Launchpad ( the MSPg2553 to be exact ) . My algorythm looked something like this:
Timer0 has 2 compare match interrupts ( CCR0 and CCR1 ) and it can be configured to count up to CCR0 and then to reset itself. At CCR0 I take the value of first pixel of the frame and set CCR1 to equal it. I also set the corresponding led to be lit. At CCR1 I set the led to be off and increment the pixel counter so that at CCR0 the next led will be lit and the corresponding value will be written to the CCR1 register.
This will continually cycle through the entire matrix and thus draw a frame. I also count the number of times the frame has been drawn and after the correct amount of times I increment the frame counter so the next frame will be drawn. All this is done with iterative for loops because that’s how interrupts function.
My frame data is in arrays and selecting an array in a for loop is trickier than you might expect because you need to employ pointers. Now most programmers will run in fear when you mention pointers but I didn’t find them to me difficult at all I thought they were rather neat and useful.
Here is all that is needed for my project.
|
1 2 3 4 5 6 7 8 9 10 11 |
.....
const unsigned int (*frame_array[50])[5][10];
.....
frame_array[0]=& frame_0;
frame_array[1]=& frame_1;
frame_array[2]=& frame_2;
.... |
I have an array of pointers that point to arrays. Yo dawg, right ? And to initialize this array of pointers I simply point the elements to the arrays I need. Simple really.
What usually confuses people is the syntax and there really is two things you need to know – ‘*register’ equals the value of the register being pointed to and ‘& register’ equals the address of the register. An example
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
register=1; //register is set to equal something
pointer= & register; //pointer is set to point to the register
// and to use it
new register = *pointer; // a new register is set to equal the value of the register that the pointer is pointing to
//it is even more useful with arrays
Array_0[]= some data;
Array_1[]= some other data;
.... //here we have use an array of pointers so we can switch easily between the arrays
(array_pointer[0])[] = & Array_0;
(array_pointer[1])[] = & Array_1;
..... // and to use them
new register = (*array_ponter)[x][y]; |
And finally some videos of it in action.
Some friend of a friend is a pixel artist and did this animation for this display. I also gifted this to a someone for her birthday, hence the box.

After a bit of delay or laser-cut parts finally arrived. They are a mixture of aluminium and steel parts. I spent most of the day cleaning the components from bits of molten metal, a side effect of the laser cutting process. Next step will be to send them off to be anodized for protection and aesthetic purposes. This is all very exiting as this brings us ever closer to a complete robot platform.
Unfortunately not everything has been satisfactory. This is the second time we have ordered our laser cut components from FinEst Steel and both of the times we had problems with poor quality controll. The first time one of the sharp leg “bones” was misshapen from what seem like a CNC belt slipping. We did not recive a replacement. At the time we believed this to be an isolated incident and made no mention of it here.
This time one of the ordered components was not cut and in its place we received an overabundance of a different, similar component. I have contacted them about the problem and we shall see how it gets handled this time.
I have been tasked with the design of the next year’s coil-gun driver for University of Tartu’s robotics club. Since this will be handed out to newcomers and complete novices special care needs to be taken in it’s design. The driver needs to be as safe and as foolproof as possible.
One of the most common novice mistakes in electronics is connecting the power plug backwards. Mechanical solutions usually prevent that but our solution also needs to have a degree of flexibility that mechanical solutions cannot provide.
Turns out that there is a low cost, high efficiency electronic way of doing reverse input protection. An ideal diode. “That’s impossible”, I hear you say “those don’t exist!”. Oh but they do and they are called MOSFETs. Using a single n-mosfet and a resistor it is possible to drive the low side of currents in excess of 10A.
I was also sceptical at first so I set out to test this. I needed this configuration to provide reverse input protectionat 9A, 12V without needing a heatsink. So I soldered a MOSFET to some stripboard, hooked it up to a beefy power supply and an even beefier variable resistor and set out to gather some data.

from left to right: voltage drop across in mV, temp of mosfet in C, supply voltage in V, current in A
Here we see that at 9A the power dissipated on the MOSFET is only around 1W which the SOIC-8 package of the MOSFET can handle with ease.
Success!

The first board that was soldered with my oven worked but was ugly, mostly because my method of applying paste was at best sloppy. So today I went to the local pharmacy and got myself a syringe. I’d say I’m quite pleased with the results ( ignore the routing error, this is only a proof of concept board ) .
LEDs are cool. There is no doubt about it. But you know what is even cooler? A lot of leds. As a fun learning exercise I decided to attempt a LED dot matrix display with some limitations to make it interesting. Namely it needs to be capable of at least 8 bits of grey-scale and each pixel needs to be individually addressable. Why? Why for animations of course. Also the total current consumption of the device needs to be less than 10mA at 3V.
Ever since playing Mass Effect 2 I have been thinking of 8bit fire animations. After a couple of hours of searching the web for fire GIF-s I found a suitable animation. I happened to have 50 Led-s laying around so I decided that my resolution was going to be 5×10 pixels. Obviously the animation I found is much larger than that. Nothing a little image manipulation can’t fix. Using Photoshop I re-sized the animation, converted it to 8-bit gray-scale and extracted the frames into separate bitmaps.
That was the easy part. In order for those animations to be useful to me they need to be converted into arrays of brightness levels. Since I didn’t believe it to be an extremely important for me to learn all about GIF encoding I wrote this python script to handle the conversion.
Here is my code. It should be portable and should handle any sequence of images that follow the naming convention of ‘prefix+number(0..n).bmp’
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
from PIL import Image
frames= raw_input("Enter nr. of frames: ")
prefix = raw_input("Enter filename : ")
filetype = raw_input("Enter filetype: ")
f=open('frame_data.txt','w')
j=0
for k in range(int(frames)):
filename = prefix + str(k+1)+"."+ filetype
i = Image.open(str(filename))
pixels = i.load() # this is not a list, nor is it list()'able
width, height = i.size
f.write("const unsigned int frame_"+str(k)+"["+str(height)+"]["+str(width)+"] "+"= \r{")
all_pixels = []
for y in range(height):
for x in range(width):
cpixel = pixels[x, y]
print cpixel
all_pixels.append(cpixel)
f.write(str(cpixel[0]*16)+",")
f.write("};\n")
f.close()
print "Operation completed" |
requirements: pyton 2.7 & PIL(Python Imaging Library)
and here is some sample data that I got
|
1 2 3 4 5 6 7 8 9 10 |
const unsigned int frame_0[5][10] =
{3552,1840,256,1568,784,1440,1440,256,128,384,3152,3808,2752,
1968,2224,2368,1040,0,1184,384,2880,3936,4080,1440,3024,3280,
512,0,784,512,2880,4080,3280,1568,2368,2096,1312,1568,784,256,
2496,1968,1840,3280,1440,384,1040,1312,512,384,};
const unsigned int frame_1[5][10] =
{3408,2624,256,1040,1184,1040,1568,384,0,384,2624,3552,3408,2096
,2096,2224,1840,128,512,512,2880,3280,4080,2224,2096,3680,1440,0
,512,512,2752,3552,3808,1840,1968,2496,1312,1440,912,256,1968,
2096,1440,2880,1840,656,512,1184,656,384,}; |
Because of lazyness I used notepad++ to delete the last comma of the array (search and replace ‘,}’ with ‘}’)
Next post will explain why my script expands the original values to 12 bits and how pointers and arrays can made to play nice.

overview
So now the hardware part of the build has been completed. We have a safe way to switch the heating element on and we have a way of measuring the temperature of the oven. Now all that is needed is a way to automate it for reflow.
For those not in the know reflow soldering is a process wherein smd components are soldered to a PCB using solder paste ( a mixture of tin powder and flux ) and indirect heat. For good results an specific temperature profile needs to be maintained. Really high-end industrial machines follow complex profiles and are accurate to fractions of a degree but really there are two phases to reflow soldering – the soak/pre-heat phase and the solder phase. There are of course other considerations like ramp up time and so fourth but for home brew they really aren’t that important.

close-up of the driver board
So what do these separate phases entail? According to the spec sheet that I found the soak phase has a maximum ramp up rate of 6C/sec, a time duration in 60 to 120 seconds and a maximum of temperature of 150C. I’m pretty certain that the maximum ramp up rate of my grill is much lower that 6C/sec so I don’t have to bother with that but the other requirements I do need to be mindful of. Similarly the reflow phase has similar requirements max: ramp up rate of 3C/sec, time above 217C 60 to 150 sec a peak temperature of 260 deg and time within 5C of peak temperature of ~30 sec.

the oven splayed open
In the beginning I had hoped that simply turning on the grill when the temperature is lower than the set point and turning it off when it reaches it would suffice but such a scheme lead to massive overshoots of more than 15C usually. That is not acceptable. So a proper PID algorithm was needed.

location of the temperature sensor
PID has always been something that beginners fear and is always made out to be more complex than it really is. It really is quite simple actually. It’s actually all in the name – “Proportional Integral Derivative”.
|
1 2 3 4 5 6 7 8 9 10 |
previous_error = setpoint - process_feedback
integral = 0
start:
wait(dt)
error = setpoint - process_feedback
integral = integral + (error*dt)
derivative = (error - previous_error)/dt
output = (Kp*error) + (Ki*integral) + (Kd*derivative)
previous_error = error
goto start |
A PID algorithm has as input an error – the difference between the desired variable and the set variable ( in my case the temperature ) and as an output a signal used to influence that variable ( in my case the duty cycle of PWM ). The proportional component of PID is the simplest. You just take the error and multiply it with a constant. Other components aren’t that much more difficult.
The most difficult part about PID is finding the constants. I did it through trial and error but wikipedia has some info on various other methods as well . (http://en.wikipedia.org/wiki/PID_controller#Loop_tuning)
When it comes to electronic temperature measurement one only really has two options thermistors or thermocouples. Both means have their place in the arsenal of an electrical engineer but they fundamentally differ in the type of temperature measurement that they enable. One measures relative temperature and the other measures absolute temperature.
Because thermocoples can only measure relative temperature their interface circuits tend to be more complex and as such more expensive than thermistor circuits. For my reflow oven project I decided to go with thermistors as the interface circuitry only needs a ADC and resistor.



Thermistors are really nothing more than resistors that have been engineered to have a maximal resistance variance over a temperature range. There are two type of thermistors NTCs and PTCs. NTCs (Negative Temp. Coefficient) as the name states has a negative temperature coefficient and are most often used for temperature measurement. PTCs usually serve as resetable fuses.
Measuring resistance with a micro controller poses some interesting challenges. Normally one would use a known constant current source and measure the voltage drop on the resistor but something cleverer can be done with resistors. Since the temp-resistance graph for thermistors is roughly exponential and the output voltage-resistor graph of a voltage divider resembles the reciprocal of negative exponential graph, combining them yields something quite surprising. Namely we see a nearly linear temperature – voltage graph. No need for look up tables.
I had trouble finding thermistors that met my strict specs of being able to handle 300C and not costing 10 euros. Finally my friend Jaanus gave me one cheap thermistor that according to the manufacturer only did up to 150C. Some testing revealed that this thermistor could handle temperatures in excess of 250C and when compared to a FLUKE thermometer was only off by a few degrees.
A word on using thermistors in ranges that are out of spec.
First of all in order to use the thermistor effectively a proper selection of the accompanying resistor needs to be made. This is easiest with a reference thermometer. Since the voltage – temperature graph is linear only near the middle it makes the most sense to choose the second resistor to be equal to the resistance of the thermistor in the middle of the temperature range you are interested in.
Secondly since you are now using components that no longer are in spec a recalibration needs to be done. Since we now can presume a linear proportionality we only need to take calibration measurements at the extremes of the temperature range we are interested in. It is also important to note that the smaller the range, the more accurate the reading will be.
Join us next time as we discuss the programming of a simplistic PID controller and microcontrollers in general.
Even though I have been building robots for the past 3 years somehow I have managed to avoid writing any code for them. When confronted with this paradox I usually excused myself by claiming that the need had never arisen. Often I world also continue with explaining that I can totally code in theory and all I really lack is experience. Well, time to find out. How wrong have I been all these years?
Since all our robots currently reside in Japan with Tõnu and thus temporarily unavailable to me I must seek other ways to test my coding knowledge. For some reason embedded programming just seemed to be the way to go.
I decided to start with a PID controller for a reflow oven. Though admittedly it began as something much simpler. About a year ago Tõnu purchased a small sandwich grill he had hoped to convert into a reflow oven. He didn’t really have time for it so the project was handed over to me. I also gave up after struggling with it for a few evenings.
The oven originally employed a some heat switch that opened at a set temperature. Unfortunately the stock oven only reached a max temperature of about 170C – not enough to melt solder. Plainly the switch had to be replaced. Something that could handle mains voltage and currents in excess of 2A was needed. Stubborn as I was ( and still am ) I wanted to use a completely solid state solution so reed switches and relays were out of the question. You know for PWM controll. Right?
First attempts featured large transistors salvaged from old ATX power supplies that were used to replace the heat switch. I destroyed those pretty quick. Turns out 220VAC is more than the base of a conventional transistor can handle. I had also toyed with diode bridges and high DC voltagges but I quickly concluded that route to be too dangerous. By then I had gotten shocked a few times, blown the circuit breaker more than once and lost interest, courage. That grill then spent a fewer months collecting dust in some corner of the lab.
a simple dc to ac driver
Half a year later I encountered some TRIAC-s that seemed to be exactly what I needed. I faired batter – not a single TRIAC was lost. Having solved one I immediately ran into another. Dealing with DC and high voltage AC in the same circuit poses some interesting challenges. Ground for example. You can’t use earth as ground because any control circuitry not isolated from the mains would blow up instantly. Same goes for the live and neutral nodes. Some cheap optocouplers that were specially designed for high voltage ac did the trick. My simple solid state relay was completed.
Stay tuned for part 2 of the saga as we discuss temperature measurement.
Once again some progress has been made on our wheeled robot, namely it now has wheels that are attached to a drive train. Enjoy these photos of the assembly and some footage of the first test runs. It currently has no drive electronics of its own and as such the test runs were made with a remote control that Matis kindly borrowed for this occasion.
I have some concerns about the center of gravity of our robot as I fear it is to far from the ground and could make acceleration and deceleration troublesome. That will be tested when some more permanent circuitry has been attached to the frame.