Project Managment

What I have done

I have finished most of the CAD modeling and figured out the basic of the electronics

What needs to be done

I still need to put all my electronics on the PCB boards, laser cut everything, and code everything.

The plan

Day What I need to do
June 5th On this day I plan on finishing all y cad designs by designing the plate and any electronic holders along with a way to attach the up and down mixer mover. Lastly I want to make sure all the materials I need for this project have been ordered so that I can get them on time.
June 6th On this day I want to make sure all my 3d prints fit and then redesign them if they don't. I also plan on designing the laser cut for the box around the carriage
June 7th On this day I would like to completely breadboard out all my electronics and start designing some PCB boards for all of it.
June 8th Today I Would like to finish designing the PCB boards and go ahead and mill them all out. While they are milling I would like to go ahead and laser cut out my basic box for my entire system to hold everything together.
June 9th On this day I Want to put everything together and start coding to all. Figure out what I need to fix and add to make it all work

Doing the Plan

June 5th

Today I started by getting my 3d prints for the end caps..


The next thing I had to do was design the plate that could connect to the sliders I had already made. To do this I made the plate and gave it some legs that would fit in the sliders so that it could connect to everything. Here is my design, and it once it was 3D printed.
image
image
Once I had it all printed out the plate I tested it all the carriage and here is a video of the whole thing.


And as seen here it worked great. This was a perfect sign for me and really motivated for me to continue. Next I had to design and 3d print the new pump holders so that I could hold the pumps in place for the liquids. To do this I designed it to fit onto a 1/8" inch wall which is what I plan to make the backdrop. Here is an image of the design and the actual 3d print.
image
image
After I had finished making the pumps I decided to design the box for the whole machine before the day ended. Here is an Image of my design.
image

June 6th

After yesterday I started out the day by cutting out my box, but I started with a test cut on cardboard as seen here.


image
image
image

After making sure it all fit I decided to test the gantry carriage system in the cardboard before the wood. To do this I just bread boarded out with the pico and motor driver.


After making sure this worked I then decided to cut it on wood and wood glue it all together.


image

Before the day ended I decided to design my boards to mill tomorrow. To do this I decided that I would do two boards, one on the control panel and another that holds the raspberry pi pico, and all the other devises I needed to control such as 3 pumps, 1 stepper motor, and a time-of-flight sensor. Here is an image of both the boards.

image
image

June 7th

Today I started out by milling the boards. I used the bantam milling machine and cut out both boards at the same time as seen here.


image

After milling out the board I decided to go ahead and solder the power to the switch and the pico just so that I could see if ti all worked together. I also got to test if naming a code main.py would really make it run on power up. Here is a video of it all working.


Now that I knew my code and boards would work I soldered all my buttons onto the button board as seen here.
image

Before soldering the rest I realized that I would actually need wholes for wires and power to pass through in my box, so I drilled them all into the box.
image
image
image

After making ways for all the wiring to be possible I then had time to solder on the motor driver and servo motor to my board before the day ended. Here is a video of the carriage going back and forth.


June 8th

My goal for today was to get buttons working and to get the limit action switch to work also. To start things off I had already soldered my buttons onto the board, but I still had to solder them to the Pico. Once this was done using my own knowledge of python and a little assistance from ChatGPT I ended up with a test code that made it so that the 3 buttons moved the plate forward 50, 100, 150 steps forward. And the silver start button moved the plate back 50 steps. Here is a video of it working.


Once I got this working I then soldered the Limit action switch to the PCB and changed the code so then when the silver button is pressed it makes the plate go back until the limit action switch is pressed so that it zeros out the whole system. Here is what it looked like after that.


Before ending the day I decided to get the system ready to add the Time of Flight VL53l0x sensor.
image
To prep for the sensor I needed to design a holder for the sensor so that it could be held straight so that it does not see something else. To do this I just made a open holder that you can slide the sensor into that would grab onto the t-bar aluminum tracks as seen here.
image
image

June 9th

It was at the start of today that I realized that my wiring was awful and that I was going to need a new plan.
image
After ripping a trace I decided to re mill my board and then re solder the whole thing with pin headers so that I could easily wire my whole project. Here is a video of me soldering and a picture of my wiring after soldering


image
Here in my wiring you can see all my components. I have 3 H-bridges, one of which controls the stepper, motor and the other two so that I can control the pumps. You can see my Raspberry Pi Pico W RP2040 as my microcontroller. You can see my 12v, 5amp power supply connected to everything with a voltage regulator in between.

June 10th

Today I got my pumps working using the code below.

import machine

# Pin assignments for L298N H-bridge
motor1_in1 = machine.Pin(6, machine.Pin.OUT)
motor1_in2 = machine.Pin(7, machine.Pin.OUT)

motor2_in1 = machine.Pin(8, machine.Pin.OUT)
motor2_in2 = machine.Pin(9, machine.Pin.OUT)

# Function to control motor direction
def control_motor(motor_in1, motor_in2, direction):
    if direction == 'forward':
        motor_in1.on()
        motor_in2.off()
    elif direction == 'backward':
        motor_in1.off()
        motor_in2.on()
    elif direction == 'stop':
        motor_in1.off()
        motor_in2.off()
    else:
        raise ValueError('Invalid direction')

# Example usage: Run both motors forward for 2 seconds
control_motor(motor1_in1, motor1_in2, 'forward')
control_motor(motor2_in1, motor2_in2, 'forward')
machine.sleep(2000)

# Stop both motors
control_motor(motor1_in1, motor1_in2, 'stop')
control_motor(motor2_in1, motor2_in2, 'stop)



Today I also molded a cup holder to out of silicone to put in the plate to help absorb some vibration and cause less spoilage. To do this I used one of the hold cup holders because the measurements are the same diameter and put a red solo cup in so that the could cast silicone as seen below.
image
image
image

June 11th

Today I coded the whole project. But before that I noticed that even if my wiring looks a lot better it still is not the best, so I laser cut some covers on black acrylic to somewhat cover it up.


After this I had to code the whole project. Here is a video of me coding, and my maybe final code listed below with comments to help explain it all.


from machine import Pin
from time import sleep
from machine import Pin, I2C
from vl53l0x import VL53L0X

#extra variables
step = 0
sodas = 0
fill_cup = 10
button1_hit = 0
button2_hit = 0
button3_hit = 0
button4_hit = 0

#setting up time of flight sensor
sda = Pin(0)
scl = Pin(1)
id = 0
i2c = I2C(id=id, sda=sda, scl=scl)
tof = VL53L0X(i2c)
budget = tof.measurement_timing_budget_us
print("Budget was:", budget)
tof.set_measurement_timing_budget(40000)
tof.set_Vcsel_pulse_period(tof.vcsel_period_type[0], 12)
tof.set_Vcsel_pulse_period(tof.vcsel_period_type[1], 8)

#setting up buttons
# Button GPIO Pins
button1_gpio = 18 # start
button2_gpio = 19 # lower
button3_gpio = 21  # middle
button4_gpio = 20  # upper
# Button Pins
button1 = Pin(button1_gpio, Pin.IN, Pin.PULL_UP)
button2 = Pin(button2_gpio, Pin.IN, Pin.PULL_UP)
button3 = Pin(button3_gpio, Pin.IN, Pin.PULL_UP)
button4 = Pin(button4_gpio, Pin.IN, Pin.PULL_UP)
# Variables to track button states
button1_state = 1
button2_state = 1
button3_state = 1
button4_state = 1

#setting up limit action switch
# Limit Action Switch GPIO Pin
limit_switch_gpio = 15
#limit pin
limit_switch = Pin(limit_switch_gpio, Pin.IN, Pin.PULL_DOWN)

#setting up stepper motor
#pins
IN1 = Pin(2, Pin.OUT)
IN2 = Pin(3, Pin.OUT)
IN3 = Pin(4, Pin.OUT)
IN4 = Pin(5, Pin.OUT)
#pin array
pins = [IN1, IN2, IN3, IN4]
#turning sequence for pins
sequence_clockwise = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
sequence_counterclockwise = [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]
#stepper paramiters
steps_per_revolution = 200 
delay = 0.001
# Set all pins to LOW initially
for pin in pins:
    pin.value(0)

#pumps
#two
motor2_in1 = machine.Pin(6, machine.Pin.OUT)
motor2_in2 = machine.Pin(7, machine.Pin.OUT)
#three
motor3_in1 = machine.Pin(8, machine.Pin.OUT)
motor3_in2 = machine.Pin(9, machine.Pin.OUT)
#one
motor1_in1 = machine.Pin(12, machine.Pin.OUT)
motor1_in2 = machine.Pin(13, machine.Pin.OUT)

def step_forward(num_steps):
    sequence = sequence_clockwise
    for _ in range(num_steps):
        for step in sequence:
            for i in range(len(pins)):
                pins[i].value(step[i])
            sleep(delay)

def step_backward(num_steps):
    sequence = sequence_counterclockwise
    for _ in range(num_steps):
        for step in sequence:
            for i in range(len(pins)):
                pins[i].value(step[i])
            sleep(delay)

def stepper_idle():
    for pin in pins:
        pin.value(0)

def button_callback(pin):
    global button1_state, button2_state, button3_state, button4_state, button1_hit, button2_hit, button3_hit, button4_hit

    if pin == button1 and button1_state == 0:
        if button1_hit == 0:
            button1_hit = 1
            sleep(.1)
        elif button1_hit == 1:
            button1_hit = 0
            sleep(.1)
        sleep(.1)

    elif pin == button2 and button2_state == 0:
        if button2_hit == 0:
            button2_hit = 1
            sleep(.1)
        elif button2_hit == 1:
            button2_hit = 0
            sleep(.1)
    elif pin == button3 and button3_state == 0:
        if button3_hit == 0:
            button3_hit = 1
            sleep(.125)
        elif button3_hit == 1:
            button3_hit = 0
            sleep(.125)
    elif pin == button4 and button4_state == 0:
        if button4_hit == 0:
            button4_hit = 1
            sleep(.125)
        elif button4_hit == 1:
            button4_hit = 0
            sleep(.125)
    button1_state = button1.value()
    button2_state = button2.value()
    button3_state = button3.value()
    button4_state = button4.value()

button1.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=button_callback)
button2.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=button_callback)
button3.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=button_callback)
button4.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=button_callback)

