Spring has finally sprung in Toronto, and this weekend it is the Easter holiday.
We will be closed on Friday April 19 and back in the office on Monday April 22.
Canada Post will not be delivering or picking up on April 19 or Monday April 22.
UPS will not be delivering or picking up on Friday April 19.
For our local Toronto customers:
We hope you have a nice long weekend!
Today we received our 10,000th order! Thank you to all our customers for making our business possible. We cannot possibly express how much we appreciate your business.
We are pleased to announce that we have partnered with Route to offer shipping insurance for our customers!
This is completely optional- please feel free to opt out if you do not want the insurance.
The process is pretty simple. For $1.82 on a $100 or less order, Route will insure your shipment end to end. Above $100, the premium will increase proportionate to the order size. If there are any problems, submit a claim to Route and your order will be refunded or replaced. Route is backed by Lloyds of London.
If you have any questions or concerns, please let us know!
In our first installment, you learned how we put together our Raspberry Pi-powered Mechanical Speedometer, now we will share how the device works.
First, a bit about the Adafruit Motor HAT. This is a great add-on board for the Pi, and it allows you to control up to 4 regular motors. You have to solder the headers to the HAT which takes a few minutes. The HAT should be powered separate from the Pi, and the HAT can take 5V to 12V. The HAT does not have a barrel jack connector, but you can use an adapter and some wire. In our case, we ran the HAT at 5V because our Beefy Hobby Motor drove the speedometer quite well with 5V.
In classic Adafruit fashion, they have an excellent tutorial for the Motor HAT, as well as an easy to use Python library. The library is in Python 3, and you install it with the following command:
sudo pip3 install adafruit-circuitpython-motorkit
Now we'll step you through our code.
First, we import all the libraries we need:
kit = MotorKit()
We like using databases to handle data in any setting, so we are using a database to track the orders on our Odometer Pi. This simple database tracks the orders numbers, so we know when a new order has arrived. We create a database if it does not exist, keeping the order number as a unique integer. We then select the largest order number from the database, which we will use later on when we compare to the "new" largest order number.
CREATE TABLE IF NOT EXISTS Orders (
order_num INT UNIQUE,
cur.execute('SELECT MAX(order_num) FROM Orders')
order_max_list = cur.fetchone()
start_max_order = order_max_list
Here we are establishing input_orders as the URL we'll use to obtain the JSON file of our latest orders. Replace your_api_key and "your_store" as appropriate. We then create a request with the URL and parse the JSON data with r.json()
input_orders = "https://your_api_key@your_store.myshopify.com/admin/orders.json?limit=250"
r = requests.get(input_orders)
data_orders = r.json()
In this block of code we are pulling useful information out of the JSON file. In the world of Shopify, the order number is a string called "name", so we have to parse out the numeric portion. We then insert the new orders into the database, if applicable. With the "INSERT OR IGNORE" statement, it will only insert new data if the latest order number is different from all the other order numbers, since order_number is a "unique" item in our database schema.
for item_order in data_orders["orders"]:
this_order_str = item_order["name"]
this_order_number = int(this_order_str[1:6])
cur.execute('''INSERT OR IGNORE INTO Orders (order_num, order_num_str) VALUES ( ?, ?)''', (this_order_number, this_order_str))
After we have updated the the database with any new entries, we do another check of the database to get the largest number:
cur.execute('SELECT MAX(order_num) FROM Orders')
order_max_list = cur.fetchone()
end_max_order = order_max_list
In this block of code, we are checking the "ending max order" against the "starting max order". If the ending number is greater, we calculate how many new orders with the variable "increment". We then print to the screen that we are incrementing the odometer.
Through trial and error, we have determined that running the motor 10.5 seconds at 100% throttle will increase the odometer by 0.1 miles, or for us, 1 order. So we run the motor at 100%, pause code execution for 10.5 seconds with time.sleep, and then turn off the motor.
If no new orders came in, we print a message to the console.
if (end_max_order > start_max_order):
For our program to run automatically, we add it as a Cron job. To do this, we edit our crontab with the following command:
We then add the following line to our crontab, which causes our script to run every 2 minutes and then appends the text output to a log file.
*/2 * * * * python3 /home/pi/odo_order.py >> /home/pi/cron.log 2>&1
This was a super fun project for me, as it combines an old mechanical part with my favourite single board computer, the Raspberry Pi. If you are interested in learning Python, I highly recommend Dr. Charles Severance's excellent Python for Everybody Specialization from the University of Michigan via Coursera. I personally did the entire specialization, and it has been priceless as we have built a bunch of Python scripts to help run our business.
Finally, here is the end result in action:
And here's what happens when we get an order, now shipping order 9366:
Mechanical things are so satisfying. We love taking an old piece of equipment and making it work with products we sell.
Back in the day, speedometers were driven by spinning cables. These cables would typically run from the transmission via a flexible steel cable in a sheath to the speedometer. Ever been in an older car where the speedometer bounces? That is usually because the speedometer cable is about to fail.
We have been looking for interesting ways to represent data, and we were thinking it would be fun to use an old odometer to show how many orders we have received. To do this, we would need an old speedometer/odometer assembly, a motor, a way to drive the motor, and a way to couple the motor to the speedometer.
We found an old speedometer on Kijiji for $10 and verified that the odometer worked. The odometer came with 1/10 of a mile on it! We believe it came off an exercise bike...which must have collected a lot of dust! On the back of the speedometer, there is an input shaft with a square hole in it. To drive the speedometer, you just spin the input shaft. To test a speedometer, you can use a drill.
Now we had to find a way to drive the speedometer. It turns out that our Beefy Hobby Motors work really well for this application. At first we just took the input shaft and wrapped some tape around it. This sort of worked, but it was clear we would need something better, as there was a lot of slippage. We needed this thing to be precise!
Fortunately, we were able to find a speedometer cable repair kit on Amazon! With this, we got the cable with a square end on it. We were able to cut the cable with heavy duty wire cutters and put one end of it into a shaft coupler. The coupler attached to our Beefy Hobby Motor, and the other end of the cable went into the speedometer.
Everything worked great, but we needed a project enclosure. Since we have a thing for laser cut boxes, we made a 78x78x70mm box out of 3mm birch plywood and added cutouts for the speedometer, motor, and a mounting point for a Raspberry Pi. As always, we used MakerCase to lay out the case, and then added in the required holes via Inkscape.
Here are some pictures showing the box layout and the parts. In the layout, the piece floating in the lower left is the removable top.
And here are some pictures of the finished device:
Here's an overview of all the exciting new options.
Two new on board WiFi options from Arduino Foundation !
SparkFunProtoSnap uses Alligator clips to easily connect components to Micro:Bit.
New Vendors !
We are please to now offer Good Foot courier service within Toronto area.
Good Foot is a courier service that helps provide meaningful work to people with development disabilities. Their prices are reasonable and the service is excellent. We did a recent delivery to the King and University area, and our cost was $20+ HST. The courier picked up the order at 1:00 and delivered it by 4:30.
Right now we do not have a way to quote Good Foot service online, but if you are in Toronto, relatively close to the TTC, and you need your order today, give us a call at 647-794-4783 and we can setup the order for you over the phone! Please note that same day service only applies to order placed by 1:00.