This commit is contained in:
2025-08-06 14:20:36 +02:00
commit 992ce9a84f
12 changed files with 2130 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
/****************************************************
Programmed during 2011-05-02 and 2011-07-29 for the
project ACM1219 as a serial interface
Designed and developed by Adrian Beckert
Contact: adrian.beckert@gmx.ch
*****************************************************/
#include <Wire.h>
#include <EEPROM.h>
#define I2C_ADDRESS 0x48 //define register adresses
#define STATUS 0x00
#define CAP_DATA 0x01
#define VT_DATA 0x04
#define CAP_SETUP 0x07
#define VT_SETUP 0x08
#define EXC_SETUP 0x09
#define CONFIGURATION 0x0A
#define CAP_DAC_A 0x0B
#define CAP_DAC_B 0x0C
#define CAP_OFFSET 0x0D
#define CAP_GAIN 0x0F
#define VOLTAGE_GAIN 0x11
//initial operation of EEPROM for booting and factory default settins
byte values[159]={128,0,75,57,158,0,128,0,77,208,91,37,115,101,
116,67,73,78,32,49,44,48,44,48,52,46,48,44,57,57,46,57,44,48,
44,57,57,46,57,44,57,57,46,57,0,115,101,116,76,73,77,73,84,32,
48,48,46,48,49,44,48,56,46,49,56,44,48,48,46,48,48,44,48,48,46,
48,48,0,0,1,128,0,75,57,158,0,128,0,77,208,91,37,115,101,
116,67,73,78,32,49,44,48,44,48,52,46,48,44,57,57,46,57,44,48,
44,57,57,46,57,44,57,57,46,57,0,115,101,116,76,73,77,73,84,32,
48,48,46,48,49,44,48,56,46,49,56,44,48,48,46,48,48,44,48,48,46,
48,48,0};
//variables for statistics
unsigned long ti=0; //millis() is an unsigned long type (runs over after 49.7 days)
unsigned int n=0;
long long av[2];
long long vari[2];
long mini[2];
long maxi[2];
//string for saving settings from setCIN
byte settings[33];
byte limits[33];
void setup(){
if (EEPROM.read(77)!=0){ //check if EEPROM may have been already used or not
for (byte i=0;i<158;i++){
EEPROM.write(i,values[i]); //write values in EEPROM
}
}
pinMode(2,OUTPUT); //set pin 2 as output
pinMode(3,OUTPUT); //set pin 3 as output
Serial.begin(9600);
Wire.begin();
byte control;
Wire.beginTransmission(0x00); //general call
Wire.write(0x06); //reset AD7746
control =Wire.endTransmission();
delay(1); //wait for reboot
if (control!=0){
Serial.println("DEVICE CONNECTION ERROR");
}
//Set configurations saved in EEPROM
for (byte i=0;i<12;i++){
writeR(i+7,EEPROM.read(i)); //set registers as saved in EEPROM
}
//get Settings-String of EEPROM
for (byte i=12;i<45;i++){
settings[i-12]=EEPROM.read(i); //set settings-string as saved in EEPROM
}
//get limits-String of EEPROM
for (byte i=45;i<78;i++){
limits[i-45]=EEPROM.read(i); //set settings-string as saved in EEPROM
}
}
void loop(){
byte cvt[7];
byte control=0;
if (Serial.available()>0){ //check if command is available
char cmd[33];
serial_gets(33,cmd); //read incoming command
analyse_cmd(cmd); //analyse command
control=1; //indicate that a command was processed
}
if (n>50000){control=1;} //indicate if the averaging function risks to overflow
if (control==1){ //if indicator is =1
ti=millis(); //reset time
n=0; //reset number of measurements
for (byte i=0;i<2;i++){ //reset all other statistical variables
av[i]=0;
vari[i]=0;
mini[i]=16777215;
maxi[i]=0;
}
}
else{
if (bitRead(readR(0),0)==0){ //check status register if new data is available
readRegisters(7,cvt); //read new data
n++;
accumulate(cvt); //update statistical variables
}
}
}

View File

@@ -0,0 +1,118 @@
/****************************************************
Programmed during 2011-05-02 and 2011-07-29 for the
project ACM1219 as a serial interface
Designed and developed by Adrian Beckert
Contact: adrian.beckert@gmx.ch
*****************************************************/
#include <Wire.h>
#include <EEPROM.h>
#define I2C_ADDRESS 0x48 //define register adresses
#define STATUS 0x00
#define CAP_DATA 0x01
#define VT_DATA 0x04
#define CAP_SETUP 0x07
#define VT_SETUP 0x08
#define EXC_SETUP 0x09
#define CONFIGURATION 0x0A
#define CAP_DAC_A 0x0B
#define CAP_DAC_B 0x0C
#define CAP_OFFSET 0x0D
#define CAP_GAIN 0x0F
#define VOLTAGE_GAIN 0x11
//initial operation of EEPROM for booting and factory default settins
byte values[159]={128,0,75,57,158,0,128,0,77,208,91,37,115,101,
116,67,73,78,32,49,44,48,44,48,52,46,48,44,57,57,46,57,44,48,
44,57,57,46,57,44,57,57,46,57,0,115,101,116,76,73,77,73,84,32,
48,48,46,48,49,44,48,56,46,49,56,44,48,48,46,48,48,44,48,48,46,
48,48,0,0,1,128,0,75,57,158,0,128,0,77,208,91,37,115,101,
116,67,73,78,32,49,44,48,44,48,52,46,48,44,57,57,46,57,44,48,
44,57,57,46,57,44,57,57,46,57,0,115,101,116,76,73,77,73,84,32,
48,48,46,48,49,44,48,56,46,49,56,44,48,48,46,48,48,44,48,48,46,
48,48,0};
//variables for statistics
unsigned long ti=0; //millis() is an unsigned long type (runs over after 49.7 days)
unsigned int n=0;
long long av[2];
long long vari[2];
long mini[2];
long maxi[2];
//string for saving settings from setCIN
byte settings[33];
byte limits[33];
void setup(){
if (EEPROM.read(77)!=0){ //check if EEPROM may have been already used or not
for (byte i=0;i<158;i++){
EEPROM.write(i,values[i]); //write values in EEPROM
}
}
pinMode(2,OUTPUT); //set pin 2 as output
pinMode(3,OUTPUT); //set pin 3 as output
Serial.begin(9600);
Wire.begin();
byte control;
Wire.beginTransmission(0x00); //general call
Wire.write(0x06); //reset AD7746
control =Wire.endTransmission();
delay(1); //wait for reboot
if (control!=0){
Serial.println("DEVICE CONNECTION ERROR");
}
//Set configurations saved in EEPROM
for (byte i=0;i<12;i++){
writeR(i+7,EEPROM.read(i)); //set registers as saved in EEPROM
}
//get Settings-String of EEPROM
for (byte i=12;i<45;i++){
settings[i-12]=EEPROM.read(i); //set settings-string as saved in EEPROM
}
//get limits-String of EEPROM
for (byte i=45;i<78;i++){
limits[i-45]=EEPROM.read(i); //set settings-string as saved in EEPROM
}
}
void loop(){
byte cvt[7];
byte control=0;
if (Serial.available()>0){ //check if command is available
char cmd[33];
serial_gets(33,cmd); //read incoming command
analyse_cmd(cmd); //analyse command
control=1; //indicate that a command was processed
}
if (n>50000){control=1;} //indicate if the averaging function risks to overflow
if (control==1){ //if indicator is =1
ti=millis(); //reset time
n=0; //reset number of measurements
for (byte i=0;i<2;i++){ //reset all other statistical variables
av[i]=0;
vari[i]=0;
mini[i]=16777215;
maxi[i]=0;
}
}
else{
if (bitRead(readR(0),0)==0){ //check status register if new data is available
readRegisters(7,cvt); //read new data
n++;
accumulate(cvt); //update statistical variables
}
}
}

View File

@@ -0,0 +1,47 @@
//********************Subroutine********************
void displayStatus() {
byte v[19];
readRegisters(19,v);
Serial.println("\nAD7746 Registers:");
Serial.print("Status (0x00): ");
Serial.println(v[0],BIN);
Serial.print("Cap Data (0x01-0x03): ");
Serial.print(v[1],BIN);
Serial.print("/");
Serial.print(v[2],BIN);
Serial.print("/");
Serial.println(v[3],BIN);
Serial.print("VT Data (0x04-0x06): ");
Serial.print(v[4],BIN);
Serial.print("/");
Serial.print(v[5],BIN);
Serial.print("/");
Serial.println(v[6],BIN);
Serial.print("Cap Setup (0x07): ");
Serial.println(v[7],BIN);
Serial.print("VT Setup (0x08): ");
Serial.println(v[8],BIN);
Serial.print("EXC Setup (0x09): ");
Serial.println(v[9],BIN);
Serial.print("Configuration (0x0A): ");
Serial.println(v[10],BIN);
Serial.print("Cap Dac A (0x0B): ");
Serial.println(v[11],BIN);
Serial.print("Cap Dac B (0xc0C): ");
Serial.println(v[12],BIN);
Serial.print("Cap Offset (0x0D-0x0E): ");
Serial.print(v[13],BIN);
Serial.print("/");
Serial.println(v[14],BIN);
Serial.print("Cap Gain (0x0F-0x10): ");
Serial.print(v[15],BIN);
Serial.print("/");
Serial.println(v[16],BIN);
Serial.print("Volt Gain (0x11-0x12): ");
Serial.print(v[17],BIN);
Serial.print("/");
Serial.println(v[18],BIN);
Serial.println("");
}

View File

@@ -0,0 +1,382 @@
//********************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;
}

View File

@@ -0,0 +1,116 @@
//********************Subroutine********************
//Analyse command
byte analyse_cmd(char* cmd){
switch (cmd[0]*cmd[1]-cmd[2]) //analyse cmd string
{
case 11417: //read...
switch(cmd[4]*cmd[5]-cmd[6]){ //analyse read command
case 5678: //CVT
readCVT(settings);
break;
case 5523: //AVC
readAVCVT();
break;
case 6907: //STA
readSTATUS();
break;
case 6478: //MUC
readMUC(settings,cmd);
break;
default:
Serial.println("READ-ERROR");
}
break;
case 11499: //set...
Serial.println(cmd); //return received string to acknowledge the reception
switch(cmd[3]*cmd[4]-cmd[5]){ //analyse set command
case 4813: //CIN
setCIN(settings,cmd);
break;
case 5471: //LIM
setLIMIT(limits,cmd);
break;
case 7192: //VT (and white space (ASCII32))
setVT(cmd);
break;
case 5596: //CT (and white space (ASCII32))
setCT(cmd);
break;
case 6005: //EXC
setEXC(cmd);
break;
case 7157: //VTC
setVTCHOP(cmd);
break;
case 5017: //CLK
setCLKCTRL(cmd);
break;
case 7141: //VTS
setVTSHORT(cmd);
break;
case 4275: //CAP
setCAPCHOP(cmd);
break;
case 5215: //CON
setCONVMOD(cmd);
break;
case 5223: //COF
setCOF(cmd);
break;
case 4692: //CGA
setCGAINOF(cmd);
break;
case 6041: //VGA
setVGAINOF(cmd);
break;
default:
Serial.println("SET-ERROR");
}
break;
case 2998: //*IDN?
Serial.println("0x48,ACM1219,Arduino Uno ATMEGA328P-PU,AD7746 Capacitance-to-Digital Converter,A.Beckert");
break;
case 11037: //saveSettings
Serial.println(cmd); //return received string to acknowledge the reception
saveSettings();
break;
case 11399: //restoreDefaults
Serial.println(cmd); //return received string to acknowledge the reception
restoreDefaults();
break;
default:
Serial.print(cmd); //return received string to acknowledge the reception
Serial.println(",CMD-ERROR");
}
}

View File

@@ -0,0 +1,357 @@
//********************Subroutine: setCIN************
void setCIN(byte* settings, char* cmd){
float f;
if (cmd[3]*cmd[4]-cmd[5]==4813){ //check if command is CIN and not MUC or else
for (byte i=0;i<32;i++){ //copy command into settings string
settings[i]=cmd[i];
}
}
switch (settings[7]){
case '0': //disable CIN 1 and CIN 2
set_bits(CAP_SETUP,0,8,settings[7]-'0'); //set cap channel off
writeR(CAP_DAC_A,0); //disable capdac A
writeR(CAP_DAC_B,0); //disable capdac B
break;
case '1': //CIN 1 selected
set_bits(CAP_SETUP,6,2,settings[7]-'0'+1); //set CIN1
set_bits(CAP_SETUP,5,1,settings[9]-'0'); //set differential mode
setCapdacA(settings,11); //set CapdacA
setCapdacB(settings,16); //set CapdacB
break;
case '2': //CIN 2 selected
set_bits(CAP_SETUP,6,2,settings[7]-'0'+1); //set CIN2
set_bits(CAP_SETUP,5,1,settings[21]-'0'); //set differential mode
setCapdacA(settings,23); //set CapdacA
setCapdacB(settings,28); //set CapdacB
break;
default:
Serial.println("setC_ERROR");
}
}
//********************Subroutine: setVT*************
void setVT(char* cmd){
set_bits(VT_SETUP,5,3,cmd[6]-'0'); //select temp sensor int/ext,vdd monitor, ext voltage input
set_bits(VT_SETUP,4,1,cmd[8]-'0'); //set ext voltage Reference
}
//********************Subroutine: setCT*************
void setCT(char* cmd){
set_bits(CONFIGURATION,6,2,cmd[8]-'0'); //set conversion time VT channel
set_bits(CONFIGURATION,3,3,cmd[6]-'0'); //set conversion time C channel
}
//********************Subroutine: setEXC************
void setEXC(char* cmd){
set_bits(EXC_SETUP,2,2,cmd[7]-'0'); //config EXC Pin A
set_bits(EXC_SETUP,4,2,cmd[9]-'0'); //config EXC Pin B
set_bits(EXC_SETUP,0,2,cmd[11]-'0'); //set Vdd
set_bits(EXC_SETUP,6,1,cmd[13]-'0'); //set EXCON
}
//********************Subroutine: setVTCHOP*********
void setVTCHOP(char* cmd){
set_bits(VT_SETUP,0,1,cmd[10]-'0'); //set VT chop
}
//********************Subroutine: setCLKCTRL********
void setCLKCTRL(char* cmd){
set_bits(EXC_SETUP,7,1,cmd[11]-'0'); //set CLKCTRL
}
//********************Subroutine: setVTSHORT********
void setVTSHORT(char* cmd){
set_bits(VT_SETUP,1,1,cmd[11]-'0'); //set VT short
}
//Example:
//setVTSHORT_1
//********************Subroutine: setCAPCHOP********
/*
CAPCHOP approximately doubles the conversion time
*/
void setCAPCHOP(char* cmd){
set_bits(CAP_SETUP,0,1,cmd[11]-'0'); //set CAP chop
}
//********************Subroutine: setCONVMOD********
void setCONVMOD(char* cmd){
set_bits(CONFIGURATION,0,3,cmd[11]-'0'); //set converter mode
}
//********************Subroutine: setCOF************
/*
set an accurate c-channel offset
*/
void setCOF(char* cmd){
unsigned int big=65535; //16Bit full range
big*=make_long(cmd,7); //return a long type
big/=6;
big/=10000; //delete additional digits
if (big<65536){
writeR(CAP_OFFSET,big/256); //write in register
writeR(CAP_OFFSET+1,big%256); //write in register
}
else{
Serial.println("SETCOF-ERROR");
}
}
//********************Subroutine: setGAINOF*********
/*
Set gain of the c-channel
*/
void setCGAINOF(char* cmd){
unsigned int big;
big=make_long(cmd,11); //convert string into integer value
if (big<65536){
writeR(CAP_GAIN,big/256); //split value in two registers
writeR(CAP_GAIN+1,big%256); //part two
}
else{
Serial.println("SETCGAINOF-ERROR");
}
}
//********************Subroutine: setVGAINOF********
/*
change factory calibratet VT-channel gain
*/
void setVGAINOF(char* cmd){
unsigned int big;
big=make_long(cmd,11); //convert string into integer value
if (big<65536){
writeR(VOLTAGE_GAIN,big/256); //split value in two registers
writeR(VOLTAGE_GAIN+1,big%256); //part two
}
else{
Serial.println("SETVGAINOF-ERROR");
}
}
/*********************Subroutine********************
read routines
**********************Subroutine: readCVT***********/
void readCVT(byte* settings){
switch (settings[7]){ //check which C channel is enabled
case '0':
Serial.print("-999.999,-999.999,"); //if both disabled, print twice -999.999
printll(rettemp(readVT(),0),4);
Serial.println("");
break;
case '1':
printll(retcap(readC(),0),8); //read capacitance on enabled channel
Serial.print(",-999.999,"); //print -999.999 for disabled channel
printll(rettemp(readVT(),0),4); //read temperature
Serial.println("");
break;
case '2': //analog to case '1'
Serial.print("-999.999,");
printll(retcap(readC(),0),8);
Serial.print(",");
printll(rettemp(readVT(),0),4);
Serial.println("");
break;
default:
Serial.println("READ-ERROR");
}
}
//********************Subroutine: readAVCVT*********
void readAVCVT(){
float f;
if (n>1){ //avoid divisions by 0
for (byte i=0;i<2;i++){
vari[i]/=(n-1); //calculate variance
f=float(vari[i]); //convert long long to float
f/=100; //remove additional decimals (because of integer arithmetic)
f=sqrt(f); //calculate standard deviation
f/=8388608.; //convert bit value into pF
f*=4.096; //multiply with half mesure scale
av[i]/=n; //calculate average
if (i==0){
printll(retcap(mini[i],0),8); //convert bit value to pF
Serial.print(",");
printll(retcap(maxi[i],0),8); //convert bit value to pF
Serial.print(",");
printll(retcap(av[i],3),8); //convert to pF and print average
Serial.print(",");
}
else{
printll(rettemp(mini[i],0),4); //convert bit value to pF
Serial.print(",");
printll(rettemp(maxi[i],0),4); //convert bit value to pF
Serial.print(",");
printll(rettemp(av[i],3),4); //convert to pF and print average
Serial.print(",");
}
Serial.print(f,5);
Serial.print(",");
}
Serial.print(millis()-ti); //display mesured interval
Serial.print(",");
Serial.println(n); //display number of mesurements
}
else{
Serial.println("n<2 !!!");
}
}
//********************Subroutine: readSTATUS********
void readSTATUS(){
displayStatus(); //Display all Registers
}
//********************Subroutine: readMUC***********
/*
read on CIN 1 and CIN 2 multiplex. Mesure first with
actual settings, afterward load settings for other
channel and restore previous settings.Between
multiplex delays for 700ms for updating values
on c-channel.
*/
void readMUC(byte* settings, char* cmd){
long f;
switch (settings[7]){ //check current enabled channel
case '0': //both channels disabled
Serial.print("-999.999,-999.999,"); //show that both capacitance channels are disabled
printll(rettemp(readVT(),0),4); //read+print vt channel
break;
case '1': //channel 1 enabled
printll(retcap(readC(),0),8); //read+print capacitance
Serial.print(",");
settings[7]='2'; //change settings string for next step. Channel 2 will be enabled
setCIN(settings,cmd); //change coonfigurations and enable channel 2 (due to the change of settings string)
delay(700); //wait for updating the new configured channel
printll(retcap(readC(),0),8); //read+print capacitance on channel 2
Serial.print(",");
settings[7]='1'; //change settings string
setCIN(settings,cmd); //change configurations and enable channel 1
printll(rettemp(readVT(),0),4); //read+print vt channel
break;
case '2': //channel 2 enabled
f=readC(); //read first channel 2 and store result
settings[7]='1'; //start multiplex mode etc. (analog case '1')
setCIN(settings,cmd);
//delay(700);
while(bitRead(readR(0),0)==1);
while(bitRead(readR(0),0)==1);
printll(retcap(readC(),0),8);
settings[7]='2';
setCIN(settings,cmd);
Serial.print(",");
printll(retcap(f,0),8);
Serial.print(",");
printll(rettemp(readVT(),0),4);
break;
default:
Serial.println("MULTIPLEX-ERROR");
}
Serial.println("");
}
//********************Subroutine: saveSETTINGS******
/*
save the current settings in EEPROM incl. settings-string
*/
void saveSettings(){
byte a;
unsigned int b=0;
for (byte i=0;i<12;i++){ //go through every write-register and
a=readR(i+7);
if(a!=EEPROM.read(i)){ //proof if the current register has the same value as before
EEPROM.write(i,a); //write the value into EEPROM
b=1; //indicate if any change has been made
}
}
for (byte i=0;i<33;i++){
if (EEPROM.read(i+12)!=settings[i]){ //check settings-string
EEPROM.write(i+12,settings[i]); //if a value is different, write to EEPROM
b=1; //indicate if any change has been made
}
}
for (byte i=0;i<33;i++){
if (EEPROM.read(i+45)!=limits[i]){ //check limits-string
EEPROM.write(i+45,limits[i]); //if a value is different, write to EEPROM
b=1; //indicate if any change has been made
}
}
if (b==1){ //if changes have been saved
b=(long(EEPROM.read(78))*256)+EEPROM.read(79); //read how many have already been saved
b++; //increase 1
if (b>65534){ //ERROR if settings have already been changed 65534 times
Serial.println("ATTENTION CURRENT USED EEPROM FOR SAVESETTINGS HAS TO BE CHANGED.PLEASE CONSULT THE DEVELOPER A.BECKERT.");
}
EEPROM.write(78,b/256); //write new save-number to EEPROM
EEPROM.write(79,b%256); //write new save-number to EEPROM
}
}
//********************Subroutine: setLIMIT**********
/*
create limits string
*/
void setLIMIT(byte* limits, char*cmd){
for (byte i=0;i<32;i++){ //copy command into settings string
limits[i]=cmd[i];
}
}
//setLIMIT 04.99,11.21,05.02,12.17"
//********************Subroutine: restoreDefaults***
/*
restore factory defaults
*/
void restoreDefaults(){
for (byte i=0;i<78;i++){
if (EEPROM.read(i)!=EEPROM.read(80+i)){
EEPROM.write(i,EEPROM.read(80+i));
}
}
//Set configurations saved in EEPROM
for (byte i=0;i<12;i++){
writeR(i+7,EEPROM.read(i)); //set registers as saved in EEPROM
}
//get Settings-String of EEPROM
for (byte i=12;i<45;i++){
settings[i-12]=EEPROM.read(i); //set settings-string as saved in EEPROM
}
//get limits-String of EEPROM
for (byte i=45;i<78;i++){
limits[i-45]=EEPROM.read(i); //set settings-string as saved in EEPROM
}
}

View File

@@ -0,0 +1,45 @@
/****************************************************
Programmed during 2011-05-02 and 2011-07-29 for the
project ACM1219 as a microcontroller setup for the
ACM1219 interface
Designed and developed by Adrian Beckert
Contact: adrian.beckert@gmx.ch
*****************************************************/
#include <EEPROM.h>
byte values[159]={128,0,75,57,158,0,128,0,77,208,91,37,115,101, //Values to write into the EEPROM
116,67,73,78,32,49,44,48,44,48,52,46,48,44,57,57,46,57,44,48,
44,57,57,46,57,44,57,57,46,57,0,115,101,116,76,73,77,73,84,32,
48,48,46,48,49,44,48,56,46,49,56,44,48,48,46,48,48,44,48,48,46,
48,48,0,0,1,128,0,75,57,158,0,128,0,77,208,91,37,115,101,
116,67,73,78,32,49,44,48,44,48,52,46,48,44,57,57,46,57,44,48,
44,57,57,46,57,44,57,57,46,57,0,115,101,116,76,73,77,73,84,32,
48,48,46,48,49,44,48,56,46,49,56,44,48,48,46,48,48,44,48,48,46,
48,48,0};
void setup(){
Serial.begin(9600);
for (byte i=0;i<158;i++){ //write values in EEPROM
EEPROM.write(i,values[i]);
}
Serial.println("Please check:");
Serial.println("Column 1: Values to write in EEPROM");
Serial.println("Column 2: Values written in EEPROM");
for (byte i=0;i<158;i++){ //print the values written into serial port
Serial.print(i,DEC);
Serial.print(": ");
Serial.print(values[i],DEC);
Serial.print(" ");
Serial.println(EEPROM.read(i),DEC);
}
Serial.println("successful");
Serial.println("Please close the serial port and load the file 'ACM1219_Interface_Rev01' on the Arduino microcontroller");
}
void loop(){
}

View File

@@ -0,0 +1,47 @@
//********************Subroutine********************
void displayStatus() {
byte v[19];
readRegisters(19,v);
Serial.println("\nAD7746 Registers:");
Serial.print("Status (0x00): ");
Serial.println(v[0],BIN);
Serial.print("Cap Data (0x01-0x03): ");
Serial.print(v[1],BIN);
Serial.print("/");
Serial.print(v[2],BIN);
Serial.print("/");
Serial.println(v[3],BIN);
Serial.print("VT Data (0x04-0x06): ");
Serial.print(v[4],BIN);
Serial.print("/");
Serial.print(v[5],BIN);
Serial.print("/");
Serial.println(v[6],BIN);
Serial.print("Cap Setup (0x07): ");
Serial.println(v[7],BIN);
Serial.print("VT Setup (0x08): ");
Serial.println(v[8],BIN);
Serial.print("EXC Setup (0x09): ");
Serial.println(v[9],BIN);
Serial.print("Configuration (0x0A): ");
Serial.println(v[10],BIN);
Serial.print("Cap Dac A (0x0B): ");
Serial.println(v[11],BIN);
Serial.print("Cap Dac B (0xc0C): ");
Serial.println(v[12],BIN);
Serial.print("Cap Offset (0x0D-0x0E): ");
Serial.print(v[13],BIN);
Serial.print("/");
Serial.println(v[14],BIN);
Serial.print("Cap Gain (0x0F-0x10): ");
Serial.print(v[15],BIN);
Serial.print("/");
Serial.println(v[16],BIN);
Serial.print("Volt Gain (0x11-0x12): ");
Serial.print(v[17],BIN);
Serial.print("/");
Serial.println(v[18],BIN);
Serial.println("");
}

