MUFF WIGGLER Forum Index
 FAQ & Terms of UseFAQ & Terms Of Use   Wiggler RadioMW Radio   Muff Wiggler TwitterTwitter   Support the site @ PatreonPatreon 
 SearchSearch   RegisterSign up   Log inLog in 
WIGGLING 'LITE' IN GUEST MODE

Arduino nano Voltage Adder- Good Enough Resolution??
MUFF WIGGLER Forum Index -> Music Tech DIY  
Author Arduino nano Voltage Adder- Good Enough Resolution??
djthopa
Hi!
Im working on a pseudo Arduino octave / tone shifter.

I have clamped the input to the analog pin with two diodes, and a 100k resistor, one from ground and another to 5v as i have seen on other posts.

This one:

https://www.muffwiggler.com/forum/viewtopic.php?t=17766&start=all&post days=0&postorder=asc

The arduino outputs the voltage reading, and a voltage is added depending on a octave potentiometer, so i can add up to 4 volts to the signal (4 octaves) and another potentiometer that adds semitones to the signal (12 semitones)

Is kind of something similiar to doepfer precission adder.

The input works as expected, voltage higher than 5v gets clamped and under 0 volts too.

Im running the output into an inverting amplifier using a tl072, and a 5k trimmer resistor on the feedback loop of the opamp.

Since i want to maintain the original cv signal, im not amplifying it, but i had to use the trimmer to get the same readings from the input and output.

I have two main problems.

I can add octaves and semitones but cannot figure out how to substract them.

I know arduino nano analog reads at 10 bit and the dac, an mcp4725 resolution is 12 bits, so im multiplying the readings of the pots that go into arduino by 4 to scale from 10 bit to 12 bit.

I have tried creating negative values inside arduino. Eg, i have mapped the octave potentiometer map(0, 1023, -2, 2) so i can go from -2, -1, 0, +1, and +2 octaves, and then i have created 5 cases for each reading so if its -2 (meaning substract 2 octaves to the incoming signal) i would subtract -2048 to the incoming signal.

Problem is arduino will not output negative values on the dac, only positive.

The dac dac.setvoltage seems to only take int variables.

I have chequed values on the serial and they all make sense and are correct, but when i output them trough the dac, they are ignored.

Any ideas on how to tackle this problem? I would like to subtract octaves as add them too, but it aint working in my side.

Also, i have tried converting reading to voltages and after to values to be output to the dac, but that did not work either.

Cheers!

Edited: im wondering if trying with different dacs would help. I have a few mcp4922, mcp4822, mcp4802, but being dual i think i would be wasting a channel?
av500
assuming your DAC is connected to 5V (or 3.3V) and GND, it cannot output negative voltages. if you e.g. want to be able to add or subtract 2.5V, then you need to always subtract 2.5V from the 0V to 5V DAC range:

V_out = V_DAC - 2.5V.

so with V_DAC at 2.5V you add nothing, with V_DAC at 5V you add 2.5 and with V_DAC at 0V you add -2.5V

if the range needs to be larger, you need to also scale the V_DAC with an opamp.
Synthiq
If you need +/-5V out from a 5V DAC, you need a gain of 2 in the opamp as av500 pointed out. With an inverting amplifier you can achieve this output range if the positive opamp input is biased at 1/3 of the DAC reference voltage. Since the amplifier is inverting, code 0x000 will result in +5V, 0x800 is 0V and 0xFFF is -5V. Before sending the result to the DAC, negative values must be set to 0 and values above 4095 set to 4095 to prevent the DAC from generating a completely wrong output voltage.
djthopa
av500 wrote:
assuming your DAC is connected to 5V (or 3.3V) and GND, it cannot output negative voltages. if you e.g. want to be able to add or subtract 2.5V, then you need to always subtract 2.5V from the 0V to 5V DAC range:

V_out = V_DAC - 2.5V.

so with V_DAC at 2.5V you add nothing, with V_DAC at 5V you add 2.5 and with V_DAC at 0V you add -2.5V

