Stap 8: Software
Installeer de Arduino IDE op de computer die beheersing van de DAC en uploaden van de Firmware van de Seekat naar de 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); } }
Communicatie met de Seekat kan worden gedaan met een willekeurig programma geschikt voor seriële communicatie. Wij bieden Matlab drivers te schrijven en te lezen spanningen, en ook om te kalibreren de offset en krijgen van elk kanaal met behulp van een DMM.
Deze functies zijn ook worden opgenomen hieronder:
Schrijven van spanning
%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
Lezen van spanning
%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
Kalibreren van de winst en 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