Some machining pics in the early stages:
Friday, December 21, 2012
Aluminum Speakers
Related to my 2nd clock project (as yet incomplete), I machined and built a couple of aluminum speakers:
Lamp Project Result
I finished this lamp some time back but did not get around to showing the final result. Well here it is:
Temperature Logger
This past year I've starting brewing beer and a recent addition to this hobby was a fermentation chamber - which is essentially a temperature controlled chest freezer:
This temperature controller can control both a cooling source and a heat source. I use a FermWrap attached directly to the carboy as a heat source in winter.
To make this project a little more fun I decided to add the ability to monitor the temperature remotely via internet and to keep a historic log. I used the Arduino platform coupled with Cosm.com to manage the temperature logging.
This aspect of the project is pretty much superfluous in terms of producing good beer but it was fun nonetheless. Also, the temperature logging portion can be leveraged to just about any application, be it monitoring your home temperature or whatever.
This project is relatively simple compared to most Arduino applications, but there is a bit of a learning curve. If this is your first Arduino project, I recommend you go through some of the basic tutorials provided to gain some familiarity.
Cosm.com
Before we get into the hardware and programming, let me quickly introduce you to cosm.com. I initially was going to use this complicated approach involving writing to a Google spreadsheet, etc. but then I found this website that was designed for exactly this kind of thing. Cosm allows you to upload feed data to their servers and then you can access it remotely, monitoring and graphing it. You can also set alerts, etc. Here is an example from a recent fermentation:
I added a few annotations to the top graph. You may note that I also have two monitors for "Cooling state" and "Heating state". These are not plumbed physically yet so the data is not real. They were intended to indicate when the heater or cooler turned on. The functionality is in the included code but you would need to add some additional electronics to enable this.
You can take a look at my live own temperature log here (assuming I have something actively fermenting):
Hardware
This is not an especially cheap project. We're talking, maybe $80-$90 shipped. But once you've made the investment, you can use this equipment for any number of applications.
Parts list:
- Arduino microcontroller, ~$21
- There are several versions out there. This one should work well:
- http://store.mp3car.com/ProductDetails.asp?ProductCode=OPN-013&cvsfa=3961&cvsfe=2&cvsfhu=4f504e2d303133&gclid=CLiqif7yq7QCFQWonQodGQ4AHg
- Here is more info on the different versions:
- https://www.sparkfun.com/arduino_guide
- Arduino ethernet shield, ~35
- You could use a wireless shield but they are more expensive and the programming will be slightly different. I elected to use the wired ethernet shield. If you don't have an ethernet port nearby you will also need to procure a wireless access point or just splurge for the wireless shield (again programming will be slightly different).
- http://store.mp3car.com/Arduino_Ethernet_Shield_R3_p/opn-014.htm
- And you'll need an ethernet cable, of course
- +5v power supply, ~$6
- Here's one:
- https://www.sparkfun.com/products/8269
- Waterproof temperature probe, DS18B20, $10
- I used this one:
- https://www.sparkfun.com/products/11050
- ~4.7k resistor
- Should be able to find from Radio Shack or any other electronics supply store
Assembly:
Assembly is very simple. Piggy-back the Ethernet Shield on top of the Arduino as shown in the photo above. Connect the 4.7k resistor between the +5v pin (Vcc) and pin 8 of the Arduino using some wire. Connect the DS18B20 temperature probe pins as follows:
Pin 1 - to Arduino GND
Pin 2 - to Arduino pin 8
Pin 3 - to Arduino Vcc (+5v)
Connect your power supply to the Arduino and the ethernet cable to the ethernet shield. I personally taped the temperature probe to the outside of the carboy, adding some foam insulation over the top. This placement is a highly debated topic (vs. inside a thermowell or in the beer itself) so you can put it wherever you want.
Programming
I imagine the Arduino will come with some instructions but you can find pretty much what you need here:
You'll need to access the download link to obtain the software for programming the Arduino. You'll also need a USB connection to your PC to program the thing. I won't go into all the detail - it's covered in the link provided. But here are a few notes:
- You'll need to obtain a few libraries online to enable all of the functionality
- OneWire: http://playground.arduino.cc/Learning/OneWire
- download the library and extract it to your Arduino/Libraries folder
- ERxPachube: http://code.google.com/p/pachubelibrary/downloads/list
- I see that there is an updated COSM library. With some minor programming tweaks you could easily use that one instead.
- download the library and extract it to your Arduino/Libraries folder. I noticed that I had to manually create a folder called "ERxPachube" and move the files into it.
- Here is my own code for this project:
- https://docs.google.com/open?id=0B_tlDQyqTL1pNWFIal91RUd0VUE
- Take note of the comments in the software:
To enable the temperature logging, you'll also need to set up your own cosm.com account and feed. You'll also have to modify my code slightly to match your specific details:
- Replace the feed ID with your own
- Replace the API Key with your own
- Replace the Ethernet Shield MAC address with your own (should be supplied with the Ethernet board)
- I used DHCP for the ethernet address assignment. If you use a static IP address you'll need to modify it.
Now, to program the board:
- Set up the Arduino IDE software to your particular Arduino board (Tools/Board)
- Load my code with your own customization as described above
- Compile the sketch then upload to the Arduino
- To see debug info, make sure the serial port settings are set to 9600 baud (Tools/Serial Port)
- One everything is working properly you can remove the HW from your PC and place it in your fermenter environment.
Feel free to shoot me any questions you might have.
Thursday, December 16, 2010
WiFi Internet Radio via router hack!
This is very cool and will soon be incorporated into a new project I'm working on... I'll have some details fairly soon.
The project previewed below has been put on hold just a bit until I can make progress with my current work (I plan to anodize both sets of hardware at the same time to same some $$).
Monday, April 19, 2010
Sunday, September 13, 2009
Digital Defocus - A Clock
The Concept
7-segment LED's form the digital readout (DRO). These are located on a moving sled that can move back and forth using a DC closed-loop motor control system. In front of the DRO is an array of lenses that allow for defocusing of the digits as they are shifted by the motor. This creates an unusual effect that can be implemented as desired in the programing. At this time the effect is randomized over the course of a single minute. The electronics clock is a real-time clock w/ battery so that when power is lost the time is retained. The overall controller makes use of a Dorkboard which is a version of the Arduino microcontroller. 2 buttons allow for changing minutes and hours and another 2 accessory buttons are used to disable the movement and to allow for triggering a 'night mode' that quiets the system in the evening. Everything is housed is a very sturdy, custom machined aluminum housing. A 32v DC power supply powers the system.
The Electronics
A complete schematic may be found here:
A Dorkboard was used as the microcontroller. This is an Arduino system based on the Atmel ATmega128 microcontroller.
The real time clock made use of a DS1307 board with battery backup. It communicates with the Arduino using an I2C interface. A MAX7219 LED driver IC was used to multiplex the LED digits. It communicates with the Arduino using a serial interface. The L298N dual full-bridge driver IC was used to drive the DC motor using a source voltage of 32v. The 32v supply fed into a LM2574 buck regulator IC to provide a 5v supply. A series of NOR gates are used to create 4 S-R latches that act as memory for button presses. The outputs of these latches feed into the Arduino as well as a series of OR gates to provide a single output for indication if a button has been pressed.
Here is an early breadboard of the LED setup w/ switches and the DS1307 real-time clock board:
Early testing of the drive system with breadboard:
Breadboard of the 32 to 5v power regulator circuit:
The final board, almost done:
The back side of the main board almost done:
I later switched from the L293D motor driver to the L298N as seen here. It is a much more bomber driver. I had been burning up many L293D's - I think because with my 32v supply I was operating close to the power dissipation limit. At this late stage, I only had room for the device on the back side of the board:
The inside of the clock w/ electronics and motor:
Inside the completed clock:
The Firmware
The code uses nearly all of the available memory of the ATmega128. Code is fully commented and may be found here:
Closed loop motor control is enabled by using Timer2 to generate the desired pwm to the motor. A PD controller algorithm was used. Encoder feedback is counted by setting up Timer1 as a hardware counter. These counts happen in the background and thus an interrupt is not necessary. With these timers taken, I was forced to use discrete IC's (S-R latches via NOR gates) as memory for any button presses since there were no interrupts available to capture the input.
The LedControl library was used for controlling the LED's.
The Mechanical Hardware
The drive system makes use of a 40:1 gear reduction off of a small DC motor. A DC motor was used to attempt to minimize noise in the system. Regular servos and steppers are LOUD. A linkage system drives a sled that rides on 2 sets of rods and bushings. The DC motor includes an optical encoder wheel w/ encoder which allows for closed-loop control of the drive system. Ball bearings form the user interface to the top two accessory switches and machined aluminum caps were used on the buttons for the rear time changing switches.
Here you can see the ball bearing switches:
There are 2 lenses per digit. The outer dome-shaped lenses were used for aesthetics but they also serve to magnify the digits. The inner, non-visible lenses are FOFP's or fiber optic faceplates. An FOFP is comprised of an optical mosaic of glass fibers which are fused together to form a cylindrical plate. The plate is effectively equivalent to a zero-thickness window since the image formed on one surface is precisely transmitted to the opposite surface with no change in focus and minimal loss of light. This device was used to induce an interesting defocusing effect. When the LED display is in contact with the FOFP, the image is transmitted sharply in focus. However when the display is moved away, a defocused image appears.
Here's an example of an FOFP:
The entire clock was designed and modeled in 3D CAD.
Almost all internal and external parts were custom machined from either aluminum or Delrin (drive parts). The gearing system and motor were obtained from an old optical scanner. The exterior parts were made with a combination of manual milling on a large Bridgeport and CNC milling on a Taig mill. The outer front housing was countour milled using the Taig mill with a Mach3 driven control system. The tool paths were generated using Pro/Engineer.
Here are some pics of the CNC process using the Taig milling machine.
The LED sled is being cut here:
Rough cut of the front faceplate:
Rough contouring on the faceplate:
Detail of the final contour pass on the faceplate:
The finished result of the faceplate (prior to adding the lens holes):
A lot of sanding and polishing was required to turn the relatively rough surfacing into the final smooth part.
Friday, June 19, 2009
DC Motor Closed-Loop PD Control Code
Here is code to do closed-loop DC motor control with the Arduino and the L293D motor driver IC:
http://docs.google.com/View?id=dhjz44fg_8f6sh7tcj
http://docs.google.com/View?id=dhjz44fg_8f6sh7tcj
Features:
-- Makes use of the L293 motor driver; may easily be adapted to another
driver
-- Motor pwm'ing implemented by direct control of the ATmega Timer2
-- Closed-loop feedback via encoder wheel on the DC motor
-- Hardware counter implemented using Timer1 of the ATmega for
high-frequency capture of encoder counts - no interrupt
necessary!
-- PD control system implemented for motor control
My main source of info for implementing motor pwm'ing with the L293D was
this document:
http://www.arduino.cc/playground/Main/DirectionalMotorControlWithAL293D
The author is not listed so I can't provide specific credit. The code is
not particularly well-documented so I have attempted to remedy that in
my own code below.
Here is a link to the ATmega48/88/168 datasheet. I happen to be using the ATmega168. This resource is invaluable in gaining an understanding of the
hardware counters/timers. All page # references below are to this document
unless otherwise specified.
http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf
Here is a link to the L293D motor driver datasheet
http://www.robokitsworld.com/datasheets/l293d.pdf
User 'mem' from the Arduino forum was very helpful in giving me tips on implementing a hardware counter for the motor encoder. This link in
particular was exactly what was needed:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1231326297/all
Other links that were helpful:
http://letsmakerobots.com/node/2074
http://thecodebender.com/journal/2009/2/21/we-just-cant-leave-things-well-enough-alone.html
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559/8#8
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1234764073
http://abigmagnet.blogspot.com/2008/10/dc-motor-control-part-one.html
http://mil.ufl.edu/~achamber/servoPWMfaq.html
For the PD control: the P is for position and the D is for derivative (or
velocity). Other systems also make use of I (integral, which gives you a
PID controller) but it is not particularly helpful in this application.
You may want to explore it for your own application. Computing the PD
gains is left to you. These are highly dependent upon the specific motor,
load, encoder resolution, and sampling frequency. You could just knob
twiddle until you find a workable combination. There are also analytical
methods out there for determining these gains.
Specific application notes:
The code here is tailored for a system that drives a part along a slider
rod (linear motion). In my case, this is done via a worm gear and a
linkage. I have roughly a 40:1 gear ratio. A homing move is implemented
to find a hard stop at the end of travel. The part is repeatedly moved
away from and then back to the home position. I added control input for
experimental use. Slew distance, acceleration, acceleration ramp - all
of these may be specifically tailored to your own application.
My motor is a smallish DC motor with a 32v supply. The quadrature encoder
provides digital output. I am using only 1 of the outputs in this case.
You could use the 2nd output for additional accuracy. Note that some
encoders output an analog signal. I used one of these initially and was
able to square up the signal using a Schmitt trigger. However, I had
noise coupling problems as soon as any pwm was input to the motor which
yielded spurious encoder counts. I'm not an EE so I abandoned this for
the much easier-to-use digital output encoder. My motor/encoder may be
found in some printer and/or scanner products where DC motors are used.
The Timer1 counter has a 16-bit register so if you expect encoder counts
higher than 16 bits, you will need to deal with this in the code. My
application runs well below this so I did not need to account for it in
this code.
In the motor_forward subroutine, I zero out any positive move errors
since in my application all forward moves position the driven part to a
hard stop. You can remove this positive move error check and modification
if your application is different.
I am checking the encoder position every 3ms or 333Hz (sample_freq). I
have placed some debug lines within this sample countdown period to ensure
that we have sufficient processor bandwidth. It's best to apply control
at the highest frequency possible. If you have other interrupts or other
processes happening during the motor move, you will need to slow down the
sample frequency. Note that the encoder counts are being refreshed at the
speed of the counter (really fast). I am only speaking of the frequency by
which I am computing position and velocity errors and applying control
gains
My L293D / Arduino / Motor connections are as follows:
Arduino digital pin 5 to motor encoder output pin
Arduino digital pin 11 to L293D pin 7 (motor pwm)
Arduino digital pin 12 to L293D pin 2 (motor direction)
Motor + pin to L293D pin 6 (pins 3 & 6 may be swapped to flip
the motor direction)
Motor - pin to L293D pin 3
Motor encoder +5v and ground pins suitably connected
L293D pin 1 connected to +5v (enable)
L293D pins 4,5,12,13 connnected to ground
L293D pin 8 connected to +32v (motor power)
L293D pin 9 connected to +5v (logic power)
Filter caps added per: http://letsmakerobots.com/node/2074
Labels:
arduino,
dc motor,
L293D,
PD control
Subscribe to:
Posts (Atom)