Skip to content

Instantly share code, notes, and snippets.

@idriszmy
Created January 26, 2021 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save idriszmy/dd5432a17f595915c4548f93eaa3126c to your computer and use it in GitHub Desktop.
Save idriszmy/dd5432a17f595915c4548f93eaa3126c to your computer and use it in GitHub Desktop.
Making A Lucky Draw Device Using Raspberry Pi Pico
#
# Grove 16x2 I2C LCD (White on Blue)
# - https://my.cytron.io/p-grove-16-x-2-lcd-white-on-blue?tracking=idris
#
# Update:
# 10 Jan 2021: Tested with MicroPython ESP32 V1.13
#
from machine import Pin, I2C
import utime
class Grove_LCD_I2C(object):
# Commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80
# Flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00
# Flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00
# Flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00
# Flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00
def __init__(self, i2c, address, oneline=False, charsize=LCD_5x8DOTS):
self.i2c = i2c
self.address = address
self.disp_func = self.LCD_DISPLAYON # | 0x10
if not oneline:
self.disp_func |= self.LCD_2LINE
elif charsize != 0:
# For 1-line displays you can choose another dotsize
self.disp_func |= self.LCD_5x10DOTS
# Wait for display init after power-on
utime.sleep_ms(50) # 50ms
# Send function set
self.cmd(self.LCD_FUNCTIONSET | self.disp_func)
utime.sleep_us(4500) ##time.sleep(0.0045) # 4.5ms
self.cmd(self.LCD_FUNCTIONSET | self.disp_func)
utime.sleep_us(150) ##time.sleep(0.000150) # 150µs = 0.15ms
self.cmd(self.LCD_FUNCTIONSET | self.disp_func)
self.cmd(self.LCD_FUNCTIONSET | self.disp_func)
# Turn on the display
self.disp_ctrl = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
self.display(True)
# Clear it
self.clear()
# Set default text direction (left-to-right)
self.disp_mode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
self.cmd(self.LCD_ENTRYMODESET | self.disp_mode)
def cmd(self, command):
assert command >= 0 and command < 256
command = bytearray([command])
self.i2c.writeto_mem(self.address, 0x80, bytearray([]))
self.i2c.writeto_mem(self.address, 0x80, command)
def write_char(self, c):
assert c >= 0 and c < 256
c = bytearray([c])
self.i2c.writeto_mem(self.address, 0x40, c)
def write(self, text):
for char in text:
if char == '\n':
self.cursor_position(0, 1)
else:
self.write_char(ord(char))
def cursor(self, state):
if state:
self.disp_ctrl |= self.LCD_CURSORON
self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl)
else:
self.disp_ctrl &= ~self.LCD_CURSORON
self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl)
def cursor_position(self, col, row):
col = (col | 0x80) if row == 0 else (col | 0xc0)
self.cmd(col)
def autoscroll(self, state):
if state:
self.disp_ctrl |= self.LCD_ENTRYSHIFTINCREMENT
self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl)
else:
self.disp_ctrl &= ~self.LCD_ENTRYSHIFTINCREMENT
self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl)
def blink(self, state):
if state:
self.disp_ctrl |= self.LCD_BLINKON
self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl)
else:
self.disp_ctrl &= ~self.LCD_BLINKON
self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl)
def display(self, state):
if state:
self.disp_ctrl |= self.LCD_DISPLAYON
self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl)
else:
self.disp_ctrl &= ~self.LCD_DISPLAYON
self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl)
def clear(self):
self.cmd(self.LCD_CLEARDISPLAY)
utime.sleep_ms(2) # 2ms
def home(self):
self.cmd(self.LCD_RETURNHOME)
utime.sleep_ms(2) # 2m
#
# Generate random number and display it to the LCD
# using Raspberry Pi Pico
#
# Raspberry Pi Pico
# - [Bare Board] https://my.cytron.io/p-raspberry-pi-pico?tracking=idris
# - [Pre-soldered Headers] https://my.cytron.io/p-raspberry-pi-pico-pre-soldered-headers?tracking=idris
# - [Maker Pi Pico] https://my.cytron.io/p-maker-pi-pico?tracking=idris
# Grove 16x2 I2C LCD (White on Blue)
# - https://my.cytron.io/p-grove-16-x-2-lcd-white-on-blue?tracking=idris
#
# Update:
# 26 Jan 2021 - Tested with MicroPython Pico V1.13-290-g556ae7914
#
from machine import *
from utime import sleep
from pitches import tones
import urandom
from grove_lcd_i2c import Grove_LCD_I2C
sleep(1)
print("MicroPython on Raspberry Pi Pico")
print()
led = Pin(25, Pin.OUT)
button1 = Pin(13, Pin.IN, Pin.PULL_UP)
button2 = Pin(12, Pin.IN, Pin.PULL_UP)
LCD_SDA = Pin(14)
LCD_SCL = Pin(15)
LCD_ADDR = 62 # 0x3E or 62
i2c = I2C(1, sda=LCD_SDA, scl=LCD_SCL)
#print(i2c.scan())
lcd = Grove_LCD_I2C(i2c, LCD_ADDR)
lcd.home()
lcd.write(" Raspberry Pi \n Pico")
tempo = 0.8
melody1 = ('c4','g4')
rhythm1 = [8,8]
melody2 = ('c4','f4','a4','c5','','a4','c5')
rhythm2 = [8,8,8,8,4,8,2]
def play_melody(melody, rhythm):
for tone, length in zip(melody, rhythm):
beeper = PWM(Pin(18))
if tones[tone] != 0:
beeper.duty_u16(32768)
beeper.freq(tones[tone])
sleep((tempo/length)*1.3)
beeper.deinit()
play_melody(melody1, rhythm1)
sleep(1)
lcd.clear()
lcd.write(" *Lucky Winner*")
button_pressed = False
counter = 0
while True:
led.toggle()
sleep(0.1)
if button1.value() == 0:
button_pressed = True
counter = 0
if button_pressed == True:
counter += 1
if counter == 20:
button_pressed = False
sleep(1)
print("Congratulation!")
play_melody(melody2, rhythm2)
while button2.value() == 1:
pass
sleep(counter*0.025)
random_number = urandom.uniform(1, 38)
lcd.cursor_position(7, 1)
lcd.write("{:2.0f}".format(random_number))
tones = {
'': 0,
'b0': 31,
'c1': 33,
'cs1': 35,
'd1': 37,
'ds1': 39,
'e1': 41,
'f1': 44,
'fs1': 46,
'g1': 49,
'gs1': 52,
'a1': 55,
'as1': 58,
'b1': 62,
'c2': 65,
'cs2': 69,
'd2': 73,
'ds2': 78,
'e2': 82,
'f2': 87,
'fs2': 93,
'g2': 98,
'gs2': 104,
'a2': 110,
'as2': 117,
'b2': 123,
'c3': 131,
'cs3': 139,
'd3': 147,
'ds3': 156,
'e3': 165,
'f3': 175,
'fs3': 185,
'g3': 196,
'gs3': 208,
'a3': 220,
'as3': 233,
'b3': 247,
'c4': 262,
'cs4': 277,
'd4': 294,
'ds4': 311,
'e4': 330,
'f4': 349,
'fs4': 370,
'g4': 392,
'gs4': 415,
'a4': 440,
'as4': 466,
'b4': 494,
'c5': 523,
'cs5': 554,
'd5': 587,
'ds5': 622,
'e5': 659,
'f5': 698,
'fs5': 740,
'g5': 784,
'gs5': 831,
'a5': 880,
'as5': 932,
'b5': 988,
'c6': 1047,
'cs6': 1109,
'd6': 1175,
'ds6': 1245,
'e6': 1319,
'f6': 1397,
'fs6': 1480,
'g6': 1568,
'gs6': 1661,
'a6': 1760,
'as6': 1865,
'b6': 1976,
'c7': 2093,
'cs7': 2217,
'd7': 2349,
'ds7': 2489,
'e7': 2637,
'f7': 2794,
'fs7': 2960,
'g7': 3136,
'gs7': 3322,
'a7': 3520,
'as7': 3729,
'b7': 3951,
'c8': 4186,
'cs8': 4435,
'd8': 4699,
'ds8': 4978,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment