What inspired creation of ER-301?

Open architecture of ER-301 distantly resembles workflow of MaxMSP. I had Monome Aleph way back and ER-301 is everything I wanted Aleph to be. Is there any specific device/program that inspired you to create ER-301?

3 Likes

I’ve read OD referencing having Max away from keyboard, but it would be interesting to hear more specifics of that experience, drivers for the separation.

The ER-301 has been a long (continuing) journey and the list of inspirations would probably be very long. Here is one that stretches back to a mini-arcade style Pac-Man game that I had when I was 5 or 6 years old:

You can see its influence also in the ER-101. I know it seems like a silly inspiration and a lot of the experience was probably due to my young age at the time, but the immersive power of this piece of plastic was impressive. Over the years, I’ve developed little pet theories as to why…but they are part of the secret sauce, which really just means that I’m not able to commit them to words yet. :joy_cat:

Max, Pd, Reaktor, Scratch, Lego Mindstorm, Labview are definitely all influences that became relevant rather late in the design process. Ironically, I have a bias against and a distrust for graphical programming languages. In my humble opinion, the extremely high dimensionality of general programming does not project well to 2D or even 3D spaces. On the other hand, I look forward to more embeddings of graphical programming into symbolic spaces or vice versa. But this is getting off topic.

Fun aside: There are no graphical schematics for any O|D modules! I defined the circuits completely in Python where I generate the netlist for import into PCBNEW. So PCB layout is the only graphical part of circuit design for me.

So back to the ER-301. The original seed idea was to create a generalization of the digital oscillator with a focus on using external content to generate the timbres. However, it became clear as I developed the idea towards practicality that the integration of the world of digital synthesis with the modular world required such a high level of configurability that it needed its own programming language. (Warning: The previous sentence is a gruesome compression of many months of agony.) This is when I bit the bullet and started re-framing everything in terms of units and chains of units. To this day, there is a tendency to have a few major units (Sample Player, Manual Grains, Looper, the various delays) which are supported by simpler utilitarian units (VCA, Sine Osc, Mixer, etc.). The Custom Unit was the first development that turned this bias on its head and is actually quite a disruptive (but welcome) presence. :scream_cat:

Fun aside: The impetus for 4 channels was almost entirely driven by first-and-foremost panel real estate and then the economy of scale of hardware.

Enough blabbing for now. I have to get back to answering emails and fixing bugs.

17 Likes

hope you’ll continue with that kind of blabbing some day, for i find that information pretty interesting
(actually, it is crucial for my phd thesis, too…)

meantime some babbling on my side:

why didn’t or couldn’t you choose to split the hardware interface into upper and lower halves?
(thinking of intellijel’s planar with which it was made obvious to the user that he could use the module upside
down by adding an additional upside down panel. and i frequently turn modules upside down for ergonomic reasons.
e.g. my two fonitronic cascades which now serve as attenuverters for the er301 and sometimes mults…)
and if the er-302 would be split in upper and lower halves, how difficult would it be to implement an option on an admin level that turns the display(s) upside down?

Re: flippable interface

Is this useful in the case of the ER-301? Since the jack field is vertically isolated from the UI area, I believe the only effect would be to turn a right-handed interface (left hand on encoder, right hand for buttons) into a left-handed interface (right hand on encoder and left hand for buttons).

A personal comment on symmetry in user interfaces. It might just be me but something inside me is freaked out by overly symmetrical interfaces. At minimum, a slight amount of asymmetry is needed to “lock down” your perception so it is less disorienting and thus less likely to flip things in your head. I particularly dislike left/right symmetry in a user interface. Asymmetry gives your brain something to grab onto and orient itself. Imagine trying to navigate a building whose layout is completely symmetric and thus many places would look the same.

4 Likes

Right and Left hand versions of this would be amazing!

The lefties would love you :smiley:

of course not! but that is why i was meditating about an er-302

obviously your palm(s) would cover the big screen…

