Solar Powered Mechanical Light Sensitive Flower

by hannu_hell in Circuits > Raspberry Pi

2961 Views, 34 Favorites, 0 Comments

Solar Powered Mechanical Light Sensitive Flower

37.jpg
cover.gif
breath.gif
32.jpg

This project is the design of a mechanical flower which is sensitive to light and moves in the direction of light. I started off in my mind to design a compact one but as always things don't necessarily go exactly as planned. Having turned out to be a bit bigger than I hoped, I am happy that this would make a nice addition to display in my living space. The flower can be powered by solar panels as well as charged externally if required. If kept in a well lit place and the solar charging enabled it could go on working for long periods of time without charging.

I have designed the flower with 6 moveable petals and the stem is of three parts where the two upper parts are moveable. The stem has two degrees of freedom whereas each individual petal has one degree of freedom. All the parts were designed in Fusion 360 and 3D printed. The petals are lighted up with individual addressable Neo-pixels and are powered by a 5V battery which is recharged using solar panels.

The Flower is controlled using a Raspberry Pi Pico and programmed in Circuit Python which is a fork of Micro Python which is similar to the python programming language. It also has a ST7735 tft display which shows the date and time information from the DS1307 Real Time Clock module. Special thanks to PCBWay for providing the PCB for this project.

Supplies

  • 2 x ES3001 37g Analog Servos (Most hobby shops or RC Aircraft parts shops have these. I had them from an old project I worked on)
  • 3D Printing Filament (Black, Red)
  • Spray Paint (Yellow, Green) - I used them because i didn't have the color 3D filament.
  • 3D Printer
  • Hex Screws and Nuts (Diameter 2.5mm) 10mm and 15mm lengths
  • Super Glue
  • Radial Bearing
  • 6 x 4.3g Digital Servo (These also can be obtained from RC Aircraft parts shops)
  • 5V Lipo Battery (3600 mAh)
  • 5V 3A Solar Charge Controller
  • 1 x Thrust Bearing (Inner Diameter: 8mm, Outer Diameter: 22mm, Height:7mm)
  • 1 x Radial Bearing (Inner Diameter:8mm)
  • 4 x 200mA Solar Panels (120mm x 60mm)
  • 1 x 60mA Solar Panel (68mm x 37mm)
  • 28AWG Electrical Wires
  • 22AWG Electrical Wires
  • 1 x Roller type Omron Limit Switch
  • 2 x Push Buttons
  • 1 x One Way On/Off switch
  • 1 x Two Way On/Off switch
  • 3 x Photo-resistors
  • 3 x 10KOhm resistors
  • 1 x IN5933 diode
  • 1 x IN4007 diode
  • 1 x Raspberry Pi Pico
  • 1 x DS1307 RTC module
  • 1 x Logic Level Convertor module
  • 1 x ST7735 TFT display
  • 1 x 24BYJ48 stepper motor
  • 1 x ULN2003 stepper driver module

Flower Design

mf2.png
stem.gif

I started designing from the top of the flower as that would be the main weight which needed to be supported from the flower stem. That way I would be able to figure out the dimensions of the stem later on in the design stages. The hardware also needed to be tested before designing as changing the design later on would mean more trouble and work as every part fitted and assembled according to their dimensions. The analog servos were checked if the would be able to carry the load of the flower bud and the petals and their respective servos. It was also important to make room to route the wires coming from the servo up top from the petals all the way down to the flower pot where all the electronics were housed.

The flower was designed in such a way that three petals were located a bit inner to the center of the flower and the other three petals a bit outer. This allowed just enough room for the petals to move freely without mechanical interference. The mid section of the flower houses a pollen like tall structure which houses the three photo resistor which detect light. All three of them are covers on the sides so that when light hits an any one of the photo resistor it would block the light hitting on other two. This was it would be possible to get the direction of light which is the strongest or weakest for that matter.

