<![CDATA[Caden Kraft]]>https://cadenkraft.com/https://cadenkraft.com/favicon.webpCaden Krafthttps://cadenkraft.com/Ghost 5.79Sun, 03 Mar 2024 05:59:55 GMT60<![CDATA[3D Printed Dual Cycloidal Actuator]]>https://cadenkraft.com/3d-printed-dual-cycloidal-actuator/65d922ddf6e4040001065708Fri, 23 Feb 2024 00:57:43 GMT

This project is a continuation of my previous axial flux motor project. If you've not yet read that I would recommend doing so.

Ironless Axial Flux Motor
After my first custom brushless motor I felt confident enough with the basic theory of how they work to make a second design with significantly more thought and math defining the design. Creating a 3D Printed Brushless MotorWith my work in the Iowa State Solar Car club I have learned
3D Printed Dual Cycloidal Actuator

After I was finished with making my last motor project I was quite proud of the results. However, while the motor could achieve extremely high RPM's, this came at the cost of torque.

Originally I thought about rewinding the stator and possible improvements via stronger magnets and/or Iron based 3D printer filament for the stator coils among other things.

Deciding on a Gearbox

Wanting to work on something a little more different than pure motor design and not wanting to rewind any coils, I set my sights on developing a gearbox that could be integrated into my current stator design. There were 3 primary options that I was looking into when deciding what gearbox that I was going to make, Planetary, Cycloidal, and Harmonic.

All of these options definitely seem like good ideas but I had to narrow down which one I was going to choose.

Planetary would have been the easiest and probably would have performed the best but I cut it out because I didn't really find it interesting enough and wanted to learn more about the other gearboxes.

While I admire the simplicity of the harmonic drive I was wary of my ability to manufacture the flexible parts needed. I eventually chose the cycloidal drive because it seemed like the biggest technical challenge to design as well as the fact that it looks extremely cool. Cycloidal gearboxes also have nearly no backlash which definitely made it stand out against something like a planetary gearbox with the tolerances of 3D printed parts.

Defining Project Requirements

Now that I knew what gearbox I wanted to make I started to define what I wanted the final design to look like.

  • Dual cycloidal drive to reduce vibrations
  • Integration of motor and gearbox into one assembly
  • 70mm Z height restriction to keep a low profile
  • 10:1 reduction
  • Easy assembly/disassembly (no adhesives)
  • Use existing stator design from axial flux motor

Actuator Design

With my requirements set, I moved on to designing the actuator. The base motor design is based on my last axial flux motor so I began modifying that in order for it to fit a gearbox. Next I had to start work on the design of the cycloidal gearbox system itself. This was quite challenging to figure out initially because the cycloid geometry is fully defined off of parametric equations.

This guide was immensely helpful in defining the geometry. After some time I had the parameters for my parametric equations ready to go based on the size and reduction that I wanted.

Parameter Variable Value
Radius of rotor $r$ 67mm
Radius of rollers $r_r$ 4mm
Eccentricity $e$ 3mm
Number of rollers $n$ 10

$$\begin{equation}
\small{x = {r}\cos(t) - r_r\cos(t + \psi) - {e}\cos(nt)}
\end{equation}$$

$$\begin{equation}
\small{y = -{r}\sin(t) + r_r\sin(t + \psi) + {e}\sin(nt)}
\end{equation}$$

$$\begin{equation}
\small{\psi = \arctan\left(\frac{\sin((1-n)t)}{\left(\frac{r}{e}\right) - \cos((1-n)t)}\right)}
\end{equation}$$

I made an interactive graph on Desmos where you can visualize different cycloid designs quicker than you can in SOLIDWORKS.

By plotting these parametric equations from $(0 < t < \pi)$ and mirroring the result I ended up with the final geometry needed for my cycloids.

3D Printed Dual Cycloidal Actuator
Design of dual cycloid geometry for the gearbox

As this design uses two cycloids they actually rotate in the same direction but have inverted eccentricity with the benefit being that a lot of the vibration is canceled out as the center of mass is roughly centered instead of spinning around. This does come at the expense of added complexity.

3D Printed Dual Cycloidal Actuator
Cycloid geometry integrated into actuator

Now it was time to finally integrate everything together into one cohesive design. One challenge I faced during this process was the admittedly arbitrary height limit that I gave myself.

There were a lot of design revisions in order to get all of the parts to fit in the allotted space. Below is an image showing a cross section of the final design with the plastic 3D printed components highlighted.

3D Printed Dual Cycloidal Actuator
Section view of the final gearbox design

As you can see above there are some very tight gaps between a lot of the moving parts inside the gearbox as a result of needing to fit in this Z constraint. Below is an image that should give a better idea of how the motor and gearbox were integrated into a single assembly.

3D Printed Dual Cycloidal Actuator
Labeled view of the motor and gearbox separated

Once I was done combining the gearbox and motor I landed on this final design

Final Design Renders

3D Printed Dual Cycloidal Actuator
Renders of the final design
3D Printed Dual Cycloidal Actuator
Explosion view of final design
3D Printed Dual Cycloidal Actuator
Horizontal explosion view

Manufacturing and Assembly

When it came to actually manufacturing the design I had to go through quite a few prototype parts before I landed on the final geometry. There was a lot of friction problems with so many parts tightly packed together moving at high speeds so a lot of incremental improvements had to be made. Below is a picture of all the failed parts that didn't make it into the project.

3D Printed Dual Cycloidal Actuator
All the failed prototype parts

However, when I finally did figure out all the issues I was able to assemble and test the actuator. Here are some photos of what the final design looks like assembled.

Testing

Unfortunately I don't currently have access to a dynamometer to do a proper torque test. If I am able to access one I will update this post in the future with the results. Below is a video of me running the actuator on my bench.

I also took a video with the top components removed so you are able to see the cycloids in action.

My general impressions of it are fairly positive as when it's drawing around ~60W I am unable to stop the output with my hand like I easily could on the previous motor. This combined with the cycloidal nature of the gearbox I cannot feel any backlash whatsoever.

Conclusion

I really enjoyed working on this project as it is a culmination of many of the projects I've posted here over the past few years. Being able to take some wire, magnets, and plastic and assemble them in such a way where they generate rotation with enough torque that even I can't easily stop it is a pretty cool feeling and I am pretty proud of how it turned out.

One area that could be improved is the base torque of the motor. Even just reprinting the stator in Iron PLA would yield a higher torque with zero change to the design.

The other area that this actuator suffers in is friction. With the two cycloids spinning around inside the casing there is more rubbing and friction than I initially intended and I think this could be fixed by either only using a single cycloid or making the actuator taller.

I also wish I was able to do more empirical testing on the motor so I could properly characterize its performance but that may have to be a project for another day.

If you enjoyed this project check out some of my other projects that I have completed below!

]]>
<![CDATA[Solar Car HV Bus Bar Distribution]]>https://cadenkraft.com/solar-car-hv-bus-bar-distribution/65d922ddf6e4040001065707Thu, 13 Jul 2023 01:42:50 GMT

As I've continued working on the Iowa State Solar Car team one problem on our current car I have noticed is how we handle routing the high voltage connections in our battery pack. This project aims to create a design that consolidates our HV connections and makes maintenance significantly easier.

The current problem

As you can see below, currently we have a mess of 1/0 gauge wire sprawling between countless contactors, fuses, current sensors, and connectors. This network of wire is used for connecting our battery pack to our motors, chargers, solar array, and LV systems. What we currently have is a nightmare to work with and makes seemingly simple tasks such as changing fuses an hour long ordeal.