but i was surprised that you would consider your design a right-handed interface!
when i first saw this monster i figured that its designer must clearly be a leftie for
it seemed to me that this interface could be amazingly handled with only one hand,
if you are a leftie or if you have sufficient control over your left hand due to playing
the guitar for example, which is probably where i got the control from (being a rightie)!
i placed my monster in the lower left corner of a case so if i want to put both hands
on the interface i can have maximum space since this way at least two sides of the module
are free of knobs and spaghetti…
i had that case right to my sequencer and could perfectly edit with only my right hand.
have it now to the left of my sequencer and editing with only the left hand is great, too.

Heheh! Seeing it upside down like that makes me recoil in horror :scream:

Horizontally flipped yes - vertically not for me!

1 Like

i absolutely agree! and i am pretty sure it is not just only you, but rather part of (ordinary) human nature.
(i remember a study, where they tried to figure out which properties would constitute a beautiful face, and guess what?) i guess my use of ‘halves’ made you feel uncomfortable, i apologize for that.
but what i actually had in mind was more something like this, which shouldn’t be symmetrical at all if it is ought to be pretty, too;)

2 Likes

I find the the layout of the 301 really well thought out. I can operate the unit perfectly with one hand only and only take advantage of my second hand when renaming units… so kudos for that.

1 Like

Interesting article I heard a few times symmetrical faces were more beautiful but I never actually looked into it.

I love the ergonomics of the 301 especially as I’m a left handed, it’s just perfect. Although I am crazy about symmetry, I’m always trying to get things symmetrical around my house?

I’ve been thinking about this, and I would love my second ER-301 to be flipped horizontally so that I had perfect symmetry with two units :smile_cat:

I’m imagining myself programming both at the same time at an alarming rate, one left hand one right hand…

…of course this is total fantasy!

Thanks Brian! That’s an interesting read.
I recently acquired one of those myself. It brings joy to me and my friends on rainy Saturday nights.

How does that work?

1 Like

Basically, I implemented a sort of HDL (hardware definition language) in Python. Circuit components are implemented as Python objects that are collected into Python modules. You can do lots of cool things:

  • Define subcircuits in functions and call them repeatedly.
  • Have automatic rules for choosing specific part numbers based on component values and role in the circuit (low precision vs high precision resistors, electrolytic capacitors vs ceramic, and so on).
  • Automatic and manual naming of components
  • Full control over BOM generation.
  • Embed proximity hints in the netlist to aid component placement during PCB layout.
  • Easy to generate reports for error checking (identifying singleton nets or unconnected pins for example).

A huge help was being able to optimize the SOM multiplexed pin assignments based on rough estimates of component placement. So instead of connecting specific pins, you can connect functionality, like this piece of code that says assign the reset pins on the ADC to the nearest available GPIO on the SOM:

connect(adc1["~RST/~PD"],adc2["~RST/~PD"],o["ADC_RESET"],som.assign_nearest_gpio(adc1["~RST/~PD"],"PD"))

and then later during netlist generation assign actual pins using the Hungarian algorithm:

print "Optimizing GPIO assignments..."
som.compute_gpio_assignment()
print "done."    

As an example, here is the code that defines the circuitry around the ER-301 output DAC.

#############################################################
## the DAC

#
# TDM/I2S Bus Frequency: up to 36MHz
#

o.selectGroup("dac")

dac = PCM4104(o)

connect(dac["DGND"],o["DGND"])
connect(dac["VDD"],o["3.3V"])
shared.bypass(o,dac["VDD"],dac["DGND"],["0.1uF","10uF"],near=dac)

connect(dac["AGND1"],dac["AGND2"],o["AGND"])
connect(dac["VCC1"],dac["VCC2"],o["A5V"])
shared.bypass(o,dac["VCC1"],dac["AGND1"],["0.1uF"],near=dac)
shared.bypass(o,dac["VCC2"],dac["AGND2"],["0.1uF"],near=dac)

