Hi. I am using an Arduino Due.
I am trying to monitor the output of an x-ray tube. The x-ray generator is pulsatile, and produces an integer number of x-ray pulses 1/120 s in duration, one after another. My approach is to place a photodiode (I have an OSRAM BPW-34) in the beam and collect and measure the total charge liberated in the photodiode by the x rays. The charge amplifier circuit is shown below:
The op amps are two sides of an LMC6482 IC (datasheet: http://www.ti.com/lit/ds/symlink/lmc6482.pdf). The photodiode is zero-biased. The output of the voltage follower is connected to analog pin A0.
First, to check if the charge amplifier circuit is working as expected, I disconnected the voltage follower output from A0 and connected an oscilloscope probe at that node. I set the generator to give 4 pulses and took a photo of the oscilloscope trace (below). The centre horizontal line is 0V. The trigger level is a little high so the trace starts above 0 V.
The curve looks as expected: the cumulative integral of the pulses. After reaching a maximum voltage (here seen to be about 0.5 V), the voltage decays with a time constant of 1 s. Repeating exposures several seconds apart, the oscilloscope trace had the same shape each time, and consistently reached a max voltage of 0.5 or 0.49x V. This indicates to me that the circuit minus the Arduino works as expected.
Next, I disconnected the oscilloscope probe and reconnected the analog pin. Here is the relevant part of the code for exposure and analog read. The voltage follower output should be sampled by the Arduino just after the peak of the voltage trace.
const int MONITOR_DIODE = A0;
const int EXPOSURE_SWITCH = 24;
// monitor diode value
int diodeVoltage = 0;
// these delays ensure that the exposure switch remains closed for the entire duration of the exposure pulses
const int relayDelayTime = 10; // milliseconds
const int zeroCrossingDelayTime = 9; // milliseconds
// delay timing variables
unsigned long integrationPreviousMillis = 0;
unsigned long integrationCurrentMillis = 0;
void setup() {
pinMode(MONITOR_DIODE, INPUT);
pinMode(EXPOSURE_SWITCH, OUTPUT);
digitalWrite(EXPOSURE_SWITCH, HIGH); // exposure switch is open when high
}
void expose(int integrationTime) { // integrationTime in milliseconds
// close exposure switch for the integration time
digitalWrite(EXPOSURE_SWITCH, LOW);
integrationPreviousMillis = millis();
integrationCurrentMillis = integrationPreviousMillis;
while (integrationCurrentMillis - integrationPreviousMillis < (integrationTime + relayDelayTime + zeroCrossingDelayTime)) {
integrationCurrentMillis = millis();
}
digitalWrite(EXPOSURE_SWITCH, HIGH); // open exposure switch
// read voltage from monitor diode
diodeVoltage = analogRead(MONITOR_DIODE);
}
Assuming the time to execute the digitalWrite() and analogRead() functions is negligible, the time between the actual end of exposure and when the analogRead() function is executed can vary by up to 10 ms (due to the random nature of the zero crossing delay), and so the voltage at the output can vary by up to 1%.
Here are the actual values that the ADC reported, for 20 exposures spaced 5 s apart:
614, 638, 619, 450, 645, 544, 473, 580, 486, 531, 531, 563, 631, 603, 593, 510, 617, 500, 473, 570
or the corresponding voltages (in V):
0.4948, 0.5141, 0.4988, 0.3626, 0.5198, 0.4384, 0.3812, 0.4674, 0.3916, 0.4279, 0.4279, 0.4537, 0.5085, 0.4859, 0.4779, 0.4110, 0.4972, 0.4029, 0.3812, 0.4593
So for some readings it dropped by 75-80% and then jumped back up to the expected range and so on. While I do expect some variation in the x-ray output (which is why I am trying to measure it in the first place), these readings are far too erratic, and the earlier oscilloscope measurements seem to confirm that.
I wondered if perhaps the analog read was perturbing the voltage on the output node so I connected the analog pin and the oscilloscope at the same time. The oscilloscope showed the same consistent shape and max voltage while the ADC reading varied erratically. The oscilloscope voltage decayed slowly but smoothly to 0 after the max voltage was reached, which suggests that the voltage on the output node is not being perturbed by the analog read.
To see if the analog pin is otherwise working as expected, I connected it to +3.3V and it read 4095 every time. I connected it to GND and it read 0 every time. I used a voltage divider (1.2 kOhm and 1 kOhm) and it read 1795 +/- 1 every time. When reading the voltage follower output when there had been no x-ray exposure, the ADC reports a value of 0 every time. So the analog pin does seem to be working properly.
I also tried changing the analog pin and swapping out the op amp. As I saw suggested in some other threads, I tried grounding all of the other analog pins and doing multiple sequential analog reads and keeping the last value.
I am stumped as to what the cause of the erratic reading may be. If anybody has any ideas and possible fixes, I would greatly appreciate it.