From bc7922f5c85ac09cc8bd7c4651654265b3e1f1a0 Mon Sep 17 00:00:00 2001 From: l_samenv Date: Thu, 25 Jan 2024 09:40:10 +0100 Subject: [PATCH] iono pi max demo (drums) + fix spacing in ionopimax.py --- cfg/drums_cfg.py | 27 +++++++++++++++++ frappy_psi/drums.py | 65 +++++++++++++++++++++++++++++++++++++++++ frappy_psi/ionopimax.py | 35 +++++++++++----------- 3 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 cfg/drums_cfg.py create mode 100644 frappy_psi/drums.py diff --git a/cfg/drums_cfg.py b/cfg/drums_cfg.py new file mode 100644 index 0000000..e05f4ac --- /dev/null +++ b/cfg/drums_cfg.py @@ -0,0 +1,27 @@ +Node('relais.psi.ch', + 'relais test', + 'tcp://5000', +) + +Mod('rl', + 'frappy_psi.ionopimax.DigitalOutput', + 'left relais', + addr = 'o1', + value = 0, # start with relais off + ) + +Mod('rr', + 'frappy_psi.ionopimax.DigitalOutput', + 'right relais', + addr = 'o2', + value = 0, # start with relais off + ) + +Mod('drummer', + 'frappy_psi.drums.Drums', + 'drummer', + target = 150, + pattern='l2L2rl1R1L2', + left='rl', + right='rr', +) diff --git a/frappy_psi/drums.py b/frappy_psi/drums.py new file mode 100644 index 0000000..b06da48 --- /dev/null +++ b/frappy_psi/drums.py @@ -0,0 +1,65 @@ +# ***************************************************************************** +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Markus Zolliker +# ***************************************************************************** +"""iono pi max relais drums + +for demo purposes +""" + +from frappy.core import Module, Attached, FloatRange, StringType, Writable, Parameter + + +class Drums(Writable): + target = Parameter('drum speed', FloatRange(unit='beats/min')) + left = Attached(Writable) + right = Attached(Writable) + pollinterval = Parameter('drum interval', FloatRange(0, 10, unit='s'), readonly=False) + pattern = Parameter('''pattern + + a string containing: + L,R: left / right relais on + l,r: left / right relais off + blank: wait''', StringType(), readonly=False) + _pos = 0 + _wait = 0 + + def initModule(self): + super().initModule() + self.actions = {'L': self.left, 'R': self.right} + + def write_target(self, target): + self.pollinterval = 60 / max(1, target) + self.value = target + + def doPoll(self): + if not self.target: + return + if self._wait: + self._wait -= 1 + return + if self._pos >= len(self.pattern): + self._pos = 0 + for i, action in enumerate(self.pattern[self._pos:]): + upper = action.upper() + relais = self.actions.get(action.upper()) + if relais: + relais.write_target(upper == action) # True when capital letter + else: + self._wait = int(action) - 1 + self._pos += i + 1 + return diff --git a/frappy_psi/ionopimax.py b/frappy_psi/ionopimax.py index 880edef..f43871a 100644 --- a/frappy_psi/ionopimax.py +++ b/frappy_psi/ionopimax.py @@ -25,6 +25,7 @@ from math import log class Base: addr = Property('address', StringType()) + def read(self, addr, scale=None): with open(f'/sys/class/ionopimax/{self.devclass}/{addr}') as f: result = f.read() @@ -52,47 +53,47 @@ class DigitalOutput(DigitalInput, Writable): def write_target(self, value): self.write(self.addr, value, 1) - + class AnalogInput(Base, Readable): value = Parameter('analog value', FloatRange()) rawrange = Property('raw range(electronic)', TupleOf(FloatRange(),FloatRange())) valuerange = Property('value range(physical)', TupleOf(FloatRange(),FloatRange())) devclass = 'analog_in' - + def read_value(self): x0, x1 = self.rawrange y0, y1 = self.valuerange self.x = self.read(self.addr, self.scale) return y0 + (y1 - y0) * (self.x - x0) / (x1 - x0) - - + class VoltageInput(AnalogInput): scale = 1e5 - + def initModule(self): super().initModule() self.write(f'{self.addr}_mode','U') + class LogVoltageInput(VoltageInput): - + def read_value(self): x0, x1 = self.rawrange y0, y1 = self.valuerange self.x = self.read(self.addr, self.scale) a = (x1-x0)/log(y1/y0,10) return 10**((self.x-x1)/a)*y1 - - + + class CurrentInput(AnalogInput): scale = 1e6 rawrange = (0.004,0.02) - + def initModule(self): super().initModule() self.write(f'{self.addr}_mode','U') - + def read_value(self): result = super().read_value() if self.x > 0.021: @@ -100,27 +101,25 @@ class CurrentInput(AnalogInput): else: self.status = IDLE, '' return result - - + + class AnalogOutput(AnalogInput, Writable): target = Parameter('outputvalue', FloatRange()) devclass = 'analog_out' - + def write_target(self, value): x0, x1 = self.rawrange y0, y1 = self.valuerange self.write(self.addr, x0 + (x1 - x0) * (value - y0) / (y1 - y0),self.scale) - - + + class VoltageOutput(AnalogOutput): rawrange = (0,10) scale = 1e3 - + def initModule(self): super().initModule() self.write(f'{self.addr}_enabled', '0') self.write(f'{self.addr}_mode', 'V') self.write(f'{self.addr}', '0') self.write(f'{self.addr}_enabled', '1') - -