As for the petals, the material used was 1.5mm thick rubber sheets which were cut in petal shape and fitted onto the structure which mounted the servos. Beneath them also were space that accommodate the Neo-pixels for each petal which lights up the petals.

Design of Flower Base

mf4.png
mf6.png
mf7.png
mf12.png
1.jpg
2.jpg

Each petal of the flower is held in place by a 4.3g servo hinged by servo arms that fitted into the slots on the flower base structure. A second smaller structure was slotted into the top of each servo holders of the petals. These smaller structures have cutouts to insert the flexible transparent material cutouts in the shape of petals. The Neo-pixels are placed beneath each petal at a 45 degree angle to diffuse the light onto the petals.

The mid section of the flower base would house the pollen structure which would be glued on later. The pollen structure has holes cutout to pass the legs of the photo resistors. Each of the servo holders for the petals are hinged on both sides for added support and the opposite side to the servo arm is supported by a small metal rod (6mm in length). The flower base structure has a cutout on the bottom to slot in the flower bud. The petals were spray painted in yellow color on the outer section avoiding the section where the Neo-pixels lights up.

Design of Flower Bud

mf8.png
mf3.png
glow.gif

The flower bud slots into the base structure of the flower and is then glued in position. The flower bud is designed in a way that it gives enough room for the movement of the petals. The base of the flower bud also has 5mm deep cutouts for the upper stem to slot in. All the wiring from the servos, Neo-pixels and routed from the sides of the flower bud and then through the gap between the flower bud and the upper stem structure. This was a bit tricky as I had glued in the upper stem for testing the flower stem servos before routing the wires. It would have been easier if I had routed the wires before gluing in the upper stem. The order of operations is very important as it would reduce the workload and possibly avoid making mistakes.

Finally after routing the wires through the upper stem things the 37g upper stem servo was fitted into the upper stem slot and screwed in. I used a round servo horn for the stem servos as there would more mechanical engagement on the structures.

Design of Flower Stem

mf9.png
mf10.png
mf11.png
4.jpg
7.jpg

The flower stem was designed in three parts. The two upper parts are able to move and the lower part of the stem gives the height of the stem. The upper and lower parts are designed with a slant which gives a more natural look. Each part of the stem has holes cutout from the top to the bottom where wires can be routed through the stem. This was necessary to keep the flower agile but also for better looks. The second section of the stem is designed to hold a small leaf. The protruding arm like structures has holes to fit in the small leaf. The small leaf has a 60mA solar panel fitted on top of it.

Design of Flower Leaves

mf13.png
mf14.png
mf16.png
3.jpg

The mid stem section has a smaller leaf and the bottom stem section has four bigger leaves. The bottom leaves each houses a 200mA 120mm x 60mm solar panel. The leaves are designed with cutouts at the bottom for the wires to go through. The leaves are also designed with a slight slant to give a more natural look. Once designed and 3D printed, I sprayed green spray paint on it. The leaves were fitted in to the slots on the stem and glued in later on.

The smaller leaf does not provide much current but there was a more significant reason to place it there besides the power needs and looks. It provides a counter balance for the mid section stem servo when it hinges. This would reduce the load on the mid section servo as it would be supporting the whole flower structure as well as the upper stem. There are certain limitations to the movement of the servo such as going backwards less than 10 degrees would mechanically interfere so those angles should be avoided.

Design of Flower Root

mf17.png
mf18.png
heating.gif
mf19.png
15.jpg
16.jpg

The root of the flower is glued to the end of the bottom stem and all the wires from the top route down to the flower pot through the flower root. The bottom of the root has a protruding shaft with a 4mm hole to insert a metal rod for strength. This was necessary as the shaft is plastic and the metal rod would prevent from it bending and failing owing to axial loads when the flower rotates. The limit switch pusher is screwed to one side of the flower root which comes in contact with the limit switch when it rotates to a certain angle.

