|
| 1 | +# Bonsai Buckaroo + CLUE Plant Care Bot |
| 2 | + |
| 3 | +import time |
| 4 | +import board |
| 5 | +from digitalio import DigitalInOut, Direction |
| 6 | +from analogio import AnalogIn |
| 7 | +from adafruit_clue import clue |
| 8 | +from adafruit_display_text import label |
| 9 | +import displayio |
| 10 | +import terminalio |
| 11 | +import pulseio |
| 12 | + |
| 13 | +moist_level = 50 # adjust this value as needed for your plant |
| 14 | + |
| 15 | +board.DISPLAY.brightness = 0.8 |
| 16 | +clue.pixel.fill(0) # turn off NeoPixel |
| 17 | + |
| 18 | +clue_display = displayio.Group(max_size=4) |
| 19 | + |
| 20 | +# draw the dry plant |
| 21 | +dry_plant_file = open("dry.bmp", "rb") |
| 22 | +dry_plant_bmp = displayio.OnDiskBitmap(dry_plant_file) |
| 23 | +dry_plant_sprite = displayio.TileGrid(dry_plant_bmp, pixel_shader=displayio.ColorConverter()) |
| 24 | +clue_display.append(dry_plant_sprite) |
| 25 | + |
| 26 | +# draw the happy plant on top (so it can be moved out of the way when needed) |
| 27 | +happy_plant_file = open("happy.bmp", "rb") |
| 28 | +happy_plant_bmp = displayio.OnDiskBitmap(happy_plant_file) |
| 29 | +happy_plant_sprite = displayio.TileGrid(happy_plant_bmp, pixel_shader=displayio.ColorConverter()) |
| 30 | +clue_display.append(happy_plant_sprite) |
| 31 | + |
| 32 | +# Create text |
| 33 | +# first create the group |
| 34 | +text_group = displayio.Group(max_size=3, scale=3) |
| 35 | +# Make a label |
| 36 | +title_label = label.Label(terminalio.FONT, text="CLUE Plant", color=0x00FF22) |
| 37 | +# Position the label |
| 38 | +title_label.x = 10 |
| 39 | +title_label.y = 4 |
| 40 | +# Append label to group |
| 41 | +text_group.append(title_label) |
| 42 | + |
| 43 | +soil_label = label.Label(terminalio.FONT, text="Soil: ", color=0xFFAA88, max_glyphs=10) |
| 44 | +soil_label.x = 4 |
| 45 | +soil_label.y = 64 |
| 46 | +text_group.append(soil_label) |
| 47 | + |
| 48 | +motor_label = label.Label(terminalio.FONT, text="Motor off", color=0xFF0000, max_glyphs=9) |
| 49 | +motor_label.x = 4 |
| 50 | +motor_label.y = 74 |
| 51 | +text_group.append(motor_label) |
| 52 | + |
| 53 | +clue_display.append(text_group) |
| 54 | +board.DISPLAY.show(clue_display) |
| 55 | + |
| 56 | +motor = DigitalInOut(board.P2) |
| 57 | +motor.direction = Direction.OUTPUT |
| 58 | + |
| 59 | +buzzer = pulseio.PWMOut(board.SPEAKER, variable_frequency=True) |
| 60 | +buzzer.frequency = 1000 |
| 61 | + |
| 62 | +sense_pin = board.P1 |
| 63 | +analog = AnalogIn(board.P1) |
| 64 | + |
| 65 | +def read_and_average(ain, times, wait): |
| 66 | + asum = 0 |
| 67 | + for _ in range(times): |
| 68 | + asum += ain.value |
| 69 | + time.sleep(wait) |
| 70 | + return asum / times |
| 71 | + |
| 72 | +time.sleep(5) |
| 73 | + |
| 74 | +while True: |
| 75 | + # take 100 readings and average them |
| 76 | + aval = read_and_average(analog, 100, 0.01) |
| 77 | + # calculate a percentage (aval ranges from 0 to 65535) |
| 78 | + aperc = aval / 65535 * 100 |
| 79 | + # display the percentage |
| 80 | + soil_label.text = "Soil: {} %".format(int(aperc)) |
| 81 | + print((aval, aperc)) |
| 82 | + |
| 83 | + if aperc < moist_level: |
| 84 | + happy_plant_sprite.x = 300 # move the happy sprite away |
| 85 | + time.sleep(1) |
| 86 | + motor.value = True |
| 87 | + motor_label.text = "Motor ON" |
| 88 | + motor_label.color = 0x00FF00 |
| 89 | + buzzer.duty_cycle = 2**15 |
| 90 | + time.sleep(0.5) |
| 91 | + |
| 92 | + # always turn off quickly |
| 93 | + motor.value = False |
| 94 | + motor_label.text = "Motor off" |
| 95 | + motor_label.color = 0xFF0000 |
| 96 | + buzzer.duty_cycle = 0 |
| 97 | + |
| 98 | + if aperc >= moist_level: |
| 99 | + happy_plant_sprite.x = 0 # bring back the happy sprite |
0 commit comments