The main reason that our current setup is such a mess is because the American Solar Challenge regulations require contactors and fuses at most points through the HV chain leading to many breaks between wires. We also have a problem where the specialty fuses we have to buy do not have fuse holders available so we have to put them inline in a wire as seen above.

Solution Requirements

Below are the requirements I came up with for the design of the HV bussing solution.

  • No doubling up cables on a single screw terminal
  • Properly sized lugs and wire gauge based on the connection
  • Captive, clinched, or crimped nuts for the bolted connections
  • Dedicated holders for all current sensors and fuses
  • Automotive grade panel mount connectors
  • Use bus bars over cables whenever possible
  • Integrated Compact Design

One of the challenges with creating a design for this was deciding on contactors, fuses, and current sensors. Below is what I decided on.

Out of all these the 15-50a fuses were definitely the hardest to find as I wanted all of these fuses to have the same form factor and be able to mount via bolted joint. The Littlefuse 526 series is the only one online that is able to meet these requirements and it just so happens to be designed specifically for electric vehicles.

Below is the design that I came up with for the final bus bar network.

Solar Car HV Bus Bar Distribution
Labeled diagram of the final assembly
Solar Car HV Bus Bar Distribution
View of the bus bar layout
Solar Car HV Bus Bar Distribution
Exploded view of the assembly

Assembly

For the assembly I chose to use clinch nuts on the copper that allow for the nuts to be embedded into the bus bars and reduce the need for you to use a wrench on each side to tighten the fuses in place.

For the tray I designed it to be 3D printed in two parts out of PETG. There is a M3 Heat-set insert and datum pin for each bus bar to keep everything aligned as well as walls between all the bus bars to prevent shorting. As metric hardware is something we don't use fairly often I also included the allen key and socket sizes needed to do repairs embossed into the print.

Solar Car HV Bus Bar Distribution
3D printed shell with brass inserts
Solar Car HV Bus Bar Distribution
Tray with bus bars inserted
Solar Car HV Bus Bar Distribution
Final fully complete assembly

In its current state it is nearly done but is still waiting on the current sensor as well as routing all the wires and hooking it up into our battery pack. I think it should work well and will be the standard for our team's battery pack design moving forward.

Conclusion

Overall I really enjoyed this project and am glad that it greatly simplifies the design of our battery pack. I used quite a few CAD techniques I hadn't before to model the bus bars and tray. I am quite proud of how everything turned out as all the parts went together perfectly and the final design ended up being pretty clean.

To see some of the other solar car work that I've done as well as my other projects click the links below.

]]>
<![CDATA[The NTPixie, A WiFi Nixie Tube Clock]]>https://cadenkraft.com/the-ntpixie-a-wifi-connected-nixie-tube-clock/65d922ddf6e4040001065706Wed, 17 May 2023 23:17:00 GMT

I have always thought that nixie tubes are one of the coolest inventions ever made. The novelty of having such an intricate assembly of blown glass and spot welded numbers just to simply display digits is something I've always admired.

What's a Nixie Tube?

Before the invention of the LED or the seven segment display, engineers needed a device capable of displaying digits for things like voltmeters, multimeters, and frequency counters.

To solve this problem Engineers in the USSR created nixie tubes which were made of 10 digits encased in blown glass that was sealed with Neon gas. The tubes have a wire mesh anode with multiple digits acting as the cathodes. When voltage is applied across the two the Neon gas directly around the digit glows.

Project Requirements

I've looked into simply purchasing a nixie tube clock in the past but there were always a few key wants that I had for a clock that could not be found in available models online.

The project requirements I've set for this clock are listed below.

  • 6 Digits in order to display seconds
  • Neon bulb colons between the hours, minutes, and seconds
  • WiFi, or atomic capability to have a perfect synchronized time

I decided to use the IN-12 nixie tube due to its relatively low cost and the horizontal mounting making them ideal for the design I had in mind.

The NTPixie, A WiFi Nixie Tube Clock
IN-12 Nixie Tube

For the time accuracy I decided on using the Raspberry Pi Pico W and using the WiFi capability to sync to NTP time servers.

Design

For the design I started on the PCB side of things as that is what I was less familiar with. To drive the nixie tubes I decided on using the K155ID1 nixie tube driver. For the power supply I decided on using the NCH8200HV. Finally, for the colons I decided on using NE-2 bulbs.

After a few design revisions this is the final PCB and schematic that I came up with.

To save cost on ordering the PCB I decided to design it to be snapped in half and then both pieces stacked on top of each other connected via B2B connectors.

The NTPixie, A WiFi Nixie Tube Clock
Soldered Assembly

As for the design of the case, I was originally thinking of making a wooden case but did not have a wood shop at my disposal so I decided on making a clear resin SLA enclosure to sell the retro N64 look. The final case design I came up with is below.

The NTPixie, A WiFi Nixie Tube Clock
Final Case Design

Firmware

For this project I decided to use MicroPython on the Pico as it has more documentation and support online for this type of project. Below is the code I wrote for the firmware running on the clock.

import network
import ntptime
from machine import Pin, Timer
from time import localtime, sleep, time

# Define the pins for each nixie tube

nixie_pins = [
    [6, 4, 5, 7],  # nixie tube 1
    [22, 20, 21, 28],  # nixie tube 2
    [2, 0, 1, 3],  # nixie tube 3
    [18, 16, 17, 19],  # nixie tube 4
    [10, 8, 9, 11],  # nixie tube 5
    [14, 12, 13, 15]  # nixie tube 6
]

colon_pin_1 = Pin(26, Pin.OUT)
colon_pin_2 = Pin(27, Pin.OUT)

# Define the lookup table for digit to binary conversion
digit_to_binary = {
    0: [0, 0, 0, 0],
    1: [0, 0, 0, 1],
    2: [0, 0, 1, 0],
    3: [0, 0, 1, 1],
    4: [0, 1, 0, 0],
    5: [0, 1, 0, 1],
    6: [0, 1, 1, 0],
    7: [0, 1, 1, 1],
    8: [1, 0, 0, 0],
    9: [1, 0, 0, 1]
}

# Connect to Wi-Fi
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("WIFI_SSID_HERE", "WIFI_PASSCODE_HERE")
while not sta_if.isconnected():
    pass

# Set up the pins for each nixie tube
nixie_tubes = []
for pins in nixie_pins:
    nixie_tube = []
    for pin in pins:
        nixie_tube.append(Pin(pin, Pin.OUT))
    nixie_tubes.append(nixie_tube)
    #print(nixie_tubes)

# Set up a timer to update the display every second
timer = Timer(-1)

ntptime.settime()
# Define a function to update the display
def update_display(timer):
    # Get the current time from the NTP server
    print(time())
    current_time = localtime()
    # Apply the UTC offset (in seconds)
    seconds_offset = 0 #using https://time.is
    utc_offset = -5 * 60 * 60 - seconds_offset # for example, 1 hour ahead of UTC
    # -5 = CST -7 = PST 
    current_time = localtime(time() + utc_offset)
    if current_time[4]==10 and current_time[5]==10:
        ntptime.settime()
        print("NTP SYNC")
    if current_time[3]>12:
        twelve_hour_time = current_time[3]-12
    else:
        twelve_hour_time = current_time[3]
    #print(current_time)
    #print(twelve_hour_time)
    # Convert the time to digits
    digits = [
        twelve_hour_time // 10,  # hour tens
        twelve_hour_time % 10,  # hour ones
        current_time[4] // 10,  # minute tens
        current_time[4] % 10,  # minute ones
        current_time[5] // 10,  # second tens
        current_time[5] % 10   # second ones
    ]

