diff --git a/guinea-synth.py b/guinea-synth.py index faf9767..451a5aa 100644 --- a/guinea-synth.py +++ b/guinea-synth.py @@ -1,9 +1,13 @@ # Guinea synth import sys import time -from ctcsoundSession import CsoundSession +# from ctcsoundSession import CsoundSession + +# PIN numbers of rotary encoder - change these if needed: +PIN_clk = 10 +PIN_dt = 9 +PIN_btn = 25 -# todo - PIN numbers def clip(value, lower, upper): return lower if value < lower else upper if value > upper else value @@ -67,6 +71,7 @@ class hladina: self.name = name def show(self): + cls() echo(self.name) echo("{}".format(self.value), 1) @@ -124,23 +129,65 @@ if "--tkinter" in sys.argv: else: print("(using hardware controls)") - # TODO - zde bude ovládání rotačního enkodéru a diplaye + import lcddriver + _display = lcddriver.lcd() + + def cls(): + _display.lcd_clear() + + def echo(text, row=0): + _display.lcd_display_string(text, row+1) + + from RPi import GPIO + GPIO.setmode(GPIO.BCM) + GPIO.setup(PIN_clk, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) + GPIO.setup(PIN_dt, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) + GPIO.setup(PIN_btn, GPIO.IN, pull_up_down=GPIO.PUD_UP) + clkLastState = GPIO.input(PIN_clk) + # btnLastState = GPIO.input(PIN_btn) + + def _rotary_button_push(k): + _rotary.push() + + def _rotary_update(k): + global clkLastState + clkState = GPIO.input(PIN_clk) + dtState = GPIO.input(PIN_dt) + if clkState != clkLastState: + if dtState != clkState: + _rotary.up() + else: + _rotary.down() + clkLastState = clkState + + def rotary(callback): + global _rotary + if not _rotary: + _rotary = callback + while True: + time.sleep(0.001) + # TODO - tohle nějak chytřeji + _rotary = callback + + GPIO.add_event_detect(PIN_btn, GPIO.RISING, callback=_rotary_button_push, bouncetime=300) + GPIO.add_event_detect(PIN_clk, GPIO.RISING, callback=_rotary_update, bouncetime=300) + GPIO.add_event_detect(PIN_dt, GPIO.RISING, callback=_rotary_update, bouncetime=300) ###### try: - csd = CsoundSession("minimal.csd") - csd.setControlChannel("filter", 2000) - print(csd) + # csd = CsoundSession("minimal.csd") + # csd.setControlChannel("filter", 2000) + # print(csd) - print(csd.audioDevList(True)) - print(csd.csdFileName()) + # print(csd.audioDevList(True)) + # print(csd.csdFileName()) menu = param_cycle() - menu.add(odpalovac(menu, csd)) + # menu.add(odpalovac(menu, csd)) menu.add(hladina(menu, "volume")) menu.add(hladina(menu, "tone")) @@ -150,5 +197,7 @@ try: rotary(menu) print("OK") finally: - csd.stopPerformance() - del csd \ No newline at end of file + # cls() + # csd.stopPerformance() + # del csd + GPIO.cleanup() \ No newline at end of file diff --git a/i2c_lib.py b/i2c_lib.py new file mode 100644 index 0000000..1788373 --- /dev/null +++ b/i2c_lib.py @@ -0,0 +1,34 @@ +import smbus +from time import * + +class i2c_device: + def __init__(self, addr, port=1): + self.addr = addr + self.bus = smbus.SMBus(port) + +# Write a single command + def write_cmd(self, cmd): + self.bus.write_byte(self.addr, cmd) + sleep(0.0001) + +# Write a command and argument + def write_cmd_arg(self, cmd, data): + self.bus.write_byte_data(self.addr, cmd, data) + sleep(0.0001) + +# Write a block of data + def write_block_data(self, cmd, data): + self.bus.write_block_data(self.addr, cmd, data) + sleep(0.0001) + +# Read a single byte + def read(self): + return self.bus.read_byte(self.addr) + +# Read + def read_data(self, cmd): + return self.bus.read_byte_data(self.addr, cmd) + +# Read a block of data + def read_block_data(self, cmd): + return self.bus.read_block_data(self.addr, cmd) diff --git a/lcddriver.py b/lcddriver.py new file mode 100644 index 0000000..95d0267 --- /dev/null +++ b/lcddriver.py @@ -0,0 +1,132 @@ +# Driver library for LCD display. Provided by Ryanteck LTD. +# The procedures below can all be called in your own code! +# You can just stick to the print string one though ;-) + +# This is the driver library for the LCD display +# It contains some functions that you can call in your own program +# Just remember that in order to use it you have to import it +# You can do that with the line: import lcddriver +# Make sure that lcddriver is in the same directory though! +# Credit for this code goes to "natbett" of the Raspberry Pi Forum 18/02/13 + +# Backlight: Enhanced by TOMDENKT - backlight control (on/off) +# If lcddriver.py is NOT in same folder with your scripts, +# set path to lcddriver IN YOUR script such as +#import sys +#sys.path.append("/home/pi/lcd") # example, path to lcddriver.py + +import i2c_lib +from time import * + +# LCD Address +# Usually you will have to use one of the two provided values below. +# If you prefer, you can check your LCD address with the command: "sudo i2cdetect -y 1" +# This is a common LCD address. +ADDRESS = 0x27 +# This is another common LCD address. +#ADDRESS = 0x3f + +# 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 + +# flags for backlight control +LCD_BACKLIGHT = 0x08 +LCD_NOBACKLIGHT = 0x00 + +En = 0b00000100 # Enable bit +Rw = 0b00000010 # Read/Write bit +Rs = 0b00000001 # Register select bit + +class lcd: + #initializes objects and lcd + def __init__(self): + self.lcd_device = i2c_lib.i2c_device(ADDRESS) + + self.lcd_write(0x03) + self.lcd_write(0x03) + self.lcd_write(0x03) + self.lcd_write(0x02) + + self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE) + self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON) + self.lcd_write(LCD_CLEARDISPLAY) + self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT) + sleep(0.2) + + # clocks EN to latch command + def lcd_strobe(self, data): + self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT) + sleep(.0005) + self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT)) + sleep(.0001) + + def lcd_write_four_bits(self, data): + self.lcd_device.write_cmd(data | LCD_BACKLIGHT) + self.lcd_strobe(data) + + # write a command to lcd + def lcd_write(self, cmd, mode=0): + self.lcd_write_four_bits(mode | (cmd & 0xF0)) + self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0)) + + # put string function + def lcd_display_string(self, string, line): + if line == 1: + self.lcd_write(0x80) + if line == 2: + self.lcd_write(0xC0) + if line == 3: + self.lcd_write(0x94) + if line == 4: + self.lcd_write(0xD4) + + for char in string: + self.lcd_write(ord(char), Rs) + + # clear lcd and set to home + def lcd_clear(self): + self.lcd_write(LCD_CLEARDISPLAY) + self.lcd_write(LCD_RETURNHOME) + + # backlight control (on/off) + # options: lcd_backlight(1) = ON, lcd_backlight(0) = OFF + def lcd_backlight(self, state): + if state == 1: + self.lcd_device.write_cmd(LCD_BACKLIGHT) + elif state == 0: + self.lcd_device.write_cmd(LCD_NOBACKLIGHT)