View File

@@ -0,0 +1,382 @@
//********************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;
}

View File

@@ -0,0 +1,116 @@
//********************Subroutine********************
//Analyse command
byte analyse_cmd(char* cmd){
switch (cmd[0]*cmd[1]-cmd[2]) //analyse cmd string
{
case 11417: //read...
switch(cmd[4]*cmd[5]-cmd[6]){ //analyse read command
case 5678: //CVT
readCVT(settings);
break;
case 5523: //AVC
readAVCVT();
break;
case 6907: //STA
readSTATUS();
break;
case 6478: //MUC
readMUC(settings,cmd);
break;
default:
Serial.println("READ-ERROR");
}
break;
case 11499: //set...
Serial.println(cmd); //return received string to acknowledge the reception
switch(cmd[3]*cmd[4]-cmd[5]){ //analyse set command
case 4813: //CIN
setCIN(settings,cmd);
break;
case 5471: //LIM
setLIMIT(limits,cmd);
break;
case 7192: //VT (and white space (ASCII32))
setVT(cmd);
break;
case 5596: //CT (and white space (ASCII32))
setCT(cmd);
break;
case 6005: //EXC
setEXC(cmd);
break;
case 7157: //VTC
setVTCHOP(cmd);
break;
case 5017: //CLK
setCLKCTRL(cmd);
break;
case 7141: //VTS
setVTSHORT(cmd);
break;
case 4275: //CAP
setCAPCHOP(cmd);
break;
case 5215: //CON
setCONVMOD(cmd);
break;
case 5223: //COF
setCOF(cmd);
break;
case 4692: //CGA
setCGAINOF(cmd);
break;
case 6041: //VGA
setVGAINOF(cmd);
break;
default:
Serial.println("SET-ERROR");
}
break;
case 2998: //*IDN?
Serial.println("0x48,ACM1219,Arduino Uno ATMEGA328P-PU,AD7746 Capacitance-to-Digital Converter,A.Beckert");
break;
case 11037: //saveSettings
Serial.println(cmd); //return received string to acknowledge the reception
saveSettings();
break;
case 11399: //restoreDefaults
Serial.println(cmd); //return received string to acknowledge the reception
restoreDefaults();
break;
default:
Serial.print(cmd); //return received string to acknowledge the reception
Serial.println(",CMD-ERROR");
}
}

View File

@@ -0,0 +1,357 @@
//********************Subroutine: setCIN************
void setCIN(byte* settings, char* cmd){
float f;
if (cmd[3]*cmd[4]-cmd[5]==4813){ //check if command is CIN and not MUC or else
for (byte i=0;i<32;i++){ //copy command into settings string
settings[i]=cmd[i];
}
}
switch (settings[7]){
case '0': //disable CIN 1 and CIN 2
set_bits(CAP_SETUP,0,8,settings[7]-'0'); //set cap channel off
writeR(CAP_DAC_A,0); //disable capdac A
writeR(CAP_DAC_B,0); //disable capdac B
break;
case '1': //CIN 1 selected
set_bits(CAP_SETUP,6,2,settings[7]-'0'+1); //set CIN1
set_bits(CAP_SETUP,5,1,settings[9]-'0'); //set differential mode
setCapdacA(settings,11); //set CapdacA
setCapdacB(settings,16); //set CapdacB
break;
case '2': //CIN 2 selected
set_bits(CAP_SETUP,6,2,settings[7]-'0'+1); //set CIN2
set_bits(CAP_SETUP,5,1,settings[21]-'0'); //set differential mode
setCapdacA(settings,23); //set CapdacA
setCapdacB(settings,28); //set CapdacB
break;
default:
Serial.println("setC_ERROR");
}
}
//********************Subroutine: setVT*************
void setVT(char* cmd){
set_bits(VT_SETUP,5,3,cmd[6]-'0'); //select temp sensor int/ext,vdd monitor, ext voltage input
set_bits(VT_SETUP,4,1,cmd[8]-'0'); //set ext voltage Reference
}
//********************Subroutine: setCT*************
void setCT(char* cmd){
set_bits(CONFIGURATION,6,2,cmd[8]-'0'); //set conversion time VT channel
set_bits(CONFIGURATION,3,3,cmd[6]-'0'); //set conversion time C channel
}
//********************Subroutine: setEXC************
void setEXC(char* cmd){
set_bits(EXC_SETUP,2,2,cmd[7]-'0'); //config EXC Pin A
set_bits(EXC_SETUP,4,2,cmd[9]-'0'); //config EXC Pin B
set_bits(EXC_SETUP,0,2,cmd[11]-'0'); //set Vdd
set_bits(EXC_SETUP,6,1,cmd[13]-'0'); //set EXCON
}
//********************Subroutine: setVTCHOP*********
void setVTCHOP(char* cmd){
set_bits(VT_SETUP,0,1,cmd[10]-'0'); //set VT chop
}
//********************Subroutine: setCLKCTRL********
void setCLKCTRL(char* cmd){
set_bits(EXC_SETUP,7,1,cmd[11]-'0'); //set CLKCTRL
}
//********************Subroutine: setVTSHORT********
void setVTSHORT(char* cmd){
set_bits(VT_SETUP,1,1,cmd[11]-'0'); //set VT short
}
//Example:
//setVTSHORT_1
//********************Subroutine: setCAPCHOP********
/*
CAPCHOP approximately doubles the conversion time
*/
void setCAPCHOP(char* cmd){
set_bits(CAP_SETUP,0,1,cmd[11]-'0'); //set CAP chop
}
//********************Subroutine: setCONVMOD********
void setCONVMOD(char* cmd){
set_bits(CONFIGURATION,0,3,cmd[11]-'0'); //set converter mode
}
//********************Subroutine: setCOF************
/*
set an accurate c-channel offset
*/
void setCOF(char* cmd){
unsigned int big=65535; //16Bit full range
big*=make_long(cmd,7); //return a long type
big/=6;
big/=10000; //delete additional digits
if (big<65536){
writeR(CAP_OFFSET,big/256); //write in register
writeR(CAP_OFFSET+1,big%256); //write in register
}
else{
Serial.println("SETCOF-ERROR");
}
}
//********************Subroutine: setGAINOF*********
/*
Set gain of the c-channel
*/
void setCGAINOF(char* cmd){
unsigned int big;
big=make_long(cmd,11); //convert string into integer value
if (big<65536){
writeR(CAP_GAIN,big/256); //split value in two registers
writeR(CAP_GAIN+1,big%256); //part two
}
else{
Serial.println("SETCGAINOF-ERROR");
}
}
//********************Subroutine: setVGAINOF********
/*
change factory calibratet VT-channel gain
*/
void setVGAINOF(char* cmd){
unsigned int big;
big=make_long(cmd,11); //convert string into integer value
if (big<65536){
writeR(VOLTAGE_GAIN,big/256); //split value in two registers
writeR(VOLTAGE_GAIN+1,big%256); //part two
}
else{
Serial.println("SETVGAINOF-ERROR");
}
}
/*********************Subroutine********************
read routines
**********************Subroutine: readCVT***********/
void readCVT(byte* settings){
switch (settings[7]){ //check which C channel is enabled
case '0':
Serial.print("-999.999,-999.999,"); //if both disabled, print twice -999.999
printll(rettemp(readVT(),0),4);
Serial.println("");
break;
case '1':
printll(retcap(readC(),0),8); //read capacitance on enabled channel
Serial.print(",-999.999,"); //print -999.999 for disabled channel
printll(rettemp(readVT(),0),4); //read temperature
Serial.println("");
break;
case '2': //analog to case '1'
Serial.print("-999.999,");
printll(retcap(readC(),0),8);
Serial.print(",");
printll(rettemp(readVT(),0),4);
Serial.println("");
break;
default:
Serial.println("READ-ERROR");
}
}
//********************Subroutine: readAVCVT*********
void readAVCVT(){
float f;
if (n>1){ //avoid divisions by 0
for (byte i=0;i<2;i++){
vari[i]/=(n-1); //calculate variance
f=float(vari[i]); //convert long long to float
f/=100; //remove additional decimals (because of integer arithmetic)
f=sqrt(f); //calculate standard deviation
f/=8388608.; //convert bit value into pF
f*=4.096; //multiply with half mesure scale
av[i]/=n; //calculate average
if (i==0){
printll(retcap(mini[i],0),8); //convert bit value to pF
Serial.print(",");
printll(retcap(maxi[i],0),8); //convert bit value to pF
Serial.print(",");
printll(retcap(av[i],3),8); //convert to pF and print average
Serial.print(",");
}
else{
printll(rettemp(mini[i],0),4); //convert bit value to pF
Serial.print(",");
printll(rettemp(maxi[i],0),4); //convert bit value to pF
Serial.print(",");
printll(rettemp(av[i],3),4); //convert to pF and print average
Serial.print(",");
}
Serial.print(f,5);
Serial.print(",");
}
Serial.print(millis()-ti); //display mesured interval
Serial.print(",");
Serial.println(n); //display number of mesurements
}
else{
Serial.println("n<2 !!!");
}
}
//********************Subroutine: readSTATUS********
void readSTATUS(){
displayStatus(); //Display all Registers
}
//********************Subroutine: readMUC***********
/*
read on CIN 1 and CIN 2 multiplex. Mesure first with
actual settings, afterward load settings for other
channel and restore previous settings.Between
multiplex delays for 700ms for updating values
on c-channel.
*/
void readMUC(byte* settings, char* cmd){
long f;
switch (settings[7]){ //check current enabled channel
case '0': //both channels disabled
Serial.print("-999.999,-999.999,"); //show that both capacitance channels are disabled
printll(rettemp(readVT(),0),4); //read+print vt channel
break;
case '1': //channel 1 enabled
printll(retcap(readC(),0),8); //read+print capacitance
Serial.print(",");
settings[7]='2'; //change settings string for next step. Channel 2 will be enabled
setCIN(settings,cmd); //change coonfigurations and enable channel 2 (due to the change of settings string)
delay(700); //wait for updating the new configured channel
printll(retcap(readC(),0),8); //read+print capacitance on channel 2
Serial.print(",");
settings[7]='1'; //change settings string
setCIN(settings,cmd); //change configurations and enable channel 1
printll(rettemp(readVT(),0),4); //read+print vt channel
break;
case '2': //channel 2 enabled
f=readC(); //read first channel 2 and store result
settings[7]='1'; //start multiplex mode etc. (analog case '1')
setCIN(settings,cmd);
//delay(700);
while(bitRead(readR(0),0)==1);
while(bitRead(readR(0),0)==1);
printll(retcap(readC(),0),8);
settings[7]='2';
setCIN(settings,cmd);
Serial.print(",");
printll(retcap(f,0),8);
Serial.print(",");
printll(rettemp(readVT(),0),4);
break;
default:
Serial.println("MULTIPLEX-ERROR");
}
Serial.println("");
}
//********************Subroutine: saveSETTINGS******
/*
save the current settings in EEPROM incl. settings-string
*/
void saveSettings(){
byte a;
unsigned int b=0;
for (byte i=0;i<12;i++){ //go through every write-register and
a=readR(i+7);
if(a!=EEPROM.read(i)){ //proof if the current register has the same value as before
EEPROM.write(i,a); //write the value into EEPROM
b=1; //indicate if any change has been made
}
}
for (byte i=0;i<33;i++){
if (EEPROM.read(i+12)!=settings[i]){ //check settings-string
EEPROM.write(i+12,settings[i]); //if a value is different, write to EEPROM
b=1; //indicate if any change has been made
}
}
for (byte i=0;i<33;i++){
if (EEPROM.read(i+45)!=limits[i]){ //check limits-string
EEPROM.write(i+45,limits[i]); //if a value is different, write to EEPROM
b=1; //indicate if any change has been made
}
}
if (b==1){ //if changes have been saved
b=(long(EEPROM.read(78))*256)+EEPROM.read(79); //read how many have already been saved
b++; //increase 1
if (b>65534){ //ERROR if settings have already been changed 65534 times
Serial.println("ATTENTION CURRENT USED EEPROM FOR SAVESETTINGS HAS TO BE CHANGED.PLEASE CONSULT THE DEVELOPER A.BECKERT.");
}
EEPROM.write(78,b/256); //write new save-number to EEPROM
EEPROM.write(79,b%256); //write new save-number to EEPROM
}
}
//********************Subroutine: setLIMIT**********
/*
create limits string
*/
void setLIMIT(byte* limits, char*cmd){
for (byte i=0;i<32;i++){ //copy command into settings string
limits[i]=cmd[i];
}
}
//setLIMIT 04.99,11.21,05.02,12.17"
//********************Subroutine: restoreDefaults***
/*
restore factory defaults
*/
void restoreDefaults(){
for (byte i=0;i<78;i++){
if (EEPROM.read(i)!=EEPROM.read(80+i)){
EEPROM.write(i,EEPROM.read(80+i));
}
}
//Set configurations saved in EEPROM
for (byte i=0;i<12;i++){
writeR(i+7,EEPROM.read(i)); //set registers as saved in EEPROM
}
//get Settings-String of EEPROM
for (byte i=12;i<45;i++){
settings[i-12]=EEPROM.read(i); //set settings-string as saved in EEPROM
}
//get limits-String of EEPROM
for (byte i=45;i<78;i++){
limits[i-45]=EEPROM.read(i); //set settings-string as saved in EEPROM
}
}

