IO Cell - Usage Examples

I experimented with the IO cells, until I got my voltage control working. The documentation is a bit scarce on this, especially the internal addressing - so maybe the following examples could be helpful:

# AudioIn = z.UI_CELL1 (type I)
# AudioOut = z.UI_CELL4 (type II)
# UltrasonicIn = z.UI_CELL0 (type I)
# UltrasonicOut = z.UI_CELL5 (type II)
# Input/Output Cell 3 = z.UI_CELL2 (type IA)
# Input/Output Cell 4 = z.UI_CELL3 (type IA)  

# Very useful commands to check correctness of circuit
z.debug_analog_resources()
z.circuit()

# Using InputCell and OutputCell for Audio I/O

z.clear()
audio_in = z.InputCell()
audio_in.physical_address = z.IO_CELL1
audio_in.input_type = z.AMPLIFIER
g = z.GainInv()
audio_out = z.OutputCell()
audio_out.io_cell_type = z.II
audio_out.physical_address = z.IO_CELL4
z.add(audio_in)
z.add(g)
z.add(audio_out)
audio_in.output.connect(g.input)
g.output.connect(audio_out.input)
z.run()


# Using InputCell and OutputCell for Ultrasonic I/O

z.clear()
audio_in = z.InputCell()
audio_in.physical_address = z.IO_CELL0
audio_in.input_type = z.AMPLIFIER
g = z.GainInv()
audio_out = z.OutputCell()
audio_out.io_cell_type = z.II
audio_out.physical_address = z.IO_CELL5
z.add(audio_in)
z.add(g)
z.add(audio_out)
audio_in.output.connect(g.input)
g.output.connect(audio_out.input)
z.run()

# Input via AudioIn, output via "Differential Cell 3" 

z.clear()
audio_in = z.InputCell()
audio_in.physical_address = z.IO_CELL1
audio_in.io_cell_type = z.I
audio_in.input_type = z.AMPLIFIER
g = z.GainInv()
audio_out = z.OutputCell()
audio_out.io_cell_type = z.IA
audio_out.physical_address = z.IO_CELL2
z.add(audio_in)
z.add(g)
z.add(audio_out)
audio_in.output.connect(g.input)
g.output.connect(audio_out.input)
g.gain = 20
z.run()

# Input via AudioIn, output via "Differential Cell 4" 
z.clear()
audio_in = z.InputCell()
audio_in.physical_address = z.IO_CELL1
audio_in.io_cell_type = z.I
audio_in.input_type = z.AMPLIFIER
g = z.GainInv()
audio_out = z.OutputCell()
audio_out.io_cell_type = z.IA
audio_out.physical_address = z.IO_CELL3
z.add(audio_in)
z.add(g)
z.add(audio_out)
audio_in.output.connect(g.input)
g.output.connect(audio_out.input)
g.gain = 20
z.run()

# VCO 50Hz-4870Hz: CV via Cell 3, Output via AudioOut
z.clear()
z.set_divisor(z.CLOCK_SYS1, 2)
osc = z.OscillatorVoltageControlled()
osc.set_clock(z.CLOCK3)
z.add(osc)
osc.center_frequency = 0.05
osc.range_percentage = 6000
audio_out = z.AudioOut()
z.add(audio_out)
osc.saw.connect(audio_out.input)
control_in = z.InputCell()
control_in.physical_address = z.IO_CELL2
control_in.io_cell_type = z.IA
control_in.input_type = z.INPUT_BYPASS 
z.add(control_in)
control_in.output.connect(osc.control)
z.run()

VCF with input via AudioIn, output via AudioOut, the two “differential cells” control low and high pass (each connected to potentiometer and jack via a scaling & offset circuit):

z.clear()
z.set_divisor(z.CLOCK_SYS1, 2)
# Audio In
audio_in = z.InputCell()
audio_in.physical_address = z.IO_CELL1
audio_in.input_type = z.AMPLIFIER
z.add(audio_in)
# Gain
g = z.GainInv()
g.gain = 0.1
z.add(g)
audio_in.output.connect(g.input)
# VCF / Lowpass
filter_lp = z.FilterVoltageControlled()
filter_lp.filter_type = z.LOWPASS
filter_lp.center_frequency=0.8
z.add(filter_lp)
g.output.connect(filter_lp.input)
# VCF / Highpass
filter_hp = z.FilterVoltageControlled()
filter_hp.filter_type = z.HIGHPASS
filter_hp.center_frequency=1
z.add(filter_hp)
filter_lp.output.connect(filter_hp.input)
# Audio Out
audio_out = z.AudioOut()
z.add(audio_out)
filter_hp.output.connect(audio_out.input)
# LP Filter CV
lpCV_in = z.InputCell()
lpCV_in.physical_address = z.IO_CELL2
lpCV_in.io_cell_type = z.IA
lpCV_in.input_type = z.INPUT_BYPASS 
z.add(lpCV_in)
lpCV_in.output.connect(filter_lp.control)
# HP Filter CV
hpCV_in = z.InputCell()
hpCV_in.physical_address = z.IO_CELL3
hpCV_in.io_cell_type = z.IA
hpCV_in.input_type = z.INPUT_BYPASS 
z.add(hpCV_in)
hpCV_in.output.connect(filter_hp.control)
z.run()

This is awesome @mcleinn! Love that someone is playing around with the FPAA tech in a serious way.

It would be really valuable to get some more detailed feedback from you about what is lacking and confusing in the documentation so we can update it. I could maybe even open source or “wiki-fy” it in some way so you could update it directly.

1 Like

I guess, physical addressing and cell types of IO cells (I, II etc.) should be shortly explained, that is a minimum. Besides that, more (complex) examples would be probably the best way to go, someone who is really interested could take out a lot of information from those. I am thinking about examples involving CV, continous vs half wave signals, IO etc. Generally I think it is good not to overload the documentation with details.