Paso 8: Software
Instalar el Arduino IDE en el equipo que se controla el DAC y subir el Seekat Firmware para el Arduino.
Seekat Firmware
//Ardunio code for controlling Seekat DC voltage box from openDACS.com. Designed for Arduino UNO. #include “SPI.h” // necessary library int sync=10; // using digital pin 10 for SPI slave select int ldac=9; // Load dac (not implemented). You need to change some jumpers on the boards if you want to use synchronous updating and modify arduino code. int clr=8; // DAC Clear (not implemented). You need to change some jumpers on the AD58764 boards if you want to use this. void setup() { Serial.begin(9600); pinMode(7, OUTPUT); // we use this for SS pin pinMode(sync, OUTPUT); // we use this for SS pin pinMode(ldac, OUTPUT); // we use this for SS pin digitalWrite(7, HIGH); digitalWrite(sync, HIGH); SPI.begin(); // wake up the SPI bus. SPI.setBitOrder(MSBFIRST); //correct order for AD5764. SPI.setClockDivider(SPI_CLOCK_DIV32); SPI.setDataMode(SPI_MODE1); //1 and 3 communicate with DAC. 1 is the only one that works with no clock divider. } void setValue(byte DB[10]) { if (DB[0] == 255&&DB[1]==254&&DB[2]==253) // These bytes serve as a control that communication is working, and are reserved for future functionality such as synchronous updating, clear, and native arduino autoramp. { digitalWrite(sync, LOW); //assert sync-bar int o1 = SPI.transfer(DB[3]); // send command byte to DAC2 in the daisy chain. Serial.flush(); int o2 = SPI.transfer(DB[4]); // MS data bits, DAC2 Serial.flush(); int o3 = SPI.transfer(DB[5]);//LS 8 data bits, DAC2 Serial.flush(); int o4 = SPI.transfer(DB[6]);// send command byte to DAC1 in the daisy chain. Serial.flush(); int o5 = SPI.transfer(DB[7]);// MS data bits, DAC1 Serial.flush(); int o6 = SPI.transfer(DB[8]);//LS 8 data bits, DAC1 Serial.flush(); digitalWrite(sync, HIGH);//raise sync-bar to change the dac voltage. Must have LDAC-bar tied low. Serial.println(o1); Serial.println(o2); Serial.println(o3); Serial.println(o4); Serial.println(o5); Serial.println(o6); } else //This allows you to check on the scope what has been received by the Arduino for trouble shooting. Use pin 7 to trigger, then look at output of pins 13 (sclk) and 11 on the arduino to readout the bytes the arduino is getting. { digitalWrite(7, LOW); SPI.transfer(DB[0]); Serial.flush(); SPI.transfer(DB[1]); Serial.flush(); SPI.transfer(DB[2]); Serial.flush(); SPI.transfer(DB[3]); Serial.flush(); SPI.transfer(DB[4]); Serial.flush(); SPI.transfer(DB[5]); Serial.flush(); SPI.transfer(DB[6]); Serial.flush(); SPI.transfer(DB[7]); Serial.flush(); SPI.transfer(DB[8]); Serial.flush(); digitalWrite(7, HIGH); } } void loop() { if ( Serial.available()) // wait until all data bytes are avaialable { byte bytes[9]; for (int i=0; i<9; i++) { bytes[i] = Serial.read(); delay(2); //2mS pause to make sure bytes don’t run into each other. } setValue(bytes); } }
Comunicación con el Seekat se puede hacer con cualquier programa capaz de comunicación serial. Proporcionar a los conductores de Matlab a voltajes de leer y escribir y también para calibrar el offset y ganancia de cada canal con un DMM.
Estas funciones también se incluyen a continuación:
Escribir voltaje
%Find out which port the Arduino is using. One way is to use the Arduino IDE. % These are the commands you must execute in matlab to initialize for a virtual serial port COM5 on a PC. % global a; a = serial(‘COM5′,’baudrate’,115200);fopen(a) %Mac, for example: global a; a = serial(‘/dev/tty.usbmodem1431′,’BaudRate’,115200); fopen(a) function[] = setvoltageDC(channel,voltage) global a if voltage > 10 voltage = 10.0; elseif voltage < -10 voltage = -10.0; end switch channel case 1 n1 = 19; n2=0; m1=1; m2=0; case 2 n1 = 18; n2=0; m1=1; m2=0; case 3 n1 = 17; n2=0; m1=1; m2=0; case 4 n1 = 16; n2=0; m1=1; m2=0; case 5 n1 = 0; n2=19; m1=0; m2=1; case 6 n1 = 0; n2=18; m1=0; m2=1; case 7 n1 = 0; n2=17; m1=0; m2=1; case 8 n1 = 0; n2=16; m1=0; m2=1; otherwise disp(‘INVALID CHANNEL’) end if voltage >= 0 dec16 = round((2^15-1)*voltage/10); %Decimal equivalent of 16 bit data else dec16 = round(2^16 – abs(voltage)/10 * 2^15); %Decimal equivalent of 16 bit data end bin16 = de2bi(dec16,16,2,‘left-msb’); %16 bit binary d1=bi2de(fliplr(bin16(1:8))); %first 8 bits d2=bi2de(fliplr(bin16(9:16))); %second 8 bits %disp([255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]); %uncomment to check what’s being sent to the Arduino pause(.005); fwrite(a,[255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]); while a.BytesAvailable fscanf(a,‘%e’); end end
Leer voltaje
%Find out which port the Arduino is using. One way is to use the Arduino IDE. % These are the commands you must execute in matlab to initialize for a virtual serial port COM5 on a PC. % global a; a = serial(‘COM5′,’baudrate’,115200);fopen(a) %Mac, for example: global a; a = serial(‘/dev/tty.usbmodem1431′,’BaudRate’,115200); fopen(a) function v = getvoltageDC(channel) global a switch channel case 1 n1 = 19+128; n2=0; m1=1; m2=0; case 2 n1 = 18+128; n2=0; m1=1; m2=0; case 3 n1 = 17+128; n2=0; m1=1; m2=0; case 4 n1 = 16+128; n2=0; m1=1; m2=0; case 5 n1 = 0; n2=19+128; m1=0; m2=1; case 6 n1 = 0; n2=18+128; m1=0; m2=1; case 7 n1 = 0; n2=17+128; m1=0; m2=1; case 8 n1 = 0; n2=16+128; m1=0; m2=1; otherwise disp(‘INVALID CHANNEL’) end pause(.02); fwrite(a,[255,254,253,n1,0,0,n2,0,0]); pause(.02); fwrite(a,[255,254,253,n1,0,0,n2,0,0]); pause(.02); while a.BytesAvailable fscanf(a,‘%e’); % clear the buffer end fwrite(a,[255,254,253,0,0,0,0,0,0]); pause(.01); bdata=zeros([1,6]); for i=0:5; i=i+1; r=fscanf(a,‘%e’); bdata(i)=r; end bdata2=max(bdata(2)*2^8+bdata(3),bdata(5)*2^8+bdata(6)); if bdata2 < 2^15 %disp(10*bdata2/(2^15-1)) %bdata3=sprintf(‘%20f’,10.0*bdata2/(2^15-1)); bdata3=10.0*bdata2/(2^15-1); else %bdata3=sprintf(‘%20f’,-10.0*(2^16-bdata2)/2^15); bdata3=-10.0*(2^16-bdata2)/2^15; %disp(-10*(2^16-bdata2)/2^15) end v = bdata3; end
Calibrar la ganancia y offset
%plug the channel to be calibrated into a DMM. You will need to have some function of your own to read the DMM voltage. function[] = calibrateSeekat(channel) global a switch channel case 1 n1 = 19; n2=0; m1=1; m2=0; case 2 n1 = 18; n2=0; m1=1; m2=0; case 3 n1 = 17; n2=0; m1=1; m2=0; case 4 n1 = 16; n2=0; m1=1; m2=0; case 5 n1 = 0; n2=19; m1=0; m2=1; case 6 n1 = 0; n2=18; m1=0; m2=1; case 7 n1 = 0; n2=17; m1=0; m2=1; case 8 n1 = 0; n2=16; m1=0; m2=1; otherwise disp(‘INVALID CHANNEL’) end fwrite(a,[255,254,253,n1+24,0,0,n2+24,0,0]); %zero the offset register fwrite(a,[255,254,253,n1+16,0,0,n2+16,0,0]); %zero the gain register measuredValues = zeros(2,1); voltage = 0; if voltage >= 0 dec16 = round((2^15-1)*voltage/10); %Decimal equivalent of 16 bit data else dec16 = round(2^16 – abs(voltage)/10 * 2^15); %Decimal equivalent of 16 bit data end bin16 = de2bi(dec16,16,2,‘left-msb’); %16 bit binary d1=bi2de(fliplr(bin16(1:8))); %first 8 bits d2=bi2de(fliplr(bin16(9:16))); %second 8 bits %disp([255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]); pause(.005); fwrite(a,[255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]); while a.BytesAvailable fscanf(a,‘%e’); end pause(2) blah = smget(‘V’); %your code here to read voltage offset = -blah{1}; offsetsteps = round(offset/(38.14e-6)); offset8 = de2bi(mod((offsetsteps),2^8),8,‘left-msb’); d1=0;%bi2de(fliplr(bin16(1:8))); %first 8 bits d2=bi2de(fliplr(offset8));%bi2de(fliplr(bin16(9:16))); %second 8 bits %disp([255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]) pause(.005); fwrite(a,[255,254,253,n1+24,d1*m1,d2*m1,n2+24,d1*m2,d2*m2]); % +24 to access offset register while a.BytesAvailable fscanf(a,‘%e’); end pause(1) voltage = -10; if voltage >= 0 dec16 = round((2^15-1)*voltage/10); %Decimal equivalent of 16 bit data else dec16 = round(2^16 – abs(voltage)/10 * 2^15); %Decimal equivalent of 16 bit data end bin16 = de2bi(dec16,16,2,‘left-msb’); %16 bit binary d1=bi2de(fliplr(bin16(1:8))); %first 8 bits d2=bi2de(fliplr(bin16(9:16))); %second 8 bits %disp([255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]); pause(.005); fwrite(a,[255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]); while a.BytesAvailable fscanf(a,‘%e’); end pause(2) blah = smget(‘V’); %your code here to read voltage gainerror = blah{1}+10; gainsteps = round(gainerror/(152.59e-6)); gain8 = de2bi(mod((gainsteps),2^8),8,‘left-msb’); %bin16 = de2bi(gain16,16,2,’left-msb’); %16 bit binary d1=0;%bi2de(fliplr(gain16(1:8))) %first 8 bits d2=bi2de(fliplr(gain8));%bi2de(fliplr(gain8(1:8))) %second 8 bits pause(.005); fwrite(a,[255,254,253,n1+16,d1*m1,d2*m1,n2+16,d1*m2,d2*m2]); % +16 to access gain register instead of data register while a.BytesAvailable fscanf(a,‘%e’); end pause(1) voltage = 0; if voltage >= 0 dec16 = round((2^15-1)*voltage/10); %Decimal equivalent of 16 bit data else dec16 = round(2^16 – abs(voltage)/10 * 2^15); %Decimal equivalent of 16 bit data end bin16 = de2bi(dec16,16,2,‘left-msb’); %16 bit binary d1=bi2de(fliplr(bin16(1:8))); %first 8 bits d2=bi2de(fliplr(bin16(9:16))); %second 8 bits %disp([255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]); pause(.005); fwrite(a,[255,254,253,n1,d1*m1,d2*m1,n2,d1*m2,d2*m2]); while a.BytesAvailable fscanf(a,‘%e’); end end