if the range needs to be larger, you need to also scale the V_DAC with an opamp.


Yes my MCP4725 is connected to the Arduino nano 5volt rail. I have checked the specs and max supply voltage is 6.5v. Was thinking of powering from the +12v im already powering the other TL072.

Ok i think im starting to understand. The problem i see (sorry for my lack of knowledge) is that if i have a cv input say of 1volt, then it would automatically get scaled down to -1.5v volts, which is somehow not the equal cv in.

What i want to achieve (and i dont know if its possible with my setup) is to have voltage go trough unaffected, and depending on the Octave pot, add or subtract octaves to that cv in.

As i mentioned before i can add but not subtract.

So if i add a inverting amplifier after the dac, setup with a gain of -2.5v i could achieve this?

Thanks for the clarification on the DAC values Synthiq. I thought i was doing something wrong.

So basically all the negative offset and scaling has to be done outside of arduino with an opamp.

I get lost with the code you mentioned : code 0x000 will result in +5V, 0x800 is 0V and 0xFFF is -5V, im used to decimal values and not hexadecimal values, need to get into it properly.

Thanks for the clarification on scaling the values before being sent to the dac, though i was going mental there!

Many many thanks for your supervaluable info!

Here is the code on the arduino:

#include <Wire.h>
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;

const int voltRead = A0;
const int octRead = A1;
const int toneRead = A2;

int octReadValFinal;
int toneReadValFinal;


void setup() {

Serial.begin(9600);

pinMode(voltRead, INPUT);
pinMode(octRead, INPUT);
pinMode(toneRead, INPUT);



dac.begin(0x60);

}

void loop() {

/////////////////////////////////////////////////////
int voltReadVal = analogRead(voltRead);

///////////////////////////////////////////

int octReadVal = analogRead(octRead);

//Map Reading to 5 values, -2- -1, 0, 1, 2 (octaves)

//int octReadValMap = map (octReadVal, 0, 1023, -2, 2); // Doesnt work

int octReadValMap = map (octReadVal, 0, 1023, 0, 4);

/////////////////////////////////////////////

int toneReadVal = analogRead(toneRead);

int toneReadValMap = map (toneReadVal, 0, 1023, 0, 12);

///////////////////////////////////////////////////////

switch (octReadValMap) {
case 0:
//octReadValFinal = 0;
octReadValFinal = 0;
break;
case 1:
//octReadValFinal = 1;
octReadValFinal = 1023;
break;
case 2:
//octReadValFinal = 2;
octReadValFinal = 2046;
break;
case 3:
//octReadValFinal = 0;
octReadValFinal = 3069;
break;
case 4:
//octReadValFinal = 1;
octReadValFinal = 4092;
break;

}

////////////////////////////////////

switch (toneReadValMap) {

case 0:

toneReadValFinal = 0;
break;

case 1:

toneReadValFinal = 85.25;
break;

case 2:

toneReadValFinal = 170.5;
break;

case 3:

toneReadValFinal = 255.75;
break;

case 4:

toneReadValFinal = 341;
break;


case 5:

toneReadValFinal = 426.25;
break;

case 6:

toneReadValFinal = 511.25;
break;

case 7:

toneReadValFinal = 596.75;
break;

case 8:

toneReadValFinal = 682;
break;

case 9:

toneReadValFinal = 767.25;
break;

case 10:

toneReadValFinal = 852.5;
break;

case 11:

toneReadValFinal = 937.75;
break;

case 12:

toneReadValFinal = 1023;
break;



}


int sumvoltReadTone = voltReadVal + (octReadValFinal / 5) + (toneReadValFinal / 5);



//Need to create an offset for octReadVal ??

dac.setVoltage(sumvoltReadTone * 4, false); // convert from 10 bit reading to 12 bit writting *4


}
Synthiq
With the 4096 steps of the 12-bit DAC mapped to a 10V output range, an octave shift corresponds to a 409.6 count shift per octave and a semitone shift to a 34.133 count shift. If this is taken into account directly in the switch statements for octReadValFinal and toneReadValFinal no more scaling or offset is required.
octReadValFinal: -819, -410, 0, 410, 819
toneReadValFinal: 0, 34, 68, 102, 137, 171, 205, 239, 273, 307, 341, 375, 410
The voltReadVal has to multiplied by 2 to map correctly to the output voltage.
int sumvoltReadTone = 2048 - (2*voltReadVal + octReadValFinal + toneReadValFinal) // 2048 is the code for 0V out, the subtraction due to the inverting amplifier
sumvoltReadTone = constrain(sumvoltReadTone, 0, 4095)
djthopa
Synthiq wrote:
With the 4096 steps of the 12-bit DAC mapped to a 10V output range, an octave shift corresponds to a 409.6 count shift per octave and a semitone shift to a 34.133 count shift. If this is taken into account directly in the switch statements for octReadValFinal and toneReadValFinal no more scaling or offset is required.
octReadValFinal: -819, -410, 0, 410, 819
toneReadValFinal: 0, 34, 68, 102, 137, 171, 205, 239, 273, 307, 341, 375, 410
The voltReadVal has to multiplied by 2 to map correctly to the output voltage.
int sumvoltReadTone = 2048 - (2*voltReadVal + octReadValFinal + toneReadValFinal) // 2048 is the code for 0V out, the subtraction due to the inverting amplifier
sumvoltReadTone = constrain(sumvoltReadTone, 0, 4095)


Wow!

I was doing 12 bit dac mapped to 5v output range, assuming that would be the range since i was limiting the arduino inputs to 5v.

Back to the computer to get this one rolling, thanks for looking into the code and sending me the correct scaling and values!

Synthiq! we're not worthy we're not worthy
Synthiq
djthopa wrote:
I was doing 12 bit dac mapped to 5v output range, assuming that would be the range since i was limiting the arduino inputs to 5v.

My assumptions was that the 5V DAC voltage is mapped to +/-5V at the output as the thread title suggests. In practice the output voltage can only be -2V to +5V with 0-5V CV range and +/-2 octaves shift. It would be possible to change the dc shift in the output buffer so it can output -2V to +8V instead so there would be no clipping with 5V CV input and max octave and semitone shift but it would also require some small changes to the software.
djthopa
So, i got the code change, and realised i was using a non inverting amplifier after the dac.

I have changed it to an inverting amplifier;

When 0 volts come from the dac the opamp outputs -5v.

When i output 5 volts from the dac the opamp outputs 0V.

So that would make a voltage range of 10 volts.

If i wanted to make the voltage range down to 5 volts,

Would i change:

int sumvoltReadTone = 2048 - (2 * voltReadVal + octReadValFinal + toneReadValFinal);

to

int sumvoltReadTone = 2048 - (4 * voltReadVal + octReadValFinal + toneReadValFinal);

And multiply the toneReadValFinal and octReadValFinal case values *2 also?

How would the scalling of the values inside arduino work out?

Many thanks!
Synthiq
djthopa wrote:
So, i got the code change, and realised i was using a non inverting amplifier after the dac.

I have changed it to an inverting amplifier;

When 0 volts come from the dac the opamp outputs -5v.

When i output 5 volts from the dac the opamp outputs 0V.

So that would make a voltage range of 10 volts.

It still looks like an non-inverting amplifier with a gain of 1 but with a -5V offset so the voltage range is still 5V.
Synthiq
djthopa wrote:
If i wanted to make the voltage range down to 5 volts,

Would i change:

int sumvoltReadTone = 2048 - (2 * voltReadVal + octReadValFinal + toneReadValFinal);

to

int sumvoltReadTone = 2048 - (4 * voltReadVal + octReadValFinal + toneReadValFinal);

And multiply the toneReadValFinal and octReadValFinal case values *2 also?

How would the scalling of the values inside arduino work out?

That sounds reasonable. With an inverting amplifier, the gain should be 1 and the noninverting input should be biased at Vdd/2 so 0V from the DAC results in 5V at the amplifier output and 5V generates 0V at the output. Limiting the output range to 0-5V will limit how much shift to the CV voltage you can apply to the input when it is close to 0V or 5V so I'm not sure it is a good idea.
djthopa
Synthiq wrote:
djthopa wrote:
So, i got the code change, and realised i was using a non inverting amplifier after the dac.

I have changed it to an inverting amplifier;

When 0 volts come from the dac the opamp outputs -5v.

When i output 5 volts from the dac the opamp outputs 0V.

So that would make a voltage range of 10 volts.

It still looks like an non-inverting amplifier with a gain of 1 but with a -5V offset so the voltage range is still 5V.


Im feeding the dac out trough a 10k resistor and into to the negative input of the opamp, and feeding a 20k trimmer resistor from the -input of the opamp into the opamps out. Also grounding the positive input of the opamp trough a 4.7k resistor. Thats an inverting amplifier with a gain of -2 right? hmmm..... cry

With these values and the ones you provided for the arduino code, im getting perfect 12 semitones and -2 octaves, 0 and +2octaves, so no octave change if the oct potentiometer is in the middle position.

But yes, when i feed 0 volts into the op amp, it outputs -5v Dead Banana

Is this an offset or a negative gain?

The matter that mostly concerns me is that if i have 0 volts on the dac input, the final out is 5 octaves lower, so im trying to have this possibility of adding / substracting octaves without having to zero down to -5v.

Many thanks for your help
Synthiq
djthopa wrote:
Im feeding the dac out trough a 10k resistor and into to the negative input of the opamp, and feeding a 20k trimmer resistor from the -input of the opamp into the opamps out. Also grounding the positive input of the opamp trough a 4.7k resistor. Thats an inverting amplifier with a gain of -2 right? hmmm.....

Yes, but the gain is also given by (Vout2 - Vout1)/(Vin2 - Vin1) so we have (0V - -5V)/(5V - 0V) = +1.

Quote:
But yes, when i feed 0 volts into the op amp, it outputs -5v

With the non-inverting input at ground and 0V to the input resistor, no current should flow in the input, or feedback, resistor so the output should also be at ground. If the output is at -5V, there must be another signal to the inverting input that supplies a 250uA current.
djthopa
Synthiq wrote:
djthopa wrote:
Im feeding the dac out trough a 10k resistor and into to the negative input of the opamp, and feeding a 20k trimmer resistor from the -input of the opamp into the opamps out. Also grounding the positive input of the opamp trough a 4.7k resistor. Thats an inverting amplifier with a gain of -2 right? hmmm.....

Yes, but the gain is also given by (Vout2 - Vout1)/(Vin2 - Vin1) so we have (0V - -5V)/(5V - 0V) = +1.

Ah ok, got it.

Quote:
But yes, when i feed 0 volts into the op amp, it outputs -5v

With the non-inverting input at ground and 0V to the input resistor, no current should flow in the input, or feedback, resistor so the output should also be at ground. If the output is at -5V, there must be another signal to the inverting input that supplies a 250uA current.


This is happening with inverting op amp configuration, with the non inverting configuration i was getting 0v in 0 out.

Thanks Synthiq. Considering now the pros /cons of using the inverting or the non inverting configuration. hmmm.....
av500
djthopa wrote:
av500 wrote:
assuming your DAC is connected to 5V (or 3.3V) and GND, it cannot output negative voltages. if you e.g. want to be able to add or subtract 2.5V, then you need to always subtract 2.5V from the 0V to 5V DAC range:

V_out = V_DAC - 2.5V.

so with V_DAC at 2.5V you add nothing, with V_DAC at 5V you add 2.5 and with V_DAC at 0V you add -2.5V

if the range needs to be larger, you need to also scale the V_DAC with an opamp.


Yes my MCP4725 is connected to the Arduino nano 5volt rail. I have checked the specs and max supply voltage is 6.5v. Was thinking of powering from the +12v im already powering the other TL072.

Ok i think im starting to understand. The problem i see (sorry for my lack of knowledge) is that if i have a cv input say of 1volt, then it would automatically get scaled down to -1.5v volts, which is somehow not the equal cv in.

What i want to achieve (and i dont know if its possible with my setup) is to have voltage go trough unaffected, and depending on the Octave pot, add or subtract octaves to that cv in.

As i mentioned before i can add but not subtract.

So if i add a inverting amplifier after the dac, setup with a gain of -2.5v i could achieve this?



yes, 1V would get scaled down to -1.5,V but your "zero/middle" value from the DAC is 2.5V, so it's back to 1V:

V_out = V_in + V_DAC + V_ofs = 1V + 2.5V - 2.5V = 1V

you cannot power the DAC from 6.5V or 12V, 5V is correct and you scale the DAC output with an opamp...
djthopa
av500 wrote:
djthopa wrote:
av500 wrote:
assuming your DAC is connected to 5V (or 3.3V) and GND, it cannot output negative voltages. if you e.g. want to be able to add or subtract 2.5V, then you need to always subtract 2.5V from the 0V to 5V DAC range:

V_out = V_DAC - 2.5V.

so with V_DAC at 2.5V you add nothing, with V_DAC at 5V you add 2.5 and with V_DAC at 0V you add -2.5V

if the range needs to be larger, you need to also scale the V_DAC with an opamp.


Yes my MCP4725 is connected to the Arduino nano 5volt rail. I have checked the specs and max supply voltage is 6.5v. Was thinking of powering from the +12v im already powering the other TL072.

Ok i think im starting to understand. The problem i see (sorry for my lack of knowledge) is that if i have a cv input say of 1volt, then it would automatically get scaled down to -1.5v volts, which is somehow not the equal cv in.

What i want to achieve (and i dont know if its possible with my setup) is to have voltage go trough unaffected, and depending on the Octave pot, add or subtract octaves to that cv in.

As i mentioned before i can add but not subtract.

So if i add a inverting amplifier after the dac, setup with a gain of -2.5v i could achieve this?



yes, 1V would get scaled down to -1.5,V but your "zero/middle" value from the DAC is 2.5V, so it's back to 1V:

V_out = V_in + V_DAC + V_ofs = 1V + 2.5V - 2.5V = 1V

you cannot power the DAC from 6.5V or 12V, 5V is correct and you scale the DAC output with an opamp...


Ok! had not thought about that, yes of course very frustrating the DAC is @ 2.5v in the middle (2048)!!!

Thanks av500!!
Sandrine
The offset can be from a 2.048V reference or a 4.096V reference that is built into some DACs so the "center" voltage at 2048 is still 0 volts but the op amp gain must be compensated to produce gain to 5V again.
I use those voltages (i.e. the LM4040 shunt regulator which is really just a precision zener diode)rather than the 5V for offset as the 5V regs can vary quite a bit with temperature and lot.

In any case it's surprisingly accurate (I hate using trimmers) when combined with 0.1% resistors
djthopa
Sandrine wrote:
The offset can be from a 2.048V reference or a 4.096V reference that is built into some DACs so the "center" voltage at 2048 is still 0 volts but the op amp gain must be compensated to produce gain to 5V again.
I use those voltages (i.e. the LM4040 shunt regulator which is really just a precision zener diode)rather than the 5V for offset as the 5V regs can vary quite a bit with temperature and lot.

In any case it's surprisingly accurate (I hate using trimmers) when combined with 0.1% resistors


Hi! Thanks for the info.

Yes, unfortunately i have found a small drift on the tuning of the dac since yesterday. Its colder now that when i was testing it yesterday.

Also powering the arduino from usb or my eurorack case made some small differences too.

Im going to try with a mcp4822 that has an internal reference.

Will see how it goes!

Thanks for the help!
djthopa
Hi,

I have finished the breadboard of this module.

I have added two spdt switches, each substracting or adding +1v or -1v to the input signal.

Also it has a potentiometer that adds 0 to 12 semitones.

I ended up using a MCP4822 12 bit dac, that has its signal inverted and gained with an op amp to be able to have a bipolar signal from the DAC out, ranging from -2 volts to 2 volts.

