# This project aims to control a pump through an electrical variator
# It can be seen as an "intelligent timer" because it counts period
# of time (selected by pushing a button)
# but it also creates a ramp up and down, and also reverse the pump at the
# end, in order to empty the pipe
# It also display everything which need to be known on a screen.
# The following technologies are to be used :
# - I2C for screen
# > https://www.tomshardware.com/how-to/lcd-display-raspberry-pi-pico
# - SPI for the control of the MCP digital pot
# > https://www.takaitra.com/mcp4151-digital-potentiometer-raspberry-pi/
# > http://electroniqueamateur.blogspot.ca/2013/04/faire-varier-une-resistance-au-moyen-de.html
# > no, no C translation : https://microdigisoft.com/spi-communication-with-raspberry-pi-pico-w/
# - Pin IN for the input timer button
# - Pin IN to read the value of a pot for custom timing
# > https://randomnerdtutorials.com/raspberry-pi-pico-analog-inputs-micropython/
# - Pin OUT for the order which are to be sent to the relay
# import machine
# import time
# Run
# No Run => Menu
# Button #1 => 20min puis retour cuve
# => 20 min ? OK / KO
# Button #2 => temps choisi
# => Choisir votre temps, puis OK, puis vous avez choisi XXX OK/KO ? puis le temps et retour cuve
import time, utime
from machine import Pin, ADC
from machine import I2C
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
normal_time = 20
custom_time = 0
is_setup = False
is_running = False
buttonOK = Pin(13, Pin.IN, Pin.PULL_DOWN)
buttonFree = Pin(14, Pin.IN, Pin.PULL_DOWN)
buttonKO = Pin(15, Pin.IN, Pin.PULL_DOWN)
pot = ADC(Pin(26))
output = ""
I2C_ADDR = 0x27
I2C_NUM_ROWS = 4
I2C_NUM_COLS = 20
MAX_POT_VALUE = 65535
MAX_DURATION = 3600
DEBUG = True
def emergency_callback(pin):
global DEBUG
if (DEBUG):
print("EMERGENCY !")
re_init()
buttonKO.irq(trigger=Pin.IRQ_FALLING, handler=emergency_callback)
i2c = I2C(0, sda=machine.Pin(8), scl=machine.Pin(9), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
def my_print(msg):
global output
global DEBUG
if not msg == output:
lcd.clear()
lcd.putstr(msg)
output = msg
if DEBUG:
print(msg)
def ramp_up(duration):
# General message
msg = "Cycle\nRamp up of" + str(duration) + "\n"
print("Cycle\nRamp up of" + str(duration) + "\n")
def cycle(duration):
ramp_up(10)
# pump_on(duration)
# ramp_down(10)
# pump_switch(20)
utime.sleep(40)
# bip()
utime.sleep(2)
def re_init():
global output
global duration
output = ""
duration = 0
my_print("Ready to wash !")
def main():
global button
global lcd
global output
my_print("Ready to wash !")
while True:
# Button for classic 20' cycle
if buttonOK.value():
my_print("Lets cycle 20 SEC")
cycle(20)
re_init()
# Button for free duration
if buttonFree.value():
duration = 0
while True:
# 65535 = 1h
tmp = round(pot.read_u16()/MAX_POT_VALUE*MAX_DURATION/10)*10
if not tmp == duration:
duration = tmp
my_print(str(round(duration / 60)) + " MIN " + str(duration % 60) + "SEC\n\n\nOK ?")
utime.sleep(2)
if buttonOK.value():
my_print("Lets cycle " + str(duration) + "SEC")
cycle(duration)
re_init()
break
if buttonKO.value():
my_print("KO on sort")
re_init()
break
print("en dehors du while pot")
continue
utime.sleep(0.5)
# print("en dehors du while menu")
if __name__ == "__main__":
main()
# # Define SPI pins
# sck = machine.Pin(16) # SCK
# mosi = machine.Pin(17) # MOSI
# miso = machine.Pin(18) # MISO
# cs = machine.Pin(19) # CS
# # Create an SPI object
# spi = machine.SPI(0, baudrate=1000000, polarity=0, phase=0)
# # Select the peripheral device
# cs.value(0)
# # Send data to the peripheral
# spi.write(b'Hello, SPI!')
# # Deselect the peripheral
# cs.value(1)
# # Read data from the peripheral
# received_data = spi.read(10)
# # Print received data
# print('Received Data:', received_data)
# # Close the SPI bus
# spi.deinit()