Raspberry Pi Pico DCO

It’s a bit confusing to look at the boards laid out like that, but I’m planning on having 6 voices - I wanted to have a sense of how to actually build the parts I need, which is why I’ve just done a single stripboard design for each piece of the puzzle. The stripboards for the oscillator and envelopes are duplicated across the top and bottom, so I only need x3 boards of each for the 6 voices.

I was originally planning on having each voice go: oscillator → vca (controlled by EG) → mixer, and then all 6 voices into a single filter at the end.

I’m going to have a look at the AS3350 design @jkb has used in their voice card, though, and think about using a filter for each voice.

1 Like

Ok, it’s unusual to do it that way, but hey ho, it’s your design at the end of the day. I would have a final VCA to close the filter with its own EG too then in that scenario. Not many synths have VCAs after the VCO with an eg to control them, normally you put a VCA after the VCO as a level control for mixing, like in my design I use quad VCAs like the AS3364 to mix each waveform down from the VCO. So one control voltage sets the level of the saw tooth for all 6 VCOs. Same for pulse. I guess a EG can do the same thing by just adjusting the sustain level from 0-100 all ADR at 0 time. But you would only need 2 EGs to control the 12 VCAs. 6 for each wave from the DCO.

Easier build would be 6 VCOs to 6 filters to 6 VCAs and a final mixer to mix it all down. Obviously 6 EGs to drive the filters and VCAs or even 12 (6 for each) if you want to go mad. As the Pico can easily produce a 6 note unison it can be used mono or poly. You really need an LFO for modulation of the filter, the current Pico DCO cannot do modulation, but I have a new version of the code that supports FM modulation of the DCO and octave switching.

Updated the Pico DCO board with a second 8 channel DAC as I remembered I needed velocity CV’s as well as volt/octave CV’s. Just tested it and all working. So effectively this now has the extra functions of a MIDI to CV converter from 1-6 notes

4 Likes

I had a little time on my hands tonight and ported the code to a Seeed RP2040 in single DCO mode, there’s enough pins to make a dual DCO in a single Seeed with detune/FM/gate out/MIDI input/octave switch and possibly other options like a CV output from an I2c DAC.

4 Likes

So I built my stripboard layout of the dual voice card, and the top half was working without issue. I’ve added the bottom half, and I was getting saw but no square - I swapped over to my scope rather than the audio probe I was using, and now get absolutely nothing on either the top or bottom oscillator. Did some basic troubleshooting and the right voltage was on the TL074 at least, will look again properly tomorrow.

What should I look for on the pi output pins to verify that the correct signal is coming out? Either on a multimeter or a scope.

I just want to make sure I can rule that out as an issue, as I’m not sure how building the bottom oscillator could cause the top one to stop working… I’m worried I shorted reset_0 to ground as I was using crocodile clips. Could that damage the pi?

1 Like

I am having such a frustrating time with this. Twice it’s just magically come to life… when I first tested the stripboard layout, and earlier this afternoon after I reflashed the pico.

Do these scope images seem right? The reset signal seems too small (0.5v) and the PWM signal seems too infrequent?


I’ve tried flashing the pico again but with the same result. I’ve ordered a new one, but I could really do with knowing whether it’s the pico or the following circuit that’s the issue. I’ve got two circuits built, and for the few minutes it worked it worked through either, which I think points to the pico being the problem (along with what I think are suspicious scope images, though I’m not sure…)

The LM7805 is also getting pretty warm with the pico running…

1 Like

Which dual voice card have you built, can you elaborate.

From memory the Pi outputs a square wave on the reset pin and a pulse on the range pin, but I would have expected it to be 3.3v in amplitude. So your waveforms look incorrect in amplitude

The 7805 should not get too hot, its only powering the Pico and the Pico is only powering the opto isolator from its regulator.

Also if it helps, you should have a sawtooth on pin 1 and a sawtooth on pin 8 and then the squarewave on pin 14 of the TL074 if that helps with diagnosis, as the pin 1 is the first place it should appear I would look there.

2 Likes