View File

@@ -0,0 +1,45 @@
/****************************************************
Programmed during 2011-05-02 and 2011-07-29 for the
project ACM1219 as a microcontroller setup for the
ACM1219 interface
Designed and developed by Adrian Beckert
Contact: adrian.beckert@gmx.ch
*****************************************************/
#include <EEPROM.h>
byte values[159]={128,0,75,57,158,0,128,0,77,208,91,37,115,101, //Values to write into the EEPROM
116,67,73,78,32,49,44,48,44,48,52,46,48,44,57,57,46,57,44,48,
44,57,57,46,57,44,57,57,46,57,0,115,101,116,76,73,77,73,84,32,
48,48,46,48,49,44,48,56,46,49,56,44,48,48,46,48,48,44,48,48,46,
48,48,0,0,1,128,0,75,57,158,0,128,0,77,208,91,37,115,101,
116,67,73,78,32,49,44,48,44,48,52,46,48,44,57,57,46,57,44,48,
44,57,57,46,57,44,57,57,46,57,0,115,101,116,76,73,77,73,84,32,
48,48,46,48,49,44,48,56,46,49,56,44,48,48,46,48,48,44,48,48,46,
48,48,0};
void setup(){
Serial.begin(9600);
for (byte i=0;i<158;i++){ //write values in EEPROM
EEPROM.write(i,values[i]);
}
Serial.println("Please check:");
Serial.println("Column 1: Values to write in EEPROM");
Serial.println("Column 2: Values written in EEPROM");
for (byte i=0;i<158;i++){ //print the values written into serial port
Serial.print(i,DEC);
Serial.print(": ");
Serial.print(values[i],DEC);
Serial.print(" ");
Serial.println(EEPROM.read(i),DEC);
}
Serial.println("successful");
Serial.println("Please close the serial port and load the file 'ACM1219_Interface_Rev01' on the Arduino microcontroller");
}
void loop(){
}