I summed the voltages (from the DAC out 1 (Octave), the Dac Out 2 (tone) and an external voltage in, into a dc mixer with two inverting stages as in the the CGS dc mixer.

Here is the simulation:

http://tinyurl.com/yc4uncfy

What i dont know if the precision im getting is good enough for continuing with this approach or not.

This is the readings from my Oscilloscope, im comparing the voltage going into the circuit to the final voltage coming out of the circuit.

- 2 Octaves = -1-96v
-1 Octave = -980mv
0 volts = -20mv
1 Oct = 960mv
+2 Octaves = 1.92volts

I dont know if i should try to compensate via the 5k trimmer resistor (which i have) or via the code.

here is the sketch, apologies for the //Comments, im pretty new to coding so i find it easier to know what does what. Also the if conditions are a mess i know......


// MCPDAC relies on SPI.
#include <SPI.h>
#include <MCPDAC.h>

const int voltRead = A0;
const int octRead = A1;
const int toneRead = A2;

int octReadValFinal;
int toneReadValFinal;


// MCPDAC relies on SPI.
#include <SPI.h>
#include <MCPDAC.h>

const int voltRead = A0;
const int octRead = A1;
const int toneRead = A2;

int octReadValFinal;
int toneReadValFinal;

//Declaration of Switches for Octave up / Down, the idea is have a final sum


void setup() {

// CS on pin 10, no LDAC pin (tie it to ground).
MCPDAC.begin(10);

// Set the gain to "HIGH" mode - 0 to 4096mV.
MCPDAC.setGain(CHANNEL_A, GAIN_HIGH);
MCPDAC.setGain(CHANNEL_B, GAIN_HIGH);

// Do not shut down channel A, but shut down channel B.
MCPDAC.shutdown(CHANNEL_A, false);
MCPDAC.shutdown(CHANNEL_B, false);
//MCPDAC.shutdown(CHANNEL_B, true);

Serial.begin(9600);

pinMode(voltRead, INPUT);
pinMode(octRead, INPUT);
pinMode(toneRead, INPUT);

//This are the pins the on -off on switches are connected to, middle off //switch pin goes to ground

pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);

}

