Telex: Teletype expanders


Gonna scope it up tonight and see what is going on. I’ll share my results.


Hmm. Hooked up the scope. Not what I expected either.

Blue channel is recording power-on. Red channel is recording a hard-coded TR pulse at the end of the initialization function.

I’m not sure where in this sequence I actually flipped the switch. We’re dealing with milliseconds and me holding the probe against the Teensy V-in and ground. I’ll assume it is right around that voltage spike in blue.

What I see is that the Teensy power rises to 1.7V quite quickly. Then, it is less that 400ms between that power on and the pulse execution.

I have a secondary pulse being sent from the Teletype at init on a delay of 181ms. It blinks at exactly the same time (give or take a few ms) as the red pulse. I don’t have a 3+ channel scope to show it here.

So…the theory of super-slow voltage rise due to my circuit seems to not necessarily be the case.

When I profiled my init function, the whole thing took less than a millisecond. I’ll check it again tonight.

Hmmm. Wish there was a “boot faster” button. That would make this easier. :slight_smile:


Just looking through the setup() function.

Are you 100% sure you’re building with the DEBUG code disabled? Otherwise this line

while (!Serial);

will stop the world until the serial port initialises.

edit: can you try manually setting a GPIO high right at the beginning of the setup function and measuring that. I’ve noticed a lot of pointers and calls to new, it’s possible that you’re over taxing the allocator. Looking at the code, you could probably eliminate all the calls to new and the pointers (as far as I can tell there is no dynamic allocation needed e.g no calls to delete). Do you know much about RAII style C++?

edit: not sure the use of new will cause the hundreds of milliseconds delay though… is it possible there is some before main code hidden somewhere?


100%. With no USB connected, it would have never started up as it would be waiting forever for the serial connection. :slight_smile:

I will this evening when I’m back from the office and a dinner. On second thought, might be more like early tomorrow morning as I’ve not had the best of luck with wine and probes in the past. :wink:

It doesn’t. When I measured it, it didn’t look like the init function took over 1ms to execute.

At this point, I’m really not sure where the delay is coming from. Need to root around some more to see if I can identify any more potential culprits.

Will check again tonight/tomorrow morning.


Try a blank sketch with nothing in it apart from turning a GPIO on? That will give you the absolute baseline. (Well, not without replacing the Teensyduino framework.)

After you’ve sobered up though :tropical_drink: :sunglasses:


Ok. Test complete.

Right there with you, @sam; was planning to create an empty sketch with only the LED set. Here is the code:

And, what is going on is so evident visually that I didn’t need to wait till the wine-free morning in order to scope it. :slight_smile:

  • The TXo on the left is running the full module code is getting TO.TR.P 1 delayed at 191ms.
  • On the right, the code above is executing with a pulse on TR 1 and nothing else; no additional libraries, no additional code…

Video follows:


Time to get more paper towels and dig in.


I downloaded the video and Zaprudered it frame by frame. The Teletype is fully booted before the 2 LEDs come on :confused:

According to this post, you can define your own startup_early_hook to run code even earlier in the boot process.

Right, just tried my own TXo, with DEL 210: TO.TR.P 1 in the I script, I get no pulse at power on. With DEL 211: TO.TR.P 1 in the I, I do get a pulse.

That’s with a Doepfer LCB w/PSU3.


Announcing TELEX Firmware v.016

TELEXo Changes:

  • Recompiled reducing Teensy startup to 175ms (from 400ms)
  • Optimized memory for LED and Quantization Tables (moved to FLASH)
  • Fixed updates to envelope AD times while the envelopes are active and in that segment

TELEXi Changes

  • Recompiled reducing Teensy startup to 175ms (from 400ms)

Get them here:

Remember: make sure your Teensy is not connected to Euro-power when updating the firmware! Instructions for firmware updates are in your manual and on the main GitHub page.

@sam & @tehn -

I was able to reduce the startup time for the TELEX so that no additional delay is needed on the Teletype - although we still may need to add a little one on the TT to keep it from racing Ansible and others to the starting line.

Turns out, at some point a 400ms delay was added to the Teensy prior to calling the USB initialization to reduce complaints when people were trying to use components that weren’t ready because the Teensy started up “too fast”.

I modified “pins_teensy.c” on line 586 from 400 to 175. This should capture my case and @sam’s case - which was a little slower. I could go lower - but I didn’t want to push any of the components to unstable places (especially the DAC).

// for background about this startup delay, please see these conversations
// reduced to 175 from 400 for the TXo firmware

I’ll be putting some instructions for this on the GitHub site for the TELEX tomorrow for those that want to compile it themselves. Unfortunately, you have to go in and modify the code in your Arduino directory. It applies to everything you compile for the Teensy. (Shudder.)

Here is the nice forum where I got some help (saving me a lot of time):

Finally, thanks for inspiring further investigation. I’m glad we could keep startup as zippy as possible. :slight_smile: :slight_smile: :slight_smile:


Hey folks, what is the setup for using the onboard ADSR as a VCA?


Not next to mine but if I recall you setup the oscillator ( cv level 10, Osc to a freq greater than 0) then set up a trigger , then set up an envelope.


Thanks…but I guess I’m missing the routing part. Say you have CV 1 operating as an oscillator. And CV 2 as an envelope. What is the mechanism for routing the oscillator audio and having that envelop CV control the level?


Nevermind…stumbled onto the solution. So you enable oscillator on CV 1, then enable envelope on the same CV 1. Then TO.ENV.TRIG 1 1 pings that envelope…it’s as if a VCA is built into that one CV out. (As it says in the manual…duh…but until I experienced the operation, it didn’t make sense.).


Now that I’m wrapping my head around this…I want to build this up as a travel machine someday. :sunglasses:


Exactly. It’s all stacked in one channel. It makes sense once you get it, but I admit I stumbled on it.


Yup. The extended functions that are linked to each CV channel interact. CV controls the “peak”. Oscillations move between the peak and its polar opposite. Envelopes control changes to the peak over time - which cause it to behave like a VCA when the oscillator is active. :slight_smile:

The ENV also can be a bit confusing in that it mutes the CV channel until a TRIG command is sent - at which point it goes through the envelope to the peak voltage.

Once you get the hang of everything, the interaction model opens up some interesting behaviors. Try playing with negative voltages, slews (for both CV and OSC), offsets, changes to the oscillators center (OSC.CTR), slow LFO rates, morphing waveforms, rectification, log curves, changing attack + decay times mid-envelope, and the EOR/EOC triggers. You can get some wacky-cool stuff out of it for modulation and/or audio-rate enjoyment.


Thanks, gents. [head explodes]


Nice one!

I will add a 50ms startup delay.

Have you consider asking for the 400ms delay to be changed to a define that could be overridden more easily? (And would that even be possible with the Arduino IDE?)


The IDE is pretty crap when it comes to dependencies. I have a feeling that there is not a lot of flexibility in this regard, but I haven’t asked if it is indeed possible (or done any experiments).

Good call. :slight_smile:

I was surprised that our two systems differed by 20ms.


Talking about your Script above with the ENV.EOR and ENV.EOC…If I understand this Scene correctly…

Each single M Script blasts Script 8 4 times?

Then, as 8 gets triggered each time, B is read as 1, then line two it becomes 2, then on the second Script 8 read it is read as 3 and 4, 3rd Script 8, it is now 5 and 6, etc…

So those looped reads of Script 8 happen REALLY fast, eh?


Is A needed? Can you use I instead?