The lower end of the shaft is designed with a hex shape which can fit into the top part of the top coupler. The top coupler has a hex shape cutout where the bottom end of it fits into the strut which is bolted to the coupler at the bottom that is fixed to the shaft of the stepper motor which turn the flower. The top coupler sits on top of the thrust bearing which takes on the axial loads from the total weight of the flower and its components. A radial bearing in placed above the coupler to counter radial loads when the stem moves outwards.

Design of Bearing Enclosure

mf20.png
mf21.png
mf23.png
12.jpg
13.jpg

The bearing enclosure was designed in two piece and bolted together after the components were put in place. It houses the radial bearing, thrust bearing and the coupler. The legs of the enclosure are bolted to the top half of the flower pot. Once again it is important to note the order of operations as the shaft needs to fitted in through the radial bearing, coupler and the thrust bearing with one half of the enclosure. Once all the parts are seated in the enclosure, the other half can then be bolted on to the opposite half of the enclosure. The limit switch is fixed to one half of the bearing enclosure so that when the limit switch pusher on the flower root turns as the stepper motor turns it comes in contact to determine the starting position. The limit switch is necessary as continuous turning without limiting would cause the wires to get entangled with the flower stem and limit the motion of the flower as it turns.

I could have made the design more robust and mechanically stable by using aluminum rods instead of plastic shaft to fit in the bearings. Even though the plastic shaft is fitted with a 4mm metal rod, the properties of plastic allows to give more tolerances owing to mechanical vibrations and deformations when in action.

Design of Flower Pot

mf24.png
mf25.png
18.jpg
20.jpg
21.jpg
22.jpg

The flower pot is designed in three parts. The bottom part, the top part and the lid. The bottom part houses the battery, solar charge controller, and the ULN2003 stepper motor driver. On the sides of the bottom part there are two switches, one to turn the power on to the flower and another to switch between solar charging and external charging. In addition to this there is micro USB charge port for charging the battery externally.

The top part of the flower pot houses the PCB for all the electrical connections. The bearing enclosure is also fixed to the top part of the flower pot. The stepper motor is also fixed on the top part of the flower pot. It has holes cutout to guide the wires from the bottom part of the flower pot to the top part and vice versa.

The flower pot lid houses two push buttons. One is to activate and deactivate the light following mode of the flower. The other switch can be programmed to do various functions such as to move the petals in a certain pattern or close up or open up the petals depending on certain lighting conditions. It can also be programmed to show different color gradients from the Neo-pixels depending on the time of the day (The RTC module provides the date and time information). The flower lid also has the ST7735 TFT display housing fixed which gives the date and time information. The top part and the bottom part of the flower pot are bolted in and the lid finally bolted in to the top part.

Electronics and PCB Design

28.jpg
pcb_design.png
2d_pcb.png

The flower is powered by a 5V Lipo battery which can be charged using the solar panels as well as externally if required. It is controlled by a Raspberry Pi Pico and all its GPIO pins are utilized in this project. The real time clock (RTC) module (DS1307) communicates with the Pico using the I2C protocol and requires to shift its logic level voltage as the RTC is a 5V logic module and the pins on Pico are 3.3V tolerant. Therefore a logic level convertor is used to shit the logic when communicating.

The ST7735 TFT display communicates with the PICO via SPI protocol and is used to display the time and date information on the display. It is also capable of showing bitmap images and is limited to the storage capacity of the Raspberry Pi Pico which is 1MB. The display itself has an SD Card slot but to communicate with the Pico it would require more GPIO pins which in this case was not an option as all the pins were already in use.

The three photo resistors are connected with 10KOhm pull down resistors on each and the readings obtained are from 0 to 65536 with higher values indicating more light and lower indicating less light. Its a bit surprising that the results show a 16 bit ADC (Analog to Digital Convertor) reading although the Pico has a 12 bit ADC.

There are two capacitors of 22 MicroFarad placed between the positive and negative terminals leading to the power rails of the six smaller servos (4.3g) which moves the petals and two bigger servos (37g) which moves the two upper parts of the flower stem.

In order to prevent reverse voltage spikes from the stepper motor flowing back to the Pico, a diode (IN4007) has been placed between the common ground whereby only current can flow into the motor and not the other way around.

A one way power on/off switch connects the battery to the power rail of all the components. Another two way switch is used to switch between charging modes. Switching the in one direction allows for charging of the battery using the solar panels and switching to the other direction allows to charge the battery externally through the micro USB port. This would come handy as solar charging might sometimes take some time while charging externally would require less time. To be fair this switching was most handy during the testing period where you would drain the battery often times faster than recharging and in conditions with inadequate lighting. The schematic is attached if anyone is interested in having a look.

The circuit schematic was designed using EasyEda software and the PCB design was created once the schematic was finalized. The EasyEda software has a rich library of components which can be easily searched and deployed in any of your projects. They also have a numerous amount of user contributed components which their footprint match most of the available components in the market.

PCBWAY

24.jpg
26.jpg
25.jpg
23.jpg

Once the design of the PCB was completed it was time to place the order from PCBWAY. By generating the gerber files of project and uploading it online to PCBWAY. You have many options to customize your pcb design and since I wanted my flower pot to fit in all the electronics in a circular shape i decided to design the pcb in a round shape with a circular cutout in the middle and rectangular cutouts at both ends. This would give enough room for the bottom stepper motor as well as the bearing housing legs. I ordered pcb in yellow color since there are many color options and pcb layer option available on their website.

After placing the order the review process took less than 10 minutes and was approved almost instantly. From then on the production process started and I received the PCBs in 3 days. The quality of the PCBs were very good and the finishing was amazing. It fitted perfectly in the flower pot with all the components in the right place.

If you would like to make your projects look neater and compact you can get your custom PCBs for your projects from PCBWAY at reasonable rates.

Connecting the Electronics

elec2.gif
elec.gif
27.jpg

After receiveing the PCB, it was time to make all the connections. Before mounting the PCB to the flower pot all the wires were soldered on the PCB and since they were all labeled there was little chance of making any mistake. Pin headers were soldered intially to the PCB for mounting the Raspberry Pi Pico and the DS1307 module. All the other components such as the logic level shifter and the wires leading to the ST7735 display were directly soldered onto to the PCB. The two push buttons were glued onto the flower pot lid and their leads soldered to the PCB.

Programming the Flower

screen.gif
light.gif

The Circuit Python which is a fork of Micro Python was used to program the Raspberry Pi Pico as they already have an abundance of libraries which support the many hardware components. Its ease of use makes it simpler for testing prototyping fast. Some of the external libraries used are adafruit_register, adafruit_motor, adafruit_display_text, adafruit_bus_device, adafruit_ds1307, adafruit_pixelbuf, adafruit_st7735r, adafruit_ticks, neopixel libraries.

12.1 Setting up RTC module and ST7735 TFT display

import time
import board
from digitalio import DigitalInOut, Direction, Pull
from adafruit_st7735r import ST7735R
import displayio
import terminalio
import busio
from adafruit_display_text import label
import adafruit_ds1307

# RTC setup
i2c = busio.I2C(board.GP1, board.GP0) # SCL and SDA pins
rtc = adafruit_ds1307.DS1307(i2c)

# Create python list for extracting the month and day of week from number received from RTC module.
months = ['JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER']
week = ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY']

# Create RTC object
t = rtc.datetime

# Setting up the SPI Pin interface for ST7735 display
mosi_pin = board.GP11
clk_pin = board.GP10
reset_pin = board.GP17
cs_pin = board.GP18
dc_pin = board.GP16

displayio.release_displays()
spi = busio.SPI(clock=clk_pin, MOSI=mosi_pin)
display_bus = displayio.FourWire(spi, command=dc_pin, chip_select=cs_pin, reset=reset_pin)
display = ST7735R(display_bus, width=128, height=160, bgr = True)

# Bitmaps stored on the raspberry pi pico
bitmap = displayio.OnDiskBitmap("/slide_show/a.bmp")
bitmap1 = displayio.OnDiskBitmap("/slide_show/b.bmp")
bitmap2 = displayio.OnDiskBitmap("/slide_show/c.bmp")
bitmap3 = displayio.OnDiskBitmap("/slide_show/d.bmp")
bitmap4 = displayio.OnDiskBitmap("/slide_show/e.bmp")
bitmap5 = displayio.OnDiskBitmap("/slide_show/f.bmp")
group = displayio.Group()
display.show(group)

# This block of code is for displaying the flower bitmaps at the start of the program on the screen.
# It changes the colors of the petals on the the bitmap of flower on the screen
tile_grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader)
group.append(tile_grid)
time.sleep(0.5)
tile_grid = displayio.TileGrid(bitmap1, pixel_shader=bitmap.pixel_shader)
group.append(tile_grid)
time.sleep(0.5)
tile_grid = displayio.TileGrid(bitmap2, pixel_shader=bitmap.pixel_shader)
group.pop()
group.append(tile_grid)
time.sleep(0.5)
tile_grid = displayio.TileGrid(bitmap3, pixel_shader=bitmap.pixel_shader)
group.pop()
group.append(tile_grid)
time.sleep(0.5)
tile_grid = displayio.TileGrid(bitmap4, pixel_shader=bitmap.pixel_shader)
group.pop()
group.append(tile_grid)
time.sleep(0.5)
tile_grid = displayio.TileGrid(bitmap5, pixel_shader=bitmap.pixel_shader)
group.pop()
group.append(tile_grid)
time.sleep(0.5)

# Creates another group for displaying the date and time on the display
splash = displayio.Group()
display.show(splash)
color_bitmap = displayio.Bitmap(128, 160, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xe3c524  # Yellow Color
bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(118, 150, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x000000  # Black Color
inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=5, y=5)
splash.append(inner_sprite)

# Display the label "TIME"
text_time_label = displayio.Group(scale=1, x=50, y=24)
text_time_label_content = "TIME"
text_time_label_spot = label.Label(terminalio.FONT, text=text_time_label_content, color=0xe3c524)
text_time_label.append(text_time_label_spot)  # Subgroup for text scaling
splash.append(text_time_label)

# Display the actual time from the RTC module
text_time_value = displayio.Group(scale=2, x=35, y=54)
text_time_value_content = f"{t.tm_hour}:{t.tm_min}" # Get the time in hours and minutes
text_time_value_spot = label.Label(terminalio.FONT, text=text_time_value_content, color=0xf31c28)
text_time_value.append(text_time_value_spot)  # Subgroup for text scaling
splash.append(text_time_value)

# Display the label "DATE"
text_date_label = displayio.Group(scale=1, x=50, y=84)
text_date_label_content = "DATE"
text_date_label_spot = label.Label(terminalio.FONT, text=text_date_label_content, color=0xe3c524)
text_date_label.append(text_date_label_spot)  # Subgroup for text scaling
splash.append(text_date_label)

# Display the actual date from the RTC module
text_date_value = displayio.Group(scale=1, x=35, y=110)
text_date_value_content = f"{t.tm_mday} {months[int(t.tm_mon)-1]}\n{week[int(t.tm_wday)-1]}"
text_date_value_spot = label.Label(terminalio.FONT, text=text_date_value_content, color=0xf31c28)
text_date_value.append(text_date_value_spot)  # Subgroup for text scaling
splash.append(text_date_value)


12.2 Setting up Neo-Pixels

import time
import board
from digitalio import DigitalInOut, Direction, Pull
from rainbowio import colorwheel
import neopixel


pixel_pin = board.GP13
num_pixels = 6
# Initialize the pixels
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)

RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)

# Color Gradients of Blue
BLUE1 = (7, 0, 196)
BLUE2 = (0, 0, 255)
BLUE3 = (0, 82, 255)
BLUE4 = (0, 122, 255)
BLUE5 = (0, 163, 255)
BLUE6 = (0, 204, 255)

# Fucntions for neopixel animations from adafruit
def color_chase(color, wait):
    for i in range(num_pixels):
        pixels[i] = color
        time.sleep(wait)
        pixels.show()
    time.sleep(0.01)
    
def rainbow_cycle(wait):
    for j in range(255):
        for i in range(num_pixels):
            rc_index = (i * 256 // num_pixels) + j
            pixels[i] = colorwheel(rc_index & 255)
        pixels.show()
        time.sleep(wait)

b = 0.1
# Function for breathing effect of blue gradient pixels on the six petals
def breath_pixels():
for i in range(5):
    pixels.deinit() # Deinitialize pixels before sending new signal for addressing the neopixels
# Changes the brightness parameter 'b' by 0.1 each loop
    pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=b, auto_write=False)
    for i in range (8):
        pixels.deinit()
        pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=b, auto_write=False)
        pixels[0] = BLUE1
        pixels.show()
        pixels[1] = BLUE2
        pixels.show()
        pixels[2] = BLUE3
        pixels.show()
        pixels[3] = BLUE4
        pixels.show()
        pixels[4] = BLUE5
        pixels.show()
        pixels[5] = BLUE6
        pixels.show()
        b+=0.1
        time.sleep(0.01)

    for i in range (8):
        pixels.deinit()
        pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=b, auto_write=False)
        pixels[0] = BLUE1
        pixels.show()
        pixels[1] = BLUE2
        pixels.show()
        pixels[2] = BLUE3
        pixels.show()
        pixels[3] = BLUE4
        pixels.show()
        pixels[4] = BLUE5
        pixels.show()
        pixels[5] = BLUE6
        pixels.show()
        b-=0.1
        time.sleep(0.01)


12.3 Setting up photo resistors, stepper motor and limit switch

import time
import board
from digitalio import DigitalInOut, Direction, Pull
import analogio
from adafruit_motor import stepper

# Setup limit switch
switch = DigitalInOut(board.GP12)
switch.direction = Direction.INPUT
switch.pull = Pull.UP

photo_resistor1 = analogio.AnalogIn(board.GP26)
photo_resistor2 = analogio.AnalogIn(board.GP27)
photo_resistor3 = analogio.AnalogIn(board.GP28)

# Setup coils for stepper motor
coils = (
    DigitalInOut(board.GP19),  # A1 (In4)
    DigitalInOut(board.GP21),  # A2 (In2)
    DigitalInOut(board.GP22),  # B1 (In1)
    DigitalInOut(board.GP20),  # B2 (In3)
)

for coil in coils:
    coil.direction = Direction.OUTPUT

stepper_motor = stepper.StepperMotor(
    coils[0], coils[1], coils[2], coils[3], microsteps=None
)

not_limit = True

""" Stepper motor forward and backward movement fucntions defined below. 'not_limit' is a global boolean variable where it is initially set to True. When the limit switch is pushed this variable changes to False and moves the stepper motor forward 20 steps and then changes back the value of it to True. This is defined in the stepper_back function below as the limit switch will only be triggered when the stepper moves back. """

def stepper_fwd(steps):
    for _ in range(steps):
        stepper_motor.onestep(direction=stepper.FORWARD)
        time.sleep(0.01)
    stepper_motor.release()

def stepper_back(steps):
    global not_limit
    if not_limit:
        for _ in range(steps):
            stepper_motor.onestep(direction=stepper.BACKWARD)
            time.sleep(0.01)
            if switch.value:
                not_limit = False
                break
    stepper_motor.release()
    if not not_limit:
        for _ in range(30):
            stepper_motor.onestep(direction=stepper.FORWARD)
            time.sleep(DELAY)
            not_limit = True

