FAQ & Terms of UseFAQ & Terms Of Use   Wiggler RadioMW Radio   Muff Wiggler TwitterTwitter   Support the site @ PatreonPatreon 
 SearchSearch   RegisterSign up   Log inLog in 

HELP 1VOCT Analog Keyboard Controller w/ Arduino
MUFF WIGGLER Forum Index -> Music Tech DIY Goto page 1, 2  Next [all]
Author HELP 1VOCT Analog Keyboard Controller w/ Arduino
Kevin Mitchell
Hello! For a few weeks now I've been picking at a controller project of mine. I've been tinkering with modular synth stuff and could really use a CV controller. I've snagged a Fatar synth keyboard and worked out mapping the keys with an arduino nano board and was using a PWM pin as CV output to experiment. But I'm using a 5 octave keyboard (61 keys) and the <5v on the arduino will not be enough for scaling notes C1 to C6 and probably not a clean enough signal to use as CV.

I believe I need a decent DAC to get the job done. The problem here is I'm very new to synths, haven't written original code in years and would not know what DAC device would be ideal for this project. If the fine folks of this forum have any pointers to lend I would very much appreciate it! This week I would like to finish up the circuit with modulation and pitch wheels so I can box everything up!

I aim to design a polyphonic controller with 3 CV outputs. Just stumped on the digital to analog part for a good CV signal!
I would suggest the MCP4812 dac from Microchip. It uses an SPI interface and you should have no trouble finding example code and circuits using it. You will need an amplifier after it to get enough voltage to cover the keyboard range.

Datasheet.. p4822.pdf

Code... le1/MCP48x2_example1.ino
Kevin Mitchell
Thanks. I was going to snag the 12bit verson but wanted to know what other DACs would be ideal. These SPI chips seem likely to be my best bet.

I've spent some time last night learning about the operations of opamps - after 3+ years of making stompboxes I'm finally learning the engineering side Mr. Green . From what I understand designing an amplifier shouldn't be difficult.

I guess I'll need a few DAC chips if I want multiple CV outputs.
Kevin Mitchell
I've noticed those MCP DACs have dual configuration. So It would produce two CV signals?

If I aim to have at least 3 CV signals perhaps I should source a quad DAC that works through SPI so the microcontroller pins aren't all tied up - considering how the scan matrix already occupies most of them.

I'm trying to wrap my head around "bits" and how this plays into the DAC's resolution and what I need done. Also I'd have to source examples of the quad DACs I'm seeing. Cheapest being the MAX5250. DATA SHEET
Those MAX chips are expensive, especially the 12 bit ones. 12 bits is worth doing, especially for midi CC and pitchbend.

Running two MCP4822 dacs instead of one, would tie up only one more pin on the MCU. They can share the SPI signals (SCK and SDI) and have a chip select (CS) line each. So four pins total.

The first answer here has an example.. -for-different-slaves

If you are really pressed for I/O, you might be able to use a single CS pin and run it through an inverter to the second DAC, so it is high on one dac and low on the other or vice-versa. I'd test that on a breadboard though, as I haven't tried it myself. You might have some CD4069 IC's sitting around from your guitar pedal building wink
I used two mcp4922 dacs for a teensy project I recently finished that required four CV outputs.
Worked great and they are cheap, but you do need an external reference.
You might also want an opamp with a trimmer behind each CV channel to buffer and scale the signal.
Kevin Mitchell
I've purchased the MAX5250 so I can get started experimenting. Totally should have added 2 MCP4922 chips to the order. But Im curious to see if I can get good resolution with 10bits for 61 keys with room for pitch bend on both low and high notes.

Can anyone share some info on how the note/voltage data is entered to the DAC and how to adjust the output voltage with an amplifier circuit to set it for 1volt per octave CV? Just wondering what worked for others. FYI - this project will have no MIDI data and is just scanning the keys and outputting 3 1volt per octave CV signals and one gate. I will likely redesign some things as I find more use of the controller - such as note priority programming, sequence recording w/ speed & spacing, note data display and some other tricks.

I hope to transfer the code to a smaller MCU such as an ATtiny device when everything is done. I/O pins aren't a big deal since I'm still designing the thing but I do plan on turning this into a standalone board without the arduino. This project is a great learning experience for myself.
On the digital side, you need to scale the 61 keys to 10 bit values. If you work with 64 instead of 61 the numbers will line up nicely....

DAC = ( 1024 / 64 ) * key

..where key is 0-60. The top key would have a DAC value of (1024/64)*60 = 960.

From the data sheet for the MAX5250 table 2, Vout = Vref * (DAC/1024)

Assuming you use an LM-4040 2.5v voltage reference, for the top key you get Vout = 2.5 * ( 960/1024) = 2.34375v

What you really wanted was 5volts, sincce you are using 1v/oct and the top key is 5 octaves up.

If you look at figure 10 in the max5250 datasheet, you see the DAC output setup with a non-inverting opamp amplifier. You need to calculate the resistors to replace the 10k resistors in the diagram. If you go here.. 4375&vout=5&rin=&rf=10

.. there is a non-inverting op amp calculator. If you set the input voltage to 2.34375, output to 5v and one resistor to be 10k, the other resistor is calculated as 8.82k. You can use an 8.2k resistor in series with 1k trimmer. Then once you are done, you press the top key and adjust the trimmer to give 5v.
widdly wrote:
If you are really pressed for I/O, you might be able to use a single CS pin and run it through an inverter to the second DAC, so it is high on one dac and low on the other or vice-versa.

Not recommended because in that case the spi is always active on this device and you could get problems if you program the processor by spi.
Besides that: it is not common use of the spi bus.
Kevin Mitchell
Thank you very much, widdly for breaking that down for me! I've learnt about opamp configurations the other night so I'd have a better idea of how these things work. I should have learnt this stuff long ago meh

So with that setup I'll get notes C0-C5. If I really want C1-C6 (1-6 volts) perhaps I should add an additional non-inverting opamp configuration with higher voltage going to the supply pins.

Here's some math I slapped together;
VR(960/1024)(Rf/Rg + 1) = DACout
to external non-inverting opamp for CV greater than 5v (opamp gets 12v to power)
DACout(Rf/Rg + 1) = Amplified CV for C1-C6 scale
Rf = 10k and Rg = 50k for the external amp
I think amplifying the voltage with a non-inverted opamp config to get +1 volt will be an issue if the DAC is putting out 0 volts (for key 1). I will have to tinker when the part comes in tomorrow.

Do you think getting VR from a resistor divider would be an issue? Though for consistency reasons perhaps it's best to obtain all power references from regulators. I'll draw out a schematic after I play with that calculator and choose resistor values. I hope I'm not misunderstanding anything here.
Personally, I wouldn't bother doing the C1-C6 idea. Usually your VCO has a coarse knob or octave switch built in.

One way to do it would be a dc mixer and mix the DAC output with 1v. You could add in other voltages via a switch to get octave switching.

The LM4040 2.5 referece is a really cheap part. You could do it with regulators and resistor dividers too. It would be a little less accurate though.
Kevin Mitchell
Thank you very much. I'm just curious of how I'd go about getting voltages higher than 5v for a wider scale of notes - instead of relying on the synth module alone to select the tuning/scale.

This weekend I hope to have the time to tinker with the pitch shift and modulation part of the controller.

Today I'll purchase a couple MCP4822 DACs, some LM4040 2.5v shunts and anything else that comes to mind for my parts bin. I aim to etch the control board next week. Also I'll probably hit the lumber yard this weekend to start building the cabinet.
Kevin Mitchell
I'm back. A bit behind on the development of the circuit due to other projects on the bench.

So here's what's going on. With trial and error I've developed a basic controller but am still working on the circuit and mostly - the programming.

I was having an issue amplifying the output of the DAC. The MCP4288 has a reference voltage of 2048mv - so 4096 is full resolution (NOTE - NOT THE 5VOLTS NEEDED). My programming accounts for 4096 / keyPressed = DAC output. I've been playing with the math to get a decent scale to amplify with a non inverting amp setup. I've been experiencing issues with my power supply drifting around for it seems ground goes under a few milivolts from time to time and throws off my calculations. When that isn't an issue I still can't seem to get accurate 1v per octave to stay consistent throughout all 5 octaves. I'm not sure what the best way to go about stabilizing the circuit would be and also to fix the issue with the voltage scale.

The next thing I'm doing is adding input shift registers so I can save pins collecting MAKE and BREAK data for the MCU. I hope using these registers does not slow down the performance so I can accurately gather velocity timing (time between MAKE and BREAK). It might be best to not run MAKE and BRAKE through the series of registers and instead link each register directly to the MCU though I'm not sure yet - I haven't tested it. I'll also be working on two additional CV outputs for polyphonic functionality, a 4th CV output for velocity AND using the force sensing resistor that came with the keybed assembly for aftertouch - taking advantage of all the keybed has to offer.

I'm still writing up the schematic (using an Atmega328 chip) but I did put this together for reference on connecting the fatar keyboard to the arduino. Instead of using 16 or 24 pins I can get away with only using 6 pins of the MCU using shift registers. Or at least that's the idea for now.
Kevin Mitchell
I'm looking for suggestions for pre-scaling and amplifying the DAC's resolution through the arduino software and buffer circuit. I've tried the simple methods and haven't gotten the voltages exactly where they needs to be.

I've been following methods such as examples on this page and others alike. It's a simple non-inverting amplifier but it's not working out as I have calculated though it has come close to the appropriate resolution - it doesn't seem to be stable or consistent.
If are a masochist you could do it with logic gates, CMOS switches, resistor ladder with trim pots. No Arduino needed. You may want to implement a priority encoder. I almost did this with a failed Roland keyboard. They use a diode matrix with something like a decade counter to pulse the matrix at each row one at a time. The mapping of the diode network was seemingly random so it required reverse engineering a very large PCB with over 100 components. I gave up and purchased a maudio oxygen used.
Kevin Mitchell
I'm mapping the keys out perfectly fine it's just the resolution of the DAC to the non-inverting opamp that I'm having trouble with. I'd rather use the arduino because it's much easier for me to further develop and tweak the thing through software alone. Otherwise I would have just done the MFOS 1 volt per octave scanner.

I'm almost finished designing the PCB to take it off the breadboard I just have to pin down the actual 1v per octave part that I'm having trouble with. This would be rev. 1 of my controller and would be monophonic with no velocity or after touch data used. Those will be implemented in the next run. For now I need to get the basics fixed up - which is near finished.
hey Kevin,

here is what I've done:


apply gain to make the V/OCT signal too big, then through an attenuator to bring it down to perfect. I press the key that should output 5V, and with volt meter, adjust the trim pot until the output is exactly 5V. your op amp will need to be powered from more than 5V for this to work. This was for euro-rack, so I had +/- 12V supply available for the output op amps.

trim pot is definitely the "easiest" way to tune in a solid V/OCT output.
Kevin Mitchell
Thank you! Seems there's a little more going on in your design. I'll give that amplifier circuit a try in a few hours.

How did you go about the resolution of the DAC? For the 12bit with a gain of 2 I've mostly seen something like "4095 / 60 * keypressed" which may not give the resolution and accuracy I need.
I would forget about the external gain in your calculation for DAC output. treat your 12 bits as your full range, which I assume in this case is 5V.

note_number * (4095 / 60) is indeed what you'll end up with. I'm sure you've noticed that 4095 / 60 = 68.25, so there will be some error no matter what. you can try to do something about those fractions, but I did not, and found no need to. I definitely recommend building, testing, measuring, before deciding via math that its not accurate enough.

a more direct answer to your question "How did you go about the resolution of the DAC?" : I divided the full output range into 60 "equal" steps.

I don't remember off hand what the error comes out to be, but I remember that it is far below what you could expect from a guitar or bass, as far as intonation goes. smile
Kevin Mitchell
Thank you.

"4095 / 60" should give close to full output range when multiplying with key 0 to 60.

With an internal voltage reference of 2048mv (that's why 4095 is the top of the scale) the full scale would actually be just above 4 volts - which is why an amplifier is needed. So with keyPressed * (4095 / 60) I would need to multiply the output by ~1.22. That's the idea I've had but I haven't had success amplifying it for accurate scaling. I've tried increasing "60" for more resolution and increasing the multiplier but still no cigar. I've tried a few opamps and both single(+/gnd) and dual(+/-) 12v supplies.

Maybe it's a breadboard error. I'll find out tonight.
ah, gotcha!

I would not adjust the scaling in code whatsoever. write the code assuming perfect scaling after the DAC. Then, instead of trying to have an op amp provide exactly 1.22x gain, wire one up for 1.4x with an attenuator after it. My circuit has a buffer after the attenuator so that the destination (whatever you're patching this CV to) has no impact on the output level.

I'm not sure about your familiarity here, but resistor tolerance will not let you get perfect gain. Available values vs. available precision will keep you from getting the exact gain you need, which is why the trim pot is necessary. maybe you know this, my bad if so!
Don't forget, if you want to use a single inverting buffer (with scale and offset) after the DAC, you can output the note values "backwards": (60 - note_number) * 4095 / 60.
(Personally I'd just multiply by 64 rather than trying to squeeze the last bit out of the DAC.)
Nice amp example:

from here:
Kevin Mitchell
nigel wrote:
Don't forget, if you want to use a single inverting buffer (with scale and offset) after the DAC, you can output the note values "backwards": (60 - note_number) * 4095 / 60.
(Personally I'd just multiply by 64 rather than trying to squeeze the last bit out of the DAC.)

That's a good idea. I'll give that a shot later. It has been mentioned earlier in this post. Using an non-inverting amplifier, 100k from neg-input to ground and 22k tied between neg-input and output I get close to the resolution needed with 1.2* gain though it seems the octaves go off a little. I was hoping for perfect .0833 per note, 1 volt per octave but I understand it wont be - and doesn't have to be perfect. Especially considering the synth it would control can compensate for any small errors.

I've been shocked on how few 1v per octave keybed scanner circuits there are out there - almost all are midi to cv projects. It's been a great deal designing my own practically from scratch. Having a little programming background helps a bit hihi
Kevin Mitchell
Back with a couple more questions that I hope gets attention. CV is tracking very well! Now I need to fix the velocity data.

I was hoping calculating the difference in time between MAKE and BREAK using millis() or micros() would relay enough time data to create velocity information. Sadly the number I'm getting is about 2 or 4 milliseconds which isn't enough range of data. Is there a better way to go about this?

Also; has anyone worked with the force sensing resistor for after touch data? I have to press very hard on a key to get anything through the FSR... Hoping it's not a bad strip.
MUFF WIGGLER Forum Index -> Music Tech DIY Goto page 1, 2  Next [all]
Page 1 of 2
Powered by phpBB © phpBB Group