I recently bought an
infrared heater which makes a space feel much warmer if it's aimed at me.
But it has a relatively narrow beam. So I figured it would be cool to come up
with some contraption that automatically swivels the heater to always aim it at me.
I often thought about building such a device before, though more in the summer, and to use it with a fan instead of a heater.
My original idea was to have some sort of transmitter on my belt and a directional antenna to sense where I am. But having bought a wide angle (120°) camera module for my Raspberry Pi computer, I realized I could use that and image analysis to figure out where I am instead.
So I tweaked my imgcomp program to output
where it last saw motion, and I made it output the position using
character graphics for debugging. Here
I'm walking across the camera's field of view, with the output below what
the camera sees, printing the horizontal position every time it captures a new frame
with motion.
What kept me from just using a camera for this until now was t hat I only recently bought a camera module with a really wide angle lens. Without a wide angle lens, the camera would have to swivel with the heater, and then the whole image moves, which would make detecting other motion much more complicated. And of course there is the problem of walking out of view, and should the camera hunt for the person after that? At any rate, moving the camera would add a LOT of complexity.
The next challenge was to make the raspberry pi turn a motor to swivel the heater.
My first thought was to use a relay board like I did for my
mouse experiments, but I needed some way to
go back and forth and be able to set the position repeatably. I would have needed
a whole bunch of switches to detect the current angle, so that would have
been complicated. Also, the clicking
of the mechanical relays would be annoying. I thought about using
solid state relays, but the whole thing would still be complicated.
Then I realized about five years ago I bought this stepper driver, which I hadn't even taken out or the bag all this time. It turned out, that one was now discontinued and I couldn't even get documentation for it on line/ So i had to figure it out by trial and error. But it worked fine using the 3 volts from the raspberry Pi's I/O pins.
I used it with a small stepper motor, probably from an old dot matrix printer.
Using this stepper driver was so much more elegant than what I came up with
to drive the stepper for my computer
controlled box joint jig in 2003, but back then, there was no Raspberry pi
or Arduino or ordering parts like this on line cheaply.
I added a little pointer to the motor, making a little "gun" for a little chipmunk toy to aim to debug and test my software.
I raised the camera up a bit behind the chipmunk doll so it wouldn't trigger off the motion of the chipmunk itself.
Lots of fun testing it. Using the smallest micro stepping the controller
had available (I think it divides each physical step into 16 micro steps), I was
able to get it to move very smoothly and quietly. Here I'm moving side
to side to make sure the aim follows me.
I wanted a lazy susan bearing for a platform to swivel the heater with, but
there were none available in the stores locally. But searching for a bearing,
I saw I could get a whole lazy susan platter from Canadian Tire for $12.
But when I had a look at it, the "bearing" it sits on is far too small.
They had another one with a bigger bearing, but it cost twice as much,
and the bearing on it didn't really work. So I gave up on that.
Instead I rigged up four roller skate bearings to make a rotating platform.
The bearings are screwed to the sides of small wooden blocks. The head of a drywall screw is just barely big enough to hold the bearing, and with a washer behind the bearing, it can spin freely without rubbing against the block.
A fifth bearing fits tightly in a hole in a disk to act as the central pivot.
I used a forstner bit that I modified
to make the hole of just the right size.
Bearing blocks in place, and screwing on another block in the middle to hold the
screw that holds the central pivot bearing.
I made a mount for the motor out of 3 mm baltic birch plywood. I marked
the hole positions by tapping a piece of plywood onto the screw studs sticking
out of the motor. The motor is about a NEMA-17 size, but with studs sticking
out instead of screw holes.
The motor already has a timing belt pulley on it (press fit on, so not easily
removable), but it was just what I needed. I used a long timing belt
that probably came from the same dot matrix printer that the motor came out of
to go around the wooden disk.
A spring rotates the bracket to apply constant tension against the belt. That way I didn't have to worry about making the disk accurate to a fraction of a millimeter.
A screw and washer fix the belt to the disk. This limits the rotation to just
under three quarters of a turn or about 240 degrees. But my camera module
only has a 120 degree field of view, so I didn't need that much range
of rotation.
A tray for the infrared heater base screws to the top of the disk.
Then lots of tweaking. With the belt making for about a 14:1 reduction,
I needed to run the motor faster, and that meant paying more attention to
how I ramped the speed up and down.
Fortunately, I was able to get sufficiently accurate timing on the raspberry pi with regular Raspian Linux, just with a regular program and using the "usleep()" function, so long as there wasn't any new processes launched while stepping.
I made the stepper driver a separate program, because that program had to run with root privileges to get access to the I/O lines. I modified my image analysis program to send updated positions via UDP packets to the stepper driver program running on the same computer.
The whole thing turned out to be tricky, because while ramping the speed up and down,
the actual target position could change, and the code had to be able to take that
all into account. For example, it could be in the process of ramping up to swivel
left when the target suddenly switches to the right, but in that case, it can't
just reverse, it has to keep going but ram down gently, then reverse and ramp
up towards the new target. It also needs to know when to start ramping down
to exactly hit zero speed on target. And my code currently does that for just
one motor. It would be cool to come up with something that can do that for
several motors at the same time.
I ended up still using the finest micro stepping, because I realized swivelling faster would lead to unnecessary twitchiness. Plus, micro stepping makes it quieter.
I also added some hysteresis so it wouldn't swivel unnecessarily. The infrared
heater's beam is about 20 degrees wide, so it doesn't need to aim spot on all the
time.
I then screwed all the pieces down to a piece of wood, which I then clamped to the table on my pantorouter, and set up with the infrared heater on the floor.
I have gotten lots of suggestions on my Instagram that I should mount the heater to the ceiling, but there's actually quite a bit of heat that rises up from it too, and I didn't want that to heat up the heater itself. For now, to be safe, it goes on the floor.
I needed a simple "project" to try it out with. I had bought a cheap shelf from
Walmart, for about as much as the wood would have cost, so I assembled
that while in front of the heater. I thought that the heater swivelling and the
sound of the stepper motor would be really distracting, but it wasn't. And it
was nice to always have the heater aimed at me. Otherwise, I would have worn
a fleece while doing this. The basement temperature was 14°C (57°F)
I'm not sure how useful this thing is. It would be more practical to just buy another infrared heater or two, because the cost of running this heater here is just ten cents per hour. But in my previous big garage workshop, maybe with a really directional heater, and a contraption that could also aim up and down, and to have several of these high up in the corners of the shop would have made a big difference in terms of not needing to heat the shop as much.
To my Woodworking website.