Go Down

Topic: Digital to Analogue Conversion (Read 707 times) previous topic - next topic

Javaid

Dear All,

I am using this code to get analogue signal from the Arduino Uno using MCP4921 chip. Pin 8 from the chip is the output.
Code: [Select]

// SPI Interface SS_PIN(PB2), SCK_PIN(PB5), MOSI_PIN(PB3), MISO_PIN
// Arduino Pin 10 13 11 12
// MCP4921 DAC SS SCK MOSI n/a
#include "SPI.h"
// ATmega328P ADC
int analogPin = 0; // analog input channel
// ADC analog input value
word sensorValue = 0; // equivalent to unsigned int
// Byte of data to output to DAC
byte data = 0;
void setup() {
//set pin(s) to input and output
pinMode(analogPin, INPUT);
}
void loop() {
// read the value from the sensor:
sensorValue = analogRead(analogPin); // comment out this line to test DAC
// sensorValue = 0x0200; // 0x03FF = Vref, 0x0200 = 1/2 Vref
sensorValue = sensorValue << 2 ; // 10 bit ADC to 12-bit DAC word
// set SS pin low, beginning 16-bit (2 byte) data transfer to DAC
digitalWrite(10, LOW);
// send high byte
data = highByte(sensorValue);
data = 0b00001111 & data; // clear 4-bit command field (optional)
data = 0b00110000 | data; // 0=DACA, 0=buffered, 1=1x, 1=output enabled
SPI.transfer(data); // alt: shiftOut(MOSI, SCK, MSBFIRST, data);
// send low byte
data = lowByte(sensorValue);
SPI.transfer(data); // alt: shiftOut(MOSI, SCK, MSBFIRST, data);
// set SS pin high, completing 16-bit transfer to DAC
}

I am getting a continuous signal of 5V (as shown by multimeter :P)
I have connected a LED to ensure that. Now I want to change the voltage. Let's say 1V or 2V in order to see whether the intensity of the LED goes down or not.
How should I do that ??

Grumpy_Mike

By setting the value of sensorValue not to what you read but from your code.

However this code appeares to read the analogue input and write it out to your D/A so you could just put a pot on the analogue input and so get a variable output.

Note that the LED will not light up at all if it has less than the forward voltage across it so at less than say 1.7V you will see nothing at all. I hope you have a resisitir in with the LED as well.

Javaid

Yes I do have a resistor there. But let's just forget the idea of using a pot for a second :P

All right, I got another code.
Code: [Select]

#include "SPI.h" // necessary library
int del=0; // used for various delays
word outputValue = 0; // a word is a 16-bit number
byte data = 0; // and a byte is an 8-bit number
void setup()
{
  //set pin(s) to input and output
  pinMode(10, OUTPUT);
  SPI.begin(); // wake up the SPI bus.
  SPI.setBitOrder(MSBFIRST);
}

void loop()
{
  for (int a=0; a<=4095; a++)
  {
    outputValue = a;
    digitalWrite(10, LOW);
    data = highByte(outputValue);
    data = 0b00001111 & data;
    data = 0b00110000 | data;
    SPI.transfer(data);
    data = lowByte(outputValue);
    byte x = SPI.transfer(data);
    digitalWrite(10, HIGH);
    delay(del);
  }
  delay(del+25);
  for (int a=4095; a>=0; --a)
  {
    outputValue = a;
    digitalWrite(10, LOW);
    data = highByte(outputValue);
    data = 0b00001111 & data;
    data = 0b00110000 | data;
    byte x = SPI.transfer(data);
    data = lowByte(outputValue);
    SPI.transfer(data);
    digitalWrite(10, HIGH);
    delay(del);
  }
  delay(del+25);
}

But with this, there are 2 problems:
1- LED keeps on blinking, so how do I stop the LED from blinking?
2- And is there no way of changing the voltage via coding and if so what is it ?

Grumpy_Mike

The LED blinks because that is what the code is telling it to do. It is rapidly ramping up and down the voltage, when this drops below the turn on voltage the LED goes out. You have no delay between each step so it looks to be going just on and off.

With this code if you delete the two lines that define outputValue and replace it with something like
OutputValue = 256 you will get a fixed output voltage.

Javaid

You are right about making the value 256. It stopped blinking and is shining as brightly as ever :P

But still no means to change the voltage value :-S

Is it even possible to get 3V (say) or 4V as it is connected to 5V of Arduino ?

Grumpy_Mike

Try a diffrent value, say 128 it is this value that gets translated into an output voltage. Have you measured it with a meter to check it?

Replace those lines and increase the delay time to say 100 (it is currently set at zero) and you should see some faiding of the LED.

Javaid

My friend, this might come as a shock but I think that the LED just doesn't give a damn  :~

Nothing has changed, I tried making the delay 900. I put the value to be 1, still it is shining like before  :smiley-eek:

Nick Gammon

I happened to have a MCP4921 lying around (waiting for some use for it) so I was able to wire up your circuit. I presume you are tying pin 5 low, and putting +5V onto pin 6 (DAC input).

Then using your exact sketch, but changing this one line:

Code: [Select]
int del=10; // used for various delays

... it all seems to work perfectly. I didn't use an LED, just a multimeter. The voltage starts off at zero, and climbs up to just over 5V, then goes down again. So the chip seems to work as you would expect it to.

The only reason for changing the delay was to slow it down enough to see the different voltages on the meter.

Nick Gammon

OK, more test data. I hooked up an "ordinary cheap" red LED to pin 8 (the output) via a 120 ohm resistor. Then the thing just seemed to freeze (the voltage didn't change). Checking the limits of the device, it seems that 25 mA is the absolute maximum rating, and it would have been drawing close to 25 mA. Changing the resistor to 1K it now worked, after a fashion. That would have drawn 3 mA at 5V (assuming a 2V forward LED voltage). Now the LED goes on and off.

However the "fading" seems to be fairly abrupt, (at around the 2V output mark). Much below 1.8V and the LED is off (which you would expect, that being its forward voltage) and above about 2.4V it seems to be on (that might partly be because of the way our eyes work).

So the sketch works, but the LED is not a very precise measuring tool.

Javaid

That's what I am talking about  :P

Thanks a lot Nick. You made my day  :)

Go Up