Thanks craigyb - When I shorted one of the GPIO pins to ground, I fried the pico. It had thrown me because I was seeing a clock signal leaving the pico, but nothing was happening after that point, so I’d assumed something was wrong with my layout. But the clock signal coming out of multiple incorrect gpio pins and being low voltage eventually pointed me in the right direction.

Swapped in a new pico this morning and everything is working as expected.

I’ll add the stripboard layout to the verified thread later today, then start working on all the other pieces.

3 Likes

Easily done, I blew the UART gpio pin when breadboarding the second DCO board, fortunately I ordered 3 Picos when I started this project. I shoved 5v into the 3.3v gpio pin and then no MIDI. Fortunately if I don’t need so many gpio pins I can reconfigure design to use another RX pin.

3 Likes

Oooh man, you are making my day here. This is brilliant sir.

1 Like

I wanted to fix an issue on this about the MIDI channel being only on channel 1. As there are no spare pins (well 1) on the Pico I thought about how to manage the gates to use less pins.

So using a 74hc595 with 3 wires you can achieve upto 8 gate outputs, there is a library already available for the Pico to control a 595.

This then frees up 3 pins of the Pico, 4 now being available it would be possible to use a hex rotary to select the MIDI channel and read the 4 pins to decode the switch.

What do you think?

I guess it should work. Clock speed of the 595 can be multiple Mhz so timing won’t be an issue here.

Other options I could think of is cycling through the channels with just the one pin you have left. Or using MIDI system messages to change channel.

I guess a controller message could do it, but as soon as it receives that message it will jump channel and no longer respond until you switch the sender to that channel. But it’s an option. I was just thinking about the DCO boards as they are limited stuck on channel 1.

Also that needs to be stored in eeprom as well.

For my implementation I think with my programmer I can send a control change after I select midi channel and therefore for me it would not be an issue unless I somehow sent a random control change from external sources that it read.

I’m no expert on this, but changing MIDI_CHANNEL either by USB or MID seems to cause problems of lockout etc. If I change it over MIDI and then try to use the MIDI port it doesnt respond, but the USB port does reposnd on the new channel.

This is how I’m setting the MIDI_CHANNEL variable.

Changed from a define to an integer

uint8_t MIDI_CHANNEL = 1;

Then in USB and MIDI I have the following

        if (buff[2] == 3)
            { // midi channel change
            for (int i = 0; i < NUM_VOICES; i++)
            {
                VOICES[i] = 0;
                VOICE_GATE[i] = 0;
            }
            if (buff[3] >> 0 && buff[3] << 17)
            {
                MIDI_CHANNEL = buff[3];
            }
        }

AND

if (lsb == 3)
{ // midi channel change
for (int i = 0; i < NUM_VOICES; i++)
{
VOICES[i] = 0;
VOICE_GATE[i] = 0;
}
if (msb >> 0 && msb << 17)
{
MIDI_CHANNEL = msb;
}
}

Do you intend to do bit shift operations or greater than/less than comparisons?
In C ‘>>’ and ‘<<’ are left and right shift bitwise operations. Maybe you want just the single ‘>’ and ‘<’ ?

2 Likes

Thanks, it didn’t work with either but I will change them back to single

Actually, is there a specific channel change MIDI message, or are you trying to use something else to do it?

You should take care as well, I took a peek at the code and it looks like it counts from 0, and most operations involving MIDI_CHANNEL subtract one from it before doing any comparisons. So MIDI_CHANNEL = 1 is always checking if the channel bits are 0.

if (midi_serial_status == (0x90 | (MIDI_CHANNEL-1))) {

3 Likes

So basically he sets MIDI_CHANNEL to 1 and then removes 1 from it to get 80 or 90 for note on/off etc.

I need to look into it more closely

Check out https://www.midi.org/specifications-old/item/table-1-summary-of-midi-message

The 0x90 | (MIDI_CHANNEL-1) is doing a bitwise OR between the 4 bit Note On (1001 in binary, 9 in hex) and the current channel - if MIDI_CHANNEL is 1, it will create 0x90 - which is a note on status message on channel 1. If you set your MIDI_CHANNEL to 2, it will create 0x91 - note on on channel 2 message.

Cheers

1 Like

I think I can just increment the -1 to get the midi channel to increase/decrease etc or am I not thinking it through properly.