Showing posts with label AVR. Show all posts
Showing posts with label AVR. Show all posts

Monday, February 3, 2014

Reflow oven

I started a new project recently, a reflow oven. This time, I've started with the physical build, and the software side of it will lag behind. I've laser cut the case I designed in OpenSCAD, and I couldn't be more pleased with the results.

The case with the "human interface" components - a touch screen LCD a 1 watt speaker.

I have some projects in R&D for Anibit, and I'm going to need to whip up some PCB's. I need a reflow oven, and I'm going to recycle an old toaster-over. I was inspired by this project, which was in turn based on osPID. The touch-screen was something I've had lying around, waiting for a project. 

Sunday, December 22, 2013

Traffic Light

[Editor's note. This is a post that I started almost 3 years ago, I'm making an effort to purge or polish some of the unfinished or unworthy posts on Bytecruft]

This is a traffic light I made for my kids. It's got a ATtiny 13 driving the leds. It also features a "soft" on-off circuit   driven by a tactile momentary push button.

I know, another AVR LED based project. They're so easy. I swear, I work on more than LEDS and with chips other than AVR's. It's just that the AVR ones tend to get 100% finished. Part of my hopes for this blog is to provide motivation to finish a couple of the unfinished projects I have. Actually, looking back, it's not so much a problem of motivation, but time. I usually "multithread" my projects, work on several at once, to keep form getting burned out or over-obsessed with one. Sometimes, before I know it, a project hasn't been touched in a couple months.

This is a project I did for my kids, it was another one of those "in between" projects, where my goal was to make a small project that would be lightweight after working on something big.

Present-day action shot, I finally replaced the 3+ year old batteries
during the teardown/photo shoot for this.

The real neat trick with this project, in my opinion, was the power management.

Wednesday, September 4, 2013

Really short sanity check list for vexing AVR anomalies.

I've been chasing down some bizarre behavior on an Atmega 1284 for the better part of a week.

I'm posting this so that I can print it out and tape it to my forehead for future reference.

When trying to determine the root cause of strange behavior in your code, you have to sometimes use a process of elimination. Sometimes, it's best to check the easiest possibilities first, regardless of how likely you may think any given cause is. My code was behaving in pseudo consistent ways, something would fail, repeatedly. I would add code to try and catch the error before thing went haywire. I was convinced I had a memory overwrite, or a stack overflow. As soon as I would add the code to catch a problem. It would start working, or stepping though the code would give a different result than running full speed.

Here is a list of things to check while your scratching your head: (In this order)


  1. Fuses. (This turned out to be my problem). I had my fuses set for an external RC oscillator, instead of a crystal. Fuses are so easy to check, it should be the first thing you do. Scrutinize each setting, read the datasheet for each one.
  2. Proper capacitors on the external crystal.
  3. Breadboard noise. I rebuilt my breadboard, it started working better, but not perfect, so I'd assumed it was noise and a memory clobber causing the issues.
  4. Proper JTAG connection. (JTAG seems more sensitive to noise than SPI/debug wire debugging). To eliminate this as a possible cause, program the flash with the "device programming tool" in AVR Studio, using the generate hex file, and use the verify feature. Write some diagnostic code to print to a serial port, then disconnect the JTAG. If your problems go away, it may have been the tool.
  5. Memory stomp. These are pretty common, and can be hard to pinpoint, in pointer arithmetic-heavy code. Stack overflows are particularly nasty and difficult to detect, set breakpoints at your "deepest" code paths, and look at the SP register in the debugger. Comment/stub out large local variables, and eliminate recursion.
  6. Compiler bugs

The last one is actually pretty rare, but it does happen. Odds are you will have found the problem before oyu get to that stage.

--P

Wednesday, March 13, 2013

Seeding the standard C random number generator on AVR chips.

The rand() function in C gives your a pseudo-random number generator. To purists, it's got a lot of flaws, but I'm glossing over that for this post. In many cases, it is "good enough" to get the job done. A lot of times, I don't care that the distribution is not strictly even when you do something like.

int foo = rand() % 10;

Many times, just a rough approximation like above is enough to make something "feel random".

The rand() function uses a formula that calculates new "random" numbers based on a formula that includes the previously generated value(s).

