Hagiwo $9 Raspberry pi VCO with Seeed XIAO RP2040 Eurorack Modular Synthesizer

Bipolar modulation requires that there is a positive voltage on at least one of the inputs, either the Pitch pot, the V/OCT input or both. For the Modulation input the pot needs to be set to a positive value to allow a bipolar modulation CV. The clamp diodes will remove any modulation that causes the combined voltage to go below zero or >3.3V after scaling. So it will fail for extremely low or extremely high pitches or very wide modulation swings. For me these are edge cases and not a problem, and the convenience of not needing to level-shift the modulating CV is a big advantage, as is the simplicity of using only 2 analogue inputs. YMMV of course…

Yeah it’s basically what I thought, you cannot get around the 0-5v limit simply by mixing voltages.

But you gave me a idea, as I’ve lost the mod CV input to FM/pitchbend I can mix the mod CV with the CV pot as you did, I haven’t implemented the mod CV at all yet so not a big issue, but I do have a working FM/pb input now to play with. This is the same way as FM input was implemented on the PolyDCO.

The pitch pot has a range of 0-127 so it’s frequency range is limited for easy tuning. I need to get at least an octave +/- out of the FM input, so I will be playing about to get the range I need. For some reason my pc has stopped recognising the Seeeds so I can’t upload any mods currently until I perform a reboot.

No, there’s no way round the 0 - 5V range limit; basically you can’t push the oscillator below its minimum frequency or above its maximum. I suspect these restrictions will creep in however the input voltages are processed.

You might get round the upload problem by holding the Boot button down on the RP2040 while resetting it - that fixes intermittent failed uploads for me.

I managed to get my Seeed to see the USB ports again and loaded my new code. I’m happy that I now have an alternative input for FM and PB even though I do have to bias them at 2.5v, means even at a 0V or 5V CV I can modulate or pitchbend the VCO. Now to redesign my synth.

I would be interested in seeing code that gave PWM for the squarewave and how you controlled the LED

But just had a rolling blackout thanks to Putin

I don’t want to publish the whole of my modified code without permission from Hagiwo, so here are the bits to implement PWM and the RGB LED. Hope they make sense!
PWM:
In the ‘mod parameter set’ block of loop(), replace

  if (mode == 0) {//fold
    mod = constrain(analogRead(29) + analogRead(28), 0, 1023) * 0.0036 + 0.90; //28 is CV , 29 is pot
  }

with

  if (mode == 0) {//fold
    if (2 != waveform) { // normal wavefold
      mod = constrain(analogRead(29) + analogRead(28), 0, 1023) * 0.0036 + 0.90; //28 is CV , 29 is pot
    } else {  // PWM for square wave
      mod = constrain(analogRead(29) + analogRead(28), 0, 1023) / 8;
    }
  }

In loop1(), replace

    if (mode == 0 ) {//wavefold
      for (int i = 0; i < 256; i++) {
        mod_wavetable[i] = wavetable[i] * mod;
      }
      for (int i = 0; i < 256; i++) {  //fold

with

    if (mode == 0) { // wavefold
      if (2 == waveform) {
        // PWM rather than wavefolding for square wave
        for (int i = 0; i < 128 + mod; i++) {
          mod2_wavetable[i] = 511;
        }
        for (int i = 128 + mod; i < 256; i++) {
          mod2_wavetable[i] = -511;
        }
      } else {
        for (int i = 0; i < 256; i++) {
          mod_wavetable[i] = wavetable[i] * mod;
        }
        for (int i = 0; i < 256; i++) {

and add another closing brace at the end of the for loop! This allows quite extreme PWM, which I like. You may perhaps want to limit the maximum value of mod to something rather less than 127 for a more moderate effect.

For the RGB LED, add

#include <Adafruit_NeoPixel.h>

at the head of the source code and just before the setup() function add the lines

Adafruit_NeoPixel pixel(1, 16, NEO_GRB + NEO_KHZ800);
int colour[][3] = { {100,   0,   0}, // red
                    { 88,  12,   0}, // orange
                    { 65,  35,   0}, // yellow
                    {  0, 100,   0}, // green
                    {  0,  70,  20}, // cyan
                    {  0,   0, 100}, // blue
                    { 40,   0,  40}, // magenta
                    { 45,  40,  35}  // white
                  };

Add the lines

  pixel.begin();
  pixel.setPixelColor(0, pixel.Color(colour[0][0], colour[0][1], colour[0][2]));
  pixel.show();

at the end of setup. Finally add these lines in loop() just before the end of the ‘push sw’ if() block

    // set the neopixel colour
    pixel.clear();
    pixel.setPixelColor(0, pixel.Color(colour[waveform][0], colour[waveform][1], colour[waveform][2]));
    pixel.show();

I hope this makes sense - it’s far harder abstracting bits of code than just publishing the lot!

From a discussion in another topic:

2 Likes

How does the Neopixel led connect? Are you using the same onboard led and if so how did you get it to the front panel?

Sorry just saw your description of the light pipe in a previous post, makes sense now, not sure I can easily implement that into my build

Yes, I used the on-board neopixel but you should be able to add a separate one. It just needs +3V3, Gnd and a connection to a GPIO pin. The on-board one uses GPIO16 which is not broken out on my board, but you could connect the data_in pad of an external one to any spare GPIO. Just specify the relevant pin in the constructor - e.g. to use GPIO10:

Adafruit_NeoPixel pixel(1, 10, NEO_GRB + NEO_KHZ800);
2 Likes

Cool, I think we have one spare GPIO, so maybe I will give it a go at the weekend when I can get some LEDs

Power was out all morning so took the opportunity to go into town and buy some Neopixel LEDs, works wonderfully well, many thanks.

4 Likes

Excellent - glad you got it working!

1 Like

In case it’s of use to anyone, I’ve now uploaded my modified code and details of the revised hardware to GitHub. The repository includes the stripboard layout that I used for my build, the modified schematic and a zipped Kicad project which includes a proposed (but untested - use at your own risk!) PCB layout.

1 Like

Thanks to you I have the nice LED displays of the waveform number, plus after upgrading the Seeed XIAO Rp2040 to Zeros with the extra pins I’ve now got the wave selection under microprocessor control. I can read the front panel pot value and output 0-7 from 3 shiftregister outputs and of course store that data for recall. All looking good so far



4 Likes

What type of LED are you using in the 3rd picture (green and blue)? It looks as if they are mounted on something.

They are just standard WS2812 NeoPixel or whatever sitting proud of the board by about 10mm on wire legs. I use a couple of tops cutoff from clear LEDs as filters when they are fitted behind the panel.

@craigyb
Can you detail to me how you create your front panel above please. It looks very clean. Is it silkscreened?

They are just glossy paper printed using an A3 photo printer and then laminated, you can see my printer doesnt quite fit the width of a 19" rack so I have two white lines either side. I laminated with matt laminate and glue it to the panel with a pritt stick.

3 Likes

Looks very nice!! I do something similar with my modular modules. Print a 4x6 photo jpg and cut and glue to fit. I did not think to laminate though. That is a great idea. Thanks!