# Code below is to cycle less common digits to in order to prevent leaking this section should be reworked some day

    if current_time[3]==3 and current_time[4]==0:
        digits = [0,0,0,0,0,0]
    elif current_time[3]==3 and current_time[4]==1:
        digits = [1,1,1,1,1,1]
    elif current_time[3]==3 and current_time[4]==2:
        digits = [2,2,2,2,2,2]
    elif current_time[3]==3 and current_time[4]==3:
        digits = [3,3,3,3,3,3]
    elif current_time[3]==3 and current_time[4]==4:
        digits = [4,4,4,4,4,4]
    elif current_time[3]==3 and current_time[4]==5:
        digits = [5,5,5,5,5,5]
    elif current_time[3]==3 and current_time[4]==6:
        digits = [6,6,6,6,6,6]
    elif current_time[3]==3 and current_time[4]==7:
        digits = [7,7,7,7,7,7]
    elif current_time[3]==3 and current_time[4]==8:
        digits = [8,8,8,8,8,8]
    elif current_time[3]==3 and current_time[4]==9:
        digits = [9,9,9,9,9,9]
        
    print(digits)
    # Convert the digits to binary and display them on the nixie tubes
    for i in range(6):
        binary = digit_to_binary[digits[i]]
        for j in range(4):
            nixie_tubes[i][j].value(binary[j])
    colon_pin_1.value(1)
    colon_pin_2.value(1)
    sleep(0.5)
    colon_pin_1.value(0)
    colon_pin_2.value(0)

# Start the timer
timer.init(period=1000, mode=Timer.PERIODIC, callback=update_display)

# Put the device to sleep to save power
while True:
    sleep(1)  # can be interrupted by timer events

Input WiFi SSID, password, and timezone for this code to run

Final Assembly

Below are renders and pictures of the final design up and running.

The NTPixie, A WiFi Nixie Tube Clock
The NTPixie, A WiFi Nixie Tube Clock

You can see an orbital view of the design by dragging on the model below.


Conclusions

I have been using it on my bedside for the past few weeks now and it has kept time perfectly and I haven't yet noticed any major issues. One issue I am running into is that two of the four bulbs on the colons don't seem to light up consistently. I've read online about needing time for the bulbs to polarize and as they do turn on some of the time I think that's what the problem is.

This has been one of my favorite projects because it was very interdisciplinary in the amount of skills that I had to use in order to complete it. Second, thanks mostly to the superb quality of the SLA print (plus 2 coats of Rust-Oleum Crystal Clear Enamel), this project looks the most polished and least DIY out of anything I've ever done. This clock allowed me to hone in on my PCB design skills and I hope I can use them more on future projects.

Thanks for reading, please check out some of my other posts below!

]]>
<![CDATA[Ironless Axial Flux Motor]]>https://cadenkraft.com/designing-a-coreless-axial-flux-motor-part-1/65d922ddf6e4040001065704Fri, 09 Sep 2022 04:39:12 GMT

After my first custom brushless motor I felt confident enough with the basic theory of how they work to make a second design with significantly more thought and math defining the design.

Creating a 3D Printed Brushless Motor
With my work in the Iowa State Solar Car club I have learned so many things about so many different technologies that I have not had the chance of working with before. One of the things that has come to interest me the most are motors. Getting the chance to
Ironless Axial Flux Motor

As my first design was made by looking at images online and implementing dimensions based on what looked right I found that there were some serious inefficiencies that could be remedied with a bit of math.

Why Axial Flux?

One of the main reasons that I chose to use an axial flux motor design was because the air gap between the magnets and the coils is more or less two dimensional. As opposed to a traditional radial flux motor this allows me to adjust the air gap with shims instead of redesigning the rotor every time to adjust it.

Ironless Axial Flux Motor
Axial Flux (left), Radial Flux (right)

Another benefit to this design is that because this is a DIY project I do not have the budget to order the custom magnets with a bend for a radial flux rotor.

Ironless Axial Flux Motor
Magnets traditionally used in radial flux motor

The flat nature of an axial flux motor allows me to use traditional rectangular bar magnets that can be found cheaply online in large quantities without the need to have them custom made.

Coreless Design and Halbach Array

Similarly to the magnets, due to cost constraints for this project and the manufacturing capability that I currently have in my college apartment, I am not able to custom make ferrite or steel laminate ferrous cores inside the coils.

As a ferrous core is extremely important in shaping the magnetic field around the coils, I had to research a different solution to remedy this and came across the Halbach magnet array. This works by alternating the magnet poles by 90 degrees at a time instead of 180 degrees like normal designs.

Ironless Axial Flux Motor
Halbach Array (top), Alternating Array (bottom)

This uses extra magnets to shape the magnetic field as a iron core traditionally would. As there are very little designs on the internet that I could find the utilize a Halbach pattern I chose to implement it into my design to hopefully contribute some experience implementing it into a motor once the design is completed.

This means that while the rotor of my motor has 12 poles it actually utilizes 24 magnets to implement the Halbach design.

Ironless Axial Flux Motor
Example of Halbach array pattern

Defining Specifications

Next I had to define a few specifications around various aspects of the motor needed to calculate the number of coil turns needed for the final design.

I found an excellent research paper online that outlined the mathematical parameters needed to successfully create a Halbach axial flux design.

[PDF] Paper 088 , ENG-xxx Design and Test of an Ironless Axial Flux Permanent Magnet Machine using Halbach Array | Semantic Scholar
Conventional permanent magnet electric machines utilize ferromagnetic cores of high permeability. The high core permeability relative to the surrounding material helps to concentrate the magnetic flux in the core, and guide the flux across the airgap of the machine. An ironless machine design remove…
Ironless Axial Flux Motor

Design and Test of an Ironless Axial Flux Permanent Magnet Machine using Halbach Array

Through this paper and some preliminary CAD design as well as a quick inventory of all of the motor controllers and bearings that I had already, I was able to define certain parameters needed to calculate the coil turns below.

Parameter Value
DC Bus Voltage 24 V
Base Speed 700 rpm
Rated Current 7 A (rms)
Wire Diameter 0.65 mm
Poles 12
Coils 18
Connection Star (Y connection)
Coil Area ($A_{coil}$) 4.92*10-4 m2
Outer Radius ($r_o$) 65 mm
Inner Radius ($r_i$) 35 mm
Magnetic Flux Density ($B$) 0.5 Tesla

I chose for the motor to have 12 poles and 18 coils as it has an efficient high winding factor.

Ironless Axial Flux Motor
Winding Factor from Bavaria Direct Online Calculator

Calculating Parameters

The first step in defining the coil turns needed is calculating the area of the motor that is covered by the coils.

$$\small{A_{rotor}=\pi (({r_0}^{2})-({r_i}{r_i}))}$$

Next, I needed to define an optimal outer to inner radius ratio in order to maximize the efficiency of the motor. As the paper above says, an optimal ratio for this is around 0.5. This allowed me to define the inner and outer radius based on the 36mm*6mm*6mm magnets that I found online.

$$\small{\alpha=\frac{r_i}{r_o}}$$

Then I had to calculate the peak flux density using the equation below as well as the recommended mean air gap flux density of 0.5 Tesla from the paper above.

$$\small{\tau=\frac{F}{A_{rotor}}=\frac{Bli}{lw}=\frac{Bi}{w}=BZ}$$

$$\small{B=\frac{2B_m}{\pi}}$$

After using these two equations I arrived at a mean air gap flux density of 0.785 Tesla. Using the next couple equations I was able to use this value combined with others above to figure out the final number of coil turns.

$$\small{e_{ph}=N_{ph}A_{coil}\frac{dB(\theta)}{dt}}$$

$$\small{B(\theta)=B_m\sin{{(\omega}_et)}}$$

$$\small{e_{ph}=N_{ph}A_{coil}\omega_eB_m\cos{(\omega_et)}}$$

$$\small{N_{ph}=\frac{e_{ph}}{A_{coil}\omega_eB_m}}$$

The electrical frequency of the stator voltage can be determined using the shaft speed and number of pole pairs.

$$\small{{\omega_e}=\frac{700\ rpm}{60\ s}\cdot2\pi\cdot6}$$

Plugging in the final numbers into the equation below equates to about ~87 coils per phase of the motor.

$$\small{N_{ph}=\frac{\frac{24\ V}{\sqrt3}}{4.92\cdot{10}^{-4}\cdot\frac{700\ rpm}{60\ s}{2\pi}\cdot{6}\cdot{0.785\ T}}}$$

$$\small{N_{ph}=81.57}$$

Dividing this by six as there are 6 coils per phase it equates to around 14 turns per coil.

Finalizing the Design

Now that I had the parameters defined I started work on creating the final design. The final design will consist of mostly 3D printed parts and a 62mm*40mm*12mm unsealed roller bearing. This bearing has significantly more rigidity than the 608 skateboard bearing I used in my first design.

Here are a few renders of the final motor design that I decided on. The white/clear parts are printed in PLA while the base stator is made of PETG for the extra temperature resistance as the coils heat up.

Ironless Axial Flux Motor
Completed assembly
Ironless Axial Flux Motor
View of the magnets and coils with the rotor hidden

Below is a draggable render where you can see the final explosion view of the design from multiple angles.

Here is an image of all of the different printed parts and hardware (aside from magnets and enamel wire) needed to assemble the motor.

Ironless Axial Flux Motor
All completed printed parts

These photos show a more in depth look at the design that I used in order to secure the bearing to the plastic piece. This has proved to work significantly better than the friction fit bearing mount seen in my first design.

Finally here is an image of the final design assembled (again without magnets or coils) with a Sharpie for scale.

Ironless Axial Flux Motor

Last but not least, I thought I would throw in an image showing the amount of prototype parts it took to get the fitment of everything just perfect.

Ironless Axial Flux Motor
All of the failed prototype parts created through the design process

Assembly

Now that the printed parts are completed and they are successfully test fit I ordered the necessary magnets and wire needed to complete the motor and finally get it up and running.

The step-by-step plans for what the assembly will include are listed as below.

  • Wind all 18 coils coils (0.65mm Enamel Wire)
  • Measure coil resistance with University LCR meter
  • Solder power leads and connectors to coils
  • Assemble magnets into rotor (36x6x6mm Neodymium magnets)
  • Create test stand to power and characterize properties of the motor

Here are the photos of the wound coils for the motor as well as the magnets in the rotor. I used a magnetometer app to find the northern pole of the magnets in order to properly construct the Halbach array.

In order to make sure that I wound the coils correctly and the solder joints didn't induce any added resistance I took the stator assembly to one of the university LCR meters to measure resistance and inductance.

Below is a table summarizing the LCR measurements.

AB AC BC
Resistance (mOhms) 699 705 708
Inductance (uH) 56.45 57.69 57.19

While coil A differed slightly I deemed this within my allotted margin of error and moved forward.

Finally once it was fully assembled I was able to hook everything up and hope that it would spin. Below is a video of its first spin.


Video of me spinning up the motor for the first time.

I would have liked to test the torque of the motor with a dynamometer but I did not have access to one at the time. Maybe I will save this for a future project but for now I'll have to leave this one here.


Conclusion

I really enjoyed this project because it was the first project I've done that required me to do a lot of research and get a baseline understanding of what was needed to complete the project before even starting.

This took quite a long time to make but I think it was ultimately worth it as I have vastly expanded my knowledge of motors and motor design and I actually was able to create a working motor. Hopefully I am able to carry the skills that I learned through this project onward to future ones.

Thanks for reading this post. If you are interested in any of my other posts they are linked below!

References

[1] T. Batzel, A. Skraba, and R. D. Massi, “Design and Test of an Ironless Axial

Flux Permanent Magnet Machine using Halbach Array,” IAJC-ISAM Joint

International Conference, vol. 88, 2014.

]]>
<![CDATA[Solar Car GPS Tracker]]>https://cadenkraft.com/solar-car-gps-tracker/65d922ddf6e4040001065703Tue, 09 Aug 2022 02:54:00 GMT

This is a quick post about a small project that I made for the PRISUM Solar Car Club here at Iowa State.

Every other summer our team competes in the American Solar Challenge.

ASC & FSGP – Collegiate solar car competition
Solar Car GPS Tracker

This competition consists of both a track race as well as a 1300 mile road race across the US seen above. The track race (FSGP) which includes safety scrutineering of the car as well as the American Solar Challenge road race are both about a week long leading to a very long two week competition.

As I could only get one week off from my internship I chose to attend the American Solar Challenge which means that I would have to sit and anxiously wait for updates from the team and completely out of the loop to what was happening live.

Solar Car GPS Tracker
Photo of our current solar car that went on race

I then realized that our car's telemetry system, which is cellularly linked and connected to the internet wherever the car goes, outputs the latitude and longitude of the car live every second through its log files.

The problem was that there wasn't any good way to display that data and as the competition drew near many of my friends and family began asking where they could follow the competition.

This gave me the idea to make this tracker webpage so anyone in the world could see the live position and speed of our car.

The main aspect of this project uses a project called Leaflet.

Leaflet — an open-source JavaScript library for interactive maps
Leaflet is a modern, lightweight open-source JavaScript library for mobile-friendly interactive maps.
Solar Car GPS Tracker

Leaflet is an open source project for implementing custom maps into websites without the need for embedds, iframes, or api keys. This seemed like the perfect use case for me and I began coding up the site.

Once I got the map readly and scaled correctly I made a basic theme with our team colors and used the official route data from the American Solar Challenge website in order to map a route along the map with checkpoints.

Solar Car GPS Tracker
Completed basic map view and UI

Next I had to handle the hard part which consisted of establishing a live connection to the car while keeping the webpage static which is needed for using Github pages.

I started this process by procrastinating the hard part and spending way to much time in Photoshop creating a clipart-esc sprite of our current solar car.

Solar Car GPS Tracker
Solar Car Map Marker Design

Finally I started on the live connection aspect and started implementing a websocket connection to the car. Unfortunately for me, our software team that made the telemetry page codes things extremely efficiently compressing all of the car's data output into illegible strings of bytes. While making the message size 20 times smaller this made rummaging through their code trying to understand it all 20 times harder.

In the end I was able to get the connection established to the car with my final bug-fix that got everything working being pushed to Github at 8:57am just three minutes before the competition started at 9:00.

With the tracker up and running there were many current members and alumni of the team as well as friends and family that were able to see the current status of the car with the GPS even being accurate enough for you to be able to roughly see the racing line on the track race.

