Files
2025-08-06 14:20:36 +02:00

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;
}