Showing posts with label hardware. Show all posts
Showing posts with label hardware. Show all posts

Saturday, October 13, 2012

Hardware PWM PIC/AVR

PWM is one of those things that we've always done in software. It allows us to set the frequency and duty cycle easily but at a cost of cpu cycles. In fact, until recently we didn't actually know what frequency and duty cycle meant and because our PWM experience was mostly with servo- and motor-control, trying to understand them in these terms was more confusing than it needed to be.

Consider how a servo works.
We have to send a continuous series of pulses between 1ms and 2ms wide (in practice, between 0.6ms and 2.4ms) at least every 20ms. This is where frequency, duty cycle and comparing to hardware pwm gets confused.

With a servo, you need send only one pulse, up to 2ms wide, every 20ms.
This means that for 18 out of 20 milliseconds, the output doesn't actually need to do anything:


So the first thing we need to do is to forget all about servo control.
With that out of the way, we need to understand how PWM is produced inside our microcontroller. If we were doing it in software, this is probably how we'd do it:

First, set up a timer. Every time the timer rolls over, switch on an output pin.
Secondly, set up a CCP (compare, capture, pwm) interrupt.
Put simply, in compare mode, we give this register a value. Whenever the timer value reaches this "milestone" or "waypoint" or whatever term you want to give it, an interrupt occurs. When this interrupt occurs, we turn the output pin off.


The end result is a PWM square wave.
The frequency is determined by the timer1 interrupt. In this example, we're assuming a 16-bit timer1 so the timer counts up to 65,535 and raises the interrupt every time the timer rolls over to zero.
If we pre-loaded timer1 with a value each time, we could reduce the number that timer1 counts up to (actually, we'd start it from a higher value; it always raises an interrupt on rollover to zero, but the principle is the same). If timer1 is only counting up to, say, 20,000 instead of 65,535 (so we'd start the timer1 off at 65535-20000 = 45,535 to get it to count up to 20,000) then the frequency (number of times something occurs) is increased.

Duty cycle is a whole other thing and is dependent on which "value we're counting up to".
In terms of servo control, duty cycle doesn't actually mean anything - we're dealing with definite lengths of time. Turn on a pwm pin, then after 1.5ms, turn it off again. This 1.5ms isn't actually a percentage of a frequency, it's just an amount of time to leave a pin on for.

But if we're creating a continuous, repeating square wave, duty cycle (as a percentage) depends on which value we're counting up to.

If we wanted a 50% duty cycle (half the square wave is high, half low) we need to know what value we count up to, in order to create the timer1/reset interrupt. Then we set our CCP (turn-output-pin-off) interrupt to half this value.

It seems that this is where confusion creeps in when working with hardware PWM.
The datasheets talk about frequency, duty cycle, resolution and all this sort of crazy stuff that just gets confusing - especially when you're trying to load a value to 25% into a register to set the duty cycle.

In order to create a 25% duty cycle, you need to first know the "timebase" for the PWM signal. This is the same as the number the timer is counting up to. Take 25% of this and put that value into the duty cycle register. So if we have an 8-bit PWM cycle (timer is counting from 0-255) in order to create a 25% duty cycle, we need to set the CCP value to 256*25% = 256/4 = 64.

BUT
If we're using a 16-bit timer (counting from 0-65,535) then a 25% duty cycle would need a CCP value of 65536*25% = 65535/4 = 16,384

So in summary -
To increase the frequency, we need our PWM module to count up to a lower value.
To create a duty cycle (in percentage terms) we need to know what number we're counting up to, calculate the number to count up to, in order to create the % based duty cycle and put that value into the duty cycle register.

This is nothing like the way we've been creating PWM for servos in code but does provide us with a really quick and easy way of playing PCM based wav files. Here's a snippet from the datasheet for a PIC16F1825


So by loading the value 0x1F into our PWM register, the hardware will automatically reset the PWM output pin 250,000 times per second. Because of this, the maximum "resolution" - maximum number we can set the CCP interrupt to is a 7-bit value (0-127). In order to create a 250khz carrier wave, the timer1 "count-to-this" value (or hardware equivalent) has to be less than 255 to ensure it can be reset enough times during one second. Because "timer1" is counting up to a value less than 255, the CCP interrupt point cannot be an 8-bit value (0-255) so the maximum resolution is a 7-bit value (0-128).