Over the next several days of the competition I had nothing better to do but to make even more updates to the tracker. The final iteration included a terrain view button, live connection and speed status, and changing the direction the solar car icon faced based on the movement of the actual car.

And with that the project was more or less complete and I headed off to take part in the American Solar Challenge which ended up being a great experience!

If anyone is interested, the live webpage for the solar car is below. Whenever we test drive the car around campus it should connect and update the position live.

Finally, if anyone wants to see my horrid coding skills barely holding this whole project together the source code from the site and the repository its hosted out of is linked below.

GitHub - CKraft11/SolarCarTracker: Website for tracking the Iowa State University PrISUm Solar Car
Website for tracking the Iowa State University PrISUm Solar Car - GitHub - CKraft11/SolarCarTracker: Website for tracking the Iowa State University PrISUm Solar Car
Solar Car GPS Tracker

Github repo for tracker site

This project was really fun to work on and I definitely learned a lot as coding projects are not something I often do. It was also really cool hearing from all the past alumni on the team, some of whom I've never met, talk about religiously stalking the page in an open tab at work for those two weeks.

]]>
<![CDATA[Creating a 3D Printed Brushless Motor]]>https://cadenkraft.com/creating-a-3d-printed-brushless-motor/65d922ddf6e4040001065702Fri, 08 Jul 2022 03:02:00 GMT

With my work in the Iowa State Solar Car club I have learned so many things about so many different technologies that I have not had the chance of working with before.

One of the things that has come to interest me the most are motors. Getting the chance to learn and tune the motors on our car has led me to develop a further interest in how they work.

On our current car we use BLDC motors from Mitsuba in Japan directly driving our wheels inside the rims of our wheels.

Creating a 3D Printed Brushless Motor
Mitsuba 2096D3 Motors Used

With this urge to dive deeper and figure out how exactly brushless motors work I decided to try and design my own so I can experience every hurdle and roadblock and hopefully learn something from it.


Going into the design I just wanted to try my hand at making a motor without having to learn advanced motor simulation software like Ansys MotorCAD and Ansys Maxwell. My goal was simply to make a motor that works and spins on its own.

Starting a design in Autodesk Inventor, I began by creating the main profile of the stator.

Creating a 3D Printed Brushless Motor
Bottom Stator Profile Design

I made this design using reference images I found online while adding features optimizing the design to be 3D printed. As seen above I also added slots on either side of the coil to make routing each coil and keeping it organized significantly easier while allowing all the wires to go into the center so the design can be screwed flush.

Continuing on the design I needed to create a solution for implementing a bearing. As I wanted to keep the costs down on the project I decided to use a standard open ball 608 skateboard bearing that I had lying around.

Creating a 3D Printed Brushless Motor
Open Ball 608 Bearing

Finally I ordered some 2mm*10mm*20mm neodymium magnets off of AliExpress. I then culminated this into a final design using all of these parts.

Creating a 3D Printed Brushless Motor
Explosion View of the Final Design

Now it comes time to assemble the motor. I started researching different ways of winding the coils and different parameters in terms of coil winding and wire gauge that I could use to my advantage to increase the efficiency of the motor.

I started researching the differences between Wye and Delta winding configurations.

Creating a 3D Printed Brushless Motor
Diagram of Delta and Wye Configurations

Although a Wye configuration on paper would be better suited for this motor design because of the reduced need of current to start spinning the motor. However, I chose to use the Delta configuration as it was significantly easier to wire given the design that I had.

This link below contains a lot of interesting information if you are interested in learning more about the differences in these two types of windings.

Difference between Delta and Wye | Difference Between
Difference between Delta and Wye Electricity is a necessity these days used to illuminate buildings and homes, to operate air conditioners and to power trains. In fact, electricity powers almost everything such as computers, radios, televisions, medical devices, and an ever-increasing variety of dev…
Creating a 3D Printed Brushless Motor

Although I could research and try to optimize the wire guage of the coil I already had a spool of 0.5mm enameled copper wire that I did not have plans to do anything with so I decided to use that.

I chose to use this wire with 60 windings across the all 6 poles of the motor in 3 individual phases.

Creating a 3D Printed Brushless Motor
Stator Wiring Completed

Now that the wiring was done I needed to test the motors functionality. I hooked the motor up to an old ESC that I had from making drones and using a servo controller to manually control the RPM of the ESC. I found that the motor worked best around 14-15 volts but did not have a lot of torque output.

Creating a 3D Printed Brushless Motor
Completed Motor Assembly

One thing I did notice was that I needed to flick the motor pretty hard in order for it to start spinning. This is probably due to many inefficiencies in the motor such as lacking an iron core for the electromagnet or the higher starting amperage needed for a Wye configuration.

Future Changes

Below I am going to sum up a few key takeaways that I have learned from this project and future ways I could remedy it in the next motor design that I make. I think the biggest faults in the current design are as listed below.

  • Lack of iron core in the electromagnets
  • Magnets are pretty weak and could be stronger
  • Spacing between the coil and magnet significantly too high
  • Using Delta wiring instead of Wye

Some ways that I could remedy this are by making an axial flux motor for my next design. This would allow for an extremely thin gap between the rotor and stator and because of the coil design of an axial flux motor I could also make a separate jig for more accurately winding each individual coil instead of winding around the stator all at once.

Creating a 3D Printed Brushless Motor
Example of an Axial Flux Motor

Since making this I have also learned more about motor theory and simulating motors through applications like Ansys MotorCAD and Maxwell through work that I have done at my internship at Husco Automotive.

Hopefully I will be able to utilize these skills in order to refine my next design to be more efficient and quantitatively thought out.

Stay tuned for that to come!

]]>
<![CDATA[Solar Car Steering Wheel]]>https://cadenkraft.com/designing-solar-car-steering-wheel/65d922ddf6e4040001065701Thu, 24 Mar 2022 03:26:00 GMT

At Iowa State University, one of my main interests has quickly become the PRISUM Solar Car Club. It has given me an opportunity to use my engineering skills outside of classes with some pretty cool people.

Solar Car Steering Wheel
Current PrISUm Solar Car, P15 Eliana

As I am a Freshman at Iowa State, and at the time of writing P15 is coming to the end of its build cycle, most of the core systems in the car have already been set in stone. However there are a few smaller projects that haven't been tackled yet.

One of these projects is redesigning the steering wheel. The current steering wheel in the car has given us many problems that have greatly inhibited our ability to drive reliability without breaking down. Looking at the image of the disassembled current steering wheel below you can see that it mostly consists of a waterjet sheet of carbon fiber with holes drilled for the quick disconnect fitting and the buttons used for turn signals, hazards, etc.

Solar Car Steering Wheel
Old P15 Steering Wheel Disassembled

The problem with this design is that the wires that connect to the buttons to the aptly named buttonboard PCB that controls them, get individually routed to buttonboard deeper into the car. This means that when rotating the steering wheel, as there are more than 15 individual wires being rotated, over time some either develop a loose connection or snap off entirely.

As the steering wheel controls everything from turn signals to our regenerative braking we cannot have these faults inhibit us from driving at race this summer.

Some other smaller issues with this design are that as the holes for the buttons are drilled, the number of them and their positions are fixed and can only be redone by re-waterjetting the main carbon panel which can cost up to $50 in materials and machine time. The hole pattern was also drilled by hand with no CAD available which makes creating a strain relief component that integrates with the current design quite challenging.