So where do you get the "starting point" for the first number in the formula?

The standard C library maintains an internal state for the random number generator, and you can "seed" this state with the "srand(unsigned int)" function.

So what do you pass to it?

Well for any given "seed", you will generate the same sequence of pseudo-random numbers. For instance:

srand(42);
int a = rand() % 10;
int b = rand() % 10;
int c = rand() % 10;

will yield the same sequence for a,b, and c every time it is run. What if that is undesirable? It's almost like you need a random number to seed the random number generator, a "catch 22".

On desktops, seed values are often taken from some system time register, on Linux systems, it's sometimes generated from a timer that measures the time between a user typing keys.

On microcontrollers, you often don't have inputs, and system up-time timers don't work because the time will likely have the same value in the power up initialization sequence.

It can be difficult to get these miracle computing machines to be non-deterministic when you want them to.

A trick you may be able to use, depending on your setup is to use the ADC (analog digital convert) built in to most AVR's (on other brand) micros to read a voltage level on a pin that is "floating" or otherwise not tied well to a particular voltage. Here's a short example of how that looks on an AtTiny85:

#include <avr/io.h>
#include <stdlib.h>


void setup_seed()
{
unsigned char oldADMUX = ADMUX;
ADMUX |=  _BV(MUX0); //choose ADC1 on PB2
ADCSRA |= _BV(ADPS2) |_BV(ADPS1) |_BV(ADPS0); //set prescaler to max value, 128

ADCSRA |= _BV(ADEN); //enable the ADC
ADCSRA |= _BV(ADSC);//start conversion

while (ADCSRA & _BV(ADSC)); //wait until the hardware clears the flag. Note semicolon!

unsigned char byte1 = ADCL;

ADCSRA |= _BV(ADSC);//start conversion

while (ADCSRA & _BV(ADSC)); //wait again note semicolon!

unsigned char byte2 = ADCL;

unsigned int seed = byte1 << 8 | byte2;

srand(seed);

ADCSRA &= ~_BV(ADEN); //disable ADC

ADMUX = oldADMUX;
}

In my case, PB2 was connected to a resistor, which was then connected through an LED to ground. When the pin is in a "high z" state (eg, not driven by the CPU), this approximates "floating" close enough to give me nice erratic values. Notice that I use the "low bits" of the ADC. The low bits represent smaller voltage differences, and exhibit greater variance, so they're more likly to swing a lot on a floating pin.

I'm not sure if it was really needed to scale the IO clock down by 128x, I just added it for flourish, thinking more time would mean more variance. I have no scientific evidence that is true though.

Enjoy!

--P

Thursday, January 31, 2013

CNC update

I hit a milestone with my CNC project tonight, I made my first cut!

Here's the current state of it configured for milling:



I'm using the Zen Toolworks 12x12 , F8 edition. The F8 edition has an extended Z-axis travel on the gantry, which is needed to be able to use the device for 3D printing. One thing I didn't realize initially were that: 1) configured as a milling machine, the spindle will not reach down to the bed, and 2) the extra Z axis travel does not benefit milling as much, because the gantry clearance is one of the limiting factors. The two possible approaches to address the first issues are to either re-work(ie invent your own) the spindle mount to lower it close to the bed, or to build an elevated platform as your new work area. I decided to do that because it reportedly reduces error due to frame torsional forces. I could always build a new mount and remove the table. The Zen is pretty flexible in that way, a good deal of the design can be up to you.

Tuesday, January 15, 2013

CNC progress pic.

Just a quick shot of my cnc build in progress, I'll post more about it later. I had a slow start waiting for all the parts, I think I'll avoid ordering big stuff around Christmas next year.
Tonight I'm working on end stops and the y-axis of thr Zen Toolworks chassis.

Thursday, January 3, 2013

New Project - CNC/3D printing

While physical computing has captured my fancy the past few years, one thing that seems to have frustrated me is the physical construction for my projects. I have a degree in Mechanical Engineering, though I went into Software Engineering professionally, so that struck me as odd. I think I've grown accustomed, spoiled even, on the fantastic availability of free and low cost tools available in the software world. I'm used to having as powerful tools to develop software as a hobby as the professionals use. Not so with hardware. Things are getting better though.