void loop() {


static unsigned int volts = 0;

/////////////////////////////////////////////////////

int voltReadVal = analogRead(voltRead);

///////////////////////////////////////////

int octReadVal = analogRead(octRead);
int octReadValMap = map (octReadVal, 0, 1023, 0, 4);
// -2 Octave, -1 Octave, 0 Octaves, +1 Octaves, +2 Octaves

Serial.print(octReadValMap); // print the A1 input
Serial.print('\t'); // print a tab character

//Here we have to consider the different octave switch postitions.
//We have 2 Switches, each with 3 possible positions so 9 combinations


// A+ / B+ = +2 Octaves // octReadValMap = 0

if ((digitalRead(2) == 0) && (digitalRead(4) == 0)) {
octReadValMap = 0;
}

// A+ / B = +1 Octaves // octReadValMap = 1 // ok

else if ((digitalRead(2) == 0) && (digitalRead(5) == 1) && (digitalRead(4) == 1)) {
octReadValMap = 1;
}

// A+ / B- = 0 Octaves // octReadValMap = 2 // ok

else if ((digitalRead(2) == 0) && (digitalRead(5) == 0)) {
octReadValMap = 2;
}

// A / B+ = +1 OCtaves // octReadValMap = 1 // ok

else if ((digitalRead(2) == 1) && (digitalRead(3) == 1) && (digitalRead(4) == 0)) {
octReadValMap = 1;
}

// A / B = 0 Octaves // octReadValMap = 2 // Ok

else if ((digitalRead(2) == 1) && (digitalRead(3) == 1) && (digitalRead(5) == 1) && (digitalRead(4) == 1)) {
octReadValMap = 2;
}

// A / B- = -1 Octaves // octReadValMap = 3 // ok

else if ((digitalRead(2) == 1) && (digitalRead(3) == 1) && (digitalRead(5) == 0)) {
octReadValMap = 3;
}

// A- / B+ = 0 Octaves // octReadValMap = 2 //ok

else if ((digitalRead(3) == 0) && (digitalRead(4) == 0)) {
octReadValMap = 2;
}

// A- / B = -1 Octaves // octReadValMap = 3 // ok

else if ((digitalRead(3) == 0) && (digitalRead(5) == 1) && (digitalRead(4) == 1)) {
octReadValMap = 3;
}

// A- / B- = -2 Octaves // octReadValMap = 4 //ok

else if ((digitalRead(3) == 0) && (digitalRead(5) == 0)) {
octReadValMap = 4;
}

////////////////////////////////////////////////////

//A- =if (digitalRead(3) == 0) {octReadValMap = 3;}

//A =if ((digitalRead(2) == 1) && (digitalRead(3) == 1)) {octReadValMap = 2;}

//A+ =if (digitalRead(2) == 0) {octReadValMap = 1;}

//B- =if (digitalRead(5) == 0) {octReadValMap = 3;}

//B = if ((digitalRead(5) == 1) && (digitalRead(4) == 1)) {octReadValMap = 2;}

//B+ = if (digitalRead(4) == 0) {octReadValMap = 1;}





/////////////////////////////////////////////

int toneReadVal = analogRead(toneRead);
int toneReadValMap = map (toneReadVal, 0, 1023, 0, 12);
// 12 semtitones

Serial.print(toneReadValMap); // print the A2 input
Serial.println('\t'); // print a tab character

///////////////////////////////////////////////////////

switch (octReadValMap) {
case 0:
octReadValFinal = 2046;
break;
case 1:
octReadValFinal = 1023;
break;
case 2:
octReadValFinal = 0;
break;
case 3:
octReadValFinal = -1023;
break;
case 4:
octReadValFinal = -2046;
break;

// case 0:
//octReadValFinal = 1023;
// break;
//case 1:
//octReadValFinal = 0;
//break;
//case 2:
//octReadValFinal = -1023;
//break;

}

////////////////////////////////////

switch (toneReadValMap) {

case 0:

toneReadValFinal = 0;
break;

case 1:

toneReadValFinal = (1023 / 12) * 1;
break;

case 2:

toneReadValFinal = (1023 / 12) * 2;
break;

case 3:

toneReadValFinal = (1023 / 12) * 3;
break;

case 4:

toneReadValFinal = (1023 / 12) * 4;
break;


case 5:

toneReadValFinal = (1023 / 12) * 5;
break;

case 6:

toneReadValFinal = (1023 / 12) * 6;
break;

case 7:

toneReadValFinal = (1023 / 12) * 7;
break;

case 8:

toneReadValFinal = (1023 / 12) * 8;
break;

case 9:

toneReadValFinal = (1023 / 12) * 9;
break;

case 10:

toneReadValFinal = (1023 / 12) * 10;
break;

case 11:

toneReadValFinal = (1023 / 12) * 11;
break;

case 12:

toneReadValFinal = (1023 / 12) * 12;
break;



}

//Octave and Semitone

int octPots = 2048 - (octReadValFinal);
// int octPots = 2048 - (octReadValFinal + 0.05); Code Trimmer?


int tonePots = (toneReadValFinal);
// int tonePots = (toneReadValFinal + 0.14); Code Trimmer?


int finalOut1 = octPots;
int finalOut2 = tonePots;

finalOut1 = constrain(finalOut1, 0, 4095); //4096 values
finalOut2 = constrain(finalOut2, 0, 4095); //4096 values


MCPDAC.setVoltage(CHANNEL_A, finalOut1);
MCPDAC.setVoltage(CHANNEL_B, finalOut2);

// I need to sum this voltages externally

I just Received some LM4040 voltage references, so im considering trying that approach too.

Many thanks to all that have contributed and helped me out!!
djthopa
Hi,

Hoping every one had a good start of the year.

I have made some calibration adjustments via hardware / software with the following errors:

-2 Octaves // Reading of -1.925 /0.075v error

-1 Octaves // Reading of -1.001v /Error of 0.001v

0 Octaves // Reading of -0.013 / Error of -0.013v

+1 Octaves // Reading of +1Volt // No error

+2 Octaves // // Reading of 1.900Volt // 0.1v Error

For the tone offset potentiometer for 1-12 tones, i had to add independent offsets to get: 1v / 12 steps = 0.083v

-0 Semitones :0 + 15.13 Final Out: 0v;
1 Semitones : 85.25 + 12.1; Final Out: 0.083v
2 Semitones : 170.5+ 8; Final Out: 0.166v
3 Semitones : 255.75 + 8.8; Final Out: 0.250v
4 Semitones :341 + 3.2; Final Out: 0.333v
5 Semitones :426.25; Final Out: 0.416v
6 Semitones :511.5; Final Out: 0.5v
7 Semitones : 596.75; Final Out: 0.583v
8 Semitones :682 - 5.8; Final Out: 0.666v
9 Semitones :767.25 - 7.3; Final Out: 0.75v
10 Semitones : 852.5 - 10.4; Final Out: 0.833v
11 Semitones : 937.75 - 13.2; Final Out: 0.916v
12 Semitones :1023 - 15; Final Out: 1v

So is this a right approach to adjusting the DAC and final outputs?

If in the cases used the maximum error i get is 0.099v = 0.1volt ( for +2 octaves switch) do you think its a viable error?

I have read that "Humans can distinguish a difference in pitch of about 5-6 cents." and mine is 0.12cents

So good to go? Any advice?

Many thanks!
Grumble
If you are brave enough you could go foor an Analog Devices AD5754 which is a 16 bit 4 channel Digital to Analog Converter, with the following output voltages (software selectable):

Output Range (V) Gain Value
+5
+10
+10.8
±5
±10
±10.8[/list][/list]
The 10.8 volt range is very handy for midi.
djthopa
Grumble wrote:
If you are brave enough you could go foor an Analog Devices AD5754 which is a 16 bit 4 channel Digital to Analog Converter, with the following output voltages (software selectable):

Output Range (V) Gain Value
+5
+10
+10.8
±5
±10
±10.8[/list][/list]
The 10.8 volt range is very handy for midi, since midi is 10 octave + 8 keys.


Hey Grumble,

Thanks for your feedback as always!

Im starting to learn about DAC and ADC so maybe going for 16 bit resolution might be a little bit too much for me at the moment?

I will defo look into it!!!

Many thanks!
Grumble
My guess is that 16 bits are just as easy as the 10 bits from the Arduino ADC, maybe just the interfacing is more problematic since some more hardware is involved and some more programming.
djthopa
Grumble wrote:
My guess is that 16 bits are just as easy as the 10 bits from the Arduino ADC, maybe just the interfacing is more problematic since some more hardware is involved and some more programming.


Hi again,

I have been looking at the DAC you suggested, and it seems to be only available as smd and the price is

Ill keep in on my watchlist!

Thanks!
Grumble
yes it is pricey hihi
but smd does not have to be a concern, since there are nice and cheap converter boards for sale like these:
https://nl.aliexpress.com/item/35-stks-7value-5-stks-PCB-Board-Kit-SMD -Turn-DIP-SOP-MSOP-SSOP-TSSOP-SOT23/32842167258.html
djthopa
Grumble wrote:
yes it is pricey hihi
but smd does not have to be a concern, since there are nice and cheap converter boards for sale like these:
https://nl.aliexpress.com/item/35-stks-7value-5-stks-PCB-Board-Kit-SMD -Turn-DIP-SOP-MSOP-SSOP-TSSOP-SOT23/32842167258.html


Yes it is expensive!

I am eventually going to get into SMD pretty soon. I have all the modules, tools and boms ready in pile, just need to finish my thru hole backlog Dead Banana

Gracias
MUFF WIGGLER Forum Index -> Music Tech DIY  
Page 1 of 1
Powered by phpBB © phpBB Group