for i in xrange(4):
    j = i+1
    connect(dac["VREF%d+"%j],o["REF5V"])
    connect(dac["VREF%d-"%j],o["AGND"])
    # Low ESR recommended (e.g. tantalum or multilayer ceramic)
    shared.bypass(o,dac["VREF%d+"%j],dac["VREF%d-"%j],["0.01uF","1uF"],near=dac)

# Low ESR recommended (e.g. tantalum or multilayer ceramic)
shared.bypass(o,dac["VCOM1"],o["AGND"],["0.1uF"],near=dac)
shared.bypass(o,dac["VCOM2"],o["AGND"],["0.1uF"],near=dac)

def CreateOutputFilter(inP, inN, out, opamp):
    # refer to tina-ti/audio-output-circuit.TSC
    C1 = Capacitor(o,"22pF|C0G|50V",near=opamp)
    C2 = Capacitor(o,"560pF|C0G|50V",near=opamp)
    C3 = Capacitor(o,"560pF|C0G|50V",near=opamp)
    C4 = Capacitor(o,"2200pF|C0G|50V",near=opamp)

    # DC-blocking capacitors
    C5 = ElectrolyticCapacitor(o,"150uF",near=opamp)
    C6 = ElectrolyticCapacitor(o,"150uF",near=opamp)

    R1 = HighPrecisionResistor(o,"499R|0.1%",near=opamp)
    R2 = HighPrecisionResistor(o,"499R|0.1%",near=opamp)
    R3 = HighPrecisionResistor(o,"604R|0.1%",near=opamp)
    R4 = HighPrecisionResistor(o,"604R|0.1%",near=opamp)
    R5 = HighPrecisionResistor(o,"1.5k|0.1%",near=opamp)
    R6 = PowerResistor(o,"220R|1/2W",footprint="r_1206",near=opamp)
    R8 = HighPrecisionResistor(o,"1k|0.1%",near=opamp)
    connect(inN,C1[1],C5["+"])
    connect(inP,C1[2],C6["+"])
    connect(C5["-"],R3[1])
    connect(C6["-"],R4[1])
    connect(R3[2],R5[1],R1[1],C4[1])
    connect(R4[2],R8[1],R2[1],C4[2])
    connect(R1[2],opamp["IN-"],C3[1])
    connect(R2[2],opamp["IN+"],C2[1])
    connect(R8[2],C2[2],o["AGND"])
    connect(opamp["OUT"],R6[1],C3[2],R5[2])
    connect(R6[2],out)
    disable_edit()
    # jumpers to bypass the AC-coupling capacitors
    jumper = Resistor(o,"AC|DC",near=dac,bom_include=False)
    connect(jumper[1],C5[1])
    connect(jumper[2],C5[2])
    jumper = Resistor(o,"AC|DC",near=dac,bom_include=False)
    connect(jumper[1],C6[1])
    connect(jumper[2],C6[2])
    enable_edit()
    

quad = OPA1664(o,near=dac)
connect(quad["V+"],o["POSV"])
shared.bypass(o,quad["V+"],o["AGND"],["10uF","0.1uF"],near=quad)
connect(quad["V-"],o["NEGV"])
shared.bypass(o,quad["V-"],o["AGND"],["10uF","0.1uF"],near=quad)

CreateOutputFilter(dac["VOUT3+"],dac["VOUT3-"],o["AUDIO3"],quad.part(3))
CreateOutputFilter(dac["VOUT2+"],dac["VOUT2-"],o["AUDIO2"],quad.part(4))
CreateOutputFilter(dac["VOUT1+"],dac["VOUT1-"],o["AUDIO1"],quad.part(1))
CreateOutputFilter(dac["VOUT4+"],dac["VOUT4-"],o["AUDIO4"],quad.part(2))


# some user-friendly net naming
for i in range(4):
    connect(dac["VOUT%d+"%(i+1)],o["DAC_VOUT%d+"%(i+1)])
    connect(dac["VOUT%d-"%(i+1)],o["DAC_VOUT%d-"%(i+1)])