I've decided to take it to the next level, and I'm investing in a small CNC that will also be capable of 3D printing. I'll document my progress on ByteCruft. (My robot project is not stalled, but I'm putting the CNC project first, since there's a long lead time with getting up to speed.) I currently know very little about milling beyond what I remember from school almost 20 years ago. I expect my progress to go faster than my typical  'epic' level project, since I'm focusing less on trying to do lot of design myself. I'm mostly cherry picking various kits and packages and making them work together.

Monday, August 20, 2012

Seeeduino Stalker Waterproof Solar kit review PART 2

In my last post, I covered the Seeeduino Stalker board itself, I wanted to get into some of the other aspects of the kit.

The hardware (continued)

Monday, August 13, 2012

Bench Power Supply

I decided to mothball my power supply project. I may come back to it one day, I may not. I sort of had a rage-quit moment this week-end, when I blew one of the channel's regulator circuits. The thing is, I didn't do anything I didn't think it could handle. Now, the voltage output is always 2 volts higher than what I set it for, and the current-limiting seems to never kick in, it goes to 1 full amp (or at least that's the max I'm capable of measuring) when I short it. Meh. I thought it was more robust than it appeared to be, and I didn't want to spend more time to complete it, only to run into more issues. It needs some re-design.


The Bench Power Supply (Powerbug 6000), in its
open casket, the mothballs are in my head.... and my heart.

So as a wrap up, I'm just going to post some pictures I (and my wife, player with an in-law's camera) took of the project.

Wednesday, August 8, 2012

Seeeduino Stalker Waterproof Solar kit review

I had a little extra scratch recently, so I decided to geek out on some new toys without  a specific purpose in mind. One of the nuggets I picked up was the Seeeduino Stalker waterproof solar kit. From Seeed Studios in Shenzhen, China.



At the time of writing the kits go for $59.50 US, which, as you'll see in minute, is a pretty good deal, for what you get. I live in North Carolina, and the free shipping via Hong Kong post/registered airmail took about two weeks, give or take a day or two. As an aside, it boggles my mind that I can get something shipped out of Shenzhen *for free*, (my package was several pounds too), and I order something that ships out of a neighboring state and get socked with a $10 shipping fee.

I'm going to take a stab at doing a proper review for the kit, maybe it will inspire me to figure out what to actually do with the thing.

Tuesday, July 17, 2012

Slowly I turned...

It's been a slow summer. I'm still making progress on the bench power supply. It's in the "just get it done so I can move on" phase.

I've got the regulator part of the circuit finalized. I don't think it's perfect, but I think if I ever want to work on something else, I need to move ahead. Since the powersupply has three channels, I plan to have 3 discrete boards.

Here is one of the boards, pre-soldering:
One channel regulator board.
On the left side of the board, there are two PWM'ed input for the voltage and current settings, and two "Vsense" and "Isense" analog outputs that will run directly to ADC inputs on the Atmega 644. The top of the board will have inputs from the ATX power supply at 12 and 5 volts. A variable 0-9V output will come form the bottom-right side.


Wednesday, May 30, 2012

Bench Power Supply - Progress Update

Here's a little video I shot of my power supply in action. I think it is very close to being workable. I have a bunch of placeholder parts, since I'm holding off on placing an order for final parts until I do more testing.

One thing I've been working on recently is the current-limit-mode indicator LED's. It's a little but harder of a problem than I thought it would be. My current limit comes from Q1 in the schematic. As the current flowing through R1 rises, it causes the voltage on the "+" input of the U2 op-amp to eventually exceed the ISET voltage. This drives U2's output high which in effect ties U4's output close to ground. My idea was to connect the "+" side of U4 to a spare input on my IO expander, and sample it's value in code. My initial thoughts were that a low value indicates that the circuit is in "current limit" mode. It turns out there are numerous reasons that this wont work. The face palm moment was realizing a low VSET value will also trigger the current limit logic regardless of the actual current! The other major problem was that I was using a digital input to estimate what is really an analog voltage.

Anyways here's the video:

Friday, May 18, 2012

Bench Power Supply - Point of no return