def zero_machine():
    while limit_switch.value() == 0:
        step_backward(1)

def move_to_place(place):
    print("move to place was called")
    while True:
        distance = tof.ping() - 50
        if distance < place:
            step_forward(1)
        elif distance > place:
            step_backward(1)
        else:
            break
        sleep(delay)  # Add a small delay between steps for smoother motion

    stepper_idle()

while True:

    button1_state = button1.value()
    button2_state = button2.value()
    button3_state = button3.value()
    button4_state = button4.value()
    #zero machine when turned on
    if step == 0:
        zero_machine()
        step = 1
        sodas = 0
    elif step == 1:
        if button1_hit == 1:
            if button2_hit == 1:
                sodas += 1
            elif button3_hit == 1:
                sodas += 1
            elif button4_hit == 1:
                sodas += 1
            step = 2
    elif step == 2:
        if button2_hit == 1:
            move_to_place(136)
            motor1_in1.on()
            motor1_in2.off()
            sleep(fill_cup/sodas)
            motor1_in1.off()
            motor1_in2.off()
        if button3_hit == 1:
            move_to_place(236)
            motor2_in1.on()
            motor2_in2.off()
            sleep(fill_cup/sodas)
            motor2_in1.off()
            motor2_in2.off()
        if button4_hit == 1:
            move_to_place(330)
            motor3_in1.on()
            motor3_in2.off()
            sleep(fill_cup/sodas)
            motor3_in1.off()
            motor3_in2.off()
        step = 3
    elif step == 3:
        zero_machine()
        sleep(5)
        step = 0
        button1_hit = 0
        button2_hit = 0
        button3_hit = 0
        button4_hit = 0

     # Perform other tasks or pause the program
    sleep(0.125)

    # Check if all buttons are released
    if button1_state == 1 and button2_state == 1 and button3_state == 1 and button4_state == 1:
        stepper_idle()
    print(button1_hit)
    print(button2_hit)
    print(button3_hit)
    print(button4_hit)
    print()


And lastly here is that code working.


All thats left now is to add the tubing and test with liquids which I have to wait till tommorow becuase thats when tubing gets here.

Final result

After getting and attaching the tubing here is a video of everything working.



Files

All Files Download