-
Notifications
You must be signed in to change notification settings - Fork 6
/
AD7746_clean.pde
151 lines (113 loc) · 3.51 KB
/
AD7746_clean.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <Wire.h>
//AD7746 definitions
#define I2C_ADDRESS 0x48 //0x90 shift one to the rigth
#define REGISTER_STATUS 0x00
#define REGISTER_CAP_DATA 0x01
#define REGISTER_VT_DATA 0x04
#define REGISTER_CAP_SETUP 0x07
#define REGISTER_VT_SETUP 0x08
#define REGISTER_EXC_SETUP 0x09
#define REGISTER_CONFIGURATION 0x0A
#define REGISTER_CAP_DAC_A 0x0B
#define REGISTER_CAP_DAC_B 0x0B
#define REGISTER_CAP_OFFSET 0x0D
#define REGISTER_CAP_GAIN 0x0F
#define REGISTER_VOLTAGE_GAIN 0x11
#define RESET_ADDRESS 0xBF
#define VALUE_UPPER_BOUND 16000000L
#define VALUE_LOWER_BOUND 0xFL
#define MAX_OUT_OF_RANGE_COUNT 3
#define CALIBRATION_INCREASE 1
byte calibration;
byte outOfRangeCount = 0;
unsigned long offset = 0;
void setup()
{
Wire.begin(); // sets up i2c for operation
Serial.begin(9600); // set up baud rate for serial
Serial.println("Initializing");
Wire.beginTransmission(I2C_ADDRESS); // start i2c cycle
Wire.send(RESET_ADDRESS); // reset the device
Wire.endTransmission(); // ends i2c cycle
//wait a tad for reboot
delay(1);
writeRegister(REGISTER_EXC_SETUP, _BV(3) | _BV(1) | _BV(0)); // EXC source A
writeRegister(REGISTER_CAP_SETUP,_BV(7)); // cap setup reg - cap enabled
Serial.println("Getting offset");
offset = ((unsigned long)readInteger(REGISTER_CAP_OFFSET)) << 8;
Serial.print("Factory offset: ");
Serial.println(offset);
writeRegister(0x0A, _BV(7) | _BV(6) | _BV(5) | _BV(4) | _BV(3) | _BV(2) | _BV(0)); // set configuration to calib. mode, slow sample
//wait for calibration
delay(10);
displayStatus();
Serial.print("Calibrated offset: ");
offset = ((unsigned long)readInteger(REGISTER_CAP_OFFSET)) << 8;
Serial.println(offset);
writeRegister(REGISTER_CAP_SETUP,_BV(7)); // cap setup reg - cap enabled
writeRegister(REGISTER_EXC_SETUP, _BV(3)); // EXC source A
writeRegister(REGISTER_CONFIGURATION, _BV(7) | _BV(6) | _BV(5) | _BV(4) | _BV(3) | _BV(0)); // continuous mode
displayStatus();
calibrate();
Serial.println("done");
}
void loop() // main program begins
{
// if we recieve date we print out the status
if (Serial.available() > 0) {
// read the incoming byte:
Serial.read();
displayStatus();
}
long value = readValue();
Serial.print(offset);
Serial.print("/");
Serial.print((int)calibration);
Serial.print("/");
Serial.println(value);
if ((value<VALUE_LOWER_BOUND) or (value>VALUE_UPPER_BOUND)) {
outOfRangeCount++;
}
if (outOfRangeCount>MAX_OUT_OF_RANGE_COUNT) {
if (value < VALUE_LOWER_BOUND) {
calibrate(-CALIBRATION_INCREASE);
}
else {
calibrate(CALIBRATION_INCREASE);
}
outOfRangeCount=0;
}
delay(50);
}
void calibrate (byte direction) {
calibration += direction;
//assure that calibration is in 7 bit range
calibration &=0x7f;
writeRegister(REGISTER_CAP_DAC_A, _BV(7) | calibration);
}
void calibrate() {
calibration = 0;
Serial.println("Calibrating CapDAC A");
long value = readValue();
while (value>VALUE_UPPER_BOUND && calibration < 128) {
calibration++;
writeRegister(REGISTER_CAP_DAC_A, _BV(7) | calibration);
value = readValue();
}
Serial.println("done");
}
long readValue() {
long ret = 0;
uint8_t data[3];
char status = 0;
//wait until a conversion is done
while (!(status & (_BV(0) | _BV(2)))) {
//wait for the next conversion
status= readRegister(REGISTER_STATUS);
}
unsigned long value = readLong(REGISTER_CAP_DATA);
value >>=8;
//we have read one byte to much, now we have to get rid of it
ret = value;
return ret;
}