For our audio playback example, we can set the PWM output "carrier wave" to 250khz - an inaudible frequency except for small animals - and then set the "duty cycle" using the value of each sample in the wav file. It needs a little adjustment, since we're reading 8-bit values from the wav file. Luckily these eight-bit values represent duty cycles in binary (so a 50% amplitude in the sound wav is recorded as 128 in the wav file - i.e. 50% of the maximum 256). So if we could convert an 8-bit value to a 7-bit value, we could just load this straight into our CCP value register in PWM hardware.

To convert 8-bits to 7-bits is quite easy.
We simply bit-shift the entire value to the right by one place.
This is the same as dividing the value by two (but bit-shifting is a quicker operation to do).

What this does is makes all max values of 256 a new value 128.
All minimum values of 1 are discarded (or treated as zero) and the new minimum value becomes 2 (which when bit-shifted or divided by two is one). The overall result is a tiny loss of definition in the sound - but given the low-quality hardware we'll be playing it back on, is of little concern.

So there we have it.
A quick round up of how to play sounds from a 22khz using PWM hardware:


  • Set up the "carrier wave" frequency to be 250khz by loading PR1 with the value 0x1F. 
  • Every 1/22050th of a second, load another byte from the wav file, bitshift right by one position (divide by two) and set CCPR1L.


That's it!

Friday, September 30, 2011

What can you salvage from a floppy disk drive?

In true Nerd Club fashion, no sooner have we decided to start (or re-start) a project, and something else comes along and takes our attention away. This time, it was the postie bringing us a clutch of four floppy disk drives, won off eBay just 48 hours earlier.

Why would anyone want such old crappy hardware?
Well, for a start the winning bid was just 1p, so even allowing �3 for delivery, they came to less than a pound each. (if you're ever at a car boot, and someone is selling off job-lots of drives as they often do, for 50p or so, it's worth grabbing a few). But that's not the main reason - we actually went out looking for old floppies, as a source of cheap stepper motors.

Here's what we found in one of our floppy drives:


The bit we're interested in is the stepper motor - usually seen at the back, next to the IDE cable connector. Whip the lid off and take a look. The motor usually has a corkscrew shaft and a bit of grease on it. These aren't important right now.


Normally two screws is all it takes to get the motor out of the casing. The other end of the shaft is usually in a part moulded into the actual casing. If the shaft and casing are all one unit (as often found in low voltage or portable/laptop drives) you'll need to undo a few more screws. But 99% of drives are built like this one.


Undo the two screws and pull the stepper motor backwards. Eventually it will stop. That's the flexible ribbon cable holding it in place. Pull until it comes free.


If your motor still has the ribbon cable attached, you can use this to connect to a PCB in future. But most messing about with steppers is first done on a breadboard/prototyping board, in which case simply solder some wires onto each of the four connection points.


The rest of the drive can be junked. We've got what we came for. But if you're in a scavenging mood, there's plenty more to be had from these little things. Get rid of the disk caddy and moving parts...


Remove the plate above the spinning head and pull. The actual spinning head should come off in your hands. It's a doughnut-shaped magnet with a spindle in the middle. It should just lift off. Undo a few screws from the bit it's sitting on and you should see some cool coils.


It's these coils that control how the head spins. As each coil is activated in a particular sequence, it can attract or repel the magnets inside the spinny head thing. If you really wanted to, you could use this as another crude stepper motor. But it's probably more hassle than it's worth. The coils themselves, however, might be useful in other projects.

Let's take a quick look at what we've scavenged from our floppy disk drive:


In our drive (though not all) we found some useful 0.1" pitch flexible ribbon cables. These are useful for joining two or more PCBs together, especially if soldering isn't your strong point - they're quite easy to work with.

There were a few springs, used to pull the disk drawer in and out, and a few "peg-style" clip springs too.

The rod that the disk head was on could always come in useful for something robot-y.
Of course, the stepper motor is going to come in handy - that's what we came for in the first place! And there were also a few "self-tapping" screws which might be handy in future. They have a slightly wider thread than normal screws and are perfect for fixing into plastic or acrylic (where they make their own thread as they are screwed into place, hence the name)

Not a bad haul for a few minutes work.
Get yourself some component bins, a few cheap drives and get to work!



Friday, September 9, 2011

