||[Jan. 21st, 2009|10:29 pm]
I can't wait to hack this:
Open source, open hardware.
||[Jan. 2nd, 2009|04:27 am]
Although this has nothing to do with electronics and computers, I am quite interested in sewing - backpacks, messenger bags, wallets, dress shirts, pants, etc. so I'll also be posting sewing projects here.|
My duct tape wallet is slowly falling apart, but everyone seems to like it - cashiers comment on it all the time. I love it because it's lightweight, small, and thin. And it holds all my money, cards, and change. It's perfect. But because it's slowly degrading, sometimes it gets sticky where the tape has rubbed sideways or peeled off, and various holes are patched up. So time for a new wallet, but this time I am making it out of Tyvek, an amazing material.
I am making the exact same wallet as the duct tape one. You can either sew the wallet together (which I am doing), or tape it together with packing tape or duct tape or another suitable tape.
Materials: Tyvek or fabric of your choice (duct tape, 1000 denier nylon, denim, rip-stop nylon, etc), 3 inches of elastic (almost anything will work), optional: zipper, velcro
This is the pattern, all measurements in inches. No seam allowances are needed.
1. Place the above pattern on the right side (the side you want showing) of the fabric.
2. Cut out the perimeter.
3. Sew (or tape) the middle of the elastic to the skinny flap. This is going to be the card holder. OPTIONAL: sew velcro to the flap to keep the wallet closed.
4. Fold the flap along the dotted line (about 1/4 inch from the body of the wallet, depending on how many cards you carry) and sew the elastic to the body at the top and bottom of the elastic.
5. Fold the larger flap over. This is going to be the change pocket. This flap seems too long (it goes past the halfway point) because we are going to make accordion folds so that it expands when we put things in it. OPTIONAL: sew velcro to the flap to keep the wallet closed.
6. Make accordion folds at both sides of the flap. Sew them up. Finally, sew the bottom (you may not want to sew over the accordion folds - I did). The pocket is now complete. OPTIONAL: add a zipper to the top of it.
7. Fold the wallet in half and sew up the sides. Turn it over. Your wallet is complete.
With stuff in it:
|PWM LED Fading
||[Sep. 25th, 2008|03:44 pm]
At work we have these orbs from Ambient Devices (http://www.ambientdevices.com/cat/orb/orborder.html) which connect to the serial port and you can make it "display" almost anything you want, from the weather to stock prices. For one hundred fifty frickin dollars. All it contains is a few red, green, and blue LEDs and a 16F or 18F series PIC. The colors change and pulse up and down. I guess it's expensive because it also has a wireless "pager" receiver on the 929.6625 MHz band. But not worth $150.
Four bytes are sent to it... a start byte letting it know valid data is coming next, followed by a mode byte, and then color and pulse rate. More info about it is in the developer section of the site (http://www.ambientdevices.com/developer/).
When I opened it up and saw how simple it was, I realized I could build my own. Also, it gave me a good excuse to play with LEDs, and learn about the PWM functionality of the PIC 16F series microcontrollers.
To test the PWM, I wrote a program that fades an LED on and off, using the hardware PWM and one of the hardware timers in the microcontroller. The micro runs on an internal 4MHz clock, which produced 1MHz instruction cycles. It uses a PWM period of approximately 1ms. The fading effect is created by modifying the duty cycle to change the intensity of the LED.
The following is the core of the code. The main loop calls fadeU to turn the brightness of the LED up by adding the variable 'step' (which I set to 0x04) to the duty cycle register (CCPR1L). It then pauses for a very short time (about 16.384 ms) by calling T0ov which waits for Timer0 to overflow. I set the Timer0 prescaler to 64 (it divides the 1MHz clock by 64. 1000000 / 64 = 15625. 256/15625 = 16.384 ms). It then checks to see if there would be an overflow of the CCPR1L register by adding 'step' to it again, but this time it puts the result in W and checks the carry flag in the status register. If there's no carry, then it can continue to increment, otherwise, it clears the carry flag and returns to the main loop. The fadeD function does the same thing, but uses subtraction.
I used a 16F767.
call fadeU ;fade up
call fadeD ;fade down
goto LOOP ;repeat forever
movlw step ;increment duty cycle
addwf CCPR1L,F ;
call T0ov ;pause
addwf CCPR1L,W ;add step to duty cycle to
btfss STATUS,C ;check for overflow
goto fadeU ;fade up more if no overflow
bcf STATUS,C ;clear carry flag
return ;done fading up
movlw step ;decrement duty cycle
subwf CCPR1L,F ;
call T0ov ;pause
subwf CCPR1L,W ;subtract step from duty cycle to
btfsc STATUS,C ;check for overflow
goto fadeD ;fade down more if no borrow
bcf STATUS,C ;clear carry flag
return ;done fading up
T0ov ;rather than using Pause, check TMR0
btfss INTCON,TMR0IF ;check T0 overflow flag
goto T0ov ;wait for T0 to overflow
bcf INTCON,TMR0IF ;clear overflow flag
The next thing I would like to do is use an 18F series PIC with USB capabilities and use RBG LEDs.
|Digital to Analog Conversion
||[Sep. 25th, 2008|03:39 pm]
As they say, "it's an analog world."
I wrote a short program in Microchip's MPLAB using their C18 compiler to test the free sample 12-bit DAC I received in the mail.
The program takes the SIN of a floating point number, ADdata, and like a typical sin function, gives an output from -1 to +1, depending on the value of ADdata. It then multiplies the result by 32768 (2^15) to give a range from -32768 to +32767. It adds 32768 to that, giving a final range of 0 to 65535. This gives us a number that can be represented as a 16-bit integer. The DAC is only 12 bits, though, so we send the highest 12 bits of the integer and discard the lowest 4 bits (which don't really matter that much anyways). The data is sent to the DAC via the SPI (serial port interface). ADdata is then incremented by a small amount, and we do the whole thing over again.
The PIC is running on it's internal RC 8MHz oscillator, and the instructions are executed at 2MHz. You'd think you could get a pretty decent sinusoidal frequency out of the DAC, but the following image shows that it output a wave at a measly 5Hz.
This is probably due to the fact that I used a high level language (HLL), which adds some extraneous overhead which wouldn't be there if I programmed in assembly. The sin function and floating point routines add a LOT of instructions to the program. Another factor that determines the frequency is how much the variable ADdata is incremented. Here, it is incremented by 0.1. When this number was increased, to say, 1, the resolution of the waveform became quite choppy, like in the figure below, but the frequency increased a bit.
At an increment level of only 0.01, the sin wave was very smooth, but the frequency was only about 2Hz.
The guts of the program are below:
data = (int)((sin(ADdata)*32768.)+32768.); //do math and convert float to int
dataL = (char) (data >> 4); //get the middle 8 bits of the int
dataH = (char) (data >> 12); //get the highest 4 bits of the int
SPI_CS=0; //chip select DAC
WriteSPI(0b00010000 + dataH); //send 1st byte
WriteSPI(dataL); //send 2nd byte
SPI_CS=1; //deselect DAC
ADdata = ADdata+.1; //increment ADdata
|Magnetic Stripe Card Reader with PIC12F683
||[Sep. 25th, 2008|03:38 pm]
Quick update: an I2C eeprom chip could be added for more memory, or a flash drive could be interfaced. USB flash drives, however, are difficult to interface because PICs do not have USB Host capabilities.
Project: Read a magnetic stripe (credit card or similar)
Background: I became interested in magstripes because my student card has one (two actually, one to get into my dorm and one to add money to, like debit), and I wanted to see what is on these stripes. There are many articles detailing how magstripes work and the data format:
Theory: We are primarily concerned with the binary coming out of a card reader, and its format.
3 signals are generated:
/CP - Card Present (active low) - goes low when swiping a card
/DATA - Data (active low) - valid on low clock pulse
/STROBE - Clock (active low)
Format of the data:
Bytes are 5 bits wide, 4 data bits and one parity bit.
Bit 1, the least significant bit (LSB) is sent first.
There is a 16 character set - 10 data, 3 control, and 3 framing.
"The magstripe begins with a string of zeros to permit the self-clocking feature to "sync" with the data and begin decoding. A start sentinel  then tells the reformatting process where to start grouping the decoded bitstream into groups of 5 bits each. At the end of the data, an "End Sentinel" is encountered, which is followed by an "Longitudinal Redundancy Check (LRC) character. The LRC is a parity check for the sums of all b1, b2, b3, and b4 data bits of all preceding characters. The LRC character will catch the remote error that could occur if an individual character had two compensating errors in its bit pattern (which would fool the 5th-bit parity check). "
Process: In order to obtain this information, we need a way to capture the bitstream and save it. A perfect task for a small microcontroller. I decided to use the PIC12F683 because it has an internal clock of 8MHz (plenty fast enough to capture the bitstream), can operate between 2 and 5V (battery powered from button cell or AAA), has many different types of interrupts (we'll use two in particular, external interrupt and IO change interrupt), enough IO pins (6, we'll use 3 for the card reader, and perhaps more for optional LED display), its small 8 pin footprint, and finally it has enough memory (96 bytes of user RAM and 256 bytes of EEPROM). We can read in a total of about 85 bytes (the typical credit card has about 38 bytes).
Program: Source code here (written in PIC assembly). First, we must initialize the microcontroller - this entails setting up the IO pins for digital input or output, enabling inuterrupts and edge trigger, and setting the internal oscillator. Also, if using display LEDs, to blink an LED to indicate "ready to scan."
Then we enter a loop where nothing happens, we simply wait until the card is read, that is, an interrupt occurs.
We connect the STROBE to the external interrupt pin of the PIC (GP2). The CARD PRESENT line is connected to GP3, which is set up for interrupt on change (that is, when the bit goes from low-to-high or high-to-low). DATA is connected to GP0 and is simply read by the microcontroller in the interrupt service routine (ISR).
The ISR is the bulk of this program. There are two entry points - the CP interrupt on change and the STROBE external interrupt, which will occur on the falling edge of the clock (high-to-low, though, theoretically, it shouldn't matter what edge we trigger on). Since there are two entry ways, the first thing the ISR checks is to see if the CP is high or low, if it is low we ignore it and start capturing the bitstream. The STROBE will be the source for most interrupts. Because the data is read on pin 0, we mask that bit by ANDing the rest of the port with 0, effectively clearing any other 1s that might be in it. We then ADD this bit into the first user register possible (we're going to need indirect addressing) and shift the register to the left to prepare for the next bit. After 5 bits are read in, we need to take complement of the byte because the data is read in complement form (low=1, high=0). Then we increment to the next byte and the next user register. That's the general principle, but there is a complication - making sure the 5 bits in each byte correspond to the same byte that's on the card, because the leading zeros can cause misalignment. This is easily fixed by saving the bitstream starting when the first 1 is read (from the start sentinel 11010).
Finally, the last interrupt will be CP going high, indicating we are done reading all the data in from the card. At this point we write all the data from the user registers into EEPROM and optionally blink an LED indicating we are done. We have saved our data in nonvolatile memory, so power can be turned off.
Shortcomings: There are a few shortcomings with this program, mostly with the user interface. The way I have written it, a card can be scanned once or twice, or a different card can be scanned second. The power must not be turned off in between scans, or the first scan data will be overwritten. I have not fully figured out the EEPROM write, I get spurious data the second time a card is read.
Error detection - I have not programmed any error detection. I do not make use of the parity bit, or the LRC at the end of the bitstream.
Also, once we have our data, we need to present it in a form understandable by the user, most easily done with a seven segment display and a momentary push button switch to view each character. This presents a problem. A switch requires another input pin, and a seven segment display requires seven output pins, however we only have three pins to work with. The seven segment display could be driven with two pins going to a shift register, and then to the seven segment display. We would need another chip, increasing the complexity and size. Or we could use another PIC with more IO pins.
Development: The next step will be to port the program to a PIC with more IO pins, in order to have a display. I'll also get a PIC with more EEPROM, so more cards can be read. The abilities of the user interface will be expanded, to include deleting a card from memory, rescanning a card, and a seven segment LED to display one character at a time.
I welcome ideas, comments, and questions.
|Cypress PSoC Eval Kit
||[Sep. 25th, 2008|03:38 pm]
I've been playing with the PSoC (programmable system on chip) evaluation kit from Cypress. They have a graphical layout program called PSoC Express. It's simple to drag and drop inputs, outputs, and "valuators" (LUTs, if-else-then structures, etc). They have some excellent interface options, and so far I'm really impressed. The time it takes to create a simple little application is just a few minutes - it would take hours on a PIC. Here's a slide I pulled from one of their presentations:
The PSoC chips have a M8C CISC microcontroller at the core, and analog and digital blocks surrounding it. Reading their literature, these PSoCs can reduce part counts by 50%. To me, they feel like a PIC with a CISC instruction set and a nice set of analog features.
|Digital IIR Filters
||[Sep. 24th, 2008|04:11 pm]
I much prefer digital over analog, and I just finished my DSP2 class. I also love MATLAB.
For my final project, I decided to explore the effects of quantization of the coefficients of various structures of infinite impulse response filters.
Simply put, I created a lowpass Chebyshev Type I filter (order 10, fc = 0.4 [normalized]). MATLAB outputs the numerator and denominator coefficients in Direct Form. I found some MATLAB programs which transform the direct form into cascade, parallel, and lattice-ladder structures. These structures are just a way of arranging/manipulating the coefficients; the frequency/phase response doesn't change. So why do these different structures exist? Because in a real system, we can't have infinite precision numbers. MATLAB outputs the coefficients as 64-bit Doubles, which for our sake, are "infinite" precision.
(I also like low power, low cost, low speed microcontrollers (i.e. 8-,16-bit Microchip PICs). Running a 64-bit floating point routine on one of these 20MHz beasts would take forever, so we quantize our filter coefficients to something more reasonable, like 8 or 16 bits.)
Because the coefficients used to implement the filter are not exact, the resulting poles and zeros will, generally, be different from the desired poles and zeros. As a consequence, the resulting filter will have a different frequency response than the one desired. If the poles are close to the unit circle, the stability of the filter may also be affected.
The different filter structures have varying sensitivity to the filter coefficient quantization. I quantized the coefficients in fixed point, from 6-24 bits.
Performance was measured by mean squared error in the passband only, and mean squared error across the whole frequency band. This later turned out to be unnecessary, as both MSEs are pretty much the same.
The direct form structure performed the worst, by far. The cascade, parallel, and lattice-ladder all performed about the same, and all performed really well.
The cascade filter closely matched the frequency and phase response of the original filter, while the parallel and lattice-ladder responses began to level out in the high frequency range (however they were still down about -50dB at 6-bits (and down even lower as the number of quantization bits increased), so this deviation isn't as dramatic as it looks in the frequency responses).
Full paper is here. Hopefully, my webserver is working.
||most recent entries