Analog Sensor Resolution Problem

I am reading pressure from to transducers that output a 0 to 1000 PSI mapped to 1 -5 volts. They are connected to my analog pins so that I can read them. The onboard ADC translates that voltage from 0 to 1023 which I map to 0 to 255. That value is sent via a 900mhz xbee to a receiving unit that analog writes it so that a flow computer can map back the value to PSI. The problem is that my resolution factor of 0-255 to 0-1000psi either off ~ -4 PSI on the low end and ~+4 psi on the high end. Meaning the pressure may read 1000 PSI when in actuality it is 996 PSI ect. How do I increase this resolution so that I can accurately go to higher PSI ranges like 10000 PSI?

Sending Unit Code.

int sensorPin5 = A14; // sensor positive lead // 1st transducer
int sensorPin6 = A15; // sensor positive lead // 2nd transducer
// int PinOut = 9; // enable for direct send to flow computer
float sensorValue = 0; // variable to store the value coming from the sensor
float sensorValue1 = 0;
float outputValue = 0;
float outputValue1 = 0;
byte packagedData = 0;

void setup() {

Serial1.begin(9600);
}

void loop() {
sensorValue = analogRead(sensorPin5);//Reads from the sensor transducer 1
if(sensorValue < 190){
sensorValue = 190;  //baseline for 0 PSI from transducer
}
outputValue = map(sensorValue, 190, 1023, 0, 255);//scaling algorithm to create sendable value

// analogWrite(PinOut, outputValue); // enable this line to send directly to flow computer
Serial1.print("<PSI,");
Serial1.print("1,");
Serial1.print(outputValue);
Serial1.println(">");
//Serial1.write(outputValue); //Sends to the Xbee from 1st transducer
delay(2500);

sensorValue1 = analogRead(sensorPin6);//Reads from the sensor transducer 2

if(sensorValue1 < 190){
sensorValue1 = 190; //baseline for 0 PSI from transducer
}

outputValue1 = map(sensorValue1, 190, 1023, 0, 255);//scaling algorithm to create sendable value
Serial1.print("<PSI,");
Serial1.print("2,");
Serial1.print(outputValue1);
Serial1.println(">");
//Serial1.write(outputValue); //Sends to the Xbee from 2nd transducer
delay(2500); //Delay 

}

Receiving Unit Code

int led = 3;
int ledOn = 255;
int ledOff = 0;
const byte numChars = 18;
char receivedChars[numChars];
char tempChars[numChars]; //temporary array for parsing

//variables to hold new data
char messageFromPC[numChars]= {0};
int integerFromPC=0;
float floatFromPC = 0.0;
boolean newData = false;
int PinOut9 = 9;
int PinOut10 = 10;
void setup(){
Serial.begin(9600);
pinMode(led, OUTPUT);

/* Debugging Code for Monitor
Serial1.begin(9600);
Serial.println("<Sensor Gather Begin>");
*/
}

void loop(){
recvWithStartEndMarkers();
if (newData == true){
strcpy(tempChars, receivedChars); //this temp copy is necessary to protect original data becuase strtok() used in parsedata() replaces commas with \0
parseData();
showParsedData();
newData = false;
}


}