# PCM4104 control and digital section
# standalone mode

# TDM, short frame (SUB pin is ignored)
# 48kHz: single rate, sys clock 768fS
# 96kHz: dual rate, sys clock 384fS

# FS1, FS0
# single rate: FS1=0, FS0=0
# dual rate: FS1=0, FS0=1
connect(dac["FS1"],o["DAC_FS1"],som["D18"])
connect(dac["FS0"],o["DAC_FS0"],som["H16"])

# FMT2, FMT1, FMT0
# TDM with zero BCK delay: 0,1,0
# TDM with one BCK delay: 0,1,1
connect(dac["FMT2"],o["DGND"])
connect(dac["FMT1"],o["3.3V"])
connect(dac["FMT0"],o["DGND"])

# MUTE
# disabled: 0
# enabled: 1
connect(dac["MUTE"],o["DAC_MUTE"],som.assign_nearest_gpio(dac["MUTE"],"PU"))
shared.pull(o,dac["MUTE"],o["3.3V"],near=dac)

# DEM1, DEM0
# off: 0,0
connect(dac["DEM1"],dac["DEM0"],o["DGND"])

# MODE
# standalone: 0
# software: 1
connect(dac["MODE"],o["DGND"])

# ~RST
connect(dac["~RST"],o["DAC_RESET"],som.assign_nearest_gpio(dac["~RST"],"PD"))
shared.pull(o,o["DAC_RESET"],o["DGND"],near=dac)

# Audio Serial Port
connect(dac["SCKI"],o["DAC_SCKI"])
shared.matched(o,o["DAC_SCKI"],S("mcasp0_ahclkx"),near=som)

connect(dac["BCK"],o["DAC_BCK"])
shared.matched(o,o["DAC_BCK"],S("mcasp0_aclkx"),near=som)

connect(dac["LRCK"],o["DAC_LRCK"])
shared.matched(o,o["DAC_LRCK"],S("mcasp0_fsx"),near=som)

connect(dac["DATA0"],o["DAC_DATA0"])
shared.matched(o,o["DAC_DATA0"],S("mcasp0_axr0"),near=som)

connect(dac["SUB"],o["DGND"])

# create a subnet for REF5V
tie = NetTie(o,"A5V-REF5V")
connect(tie[1],o["A5V"])
connect(tie[2],o["REF5V"])
shared.bypass(o,o["REF5V"],o["AGND"],["10uF"],near=tie)

# master audio clock
clk = AudioSampleClock(o,near=dac)
shared.bypass(o,clk["VCC"],clk["GND"],["0.01uF"],near=clk)
connect(clk["VCC"],o["3.3V"])
connect(clk["GND"],o["DGND"])
connect(clk["OUT"],o["DAC_SCKI"])
r = LowPrecisionResistor(o,"47k",near=clk)
connect(r[1],clk["~INH"],o["AUDIO_CLOCK_INHIBIT"],som.assign_nearest_gpio(r[1],"PD"))
connect(r[2],o["DGND"])

The ER-101, ER-102 and ER-301 were all constructed this way.

3 Likes

I couldn’t agree with you more! Very well said!

2d

1 Like

i love the layouts of all the er modules, very well thought through and i’m getting pretty fast at programming them, especially the sequencer combo, after all these months programming them became almost muscle memory!

adjust and select
adjust and select
adjust and select

3 Likes

This is all fascinating reading - thank you very much for sharing :slight_smile:

On the subject of games controllers I have an old TAC-2 - it runs off 5V and it’s pretty easy to integrate it into modular. I have just ordered a socket for it to plug into and will be wiring it up so I have something a bit more stable to work with rather than a few lose wires hehe

If it works out I’ll report back with how it performs…

Today i learned about the existence of the E-mu Drumulator. It has a very ER-y vibe !
drumulator

2 Likes