Taking all this in mind I started on defining the requirements I was going to set for myself for the new design to meet.


  • Integrate the buttonboard PCB into the steering wheel itself
  • Limit the connection from the steering wheel to the car to a single wire
  • Provide the ability for the button position and count to be quickly redesigned if needed
  • Utilize 3D printed parts as much as possible and mechanical fasteners over adhesives

With these in mind I started to design the steering wheel. I jumped into Inventor and started modeling and after a few hours was left with my first iteration.

As seen above, there are many aspects to the new design including the integration of the buttonboard PCB shown as a placeholder in green, with the smaller PCB being the compute module needed to run the code. There are also 3D printed redesignable inserts for the buttons combined with an RJ45 Ethernet jack used in order to transmit power and CAN data from buttonboard to the rest of the car.

I showed this design to the team and received a lot of really helpful feedback. The core areas of feedback are as follows.


  • This design is larger than the current one and takes up more space in the solar car. Some drivers noted that the current one already got in the way often
  • Much of the PCB and compute module are unprotected which could lead to damage from it being handled so much
  • PCB shape and size could lead to increased manufacturing cost from the PCB fabricator
  • Add some sort of gasket between the PCB and carbon panel

With this feedback I embarked on creating a second more compact and integrated design that could also fufill the new requirements of smaller size as well as protecting and optimizing the shape of the PCB.

I culminated this all into a brand new design to which a draggable view of it is seen below.



This new design includes numerous improvements from the first namely being, compact size and increased protection around the PCB and exposed electronics. It also has 2 RJ45 connectors in case one fails.

Solar Car Steering Wheel
Solar Car Steering Wheel

Seen below are areas on the new design with increased protection around the electronics.

After showing this design to the team nobody had issues to raise on the second iteration so I began working with the electronics team to develop the new buttonboard PCB meeting the form factor of my new design.


I started off by exporting the outline of the PCB placeholder I created in Inventor and opened it up into Adobe Illustrator where I marked areas where electronic components could not be placed as the PCB would be directly against another part.

These outlines could then be imported into Altium Designer, our teams' PCB designer. Members of the electrical team were then able to convert this into a PCB board outline and start the process of creating a board schematic and placing components.

Here is the finished design that they came up with below.

With this step complete we were able to order the PCB and its components and I was able to start manufacturing the mechanical parts needed for assembly.

While the center peice was again waterjet out of the same carbon material of the first, most of the components were 3D printed using the 3D Printing Club's print lab in Prusa3D PETG plastic to provide temperature resistance during the hot summer temperatures they will endure.

Solar Car Steering Wheel
Printing handle pieces on a Prusa MK3s

Once all the parts were printed and the carbon plate was waterjet I soldered and tested the components onto the brand new buttonboard PCB.

Finally, all the parts were ready to assemble. Here are some images documenting the assembly of the finished product.

And with that the project was more or less complete. The software team was able to make a few adjustments to their code and it was connected to the car and ready to go in no time.

Over the course of the past few weeks the steering wheel has been working great while driving and has presented no issues so far and seems to have solved the ones of the previous design.

