One of the benefits of learning how to make things, is that you sometimes come across something and think not only "I want that!" but also "and I think I might be able to make it!" Plus sometimes things you want can't be bought in a store. About two months ago Hackaday featured a knitting clock designed by Siren Elise Wilhelmsen.
Wilhelmsen's clock was designed as an art project that showed the passage of time by knitting a stitch every half hour, a row every day. At the end of a year the machine would drop a 365-row scarf from the bottom. This project intrigued me as it is a kind of cross-section of many of my interests: electronics, clocks and knitting. I had even recently acquired a flatbed knitting machine and was starting to learn how to make shawls and other clothing with it. This seemed like such a cool thing to have on my wall. I wanted one.
While it appeared you could commission one of Wilhelmsen's clocks from her site, no price was listed and "if you have to ask you can't afford it." Considering this was an art project with installations in hotels among other places, I figured it was out of reach regardless. Unfortunately the site didn't go into any details on how the clock was made, and only featured a short artistic video showing it in operation.
The day the post showed up on Hackaday, I actually shared it with my wife saying how cool it was and how I wanted one. Her response? "You should make one!" While I had already entertained the idea before that, her encouragement pushed me over the edge. After all, even without any instructions, if you break down what this clock is into its individual components, it isn't all that complicated. You need:
I had a stepper motor from an old 3D printer, a Raspberry Pi, and willingness to learn new skills. I needed a knitting machine, some electronics components, and a lot of new skills. To complete this project I ultimately needed to learn how to control stepper motors electronically, expand my rudimentary Python skills, and learn 3D modeling.
I have seen a number of wall clocks that feature the Latin expression Tempus Fugit or "time flies" and so I decided to name my project Tempus Nectit or the closest approximation I could find for "time knits."
The design is split into a few logical components:
One of the first parts of the design I worked on was the Adafruit motor hat for a Raspberry Pi. The kit is pretty straightforward and I essentially just followed the their motor hat documentation to assemble and test the motor hat with my Raspberry Pi. I ended up attaching a small stepper motor that was part of an out-of-commission 3D printer I had lying around.
The motor hat requires its own power supply that ranges between 5 and 12 volts. Like many geeks, I have a box in my garage that contains old power bricks, so I fished through there for some options. Something I learned from 3D printing was that stepper motors have more torque with more voltage, but I also knew that it also makes the motors louder. I tried both a 9 and 12 volt power supply and ultimately decided to go with the 9 volt, 1 amp power supply for this project as it took up a bit less space and it seemed to provide plenty of power for the stepper.
Early in the project I realized that it would be useful to be able to control the stepper motor manually with push buttons, instead of having to SSH into the machine and run scripts. I recalled in a past Adafruit project to turn a Pi Zero into a small game system, that you could attach small electronic buttons to GPIO pins on the Raspberry Pi.
I dug through some electronics kits I had around (badges from conferences) and found a few push buttons I could use. Then I looked up which GPIO pins I should use for the purpose and where they mapped on the Adafruit motor hat and followed Adafruit's guide on GPIO buttons to attach the buttons to GPIO pins 19 and 21 and corresponding ground pins using some 22AWG solid core wire. Their guide also provided some sample python code I could use to register button events and then trigger motor movements. I soldered the wire to one side of the buttons and ended up removing the pins from the other side for ease of installation later.
I decided on two buttons so that I could move the motor one stitch in either direction. This turned out to be particularly useful when casting on, as you need to rotate the knitting machine a full 360 degrees, slowly, while winding yarn under odd-numbered hooks and around even-numbered hooks. Normally you do this with one hand while the other is cranking the hand-crank on the knitting machine, and while I initially thought I'd write a script just for casting on, it turned out having this manual control that moved one stitch at a time was far more convenient.
The Raspberry Pi is running standard Raspbian as its OS so that it matched the platform in the Adafruit examples. This made it easy to go from a blank OS to one that was able to run stepper motor and GPIO examples from Adafruit.
I needed to write custom software so that I could control the knitting machine with precise steps. All of the main examples from Adafruit were in Python, but I only have a passing familiarity with the language, as my software development experience has traditionally been in C, Perl, and Bash. Fortunately, Python syntax is similar enough to the languages I know, and the examples are clear and simple, so I used Python for the whole project.
The sample scripts on Adafruit worked to cause my stepper motor to rotate each direction, but what was more important for the next step in the project was to demonstrate that I could actually control the knitting machine itself. I found a motor adapter on Thingiverse for the 48 hook Sentro knitting machine and modified it slightly in Tinkercad so I could attach it to my stepper motor.
This stepper motor originally attached to a shaft on the 3D printer using a short length of aquarium tubing and some 3D-printed clamps. I stuck with that idea and resized the hole in the motor adapter so that I could just shove the motor and tubing in there. After a little trial and error, I figured out the number of steps to move the knitting machine one stitch and ended up writing a few simple scripts that would advance the knitting machine in different ways. For instance here is my test script that advances a single stitch:
#!/usr/bin/python import time import board from adafruit_motorkit import MotorKit from adafruit_motor import stepper kit = MotorKit(i2c=board.I2C()) for i in range(54): # kit.stepper1.onestep(style=stepper.SINGLE,direction=stepper.BACKWARD) kit.stepper1.onestep(style=stepper.DOUBLE) # time.sleep(.01) #for i in range(864): # kit.stepper1.onestep(style=stepper.MICROSTEP,direction=stepper.BACKWARD) # kit.stepper1.onestep(style=stepper.MICROSTEP,direction=stepper.FORWARD) kit.stepper1.release()
Note all of the commented out sections. I experimented (and continue to experiment) with the different types of steps you can perform. The biggest challenge I found was trying to decide between the added stepper strength of double steps, or the more precise and quieter, but weaker microsteps. Also note that it takes a lot more microsteps to equal a single or double step.
Another aspect I experimented with was the amount of time to sleep between single or double steps. While microsteps didn't need a sleep function, without any sleeps during single or double steps the motor goes full speed and creates a violent and loud reaction when it cranks the knitting machine. This is useful when you want to trigger a full and fast rotation to simulate a full day of knitting, but is too much for normal operation. This is still an area I'm tinkering with in the final script.
Ultimately I found that the smaller stepper motor from my 3D printer was alternatively jamming and slipping inside of the aquarium tube more than I'd like. I ended up ordering a more powerful replacement stepper motor that had a flattened section on the motor shaft and created a new gear adapter to fit it, and that seemed to resolve most of the issues.
There was a point where I considered writing a script that would advance the machine one stitch, and then run that script hourly using cron. However, once I added button control to the design, it was clear I needed to manage the buttons at the very least with a daemon that started at boot, and ultimately decided to manage all functions within the same daemon.
This script is a work in progress, but is stored at
/usr/local/bin/knitting_clock_daemon.py. It runs in an infinite loop. First it checks the time and if it finds itself at the top of the hour, it will move the stepper forward. It divides the number of steps into segments so it can "chime" the hour, with a short sleep in between. Once it is finished moving, the script will sleep for 61 seconds to avoid the risk of triggering twice in an hour.
If you read the script you will see that I also have the motor move backwards first before moving forward. This is to attempt to prevent binding, which these cheap plastic machines sometimes want to do since there is a lack of precision in how they are machined. Moving backward briefly, and quickly, tends to reduce the risk of binding in my experience.
If it isn't the top of the hour, the script detects button presses from either of the two buttons and steps either forward or backward one stitch. It sleeps a small amount between each invocation of the loop so the CPU isn't busy, but you can still hold down one of the buttons and have it advance as you would expect.
Along with this script I created a simple systemd unit file at
/etc/systemd/system/knitting_clock_daemon.service to run it at each boot:
[Unit] Description=Start Knit Machine Controller Daemon Requires=basic.target After=basic.target rescue.service rescue.target [Service] Type=simple ExecStart=/usr/local/bin/knitting_clock_daemon.py Restart=on-failure [Install] WantedBy=multi-user.target
Once the unit file was in place, I ran
sudo systemctl daemon-reload; sudo systemctl enable knitting_clock_daemon to enable it at reboot.
Ultimately as I switched from a 48-hook to 22-hook knitting machine (more on that in the knitting machine section), I had to decide how to deal with the difference in hook count. With a 48-hook machine, performing a stitch every half hour to create a row per day, made perfect sense. With a 22-hook machine, there were a few ways I could go about dividing up the day in software.
With a 22-hook machine I first entertained the idea of knitting a panel (which means knitting backwards 24 stitches, then forward 24 stitches), instead of knitting in a circle. This was appealing at first because it solved the issue of dividing 22 hooks by 24 hours in a day. However panel knitting on a circular knitting machine, even without motor control, is risky. If you do not ensure that you move the precise distance back and forth each cycle, you will drop stitches and ruin the fabric.
Normally the knitting machine has you engage a "panel mode" with a switch, that will physically stop the machine from rotating past a particular point. As I removed the mechanism from the case, I no longer had this option and had to rely on the precision of the stepper motor. Stepper motors are precise, however these cheap plastic knitting machines have a tendency to bind every now and then. In those cases when going by hand, you simply power your way through (or move backwards briefly) when it binds.
Since my software couldn't detect binding, it wouldn't know when it dropped a stitch, so I decided to avoid the risk of it dropping a stitch at some point in the middle of the year, thereby ruining the fabric, by going with circular knit. With a circular knit, even if the machine binds, at worst it would simply be behind a stitch--something I could manually correct later.
Once I decided on circular knitting, I still had the problem of dividing 22 stitches into 24 hours. I was left with two main options. Option 1 was to figure out the number of stepper movements in a full rotation, divide it by 24, knit a single row each day. Option 2 was to do the same calculation, but divide by 12 instead. This would mean knitting twice as many rows per day, but would have the advantage of having the knitting machine rotate like a traditional clock. If I marked one of the "teeth" on the knitting machine, it could act as the hour hand on a traditional clock.
In the end, I was too enamored with the idea of the knitting machine functioning like a clock with only an hour hand, so I opted for option 2. I did experiment with advancing the machine a little bit every minute or two, so the hour hand would actually be rather accurate, but I found the small steps made it more likely the knitting machine would bind, so I abandoned it, at least for now.
I originally started the project with a Sentro 48-hook knitting machine. This matched the number of hooks in the original project and it makes sense as a clock. Since each row was made up of 48 stitches, you simply do a stitch every half hour. The original plan was to mount it to a sturdy backer board and then build a simple birdhouse-style wooden frame to cover it.
One goal with this project was to ensure any changes I made to the knitting machine were reversible. One benefit of this mounting approach was that I could keep the knitting machine inside its original case, only replacing its plastic legs with wooden dowels. It only took about two weeks since starting the project before I had mounted everything to the backer board. I just needed to spend a few hours making the top wooden cover and the project would be done.
It was only after looking at everything mounted to its backer board that my wife and I agreed that it was simply too large to mount on the wall. Technically it would work, but aesthetically it wouldn't. The 48-hook machine was out.
Fortunately Sentro also makes a 22-hook knitting machine that is not only much smaller, but also about half the price. At first I tried to figure out how best to mount it to a smaller wooden backer board, but its plastic case presented a problem. Unlike the larger machine that had openings all around, this smaller machine only opened perpendicularly from the crank. Since I intended the crank to be at the top of the machine (so I could more easily hide it in the "roof" of the case), the plastic frame would block the fabric. It had to go.
Removing the mechanism from its case was a simple matter of removing the hand crank (pull out the center plug and remove a screw) and removing the four screws that hold the case together. After I removed the mechanism I realized that it was actually so small that it would easily fit on the print bed of my 3D printer. I already had to figure out some sort of frame to mount the mechanism to my case, and realized 3D printing one might actually be an option.
Originally the case was intended to be made of wood, because the 48-hook Sentro knitting machine was too large for anything else. I switched to the 22-hook Sentro machine and realized 3D printing a case was an option. Of course there was a problem: I didn't know anything about 3D modeling. Yes I've owned 3D printers for over a decade at this point, but I had always used parts from Thingiverse or Printables that someone else designed.
I had created an parent account on Tinkercad a few weeks prior so my son could learn 3D modeling, and had even used my account to make simple modifications to existing designs, such as increasing the size of a hole in the motor mount for my Sentro machine. What started as a three- to four-week project now became a two month project as I had to teach myself 3D modeling with Tinkercad and iterate through case designs. The bottom case alone took two days to print, and I ended up printing it at least three times over the course of the project as I discovered flaws in my design.
I decided the best approach was to mount everything to a large bottom case. At the top I would have little slots where I could slide in the top cover to cover the knitting machine and electronics, and provide a little house-like roof at the top to mimic other wall clock designs I had seen (including the inspiration for this project). Ultimately the top was split into three different objects, which had a few benefits:
Designing the case was an iterative process of measuring things carefully with calipers, figuring out how to create my ideas using Tinkercad, and printing out small sections of the bottom case (in particular the circular mounting point for the knitting machine) to test my measurements.
I ended up printing the bottom case (a 2-day print job) three times. The first time I didn't notice that my button mounting section had a 1mm gap between it and the side of the case. The second bottom case fixed that, but ended up being a bit too tall, as I needed the top case to press pretty firmly against the top ring of the knitting machine to hold it in place. I didn't discover this until after the two-day print was complete, I had mounted everything, and then started work on the top case. It was OK though, as there were other less important modifications I had wanted to make anyway.
In addition to the case sections, I also needed to design a few smaller parts: plastic button covers, small clips that would hold a gear ring on the knitting machine to the case, standoffs to mount the Raspberry Pi, and a spool to hold the yarn. You can see the full set of 3D printed objects on the project's Printables page.
I tried to design this so that assembly was relatively simple and straightforward. This is the Bill of Materials:
Most of the parts are attached to the bottom case, and the top case then slides/snaps into place. While there isn't a strict order of operations here, it is easier to reach certain parts if others aren't installed, so I've tried to order these steps according to ease of access.
The first thing to install is the Raspberry Pi. You can see four holes on the back left-hand side of the bottom case (if the back is facing you). Install the Raspberry Pi using the M2x16 screws and nuts, and the 3D printed standoffs. I found it easiest to install it without the motor hat in place yet.
The next step is to install the Sentro 22-pin knitting machine. Align the knitting machine so that the area where the hand crank used to attach is facing the back of the bottom case. The bottom case has three holes that should line up with three mounting holes on the knitting machine itself.
Arrange the 3, 3D-printed short clips so that their hole on the bottom of each clip is lined up with the hole in the knitting machine. The top of the clip should rest above the gear ring. This clip serves to hold that ring in place when it moves, otherwise it has a tendency to jump the gear, especially if the machine is under any tension. Use the size 4 wood screws to screw through the clip, knitting machine, and into the bottom case. Try not to over-tighten, it's OK if there is a mm or so gap between the top of the short clip and the gear ring.
Attach the 3D-printed Sentro gear adapter to the stepper motor, and slide it through the large center hole in the back of the case so that it fits under the gear ring on the knitting machine. Arrange the stepper motor so that the wires aim downward, you will feed those through the half-circular hole at the very bottom of the case. Use the two M3x8mm screws to attach diagonal corners of the stepper motor to the case, or all four screws if you want to.
Feed the wires from the stepper motor through the half-circle hole at the bottom of the case, and then attach them to the appropriate points on the motor hat per Adafruit's instructions. Then you can attach the motor hat to the Raspberry Pi where it should stay in place.
The next step is to install the push buttons. The front of the bottom case has two slots with holes that run through the case. With this design, when the clock is mounted on the wall, the buttons will protrude through the bottom for easy access, especially when the clock is mounted high on the wall to make room for the scarf to hang from it.
The 3D printed button covers have a square section on one end. That is the back of the button cover. Locate the two button slots at the front of the case and the two holes that run through the case, and push each button cover through its corresponding hole, with the square end at the back. It will be somewhat tight fit at first, and you will want it to be somewhat loose so that the tiny bit of pressure that the buttons can exert back on the cover will be enough to push them back out. I found I had to push the button covers back and forth quite a few times to loosen things up enough.
Next route the two tactile buttons and their wires around the side and front of the case to the button slots. I aligned the buttons so that, when looking at the front, the button on the left moved the knitting machine clockwise, and the button on the right, counter-clockwise.
The slots are designed so that you can slide the buttons, wire-side up, buttons facing the button covers. There is a center bar that will stop the buttons from siding too far down the slot. Once the buttons are in place, confirm you can press the 3D-printed button covers and that they engage the tactile buttons. Then you can bend the wires back through the open slot and make things tidy.
At the back of the case on the side opposite of the Raspberry Pi you will find a series of slots. This is to mount an AC extension cord and the 5V and 9V power plugs so they can hang from the case. It is a bit of a tight fit but I was able to find an orientation that worked for my particular extension cord and power supplies.
Before you mount anything, locate the large square hole at the front of the case, near the buttons, and route the plug end of the extension cord through the hole. Be sure the extension cord you pick is long enough to reach from the wall where you intend to mount the clock to the AC outlet. I recommend a 3 meter or longer cord to be safe.
I used two sets of zip ties to secure the power supplies in place through the back slots. One set of zip ties went horizontally around the power supplies while the other went vertically, to ensure everything was secure. It was a little tricky to feed the zip ties around everything in that small space but I was eventually able to make it work.
With everything in place, I plugged in the clock and tested the buttons and confirmed everything still worked. Once the tests were complete, I went to work tidying up all of the wires so everything looked nice. Even though I knew it would be covered up with the top case, I still get quite a bit of joy from cable management.
The top case doesn't just serve a decorate purpose, without the top case on, you will not be able to test actual knitting. There is a pink ring that sits at the top of the knitting machine and contains inward-facing teeth that the machine uses to create the stitches. The original case had slots this ring slid into that prevented it from popping up, and the top case I designed serves the same purpose.
The top case is split into three pieces. I designed it this way so that I could print the top with a minimal amount of support material. In particular the 'A' section has a spool holder and yarn guides that extend in one dimension, while the 'C' piece that acts as the roof has the roof section extending in the opposite dimension.
The 'A' piece attaches first and holds the top ring of the knitting machine in place. It also features a post for the yarn spool as well as tension guides to feed the yarn into the machine. The 'B' piece acts as a name plate, and it also covers up the joint between the three pieces. The 'C' piece acts as a roof over the clock and covers up the stepper motor.
The top pieces are designed to fit and slide along a groove in the bottom case. Unfortunately you can't simply slide the 'A' section in place, because the knitting machine has a few hooks sticking up on the right side at 3 o'clock. Instead of sliding it on, you need to position the 'A' piece over the knitting machine at an angle and slide the side next to the hooks in place first. There should be just enough room so that you can have the front lip a centimeter or so in front of the corresponding groove in the bottom case. Then you can flex the bottom case on the left side just enough to fit the other side in the slot and then slide everything down the centimeter or two it needs to fit properly into the front groove. When properly seated it should be centered correctly over the knitting machine with both sides and front lips fit into their corresponding grooves.
Compared to the 'A' piece, the 'B' section of the top case is much easier to install. Simply line up the slots with the grooves and slide it in place. The nameplate is designd to cover up the seams between all three pieces so things look nicer. I also made a point when printing this piece to swap out black filament for the first layer that doesn't feature the Tempus Nectit impression so that the letters stand out more. I then switched back to white filament for the rest of the piece.
The 'C' piece comprises the rest of the front face and the roof that covers up the electronics and the stepper motor. It should slide into place like the 'B' piece with the nameplate covering up its seam. The roof sections should also hang over the sides of the bottom case, covering those seams.
After I first assembled this, I realized that I wanted one of the teeth in the pink circular rim of the knitting machine to represent the hour hand, so I removed the top case and covered the tooth with shiny metal foil tape and re-installed everything. If you wanted to do something similar you could also opt to paint one of the teeth instead, but I liked the idea of my changes being reversible.
With all of the top pieces in place, the assembly is complete! We can now move on to the initial setup and installation.
When setting this up for use, before mounting on the wall you want to cast on your yarn. First cast on with some waste yarn (white in my case) so that your actual project has nice ends.
To cast on you can follow the instructions included with the knitting machine, only using the buttons to advance the machine. Starting with the black hook, you weave the first row of yarn in and out, under the odd-numbered hooks and around the other back side of the even-numbered hooks. Then for the second row you run the yarn through the feeder at 3 o'clock, and through the tensioning holes set up to its right. Then rotate another full turn to have a full knitted row.
Note I noticed that the first couple of rows are under extra tension, more so than a few rows in, such that I actually found myself advancing the first rows manually by rotating the knitting machine's circle by hand until I could feel the tension let up and the machine less prone to binding.
Once the machine is rotating smoothly, cast on at least 10 or so rows of waste yarn and then get it back so that the black hook is at 3 o'clock, then cut the waste yarn and have its tail hang into the center of the circle, above the hook. Then put your project yarn on the other side of the hook (below), with 5-10 centimeters of tail hanging in the center, so that it will get picked up and knitting by the black hook when it advances. If this is hard to visualize, look for circular knitting machine instructions on how to switch yarn and use waste yarn to cast on.
At this point you can slip your cylinder of yarn on the 3D-printed spool and slide that onto the post on the front of the knitting machine. Plug it in and you are ready to go! In my case I decided to cover one of the teeth on that pink circular rim in shiny metal foil tape to represent the hour hand. Then I arranged it at 12 o'clock and advanced it one day at a time until I was caught up with the present day. Here is the script I used to simulate a day's worth of knitting, along with a video of the script in action:
#!/usr/bin/python import time import board from adafruit_motorkit import MotorKit from adafruit_motor import stepper kit = MotorKit(i2c=board.I2C()) steps = (2220) for i in range(steps): kit.stepper1.onestep(style=stepper.DOUBLE,direction=stepper.FORWARD) kit.stepper1.release()
Our plan for the clock is to knit a scarf that represents the current year. It will have a black background but significant days in the year (certain holidays, birthdays, anniversaries, family trips) will be marked with different colored yarn. That way when we remove the scarf at the end of the year, we will see different colored stripes marking special moments throughout the year.
If you look closely at the picture of the clock mounted on the wall, you can see a red stripe that represents Valentine's Day, and close to the beginning of the scarf, a thicker brown stripe that represents a road trip we took early in the year.
Thank you for making it this far in my deep dive into my Tempus Nectit knitting clock! This was a really gratifying project to work on as it was a cross section of so many of my interests. Now we have quite the conversation piece in our living room. Like every other wall clock I've had, I'm still tweaking it so that the hour hand is lined up properly after a full day's use. One benefit to having the machine match a 12-hour clock is that I can visually inspect it and correct if it ever jams and doesn't knit an hour, which hasn't happened yet.
And finally, here is a video of the completed project on the wall, chiming out 9 o'clock. I'm still experimenting with different sleep times in between steps, and between Double and Microsteps, to find the best balance between providing enough torque to avoid jams, without being too loud (it's a lot louder in the video with the camera close to the clock, than it seems when in the room). I'll be sure to update the daemon on this page once I settle on the sweet spot.
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Back to Index