void recvWithStartEndMarkers(){
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;

while (Serial.available() > 0 && newData == false) {

rc = Serial.read();

if (recvInProgress == true) {
if (rc != endMarker){
receivedChars[ndx] = rc;
ndx++;
if (ndx >=numChars){
ndx = numChars -1;
}
}
else{
receivedChars[ndx] = '\0'; //terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if(rc == startMarker){
recvInProgress = true;
}
}
}
void parseData(){ //splits the data into parts
char * strtokIndx; //this is used by strtok() as a index
strtokIndx = strtok(tempChars,","); //get first part- the string
strcpy(messageFromPC, strtokIndx); //copys the string to messageFromPC
strtokIndx = strtok(NULL,","); //this continues where the previous call left
integerFromPC = atoi(strtokIndx); //converts this part to integer
strtokIndx = strtok(NULL,",");
floatFromPC = atof(strtokIndx); // converts this part to a float
}
void showParsedData(){
if (integerFromPC == 1){
analogWrite(PinOut9, floatFromPC); 
analogWrite(led, ledOn);
}
else if (integerFromPC == 2){
analogWrite(PinOut10, floatFromPC);
analogWrite(led, ledOff);
}
/* Debugging Code for Monitor
Serial.print("Device ");
Serial.println(messageFromPC);
Serial.print("ID ");
Serial.println(integerFromPC);
Serial.print("Value ");
Serial.println(floatFromPC);
*/
}

you do realise that you are decreasing the resolution by mapping 0-1023 to 0-255.

for a range of 0-1000PSI,

with 0-255 its basically 4PSI resolution.

if you could used 0-1023 the resolution then is approx 1PSI!

my suggestion would be to not use the mapping to 0-255 at all and transmit the 0-1023 range instead

How do I increase this resolution so that I can accurately go to higher PSI ranges like 10000 PSI?

Typically, you'd use a different transducer. One that was compatible with the range of pressures you want to measure.

outputValue = map(sensorValue, 190, 1023, 0, 255);//scaling algorithm to create sendable value

You pass a float to a function that expects an integer value. Why?

You store the integer value that it returns, in the range of 0 to 255, in a float. Why?

Why are you mapping the value, anyway? You are sending the data in ASCII format to the other device. It makes no sense unilaterally losing precision doing that.

strcpy(tempChars, receivedChars); //this temp copy is necessary to protect original data becuase strtok() used in parsedata() replaces commas with \0

But, there is no need to retain a good copy of the data. So, quit wasting resources making a copy of it.

In that code I switched my variables from a byte to a float just to see if it made a difference. Also, I was under the impression that the analogWrite function could only send 0-255 as a 1 -5volt representation. Do you have a suggestion as to what I should do different? Also the transducers I use can be scaled internally from 0 to 10000 psi. I had them dialed back while testing because I didn't have enough pressure on a test tank to test that high.

Don't use the analog pins. Use serial.

sgt_willy:
Also, I was under the impression that the analogWrite function could only send 0-255 as a 1 -5volt representation. Do you have a suggestion as to what I should do different?

There is nothing in

That value is sent via a 900mhz xbee to a receiving unit that analog writes it so that a flow computer can map back the value to PSI.

that implies that there is an Arduino involved on the other end of the XBee network. So, no one but you jumped to the conclusion that the receiver was constrained to 0 to 255 values.

Try mapping to 256.

I apologize for the lack of clarity Paul. I created this post in hope that you would respond because it seems that you have a very strong knowledge of the capabilities of these controllers. Knowing the information you have now, is there solution that I can implement?

I think I figured out a solution. I have a Adafruit MCP4725 DAC, which is 12-bit. That should give me a 0-4096 resolution instead of the on-board 8-bit DAC the Arduino sports.

Which is a large part of the confusion. There is no "8 bit DAC" on the Arduino, it is a PWM output.

Why can't you forgo the analog to analog conversion and just send text?

Your receiver contains this code:

int integerFromPC=0;
...
integerFromPC = atoi(strtokIndx); //converts this part to integer

Look up the documentation for the atoi() function. It's a standard C library, so it's not specific to the Arduino. What happens when you send it "255" as an input? What happens when you send it "1023"? It will work equally well with both numbers. Therefore the sender doesn't need to map its output to 0-255.

When you are working with this precision, you need to be really careful with the analog signals. Make sure that the sensor and the Arduino doing the analogRead() are both using the same 5V power supply as the reference voltage.

I can send text between the arduinos that is fine but I am analogwriting to the flow computer from the receiving arduino. I was using the pwm output emulate a dac. I am having a hard time explaining this setup. But it works for my purpose, I just need more resolution. I keep recieving professional criticism as to my methods, but I am only a amateur at this and was requesting guidance instead.

Thanks Morgan I will look into that. I am using the same voltage for the arduino and the sensor. So that is a plus.

From my point of view it sounded like you were converting the pressure sensor voltage into an analog signal that you were zigbeeing to the other arduino.

Since that does not seem to be the case, the 12 bit DAC would be a good choice.

Meh, I learned a long time ago not to take things personal on these forums. I was passing a observation not a judgment. I just want to find a solution to my problem. Worst case I pay someone. Sorry you took it that way.