CNC pick and place machine update

After an evening at BuildBrighton, exchanging ideas and motor control circuits, we've had a re-think about our CNC-based pick-and-place machine. In fact, we've had several re-thinks, returned to abandoned ideas, discarded previously agreed ideas and gone around in circles enough times to make everyone very, very dizzy!

At first, we concentrated on making a machine that would be simple to understand during it's construction.
We concentrated on theoretical accuracy - using a small angle stepper motor, relatively few teeth on the cog, sticking to numbers that were easily divisible and so on. The problem with this approach is that actually obtaining parts is quite difficult - 1.8deg steppers are quite expensive (�20/unit) wereas cheaper, salvageable motors (from printers, cd drives etc) are more difficult to drive, and have peculiar voltage requirements.

Our compromise is this -

Where possible, use parts that can be salvaged from easily obtained hardware.
An old, obsolete PC could be a major source of parts - the power supply gives us multiple 5V and 12V supplies, the CD and floppy drives provide 4-wire (2 phase) stepper motors, specifically designed to run on 5V/12V. The IDE cables are perfect for connecting homemade PCBs to other parts on the machine (old hard drive cables use 0.1" pitch, the same as breadboard prototyping and lots of through-hole components, pin-headers etc).

Rather than concentrating on using motors and belts that make the maths for calculating steps per mm easier, we're going to build a machine that works with mostly salvaged parts. The final device will be a "puppet and playback" machine - the user will manually position the picking head either using buttons on the machine, or using a PC/software interface, then record the co-ordinates (in terms of steps rather than mm from a known origin) back to the PC/eeprom memory. Once one complete "animation" has been recorded, the script can be played back over and over again.

This way, the actual accuracy of the device becomes less important - it just has to be "accurate enough" to pick up a component and place it on the board. We're not going to be loading g-code type files into the device, or have to do tricky conversions from one format to another. The machine will simply use a record-the-steps-and-play-them-back approach for placing the components. So the actual distances travelled and units used won't matter; if you're using 1.8 deg steppers and half-stepping to give 400 steps/rev, with a 5mm belt, it doesn't matter how far between components the head moves: the machine will simply remember x number of steps on the x-axis and y number of steps along the y-axis. Someone using a machine with 7.5 deg steppers will simply have fewer steps in each axis to travel the same physical distance.

Talking of belts, we've decided to ditch them and go with a rack-and-pinion system.
This means we're removing another potentially costly part from the bill of materials - a 1.25mm belt can be had from a printer or a scanner, but it may be 1.2mm, or 1.25mm, or the imperial equivalent, a 0.05" pitch belt. All these belts need to have the right pulley or cog, with the teeth exactly spaced to match the belt.

By using a rack and pinion approach, everyone can use the same set of laser-cutting templates, and matching the right pulley/cog to your (possibly unknown) belt is no longer an issue.


Wednesday, August 24, 2011

Lexmark X73 all-in-one printer scanner

I got one of these off eBay today.
I'd been scouring Freecycle for a while and any time a scanner or a printer came up, put in a reply begging for it - sometimes even explaining that it was going to be fully recycled into something more interesting and infinitely more useful (although perhaps that's why no-one ever got back to me) - but nothing came up.
So I put a bid on this Lexmark X73 and won it. For an amazing 50p!



It was a bit cumbersome, travelling across Brighton & Hove with it (and a sort-of-working monitor I also got for 50p but that's for another post) under one arm, mounting and dismounting a variety of buses, but worth it in the end.

It took less than 45 minutes to reduce an all-in-one printer/scanner to this pile of recyling/rubbish...



...and this pile of rather useful looking parts:



Here's what I managed to salvage -
a) 0.1" and 0.05" pitch ribbon connectors
b) two-wire motor
c) rods and rails
d) cogs/gears/pulleys
e) four wire stepper motor
f) 5mm pitch belt
g) 2.5mm pitch belt
h) six wire stepper motor
i) my dismantling tools (not included!)

And of course, a fairly beefy power supply - 30VDC 1A output
Given that this power supply came with the printer/scanner, we can safely assume it's good enough to power all motors together - there's only one way to know for sure, but it's getting late (it took nearly three hours to get across the city and back again on the buses this evening, so I didn't get started 'til 10pm) so it'll have to wait 'til the morning now.....