Hi, I'm trying to read Analog AI3 to sample a voltage input from my Geophone hardware. However, when I write to digital port 2 just before I sample the analog voltage on AI3, the reading is always 4.9 volts. If I comment out the DigitalWrite(Pin2,HIGH) before the analog read the reading is normal. Are these lines tied together or something? I'm trying to turn on an LED to indicate that the hardware is reading/measuring Analog Input 3. Could anyone let me know why the digital port write is effecting the Analog input reading.
Thanks guys, here is the stripped down version of the polling code with the problem. I'm trying to create a mobile seismograph unit that logs data to an SD card on an Ethernet shield. This will allow me to ping the Ethernet shield for a CSV file to populate my Highcharts graph with the Seismic activity on a webpage. I have all the data logging and graphing code working find. I'm just struggling with controlling the LED on a pin 2 while reading Analog port 3 (Analog port 3 just reads 4.9 volts after the LED port is set High, shouldn't these ports be independent of each other). I'm using a circuit that I put together on a Proto shield that sits on top of the Ethernet shield, it works great for Geophones. It's attached below. The output of the circuit is what is tied to Analog pin 3. This circuit allows the geophone to pulse +/- from a 2.5 volt center and never going below 0 volts.
const int LEDIOPin = 2; // LED status pin
const int iAnalogRdAvgCnt = 4; // number of analog samples to average
static double dPrevSample= 2.5; // set to 2.5V center voltage
static double dSeismicDataLogTrigger= 15; // % of change to trigger quick recording
void setup() {
// open a serial connection
Serial.begin(9600);
pinMode(LEDIOPin, OUTPUT);
digitalWrite(LEDIOPin, LOW);
}
////////////////////////////////////////////////////////////////////////////////////////////////
// Read/Average analog measurement data
// iSampleCnt - Number of samples to average.
// Returns - averaged analog voltage.
////////////////////////////////////////////////////////////////////////////////////////////////
double ReadAnalogPort( int iSampleCnt )
{
double dCurSample= 0;
analogRead(3); // throw away first reading
for(int x=0; x<iSampleCnt; x++)
{
delay(10); // allow switching time
dCurSample += (double)(analogRead(3)*(5.0 / 1023.0)); // get sample voltage
}
return( (dCurSample / iSampleCnt) ); // Return averaged reading
}
void loop() {
double dCurSample= 0.0;
// Test analog voltage for data logger trigger
dCurSample = ReadAnalogPort(iAnalogRdAvgCnt); // get sample voltage (Avg 4 samples)
Serial.print("CurVoltage=");
Serial.println(dCurSample);
double dSampleDiff = (double)((abs(dPrevSample-dCurSample)/(double)4.9)*100); // get sample delta Max DAC Range = 4.3v
Serial.print("SampleDiff%=");
Serial.println(dSampleDiff);
if( dSampleDiff >= dSeismicDataLogTrigger ) // Triggered, Log data for x amount of time?
{
digitalWrite(LEDIOPin, HIGH); // Turn on LED to indicate data logging
// The problem occurs here after setting the digital port high, The analog read will just report 4.9 volts on AI3.
unsigned long ulRecStartTime = millis();
while( millis() - ulRecStartTime < 15000 ) // record x amount of data (15 sec)
{
// create data record
dCurSample = ReadAnalogPort(iAnalogRdAvgCnt); // get sample voltage (Avg 4 samples)
Serial.print("CurVoltage=");
Serial.println(dCurSample);
}
digitalWrite(LEDIOPin, LOW); // Data logging complete, turn off LED
}
dPrevSample = dCurSample;
delay(100); // delay in between polls
}
Moderator edit: The usual - CODE TAGS. Why is it so hard?
The digital output dose not affect the analogue input unless they are in some way connect outside the chip. So that is not your problem.
The code does show somewhat a lack of understanding. There is no need for any delays before the analogue read nor is ther need to read it twice as you are not using a high impedance voltage source and are not switching between input channels. The data type double is the same size as float on this machine so there is no need to use it. You have a float divided by an int in the return of the read. Cast the int as a float and see if it helps.
A proper schematic would help, that is one that shows the correct symbols for the components you are using.
There needs to be a protection resistor in series with the analog output from the 741
opamp, otherwise it can drive the Arduino's analog pin below 0V and destroy it, which
may be part of the problem.
No Arduino pin can tolerate being driven below -0.5V or above Vcc+0.5V, damage will
occur if enough current flows in this situation (the tiny protection diodes will cook,
basically).
Its not clear if the opamp involved is a 741 but if so that's a terrible circuit. The uA741
was state of the art five decades ago, it is most definitely nothing like state of the art
these days. It really needs at least +/-10V to work well in fact. A modern rail-to-rail
opamp will typically outperform it in every department and run from a single 5V supply.
Bear in mind that the Arduino doesn't have a hardware FPU, so all floating point math is done in software, and is pretty slow. Will this matter for this particular program? Maybe not. But it's good practice to get out of the habit of using floating point math on the Arduino whenever possible.
Mathematically, these produce the same result. There may be some small rounding error, but realistically, it'll probably work perfectly fine. Likewise, a common way of taking a percent is:
float percent = 0.75;
int value = 12345;
value = (float)value * percent;
Thanks for the input. I will change the code to not use double precession math, but I believe that is not the problem here. If I remove the digitalWrite call to set pin 2 High, all is well and the analog read on pin3 works great with accuracy. Therefore the double precision usage might be slower as you have suggested but this doesn't really effect the symptom I'm see with reading the analog port after writing to the digital port =) I noticed with the UNO hooked up to Labview and the Labivew code loaded in the UNO, If I change my VI to do almost exactly what I'm doing within my .ino code, it nets the same results. I'll have to keep playing around with the code and see if I can find a work around for this issue.
MarkT, just so you know this circuit I'm using does not produce negative voltages. The center voltage output with the geophone idle is 2.5V and when the geophone cylinder moves up/down, the voltage output of the circuit pulses above and below the 2.5 Ref, but never below 0 volts. The o-scope never lies =) Btw, this circuit might not be the best design for the 21 Century as you noted, but it's one the best circuits I've found to handle a 0-5V range without reporting negative voltages and works well with the UNO. I have tried a lot of different circuits and this has been the best and most sensitive one for my application. If you have better design for geophones, I'd sure like to see it and try it =) The design I'm using comes from here which is the best I've seen available on the Web http://web.ics.purdue.edu/~braile/edumod/educseis/educseis.htm
Thanks again all for your opinions. Hopefully, I'll discover a solution here soon =)
Btw, this circuit might not be the best design for the 21 Century as you noted, but it's one the best circuits I've found to handle a 0-5V range without reporting negative voltages and works well with the UNO.
You can't use a 741 on just a single 5V rail, it is not enough voltage.
A real schematic will allow us to help you better and a photo of your wiring.
Actually, I just found the issue. Don't really understand why I guess, but I moved the LED GND line to the dedicated GRN pin on the Analog Input side of the UNO and it works perfectly now. The ground reference I was using was the GRN pin bar on the end of the proto board where I had all the components on the proto board grounded to. For some reason isolating these grounds resolved the analog read issue after changing the state of the digital port High =)
Mike, the schematic is here as I posted earlier if you want to look at it. http://web.ics.purdue.edu/~braile/edumod/educseis/educseis.htm I would greatly appreciate any tested design changes or even a different design that would be sensitive like this has been.