Something I’ve wanted to do forever, and as part of a recent effort to use this blog more often, is add some last.fm data to my homepage. On the homepage now you should hopefully see a Music section, that features my top 3 tracks this week, and (if I am awake) the song I am listening to right now. I’m also sharing the code on here incase anyone else wants to do this. It’s pretty shit code, but for only an hour of work I think it’s fine :).
You’ll need an API Key, which you can get for free on this page.
const API_KEY = "YOUR API KEY HERE";
const USERNAME = "YOUR LASTFM USERNAME HERE";
function urlencode(obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
$(document).ready(function () {
function displayMusic() {
$("#music").show()
}
function lastfmRequest(method, params) {
params['api_key'] = API_KEY;
params['format'] = "json";
return fetch("https://ws.audioscrobbler.com/2.0/?method=" + method + "&" + urlencode(params) + "&format=json")
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
});
}
function getImage(trackinfo) {
return lastfmRequest("track.getInfo", { autocorrect: 1, track: trackinfo["name"], artist: trackinfo["artist"]["name"] })
.then((data) => {
try {
return data.track.album.image[1]["#text"];
} catch(e) {
throw new Error("No image found")
}
});
}
lastfmRequest("user.gettoptracks", { user: USERNAME, limit: "3", period: "7day" }).then((data) => {
var html = '<h3 class="colorchanger">Top This Week</h2>';
$.each(data.toptracks.track, function (i, item) {
const itemid = item.mbid;
html += '<div class="music-row">';
html += '<img id="' + itemid + '" src="' + item.image[1]["#text"] + '">';
html += '<div><a href="' + item.url + '" target="_blank">' + item.name + '</a> - ' + item.artist['name'] + '</div></div>';
getImage(item).then((img) => {
$("#" + itemid).attr("src", img);
});
});
displayMusic();
$('#listening-to').append(html);
});
lastfmRequest("user.getrecenttracks", { user: USERNAME, limit: 1 }).then((data) => {
console.log(data);
var item = data.recenttracks.track[0];
if (!item["@attr"] || !item["@attr"].nowplaying) {
return;
}
let html = '<h3 class="colorchanger">Now Playing</h2>';
const itemid = item.mbid;
html += '<div class="music-row">';
html += '<img id="' + itemid + '" src="' + item.image[1]["#text"] + '">';
html += '<div><a href="' + item.url + '" target="_blank">' + item.name + '</a> - ' + item.artist['#text'] + '</div></div>';
getImage({ name: item["name"], artist: { name: item["artist"]["#text"] } }).then((img) => {
$("#" + itemid).attr("src", img);
});
displayMusic();
$('#currently-playing').append(html);
});
});
If you end up adding this to your site please reach out :) mdl0394@gmail.com
There’s way too much to talk about when it comes to doing things (notably, there is a lot to do after the beginning). This essay isn’t going to cover all of that. The only thing I want to talk about today is how to start things. Arguably the hardest part, the moment in time right before doing something when you have to make some sort of conscious decision to turn your attention to it, to actually do it.
This whole essay started as one of my biggest pet peeves. It drives me absolutely nuts when people tell me they want to do something, but then give some reason why they can’t start quite yet. The Toolbox Fallacy is the classic example of this:
The Toolbox Fallacy is self-deception disguised as excuses or a lack of “tools”. The issue with these tools is that you believe that you need them and thus, can’t (or won’t) start a project without them.
but honestly, the obvious examples most people talk about aren’t the problem here. Those are obvious, commonplace; it’s easy to identify and point out when you are blocked by something like that. The really insidious ones always run a bit deeper, some justifications are hard to shake.
I am here to tell you:
Sometimes these excuses exist because you actually don’t want to do it.
Are you afraid that you might fail, that you might end up looking like a fool? Are you afraid it might not be what you think?
Sometimes we make these excuses because we don’t actually want to do something. Maybe we are afraid, we don’t actually have the energy, it’s just something that we literally can’t do. It’s always important to tear down our excuses to the root of their motivations. Do you really need to buy those climbing shoes, or are you just afraid to look stupid trying to climb in front of strangers? Fear is such a stupid reason not to do something. Sometimes fear exists for a reason, a learned response to a past trauma. But almost every time, it’s just not worth letting that stop you from trying.
Honest to god, just shut the fuck up. All you need to do is start doing it. The beginning is supposed to feel uncomfortable. You are supposed to want to make it work.
I like to use the metaphor of the line equation, y = mx + b. Every line is made up of two things: the y-intercept (b) and the slope (m). Everything you ever do will be made up of the same components. What matters more to you? Where you are today, or how fast you are getting better. I will be returning to this metaphor quite often, especially later when I write about how to actually get better at something. But for the purposes of this essay, the important thing to note is that on a long enough timeline (for large enough x), the y-intercept just doesn’t matter. It doesn’t matter where you start. The only two things that matter are that you do start, and that you try to get better.
Just get started.
My dear readers, thank you for making it this far with me. I hope something about this struck a chord. If it did, I swear to god, please reach out to me, I would love to know. My goal with these essays is to define a generalized process for getting stuff done, for pushing your will into the world, and making a difference. I am going to make a lot of assumptions about you as we go, I never intended to offend (however, sometimes I do try to spin a fine rhyme), my goal is not to tell you who you are, but to use my assumed persona of you as a common point of perspective that I can explain ideas from.
Here’s what I am promising for now. I will keep working on this. This essay will definitely change a lot, more will be added, embarassing things will be cut, new essays will be written. I am going to just start working on this, and eventually it will be finished.
I still wish for you on every eyelash
seeking calmer days a moment’s rest is broken by skull kid girl
slowly slipping away i’m begging it to stay but I need it to go
I worry for a second that we might not make it. I look up, we smile, and I realize how dumb that thought was.
warm midday slumber party it feels like we could spend an eternity just being us
almost done or maybe not whatever
if my life was a McDonalds order, I’d defintely order a small fry with it
it would be an honor to be woken up by your midnight stirrings
I can’t tell which one is the waiting when I am without you or when I am with you
the world keeps spinning the closer we are the slower it gets
The first time I met you I forgot how to imagine my life without you in it
bar lit lip biting our thick personal fog didn’t we just meet
first a blanket then a crack then nothing at all
Like the leaves and the wind. We need each other but we aren’t sure why.
All these books, but all I want to read is the story of us
My heart is full of holes one the shape of you cut into an unperfect whole the empty space just as meaninful as what remains i wonder each time what will convince me to let the next person take their piece Remember we are not just what is left but also what we have lost. We don’t exist only within ourselves but inside the ones who love the pieces we gave them
Not many people have really seen me. There’s not many who would care if I stopped, if I changed, if I didn’t try as hard, if I stopped loving this way, if my fire went out. You are one of the few who saw me for who I am. Who looked through and let me let you see the brilliance I hold in side. The parts of me I keep to myself because I know they’d use them against me. The confused, scary, loving, fearful, anxious and beautiful parts. I am scared that I lost you because I know what parts of me you take with you. I’m scared that I lost you because I know what parts of you I take with me. I’m scared that I lost you
Swimming without you I can remember how it felt Watching you try not to drink the salt water Listening to you ask me to marry you Water land is no fun on your own
The air is so thick I can feel it on my skin Unfortunately that reminds me of you The water is so cool but I am alone in it The water reminds me of you The wind in the trees sounds like your breath on my ear The cars on the street hold the smiles of happy couples holding hands Unfortunately they remind me of you I can’t stop reading a book I know you’ll love Unfortunately that reminds me of you My hands feel empty my heart so fucking heavy Unfortunately that reminds me of you
though it’s quiet out i hear your voice on the wind always
she was the waves and i was the beach
parking next to me metaphorically and literally waiting for you to come back
pretending not to care but i can still smell you
she’s something lovely it’s so bright outside despite the gloom
pull back the haze make me who I want to be not who I am
I’ll be asleep before the food gets here Never done this first time for it She hums while we wait for it to pass through Its just the life we live not fair
lately I been feeling like a middle child forced to be creative for attention
metaphorically me ta phor ic al ly
maybe not forever but definitely today as long as possible
Marry me, marry me We’ll buy a house in the country With a porch 3 kids and a dog We will sell furniture, yarn And maybe video blog about it from everything I know about you and everything I will learn you’re the most beautiful person I’ve ever met have a happy 27th year happy birthday love Mike
maybe not forever but definitely today as long as possible
You know this already My heart is yours to break Godamnit Yankee
Well I don’t really know what to say I’ve only really known you for 3 months But it’s felt like so much longer
midnights, cigarettes awful ideas behind brown eyes godamnit yankee
midnights, cigarettes stupid jokes with new friends drinking with yankee
brown eyes, big smile pizza desperate for more
morning cold burning into warmer days
complex headaches relive last night slowly the joyful coaster
do i want to know drunk me avoiding drunk you crave quiet places
another drunk text not sure i will ever learn crave quiet places
can help but hear it space between your sentences crave quiet places
could talk forever maybe someday we’ll run out then what
bent never broken goodnight sleep well i love you everyday always
fallen but we grew i really love you for life seven years always
]]>I am desperately looking for people outside of the engineering industry who are passionate about anything other than engineering, I’d love to just chat and gain some of your perspective. Maybe we can build something cool together
Email me at mdl0394@gmail.com if you want to chat or have advice
]]>Whenever we break some functionality out into its own method or function, we need to decide where in the file will that method or function be placed. For small projects it often doesn’t really matter, but as a codebase grows, unorganized files can become difficult for new team members to grok. Unwieldy files can really slow down new developers onboarding when they are trying to become accustomed to your project.
There are several ways to stop files from becoming organized, this post will focus on how we can order the functions within a file to make that file easier to grok. I plan to write a few more posts on the issue of file organization, specifically around the questions of “What should be a function” and “What should be a file”, if you are interested in those, subscribe to be notified when they are published.
So, how do we order the functions in our files to maintain the core pillars of consistency and scalability? Like with most standards, the rules almost don’t matter, it’s the having of rules and standards that matters. In this post I will lay out my personal preferences, and the rules that I have found to be the most logically valid (as in, they break under the least cases allowing you to maintain consistency when possible).
The core of the function ordering system I will go over in this post uses what I’ll call the “function call tree”.
A good mental model for functions in a file is a tree structure. In general you will have some root nodes that are “entrypoints” into your file. These could be exported functions, main functions, or whatever else. These entrypoints will call some other functions, that may call some other functions, etc, etc. This graph of function calls represents the function call tree.
Here’s a toy example. This code:
function A() {
B()
C()
}
function B() {
D()
}
function C() {}
function E() {}
Could be loosely represented as this tree:
myfile.js
├─ A
│ ├─ B
│ ├─ D
│ │ ├─ C
│
├─ E
This tree structure represents the first rule. Functions should always be ordered according to the function call tree.
A function should always be grouped with its leafs, and should be defined before any of its branch/leaf functions. If a branch has it’s own branches (like in the case of B()
calling D()
above) it should be defined before the next branch (D()
should be defined before C()
)
As an aside. My personal preference, and the preference of a lot of developers, is to use what I’ll call the “reverse call tree”. This is exactly the same principle as the standard tree, except leaf nodes are defined before their callers. It can be helpful to identify if a file is in standard or reverse tree structure, as it will help you grok the file much faster.
The reverse tree of the above code would look like this. All functions are defined before they are used:
myfile.js
├─ E
│
│ ├─ B
│ │ ├─ C
│ ├─ D
├─ A
Fun fact: This is a hold-over from the days of single pass compilers, where the compiler would only read a file once, and you were required to define a function before it was called.
It doesn’t really matter if you choose to use the standard or reverse tree structure. What matters is that you choose one of the two and stick with it.
This rule was implied above, but in the spirit of writing the unwritten, I will cement it here.
Functions that are the same depth, should be sorted in the order that they are called. The above definition would be invalid if C()
was defined before D()
function A() {
B()
C()
}
// ❌ Bad: C() should be after B() because it is called after B
function C() {}
function B() {
D()
}
function E() {}
Even in the reverse-tree discussed above. Functions of the same tree depth should be ordered in the order they are called (not reversed).
One common case that easily breaks the above rules, is if a function is being used by multiple functions in the file. In this scenario, I prefer to make shared functions their own tree root, and sort them after (or before when reversed) they are called.
function A() {
C()
}
function B() {
C()
}
function C() {}
The function call tree would be flat, because they are all root nodes:
myfile.js
├─ A
│
├─ B
│
├─ C
If you have any feedback on the rules I laid out here, I would love to hear it. What has worked for you in the past? Do you know of any linters that can verify these rules so I don’t have to complain about them in PR? Feel free to reach out directly to me: mdl0394@gmail.com
I have more UCS posts in the works, planned for the coming months. If you are interested in getting notified sign up to my mailing list or RSS feeds.
If you liked this post and want to join a fast growing team at a rocketship company, my team at Verkada is hiring rapidly. We’re hiring virtually all kinds of engineers, email me directly at mike.lyons@verkada.com and I’ll connect you with the right person.
This is a running series on stay caffienated, if you enjoyed this you might also enjoy:
Lately I’ve been learning to play guitar. I wanted to be able to try out a bunch of different pickups on my guitar, to get a feel for what sound I prefer. However, the only guitars on the market with hot swappable pickups are made by Relish Guitars and their cheapest guitar is $4800, a bit outside of my price range. I decided to build my own, because "how hard could it be™"
Before jumping into any design I like to throw together some requirements. In order to stop this project from growing too much, I gave my self the following limitations & requirements:
The relish guitar system uses 4 magnets to attach the pickups to the guitar body. It’s hard to find good images of this online, but the best I can tell they avoid any magnetic interference by keeping the magnets pretty far from the pickup. I believe I will be able to use a similar magnetic system in my designs.
The wonderful site GuitarFetish makes a solderless pickup connect system). This will be the simplest way to plug the pickups into my guitar electronics. I’d like to avoid making my own connection system on top of everything else.
On every electric guitar, the pickups have dampening springs. From trolling online guitar forums, it sounds like these are pretty important for dampening some vibrations from affecting the pickup. In my design, I will be sure incorporate similar springs.
Like with most projects, I tried to start at the most unsure / hardest part of the design first, and did my best to validate it fully before moving on. The most novel part of this project is definitely the removable pickups, so I started there.
The system I designed consists of 3 different precisely cut holes in the wood, and two 3D printed pieces (one that attaches to the pickup, and one to the guitar). The holes were designed to be cut with a handheld trim router (that’s all I have).
Here you can see the pickup and 3d printed parts. I chose to 3d print the guitar-side attachment as well to reduce the coupling in the design. This way if I need to re-design the attachment method, I can easily 3d print a new part, and not have to cut into the wood. In the animation, the black piece is attached to the guitar, and the red piece is attached to the pickup. The two pieces are held together by magnets when the pickup is inserted.
The wood side of the project is 3 different depths of cut. The front most cut (smallest hole) is the most precise by far as I want this to fit pretty precisely to the pickups. For this cut I will be doing a lot of sanding for finish to make sure it’s very precise.
My favorite part of having a 3d printer is how fast I can prototype parts. For this part I designed and printed 5 iterations of the mechanism before I was satisfied. The biggest challenge here was figuring out how big I needed the holes to be, and finding the smallest size magnet that would work.
Once I figured out the design, the next challenge was figuring out how the hell I was going to router it into the wood. This is a technique I figured out on my own, I am surprised I don’t see more woodworkers online doing this. It was very easy to 3d print the exact templates I needed for this project, pictured below.
Using the above templates from left to right gives you a very precise cut of my design.
Naturally, I prototyped and tested this cut many many times before I was sure that it would work. The biggest challenge with this design is that the corner radius on the front cut is too small for my router. On the final cut it took quite a lot of hand filing to get it to size.
As this is my first guitar, I started with the easiest design to cut, the Telecaster (or T-Type if you are scared of trademarks). I bought a wooden router template off ebay, and whipped up a design in fusion-360 so I had measurements to guide my cuts. Here is the final design:
Definitely the hardest part of this project, but also the least interesting for a blog post. Instead of boring you with the details I’ll just show a bunch of photos of the process. I ended up relying pretty heavily on 3d printing templates in this build, as they were a great way to print precise dimensions for measurement.
This project probably took me around 200 hours to complete, but was a huge joy to work on. I spend most of my day staring at a computer screen so it was great to build something with my hands for a change.
There are a few things I will do differently next time I build a guitar:
As with all my projects, if you are interested in any of my design files or want to chat about anything at all, feel free to reach out to me directly at mdl0394@gmail.com. If you want to hear about future projects subscribe to my mailing list or RSS feed.
My next posts will be about my processes for solving problems like these through writing, and building my own custom guitar pedal, so subscribe if you want to read more.
If you liked this post, you can also check out some other things I made here:
Once the schematic is complete, or mostly complete, we can move over to the board layout and start physically designing our PCB.
When you first open your layout, you will be presented with something like this
There’s a lot of stuff going on on this screen, here’s a quick list of what’s on screen:
PCB manufacturing has a bunch of physical constraints that limit various parts of your layout. These are things like minimum size of a trace or minimum distance between traces. A lot of the time they will provide a list of constraints, so check your manufacturer’s website for some instructions. In this guide I will use safe rules that have worked for every manufacturer I have ever used.
The most important setting is your trace width and clearance, these are controlled in Eagle using “Net Classes”. You should set the defaults to good values before you begin layout routing to simplify things down the line.
Select the “Net Classes…” option from the Edit menu in Eagle. On the left menu you will see a list of all of your net classes, and on the right you will see what nets are part of that net class. Click the “Add” button and add a “power” net class. Add all of your power lines (3V3, …) to this net class, we will set the rules for this class to use slightly wider traces for safety.
Select the rules tab, and then set your rules to what I have in the image above. Generally I use ~10mil traces for signal and ~20mil traces for power. These can vary, and will depend a lot on your manufacturer and your application. I have found these defaults to be fine for most common applications. I have also set the clearances to 3mil and 5mil, these are chosen to be much higher than the manufacturer minimum, feel free to modify them as you see fit but make sure you stay within your manufacturers constraints.
Once you have set up your net classes click OK to continue to the Placement and Routing portion of our tour.
First step is to place all of your components on to the PCB. Generally I start with any physical constraints I have, in this case I want the ESP32 to be on the edge of the board so I can plug in the USB, so I will place that first. I will then place the other components.
A good tip for simplifying things down the road is to try to avoid the yellow air wires crossing whenever possible. Generally the simpler the air wires, the simpler trace routing will be.
So start with the largest component and work your way to the smallest component. Your goal here is to keep the air-wires as clean as possible while utilizing as little space as you can. If you have GPIO air-wires that you can’t uncross it’s often a good idea to go back into the schematic file and swap the pins. The simpler you can make your layout the easier the next step will be.
Here is how my example ended up when I was finished layout:
Once you get a majority of your components placed within the outline, you can resize your outline to fit your components. This step is important, if you don’t resize your outline your boards will come back huge.
You can resize the outline by clicking on the yellow line, this will begin moving it, moving your cursor to your target position, and clicking again to stop moving. In my example I shrunk the outline to just contain the parts.
PCBs can contain many layers of routing. A layer is a single plane on which you can draw traces. Traces on two different layers will not collide with each other, allowing you to cross traces. The standard (and cheapest) option is to use a Two layer board. On a two layer board you will have traces on both the Top and Bottom of the board. By default your PCB Layout in Eagle should be two layers. You can view the layers by clicking the “Layers” dropdown in the top left.
If you can not solve (connect all your nets) your layout cleanly with two layers, consider re-arranging the parts and pins, as it’s much cheaper than adding more layers to your board.
Before we route all of our signal traces, we should draw our ground planes. In most scenarios we will use traces (lines) to connect the power and signal nets together, however we will use planes to connect the ground nets. Ground planes are designed to reduce noise in your PCB, and also simplify routing (since almost every component needs to connect to ground, it makes it easier to do them all in bulk).
Creating a ground plane in Eagle is easy. Select the layer you want to draw on using the Layer dropdown, choose the polygon tool from the left and draw a box around your board. Draw the ground plan larger than your board outline to ensure that the plane covers your entire board.
Do this once for each layer on your board (Top and Bottom). You can switch layers using the Layer dropdown. When you are finished you should have two rectangles, one red and one blue, around the outside of your board.
Just drawing the ground plane will not “Pour” the ground plane. If you want to see what traces the ground plane will draw, press the Ratsnest button.
You can undo the pour by selecting the Ripup tool from the left pane, and then selecting “all visible polygons” from the top menu. You will want to do this before continuing as it’s difficult to route while the ground planes are visible.
Note how there are connections to your GND pins (they look like little pluses on those pins), but no other pins. If you do not see connections to your ground pins, rip up the ground planes, select the “Info” tool from the left menu, click on the outline of your plane, and make sure the signal name is set to GND.
The last thing we need to do before moving on to signal routing, is add some vias between our two ground planes. As it stands our two planes are very poorly connected (only connected via the through hole pins). We add some vias to increase their connectivity, and make routing a bit simpler later.
To add a via select the via tool, change the drill size to something around 20, and click to add a single via to your PCB. Important after adding a via to your board, select the Info tool from the left, click on your via, and change the Signal Name to GND, otherwise it will not connect anything!
You’ll want to place these vias out of the way, probably around the edge of your parts. We want at least a handful of vias on our board. After creating the first one, it’s easiest to use the Copy tool to create a bunch more, this allow you to skip the Info → Signal Name step on every via.
Here you can see my finished board with 9 ground vias. Feel free to add as many as you’d like, just make sure you have them in a bunch of places to simplify routing later. Before you continue, use the Ratsnest button to pour your ground planes and make sure that the vias are touching the planes.
Eagle provides a great tool for simple PCBs like this, known as the auto router. For most simple projects this will provide a reasonable solution to routing and is the easiest way to get your board out the door.
To start the autorouter, ripup your ground planes (instruction above), choose Autorouter from the left menu, click Continue on the prompt, and then click Start. Generally I will leave the settings at default, if you aren’t getting good results you can change the Effort to High which can help.
Once all of the variants have completed, you can click through the options and see how they look on your board. In general I try to optimize for the fewest “Vias” although this is not a hard and fast rule. If none of your variants are able to complete, that normally means your layout is not solvable (at least in a simple way) and you may want to consider re-organizing your layout.
To finish, select the variant you prefer, and hit End Job. You will need to ripup and re-pour your ground planes after selecting your route. If you are satisfied with your layout feel free to go on to section 5 about exporting and order. In the next section I will cover the basics of manual routing but you often won’t need them for simple boards.
A lot of EE professionals will tell you to never trust the auto-router. In general the auto-router is a great tool to speed up simple projects, but it can definitely make mistakes and knowing how to route yourself is important.
In general your goal in routing is to connect all of the yellow “Air Wires” using traces. In practice this boils down to a core loop of: Select the Layer you want to route on, select the Route Airwire tool, choose a pin, draw trace to another pin, select the other pin. You do this over and over until you have a completed design.
If at any point you need to cross two traces, you can use a Via. A via will connect two layers together. The manufacturer will drill a hole in your board and plate the via with metal to connect the two layers together, allowing you to route traces.
Placing a via is very easy. While you are actively routing, change layers using the Layers dropdown on the top left, and it will automatically give you a via at the end of your trace. Clicking will swap layers and allow you to continue routing on the other side of the board.
Once you have connected every trace (removing all yellow air-wires) continue to the next step.
Now we have completed our board, let’s move on to board validation, exporting and ordering.
Eagle provides two great automatic checkers to help you avoid problems with your board. These are called ERC “Electrical Rule Check” and DRC “Design Rule Check”. These dialogue can be opened from the tool menu on the bottom.
ERC will warn you about issues with your schematic. You can see below it is warning me that I only have one pin on my SDC net. In general you should have No Errors or Warnings before continuing. If you truly believe something is fine, click “Approve” to ignore it.
DRC will check your layout for any errors. This is where you can load your design rules in from your manufacturer. I generally don’t bother as the default rules have always worked fine for me.
If everything is fine when you press “Check” the menu will disappear, but on the bottom left you will see “No DRC Errors”
Once you sort out any errors with ERC/DRC, move on to manual checking and exporting.
It is very very easy to make a mistake while designing and laying out you board. I always try to take a break and come back to the board with a fresh brain in order to be extra sure there aren’t mistakes in my layout. If you have a friend who knows this stuff it’s a great idea to ask them to review for you as well.
Things to check (that I have definitely forgotten to check before)
Once you have completed your validation you can export it for uploading to the manufacturer. To do this select Manufacturing from the right side, and click “Cam…”. This will bring up the CAM dialogue.
On the CAM… dialogue you shouldn’t need to modify any of the settings, just select “Export as Zip” from the top and then Process Job from the bottom right. This will create a zip file that you can upload to your PCB manufacturer. Save this somewhere you can find it for the next step.
Now comes the fun part, ordering the PCBs. There are a ton of cheap board fabs out there so it’s up to you which to use, they all work basically the same way: First you upload your board, then they review and create the PCBs, then you get your PCBs in about a week.
My fab of choice is Seeedstudios Fusion PCB. I have found their turnaround time to be great, and their prices low. There are definitely others out there: dirtypcb and jlcpcb are also great choices.
This guide will use seeed, to buy board from them use this link
On Seeed it’s extremely easy to order boards. Click the Add Gerber Files and upload that Zip archive we made in the previous step. Change the PCB dimensions to match the outline size you made earlier (you can use the Info tool in the layout to find the exact size). Don’t worry about getting the dimensions exact as they will use the gerber files to get the exactly right size
Leaving most of the settings on default is almost always fine, I normally change my PCB color to something cooler than Green, but that’s up to you. When you are finished hit “Add to Cart” and buy your PCBs!
Generally you can get 10 PCBs for about $20 ($5 + the cost of shipping from China). I suggest starting pretty small and then buying more after you validate, from my experience, there is a 99% chance you will want to make modifications to this first design.
Congratulations. You just made your first PCB. Please reach out to let me know how it went, I am always happy to answer any questions or chat projects. mdl0394@gmail.com
Before you build a PCB you should already have all of the breakout boards & devkits you want to use for the project. When designing the motherboard you should already have a good understanding of how the electronics components are wired together, if you don’t it’s easy to make costly mistakes.
For this project I will be using my Caffstat (Hackable Smart Home Thermostat) project. If you are interested in a smart home thermostat feel free to check out that project here.
This project contains 3 different breakout boards and a few through hole components. The brains of the operation are an ESP32 Devkit, there are breakouts for the Thermostat and Screen, and through hold components for the buttons, resistors, and relays.
For this tutorial I will we be using Eagle. It’s got a free tier tool that, and it integrates well into the Autodesk suite. Eagle is free for up to two layer boards, which should be all you need for most electronics projects. The information here will be pretty generally applicable to any tool, although the screenshots will be of eagle specifically.
You can download eagle for free here
A PCB Design contains two main parts, the schematic and the layout. The schematic is an abstract diagram of the connections between components in your project, and the layout is the actual physical layout of those components, and the electrical traces that connect them. The great thing about PCB design software, is that the schematic will be enforced when you are creating the layout, this makes it very straight forward to create the layout after you’ve created the schematic.
This is the completed schematic for the caffstat project. You can see all of the breakout boards as individual components (red). The connections between them are mostly being managed by net labels to simplify the schematic (more on this later).
Here is an image of the completed layout. Every component has found a space on the board, and all of the electrical traces have been drawn. Don’t worry if it looks complicated/messy now, when we go step by step it will be very easy to create.
Before you can begin drawing a schematic and layout, you need to find or create models for each and every one of your components. A device model contains both a symbol for part (goes in the schematic) and a footprint of the part (for the layout). I will list out some great resources for finding or creating these here. I can create a full tutorial for creating your own component models if you are interested, let me know at mdl0394@gmail.com
One thing to note is that Eagle comes pre-packaged with a bunch of common components. These are mostly things like standard resistors/capacitors. It’s worth checking the pre-installed library before spending too much time scouring the internet. The easiest way to check the library is to use the “Add Part” button discussed in section 3.2 of this tutorial.
The best tool I have found for looking up components and downloading models is Octopart. Their mission is to provide the best search engine for electronics components. Almost every part can be found in the search engine, I always check here first.
If octopart has the CAD Model for your part, it will appear like this, you want to download the Eagle format, this will download the library that you can install later.
I have also found quite a few schematics by just googling the part. It can often be helpful to try different variations on the name, and include the term “Eagle” or “.lbr” (Eagle library file extension) in your query. If you do find a schematic, make sure you do some measurements (you can do this on the layout of your design) to ensure it matches well with your part (sometimes people upload bad designs, or are modeling something slightly different than yours, you don’t want to order a PCB with bad footprints)
Once you have a library it’s easy to install, drag the Library (.lbr) file into the libraries
section of the Eagle Control Panel. Important: after dragging the lbr file, make sure you right click and hit “Use” otherwise you won’t actually be able to add it to your project. Libraries in use will have a green dot next to them
If you fail to find any schematics online (often the case with cheap breakout boards, or with chinese knockoffs) you might have to make your own. It’s not too hard to make your own models, mostly just a little bit tedious. Creating your own models & libraries is a full tutorial in itself, if I get interest I can put that together, for now I will refer you to the resources I used to learn the process.
A good tutorial on how to make custom eagle components can be found here: https://www.build-electronic-circuits.com/eagle-components/
Once you have your components, you can start creating your schematic.
First thing is to make a new Project and new Schematic in eagle. Go into the projects section, right click and hit “New Project”. Then right click and hit “New Schematic”. Once the schematic opens, you also want to create a layout (We’ll use this in Step 4). Do this by hitting the “Generate/Switch to Board” button on the top bar.
Once you have a schematic you need to put all of your part symbols on. The add part button is on the left bar, clicking this will bring up a dialogue that lets you choose a component. If you don’t see a component you installed here, go back to the control panel and make sure you selected “Use” on the right click menu.
Add all of your components to your schematic. Make sure you give yourself a bunch of room around components to create connections. You should also try to sort the parts in logical groupings, the simpler your schematic, the less likely-hood of bugs.
While placing components there are a few useful tools at your disposal. The Move, Rotate and Copy tools at the top of the left panel are all useful for organizing your schematic. When you want to select an object, the easiest thing to do is to click the + symbol (probably either at the center, or the origin of the part).
Here is what my schematic looks like after I have placed all of my parts.
The standard for schematics is to use a specialty component to label the shared ground. You can find this by searching “gnd” in the Add Part menu.
I will usually place one of these per component, just off the bottom of the component, and wire them to the ground pin.
You can directly connect parts together using the “Net” tool (Green line) however with more than a few parts, this will very quickly become unmanageable. Instead of doing that, I will show you how to use labels to cleanly connect parts together. Note that for some components I will not use labels for connections, this makes sense for analog circuits, or things like pull down resistors because they can be logically grouped together.
For every node that I want to connect, I will first draw a one or two unit Net. Like so:
Then using the “Name” tool I will name all of the new nets something that makes them easier to keep track of. To name a net, select the tool, then select the green line for the net, a text dialogue should pop up asking you for a name, you can then give the net a unique name, make sure that “Place Label” is checked, and click OK.
Name Tool
The first label you make probably won’t have the “Xref On” option selected (looks like a little tag symbol on the toolbar). Selecting this will clean up your diagram a bit. I also prefer to set my size to 0.05 so that tags can be neatly stacked on top of each other. You can also use the mirror options to make a left or right side label.
If you want to connect two different nodes together then you should label them the same thing. When you do this Eagle will pop up and ask you if you want to connect the two nets together. Click yes and Eagle will now know that you want those two pins to be on the same net (they will be electrically connected on your layout) .
Once you have all of your components connected properly on the schematic, it’s time to do a final review before moving on to
After wiring all of the components together, I will take a moment to review. Here is the completed schematic diagram for my thermostat motherboard. Before moving on to layout I like to rubber-duck (literally say out loud) the different connections to make sure I didn’t make any stupid mistakes.
In Part 2 I will cover: Board layout, design rules, PCB ordering, and 3d model export. Part 2 will be available in a couple of weeks, subscribe to be notified when it’s posted.
I’ve posted several previous blog posts journaling the progress of this project, check out those posts here: here
Key features include:
For the beta version, the product will still have a few limitations:
The Beta version ships in early 2021, I am only selling a few of these boards as a test run, so get your order in quick if you are interested.
If you are interested in getting updates on the progress of the project, feel free to reach out to me directly at mdl0394@gmail.com or subscribe to my email list.