Go Down

Topic: Salinity Sensor & Arduino Uno (Read 3840 times) previous topic - next topic

coding1227

I'm trying to connect a vernier salinity probe that I have (http://www.vernier.com/products/sensors/sal-bta/) to my Arduino Uno. I was reading the vernier web site and they say that you can estimate the salinity based on the voltage read by the analog 0 pin (http://www.vernier.com/engineering/arduino/analog-sensors/raw-voltage/). I tried writing a sketch (attached below) that made use of this as well as Arduino's internal voltage reference (as discussed here - http://forum.arduino.cc/index.php/topic,96070.0.html), to which I added a "calibration" (16.3 * sensor_volt) as mentioned in the probe's manual (http://www.vernier.com/files/manuals/sal-bta.pdf).

However, this sketch is giving me odd results. For a solution that has a 8.95 ppt (measuring using a stand-alone salinity probe, which I know that works correctly), my sketch measures:

Analog in reading: 38 - Calculated ppt: 0.15
Analog in reading: 44 - Calculated ppt: 0.18
Analog in reading: 46 - Calculated ppt: 0.18
Analog in reading: 45 - Calculated ppt: 0.18
Analog in reading: 45 - Calculated ppt: 0.18


Any thoughts on what I am doing wrong? Not only are the results quite different from the the independent probe's value, but also they seem to be jumping around quite a bit (due to the changes in the input voltage to my Uno)…

Code: [Select]
int potPin = 0;
float ppt = 0;
float refvoltage = 1.1;

void setup()
{
  Serial.begin(9600);
  Serial.println("Sal sensor ");
  analogReference(INTERNAL);
}

void loop()
{
  int samples = 20;
  int aRead = 0; 

  for (int i = 0; i < samples ; i++)
  {
    aRead += analogRead(potPin);
  }
  float voltage = 5.0 * aRead/ (1023 * samples);  // assuming 5V reference
 
  ppt = 16.3 * voltage;
 
  // convert voltage to pH
  Serial.print("Analog in reading: ");
  Serial.print(aRead);
 
  // print pH value on serial monitor
  Serial.print(" - Calculated ppt: ");
  Serial.println(ppt, 2); // 1 = one decimal, 2 = two decimals (default),etc   // removed the /10
  delay(500);
}

luisilva

#1
Sep 15, 2014, 12:47 am Last Edit: Sep 15, 2014, 06:11 am by luisilva Reason: 1
You have one of 2 things:
1- the wiring is wrong (and you are not reading the output of the sensor);
2- the solution don't have the tds/salinity that you think.

I don't see anything wrong in your sketch.

This lines:
Code: [Select]
 // convert voltage to pH
 Serial.print("Analog in reading: ");
 Serial.print(aRead);

beside the comment that is wrong (maybe from an old project), don't give you a value that can be interpreted. You can do sometging like this:

Code: [Select]

 int samples = 20;
 int aRead = 0;  

 for (int i = 0; i < samples ; i++)
 {
   aRead += analogRead(potPin);
 }
 int aSamples = aRead/ samples;
 float voltage = 5.0 * aSamples/ 1023;  // assuming 5V reference
 
 ppt = 16.3 * voltage;

 // print the mean value read from de CAD
 Serial.print("Analog in reading: ");
 Serial.print(aSamples);


EDIT: Do you have the sensor correct supplied  with 5V. What kind of shield you are using sparkfun or vernier? Take a look to the vernier shield:
http://www.vernier.com/engineering/arduino/connect/breadboard/

The values that you show:
Analog in reading: 38 - Calculated ppt: 0.15
Analog in reading: 44 - Calculated ppt: 0.18
Analog in reading: 46 - Calculated ppt: 0.18
Analog in reading: 45 - Calculated ppt: 0.18
Analog in reading: 45 - Calculated ppt: 0.18

like I said before are meaningless. For example the 44 (from the second reading) is the accumulated value from the 20 samples. If you dived it by 20 it gives you 2,2. If you convert if to voltage (by multiplying by 5 and dividing by 1023) it gives you 0,011V. Converting to TDS (ppt), by multiplying by 16,3  it gives you 0,175ppt. So the math of your sketch is correct. The problem is in the sampling (I guess that is in the supply of the sensor).

coding1227

Hey Luis

thanks for the response. My apologies... I forgot to mention that I am using the vernier "analog proto board adapter" (http://www.vernier.com/products/accessories/proto-board-adapters/bta-elv/), and is connected exactly as mentioned in http://www.vernier.com/engineering/arduino/connect/breadboard/ specifically for the BTA connectors. Indeed, the power source is the 5v power pin available in the Arduino Uno (5v pin in Arduino to 5v in BTA). The other connections are ground (BTA) to ground (Arduino), and Sig1 (BTA) to A0 (arduino).

Below is a sketch that I've been experimenting with. In order to get a more accurate voltage, would it help to try using the ADC?

Sorry if it seems/sounds silly... I am so confused and lost at this point :( Any advice would be really helpful... Thanks!!

Code: [Select]
int potPin = 0;
float ppt = 0;
float refvoltage = 1.1;
unsigned int ADCValue;
double Vcc;

void setup()
{
  Serial.begin(9600);
  Serial.println("Sal sensor ");
  analogReference(INTERNAL);
}

void loop()
{
  Vcc = readVcc()/1000.0;
  int samples = 20;
  int aRead = 0; 

  for (int i = 0; i < samples ; i++)
  {
    aRead += analogRead(potPin);
  }
  int aSamples = aRead/ samples;
  float voltage = 5.0 * aSamples/ 1023;  // assuming 5V reference
    // question: would it be better to use the following?:   voltage = Vcc * aSamples / 1024
   
  ppt = 16.3 * voltage;

  // print the data
  Serial.print("Voltage in: ");
  Serial.print(Vcc,3);
  Serial.print(" Analog in reading: ");
  Serial.print(aSamples);
  Serial.print(" - Calculated ppt: ");
  Serial.println(ppt, 2);
  delay(1000);
}


//Calculate the ADC voltage
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle

  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}

luisilva

The only thing that I remember is that you can try to use a different solution to check the values. I can use a glass with water and the add regular salt. A few stones. Measure the result, then add some more stones of salt, measure the result. You must see the result increasing. If you repeat this a few time you will see the readings going to some place near the 3V. If don't something is wrong or with your connections or with your sensor.

coding1227

yeah... you are right. I see that the values do change as I change the salinity of the solution. I think that it is something related to the calibration value itself. I will have to experiment a bit with this to see if I can get it to work correctly. Thanks for the guidance & suggestions... it was very helpful!

robtillaart


your original code looks good; the divide by 20 should be done in float to prevent rounding errors.

The analogReference (INTERNAL) ==> 1.1 voltage ==> multiply by 1.1 not by 5.0

Code: (not tested) [Select]

int potPin = 0;
float refvoltage = 5.0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Sal sensor ");
}

void loop()
{
  int samples = 20;
  int aRead = 0; 

  for (int i = 0; i < samples ; i++)
  {
    aRead += analogRead(potPin);
  }
  float voltage = refvoltage  * aRead/ (1023 * samples);
 
  float ppt = 16.3 * voltage;
 
  Serial.print("Analog in reading: ");
  Serial.print(aRead);
 
  Serial.print(" - voltage: ");
  Serial.println(voltage , 3);

  Serial.print(" - Calculated ppt: ");
  Serial.println(ppt, 2);
  delay(500);
}


Can you check the voltage from the sensor if that equals the ADC reading of the Arduino?

I'll need to read the PDF to see if the code matches the specs.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

robtillaart

sensor does 0..50 ppt

formula =>  16.3ppt per Volt.

so the max output is  about 3 Volt when measured directly on the sensor.

8.95ppt means something like 0.5V - should be measurable



Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

coding1227

Awesome. Thanks Rob... this will really be of help as I get the voltage measurements and work on the scaling for my values

gideongbuniel

I'm trying to connect a vernier salinity probe that I have (http://www.vernier.com/products/sensors/sal-bta/) to my Arduino Uno. I was reading the vernier web site and they say that you can estimate the salinity based on the voltage read by the analog 0 pin (http://www.vernier.com/engineering/arduino/analog-sensors/raw-voltage/). I tried writing a sketch (attached below) that made use of this as well as Arduino's internal voltage reference (as discussed here - http://forum.arduino.cc/index.php/topic,96070.0.html), to which I added a "calibration" (16.3 * sensor_volt) as mentioned in the probe's manual (http://www.vernier.com/files/manuals/sal-bta.pdf).

However, this sketch is giving me odd results. For a solution that has a 8.95 ppt (measuring using a stand-alone salinity probe, which I know that works correctly), my sketch measures:

Analog in reading: 38 - Calculated ppt: 0.15
Analog in reading: 44 - Calculated ppt: 0.18
Analog in reading: 46 - Calculated ppt: 0.18
Analog in reading: 45 - Calculated ppt: 0.18
Analog in reading: 45 - Calculated ppt: 0.18


Any thoughts on what I am doing wrong? Not only are the results quite different from the the independent probe's value, but also they seem to be jumping around quite a bit (due to the changes in the input voltage to my Uno)…

Code: [Select]
int potPin = 0;
float ppt = 0;
float refvoltage = 1.1;

void setup()
{
  Serial.begin(9600);
  Serial.println("Sal sensor ");
  analogReference(INTERNAL);
}

void loop()
{
  int samples = 20;
  int aRead = 0; 
 
  for (int i = 0; i < samples ; i++)
  {
    aRead += analogRead(potPin);
  }
  float voltage = 5.0 * aRead/ (1023 * samples);  // assuming 5V reference
 
  ppt = 16.3 * voltage;
 
  // convert voltage to pH
  Serial.print("Analog in reading: ");
  Serial.print(aRead);
 
  // print pH value on serial monitor
  Serial.print(" - Calculated ppt: ");
  Serial.println(ppt, 2); // 1 = one decimal, 2 = two decimals (default),etc   // removed the /10
  delay(500);
 }

This works well. Can you explain the variables yo used mr. Programmer?

gideongbuniel

I'm trying to connect a vernier salinity probe that I have (http://www.vernier.com/products/sensors/sal-bta/) to my Arduino Uno. I was reading the vernier web site and they say that you can estimate the salinity based on the voltage read by the analog 0 pin (http://www.vernier.com/engineering/arduino/analog-sensors/raw-voltage/). I tried writing a sketch (attached below) that made use of this as well as Arduino's internal voltage reference (as discussed here - http://forum.arduino.cc/index.php/topic,96070.0.html), to which I added a "calibration" (16.3 * sensor_volt) as mentioned in the probe's manual (http://www.vernier.com/files/manuals/sal-bta.pdf).

However, this sketch is giving me odd results. For a solution that has a 8.95 ppt (measuring using a stand-alone salinity probe, which I know that works correctly), my sketch measures:

Analog in reading: 38 - Calculated ppt: 0.15
Analog in reading: 44 - Calculated ppt: 0.18
Analog in reading: 46 - Calculated ppt: 0.18
Analog in reading: 45 - Calculated ppt: 0.18
Analog in reading: 45 - Calculated ppt: 0.18


Any thoughts on what I am doing wrong? Not only are the results quite different from the the independent probe's value, but also they seem to be jumping around quite a bit (due to the changes in the input voltage to my Uno)…

Code: [Select]
int potPin = 0;
float ppt = 0;
float refvoltage = 1.1;

void setup()
{
  Serial.begin(9600);
  Serial.println("Sal sensor ");
  analogReference(INTERNAL);
}

void loop()
{
  int samples = 20;
  int aRead = 0;  
 
  for (int i = 0; i < samples ; i++)
  {
    aRead += analogRead(potPin);
  }
  float voltage = 5.0 * aRead/ (1023 * samples);  // assuming 5V reference
  
  ppt = 16.3 * voltage;
  
  // convert voltage to pH
  Serial.print("Analog in reading: ");
  Serial.print(aRead);
  
  // print pH value on serial monitor
  Serial.print(" - Calculated ppt: ");
  Serial.println(ppt, 2); // 1 = one decimal, 2 = two decimals (default),etc   // removed the /10
  delay(500);
 }

This works well. Can you explain the variables yo used mr. Programmer?

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy