383 lines
13 KiB
C++
383 lines
13 KiB
C++
|
|
//********************Subroutine: ReadR*************
|
|
/*
|
|
read 1 Register R and return value
|
|
*/
|
|
byte readR(unsigned char r) {
|
|
byte c;
|
|
|
|
Wire.requestFrom(I2C_ADDRESS,r+1); //read every register from 0x00 until the required register
|
|
while (!Wire.available()==r+1); //wait until registers are available
|
|
|
|
for (int i=r; i>=0; i--) {
|
|
c=Wire.read();
|
|
if (i==0) {return c;} //return only required register
|
|
}
|
|
}
|
|
//********************Subroutine: readRegisters*****
|
|
/*
|
|
read a number of registers from 0 on
|
|
*/
|
|
byte readRegisters(byte number, byte* reg) {
|
|
byte c;
|
|
|
|
Wire.requestFrom((byte)I2C_ADDRESS,number); //read every register from 0x00 on
|
|
if (Wire.available()<number) { //wait until registers are available
|
|
return 10;
|
|
}
|
|
|
|
for (byte i=0; i<number; i++) {
|
|
reg[i]=Wire.read(); //copy value into array
|
|
}
|
|
return 0;
|
|
}
|
|
//********************Subroutine: writeR************
|
|
/*
|
|
write value v in register r
|
|
*/
|
|
void writeR(byte r, byte v){
|
|
Wire.beginTransmission(I2C_ADDRESS);
|
|
Wire.write(r); //register to write in
|
|
Wire.write(v); //value to write
|
|
Wire.endTransmission();
|
|
}
|
|
|
|
//********************Subroutine: setCapdacA********
|
|
void setCapdacA(byte* inp,byte start){
|
|
int capdac=int (inp[start]-'0')*100 //convert xx.x of the string to int
|
|
+int(inp[start+1]-'0')*10
|
|
+inp[start+3]-'0';
|
|
|
|
|
|
if (capdac>170){ //check if capdac has to be disabled
|
|
writeR(CAP_DAC_A,0); //disable capdac
|
|
}
|
|
else{
|
|
writeR(CAP_DAC_A,_BV(7)|(capdac*127/17+5)/10); //write value into register
|
|
}
|
|
}
|
|
//********************Subroutine: setCapdacB********
|
|
void setCapdacB(byte* inp,byte start){
|
|
int capdac=int (inp[start]-'0')*100 //convert xx.x of the string to int
|
|
+int(inp[start+1]-'0')*10
|
|
+inp[start+3]-'0';
|
|
|
|
|
|
if (capdac>170){ //check if capdac has to be disabled
|
|
writeR(CAP_DAC_B,0); //disable capdac
|
|
}
|
|
else{
|
|
writeR(CAP_DAC_B,_BV(7)|(capdac*127/17+5)/10); //write value into register
|
|
}
|
|
}
|
|
//********************Subroutine: readC*************
|
|
/*
|
|
read the 3 registers of the capacitance-channel and convert
|
|
to a 24Bit integer
|
|
*/
|
|
long readC(){
|
|
byte v[4];
|
|
readRegisters(4,v);
|
|
return long(v[1])*65536+long(v[2])*256+long(v[3]);
|
|
}
|
|
//********************Subroutine: readVT************
|
|
/*
|
|
read the 3 registers of the VT-channel and convert
|
|
to a 24Bit integer
|
|
*/
|
|
long readVT(){
|
|
byte v[7];
|
|
readRegisters(7,v);
|
|
return long(v[4])*65536+long(v[5])*256+long(v[6]);
|
|
|
|
}
|
|
//********************Subroutine: serial_gets*******
|
|
/*
|
|
read characters up to the next white space character
|
|
sent from the serial port as a string
|
|
*/
|
|
byte serial_gets(byte num, char* string) { //lentght of entered data
|
|
for (byte i=0; i<num; i++) {
|
|
while (Serial.available() == 0); //wait until data is available
|
|
string[i] = Serial.read(); //read data
|
|
if (string[i] == 13||string[i] == 95) { //if amount of data is sent complete string
|
|
string[i] = 0;
|
|
return i;
|
|
}
|
|
}
|
|
string[num-1] = 0;
|
|
while (Serial.available() > 0 && Serial.read() < 32); //if data is already available read untill finished
|
|
return num-1;
|
|
}
|
|
//********************Subroutine: setbits***********
|
|
/*
|
|
set value v of a defined bit lenght (lenght-startbit)
|
|
in the register r. For example the bits 5 to 7 of
|
|
register 0x0A have to be set on 010.
|
|
The command is: set_bits(0x0A,5,3,2)
|
|
5=Startbit,3=bitlenght,2=value of the binary code 010
|
|
*/
|
|
void set_bits (byte r, byte startbit, byte lenght, byte v){
|
|
byte b; //initialize a temp value b
|
|
b=readR(r); //read the Register which have to be changed and save as b
|
|
for (byte i=0;i<lenght;i++){
|
|
bitWrite(b,i+startbit,bitRead(v,i)); //read the value v bitwise and write simultaneously to the temp value b
|
|
}
|
|
writeR(r,b); //write the temp value b to the register r
|
|
}
|
|
|
|
//********************Subroutine: make_long*********
|
|
/*
|
|
converts 5 values of a string array (xxxxx) to type
|
|
long xxxxx
|
|
*/
|
|
long make_long(char* inp,byte start){
|
|
long a=1;
|
|
for (byte i=0;i<5;i++){
|
|
a*=10;
|
|
a+=inp[start+i]-'0';
|
|
}
|
|
|
|
return a;
|
|
}
|
|
//********************Subroutine: printll***********
|
|
/*
|
|
print integer number to the serial port with
|
|
a number of decimals so that it seems to be a float.
|
|
*/
|
|
void printll (long big, byte decimals){
|
|
byte i=0;
|
|
char zahl[11];
|
|
|
|
if (big<0){
|
|
Serial.print("-");
|
|
big*=-1;
|
|
}
|
|
|
|
while(i<decimals){
|
|
zahl[i]=big%10+'0'; //get the decimals reverse and save in array
|
|
big/=10;
|
|
i++;
|
|
}
|
|
|
|
if (decimals!=0){ //decide wether a decimal point has to be set or not
|
|
zahl[decimals]='.';
|
|
i=1; //if yes, add 1 to the string-counter
|
|
}
|
|
else{
|
|
i=0; //if not, set string-couter to 0
|
|
}
|
|
|
|
while(big>0){
|
|
zahl[i+decimals]=big%10+'0'; //get the integer part of the number
|
|
big/=10;
|
|
i++;
|
|
}
|
|
|
|
for (byte k=0;k<i+decimals;k++){ //print the string reverse
|
|
Serial.write(zahl[i+decimals-k-1]);
|
|
//Serial.print(zahl[i+decimals-k-1],BYTE);
|
|
}
|
|
}
|
|
//********************Subroutine: divll*************
|
|
/*
|
|
divide two integers a and b and adds decimals.the
|
|
number stays an integer, for every decimal, the
|
|
number increases by a factor of 10.
|
|
*/
|
|
long long divll(long long a,long long b,byte decimals){
|
|
long long rest;
|
|
long long rest2;
|
|
|
|
rest=a%b; //calculate remainder
|
|
a/=b; //calculate first digit
|
|
|
|
for (int i=0;i<decimals;i++){
|
|
rest*=10; //increase accuracy by a factor of 10
|
|
a*=10; //increase accuracy by a factor of 10
|
|
rest2=rest%b; //calculate new remainder
|
|
rest/=b; //calculate new amount to add
|
|
a+=rest; //add amount
|
|
rest=rest2; //new remainder = old remainder
|
|
}
|
|
return a;
|
|
}
|
|
//********************Subroutine: retcap************
|
|
/*
|
|
convert a bit value to a capacitance. since the bit
|
|
value is an integer the command requires the number
|
|
of decimals. The accuracy is increased to 8 decimals.
|
|
*/
|
|
long retcap(long long zahl,byte accuracy){
|
|
long long tmp1=8388608;
|
|
long tmp2=10000000;
|
|
long zahl2;
|
|
byte cas;
|
|
|
|
for (int i=0;i<accuracy;i++){ //increase decimals
|
|
tmp1*=10;
|
|
}
|
|
|
|
zahl-=tmp1;
|
|
zahl=divll(zahl,tmp1,8); //divide bit value
|
|
zahl*=4096; //full mesure range(+/-)
|
|
zahl/=1000; //remove additional decimals
|
|
zahl2=zahl; //convert long long into long
|
|
|
|
|
|
switch (settings[7]){ //check which c channel is enabled
|
|
case '0':
|
|
return -999999; //both disalbed
|
|
break;
|
|
|
|
case '1': //CIN 1 enabled
|
|
cas=settings[9];
|
|
break;
|
|
|
|
case '2': //CIN 2 enabled
|
|
cas=settings[21];
|
|
break;
|
|
|
|
default:
|
|
Serial.println("RETCAP-ERROR");
|
|
return -999999;
|
|
}
|
|
|
|
if (cas=='0'){
|
|
tmp2*=(int((readR(CAP_DAC_A)-128))*170+5)/127; //convert capdac 1 value int
|
|
zahl2+=tmp2; //add capdac 1 to mesured capacitance
|
|
return zahl2;
|
|
}
|
|
else{
|
|
return zahl2; //differential mode, no capdac added
|
|
}
|
|
|
|
}
|
|
|
|
//********************Subroutine: rettemp***********
|
|
/*
|
|
convert a bit value to a temperature. since the bit
|
|
value is an integer the command requires the number
|
|
of decimals. The accuracy is increased to 3 decimals
|
|
*/
|
|
long rettemp(long long zahl,byte decimals){
|
|
long long tmp;
|
|
long zahl2;
|
|
if (bitRead(readR(VT_SETUP),5)+bitRead(readR(VT_SETUP),6)==0){
|
|
tmp=2048;
|
|
for (int i=0;i<decimals;i++){ //increase decimals
|
|
tmp*=10;
|
|
}
|
|
zahl=divll(zahl,tmp,4); //divide bit value by range
|
|
zahl2=zahl; //convert long long into long
|
|
tmp=40960000;
|
|
zahl2-=tmp;
|
|
return zahl2;
|
|
}
|
|
else{
|
|
tmp=8388608;
|
|
for (int i=0;i<decimals;i++){ //increase decimals
|
|
tmp*=10;
|
|
}
|
|
zahl-=tmp;
|
|
zahl=divll(zahl,tmp,4); //divide bit value
|
|
zahl2=zahl; //convert long long into long
|
|
return zahl2;
|
|
}
|
|
}
|
|
|
|
//********************Subroutine: accumulate********
|
|
void accumulate(byte* cvt){
|
|
long long tmp;
|
|
long long tmpav;
|
|
long long delta;
|
|
for (byte i=0;i<2;i++){ //make twice, once for capacitance and once for VT channel
|
|
tmp=long(cvt[3*i+1])*65536 //create Bit-value out of register
|
|
+long(cvt[3*i+2])*256+long(cvt[3*i+3]);
|
|
if (tmp>maxi[i]) maxi[i]=tmp; //check if new value is max
|
|
if (tmp<mini[i]) mini[i]=tmp; //check if new value is min
|
|
if (i==0){
|
|
checkLIMIT(limits,tmp); //check if new value is out of range
|
|
}
|
|
|
|
if (n>0){ //create previous average
|
|
tmpav=av[i]/(n-1);
|
|
tmpav/=100;
|
|
}
|
|
else{
|
|
tmpav=0; //if n=0, previous average=0
|
|
}
|
|
delta=tmp*10; //increase accuracy
|
|
tmp*=1000; //increase accuracy
|
|
av[i]+=tmp; //new mean(sum)
|
|
|
|
|
|
delta-=tmpav;//1 //calculate delta
|
|
tmpav=av[i]/100;//1 //calculate new mean with 1 decimal accuracy
|
|
vari[i]+=delta*((tmp/100)-tmpav/n);//2 //calculate new sum of variance
|
|
}
|
|
}
|
|
//********************Subroutine: checkLIMIT********
|
|
/*
|
|
check if upper or lower limit is exceeded
|
|
*/
|
|
|
|
void checkLIMIT (byte* limits,long val){
|
|
byte cas;
|
|
byte loc;
|
|
|
|
val=retcap(val,0);
|
|
switch (settings[7]){ //check which c channel is enabled
|
|
case '0': //both disalbed
|
|
cas=9;
|
|
break;
|
|
|
|
case '1': //CIN 1 enabled
|
|
cas=settings[9]; //check if single mode
|
|
loc=9; //store start location of limit in string
|
|
break;
|
|
|
|
case '2': //CIN 2 enabled
|
|
cas=settings[21]; //check if single mode
|
|
loc=21; //store start location of limit in string
|
|
break;
|
|
|
|
default:
|
|
Serial.println("CHECKLIMIT-ERROR");
|
|
}
|
|
|
|
if (cas=='0'){ //enabled channel in sigle mode
|
|
if (val<retbitval(limits,loc)){ //check if lower limit is exceeded
|
|
digitalWrite(2,HIGH); //if yes set pin 2 high
|
|
}else{
|
|
digitalWrite(2,LOW); //else set pin 2 low
|
|
}
|
|
if (val>retbitval(limits,loc+6)){ //check if upper limit is exceeded
|
|
digitalWrite(3,HIGH); //if yes set pin 3 high
|
|
}
|
|
else{
|
|
digitalWrite(3,LOW); //else set pin 3 low
|
|
}
|
|
}
|
|
else{
|
|
digitalWrite(2,LOW);
|
|
digitalWrite(3,LOW);
|
|
}
|
|
|
|
}
|
|
//setLIMIT 04.99,11.21,01.00,11.17
|
|
//********************Subroutine: retbitval*********
|
|
/*
|
|
calculates the value in DEC out of 4 array elements
|
|
*/
|
|
long retbitval(byte* array,byte start){
|
|
long bitval;
|
|
bitval=long(array[start]-'0')*1000 //convert the string part xx.xx to an integer number xxxx
|
|
+long(array[start+1]-'0')*100
|
|
+long(array[start+3]-'0')*10
|
|
+long(array[start+4]-'0');
|
|
bitval*=1000000; //add 6 decimals
|
|
return bitval;
|
|
}
|
|
|