#oscillator — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #oscillator, aggregated by home.social.
-
Yep, it’s been half an hour and no dropouts… I’m calling it, my lovely new BBC Micro B is fixed :)
Yay! Soooo excited to play with it tomorrow 🥳
Here’s a before video:
https://vimeo.com/1181523949#t=26And an after:
https://vimeo.com/1182284426And the issue, for anyone else who stumbles on this thread, was the 16MHz oscillator circuit (marked X1 on the main board).
Also, I could only find a lot of 50 of them, so if anyone needs one, just hit me up and I’ll send it to you :)
Huge thanks to the folks on the stardot.org.uk for sharing the fix: https://stardot.org.uk/forums/viewtopic.php?p=246304#p246304
#BBCMicro #BBCMicroModelB #video #dropout #issue #fix #x1 #oscillator
-
Yep, it’s been half an hour and no dropouts… I’m calling it, my lovely new BBC Micro B is fixed :)
Yay! Soooo excited to play with it tomorrow 🥳
Here’s a before video:
https://vimeo.com/1181523949#t=26And an after:
https://vimeo.com/1182284426And the issue, for anyone else who stumbles on this thread, was the 16MHz oscillator circuit (marked X1 on the main board).
Also, I could only find a lot of 50 of them, so if anyone needs one, just hit me up and I’ll send it to you :)
Huge thanks to the folks on the stardot.org.uk for sharing the fix: https://stardot.org.uk/forums/viewtopic.php?p=246304#p246304
#BBCMicro #BBCMicroModelB #video #dropout #issue #fix #x1 #oscillator
-
Yep, it’s been half an hour and no dropouts… I’m calling it, my lovely new BBC Micro B is fixed :)
Yay! Soooo excited to play with it tomorrow 🥳
Here’s a before video:
https://vimeo.com/1181523949#t=26And an after:
https://vimeo.com/1182284426And the issue, for anyone else who stumbles on this thread, was the 16MHz oscillator circuit (marked X1 on the main board).
Also, I could only find a lot of 50 of them, so if anyone needs one, just hit me up and I’ll send it to you :)
Huge thanks to the folks on the stardot.org.uk for sharing the fix: https://stardot.org.uk/forums/viewtopic.php?p=246304#p246304
#BBCMicro #BBCMicroModelB #video #dropout #issue #fix #x1 #oscillator
-
Yep, it’s been half an hour and no dropouts… I’m calling it, my lovely new BBC Micro B is fixed :)
Yay! Soooo excited to play with it tomorrow 🥳
Here’s a before video:
https://vimeo.com/1181523949#t=26And an after:
https://vimeo.com/1182284426And the issue, for anyone else who stumbles on this thread, was the 16MHz oscillator circuit (marked X1 on the main board).
Also, I could only find a lot of 50 of them, so if anyone needs one, just hit me up and I’ll send it to you :)
Huge thanks to the folks on the stardot.org.uk for sharing the fix: https://stardot.org.uk/forums/viewtopic.php?p=246304#p246304
#BBCMicro #BBCMicroModelB #video #dropout #issue #fix #x1 #oscillator
-
Dear lazyweb,
Does anyone happen to know what company introduced the first TTL-compatible metal-can hybrid crystal oscillator in the DIP footprint (like a 14-pin DIP footprint, but with only the four corner pins), and when?
My web searches don't seem to yield relevant results. I'm not looking for the history of crystal oscillators in general. I think the type I've described appeared in the 1970s.
#hybrid #dip #crystal #oscillator -
Analog Siren for Psychedelic Soundscapes
https://web.brid.gy/r/https://hackaday.com/2026/03/21/analog-siren-for-psychedelic-soundscapes/
-
America Had No Domestic Quartz Crystals in 1946: Engineering Frequency Control
#quartz #quartzcrystals #quartzoscillators #oscillator #frequency #radio #SW #SWListening #electronics
-
NAND Oscillators and Logic Sequencers
I’ve had a bit of a play with logic based synthesizes in the past, but not in anger. However I’ve recently picked up “Make: Electronic Music From Scratch” by Kirk Pearson from Dogbotic.
It is excellent and a good chunk of that is based on circuits using the CD4093 Quad NAND chip, so I’ve started messing around properly with that again for a bit.
https://makertube.net/w/tJat6R4RqNqvvExkpWTgpA
Warning! I strongly recommend using old or second hand equipment for your experiments. I am not responsible for any damage to expensive instruments!
If you are new to electronics, see the Getting Started pages. Or better yet, buy their book 🙂
NAND Oscillators
As shown in the book, using a Schmitt Trigger NAND or NOT gate is a good, and relatively understandable, way to get a simple oscillator going. It is almost a “Hello World” of electronic music and has been covered and repeated all over the Internet!
Here are a few good references to dig into what is going on:
- Chapter 3 of the book.
- All About Circuits: “Exactly How Schmitt Trigger Oscillators Work”.
- Stomp Box Electronics: “Schmitt Trigger Oscillator Calculator”.
- Kristian Blastol: 40106 Hex Oscillator Bank – DIY Modular in a Week 1.1
Most circuits hook up a capacitor and potentiometer and there is an instant, tunable oscillator, but I’d like to see what is involved in generating specific frequencies, for a reason that might become clear later (in at least in a future blog post if not).
The All About Circuits page has a detailed breakdown of how the voltage, resistance, capacitance and frequency all relate to each other, and eventually, assuming a 50% duty cycle square wave, ends up with the following formula:
VT+ and VT- are the threshold voltages for the Schmitt trigger turning on and off. This will depend on the device in use, the supply voltage, and even the temperature (apparently) but for a CD4093, I’ve found the following extract of a datasheet:
So taking the operation at 25 degrees and 5V, the typical values are 3.3V and 2.3V respectively, but minimum values could be 2.6V to 1.4V. Putting these into the equation I can work out the constant 2ln(VT+/VT-) to be anything between 0.722 and 1.238. This isn’t particularly helpful…
Ok, so I can see why people just use tunable potentiometers…
So after some messing around with some capacitors and potentiometers, I seem to get a fairly decent range with a 1uF capacitor and 10K pot, so that is probably the way to go, using a trimpot to “tune” to notes I want.
At this point a simple monophonic keyed oscillator is possible, so that is what I’ll look at next,
The Basic Circuit
Here is a simple switched version of the previous circuit, with three “keys” and hence three possible notes.
The schematic for the above is as follows:
This makes it a little easier to see what is going on. Essentially we have three different resistor values available, but which one gets connected to the circuit is dependent on one of the switches being pressed.
In principle there could be as many switches and potentiometers as we like. And this is essentially the principle behind the Oskitone Poly555 except that is using a 555 timer circuit rather than a NAND oscillator, and actually the Oskitone has an individual, tunable, oscillator per key which allows for whole keyboard polyphony.
Note, that if two or more switches are pressed at the same time, then we’ll end up with several resistors in parallel giving a lower total resistance. This means that the resulting note would change as a result. So I guess one could argue that there are more possible notes than just three, but I’m not sure they’d be particularly useful notes…
A Step (or 8) Further
I’m not particularly interested in building a circuit with lots of switches on a breadboard, but some of the other circuits in the book have planted some interesting ideas.
Later on in the book, a few other chips are added to the mix:
- CD4017: Decade Counter
- CD4040: 12-Stage Ripple-Carry Binary Counter/Divider
- CD4046: Phase Locked Loop
- CD4051: 8:1 way Analog Multiplexer
- CD4053: 3-channel Analog Multiplexer
- CD4066: Quad Bilateral Switch
I won’t spoil the fun here (buy the book, I’m not linked to it – I bought my own copy, but it really is good), but it has really paved the way for me to reconsider how to use logic chips with oscillators.
What I’m interested in now is using the CD4051 analog multiplexer in place of the switches of the previous circuit, allowing me to “address” a note to be played by the oscillator.
The CD4051 datasheet has this diagram showing how it works:
This allows one of 8 circuits to be made, depending on the values of ABC, which are binary coded through the 8 values from 000 (0) to 111 (7).
The book pairs this with a CD4040 to count through the 8 values and hence produces a 8-step pitch sequencer from three chips, 8 pots, and a few passive components. But I want to drive the three address lines in a different way.
For now I’m going to connect each one up to each of the spare NAND oscillators – the 4093 has four NAND gates in total. The idea is that each of the bits will be controlled by a different oscillator, so as they go on and off in various combinations I’ll get what might feel like a fairly random selection between 0 and 7, and thus a fairly random note. I’m hoping for some interesting combinations as the they count in and out of phase.
But at this point I’m not even going to attempt to wire this up on a breadboard, so I’ve gone ahead and had a PCB built.
PCB Design
In the design I’ve included a jumper between each controlling oscillator and the sequencer, which allows the possibility of something externally controlling the sequence. I’ve also included two GND connections for use too.
I’ve also included jumper headers for power in and (audio) signal out. Note: the output signal is a 0-5V square wave signal and it is wired to the tip and shield of a TRS socket. The ring is left unconnected so either a mono or stereo lead can be used.
There are one or two silkscreen erratas on this board:
- I managed to miss out the label for the 4051, but as I’ve put it in the name for the PCB, I’m guessing that can probably be figured out in the future, when I’ve forgotten why I designed this board…
- I perhaps should have labelled the pots and trim pots.
- As described below, the values for the components used for the three additional oscillators are more useful if changed.
It might have been more useful to allow the channel select jumpers to be directly jumpered to GND, allowing me to test each oscillator in isolation, by grounding the other two channel inputs. But that can be done with leads.
So, with hindsight, there is something I should have changed on this design. The three oscillators as described are generating audio frequencies, but to drive the sequences I really want them to be acting as low-frequency oscillators. To do this, the capacitors should be swapped from 100nF to something more like 22uF, and the pots are better as 100K pots.
Unfortunately this doesn’t fit so well on the PCB – well the capacitors don’t anyway. The following highlights where the capacitors should be placed, and their polarity, instead. But it should be doable.
Bill of Materials:
- PCB
- 1x 4051 8:1 way Analog Multiplexer
- 1x 4093 quad NAND
- 8x 10K trimpots
- 3x 100K PCB mount potentiometers
- 2x 100nF ceramic capacitors
- 1x 1uF; 3x 22uF; 1x 47uF electrolytic capacitors
- 1x 3.5mm PCB mount stereo TRS socket
- Jumpers and header pins
- 1x 14-way; 1x 16-way DIP sockets
Here is a photo of a finished build:
Closing Thoughts
This was a really nice diversion. I do like the idea of using digital signals from something to select notes, so I’ll definitely come back to that at some point.
I’m not entirely sure I have anything of particular musical interest yet. But for now, it has shown some of the principles, and the book has really set off a number of ideas about using logic chips with oscillators. So I’ll come back to that at some point too.
Kevin
-
Almost a decade after getting my #hamradio license I've started playing around with #electronics again. It's so fun when you actually make things work out properly https://www.youtube.com/watch?v=5TwWUtZ6Q3I #colpitts #oscillator #breadboard #oscilloscope
-
Inside an Isotemp OCXO107-10 Oven Controlled Crystal Oscillator
https://tomverbeure.github.io/2025/10/26/Inside-an-Isotemp-OCXO107-10.html
#HackerNews #Isotemp #OCXO107-10 #Oven #Controlled #Crystal #Oscillator #Technology #Electronics #Engineering
-
Как выбрать опорный генератор и не разочароваться. Пример точной настройки 10 МГц с помощью ЦАП до 0.3 ppb (3 мГц)
Один из ключевых параметров качества радиотехнических устройств стабильность частоты, определяемая опорным генератором. Однако стремление к максимальным характеристикам не всегда оправдано. Выбор топового генератора без учета условий эксплуатации может привести к неоправданным затратам, усложнению конструкции и снижению надежности системы без существенного выигрыша для пользователя. В этой статье кратко рассматриваются основные типы опорных генераторов — от простых кварцевых резонаторов до высокоточных рубидиевых стандартов. С ростом стабильности частоты увеличиваются стоимость и сложность конструкции, а вот надёжность, может снижаться. На основе этого анализа предлагаются критерии выбора оптимального решения для разных задач. Также приводятся практические результаты: экспериментальные данные по долговременной стабильности частоты доработанного термостатированного генератора и результаты его программной подстройки с использованием ЦАП после выхода на рабочий режим.
https://habr.com/ru/companies/stc_spb/articles/945814/
#генератор #резонатор #OC #TCXO #OCXO #Rb #XO #Crystal #oscillator #стабильность_частоты
-
Things you find in barns, part 8.
Unit Oscillators: ”[These]Unit Oscillators are general-purpose radiofrequency power sources covering the ranges of 250 to 960 Mc and 180 to 600 Mc, respectively. These members of the convenient Unit Instrument line can be used to drive bridges, slotted lines, impedance comparators, and other measuring equipment. Used with a volt-meter and attenuator, they provide accurately known output voltages for the testing of receivers. (…)” Operating Instructions for the TYPES 1209-C AND ·CL UNIT OSCILLATORS, GENERAL RADIO COMPANY, June 1966.
#amateurRadio #hamRadio #oscillator #frequencySource #metering #measuringEquipment #retroElectronics #electronics #diy #technicalInstrument #ThingsYouFindInBarns
-
Things you find in barns, part 4.
A #klystron #oscillator anyone?
#physics #electronics #radio #uhf #microwave #particleAccelerator #diy -
Candle Oscillator Really Heats Things Up https://hackaday.com/2025/08/23/candle-oscillator-really-heats-things-up/ #clockhacks #oscillator #candle #clock
-
Candle Oscillator Really Heats Things Up - As the timebase for a clock, almost anything with a periodic oscillation can be us... - https://hackaday.com/2025/08/23/candle-oscillator-really-heats-things-up/ #clockhacks #oscillator #candle #clock
-
2025 One Hertz Challenge: Op-Amp Madness - Sometimes, there are too many choices in this world. My benchtop function generato... - https://hackaday.com/2025/07/31/2025-one-hertz-challenge-op-amp-madness/ #2025hackadayonehertzchallenge #clockhacks #oscillator #hardware #sinewave #analog #op-amp
-
2025 One Hertz Challenge: Op-Amp Madness - Sometimes, there are too many choices in this world. My benchtop function generato... - https://hackaday.com/2025/07/31/2025-one-hertz-challenge-op-amp-madness/ #2025hackadayonehertzchallenge #clockhacks #oscillator #hardware #sinewave #analog #op-amp
-
2025 One Hertz Challenge: Op-Amp Madness - Sometimes, there are too many choices in this world. My benchtop function generato... - https://hackaday.com/2025/07/31/2025-one-hertz-challenge-op-amp-madness/ #2025hackadayonehertzchallenge #clockhacks #oscillator #hardware #sinewave #analog #op-amp
-
2025 One Hertz Challenge: Op-Amp Madness - Sometimes, there are too many choices in this world. My benchtop function generato... - https://hackaday.com/2025/07/31/2025-one-hertz-challenge-op-amp-madness/ #2025hackadayonehertzchallenge #clockhacks #oscillator #hardware #sinewave #analog #op-amp
-
2025 One Hertz Challenge: Op-Amp Madness - Sometimes, there are too many choices in this world. My benchtop function generato... - https://hackaday.com/2025/07/31/2025-one-hertz-challenge-op-amp-madness/ #2025hackadayonehertzchallenge #clockhacks #oscillator #hardware #sinewave #analog #op-amp
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #Parts #fft #Tek #THD
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #Parts #fft #Tek #THD
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #Parts #fft #Tek #THD
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #Parts #fft #Tek #THD
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator - Tektronix must have been quite a place to work back in the 1980s. The company offe... - https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #parts #fft #tek #thd
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator - Tektronix must have been quite a place to work back in the 1980s. The company offe... - https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #parts #fft #tek #thd
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator - Tektronix must have been quite a place to work back in the 1980s. The company offe... - https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #parts #fft #tek #thd
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator - Tektronix must have been quite a place to work back in the 1980s. The company offe... - https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #parts #fft #tek #thd
-
Recreating the Analog Beauty of a Vintage Tektronix Oscillator - Tektronix must have been quite a place to work back in the 1980s. The company offe... - https://hackaday.com/2025/03/29/recreating-the-analog-beauty-of-a-vintage-tektronix-oscillator/ #totalharmonicdistortion #classichacks #oscillator #tektronix #sinewave #analog #parts #fft #tek #thd
-
STM32 Tutorial #31 - Measuring LSI Frequency (for Watchdog)
In an earlier video (Tutorial video #29) we worked with the Independent Watchdog (IWDG) and were slightly confused about the timing. In this video we will verify the results we found but actually measuring the frequency of the LSI (Low Speed Internal oscillator). It is incredible important to understand the implications of the LSI drift.
#STM32 #Tutorial #lsi #watchdog #iwdg #stm32world #oscillator #frequency
https://www.youtube.com/watch?v=4lfsBK5ahWA -
STM32 Tutorial #31 - Measuring LSI Frequency (for Watchdog)
In an earlier video (Tutorial video #29) we worked with the Independent Watchdog (IWDG) and were slightly confused about the timing. In this video we will verify the results we found but actually measuring the frequency of the LSI (Low Speed Internal oscillator). It is incredible important to understand the implications of the LSI drift.
#STM32 #Tutorial #lsi #watchdog #iwdg #stm32world #oscillator #frequency
https://www.youtube.com/watch?v=4lfsBK5ahWA -
STM32 Tutorial #31 - Measuring LSI Frequency (for Watchdog)
In an earlier video (Tutorial video #29) we worked with the Independent Watchdog (IWDG) and were slightly confused about the timing. In this video we will verify the results we found but actually measuring the frequency of the LSI (Low Speed Internal oscillator). It is incredible important to understand the implications of the LSI drift.
#STM32 #Tutorial #lsi #watchdog #iwdg #stm32world #oscillator #frequency
https://www.youtube.com/watch?v=4lfsBK5ahWA -
VNAs and Crystals - Oscillators may use crystals as precise tuned circuits. If you have a vector netwo... - https://hackaday.com/2024/12/06/vnas-and-crystals/ #oscillator #toolhacks #crystal #parts #vna
-
In the first part I described the concept and basic design parameters I was looking for and then in Part 2 I looked at the detailed electronic design for a board based on the ESP32 WROOM module I have. In this part I go into detail about the code.
- Part 1 – This introduction and high-level design principles.
- Part 2 – Detailed design of an ESP32 based PCB.
- Part 3 – Software design.
- Part 4 – Mechanical assembly and final use – todo.
Warning! I strongly recommend using old or second hand equipment for your experiments. I am not responsible for any damage to expensive instruments!
The ESP32 EduMod Hacked Synth Thing
As mentioned in the last part, the principles and code I’m using are taken from these previous posts:
I also now have a built PCB design to make development and testing a lot easier.
Recall the following design choices:
- The two ESP32 DACs are the output for two envelope generators, each driven by four pots (in standard ADSR configuration), a trigger and a gate signal.
- There are ESP32 PWM outputs for two VCOs, each with four waveforms (sine, triangle, saw, square) and an analog input (pot or CV) for frequency and amplitude.
- ESP32 PWM outputs are also used for a LFO with rate and depth analog controls.
- The ESP32 UART is used for MIDI in.
- ESP32 digital IO is used for the envelope GATE and TRIGGER signals, although they are level inverted, i.e. they should be read as active LOW.
Othe points to note:
- There are three “native” analog inputs used for the two VCO pitch and amplitude CVs. All other pots are read via a CD4067 16-way multiplexer.
- Software will determine how the VCO CVs interact with the potentiometers.
- The UART RX pin will be used for MIDI and the UART TX pin will be used for one of the PWM outputs, so there will be no serial port (via USB) for diagnostic output.
- The ESP32 is a dual core microprocessor, so the aim is to split the functionality across the two cores.
High Level Design
The tasks will be split as follows:
- Core 0:
- Runs the PWM timer at 32,768Hz (although the sample rate will be half this – more on that later).
- Manages the PWM outputs for the two VCOs and the LFO.
- Core 1:
- Runs the EG timer for the DAC at 10,000 Hz.
- Handles the reading of all the IO: “real” analog values; multiplexed analog values; digital IO.
- Handles MIDI.
Multicore ESP32 Arduino
Multicore support for the ESP32 on Arduino is provided using FreeRTOS tasks. For a FreeRTOS application, the default Arduino setup()/loop() will run on core 1. However, once tasks have been created to run on the second core, the default loop is no longer used (I believe).
FreeRTOS enables multitasking on a single CPU (core), each with its own internal priority relative to other tasks. But I’m only using it to start a single task on each core. This is achieved using the xTaskCreatePinnedToCore() function. The last parameter specifies which core to use and the 5th parameter indicates the priority – both are set to “1” as there is only a single task on each core.
The Arduino startup code has thus been reduced to the following:
void core0Entry (void *pvParameters);
TaskHandle_t core0Task;
void core1Entry (void *pvParameters);
TaskHandle_t core1Task;
void setup () {
xTaskCreatePinnedToCore(core0Entry, "Core 0 Task", 4096, NULL, 1, &core0Task, 0);
xTaskCreatePinnedToCore(core1Entry, "Core 1 Task", 2048, NULL, 1, &core1Task, 1);
}
void loop () {
// No main loop here
}
void core0Entry (void *pvParameters) {
Task0Setup();
for (;;) {
Task0Loop();
vTaskDelay(1); // Allow FreeRTOS IDLE to maintain watchdog
}
}
void core1Entry (void *pvParameters) {
Task1Setup();
for (;;) {
Task1Loop();
vTaskDelay(1); // Allow FreeRTOS IDLE to maintain watchdog
}
}I’ve simulated the setup()/loop() pattern in each of the task entry points. One thing I quickly found was that if the tasks run with no release of the processor, then FreeRTOS will fail with a watchdog error.
This is why each task includes a vTaskDelay(1) call to allow FreeRTOS to do whatever it needs to do as part of its “idle” processing.
The other thing to be careful of, which would be the same even in a single core application, is that the timers and their timer interrupt routines also allow some general processing time on each core. This will become important further in the discussion.
Task 0: PWM Generation
The essence of Task 0 is the code from ESP32 and PWM. In order to simplify things I’ve created a basic oscillator class as follows:
class COsc {
public:
COsc ();
~COsc (void);
void Setup (int pwmpin, int wave, bool lfo=false);
void QuadSetup (int sinpin, int sawpin, int tripin, int squpin);
void ScanPWM (void);
void SetFreq (uint16_t freq, uint16_t vol=MAX_VOL);
void SetMVolts (uint32_t mvolts, uint16_t vol=MAX_VOL);
}Initially the plan was to have one instance per PWM output. The pin and required waveform is configured as part of the call to the Setup() function.
But then I decided it would be more efficient to utilise the fact that the same index and accumulator can be used to read through each of the four wavetables, so created the idea of a “quad” oscillator. This just requires the four PWM pins to be used to be specified as part of the call to QuadSetup() and eliminates several calls into the ScanPWM function for separate oscillators.
There are two ways to set the oscillator’s frequency output. One is to pass in the frequency directly, the other is to pass in a millivolt reading from a potentiometer based on a 1V/oct scaling. The “zero volts” frequency is preset to be 65.406Hz, i.e. C2.
The frequency is derived from the millivolt reading using the following:
void COsc::SetMVolts (uint32_t mvolts, uint16_t vol) {
// Set frequency according to Volt/Oct scaling
// Freq = baseFreq * 2 ^ (voltage)
//
float freq = FREQ_0V * (powf (2.0, ((float)mvolts)/1000.0));
int f = (int)freq;
SetFreq(f, vol);
}With the default settings this class can be used for both VCO and LFO, but the lowest frequency for the LFO was just 1Hz. Consequently, I’ve added the option to specify a “LFO” setting as part of the single oscillator Setup() function. If enabled, then the oscillator runs 10x slower than default. This allows for frequencies down to 0.1Hz, but does mean that the frequency or millivolt parameters are now treated as being 10 times smaller than their values would imply.
Note when MIDI is added into the mix, I just use the NoteOn message to change the base frequency used for the oscillators.
The ScanPWM() function is designed to be called from the interrupt routine running at the sample rate.
The oscillators are thus created as two Quad oscillators (one per VCO) and two single oscillators for the dual waveforms of the LFO:
#define OSC_VCO1 0
#define OSC_VCO2 1
#define OSC_LFO1 2
#define OSC_LFO2 3
#define NUM_OSC 4
COsc *pOsc[NUM_OSC];
int pwmpins[NUM_OSC][4] = {
{17,18,5,19},
{21,22,1,23},
{16,0,0,0},
{13,0,0,0}
};
int oscwaves[NUM_OSC] = {
OSC_WAVES, // VCO 1 (quad)
OSC_WAVES, // VCO 2 (quad)
OSC_TRI, // LFO
OSC_SAW
};
void oscSetup() {
for (int i=0; i<NUM_OSC; i++) {
pOsc[i] = new COsc();
if (oscwaves[i] == OSC_WAVES) {
// This is a quad oscillator
pOsc[i]->QuadSetup (pwmpins[i][0], pwmpins[i][1], pwmpins[i][2], pwmpins[i][3]);
} else {
// A single oscillator - these are the LFOs
pOsc[i]->Setup (pwmpins[i][0], oscwaves[i], true);
}
}
}The timer configuration for Task 0 is as follows:
#define TIMER_FREQ 10000000 // 1MHz * 10 (0.1uS)
#define TIMER_RATE 305 // 30.5 uS * 10
Task0Timer = timerBegin(TIMER_FREQ);
timerAttachInterrupt(Task0Timer, &Task0TimerIsr);
timerAlarm(Task0Timer, TIMER_RATE, true, 0);This generates a timer interrupt running at 32,768Hz from a 10MHz timer
However, servicing 10 PWM outputs means that there is no time remaining once interrupt processing is complete for any other operations. Consequently, I set things up so that the PWM outputs are updated in two blocks of 5, meaning that the effective sample rate for PWM purposes is actually now 16,384Hz:
int toggle0;
void ARDUINO_ISR_ATTR Task0TimerIsr (void) {
toggle0 = !toggle0;
if (toggle0) {
pOsc[OSC_VCO1]->ScanPWM();
pOsc[OSC_LFO1]->ScanPWM();
} else {
pOsc[OSC_VCO2]->ScanPWM();
pOsc[OSC_LFO2]->ScanPWM();
}
}The main Task 0 Loop just pulls in the analog IO values that have been read as part of the processing of Task 1. These values are then used to set the frequencies of each VCO and the LFO.
Task 0: VCO Control
The VCO potentiometers and CV inputs have to be combined to determine the frequency and amplitude of the PWM signal.
In terms of amplitude, I’ve chosen to use the maximum of the pot or CV input to set the amplitude of VCO 1. Note that VCO 2 has no amplitude input, although with hindsight, I could have included a pot even though I’ve run out of GPIO pins for a CV input.
This means that the pot has to be turned fully “off” for the CV to become significant.
In terms of setting the frequencies, I initially thought about some kind of frequency modulation, which would have been good for linking the two VCOs together, but then decided actually I wanted a more straight forward relationship between pot and CV to allow the use of the LFO or the EGs for pitch. The result is going for a simple summation of the two inputs which gives a 3 octave range (started at C2) for each of the CV and pot, but when combined could give up to a 6 octave spread of frequencies.
When MIDI is enabled, that will set the base frequency for the summation rather than defaulting to C2. This will set the base for both VCOs, so the pots/CVs could be used for a detuning style effect.
Note: Due to the issues with the choice of pins for the inputs, the base level of the CV input for VCO2 is floating at around 300-600mV. The default (unconnected) configuration introduces an element of detuning. If the CV inputs are not wanted, then it is recommended to connect them to GND to eliminate this effect.
The result of taking this approach, combined with the frequency of scanning the inputs, means that if one VCO is used to set the frequency for the other, then it probably won’t track the voltages accurately enough for a smooth modulation. But it does generation quite a wacky “sample and hold” style aliasing effect, which actually I quite like.
I could try to do something about that, but I think in reality this is a use-case where a purely analog VCO can be added via breadboard as part of the experimentation which can be driven from the PWM VCOs – that should enable a number of possibilities for more complex oscillator modulation.
There is also some clipping at higher LFO frequencies if used as the amplitude input. This needs to be investigated to see if that is a bug in the code or handling of the CV somehow.
It is possible that this, and the aliasing of pitch, is a consequence of the frequency of scanning the analog inputs or the speed of the analogRead() function itself – it’s pretty slow. Some investigation is required to experiment with changing the frequency of the reading or rewriting to use the ESP32 API rather than the (slower) Arduino analogRead() function (more on that later).
Task 1: IO Scanning
All the IO is scanned as part of Task 1’s main processing loop. This has to cover the following:
- Real analog values from the inputs corresponding to the VCO CVs.
- Multiplexed analog values for all the pots for the VCOs, LFO and two EGs.
- Digital IO for the EG gates and triggers.
I started off reading the “real” analog IO associated with the VCOs in task 0, but found that it just wasn’t being scanned frequently enough to function in any useful manner. Also, the calls to analogRead() incur some kind of processing overhead that appears to interfere with the timing of the PWM timer interrupt, leaving “blips” in the output.
I started to think about writing a FastAnalogRead() function to use the ESP32 SDK directly rather than the Arduino analogRead() function, but before doing that moved all the IO processing over to Task 1. It turns out that this seems to work adequately so if I’ve not done that at present.
But one consequence of this chain of thought is that I now have two sets of functions performing my own analog IO reading:
- MuxAnalogRead()
- FastAnalogRead()
Which both perform in very similar ways. I’ll describe the API for MuxAnalogRead(), but the same principles were used for FastAnalogRead() too.
void MuxSetup(void);
void MuxLoop(bool bVoltageReading=false);
void MuxLoopSingle (uint8_t pot, bool bVoltageReading=false);
uint16_t MuxAnalogRead (uint8_t pot);
uint32_t MuxAnalogReadMilliVolts (uint8_t pot);The two Loop functions are designed to perform the actual reading from the hardware. Loop will read all known values in a single scan. LoopSingle() will read a single pot.
The functions MuxAnalogRead() and MuxAnalogReadMilliVolts() are used to retrieve the previously read values.
Scanning is performed using either the standard analogRead() or the ESP32 API function analogReadMilliVolts(). This is why a bVoltageReading parameter is required as part of the two Loop functions. It would be possible to calculate one from the other for every reading, but I’ve opted not to do that in order to keep the calculations required as part of a read as minimal as possible.
This allows the scanning of the hardware to happen on one core (in Task 1 in this case) yet be read from the other (Task 0).
Digital IO processing just requires monitoring the trigger and gate inputs for a HIGH->LOW transition and call the appropriate triggerADSR() or gateADSR() functions as required, although there is a bit more logic required to work in the MIDI input.
The actually scanning of IO is split over the different scans of the Task Loop as follows:
#define S_MUX (NUM_MUX_POTS-1)
#define S_FASTIO (S_MUX+1)
#define S_DIGIO (S_FASTIO+1)
#define S_ALGIO (S_DIGIO+1)
#define S_MIDI (S_ALGIO+1)
#define S_LAST (S_MIDI+1)
int taskState;
void Task1Loop(void)
{
if (taskState <= S_MUX) {
// Read each MUX pot in turn
switch (taskState) {
case 5: // VCO 1 CV
case 7: // VCO 2 CV
// These are read in millivolts...
MuxLoopSingle(taskState, true);
break;
default:
// These are read as 12-bit raw 0..4095
MuxLoopSingle(taskState, false);
break;
}
}
else if (taskState == S_FASTIO) {
Task1FastAlgIOLoop();
}
else if (taskState == S_DIGIO) {
Task1DigIOLoop();
}
else if (taskState == S_ALGIO) {
Task1AlgIOLoop();
}
else if (taskState == S_MIDI) {
Task1MIDILoop();
}
else {
taskState = S_LAST;
}
taskState++;
if (taskState >= S_LAST) {
taskState = 0;
}
}Task 1: Envelope Generation
The core of the envelope generation code is from ESP32 DAC Envelope Generator, but once again the code has been refactored into a class as follows:
class CEnv {
public:
CEnv ();
~CEnv (void);
void setADSR (int eg_a, int eg_d, int eg_s, int eg_r);
uint8_t nextADSR (void);
void triggerADSR (void);
void gateADSR (bool gateOn);
void dumpADSR (void);
}One change is setting the ADSR parameters in a single call. The values are assumed to be potentiometer readings in the range 0..4095.
Two envelope generators are created by Task 1:
CEnv *pEnv[NUM_ENV];
void envSetup() {
for (int i=0; i<NUM_ENV; i++) {
pEnv[i] = new CEnv();
}
}The nextADSR() function has to be called for each envelope generator from the timer interrupt routine.
The timer configuration for Task 1 is as follows:
#define TIMER_FREQ 100000 // 100kHz (0.01mS)
#define TIMER_RATE 10 // 0.1mS
Task1Timer = timerBegin(TIMER_FREQ);
timerAttachInterrupt(Task1Timer, &Task1TimerIsr);
timerAlarm(Task1Timer, TIMER_RATE, true, 0);This generates a 10kHz sample rate for the EGs from a 100kHz timer signal.
Task 1: MIDI
I’m using the standard Arduino MIDI library. There are a couple of points to note however:
- MIDI will set the TRIGGER and GATE according to the reception of NoteOn and NoteOff messages.
- I will need to keep track of which note is playing so that overlapping NoteOn/NoteOff messages don’t confuse the GATE handling.
- As I’m reusing the TX pin as a PWM output, PWM initialisation must happen after MIDI initialisation, otherwise MIDI will assume the use of both RX and TX.
- Serial MIDI by default implements “software MIDI THRU” so this needs to be disabled using setThruOff().
- MIDI will set the base frequency used for the VCO controls, so the pot and CV will add to the MIDI frequency.
It isn’t clear what should happen with regards to frequency on NoteOff. Here are some options:
- Reset back to default base frequency on NoteOff (the “0V” state), but this has the disadvantage that the frequency changes as soon as the gate signal initiates the Release state of the ADSR.
- Wait until the envelope has finished the Release stage to reset the base frequency. This seems sensible when using the EGs, but has the disadvantage that when just using MIDI to set pitch, it will not revert back immediately on “key up” – it will only revert back when the envelope is complete, which is confusing if the EG is not being used.
- Don’t reset the base frequency, this means the note will continue on the last used frequency until a new note is played.
I’ve opted not to reset the base frequency on the basis of: if MIDI on/off handling is required, then it will probably be using envelopes anyway. If not, then having only MIDI on setting a sustained frequency sort of makes more sense to me.
Closing Thoughts
The code will continue to evolve as I keep tinkering with it, but the current state can be found in the GitHub repository for the project here: https://github.com/diyelectromusic/ESP32EduModHackThing
There are still a few quirks and things I might continue to investigate and possibly optimise. Specifically:
- The performance for reading the “real” analog CVs for the VCOs.
- The frequency handling with respect to MIDI.
But in general I think it is starting to get pretty usable.
Kevin
https://diyelectromusic.wordpress.com/2024/05/26/educational-diy-synth-thing-part-3/
#adsr #define #envelopeGenerator #esp32 #lfo #oscillator #vca #vco
-
At least the single rail #opamp #oscillator circuit works with these counterfeit chips. Maybe I'll turn them all into #LED blinkies and Schmitt triggers.
-
In the first part I described the concept and basic design parameters I was looking for. In this part I go into detail about how I’m going about implementing them with an ESP32 WROOM board.
- Part 1 – This introduction and high-level design principles.
- Part 2 – Detailed design of an ESP32 based PCB.
- Part 3 – Software design.
- Part 4 – Mechanical assembly and final use – todo.
Warning! I strongly recommend using old or second hand equipment for your experiments. I am not responsible for any damage to expensive instruments!
The ESP32 EduMod Hacked Synth Thing
The principles and code I’m using are taken from these previous posts:
From the experience gained so far, I’ve gone for the following:
- Use the ESP32 DACs for the output for two envelope generators, each driven by four pots, a trigger and a gate signal.
- Use the ESP32 PWM outputs for two VCOs, each with four waveforms (sine, triangle, saw, square) and an analog input (pot or CV) for frequency and amplitude.
- Use another ESP32 PWM output for a LFO with rate and depth analog controls.
- Use the ESP32 UART for MIDI in.
- Use a TDA7052A as the final VCA/audio output stage.
Adding all this up, and taking the view that the VCOs will be supporting simultaneous waveforms on four pins each (rather than any kind of waveform selection input), I’m going to need some kind of IO expander. The easiest thing is probably to use an analog multiplexer for the twin ADSR and LFO controls. I’m designing this around a CD4067 analog multiplexer which provides 16 input channels and will require 4 IO pins for control and 1 IO pin for the analog value to read.
This leads me to the following pin usage, using the same cheap ESP32 WROOM module, I’ve used for my other experiments so far:
ENGPIO23PWM OUTVCO 2 SquareEG 2 GateDig InputGPIO36GPIO22PWM OUTVCO 2 SawEG 2 TriggerDig InputGPIO39GPIO1PWM OUTVCO 2 TriangleEG 1 GateDig InputGPIO34GPIO3RXD 0MIDI INEG 1 TriggerDig InputGPIO35GPIO21PWM OUTVCO 2 SineALG Mux InputAlg InputGPIO32GPIO19PWM OUTVCO 1 SquareALG Mux S0Dig OutputGPIO33GPIO18PWM OUTVCO 1 SawEG 1 OUTDAC 1GPIO25GPIO5PWM OUTVCO 1 TriangleEG 2 OUTDAC 2GPIO26GPIO17PWM OUTVCO 1 SineALG Mux S1Dig OutputGPIO27GPIO16PWM OUTLFO TriangleALG Mux S2Dig OutputGPIO14GPIO4Alg InputVCO AmpALG Mux S3Dig OutputGPIO12GPIO2Alg InputVCO 2 CVLFO SawPWM OUTGPIO13GPIO15Alg InputVCO 1 CVGNDGNDVIN3V3One thing I hadn’t considered when defining the above pinout (and subsequently designing a circuit around it) is the ESP32’s strapping pins. There are six pins that are used as configuration pins on boot to set the various mode and operation of the device and of course it assumes the use of the UART. Once booted, they can usually be used as normal GPIO pins, but if connected circuitry changes the state on boot, then unexpected things may occur.
See the discussion below for further details, implications, and things I’d wish I’d realised before putting a design together 🙂
The analog inputs for the Mux are defined as follows:
1 (I0)Not used2 (I1)LFO Rate3 (I2)LFO Depth4 (I3)EG 1 Attack5 (I4)EG 1 Decay6 (I5)VCO 1 Pitch CV7 (I6)VCO 1 Amplitude CV8 (I7)VCO 2 Pitch CV9 (I8)EG 1 Release10 (I9)EG 1 Sustain11-12 (I10-I11)Not used13 (I12)EG 2 Release14 (I13)EG 2 Sustain15 (I14)EG 2 Decay16 (I15)EG 2 AttackBasic electrical properties and design principles
- All internal control signals (CV, triggers or gates) will be using 3V3 levels. All internal audio signals will be DC biased to the 0-3V3 range.
- Internal patch points will be using jumper wires to make it clear that these are not “proper” modular signals for general patching outside of the unit.
- A special input will be provided for a MIDI IN socket.
- CV, trigger and gate signals will include basic protection to limit them to the 0-3V3 levels for use within the system.
- An output stage will be provided that will support either a directly connected small (8Ω) speaker or a mono line out jack.
- Power will be duplicated to a header on the side of the unit to allow for easy connections to breadboards.
- The PCBs will fit in a 100x100mm footprint to keep costs down, but I might end up with several per unit.
- All code will run on a single ESP32 WROOM dev module that seems easily, and cheaply, available.
There will be some, but limited protections on internal jumper connections. I’m working on the basis that it should be fairly cheap to build, all chips should be relatively cheap and easy to replace (and therefore socketed), so educated experimentation is encouraged, but uneducated plugging in will probably break something.
As long as everything stays within the 0-3V3 range, it should probably be ok, though.
ESP32 Strapping Pins
Section 2.4 of the ESP32 datasheet (“Strapping Pins”) has all the details. Essentially a number of pins are pulled high or low using the internal pullup or pulldown resistors. These define the boot configuration for the board and can be overridden by external pullup or pulldown resistors.
One or two other pins have additional circuitry too on a typical DevBoard.
The key GPIO pins used as Strapping pins are:
- GPIO 0 is the boot button, so I’m not worried about that. However to enter boot mode both GPIO 0 and GPIO 2 must be LOW. If my use of GPIO 2 is an issue, then I’ll have to flash the board before plugging it in. Once plugged in and booting from flash, then the state of GPIO 2 is irrelevant to the ESP32. GPIO 2 is pulled LOW via an external 10K resistor though on my dev board too.
- GPIO 2 on my DevKit board is also connected to the onboard LED with a 1K resistor to ground. This means that it’s use for an analog input was probably a mistake! It is possible to remove the onboard LED if required, but otherwise this means that the analog input range will be somewhat decreased to around 2.3V.
- GPIO 4 is pulled LOW. I don’t know what the significance of this is, but as this is connected to a CV input stage, when nothing is plugged in, this will be default pulled LOW externally too. I don’t know what will happen if a CV is present on boot…
- GPIO 5 is internally pulled HIGH. It is connected to a PWM output circuit, so I might be ok. To be determined…
- GPIO 12 (MTDI) is pulled LOW. It is connected to the MUX address pin, which is a digital input pin. If that works like a microcontrollers input pin then it will have a high impedance in which case, this should be fine.
- GPIO 15 (MTDO) is pulled HIGH. This determines if the boot is “silent” or not – i.e. if startup messages are sent to the UART. As I’m using the TX pin (GPIO 1) as a PWM output, it would be advantageous actually to have this LOW to stop any output, but either way it shouldn’t be a big deal. This pin is connected to a CV input stage with a default pull LOW resistor if nothing is plugged in, but I suspect the internal pull-up to be the stronger of the two and most likely to “win” out.
- GPIO 1 and 3 are TX and RX respectively. RX is connected to the MIDI IN circuit, so this means that board can’t be programmed while connected anyway. TX is configured for a PWM output circuit so there may be spurious output signals on startup for a short period of time on this output.
There is a good summary of some of the implications of attempting to use the strapping pins on this page here.
From the above discussion, I think I might get away with it for the most part (although GPIO 2 is annoying), but I’ll have to see once the boards are made up and do some proper tests. At present, I suspect the most significant ramification of the above is that I won’t be able to program the ESP32 module whilst plugged in, but that is likely to be as a result of the MIDI circuit on RX rather than anything else.
Update after testing:
- GPIO 0: not relevant.
- GPIO 2: as mentioned above, GPIO 2 will not present the full range as the analog input. I believe this is related to the voltage drop across the LED so one option is simply to desolder the LED or its resistor from the board. Also, when not connected the minimum reading is equivalent to 400-600mV rather than zero.
- GPIO 4: this largely works, but when not connected does seem to not quite read full zero, but that could just be noise.
- GPIO 5: no noticeable impact.
- GPIO 12: no noticeable impact.
- GPIO 15: this works fine with an analog input connected, but like GPIO 4 doesn’t quite get to zero when not connected.
ESP32 VCOs and LFO
These will be based on the ESP32 and PWM experiments – I’m planning to include two VCOs and a LFO.
The VCOs will take an analog input – a control voltage for frequency which can come from a pot or an external signal. One of the VCOs will also include a CV for amplitude, to allow some simple shaping (e.g. from the LFO). Both will output four PWM signals: sine, triangle, saw, square – each on its own output pin. I’ll use the built-in tone() function for the square wave – that won’t need a DDS approach.
The CV input will be using a 1V/oct scale, so the input range will be relatively narrow – just over three octaves. I do plan to hook up a MIDI input to the ESP32’s UART so that can feed a frequency directly into one of the VCOs without going via the analog stage, to give a wider range over MIDI only.
Of course, I need to decide what note/frequency 0V will start at.
Control Voltages
Each VCO analog input stage will consist of a pot which can act as a manual control voltage or as some kind of control for an external control voltage. But should the pot add to the external voltage or limit (attenuate) it? If it adds, then it would provide the ability to set an offset to the external signal. If attenuating then it affects the range of the external signal.
I originally went with the following circuit, which is largely based on the input stage of the MiniMo (ATtiny85 based) synth.
But the operation of the pot wasn’t quite what I wanted. With no CV, then the pot allows adjustments between 3V3 and 0V. But when a 3V3 CV is applied to the input, then there is effectively now a voltage divider happening which reduces the peak-to-peak range of the input signal by half and then moves the DC bias between 0-1.5V through to 1.5-3V (or there abouts). Given the limited voltage range anyway, I really wanted to be able to pick up the full 0-3V3 range of the CV if possible.
If all I want is attenuation then one way to achieve this would be to use a switched jack, where the switch will link the pot to the CV when a jack is inserted and to 3V3 when it isn’t, but I wanted to be using jumper wires with no switches.
I’ve gone for summation of the signals, so in the end I decided I’d just do it in software and wire the pots in directly to an analog input then construct a pot-less CV input stage.
As the CV input will be limited at 0-3V3 it will need to be protected against over and under voltage. I’ve seen a range of approaches to achieving this, but in the end I took the basic principles from the modules designed by Hagiwo, resulting in the following circuit:
As I understand things, for the CV input, the BAT43 zener diodes will “clamp” the input CV to GND or 3V3 in the case of under or over voltage; whilst the values of the resistors (1K/680K) mean that there is a sensible impedance but little voltage change. In some cases, I’ve seen the use of a voltage divider here to change a 5V signal into a 3V3 signal. That might be ok if the microcontroller then still treats the 3V3 signal as a “full range” (5 octave) signal, but in my case I want to preserve any 1V/Oct input on any intermediate signal, even if that then leaves me with a smaller three octave+ (0 to 3V3) range.
PWM Output Filtering
Each PWM output will be in the 0-3V3 range, at typical audio frequencies, so a simple low-pass filter will be added as follows:
This is a simple one-stage low-pass filter with a 3db point of just under 5kHz which hopefully gives a nice smooth output. I tried 470, 680 and 1K resistors and 68nF and 100nF capacitors and couldn’t see a significant difference at my test 440 Hz signal, so went with the lower values for a higher cutoff to support more audio frequencies of notes.
The LFO will have two pot controls – rate and depth (amplitude) and no external control. It will provide a triangle and saw PWM output.
Note: If the capacitor is left off the square wave signal then a sharper square wave is possible, so I’ll leave these as optional on the circuit board itself, but will probably leave them out in my build. This makes sense as the sharpest square wave would be a continuing series of odd harmonics, so if I’m filtering out any above 5kHz that will take away quite a few!
In fact, as already mentioned, in code it probably makes sense for the square wave to be a tone() signal rather than a PWM output anyway, in which case the sharpest signal would be with no resistor either, but I suspect some resistance is necessary to protect against whatever the pin ends up driving. Keeping with 470 will match the other outputs, but an even sharper signal is possible with 220 instead. I’ll stick with 470 to keep everything matched. I will be using tone() rather than PWM in the code.
Envelope Generator
The gate and trigger connections for the two envelope generators will allow external connections. This could be a button or an external active HIGH signal. To get these into the microcontroller, requires a circuit like the following (I’ve found various versions of this online, but I think the definitive version came from Rich Holmes – at least on the forums I was looking at anyway):
Again, as I understand things, the use of a diode and transistor provides over and under voltage protection, the resistors provide current protection, and the 1M to GND resistor ensures the input isn’t floating if unconnected.
One issue with this circuit is that the signal to the microcontroller is inverted – i.e. it will be default HIGH until the gate is activated in which case it will become active LOW. The code in the microcontroller has to take this into account.
There will be four of these circuits, one for each of the gate and trigger inputs for each of the two envelope generators.
A manual gate or trigger can be built from a switch that connects the EGn_EXT_yyyy signal to 3V3, with a suitable capacitor for debouncing.
Other External Signals
An external connection will be provided for MIDI IN which will be my standard 3V3 compatible, H11L1 optoisolator based MIDI circuit, so no surprises there. I’m not providing MIDI out.
This will go directly into the ESP32’s RX pin for UART 0 and processed in software to generate an internal CV/gate/trigger signal. This CV/gate/trigger won’t be visible outside the microcontroller – it will be the one part of the system that remains entirely within software. This means that MIDI should extend to a full range of pitches, not just those within the 0-3V3 1V/oct range.
There will be no special hardware for USB, so if USB MIDI is supported in the end, then it will be via the ESP32’s built-in USB port, but that might complicate the power circuitry.
VCA and Audio Output
As already mentioned, the last stage will make use of the TD7052A combining a VCA and output stage amplifier in one. This is basically the circuit I ended up with from my experiments.
The TDA7052A is designed to drive an 8Ω speaker directly from its differential outputs pins 5 and 8), but I’ve also seen it used with a single output to send to a line socket, so I’ve tried to support both here.
Ideally I’d have been able to use a switched jack socket to disable the speaker when a jack is plugged in. Instead, this is another area where there is a compromise and people will have to use one or the other only.
The resistor values on the input have been chosen to attempt to match the input ranges required of the TDA7052A, so ~0-1.2V for the control voltage and ~0-300mA for the audio input. This is the point where the audio signal finally gets the DC bias removed and from a 0-3V3 audio signal becomes a +/- 150mA signal instead. But recall that the TDA7052A will then internally bias it to around 2.6V. Also recall that the VOL signal will sit at 1.25V until pulled low by the transistor and incoming control voltage. One again I’m using a BC557 (PNP) transistor here.
The output is mono and will eventually produce around a +/- 400mV output at the socket when powered from a 5V or 9V supply.
From my experiments it seems to output a 1.5-2V signal with an 8Ω loudspeaker across pins 5 and 8 when powered from 5V. It was slightly increased with a 9V, but the signal started to distort.
To be honest, I’m not convinced of the utility of the speaker output, so it may be that if a speaker is required it will be better taken from the line out and through a secondary small amplifier of some sort. Or it may be that prototyping this section on a breadboard is a little futile – I’ll have to wait until it is on a PCB and try again.
Power and Battery
This has been left about as simple as it is possible to be:
All connectors and switches have been left with pin headers. The 7-12V header could be connected up to a 9V battery if required. The power switch can be omitted by jumpering across J9. This is fed into a LM7805 to produce a steady 5V VCC supply.
Note VCC will be fed into the ESP32’s VIN pin to create the 3V3 power signal that supplies the rest of the circuit. It will also power the TDA7052A directly.
Also note that if nothing is plugged in here (i.e. neither battery or DC), then it should be possible to power the unit from the ESP32’s USB port. If this is the case, then VCC will come from VIN from the ESP32 and the jumper J2 should be removed to disconnect VCC from the LM7805. In this case the ESP32 VIN (which comes from the USB 5V) will also be powering the TDA7052A.
According to the schematics I’ve found online for my dev board (which seem to agree with what I can trace out on my board) the on-board power circuit is as follows:
I’ve found some discrepancy in the capacitors values – another schematic suggests C1 here is 100nF. More seriously, I found one schematic that shows VCCUSB connected to VIN on the NCP1117 rather than VIN. I’m pretty sure this is a mistake and it certainly doesn’t match what I have on my board.
Taking VIN on the module pinout as being the input to the NCP1117 and with a maximum dropout voltage of 1.2V (as per the NCP1117 spec) then the input range for VIN should be 4.5V up to 20V.
Powering it from the 7805 should be perfectly adequate and in fact could probably have been omitted. But in the interests of providing some stability to the PCB when in use, along with wanting a known voltage for the amplifier, I’ve opted to include the regulator. It also means I’ll be able to test parts of the board without requiring the ESP32 plugged in, and might provide an element of protection for the ESP32 should an incorrect power supply be plugged in.
But it should be quite possible to leave it out and direct VIN directly to the input power connection if required.
There is no protection for using USB and powering the system from the regulator, so this has to be decided as a build option to be one or the other, but being able to use USB during testing may be useful.
Panel Design
I’m hoping to get all this within a 100×100 footprint for ease of manufacturing. Initial efforts seem to show that it will be possible. This is the panel design I’m going for.
Design principles:
- MIDI, power, audio output, and any external links for breadboarding will be left off the main panel – the idea being that they will probably be in the side of a case. Or they could be an additional panel element if required.
- I’ve deliberately not included a filter stage – that will be an area where breadboard experimentation will be encouraged! It can be included by taking the output of one of the VCOs and reconnecting to the input of the VCA.
- I might double up on some of the connection points to allow several patch leads – e.g. to make it easy to link to a scope.
PCB Design
I have a PCB design ready, further details available below:
- ESP32 WROOM Educational Modular Synth Thing PCB Design
- ESP32 WROOM Educational Modular Synth Thing PCB Build Guide
Closing Thoughts
I’m writing this after some experimentation and initial breadboarding, so I’m hoping much of this is from a position of knowledge (although obviously not enough knowledge to have anticipating the strapping pins issue!).
The only compromise I think I’ve had to make is that I’ve left out a filter stage. At some point, if this rather mad contraption actually works, then I might consider designing a second panel with some additional modules and that might include some filter options.
Kevin
https://diyelectromusic.wordpress.com/2024/05/07/educational-diy-synth-thing-part-2/
-
Here is another #PhasePlaneAnalysis #tutorial, this time applied to the #VanDerPolOscillator, a non-conservative #oscillator with nonlinear damping:
🌍 https://www.fabriziomusacchio.com/blog/2024-03-24-van_der_pol_oscillator/
#DynamicalSystem #ComputationalScience #PhasePortraits #Python
-
The last module of my #diysynth that I had on breadboard is now soldered to a #perfboard. It's a #LFO with triangle and square wave output, with shape #potentiometer that changes the triangle wave towards sawtooth or ramp, and the duty cycle of the square wave between 5% and 95%.
It has two speed settings with 0.12 to 5.3 Hz, or 1/80th to 0.5 Hz frequency. I might build a second one with different capacitors for higher frequencies.
#soldering #synthesizer #oscillator #electronics -
Altoids Tin Spy Radio Goes Solid State - [Helge Fykse (LA6NCA)] has a type, as they say. At least as far as radios are conc... - https://hackaday.com/2023/09/21/altoids-tin-spy-radio-goes-solid-state/ #amateurradio #transceiver #radiohacks #oscillator #lowpower #si5351 #ham #qrp
-
Clock Hack Gives DEC Rainbow a New Lease on Life - In retrocomputing circles, it’s often the case that the weirder and rarer the mach... - https://hackaday.com/2023/09/12/clock-hack-gives-dec-rainbow-a-new-lease-on-life/ #retrocomputing #arduinohacks #rainbow100-b #oscillator #pacemaker #arduino #si5351 #parts #clock #dec
-
the limited & special priced introduction set:
delivery in sept.
Liquid Sky D-vices #V4CO and #GLITHc
.
V4CO = #badass #8bit #wavetable #oscillator with evil
#subbass #overdrive and #vca
(so much more than just an oscillator)
.
GLITHc = #circuitbending #midi #multiples #micro #sequencer expander for the V4CO
.
the color of the frontplates is identically. i only fkkd up in the collage.
the red knobs are recycled and only available for the limited introduction set.
.
www.liquidskyd-vices.com -
Spy Transceiver Makes Two Tubes Do the Work of Five - Here at Hackaday, we love following along with projects as they progress. That’s e... - https://hackaday.com/2023/05/19/spy-transceiver-makes-two-tubes-do-the-work-of-five/ #continuouswave #transceiver #radiohacks #oscillator #vacuumtube #sidetone #spyradio #amateur #mixer #relay #ham #cw
-
#V4CO #wavetable #oscillator
#eurorack #UfoSystem
#LiquidSkyd_vices #LiquidSkyEurope
now in production....
first batch: 100 units -
DIY Metal Detector Gives You The Mettle To Find Some Medals - Hurricane season is rapidly approaching those of us who live in the northern hemis... - https://hackaday.com/2022/05/02/diy-metal-detector-gives-you-the-mettle-to-find-some-medals/ #operationalamplifier #metaldetector #classichacks #oscillator #circuit #op-amp #simple #news #coil
-
Tuning Fork Keeps This Throwback Digital Clock Ticking - Whatever kind of clock you’re interested in building, you’re going to need to build an oscillator ... - https://hackaday.com/2021/02/13/tuning-fork-keeps-this-throwback-digital-clock-ticking/ #clockhacks #oscillator #tuningfork #inductor #440hz #clock #retro
-
The Theremin is 100 Years Old; Celebrating the Spookiest of Instruments - It wouldn’t be October without Halloween, and it wouldn’t be Halloween without some spooky music. Th... - https://hackaday.com/2020/10/30/the-theremin-is-100-years-old-celebrating-the-spookiest-of-instruments/ #electromagneticfield #leontheremin #radiohacks #heterodyne #oscillator #theremin #history #antenna #news
-
Building a Mechanical Oscillator, Tesla Style - Before Tesla devised beautifully simple rotary machinery, he explored other methods of generating ... more: https://hackaday.com/2019/12/03/building-a-mechanical-oscillator-tesla-style/ #mechanicaloscillator #alternatingcurrent #oscillator #science #tesla #ac