Go Down

Topic: Voltage Erratic behavior (Read 999 times) previous topic - next topic

ksp1717

Hi

I am trying to control the spindle motor and the arm of a hard drive. I have been successful in controlling the motor but have problems with the later part.

I have attached the schematic I am using to make a shield for arduino. I am using a uno. So my basic idea is that I have a D/A converter MCP4725 (http://ww1.microchip.com/downloads/en/DeviceDoc/22039d.pdf). The output of D/A is connected to the non inverting input of an OPAMP in bipolar configuration (as mentioned in the datasheet of D/A). The opamp is powered by +,-5V both at 1.5A. The output of opamp is passed through a pair of matching transistor to amplify current in both polarities. The amplified signal is passed to the "arm" of the hard drive and before grounding is passed through a current sensor ACS712 (http://embedded-lab.com/uploads/datasheets/ACS712-Datasheet.pdf).

After burning components and replacing them finally I got the arm to move.

Now the problem is the arm does not move as I expect it to. I am giving a sine wave voltage which goes from -2.5 to 2.5 V outside of OPAMP. (0-5V from D/A --> opamp --> -2.5-to-2.5V). But the arm just moves rapidly up and down. I tried to measure the voltage at several points. The output of D/A shows random voltage when it is connected to opamp. If i disconnect it then I get the sine wave which I want. (i.e 0-5-0-5....)

Can someone help me figure out whats going on in there ?

Thank you for your help

--ksp

MarkT

Several things immediately leap out.

uA741 won't work from a single 5V supply.  You want a rail-to-rail opamp (with a fairly hefty output to drive those transistors.)

You need to synthesize a signal ground for the op amp circuit at mid-rail (2.5V).

I can't follow the schematic in places because wires are on top of each other.

The output stage should really be class AB, not class B, otherwise you'll get instability at centre-crossings.
[ I won't respond to messages, use the forum please ]

Magician

Quote
I am giving a sine wave voltage which goes from -2.5 to 2.5 V outside of OPAMP. (0-5V from D/A --> opamp --> -2.5-to-2.5V).

I can't follow how you off-set 2.5 voltage.  And resistor divider in negative feedback path shouldn't be at +5 V, but GND.
I'd suggest using one more OPA, having 2.5V as a reference ( gain 1) just to transform single polarity input to AC, and driving your PA (OPA + transistor ).

ksp1717

Thanks for your reply.

@MarkT
I have both 5V and -5V to the opamp.  I am not really good at electrical circuits. So I am not sure what synthesize ground means and same with class AB and B. I have attached a better schematic.

@Magician

Instead of GND, I have put it to 5V to make the signal bipolar. I did it according to the schematic given in the datasheet of MCP4725 D/A converter. I have put a link of the datasheet in my original post.

I have already tested the circuit(the bipolar output part) on a breadboard and it works fine. I also tested the entire circuit with matching transistors using a supply box at +,-5V,0.5A and everything worked fine. It is only after I made the pcb out of it these problems are creeping in. PCB was manufactured and assembled professionally. But why is this problem ?

--ksp

Magician

Quote
Instead of GND, I have put it to 5V to make the signal bipolar. I did it according to the schematic given in the datasheet of MCP4725 D/A converter.
Oh, o'k. Now I understand.  Other things, which confuse me:
Quote
I am giving a sine wave voltage which goes from -2.5 to 2.5 V outside of OPAMP. (0-5V from D/A --> opamp --> -2.5-to-2.5V).

Your PA has a gain 10. So output of DAC has to be 0.5 V peak-to-peak, 0  to 0.5  V centered around 0.25 V.  How you generate a sine wave? DC off-set in your configuration comming from the microcontroller,  what I think, you should look in the code, if there is correct scale / bias of the sine,  no overdrive and etc.

ksp1717

I am not sure what you mean here
Quote

DC off-set in your configuration comming from the microcontroller,  what I think, you should look in the code, if there is correct scale / bias of the sine,  no overdrive and etc.


I am attaching the sketch also. I am not exactly giving a sine wave but increasing the bytes from 0 to 4095 and back to 0 in steps of 250 ( an approximated sine). Do you think this is the problem ??

--ksp
Code: [Select]

byte Program = 64;
byte Device = 96; // This hardwired into the IC

int maxValue = 4095;

int minValue = 0;
int value = 4095;
int dir = 250;

#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
}

void loop()
{
  byte b1 = byte((value / 16));
  byte b2 = byte(value % 16);
 
  Wire.beginTransmission(Device);
  Wire.write(Program);
  Wire.write(b1);//(value >> 4);
  Wire.write(b2);//((value & 15) << 4); // Needed twice, since the 4 lowest bits (of 12) are in the fourth byte
  Wire.endTransmission();
 
  value = value + dir;
  if(value > maxValue) dir = -250;
  if(value <= minValue) dir = 250;

  delay(3000);
}


MarkT

Your opamp feedback network is referenced to +5V for some reason - I think you seem to be expecting a 741 to work from 0V to +5V when supplied with +5V and -5V - it probably won't.  You need to use a low voltage opamp, not a 741 (its only characterised for +/-15V supplies in the datasheet).

Can you redraw the circuit the right way up please, it'll be much easier to understand (+ve rail at the top, -ve rail at the bottom, signals travel left to right).
In particular your output stage doesn't make any sense to me - why is the output only used for feedback? Have you missed the load from the diagram?
[ I won't respond to messages, use the forum please ]

Magician

12-bit DAC , triangle wave at the output should be 0 - 409.5, to produce 0  - 0.5 V . "0" would be 204.8
You can't "scale" your triangle wave by division 16 (or shifting 4 to right), because it's changing all references. Try division by 10.
Other way to generate a sine, is  generate AC bipolar form in the code ( from -204 to + 204 ), and add 204 off-set later on, it's easier to "scale" magnitude AC.


ksp1717

@MarkT
Sorry for the diagram, I am not familiar with drawing schematics, this is the second time I am doing it. I will try to make it more legible.

The output feedback is referenced to +5V to make the 741 work between -2.5 to 2.5V i.e, to shift the D/A output of 0-5V. Please check the datasheet of D/A converter, I used the bipolar application circuit.

Yes I have left the load out of the diagram. It is connected to the terminal which is labeled "coil".

@Magician
I will try the division by 10 and get back with the results.

Thanks

--ksp

Magician

Thinking little bit more about  what they say in data sheet, I find out that basically  I was right about "scaling" and offset, but my math isn't correct. Don't know why you decide to make a gain 10, but its highly complicate calculation of the offset voltage. VDD depends on gain, so you can't just connect +5V power line as VDD and pick up any gain you want (  with resistors 910 and 100).

-2.5 / VDD = R2 / R1
VDD = 2.5 * R1 / R2 = 2.5 * 100 / 910 = 0.27472 V

Probably, you could connect VDD to +5V only for gain 1, setting  resistors in negative feedback 1:1 .

ksp1717

#10
Mar 20, 2012, 11:34 pm Last Edit: Mar 23, 2012, 12:43 am by ksp1717 Reason: 1
i have run the following code on just the D/A converter and the output of it is ~3V no matter which conversion I use.

Code: [Select]
byte Program = 64;
byte Device = 96; // This hardwired into the IC and the BoB, in other words, it is a given.

int maxValue = 4095;
int minValue = 0;
int value = 4092;
int dir = 250;

#include <Wire.h>

void setup()
{
 Wire.begin();
 Serial.begin(9600);
}

void loop()
{
//  byte b1 = value >> 4;
//  byte b2 = (value & 15)<< 4;
//  byte b1 = byte(value/16);
//  byte b2 = byte((value % 16) << 4);

 byte b1 = byte(value/10);
 byte b2 = byte(value % 10);
 
 Wire.beginTransmission(Device);
 Wire.write(Program);
 Wire.write(b1);
 Wire.write(b2); // Needed twice, since the 4 lowest bits (of 12) are in the fourth byte
 Wire.endTransmission();
 Serial.print(value);Serial.print("\t");Serial.print(b1);Serial.print("\t");
 Serial.print(b2);Serial.print("\n");
//  value = value + dir;
 if(value > maxValue) dir = -250;
 if(value <= minValue) dir = 250;

 delay(3000);
}

Magician

Code: [Select]
  byte b1 = byte(value/10);
  byte b2 = byte(value % 10);


There are  commands to get HighByte LowByte from the int.
http://arduino.cc/en/Reference/HomePage

MarkT

Can I just re-state that the 741 is not guaranteed to work at all with the inputs/outputs within 3V of a supply rail (make that 4V if the outputs are loaded by lower than 10k impedance).  Its a very poor choice of opamp with rail-to-rail 5V-compatible ones abound these days.
[ I won't respond to messages, use the forum please ]

ksp1717

#13
Mar 23, 2012, 12:42 am Last Edit: Mar 23, 2012, 12:44 am by ksp1717 Reason: 1
@MarkT
This program worked and the problem was the device address. Once I have put in the address it the D/A converter was working good. But as you have said I think the OPAMP is causing problems. I should change it in the next iteration.
Can you suggest a replacement for the 741 opamp.
I will post the output I am currently receiving in the next post.
Code: [Select]

byte Program = 64;
byte Device = 100;
int maxValue = 4075;
int minValue = 0;
int value = 4075;
int dir = -250;

#include <Wire.h>
void setup()
{
 Wire.begin();
 Serial.begin(9600);
}
void loop()
{
 byte b1 = value >> 4;
 byte b2 = (value & 15)<< 4;
 Wire.beginTransmission(Device);
 Wire.write(Program);
 Wire.write(b1);
 Wire.write(b2); // Needed twice, since the 4 lowest bits (of 12) are in the fourth byte
 Wire.endTransmission();
 Serial.print(value);Serial.print("\t");Serial.print(b1);Serial.print("\t");
 Serial.print(b2);Serial.print("\n");
 value = value + dir;
 if(value >= maxValue) dir = -250;
 if(value <= minValue) dir = 250;
 delay(1000);
}


Thanks
Shyam

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy