Buzz
« Making the Arduino Speak SPI (and talk to a BlackFin) | Main | Arduino and the SeaWolf III Part II (Serial Interfacing in C) »
Wednesday
Feb182009

Arduino and the SeaWolf III (Pressure/Depth Sensing)

Due to the ability to get a rapid working prototype I've settled on using an Arduino to act as an ADC (analog to digital converter) for the pressure (depth) sensor, status lights and the altimeter will be incorporated into the SeaWolf III design. I'm still working on getting assurances from my team that it's alright to post my source code as I more forward with this, but I'll divulge what information I'm currently feeling comfortable with. The pressure sensor is the only part we currently have but I'll be giving updates on the rest of it as it's designed.

Currently we're using the standard Arduino Decimelia but I've got 2 ReallyBareBonesBoards in the mail that I'll be adapting to more specifically fit our needs once they arrive. Our pressure sensor, the MSP 600-025-P-N-1 Transducer from MSI Sensors, already acts as a resistive load and therefore doesn't need the usual resistor being placed between in the circuit. The pressure sensor conveniently operates between .5V and 4.5V giving meaning It's not going try to blow my Arduino's ADC. Also conveniently it takes a 5V power source so the Vout pins on the Arduino will work perfectly. This leaves us with a nice simple circuit, red to the 5V, black to the ground, and white to analog pin 1. The "025" section of the part number indicates a 25PSI sensor.

(simple sketch coming)

Now... the fun part, how to use that incoming data? Firstly, given that the ADC of the Arduino is based on a voltage change of 5V, this gives us a bit of a snag we won't be using the top or bottom of this range. The digital values returned by the Arduino range from 0-1023 or a range of 1024. Since we are only using .5V to 4.5V we need to determine what the expect range of return values is. A little bit of algebra yields (1024/5) * .5 = 102.4. This is the range of values lost per each .5V that aren't being used. Therefor we're loosing 2 times this value worth of possible return values or 208.8 return values. Therefor the operable range of of our sensor will be roughly 102 to 921 this needs to be taken into consideration when writing out algorithms to deal with the input. The remaining range is 819 values this is important for writing an algorithm to interpret the data.

From the data sheet found above we can find the number of values per PSI. 819/25 = 32.76. In freshwater 2.31 ft will yeild 1 PSI. Using these two values we can find an algorithm for determining the depth given the analog input. 2.31*AnalogIn/819 = Depth in Ft. This assumes that the initial value of the sensor input would be 0 which isn't initally the case but the offset algorithm described below does a decent job of eliminating the 102 value offset that the above calculations indicate we would need to take into account.

For the purpose of the seawolf we'll need this sensor to zero out when at a depth of 0 feet. To tackle this I used a running sum algorithm. (as an aside.. due to some stupidity when creating the initial algorithm I used an array to place the values in and sumed them... just as a note... don't do that.) I suppose now would be a good time for a little code; using the Arduino IDE, getting an analog value back from a ADC is a breeze. Just as simple as analogRead(pin#).

#include <stdio.h>
#define pressure_in 0 //input put for the pressure sensor.
#define status_LED 13 //status lirght pin for testing purposes.

double pressure_offset; //initializes the pressure_offset varaible, this is used later

void setup() {

Serial.begin(9600); // set up Serial library at 9600kbps
Serial.println("Pressure Sensor Readout"); //for serial make it look pretty purposes, can be commended out.
pressure_offset = OffSet(); // builds the pressure offset from an average of 40 inputs (below main loop)

}


void loop()

double pressure;
double depth;
double altimeter;
double AnalogIn;

//takes in the pressure and offsets.
AnalogIn = analogRead(pressure_in)-pressure_offset;
//Depth calculating algothim, 2.31 PSI per foot of water, 32.76 points analog in per PSI.
depth = 2.31*AnalogIn/32.76;
//Arduino doesn't support float printing, see algorithm below.
printFloat(depth);
//choke down the massive ammounts of serial data spamming.
delay(500);
Serial.print("\n");

}

double OffSet(){

int i; //iteration counter
double sum; // where we put the value to be returned
for(i=0; i<40; i++){
sum += analogRead(pressure_in); //does the running sum for 40 values
}
return sum/40.0; // return the average

}


void PrintFloat( float f){

Serial.print((int)f); //print the non decimal portion
Serial.print("."); //print the decimal
int tmp = (f - (int)f) * 100; //print 2 decimals of the fractional part
Serial.println( abs(tmp) );

}

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
All HTML will be escaped. Hyperlinks will be created for URLs automatically.