I am trying to control a 20 kpps laser galvo with my Arduino uno. After a whole lot of research I think I have found that I need to use a DAC in between the two to make it work. I have not used the Wire transmission commands before but what I need it to do is to command the galvo to start at the same position each time the Arduino and circuit is powered on and then to advance to a set position and stop. While stopped my program will (eventually) test for other conditions then move to the next position, for a total of eight positions. Right now I am just trying to figure out how to communicate with the DAC and consequently the galvo. If I understand it right then I have to start with Wire.beginTransmission(0x62); and end with Wire.endTransmission(); and in between do some Wire.write(); commands but I'm not sure how to use them to tell the DAC to step the galvo to a certain position.
Any help on how this works would be helpful. I have downloaded the library for the MCP4725(my DAC) and have reviewed the reference material for the Wire commands on this site but it doesn't get me from A to B.
If found all that with less than 5 minutes of Google searching (including looking at the library code). That's less time than it took me to write this reply. There's certainly no shortage of info.
The calculation for the DAC output is the opposite of the ADC input. Convert from your desired position as a percent of the range then scale by by the DAC count range (in this case the DAC is 12 bit opposed to the 10 bit ADC so the factor is 4095 instead of 1023)
Position / Range * 4095 = DAC_Output
Since I purchased a Sparkfun board I saw there method and did not look for a library. Using their method the code is
Wire.beginTransmission(MCP4725_ADDR);
Wire.write(64); // cmd to update the DAC
Wire.write(DAC_Output >> 4); // the 8 most significant bits...
Wire.write((DAC_Output & 15) << 4); // the 4 least significant bits...
Wire.endTransmission();
That part can't be easier.
Question for you to determine from the documents for the galvo what the range is and how the position is related to the input voltage that "selects" the position.
(1) Assume VDD supply to the DAC is 5V. TWI Bus address of DAC (deviceAddress) is 0b01100010 (0x62).
(2) According to data sheets VREF for the DAC = VDD. And, the VOUT (Output DC voltage of DAC) is given by:(VDD*unsToDAC/4096; where, unsToDAC stands for unsigned 12-bit value to the input of DAC.
Example: To get VOUT as 1.75V, we may execute the following codes:
#include<Wire.h>
#define Vout 1.75
#define firstByteSlaveAddress 0x62
#define secondByte 0x40 //command Byte:update DAC; DAC Mode
#define thirdByte (unsToDAC >> 4); //shift to right by 4-bit, Fig-6.2 of DS; 059A --> 59
#define forthByte ((unsToDAC & 0x000F) << 4) //bit mask and then shift left by 4-bit; Fig-6.2 of DS; 059A --> A0
uint16_t unsToDAC = (uint16_t) Vout*4096/5; //unsigned 12-bit data to DAC input
void setup()
{
Wire.begin();
Wire.beginTransmission(firstByteSlaveAddress); //slave address
Wire.write(secondByte); //Fig-6.2 of DS for Command Byte
Wire.write(thirdByte); //Fig-6.2 for upper 8-bit data of DAC
Wire.write(forthByte); //Fig-6.2 for lower 4-bit data of DAC
Wire.endTransmission();
}
void loop() {
// put your main code here, to run repeatedly:
}
4) Let us connect a DVM at Vout pin of DAC. Upload the codes of Step-3. We should see that DVM reads about 1.75V.
#include<Wire.h> //Include Wire library for using I2C functions #define MCP4725 0x60 //MCP4725 address as 0x60 Change yours accordingly
unsigned int adc;
byte buffer[3];
void setup()
{
Serial.begin(9600);
Wire.begin(); //Begins the I2C communication
}
void loop()
{
buffer [0] = 0b01000000; //Sets the buffer0 with control byte (010-Sets in Write mode
adc = analogRead(A0) * 4; //Read Analog value from pin A0 and convert into digital (0-1023) multiply with 4 gives (0-4096)
float ipvolt = (5.0 / 4096.0) * adc; //Finding voltage formula (A0)
buffer[1] = adc >> 4; //Puts the most significant bit values
buffer[2] = adc << 4; //Puts the Least significant bit values
unsigned int analogread = analogRead(A0)4 ; //Reads analog voltage from A1
float opvolt = (5.0/4096.0) analogread; //Finding Voltage Formula (A1)
Wire.beginTransmission(MCP4725); //Joins I2C bus with MCP4725 with 0x61 address
Wire.write(buffer [0]); //Sends the control byte to I2C
Wire.write(buffer [1] ); //Sends the MSB to I2C
Wire.write(buffer [2]); //Sends the LSB to I2C
Wire.endTransmission(); //Ends the transmission
delay(1000);
input voltage will go to voltage (0 ... 5)
output voltage
Must be (5 ... 0) v
I want it to be
anologread A0 input voltage (0 .... 5v)
I want from the output (5 ..... 0v)
can this be achieved by changing the address
or lice ~~ or !! I tried to use it, did not
I could not do the inverting process in the output example I would like your help, maybe a simple operation