I really enjoyed making this project as allowed me to learn a lot more about the solar car club and meet more people on the team. I think the final product turned out really well and bears a striking resemblance to the CAD used to create it. Hopefully it will be able to stand up to the intense rigor of the 1300 mile American Solar Challenge this summer!

]]>
<![CDATA[Ghost Blog with Free Webhosting]]>https://cadenkraft.com/creating-a-ghost-blog-with-free-webhosting/65d922ddf6e40400010656fcWed, 23 Feb 2022 04:58:02 GMT
  • Updated 2/29/2024
  • Ghost Blog with Free Webhosting

    When I began my search to find the best blog/CMS that I could host at home (or in my dorm room) on my server, I landed on Ghost pretty quickly with its slick UI and broad feature-set including an admin panel, app integrations, and native Docker support.

    My problems arose when it came to hosting. Although I can host it on my server I currently cannot port-forward traffic to my blog, and it also introduces a pretty significant security risk.

    Bring in Github pages. Github pages is a great way to host websites completely for free with the one caveat being that they have to be completely static. As Ghost doesn't natively support this to my knowledge, this is where the guide begins.

    Requirements

    • Server/Laptop/PC you have to host the server on for local editing. The final site will be on GitHub pages so this machine doesn't have to be running 24/7.
    • Free Github account
    • Basic Linux command line knowledge
    • Patience

    Setting up Linux environment

    This guide should work natively on Linux and macOS (untested) and if you only have a Windows machine, it also works using WSL2.

    First, we need to install Docker and some other packages. Going forward, I will be listing commands that would be used on Debian/Ubuntu-based systems as that is what I personally used, but they should be similar for other platforms. To install Docker, we can run these commands below.

    sudo apt-get install ca-certificates gnupg lsb-release nano git curl imagemagick optipng pngcrush jpegoptim

    Download general packages and image optimization

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

    Add Docker GPG key

    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    Set up stable repository

    sudo apt-get update
    sudo apt-get install docker-ce docker-ce-cli docker-compose containerd.io

    Next, we want to install all of the packages needed for the static site generator that we will be running outside of the Docker container on bare metal.

    sudo apt-get install python3 python3-pip wget

    Download Python 3 and pip

    Setting up the Ghost Docker container

    The method I'm going to be using to set up Ghost with Docker is through docker-compose. Firstly we need to create a docker-compose.yml file.

    nano docker-compose.yaml

    In nano paste and edit the docker-compose install parameters below.

    Optionally you can mount the folders from within your docker container to somewhere on your local machine which can make development much easier. If you would like to do that add a volumes: section under the environment: section on both the ghost and db containers. If you are running Ghost on a remote server make sure to change url: from http://localhost:2368 to http://SERVERIP:2368. If you don't want to deal with any volumes you can delete both sections entirely.

    You also need to know your PUID and PGID of your user account. Run the following commands to determine those values and then add those to the file below.

    id -u # returns PUID
    
    id -g # returns PGID

    Get your PUID and PGID

    version: '3.1'
    
    services:
    
      ghost:
        image: ghost:latest
        restart: always
        ports:
          - 2368:2368
        environment:
          # see https://ghost.org/docs/config/#configuration-options
          database__client: mysql
          database__connection__host: db
          database__connection__user: root
          database__connection__password: EXAMPLE
          database__connection__database: ghost
          PUID: 1000 # change these to your linux account with "id -u" and "id -g"
          PGID: 100
          url: http://localhost:2368
          #NODE_ENV: development
        volumes: # allows you to easier develop and transfer files in and out of your website
          - /PATH/ON/LOCAL/MACHINE/ghost/content:/var/lib/ghost/content
    
      db:
        image: mysql:8.0
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: EXAMPLE
          MYSQL_DATABASE: ghost
          PUID: 1000 # change these to your linux account with "id -u" and "id -g"
          PGID: 100
        volumes: # allows you to easier develop backup/manage your database
          - /PATH/ON/LOCAL/MACHINE/ghost/mysql:/var/lib/mysql

    docker-compose.yml

    Press Ctrl-X to exit and Y to save your changes. Before we start the container, we also want to add your current user to the Docker group on your computer so you will be able to run all of these commands without using sudo.

    sudo groupadd docker

    Create the Docker group

    sudo usermod -aG docker $USER

    Add the current user to the Docker group

    You will likely have to log out and log in for these changes to be implemented.

    Finally, we can get into actually starting up the Ghost blog. If you are not running this on a server and are on a laptop or desktop, I recommend using VSCode with the Docker extension. The workflow is very nice for managing Docker containers and images.

    Ghost Blog with Free Webhosting

    Now we need to load up the Docker container we created earlier. Navigate to the directory that you created the docker-compose.yml file in and run

    docker-compose up -d

    This should take a while as it has to download and set up the Ghost Docker image but after it says the website is finished loading you should be able to navigate in your browser to http://localhost:2368 or http://serverip:2368 depending on your setup. You should see a nice-looking blog template with all the images loaded properly. Then you can add /ghost to the end of your URL to access the admin dashboard.

    Ghost Blog with Free Webhosting

    Here it will prompt you to set up an account and parts of your blog. I'm not going to go too much more in-depth on that side of things as that is more up to the user but if you have everything up to here working we should be good to set up the GitHub pages integration.

    Setting up Github Pages

    Now that we have our local Ghost blog up and running, we want configure a static site to be generated and sent to Github Pages. The tool we will be using is called Ecto1. A big thanks to for making it and all of the useful documentation. To install it, we just run

    GitHub - arktronic/ecto1: Ghost blog downloader/scraper/static-site-maker
    Ghost blog downloader/scraper/static-site-maker. Contribute to arktronic/ecto1 development by creating an account on GitHub.
    Ghost Blog with Free Webhosting
    git clone https://github.com/arktronic/ecto1

    Next, we need to prepare our git repository on our personal machine. To start, create a folder you want the repository to be in and initialize it.

    mkdir ghost
    cd ghost/
    git init 

    Then move all of the files cloned from the ecto1 repository into your ghost folder. After that, we need to install the required dependencies to run ecto1.

    pip install -r requirements.txt -t .

    In order for ecto1 to work, we are going to need to change a few things in the ecto1.py script

    		self.target_path_root = pathlib.Path(os.getcwd()) / 'docs'

    Change line 34 to this

    print('Done. Contents have been downloaded into:', pathlib.Path(os.getcwd()) / 'docs')

    Change line 263 to this

    Then we have to go online to Github and create a few things. Starting with the repository, create a repository with any name you like and copy the URL under the "code" dropdown.

    ⚠️
    If your do not have a custom domain the name of your Github repo should be your Github username or the static site generator will not work!

    Ghost Blog with Free Webhosting

    We want to add this repository as a remote repository location for git to push the files. We can do this by running

    git remote add origin https://github.com/yourlinkhere.git

    We need to go back to Github and generate a personal access token that ecto1 can use when creating the site to push files to your repo. Go to this link here and create a new token with a name of your choice and give it repo permissions. Copy this link and keep it somewhere safe (e.g., not in your git repository folder). Next, we can run the following commands to test everything working.

    touch test
    git add .
    git commit -m "first commit"
    git push -u origin master
    git config --global credential.helper store
    

    When prompted for a username and password, use the token created earlier in place of your password.

    You should see a test file in your Github repo and a commit message if all has gone well.

    Set up Ecto1 with Github

    Lastly, we need to set up a script to update Github with the latest version of the blog. Luckily, I have made a script for this, which is set up below

    nano ghost-updater.sh

    Create a script in your git directory

    #!/bin/bash
    
    URL="cadenkraft.com" #Change this to your url
    SERVERIP="localhost" #Change this to your server ip if Ghost is on another machine
    
    # this is needed or me running the script on my own website for this very page will break the script by replacing all the filetypes.
    PNG="png"
    JPG="jpg"
    JPEG="jpeg"
    WEBP="webp"
    
    date=$(date)
    git pull origin master
    rm -r docs
    mkdir docs
    cd docs
    echo $URL > CNAME
    cd -
    ECTO1_SOURCE=http://$SERVERIP:2368 ECTO1_TARGET=https://$URL python3 ecto1.py
    cd docs
    docker cp ghost:/var/lib/ghost/content/images/. content/images
    cd -
    IMGMSG="No image optimization was used"
    while getopts ":o:" opt; do
      case $opt in
        o)
          arg_o="$OPTARG"
          echo "Option -o with argument: $arg_o"
          if [ $arg_o = "webp" ]; then
            echo 'Conversion to webp has started'
            sleep 1
            find docs/content/images/. -type f -regex ".*\.\($JPG\|$JPEG\|$PNG\)" -exec mogrify -format webp {}  \; -print
            find docs/content/images/. -type f -regex ".*\.\($JPG\|$JPEG\|$PNG\)" -exec rm {}  \; -print
            grep -lR ".$JPG" docs/ | xargs sed -i 's/\.$JPG/\.$WEBP/g'
            grep -lR ".$JPEG" docs/ | xargs sed -i 's/\.$JPEG/\.$WEBP/g'
            grep -lR ".$PNG" docs/ | xargs sed -i 's/\.$PNG/\.$WEBP/g'
            echo 'Conversion to webp has completed'
            IMGMSG="Images converted to webp"
          else
            echo 'Standard image optimization has started'
            sleep 1
            #credit goes to julianxhokaxhiu for these commands 
            find . -type f -iname "*.$PNG" -exec optipng -nb -nc {} \;
            find . -type f -iname "*.$PNG" -exec pngcrush -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time -ow {} \;
            find . -type f \( -iname "*.$JPG" -o -iname "*.$JPEG" \) -exec jpegoptim -f --strip-all {} \;
            echo 'Standard image optimization has completed'
            IMGMSG="Standard image optimization was used"
          fi
          ;;
        \?)
          echo "Invalid option: -$OPTARG"
          exit 1
          ;;
      esac
    done
    git add .
    git commit -m "Compiled Changes - $date | $IMGMSG" ghost-updater.sh ecto1.py requirements.txt README.md serve.py docs/.
    git config --global credential.helper store
    git push -u origin master

    Paste the following code into nano and change the URL and SERVERIP variables at the top

    Also, I know there are some patchy solutions to some current bugs in Ecto1 in this script with the main problem being that Ecto1 only has access to the images served on the local site and not every image in the content/ folder. If you are reading this it is probably still working.

    sudo chmod +x ghost-updater.sh

    Make the script executable

    # Option 1
    ./ghost-updater.sh # pushes static site to github with no optmization
    
    # Option 2
    ./ghost-updater.sh -o # runs light image optimization
    
    # Option 3
    ./ghost-updater.sh -o webp # optimizes and converts images to WebP, max performance

    Run the script. Option 3 is recommended

    Image Optimization

    This script can be ran with flags to optimize the images on your site improving performance. Running ./ghost-updater.sh -o will lightly optimize all the images on your site while retaining the current file types. Adding the flag ./ghost-updater.sh -o webp will recursively convert every image on your site to .webp. This is a more browser optimized file type that should make your site run significantly faster at the expense of a slight dip in quality. The caveat of this is that it runs every single time you push an update so as to not permanently alter the source files. This makes any changes you make here fully reversible at the expense of update time.

    Conclusion

    If all of this went successfully, you should have many files in your Github repo now. To set up Github pages, go to the Github pages tab in settings and select the master branch and /docs as your root folder. You can set up a custom domain here as well. Just make sure it is the one you have been using in these scripts.

    If your page is bugged out and only showing HTML elements and no CSS or Javascript, you likely put the wrong domain in the script above. If you don't have a custom domain, the default should be https://github-username.github.io/. If all of this has worked up till now, congratulations, you're done! I hope this guide helped get you to that point.

    ]]>
    <![CDATA[Single Part Raspberry Pi Compute Cluster]]>https://cadenkraft.com/creating-a-single-part-tool-less/65d922ddf6e40400010656ffTue, 13 Apr 2021 17:09:00 GMT

    My Raspberry Pi's are some of my favorite devices that I own. Their versatility cost and ease of use have allowed me to implement them into a wide range of projects and learn a lot about computing.

    One area I had never ventured however was the idea of clustered computing. Making a compute cluster out of Raspberry Pi's had always seemed like a popular project that people do but I personally had never seen a use for one.

    Single Part Raspberry Pi Compute Cluster
    Oracle Raspberry Pi Compute Cluster

    However, after watching some videos by Jeff Geerling I was interested. Luckily enough I just so happened to have 4 Raspberry Pi 3b+'s that currently had no use. After doing some research the consensus came to be that Pi 4's are recommended for making clusters and 3's might be a bit slow but I'm mostly doing it as a learning experience as opposed to a necessity.

    Looking at the designs people have made previously for Raspberry Pi clusters I was disappointed to see that the actual mechanical design of the enclosures/lack-thereof was quite lacking in my opinion so I wanted to make my own. I tasked myself with designing a new enclosure satisfying these requirements.

    • Tool-less install of the Raspberry Pi's
    • Streamlined power delivery (No big micro-USB cables)
    • 3D printable with as few parts as possible
    • Integrated network switch and active cooling

    Here is the final design that I came up with. The view below is draggable to see the full model.

    The center black component is designed to be 3D printed without supports with integrated tool-less clips to firmly hold all of the Raspberry Pi's without any hardware. The panels around the 3D printed part are designed to be laser cut out of 3mm acrylic and provide mounting for the fans and power delivery components.

    One of the things I was worried about in having such a confined enclosure for the Raspberry Pi's was the port accessibility if I ever needed to use the HDMI ports for some reason. That is why I implemented the slots into the sides of the design. Not only do they aesthetically look cool if you side the acrylic panel out the back of the part they are perfectly lined up with the ports on the side of all the Raspberry Pi's so if needed I can still use those ports without having to ever take out any of RPI's.

    On that note, some may notice that the traditional way that the Pi's receive power, the micro USB port on the side of the PCB, would be completely inaccessible in its current state. One solution that many have used online is to power the Raspberry Pi's through the 5v GPIO headers as they can actually take a power input. While this would work and would be pretty easy to implement, one of the downfalls of powering the Pi's directly from the 5v line is that your input voltage does not go through any of the filtering or reverse polarity protection that it would when powering over USB.

    As I don't trust myself enough to risk 4 Raspberry Pi's at once I needed a better solution. After doing some research and probing with my multimeter I concluded that there are actually a couple of pads on the PCB below the USB port for 5v and GND. These are where the USB port actually connects to the PCB so you still retain the filtering and protection.

    Single Part Raspberry Pi Compute Cluster
    5V pads in red, GND in black

    Although soldering directly to Pi's seems like a much more drastic measure to take I thought that it was worth the risk and that it was the solution that I ended up going with.

    Next, I needed to tackle the cooling. Admittedly, this is where I went a bit overkill. I initially wanted to use the NF-A4x20 PWM fans by Noctua.

    Amazon.com: Noctua NF-A4x20 PWM, Premium Quiet Fan, 4-Pin (40x20mm, Brown) : Electronics
    Buy Noctua NF-A4x20 PWM, Premium Quiet Fan, 4-Pin (40x20mm, Brown): Case Fans - Amazon.com ✓ FREE DELIVERY possible on eligible purchases
    Single Part Raspberry Pi Compute Cluster

    However, at almost $15 each, $30 for cooling 4 $30 computers just didn't really make a lot of sense. Then I came up with a different idea. As the length of the network switch afforded me extra room between the Pi's and the back of the cluster, the fans that I chose could be quite thick. This led me to pick 40mm server fans to use in the design.

    Single Part Raspberry Pi Compute Cluster

    After they arrived I was disappointed to find out that the reviews of the fans being unbearably loud were true after some preliminary testing. However, they did push an unimaginable amount of air for their size so I decided to come up with a solution to tackle the noise.

    My first idea was to hook up the PWM headers on the fans to the extra GPIO headers on one of the Raspberry Pi's and control it through temperature but that quickly became too far out of my element and probably out of the scope of the project. I decided to do the fan control the old-fashioned way by manually adjusting the voltage of the fans. To accomplish this I used a LM2596 Buck converter to limit the input voltage to the fans thus limiting the noise.

    Single Part Raspberry Pi Compute Cluster
    LM2596 DC-DC Buck Converter

    After some testing, I concluded that the optimum level for the fan speed was setting them to just 3 volts! Normally I would think that the fans wouldn't even be capable of spinning 9 volts under their rating but not only did they spin, when they were mounted into the enclosure I could feel a steady stream of airflow even through the USB ports.

    Putting everything together

    Now that all the systems have been explained it's finally time to show off what it looks like put together.

    Single Part Raspberry Pi Compute Cluster
    View of the front with all of the Raspberry Pi's connected
    Single Part Raspberry Pi Compute Cluster
    All of the Pi's powered and working
    Single Part Raspberry Pi Compute Cluster
    Back wiring and fan controller

    As seen in these photos there were some things added that I forgot to mention including the fan filters and power switch etc. Overall I think it came out really well and surprisingly accurate to my original CAD model.

    So what do I actually use it for?

    This is the main question that people are asked when you make these types of cluster projects is what people actually use them for. And to be perfectly honest there isn't really much you can do that you can't do on any normal server.

    Single Part Raspberry Pi Compute Cluster
    PiHole Logo

    That being said, it was a really good learning experience and I am currently using my cluster to host a local PiHole adblocking instance and even the local version of this blog. All of the Raspberry Pi's are installed with Raspberry Pi OS running k3s, a stripped-down lightweight version of Kubernetes.

    K3s: Lightweight Kubernetes
    Single Part Raspberry Pi Compute Cluster

    If you are interested in information to set up the software side of things, that is a bit outside the scope of what I can explain through the medium of this post, but linked below is an excellent video series by Jeff Geerling that I used as a basis to build my cluster off of.

    Raspberry Pi Cluster Ep 1 - Introduction to Clustering
    In this video, I introduce the concept of Raspberry Pi clustering, and cluster computing in general. Technology like Beowulf clusters and Kubernetes has made...
    Single Part Raspberry Pi Compute Cluster

    This is a great guide for someone interested in setting up their own cluster from start to finish and I would highly recommend it.

    Resources for building your own cluster

    Here I am going to go over the basic steps and requirements for building your own cluster off of the design showcased above.

    Requirements:

    • x4 Raspberry Pi (2-3b+)
    • x1 TpLink TL-SG105 Gigabit Network Switch
    • x2 Sunon 40mm GM1204PQV1 fan
    • x1 5v 5A Barrel jack power supply and female plug
    • x1 Toggle Switch
    • x1 LM2596 Buck Converter
    • x4 6in Ethernet Cables
    • x4 8gb+ MicroSD Cards
    • x1 3-Way Screw Terminal
    • x10 10mm M3 screws
    • x8 25mm M3 screws
    • x4 M3 Nuts
    • Wire
    • 3D printer
    • Laser cutter if you want to be fancy
    • Lots of patience

    Below are the files that are needed to create this design. The assembly should be pretty self-explanatory just know that the 10mm M3 screws hold the panels to the 3D printed part while the 25mm ones and the nuts hold the fans. I have also included the files for the panels in DXF and STL formats if you do not have the means to laser cut them. The design should work just the same with them printed.


    ]]>