Hi,
Can someone tell me if I can use arduino for SBE 3s sensor? (http://www.seabird.com/sbe3s-temperature-sensor)
It's a temperature sensor with frequency output..
The low noise characteristics of the SBE 3S allow the use of hybrid frequency measuring techniques to obtain rapid sampling with very high resolution; 40 μ°C resolution can be readily obtained at a 6 Hz sampling rate.
Yes you can read the frequency, but not very accurately.
The CPU clock on the Arduino is not accurate and drifts substantially with temperature.
Depending on how you read the input, there will be timing jitter.
Basically, using an Arduino would throw away a large part of the measurement precision and accuracy that you paid for, and unless you have a separate, precise frequency standard for comparison, the answer would be wrong.
That SBE 3S accuracy is going to be difficult to match. The ATMega328p does have capture hardware (ICP1), which is what you need to measure it. However, the Uno's ceramic resonator is not very accurate, so you need to find someone with an ATMega328 board that has a crystal or even better make your own board with a TCXO.
OK!
So ArduinoUno has only one port for high speed timer? ICP1
Because another sesnsor I have is SBE-4 for measuring conductivity and it also work with frequency output..
The Idea was to make a cheap board for extra expensive transducers to measure temperature and conductivity and send those measured datas over ethernet to PC or other boards...
"have in mind that I have no experience with microcontrollers so some question will look strange to you"
Again, how accurately and precisely do you want to know the temperature? If you use the Arduino to read that device, plan on the process adding at least 1% error.
My idea is to count (frequency) on pin interrupt.. so when I receive a +5V on input the interrupt is executed and counter is incremented...
The calculation of frequency is then calculated in timerinterrupt where also a local variable will be setted with frequency for temperature and conductivity (I have both SBE 3 and SBE 4 sensors)
The problem with using an interrupt is that it can take quite a few clocks before the interrupt code starts to run, at which point the code can then transfer a timer (which did not stop running) to some other register. The ICP hardware immediately captures a timer (e.g. ICP1 captures timer1), and then an interrupt starts so you can do what you want with the captured time. It is not what I would call high speed, but it can be as accurate as the system clock. You have to get a few captures to build the full accuracy. To measure a 7kHz square wave the captured timer counts are offset by about 2,285. If the timer is driven by a 10ppm crystal then capturing 44 of those events should be about equal to the crystal accuracy. The counts in 44 such sensor events repeated add up to 100,540. And 16,000,000*44/100,540 can be reported with five significant digits (e.g. 10ppm) as 7002.2Hz (well that is my understanding anyway).
The ATMega328pb has ICP1, ICP3, and ICP4, but I don't think it is in GCC yet, you would have to use Atmel Studio to work with it. The ATMega1284p has ICP1 and ICP3 and there are a few boards you can find that work with the Arduino.cc IDE.
Hi,
I'am back with my project so I need some help or idea from you (I have only basic knowledge)..
Here is my program to measure frequency from SBE3 sensor..
How it works...
I have a Timer interrupt set to 1 second (I think please correct).
Then I have two pin interrupts declared..
When a signal is present on pin the method attached to interrupt is executed (in this case a counter is incremented by 1)..
When a timer interrupt is executed the booblean flag is set to true... so in the main loop I can verify for this flag and when is true the temperature is calculated with calcTemp method...
I'am not sure if timer interrupt is exactly one second.. (must verify if quartz is 12Mhz or 16Mhz (i thing is 12Mhz...)..
#include <SPI.h>
#include <Ethernet.h>
#include <Math.h>
//mac adresa ethernet-a
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
//to bom porebral iz conf datoteke na SD kartici
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
const byte interruptPinTemp = 2;
const byte interruptPinSlanost = 3;
//konstante za SBE-3
const double g = 4.85442486e-003;
const double h = 6.77300393e-004;
const double i = 2.65502731e-005;
const double j = 2.06782794e-006;
const double f = 1000.0;
volatile int cnt = 0;
volatile int cnt1 = 0;
volatile double slanost = 0;
volatile double slanost1 = 0;
int timer1_counter;
boolean bData = false;
volatile int dvesek = 1;
void setup() {
Serial.begin(9600); // inicializacija serijskega porta
noInterrupts(); // disable all interrupts
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
pinMode(interruptPinTemp, INPUT_PULLUP);
pinMode(interruptPinSlanost, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPinTemp), beriTemperatura, CHANGE);
attachInterrupt(digitalPinToInterrupt(interruptPinSlanost), beriSlanost, CHANGE);
TCCR1A = 0;
TCCR1B = 0;
timer1_counter = 34286; // preload timer 65536-16MHz/256/2Hz
TCNT1 = timer1_counter; // preload timer
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
interrupts();
}
//Timer interrupt na 1 sekundo
ISR(TIMER1_OVF_vect) // interrupt service routine
{
TCNT1 = timer1_counter; // preload timer
if (dvesek++ == 2)
{
cnt1 = cnt / 2 ; // prepisemo vrednost v cnt1
bData = true; // postavimo flag
cnt = 0;
dvesek = 1;
}
}
void loop() {
// če je postavljen flag, da so podatki jih izpišemo ali naredimo karkoli drugega
if (bData == true)
{
bData = false;
Serial.println(calcTemp(cnt1), 3);
}
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 1"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>Temperatura na tipalu:");
// output the value of each analog input pin
client.print(calcTemp(cnt1), 3);
client.println("
");
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
void beriTemperatura() {
cnt++;
}
void beriSlanost() {
slanost++;
}
//funkcija preračuna iz frekvence temperaturo
double calcTemp(double frekvenca)
{
double logRes = log(f / frekvenca);
return 1.0 / (g + (h * logRes) + (i * pow(logRes, 2.0)) + (j * pow(logRes, 3.0))) - 273.15;
}
No .. I don't have trouble to understanding this.. I just wan't to use some "cheap" device to read frequency...Is there some other "board" to do this? (not expensive? and easy - modular as arduino?)
If you can afford that particular sensor ($1700 in 2004) and need the high accuracy provided by it, then you can afford the device needed to accurately read the output frequency.