""" The follow_light function below allows the flower to follow the light whereever it is brightest.
step_count is a global variable which keeps track of the amount of steps moved by the stepper motor.
It starts by moving the flower to the initial location where it moves back until the limit switch is pressed. It then reads the values from the three photo resistors. It should be noted that the front of the flower which the stem can bend is between the photo resistor 2 and photo resistor 3, therefore it first compares the value of p2 with p1 and then if p2 is less than p1 it moves in larger steps (100 steps) until p2 is greater than p1. Once p2 is greater than p1, it has to compare with p3 to position the flower in the correct point where it is brightest. To do this it needs to move in smaller steps as p2 and p3 are closer to each other and minute changes need to be made to position itself. If the flower reaches its limits while moving it moves a complete turn in the opposite direction to reach the desired position. I have defined higher number of steps in some cases as the stepper motor sometimes skips steps sometimes owing to the loads and restriction of movement due to the position of wires. """

step_count = 0

def follow_light(micro_steps):
    global step_count
    stepper_back(4000)
    while True:
        p3 = photo_resistor3.value
        p1 = photo_resistor1.value
        p2 = photo_resistor2.value
        if not redButton.value:
            break
        if p1 > p2:
            if step_count > 1600:
                stepper_back(1500)
                step_count-=1500
            if step_count <= 1600:
                stepper_fwd(100)
                step_count+=(100)
        if p2 > p1:
            if p2 > p3:
                if (p2 - p3) > 3000:
                    if step_count > 4000:
                        stepper_back(3900)
                        step_count-=3900
                    if step_count <= 4000:
                        stepper_fwd(micro_steps)
                        step_count+=micro_steps
            if p3 > p2:
                if (p3 - p2) > 3000:
                    if step_count < 100:
                        stepper_fwd(3900)
                        step_count+=3900
                    if step_count >= 100:
                        stepper_back(micro_steps)
                        step_count-=micro_steps


12.4 Setting up servos for the petals and the stem

import time
import board
from digitalio import DigitalInOut, Direction, Pull
import pwmio
from adafruit_motor import servo

""" Below variables are global variables which are initialized and deinitialized when needed. I needed to do this because sometime when servos were initialized the neopixels were not giving the correct signal. This could be because everything is powered using the same source but I am not sure. I found that when i deinitialized the servo pins, the neopixels were addressed as expected. Therefore put the initializationof the servos and deinitialization in seperate fucntions and whenever I needed to address the neopixels i deinitialized the servos and again initialized them back when i wanted to move the servos. If anyone knnows for sure exactly I would love to know, but for now this fixes it """

petal1 = None
petal2 = None
petal3 = None
petal4 = None
petal5 = None
petal6 = None
pwm_servo_1 = None
pwm_servo_2 = None
pwm_servo_3 = None
pwm_servo_4 = None
pwm_servo_5 = None
pwm_servo_6 = None
pwm_servo_7 = None
pwm_servo_8 = None
lower_stem = None
upper_stem = None


def servo_initialize():
    global petal1, petal2, petal3, petal4, petal5, petal6, lower_stem, upper_stem, pwm_servo_1, pwm_servo_2, pwm_servo_3, pwm_servo_4,pwm_servo_5, pwm_servo_6, pwm_servo_7, pwm_servo_8
    pwm_servo_1 = pwmio.PWMOut(board.GP2, duty_cycle=2 ** 15, frequency=50)
    petal1 = servo.Servo(
        pwm_servo_1, min_pulse=500, max_pulse=2200
    )

    pwm_servo_2 = pwmio.PWMOut(board.GP3, duty_cycle=2 ** 15, frequency=50)
    petal2 = servo.Servo(
        pwm_servo_2, min_pulse=500, max_pulse=2200
    )

    pwm_servo_3 = pwmio.PWMOut(board.GP4, duty_cycle=2 ** 15, frequency=50)
    petal3 = servo.Servo(
        pwm_servo_3, min_pulse=500, max_pulse=2200
    )

    pwm_servo_4 = pwmio.PWMOut(board.GP5, duty_cycle=2 ** 15, frequency=50)
    petal4 = servo.Servo(
        pwm_servo_4, min_pulse=500, max_pulse=2200
    )

    pwm_servo_5 = pwmio.PWMOut(board.GP6, duty_cycle=2 ** 15, frequency=50)
    petal5 = servo.Servo(
        pwm_servo_5, min_pulse=500, max_pulse=2200
    )

    pwm_servo_6 = pwmio.PWMOut(board.GP7, duty_cycle=2 ** 15, frequency=50)
    petal6 = servo.Servo(
        pwm_servo_6, min_pulse=500, max_pulse=2200
    )

    pwm_servo_7 = pwmio.PWMOut(board.GP8, duty_cycle=2 ** 15, frequency=50)
    lower_stem = servo.Servo(
        pwm_servo_7, min_pulse=500, max_pulse=2200
    )

    pwm_servo_8 = pwmio.PWMOut(board.GP9, duty_cycle=2 ** 15, frequency=50)
    upper_stem = servo.Servo(
        pwm_servo_8, min_pulse=500, max_pulse=2200
    )

