Real-Time Insights
GUSH-OS feeds us live data insights, pushing innovation and efficiency.
All running on a Raspberry Pi 5.
CTO
Vertical Strawberry Farm Start-up
2024-Present
gush.farmHARVESTS TRACKED
% LABOUR EFFICIENCY INCREASE
% YIELD INCREASE
As CTO at GUSH, I've had the privilege of working with an incredible team of dedicated mission driven individuals to advance indoor vertical strawberry cultivation.
Joining just a few months after the farm's construction, I knew that optimizing operational efficiency and yield required reliable and highly automated data collection and analysis.
In the first month, I designed and built the 'Binscanner' which automated yield data collection. I also built a robust data model and database, and 'GUSH-OS' a custom web-app front-end to integrate, visualize and analyze all the farm's data. Finally, I built the 'GR-NFC' which tracks labour efficiency.
One key success was the design and implementation of a cost-effective solution to double our light uniformity across the entire farm, resulting in a 53% increase in yield.
Beyond these projects, my role at GUSH involves hands-on engineering across multiple disciplines - from designing industrial sized farms, integrating mechanical, fluid, electrical and biological systems, optimizing automation controls flows, and developing software solutions, to leading agronomic initiatives, experimental trials, strategic decision making and operations.
import LCD_1in44
from PIL import Image, ImageDraw, ImageFont
from datetime import datetime
import pytz
import sys
import time
from threading import Thread
import queue
from Gsheets import PostSheet, create_and_use_service_account
from sqlalchemy import create_engine
def main():
try:
# Initialize components
disp = initialize_display()
image, draw = initialize_graphics(disp)
engine = initialize_database()
input_thread = initialize_input_thread()
# Initialize state
current_state = 'IDLE'
harvester = None
bin_or_action = None
# Main loop
while True:
# Handle RFID scans
handle_rfid_scans(input_queue)
# Handle button inputs
handle_button_inputs(disp)
# Update state machine
current_state = update_state_machine(current_state)
# Update display
update_display(current_state, image, draw)
# Show updated display
disp.LCD_ShowImage(image, 0, 0)
time.sleep(0.1)
except KeyboardInterrupt:
cleanup(disp)
except Exception as e:
print(f"Error in main loop: {e}")
cleanup(disp)
if __name__ == "__main__":
main()
GUSH-OS feeds us live data insights, pushing innovation and efficiency.
All running on a Raspberry Pi 5.
import datetime
from GSheets import PostSheet, GetLastEntry, upload_file_to_drive
from dymoM11 import get_bin_weight
from Cam2 import capture_image
from functions import check_wifi_connection
from gui import run_gui, nfc_page, confirm_data
def main():
# 1. Initial Setup
check_wifi_connection()
values = run_gui() # Get initial input values from GUI
while True:
# 2. NFC Card Reading
if values['bin_id'] is None:
nfc_data = nfc_page()
# Process NFC data to get bin_id
# Continue only when valid bin card is scanned
# 3. Data Collection
bin_weight = get_bin_weight()
image = capture_image()
# 4. Generate Scan ID
scan_id = int(GetLastEntry()) + 1
# 5. Process and Save Image
image_path = f"{scan_id}-Berries.jpeg"
cv2.imwrite(image_path, image)
# 6. Upload to Google Drive
image_id = upload_file_to_drive(image_path)
# 7. Process and Submit Data
try:
confirm_data(
scan_id=scan_id,
date=datetime.datetime.now().date(),
time=datetime.datetime.now().time(),
bin_id=values['bin_id'],
bin_weight=bin_weight,
berry_weight=calculate_berry_weight(bin_weight, values['pack_type']),
cultivar_id=values['cultivar_id'],
grow_room=values['cycle_id'][:3],
cycle_id=values['cycle_id'],
grade=values['grade'],
pack_type=values['pack_type'],
week_num=calculate_week_number(),
group_id=values['group_id']
)
values['bin_id'] = None # Reset for next scan
except Exception as e:
print(f"Error submitting data: {e}")
break
if __name__ == "__main__":
main()
#README
#PINOUT
# Positive to 3.3V
# Negative to GND
# Signal to GPIO0
# SETUP
# ls /dev/tty.*
# rshell -p /dev/tty.usbmodem*
# cp main.py /pyboard/main.py
# repl
# import main
from gpiozero import Servo
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
# Initialize pigpio factory
factory = PiGPIOFactory()
# Create servo on GPIO17 using pigpio with specific pulse widths
# MG90S servo uses 500-2400 microseconds
servo = Servo(14,
min_pulse_width=0.0005, # 500us
max_pulse_width=0.0024, # 2400us
pin_factory=factory)
try:
while True:
print("Moving to maximum position")
servo.value = -0.18 # Full clockwise
sleep(0.2)
print("Moving to minimum position")
servo.value = -0.8 # Full counter-clockwise
sleep(0.2)
except KeyboardInterrupt:
print("\nExiting program")
servo.detach()