Infineon Team
Published © MIT

SunChaser - A MicroPython-Powered Solar Tracker

Unlock the full potential of renewable energy and harness the power of the sun for efficient data collection in AI projects.

AdvancedFull instructions providedOver 2 days3,210

Things used in this project

Hardware components

CY8CPROTO-062-4343W
Infineon CY8CPROTO-062-4343W
×1
LDR, 5 Mohm
LDR, 5 Mohm
×4
Resistor 10k ohm
Resistor 10k ohm
×4
servo motor MG995 (180)
×1
Servo motor MG995 (360)
×1
Breadboard (generic)
Breadboard (generic)
×1
Solar Panel, 2.5 W
Solar Panel, 2.5 W
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Battery, 3.7 V
Battery, 3.7 V
×1
Step-Up Voltage Regulator - 5V
SparkFun Step-Up Voltage Regulator - 5V
×1
Swivel Plate with Ball Bearing
×1

Software apps and online services

MicroPython
MicroPython
Thonny ID

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Tracker_base

Sketchfab still processing.

Tracker_cover

Sketchfab still processing.

Servo_V_holder

Sketchfab still processing.

second_axis_mount

Sketchfab still processing.

Solar_panel_holder

Sketchfab still processing.

LDR_Sensor

Sketchfab still processing.

Gear1

Sketchfab still processing.

Gear2

Sketchfab still processing.

Part1axis2

Sketchfab still processing.

Batt_holder

Sketchfab still processing.

Schematics

Tracker_shematics

Code

main

MicroPython
import time
from machine import PWM , ADC


# Define the PWM objects for the servo motors

horizontal_servo =PWM('P9_1', freq=50) # Horizontal servo on Pin 9
vertical_servo = PWM('P9_6', freq=50) # Vertical servo on Pin 10
        
        
        
servoh = 90 # Starting position for horizontal
servov = 45 # Starting position for vertical

servovLimitHigh = 150
servovLimitLow = 30
ldr_tl = ADC("P10_4") # Top Left LDR
ldr_tr = ADC("P10_2") # Top Right LDR
ldr_bl = ADC("P10_3") # Bottom Left LDR
ldr_br = ADC("P10_0") # Bottom Right LDR


def map_angle_to_value(angle_deg):
    """
    Maps an input angle (in degrees) to a value within the specified output range.

    Args:
        angle_deg (float): Input angle in degrees (between 0 and 180).

    Returns:
        int: Mapped value within the specified output range.
    """
    # Define the input and output ranges
    input_min = 0
    input_max = 180
    output_min = 0.025 * 65535  # 2.5% of 65535
    output_max = 0.125 * 65535  # 12.5% of 65535

    # Calculate the mapped value
    normalized_angle = (angle_deg - input_min) / (input_max - input_min)
    mapped_value = int(output_min + normalized_angle * (output_max - output_min))

    return mapped_value
def	set_servo_angle(servo, angle):
    duty = map_angle_to_value(angle)# Convert angle to duty cycle
    servo.duty_u16(duty)

tolerance = 3500 # Adjust this value as needed
update_interval = 0.05 # change to 1 minutes for outdoor tracking 
set_servo_angle(vertical_servo, servov)
set_servo_angle(horizontal_servo, 45)
time.sleep(update_interval)

set_servo_angle(horizontal_servo, servoh)

# 
# while True:    # Read LDR sensor values
for i in range (1000) : 
    top_left = ldr_tl.read_u16()
    top_right = ldr_tr.read_u16()
    bottom_left = ldr_bl.read_u16()
    bottom_right = ldr_br.read_u16()
    # Calculate differences between opposite LDRs
    horizontal_diff = (top_left+bottom_left) - (top_right+bottom_right)
    vertical_diff = (bottom_right+bottom_left) - (top_right+top_left)
    # Check and adjust the horizontal servo

    # Check and adjust the vertical servo
    if	abs(vertical_diff) > tolerance:
        if vertical_diff > 0 and servov > servovLimitLow:
            servov -= 1# Move down
        elif vertical_diff < 0 and servov < servovLimitHigh:
            servov += 1# Move up
        set_servo_angle(vertical_servo, servov)
    # Wait for the update interval before the next adjustment
    if abs(horizontal_diff) > tolerance:
        if horizontal_diff > 0:
            servoh = 10 
        elif horizontal_diff < 0 :
            servoh = 170 # Move right
        set_servo_angle(horizontal_servo, servoh)
    
    time.sleep(update_interval)
    set_servo_angle(horizontal_servo, 90)

Credits

Infineon Team

Infineon Team

90 projects • 134 followers

Comments