def servo_deinitialize():
    global pwm_servo_1, pwm_servo_2, pwm_servo_3, pwm_servo_4, pwm_servo_5, pwm_servo_6, pwm_servo_7, pwm_servo_8
    pwm_servo_1.deinit()
    pwm_servo_2.deinit()
    pwm_servo_3.deinit()
    pwm_servo_4.deinit()
    pwm_servo_5.deinit()
    pwm_servo_6.deinit()
    pwm_servo_7.deinit()
    pwm_servo_8.deinit()

# Initialize servos and make the stem upright and release the servo torque on them by setting the angle to None.

servo_initialize()
lower_stem.angle = 15
upper_stem.angle = 20
time.sleep(0.1)
lower_stem.angle = None
upper_stem.angle = None

""" The function below moves the stem to a downward position and makes three petals move in one direction while the other three move in opposite direction mimicking a dancing flower. It does it for three times and then come back up to its original upright position """

def flower_dance():
for i in range(15, 90):
    lower_stem.angle = i
    time.sleep(0.02)
time.sleep(0.5)
for i in range(20, 80):
    upper_stem.angle = i
    time.sleep(0.02)
upper_stem.angle = None
lower_stem.angle = None
time.sleep(1)

for _ in range(3):
    for i in range(50, 100):
        petal1.angle = i
        petal2.angle = i
        petal3.angle = i
        petal4.angle = i
        petal5.angle = i
        petal6.angle = i
        time.sleep(0.02)
    for i in reversed(range(50, 100)):
        petal1.angle = i
        petal2.angle = i
        petal3.angle = i
        petal4.angle = i
        petal5.angle = i
        petal6.angle = i
        time.sleep(0.02)
time.sleep(1)
for i in reversed(range(15, 90)):
    lower_stem.angle = i
    time.sleep(0.02)
time.sleep(0.5)
for i in reversed(range(20, 80)):
    upper_stem.angle = i
    time.sleep(0.02)
upper_stem.angle = None
lower_stem.angle = None

Conclusion

I really enjoyed this build and working with Raspberry Pi Pico is much more forgiving as it allows a lot of storage capacity and simplicity in writing code. One of my concerns is about the charging speed using the solar panels. I haven't had the chance to fully test it since these days the lighting conditions are inadequate and normally I get to work on these projects during the late hours in the night. I had tested 3 of the four solar panels used as leaves connected in parallel to hook it up to my phone it does charge so I presume in good lighting conditions it would be able to charge the battery. It would definitely take awhile but that's a known given the battery is 3.6Ah and the solar panels provide just below an Amp.

Since this build has more room for improvement, I have several ideas for added functions such as to show appropriate colors from the Neo-pixels during different times of the day since it has an RTC module. Another such function could be to display the level of happiness of the flower depending on the brightness of sunlight it could move the stem up or down and petals in or out. If you have any ideas please share it here and I would also be happy to give my opinion. Thanks!

Watch on YouTube - Mechanical Flower

Watch on YouTube - Light Sensitive Flower

3D Model Files