Just  a quick(not really) update.

I've got a lot of the code side of things worked out. I had a lot of "fun" doing software debouncing for my rotary encoders. After hooking up a logic analyzer, I realized that using the I2C IO expander for the encoders was not going to work. The I2C chip I'm using, an MCP23018, has a couple interrupt lines, one of which I used to alert my ATmega that the expander needed attention. Since the expander is an I2C "slave", this is the only way it can initiate communication with the microcontroller. An interrupt handler in my code would set a flag and exit. When my "main update loop" got around to checking that flag it would then issue a series of I2C commands to query the expander for the encoder line change that triggered the original interrupt. All of this turned out to be way too slow to process encoder input. The main culprit was the fact that it depended on the main code loop getting around to checking that flag. From my logic captures, I could see that encoder edge transitions could happen sometimes 5ms apart. When there was a lot going on, such as heavy LCD updates, my main loop could sometimes take 20-30ms to complete one loop. Ouch.

You can't easily, if at all do I2C in an interrupt handler, you can not be sure of what state the I2C line is in when the interrupt fires. In the end, rather than figuring out a way to do I2C in an interrupt, or doing more flag checking (which would have been a hack, sometimes most of the CPU time is spent deep in the LCD bit bang code), the simpler solution was to move the encoders to the AVR itself. I had to give up UART functionality that I was planning, since I'm tight on allocated pins, but I was leaning toward doign that anyways.

Friday, May 4, 2012

Bench Power Supply: Power Control

In this truly awful video, you can see my bench power supply at work.

For testing, I coded a function to cycle the voltage between 0-5.0V.  In reality, 0-100% duty cycle is the parameter the code changes. A "PWM'ed"  square wave(yellow trace) is fed to an RC filter, which is then buffered with an op-amp(the op amp output is the blue trace).

