Reflow oven

It’s been a few months since the last post (or maybe a year), and I figured I better update the blog or whats the point. Anyhow the toaster oven we were using in the kitchen finally took a dump. So I figured what better thing to do than build a solder re-flow oven out of the non working unit. I am pretty psyched about doing more smd type work but I’m not the steadiest person around, so soldering small components with my soldering iron can be a pain. Besides it gives me an excuse to play with a PID controller. As usual I had a few prerequisites for the project. The main one was to try and not buy anything new for the project, at least new to me. I am really trying hard to purge some of the “junk” electronics stuff I seem to collect. That being said I knew I would have to buy a few things, which I think only ended up being a solid state relay that I bought off ebay for under $20. with shipping. A 5volt 120MM computer fan I bought from Amazon for $9. and a ‘K’ type thermocouple I got from Adafruit (http://www.adafruit.com/product/270). I gutted the oven to take a look at how I could layout the project. After that I realized the controller and relay unit would have to be in a separate enclosure. Due to the fact that the oven had zero space to house the controller, and there was no way the relay and heat sink were going in there. Below is a photo of what I came up with. I can’t take all the credit though. The idea for using the computer power supply case as a housing for the relay and controller I got from this brilliant guy (http://andybrown.me.uk/wk/2014/05/11/awreflow/).

DSCN4293

Oven and controller

As you can see I 3d printed a small box to house the actual controller, and LCD board. The controller consists of a TI MSP430G2553 micro-controller, a Maxim Max6675 thermocouple amplifier, a Nokia 5110 LCD and a few discreet components and that’s it. I’m also happy to say that due to TI and Maxim’s awesome samples program I got the chips for frrreeeeee! I had purchased something from the store at 43oh.com in the past and picked up  a smd proto board for the msp430 that forum member RobG had designed. I wanted to not have it sitting around so instead of designing a pcb for the project I went ahead and used the proto board. Looking back, I think I should have just gone ahead and designed the pcb, it would have saved me a lot of time soldering tiny wires, but oh well it’s done. Here are few photos, warning may give nightmares!

reflow top

reflow top

reflow bottom

reflow bottom

There is also a LCD board which stacks on top of the control board.

Nokia 5110 board

Nokia 5110 board gutted from an actual phone!

Here they are stacked.DSCN4280

I needed a couple of buttons to scroll through the menu items for the control. I hacked out a small board for that which has a couple of caps on it for de-bouncing the buttons and also a mosfet for switching the solid state relay. Here is the whole stack fitted into the top half of the 3d printed enclosure.

full stack

full stack

I talked briefly about the computer power supply enclosure which houses the relay. Inside the enclosure the relay sits on an heat sink I got from an old mother board or something, I can’t exactly remember, but with a few extra holes it worked perfectly for the relay. I also needed to somehow get a suitable voltage for the controller, I have 120volts AC coming into the power supply housing and going to the relay but I didn’t want to deal with building a circuit to rectify and drop the voltage so I cheated and broke open an old cell phone charger. That gives me a stable 5 volts that I regulate down to 3.3volts on the controller board. I also chose to add a little extra cooling for the relay by installing a 5volt 120MM fan into the already pre-drilled power supply enclosure. I 3d printed another small box to isolate the cell phone charger from the other components in the power supply enclosure. I like the way it turned out.

old PSU

old PSU

For the PID controller, I used code provided in this document : (http://cms.edn.com/contenteetimes/documents/embedded.com/2000/f-wescot.pdf)  I also did a ton of research via the net. In the end I found I liked the way the author explained the functionality, without getting too technical with theory. It’s not like I’m using this in anything that is too critical, and it will never not be monitored while in use. I’m not going to publish the code here, but it’s up for grabs here: https://github.com/timotet/reflowOven. I’m sure it can be improved upon. Now I will give a brief run down on how the code runs. When powered on the the Reflow Time! screen is shown. There are 2 items you can select from this screen, reflow and adjust PID. You select by using the bottom button and scroll by using the top button.

1st screen

1st screen

If Adjust PID is selected, at the next screen you can make adjustments to the PID terms.

It look’s like this: DSCN4371

You can scroll with the top button and select with the bottom button, once you select one of the PID terms you can change the value by using the top button to increase the value and the bottom button to decrease the value, a long press of greater than 2 seconds on the bottom button saves the current value and lets you either select another PID term for adjustment or select the exit menu item.

If you select Reflow you get a screen with options for either a RHOS profile or a leaded solder profile.

DSCN4372

 

 

 

 

 

Once you choose your desired profile the controller tells you either RHOS profile loaded or LEAD profile loaded.

DSCN4373

 

 

 

 

 

 

After that its on to the fun!

DSCN4377

RHOS profile

DSCN4374

LEAD profile

Once one of these screens is displayed the oven is on and running. As you can see the screen is displaying the time passed in seconds, the set temperature and the current temperature. Also some debug info in the top right corner that I didn’t feel like removing. It shows the value of the error offset in the PID calculation, if I remember correctly. It’s kinda neat to see it at a high value when the oven is heating up and then watch the value decrease as the set temp is reached. Unfortunately I ran into some RAM limitations with the MSP430G2553 chip and I could not do a complete lcd refresh as the time and temp changed. So instead of re-writing the whole screen every second or so I just drew the reflow profile once then updated the second count and the temperature, I also wrote one pixel to the screen that corresponded to the time and temperature as the process ticked away. So in the end it would have looked better to be able to refresh the whole screen with the profile curve re-drawn along with the current curve being plotted over it, but alas, this works too and the current profile gets plotted over the original profile, just not as cleanly. So if at any time while the profile is running the bottom button can be pressed and the process will be aborted. Of course it has a screen too!                                  DSCN4380

And there’s a reflow completed screen as well, but for some reason I didn’t take a picture of it oh well!

Now on to weather it works or not? Well it does and surprisingly well at that. So all in all I’m pretty psyched.

 

 

Here’s a couple of photos of some boards I re-flowed! woot woot!:)

DSCN4303

DIY TMP100 temp sensor break out.

20151004_160853

A light for my mom’s sewing machine. I know a bit over kill!

Over all I’d say it works.

 

Posted in Electronics, Hacks, hunh? | Tagged , , | Leave a comment

Nature!!

I didn’t mention it in my Bio, but I am an avid rock climber. I spend a lot of time out at Smith Rock state park in Oregon. I really enjoy being out with my family at the park. I was hiking out at sunset on Jan 21st and got this shot of the sunset. Nature, pretty cool!DSCN4221

Posted in hunh? | Leave a comment

I’ve been printing!

I have been having some fun with my printer and thought I’d show off some of the prints.

I saw this little robot on the Adafruit site about a year ago and thought it would be a fun project to do with my daughters. Here is the link: https://learn.adafruit.com/trinket-powered-rover. Well it turns out that the project was a little more involved than they wanted to invest their time in so I went ahead and finished it myself. A couple of things I did differently were, I didn’t have a Adafruit Trinket(http://www.adafruit.com/products/2000), but I did have a ATiny 85. I also just hardwired it to perfboard instead of using a mini breadboard. And last but not least I printed a battery tray to sit on the back of the robot. I bought the ultrasonic sensor off e-bay for 5 bucks, and used the link in the tutorial to buy the tank tread/ bracelets. I did however get the servos from Adafruit and hacked them to be full rotation. This was a fun project and in the end I got the “Yea that’s cool dad” from the girls. Here are a couple shots of it.

DSCN4141 DSCN4144 DSCN4145

The other fun thing I’ve printed was an enclosure for a clock kit I built . I bought the kit from a long time 43oh forum member RobG(https://www.tindie.com/products/RobG/msp430-nixie-clock-kit/). The kit was a breeze to assemble, all through hole components and I think designed very well. RobG offers a basic enclosure for a low cost but its kind of generic considering how cool the clock looks. To run the Nixie tubes it has 190 volts on the pcb. Being that I have daughters, and even thought they are 9 and 11, I didn’t want any wandering fingers to get zapped. That applies to everyone nobody wants to get shocked. So it gave me a good excuse to design and print an enclosure for the clock. This is what I came up with. I uploaded a .zip file to the 43oh site with the .stl files if anyone is interested in giving it a shot on their printer. (http://forum.43oh.com/topic/5915-msp430-nixie-clock/page-3#entry54347) Here are a few shots of it. I added the colon between the 2 middle digits, why? Because I could!

clock1 clock2 clock3 clock4 clock5

Posted in 3d printing | Leave a comment

Audio Book

My wife has a friend whom she wanted to build a small amplifier for. This amp was to be used around the house at times when the main stereo was either in another room or not available. As we were brainstorming on what to use for an enclosure for the amp. The idea of putting it into an old book came up, partly because her friend loves old books and it’s cool. This is the finished project, we used an Adafruit 3.7 watt amplifier breakout (http://www.adafruit.com/product/987), some old speakers we had in the junk bin, a spare 5v cell phone charger, I designed and 3D printed a couple of parts, hot glue and of course an old book. Her friend loved it, and it was fun to make.

Here are some photos.

3d printed insert

3d printed insert

Speaker Hinge

Speaker Hinge

Power Block

Power Block

Back Side

Back Side

Electronics

Electronics

Finished!

Finished!

Posted in 3d printing, Electronics, hunh? | Tagged , , | Leave a comment

ringLight P2!

DSCN3595

I finally got around to finishing the ringLight up this weekend. It seems like when you want to get something done quick it takes twice as long as it should. (edit: a month ago… see what I mean.) Well that and you need to actually work on it. That being said I’m gonna call this a finished project. I left the programming header on there so I could always update the software running on the MSP430 if I feel so inclined.

As far as the code goes I think its pretty simple. I have to thank Kevin Timmerman or oPossum as he’s known on the web for the LED driver code. I also have to thank my friend Larry Fogg for getting psyched to write some code as well. All the code does once power is supplied is check to see what color or animations were running last, then if the button is pressed cycle through multiple colors and a couple of animations depending on how many presses are happening. One nice feature is that once the state has changed the processor writes the current state to the flash memory for next time. That way the last state is remembered when the printer is turned on again. It also only writes to the leds the one time, that way the MSp430 doesn’t resend the led info over and over. At that point, I could put the processor in low power mode but since it is powered by the printer power supply there is no real need.

Here’s the code if anyone is interested:

//  5/10/14
// For controlling the Mandelbots ringLight WS2812 leds
// Thanks to Kevin Timmerman for the ws2811_hs.asm led driver code
// Written by Larry Fogg and Tim Toliver
//

#include "stdint.h"
#include "stdlib.h"
#include <msp430g2452.h>

void write_ws2811_hs(uint8_t *data, unsigned length, uint8_t pinmask); //prototype for ws2811_hs.asm

#define button BIT3
#define ledPin BIT7
#define numColors 1972

static const uint8_t red[12] = { 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00 };
static const uint8_t green[12] = { 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00 };
static const uint8_t blue[12] = { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF };
static const uint8_t purple[12] = { 0, 128, 128, 0, 128, 128, 0, 128, 128, 0,
128, 128 };
static const uint8_t yellow[12] = { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
0xFF, 0x00, 0xFF, 0xFF, 0x00 };
static const uint8_t orange[12] = { 0x80, 0xFF, 0x00, 0x80, 0xFF, 0x00, 0x80,
0xFF, 0x00, 0x80, 0xFF, 0x00 };
static const uint8_t steelBlue[12] = { 130, 70, 180, 130, 70, 180, 130, 70, 180,
130, 70, 180 };
static const uint8_t pink[12] = { 20, 255, 147, 20, 255, 147, 20, 255, 147, 20,
255, 147 };
static const uint8_t aqua[12] = { 255, 0, 255, 255, 0, 255, 255, 0, 255, 255, 0,
255 };

static uint8_t z[12]; //GRB values for 4 LEDs
uint8_t pressCount;   //keep track of button presses
uint8_t buttonPressed = 1; //start with true so stored pressCount is executed

//for writing flash
uint8_t * Flash_ptr = (unsigned char *) 0x1040; //location to write in flash info segment C

void millisecDelay(int delay) {
int i;

for (i = 0; i < delay; i++)
_delay_cycles(10000); //roughly 1 msec. calibrate this
}

#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void) {
_disable_interrupts();
pressCount++;                    //increment button presses
buttonPressed = 1;                //true
millisecDelay(300);                 //for button debounce
P1IFG &= ~button;                //clear interrupt flag
_enable_interrupts();
}

void writeFlash(unsigned char data) {
_disable_interrupts();
FCTL1 = FWKEY + ERASE;                    //Set Erase bit
FCTL3 = FWKEY;                            //Clear Lock bit

*Flash_ptr = 0;                         //Dummy write to erase Flash segment

FCTL1 = FWKEY + WRT;                      //Set WRT bit for write operation

*Flash_ptr = data;                        //Write value to flash

FCTL1 = FWKEY;                            //Clear WRT bit
FCTL3 = FWKEY + LOCK;                     //Set LOCK bit
_enable_interrupts();
}

void loadLED(int ledNum, uint8_t R, uint8_t G, uint8_t B) //load z[] for one LED
{
z[ledNum * 3] = G;
z[ledNum * 3 + 1] = R;
z[ledNum * 3 + 2] = B;
}

void writeLEDs() {
_disable_interrupts();
write_ws2811_hs(z, sizeof(z), ledPin);
_enable_interrupts();
}

void getRGB(int color, uint8_t *R, uint8_t *G, uint8_t *B) //this generates RGB values for 1972 rainbow colors from red to violet and back to red
{
float brightness = 0.3; //scale factor to dim LEDs. if they are too bright, color washes out

if (color >= (numColors / 2)) //adjust color for return from violet to red
color = numColors - color;
if (color < 199) {
*R = 255;
*G = 56 + color;
*B = 57;
} else if (color < 396) {
*R = 254 - (color - 199);
*G = 255;
*B = 57;
} else if (color < 592) {
*R = 57;
*G = 255;
*B = 58 + (color - 396);
} else if (color < 789) {
*R = 57;
*G = 254 - (color - 592);
*B = 255;
} else {
*R = 58 + (color - 789);
*G = 57;
*B = 255;
}
*R *= brightness; //apply brightness modification
*G *= brightness;
*B *= brightness;
}

void allWhite(uint8_t intensity) //all LEDs stay white
{
int i;

for (i = 0; i < 12; i++)
z[i] = intensity;
writeLEDs();
}

void allBlack() //all LEDs off (black)
{
int i;

for (i = 0; i < 12; i++)
z[i] = 0x00;
writeLEDs();
}

void lightning() {
uint8_t R, G, B;
int color; //numeric index into color palette
int flashDuration;

while (!buttonPressed) {
allBlack(); //clear LEDs
color = rand() % numColors;
if (color % 7 == 0) //every so often, throw in a bright white flash
{
R = G = B = 0xff;
flashDuration = 10; //quicker for white flash
} else {
getRGB(color, &R, &G, &B); //get random color
flashDuration = 50; //slower for color flash. makes color more apparent
}
loadLED(rand() % 4, R, G, B); //load color into random LED
writeLEDs(); //flash the LED
millisecDelay(flashDuration);
allBlack(); //clear LEDs
millisecDelay(rand() % 500); //wait for next flash
}
}

void drawSnake(int headLoc) //draw snake starting at headLoc
{
int shoulderLoc, torsoLoc, tailLoc;
uint8_t R, G, B; //color of head

getRGB(rand() % numColors, &R, &G, &B);
shoulderLoc = (headLoc + 1) % 4; //find correct array locations for body parts. keep within 0-3 range
torsoLoc = (headLoc + 2) % 4;
tailLoc = (headLoc + 3) % 4;
loadLED(headLoc, R, G, B); //random color head
loadLED(shoulderLoc, 0, 0, 0);
loadLED(torsoLoc, 0, 0, 0);
loadLED(tailLoc, 0, 0, 0); //black tail
writeLEDs(); //draw the snake
}

void chaseSnakeTail() //white head, black tail. Snake goes in circles
{
int headLocation = 0; //which LED is the head (white)
int crawlSpeed; //delay between snake moves
int slowSpeed = 150;
int fastSpeed = 10;
int CWdirection = 1; //start with clockwise direction = true

while (!buttonPressed) {
for (crawlSpeed = slowSpeed; crawlSpeed > fastSpeed; crawlSpeed -= 2) //speed up tail chasing
{
drawSnake(headLocation);
millisecDelay(crawlSpeed);
if (CWdirection)
headLocation += 3;
else
headLocation++;
headLocation %= 4; //keep LED in range (0-3)
if (buttonPressed)
break;
}

CWdirection = !CWdirection; //reverse direction for next cycle

for (crawlSpeed = fastSpeed; crawlSpeed < slowSpeed; crawlSpeed += 2) //slow down tail chasing
{
drawSnake(headLocation);
millisecDelay(crawlSpeed);
if (CWdirection)
headLocation += 3;
else
headLocation++;
headLocation %= 4; //keep LED in range (0-3)
if (buttonPressed)
break;
}
}
}

void allColors() //display rainbow color progression, each LED out of phase with the others
{
uint8_t R, G, B;
int color;
int ledNum; //0-3

while (!buttonPressed)
for (color = 0; color < numColors; color++) //progress from red to violet and back to red
{
for (ledNum = 0; ledNum < 4; ledNum++) {
getRGB((color + ledNum * 200) % numColors, &R, &G, &B); //offset LED colors by 200 from neighbors
loadLED(ledNum, R, G, B);
}
writeLEDs();
millisecDelay(4);
if (buttonPressed) //allow exit from function
break;
}
}

void writeLeds(const uint8_t color[12]) {

unsigned j;
for (j = 0; j < 12; j++) {
z[j] = color[j];
write_ws2811_hs(z, sizeof(z), ledPin);
}

}
void main(void) {
WDTCTL = WDTPW + WDTHOLD;            // No watchdog reset

DCOCTL = 0;
BCSCTL1 = CALBC1_12MHZ; // Run at 12 MHz
DCOCTL = CALDCO_12MHZ;

//P1SEL &= ~ledPin | button;
P1DIR |= ledPin;   // ledPin is an output
P1OUT = 0;         // set port 1 low

P1DIR &= ~button;  // button is an input
P1REN |= button;   // pull down on button
P1OUT &= ~button;  // set pull down
P1IES &= ~button; // Interrupt Edge Select - 0: trigger on rising edge, 1: trigger on falling edge
P1IFG &= ~button;  // interrupt flag for p1.3 is off
P1IE |= button;    // enable interrupt

FCTL2 = FWKEY + FSSEL_1 + FN3; // MCLK/32 for Flash Timing Generator 12mhz/32 = 375hz  // these both work has to be between 257-476 hz
//FCTL2 = FWKEY + FSSEL_1 + 0x1A;             // MCLK/27 for Flash Timing Generator 12mhz/27 = 444hz

pressCount = *Flash_ptr; // load value written in flash

_enable_interrupts();

while (1) {
if (buttonPressed) {
buttonPressed = 0; //reset

switch (pressCount) {
case 0: //bright white
allWhite(0x80);
break;
case 1: //dim white
allWhite(0x40);
break;
case 2:
lightning();
break;
case 3:
allColors();
break;
case 4:
chaseSnakeTail();
break;
case 5:
writeLeds(red);
break;
case 6:
writeLeds(blue);
break;
case 7:
writeLeds(green);
break;
case 8:
writeLeds(purple);
break;
case 9:
writeLeds(yellow);
break;
case 10:
writeLeds(orange);
break;
case 11:
writeLeds(steelBlue);
break;
case 12:
writeLeds(pink);
break;
case 13:
writeLeds(aqua);
break;
default:
pressCount = 0; //default to 0
buttonPressed = 1; //force execution of case 0
break;
}
writeFlash(pressCount);  // write to flash for poweroff
}
}
}

One problem I have with my design is the LDO I chose for the 5v power supply to the leds.  The part I chose is the TI LP2989. I used this part due to the fact that it could handle up to 500mA, I could use my existing 12v power supply from my printer and it seemed pretty easy to implement in my design. It wasn’t a complete fail as can be seen by the working light but if I try to get any more than 200mA out of the LDO that sucker gets HOT! I figured the WS2812 leds at full brightness should pull around 240mA. The data sheet for theLP2989 states guaranteed 500mA continuous output current. I used the schematic right off the data sheet for the layout on my board and used the correct capacitors as per the data sheet. I’m still doing something wrong though. Here is a schematic comparison . The problem could be in the ERROR output , the data sheet says see app hints , but in the app hints it never gets discussed. Nice one TI!

Lp2989

 

LP2989MI was going to post my build on the 43oh forum and ask for help in figuring out why theLDO is not working correctly maybe somebody over there has some insight. I also thought about posting on TI’s E2E forum as well. It works but there is still that unanswered question?

 

That pretty much wraps this post. Here’s a couple shots of it installed on the machine.

DSCN3601

DSCN3604

a small video:

 

Posted in 3d printing, CNC, Electronics | Tagged , , , | Leave a comment

OLS 3d Printed case

Here is a quick post to show off a case, well it’s not really a case but a sort of case. Since there is no full top covering I don’t think it could be called a full case anyhow here it is:

DSCN3519

I was always worried about it shorting out on some random piece of solder or steel on my bench, not any more! Here’s the bottom:

DSCN3520

 

 

Posted in 3d printing, CNC, Electronics, hunh? | Tagged , | Leave a comment

ringLight for the Mandelbot

Last August I finished assembling a 3d printer that I had in the works for over a year. The printer from now on will be referred to as The Mandelbot! I will blog on the topic of said printer in the future. As for today’s post the Mandelbot needed a light to illuminate the build area. I looked around on the web for some kind of pre-built solution, but I had some criteria that had to be met. I wanted it to fit in a certain location on the  machine so that quickly narrowed down the options I had. I definitely wanted it to be rgb led, I mean its got to change colors. I thought using one of the neo pixel rings Adafruit sells might do nicely but due to size constraints no dice! So I figured it was a good excuse for me to have some pcb’s made up. I tend to always machine, or etch my own pcb’s. I do this because it’s fun and I want it now, or in the time it takes me to make it. But this one was special. I wanted the end product to be awesome, easier to solder (smd stuff), and look great. Even though once its on the machine you really wont be able to see it unless you look up from underneath.

I had some ideas for how I wanted the light to work with the printer. I thought it would be great if I could control the light via the printer interface with mcode’s. The downfall there is I would have to change the firmware to recognize those codes, which would be fine except that the firmware is still being upgraded all the time, and I’ve been keeping up with the latest build. I use a Smoothieboard for the Gcode interpreter on the Mandelbot, and I am pretty sure the developers of Smoothie are not going to want to include some code for a machine no one else has. So that means the light has to have some sort of controller IC. In comes the MSP430. Since I was going to have rgb leds on the board I decided to go with the WS2812 rgb led. To control the leds I am using a MSP430G2452. There are a couple of voltage regulators on there to handle the power needs, because I am running this off the 12v 15amp supply for the machine, one is a TI LP2989 5v 500ma LDO for the leds, and the other is a TPS70936 3.6v 150ma LDO for the MSp430. There’s also a button for cycling through the colors. I’ve been curious about these leds for awhile so I figured this was as good of an excuse as any to mess with them.

Here’s the schematic:

ringLight

ringLight schematic

After I checked, re-checked, and triple checked, I sent it in to OSH Park. I know I could have more made for cheaper if I would have used any one of a number of off shore manufacturers but I only needed 2 and the OSH park boards looked great. I have to say the OSH Park web site is painless to use and the quality is great!

Here is what I ended up with:

Awesome!

Now to get busy.

Here’s the power rail all soldered up and working, well the led is.

DSCN3488

It works!

A little while later and a couple of sacrificed leds.DSCN3537

I am definitely happy with the way they turned out. Now to dial in the code and mount it on the machine. I will post when I get that done.

Posted in CNC, Electronics | Tagged , | Leave a comment