Converting Analog values to 12bits

Hey all,

I am building a proximity capacitive sensor that would be able to control CV devices( Synthesizers). My current issues is that I am having a problem converting the analog values( from the capacitive sensor) to bits. I know you can use the map function for this, but the issues is that the map function doesn't deal with floats.

Anyone have any idea how to do this ?

So I am basically wondering how do you convert analog values to bits, that can be sent to a dac(MCP4822) to control cv devices.

Multiply the 10-bit result from an analogRead by 4, results in a 12-bit value.
Or just shift it left 2 bits:

newAnalog = analogRead(A0)*4;
or
newAnalog = analogRead(A0)<<2;

Or see this:- http://forum.arduino.cc/index.php/topic,106025.0.html

Ok thanks for both the suggestion. I made a mistake in the first post. I am actually using the cap sense library for the proximity capacitive sensor code. Since the value I get is actually digital values, are there any other ways to convert this value to bits ?

The cap sense library.

http://playground.arduino.cc/Main/CapacitiveSensor?from=Main.CapSense

Ashvin: Since the value I get is actually digital values, are there any other ways to convert this value to bits ?

Values are already store in "bits". You can use masking, shifting and other bit-wise operations to manipulate the bits as you see fit.

Normally you store the value from analogRead() into an INT. That means it has 16 bits - although only the low 10 of them are meaningful.

...R

Ashvin: Ok thanks for both the suggestion. I made a mistake in the first post. I am actually using the cap sense library for the proximity capacitive sensor code. Since the value I get is actually digital values, are there any other ways to convert this value to bits ?

As the numbers are int type you can just use the map function to put them into any range you want.

Thanks guys again for your help. So it is true I can just use the map function to solve my conversion problem. Now I have another small issues with sending the data to MCP4822. I am using the SPI library to do this but the issues is with SPI.transfer I am only able to send 8 bits. Since I am using the MCP4822 which is 16 bit DAC how do I send 16 bits to it. I did some reading on Bitwise but I am still pretty confused over the whole concept. So how do I send my MCP4822 16bits(12bits of information and 4bits of command) ?

Cheers, Ashvin.

http://ww1.microchip.com/downloads/en/DeviceDoc/22249A.pdf See page 23, fig 5-1.

byte commandByte = 0bxxxx0000; // xxxx are command bits, 0/1 as needed
int dataWord = 0x0FFF; // 12 bits of data

digitalWrite (cSPin, LOW);
SPI.transfer (commandByte | (highByte(data Word) ) ); // combine 4 bits & 4 bits
SPI.transfer (lowByte (dataWord) ); // lower 8 bits
digitalWrite (csPin, HIGH);

Set up the command bits for channel select, gain, and active per page 22.

what you could do to get 12 bits precision is to to add up 16 samples and divide by 4.

int sum = 0;
for (byte s = 0; s < 16; s++) sum += analogRead(A0);
int value = sum/4;

It is an wel known technique, for every bit extra you take 4x the number of samples.
so 12 bits => 4 x 4 samples. The division by 4 is to get fit back to 12 bits again

This is quite costly e.g. 14 bits will take 256x samples (divide by 16)

Hey thanks once again for all the help, I got the conversion to work! Anyways I would really like to better understand the code. Could anyone just give a basic explanation on these lines -

byte commandByte = 0bxxxx0000; // xxxx are command bits, 0/1 as needed

int dataWord = 0x0FFF; // 12 bits of data

I just want to know why is it (0b) ?

and the other one is why is it - 0x0FFF ( what does the FFF mean ) ?

Thanks in advance my friends!

Cheers, Ashvin.

“0b” introduces a binary number, and “0x” introduces a hex number.
0xFFF has the decimal value 4095 (212 -1)

0bxxxx0000 is used to clearly visualize where the bits are. 0b indicates binary format 0x0FFF is used to clearly visualize where the four, 4-bit nibbles are. 0x indicates hexadecimal (hex) format 0b0000111111111111 could have been used also, 0x0FFF is easier to see tho. F in 0x format is the same as 0b1111, or 15 decimal 0x0FFF is easier to see as 12 bits of 1, vs 4095 in decimal.

0b00000000 = 0x00 = 0 0b00000001 = 0x01 = 1 0b00000010 = 0x02 = 2 0b00000011 = 0x03 = 3 0b00000100 = 0x04 = 4 0b00000101 = 0x05 = 5 0b00000110 = 0x06 = 6 0b00000111 = 0x07 = 7 0b00001000 = 0x08 = 8 0b00001001 = 0x09 = 9 0b00001010 = 0x0A = 10 0b00001011 = 0x0B = 11 0b00001100 = 0x0C = 12 0b00001101 = 0x0D = 13 0b00001110 = 0x0E = 14 0b00001111 = 0x0F = 15

So depending on what you're doing, expressing things in binary, or hex, or decimal can make it easier to see what's going on.

Thank you Crossroads and everyone else for all the help. I now have a new problem and I am not to sure if it's due to hardware or software. So I am currently using my DAC to control synthesizers which have Control voltages input. The issues is my DAC is outputting its values in steps, I was wondering if there is anyway to smoothen out this steps ?

1) I was reading on a forum that I mite need to put a low pass filter on the DAC output to smoothen its output.

2) Is it because I have to use a logarithmic scale ?

Not too sure what to do. Any help is much appreciated.

Cheers, Ashvin.

issues is my DAC is outputting its values in steps,

What DAC is this then? All DACs do this. You need to get one with more bits resoloution so the steps are smaller.

Hey all,

Alright here is a sample audio from my device. As you can hear the pitch is moving up in steps due to how the DAC is sending it voltage. I was wondering is there a way to smooth these steps out ? I am trying to achieve a gliding effect.

Audio Sample-

https://soundcloud.com/ashvin-pal/newfile1

Cheers, Ashvin.

I was wondering is there a way to smooth these steps out ?

Did you not read my last answer, or did you just not believe it?

Oh sorry my friend I do believe you for sure. I just thought maybe I asked the question in the wrong way.