You can also see the LCD updating in realtime. The voltage reading is coming from the ADC on the ATmega 644. It's has a hard time keeping up with the displayed "SET" value, but there probably several factors, the biggest of which purely software related, I simply don't refresh the "widget" that displays the voltage reading any faster than 3Hz. 
(Ignore the Amperage settings/reading, they're not coded yet, the analog portions of that have me the most intimidated)




Anyways, crappy quality aside, this is a great demonstration of how PWM signals can be used to generate analog voltages from a digital MCU pin, and how "duty cycle" affects what comes out of a simple low-pass RC filter.


--P



Monday, April 30, 2012

Bench PSU: AVR JTag update #4 (I think I can stick a fork in it now)

I've slowly but surely made progress on my bench power supply. I think my JTAG issues are a thing of the past. I've done a couple things to ensure reliable communications, and I've now got the AVR Dragon running at 2 MHz with 0 errors so far. First, I put the 20pf capacitor on the JTAG clock line, at the breadboard side. I know I derided the lowly 20pf cap in the past as a pawn of the Capacitor Cartels, but I'm eating crow now.

The second thing I did was to create a JTAG "Bread Head", so named in and inspired from this post on Blondihacks: Bread Head. I'm not a great photographer, and macro shots seem to be even harder, but here it goes:


My Atmel 644 (and pin compatible DIP 40s) JTAG
Breadboard adapter. I could probably trim a little more
perfboard off the top.

Tuesday, April 24, 2012

Bench PSU: AVR JTag update #3

In my last post, I reported that I got my AVR Dragon to work in a 5V circuit by creating what I called a "shielded JTAG cable":


I speculated that "cross talk" interference might have been causing my un-reliable JTAG when running my circuit at 5V. (It worked fine at 3.3V, but some components in my final circuit are 5V parts, I also noticed that many 20 Mhz AVRs are only rated to run at a full 20Mhz above about 4.5V)

I got my DSO Quad hobbyist class digital scope last week, and I was all set to write up a really scientific post documenting my construction and testing of a shielded AVR cable, then something strange happened. I switched to another 2x5 "unshielded" JTAG cable to reproduce my original problem. When I hooked up my DSO to the JTAG clock line, the programming functionality worked flawlessly at 5 Volts! Curse you, Heisenberg! (Yes, I know that this is not really the meaning of the Uncertainty Principle, but any time I run across a case where the act of measuring something alters the quantity I'm trying to measure, I think it it).

Wednesday, April 18, 2012

Bench PSU: AVR JTag update #2 (it's alive!)

I think I figured out the noise issue on my ATmega setup.

After I posted my ATDH1150 teardown yesterday, I got to thinking about the "JTAG-X" port on the device:


It's a 2x7 JTAG port that looks to be wired to the same lines as the 2x5 "JTAG-A", except that one of the two rows is almost, if not all, connected to GND. I'd seen this done other ribbon cable type connections, but I never really thought much about why this was done. The effect of it is to make every other wire in the ribbon a GND line. I'm probably butchering terminology here, but I think this is a form of shielding. It helps to reduce electromagnetic interference, or cross-talk(is that the right term?) between the signal lines.

My experiments so far with my AVR Dragon-breadboard setup lead me to strongly suspect that noise was the culprit, and contrary to my initial intuition, many types of noise can become more of  problem with higher voltages.

Tuesday, April 17, 2012

Bench PSU: AVR JTag update

I did some more experimenting with my AVR Dragon JTAG woes today, despite not really having the time (I was supposed to file my taxes, but thanks to the District of Columbia, I get one more day. Why put off until tomorrow what you could easily do the day after tomorrow?

To summarize my last post:

ATmega 644 in a breadboard, JTAG functionality only seems to work reliably when powered at 3.3V vs 5V.

I was a little distraught that I had to spend time with dumb issues like this, and not on to cooler stuff. In building this power supply though, I'm sure that I'm going to face a lot of noise issues. I felt dumb.

Well, I'm an Engineer, and what do Engineers do when they feel dumb? They get empirical. Hypothesize, Measure, Test, Rinse, Repeat. Through process of elimination, I knew I could come up with a list of things that were not the cause of my problems. I made a list of random notes as I tried various things that might show a different behavior.

Monday, April 16, 2012

AVR JTAG programming oddities

I recently launched a new project, I'm working on a bench power supply. I've wanted to do the "old ATX PC PSU to bench power supply" thing for a while, and there was a recent series on the EEVBLOG whose design I'm taking a lot of inspiration from. (That David Jones is a freakin' genius). I want to have a little more "kapow" than his design, 0-9 V, 3 channels. I don't know if that's a folly on my part, but time will tell.

I finished up the "thinking a lot about it" phase, where I watch TV and daydream about what I want to do, and I moved into the prototype/experiment/pre-design phase.

I'm going to use an ATmega 644 as the main MCU to drive my logic. I'm wavering between that and the ATmega 328, but I just think the 328 probably doesn't have enough pins.

I've thrown together a few lines of code for doing the LCD display logic, using a "HD4478x" library for AVR's I found on the internet(I'll wait until my project is farther along before giving credit, since I might swap it out or roll my own in the end).

I went to test on a breadboard tonight and I discovered something very perplexing that I've not run into before...

Thursday, April 5, 2012

Wifi Links.

I haven't made any progress on the Wifi project lately. I've been on a pseudo-vacation for the past week.

In case you've landed here from Google with an interest in the MRF24WB0MA Wifi board from Microchip, I've got  few interesting projects I've run across you may find interesting.

"Jeff", trying(unsuccessfully?) to get the board working with an Arduino:
http://jmsarduino.blogspot.com/2012/01/mrf24wb0ma-not-working-yet.html

"Manis B", got a webserver running on an Arduino with the board:
http://theiopage.blogspot.com/2011/10/connecting-mrf24wb0ma-to-arduino.html
(Also, really nice, pragmatic setup with connecting the pads, made me realize my mount was overkill - but fun)

"Blondihacks", did extensive experimentation with the board with an Atmega 168:
http://quinndunki.com/blondihacks/?p=840
(Also, a fantastically done write-up, even though she deems it "a failed experiment")

And last but not least, one for my favorite blogs, Dangerous Prototypes, recently posted about a MCW1001A chip that is a companion to the MRF24WB0 boards that implements the TCP stack for you and communicates via UART:
http://dangerousprototypes.com/2012/04/04/mcw1001a-tcpip-socket-communications-interface-with-gpio/

--P