Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Achim Morschhauser
GeomagLogger
Commits
19c38b28
Commit
19c38b28
authored
Oct 25, 2018
by
Achim Morschhauser
Browse files
Merge branch 'master' into testrasp
parents
cc947d62
0b26e80b
Changes
7
Hide whitespace changes
Inline
Side-by-side
m
akefile
→
M
akefile
View file @
19c38b28
SRC_DIR
=
./src/
OBJ_DIR
=
./lib/
HDR_DIR
=
./include/
SRC_DIR
=
src/
OBJ_DIR
=
lib/
HDR_DIR
=
include/
LIB_DIR
=
./lib/
USR_DIR
=
./
usr/
BIN_DIR
=
./
bin/
USR_DIR
=
usr/
BIN_DIR
=
bin/
#--------------------------------------
#--------------------------------------
...
...
@@ -18,7 +19,7 @@ CCFLAGS=-g -lrt -std=c++11 -pthread
EXCL
=
driver_serial_emulate.o
# Uncomment to use virtual serial port. Run 'make clean all' afterwards
#
EXCL=driver_serial.o
EXCL
=
driver_serial.o
.SECONDARY
:
...
...
@@ -28,12 +29,17 @@ all: $(USR_TARGET:%=$(BIN_DIR)%)
@
echo
----
DONE
----
$(BIN_DIR)%
:
$(filter-out $(OBJ_DIR)$(EXCL)
,
$(OBJ_FILES)) $(USR_DIR)%.cpp
$(CC)
$(CCFLAGS)
-o
$
(
@
)
$^
-I
./include/
$(BIN_DIR)%
:
$(USR_DIR)%.cpp $(LIB_DIR)libLogger.so
$(CC)
$(CCFLAGS)
-no-pie
$<
-o
$@
-I
$(HDR_DIR)
-L
$(LIB_DIR)
-Wl
,-rpath,
"
\$
$ORIGIN
/../
$(LIB_DIR)
"
-lLogger
# $(CC) $(CCFLAGS) $< -o $@ -I$(HDR_DIR) -L$(LIB_DIR) -lLogger
$(OBJ_DIR)%.o
:
$(SRC_DIR)%.cpp
$(CC)
$(CCFLAGS)
-c
-o
$@
$<
-I
$(HDR_DIR)
$(CC)
$(CCFLAGS)
-fPIC
-c
-o
$@
$<
-I
$(HDR_DIR)
$(LIB_DIR)libLogger.so
:
$(filter-out $(OBJ_DIR)$(EXCL)
,
$(OBJ_FILES))
$(CC)
$^
-shared
-o
$@
clean
:
rm
$(BIN_DIR)
*
rm
$(OBJ_DIR)
*
rm
-f
$(BIN_DIR)
*
rm
-f
$(OBJ_DIR)
*
rm
-f
$(LIB_DIR)
libLogger.so
include/Driver_Obs_Serial.hpp~
deleted
100644 → 0
View file @
cc947d62
/*
* Driver_Obs_Serial.h
*
* Created on: May 12, 2016
* Author: mors
*/
#ifndef INCLUDE_DRIVER_OBS_SERIAL_HPP_
#define INCLUDE_DRIVER_OBS_SERIAL_HPP_
#include <driver_serial_emulate.hpp>
//#include <driver_serial.hpp>
#include <driver_obs.hpp>
class Driver_Obs_Serial: protected driver_obs {
//
// Private class variables
//
/** The serial driver to use */
private: driver_serial_emulate serial;
//private: driver_serial serial;
//
// Constructors
//
public:
/** Constructor with baud rate */
Driver_Obs_Serial(std::string port, buffer_obs* buffer);
/**
* Constructors of derived classes must call set_term(term,termlen)
* and set_baud(const char* init_char) or set_baud(int baud).
*/
//
// Public Methods
//
/** Take a single measurement. An object data_obs with the timestamp is returned.
This method must be implemented as specified in the abstract class driver_obs */
public: virtual int get(data_obs* data)=0;
/** Take continuous measurement in triggered mode */
public: virtual int run(int freq)=0;
/** Take continuous measurement in freerun mode */
public: virtual int freerun(int freq)=0;
/** Stop continuous measurements */
public: virtual int stop()=0;
//
// Private Methods
//
protected:
/** Receive raw from serial port without time information. */
virtual int receive_raw(char *buf, int buflen, double timeout);
/** Receive from serial port without time information. */
virtual int receive(char *buf, int buflen, double timeout);
/** Receive from serial port with time information. */
virtual int receive(char *buf, int buflen, double timeout,
struct timespec *recv_time);
/** Send a command to the serial port. */
virtual int send(const char* cmd);
/** Send a command to the serial port. */
virtual int send(char* cmd);
/** Flush the buffer of the serial port. */
virtual int flush();
/** Initialize the instrument with automatic determination of the baud rate */
virtual int set_baud(const char* init_char);
/** Initialize the instrument with given baud rate */
virtual int set_baud(int baud);
/** Set the termination characters. */
virtual int set_term(const char* term,int termlen);
};
#endif /* INCLUDE_DRIVER_OBS_SERIAL_HPP_ */
include/driver_obs.hpp
View file @
19c38b28
...
...
@@ -32,6 +32,9 @@ buffer_obs* buffer;
/** The calibration constants of the instrument */
Obs_Calibration
*
cal
;
/** The selected sampling frequency */
double
freq
;
//
// Public Methods
//
...
...
include/driver_obs_obsdaq.hpp~
deleted
100644 → 0
View file @
cc947d62
/********************************************************************************
* WRITTEN BY ACHIM MORSCHHAUSER, GFZ POTSDAM, April 2016 *
* mors//gfz-potsdam.de *
* *
* This class provides the driver for an OBSDAQ ADC. *
* *
* It is based on the abstract observatory driver class driver_obs. *
* *
********************************************************************************/
#ifndef _DRIVER_OBS_OBSDAQ_H
#define _DRIVER_OBS_OBSDAQ_H
#include <string>
#include <Driver_Obs_Serial.hpp>
#include <data_obs_vector.hpp>
#include <data_obs.hpp>
#include <buffer_obs.hpp>
class driver_obs_obsdaq : protected Driver_Obs_Serial
{
//
// Private class variables
//
private:
/** The address to use (RS-485) */
int RS485_addr;
std::string RS485_addrstr;
/** The quartz crystal frequency */
int quartz_freq;
//
// Constructors
//
/** Standard constructor */
public: driver_obs_obsdaq(std::string port, buffer_obs* buffer);
/** Standard constructor */
public: driver_obs_obsdaq(std::string port, buffer_obs* buffer, int addr);
/** Standard constructor */
public: driver_obs_obsdaq(std::string port, buffer_obs* buffer, int baud, int addr);
//
// Public Methods
//
public:
/** Take a single measurement. An object data_obs with the timestamp is returned.
This method must be implemented as specified in the abstract class driver_obs */
int get(data_obs* data);
/** Take a single measurement and return all data */
int get(data_obs_vector* data);
/** Take continuous measurement in triggered mode */
int run(int freq);
/** Take continuous measurement in freerun mode */
int freerun(int freq);
/** Stop continuous measurements */
int stop();
//
// Private Methods
//
private:
/** Send an OBSDAQ-type command to address of RS-485 serial port */
int send(const char* cmd);
/** Send an OBSDAQ-type command to address of RS-485 serial port, check and get response */
int checked_send(const char* cmd, const char* reply, int digits, double timeout,
std::string* recv);
/** Send an OBSDAQ-type command to address of RS-485 serial port and check response */
int checked_send(const char* cmd, const char* reply, int digits, double timeout);
/** Initialize the instrument */
int init();
protected:
/** Set the termination characters for serial comm. */
int set_term();
};
#endif /* _DRIVER_OBS_OBSDAQ_H */
src/data_obs.cpp
View file @
19c38b28
/*******************************************************************************
*
* WRITTEN BY ACHIM MORSCHHAUSER, GFZ POTSDAM, April 2016
*
* mors//gfz-potsdam.de
*
*
*
* This class provides a container for observatory data.
*
* It can store only timestamping data, but may be extended to store more data.
*
* For example, see the classes data_o
l
bs_scalar and data_obs_vector.
*
*
*
******************************************************************************
**
/
/*******************************************************************************
* WRITTEN BY ACHIM MORSCHHAUSER, GFZ POTSDAM, April 2016
*
* mors//gfz-potsdam.de
*
*
*
* This class provides a container for observatory data.
*
* It can store only timestamping data, but may be extended to store more data.*
* For example, see the classes data_obs_scalar and data_obs_vector.
*
*
*
******************************************************************************/
// C++ Headers
#include
<iomanip>
// For parsing strings
...
...
src/driver_obs_obsdaq.cpp
View file @
19c38b28
...
...
@@ -101,9 +101,6 @@ driver_obs_obsdaq::driver_obs_obsdaq(std::string port, buffer_obs* buffer,
// Set the ObsDAQ baud rate
// Stop the measurement
stop
();
// Initialize
init
();
...
...
@@ -261,7 +258,7 @@ int driver_obs_obsdaq::run(double freq) {
/****************************************************************************
* *
* Run the OBSDAQ in freerun mode (no triggering).
*
* Run the OBSDAQ in freerun mode (no triggering). *
* *
***************************************************************************/
int
driver_obs_obsdaq
::
freerun
(
double
freq
)
{
...
...
@@ -278,6 +275,9 @@ int driver_obs_obsdaq::freerun(double freq) {
data_obs_vector
data
;
// The receive buffer
char
buf
[
200
];
// Data parser function
int
(
driver_obs_obsdaq
::*
parse_data
)(
data_obs_vector
*
data
,
char
*
buf
);
//std::function<int(data_obs_vector* data, char* buf)> &parse_data;
/////////////////////////////////////////////////////////////////////////
//
...
...
@@ -301,10 +301,20 @@ int driver_obs_obsdaq::freerun(double freq) {
send
(
"#PP00000000"
);
usleep
(
2e5
);
// Use ASCII mode
//checked_send("#CS","",0,1);
// Use binary mode
checked_send
(
"#CS"
,
""
,
0
,
1
);
// Flush
usleep
(
1e6
);
flush
();
if
(
freq
<
10.0
){
// Use ASCII mode
checked_send
(
"#CS"
,
""
,
0
,
1
);
parse_data
=
&
driver_obs_obsdaq
::
parse_data_ascii
;
}
else
{
// Use binary mode
checked_send
(
"#CB"
,
""
,
0
,
1
);
parse_data
=
&
driver_obs_obsdaq
::
parse_data_bin
;
}
/////////////////////////////////////////////////////////////////////////
//
...
...
@@ -327,12 +337,10 @@ int driver_obs_obsdaq::freerun(double freq) {
data
.
set_time
(
&
recv_time
);
// Parse data from answer
if
(
(
this
->*
parse_data
)(
&
data
,
buf
)
>=
0
){
if
(
parse_data_ascii
(
&
data
,
buf
)
>=
0
){
//parse_data_ascii(&data, buf);
// Calibrate the measurement/ASCII
driver_obs
::
cal
->
calibrate
(
&
data
);
// Calibrate the measurement/ASCII
driver_obs
::
cal
->
calibrate
(
&
data
);
}
...
...
@@ -405,15 +413,12 @@ int driver_obs_obsdaq::auto_calibrate(int channel, int repeat){
send
(
"#PP00000000"
);
usleep
(
1e6
);
/////////////////////////////////////////////////////////////////////////
//
// Calibration
//
/////////////////////////////////////////////////////////////////////////
//
// Repeat calibration step
//
for
(
int
k
=
1
;
k
<=
repeat
;
k
++
){
...
...
@@ -427,6 +432,7 @@ int driver_obs_obsdaq::auto_calibrate(int channel, int repeat){
// Check if calibration is finished
sprintf
(
cmd
,
"$%1dRR"
,
channel
);
usleep
(
4.0
/
freq
*
1e6
);
while
(
checked_send
(
cmd
,
"R0"
,
2
,
5
)
<
0
){
}
...
...
@@ -434,12 +440,13 @@ int driver_obs_obsdaq::auto_calibrate(int channel, int repeat){
sprintf
(
cmd
,
"$%1dRO"
,
channel
);
send
(
cmd
);
//TODO Repeat loop instead of just omitting
if
(
receive
(
recv
,
sizeof
(
recv
),
5
)
==
0
)
{
// Parse the offset value and add to average
n32
=
(
uint32_t
)
strtoul
(
&
recv
[
3
],
NULL
,
16
);
num
=
0x800000L
;
offset
+=
(
double
)
(
n32
^
num
)
-
(
double
)
num
;
offset
+=
(
double
)
(
n32
^
num
)
-
(
double
)
num
;
}
// Necessary to avoid time outs
...
...
@@ -449,6 +456,7 @@ int driver_obs_obsdaq::auto_calibrate(int channel, int repeat){
sprintf
(
cmd
,
"$%1dRF"
,
channel
);
send
(
cmd
);
//TODO Repeat loop instead of just omitting
if
(
receive
(
recv
,
sizeof
(
recv
),
5
)
==
0
)
{
// Parse the full-scale value and add to average
...
...
@@ -463,6 +471,14 @@ int driver_obs_obsdaq::auto_calibrate(int channel, int repeat){
// Calculate the average of calibration constants and send them to
// OBSDAQ.
//
// Offset
n32
=
((
int32_t
)
(
scale
/
repeat
)
+
(
int32_t
)
0x800000L
)
^
(
int32_t
)
0x800000L
;
sprintf
(
cmd
,
"$%1dWF%06X"
,
channel
,
n32
);
send
(
cmd
);
std
::
cerr
<<
"Set offset: "
<<
scale
/
repeat
<<
" "
<<
cmd
<<
std
::
endl
;
// Full-scale
n32
=
((
int32_t
)
(
offset
/
repeat
)
+
(
int32_t
)
0x800000L
)
...
...
@@ -470,15 +486,7 @@ int driver_obs_obsdaq::auto_calibrate(int channel, int repeat){
sprintf
(
cmd
,
"$%1dWO%06X"
,
channel
,
n32
);
send
(
cmd
);
std
::
cerr
<<
"AUTO CAL: "
<<
scale
/
repeat
<<
" "
<<
cmd
<<
std
::
endl
;
// Offset
n32
=
((
int32_t
)
(
scale
/
repeat
)
+
(
int32_t
)
0x800000L
)
^
(
int32_t
)
0x800000L
;
sprintf
(
cmd
,
"$%1dWF%06X"
,
channel
,
n32
);
send
(
cmd
);
std
::
cerr
<<
"AUTO CAL: "
<<
scale
/
repeat
<<
" "
<<
cmd
<<
std
::
endl
;
std
::
cerr
<<
"Set scale: "
<<
scale
/
repeat
<<
" "
<<
cmd
<<
std
::
endl
;
return
(
0
);
...
...
@@ -738,9 +746,6 @@ int driver_obs_obsdaq::parse_data_ascii(data_obs_vector* data, char* buf) {
***************************************************************************/
int
driver_obs_obsdaq
::
parse_data_bin
(
data_obs_vector
*
data
,
char
*
buf
)
{
// TODO Use for sampling rates higher than 10 Hz (else, suppl. data is
// not returned).
// OBSDAQ uses LittleEndian
/////////////////////////////////////////////////////////////////////////
//
...
...
@@ -760,6 +765,19 @@ int driver_obs_obsdaq::parse_data_bin(data_obs_vector* data, char* buf) {
// Set data to missing
data
->
set_data_MD
();
////////////////////////////////////////////////////////////////////////
// TODO Use for sampling rates higher than 10 Hz (else, suppl. data is
// not returned).
// OBSDAQ uses LittleEndian
////////////////////////////////////////////////////////////////////////
if
(
freq
<
10.0
){
std
::
cerr
<<
"ERROR: Binary mode not available for sampling rate "
<<
"of lower than 10 Hz. Current sampling rate is "
<<
freq
<<
" Hz."
<<
std
::
endl
;
return
(
-
1
);
}
////////////////////////////////////////////////////////////////////////
//
// Parse the binary data (Manual 12.5.2).
...
...
@@ -769,7 +787,7 @@ int driver_obs_obsdaq::parse_data_bin(data_obs_vector* data, char* buf) {
//
// Some checks on data consistency are performed
//
// Check for supplementary channels
if
(
buf
[
1
]
&
(
unsigned
char
)
64
){
reclen
=
14
;
...
...
@@ -777,9 +795,12 @@ int driver_obs_obsdaq::parse_data_bin(data_obs_vector* data, char* buf) {
// Check 7th bits
for
(
int
i
=
0
;
i
<
strlen
(
buf
);
i
++
){
if
(
buf
[
i
]
<
32
||
buf
[
i
]
>
159
){
fprintf
(
stderr
,
"Faulty data: 7th bit check failed for %d."
,
buf
[
i
]);
if
((
unsigned
char
)
buf
[
i
]
<
32
||
(
unsigned
char
)
buf
[
i
]
>
159
){
fprintf
(
stderr
,
"Faulty data: 7th bit check failed for byte %d: %d.
\n
"
,
i
,(
unsigned
char
)
buf
[
i
]);
//fprintf(stderr,"%d %d %d %d %d %d %d %d\n",buf[i]&1,(buf[i]&2)/2,
// (buf[i]&4)/4,(buf[i]&8)/8,(buf[i]&16)/16,(buf[i]&32)/32,
// (buf[i]&64)/64,(buf[i]&128)/128);
return
(
-
1
);
}
...
...
@@ -944,14 +965,14 @@ int driver_obs_obsdaq::init() {
}
// Define the filter commands (Table 6 in Manual)
filter_cmds
[
0
]
=
"03
\0
"
;
filter_cmds
[
1
]
=
"13
\0
"
;
filter_cmds
[
0
]
=
"03"
;
filter_cmds
[
1
]
=
"13"
;
filter_cmds
[
2
]
=
"23"
;
filter_cmds
[
3
]
=
"33"
;
filter_cmds
[
4
]
=
"43
\0
"
;
filter_cmds
[
4
]
=
"43"
;
filter_cmds
[
5
]
=
"53"
;
filter_cmds
[
6
]
=
"63"
;
filter_cmds
[
7
]
=
"72
\0
"
;
filter_cmds
[
7
]
=
"72"
;
filter_cmds
[
8
]
=
"82"
;
filter_cmds
[
9
]
=
"92"
;
filter_cmds
[
10
]
=
"A1"
;
...
...
@@ -972,105 +993,109 @@ int driver_obs_obsdaq::init() {
***************************************************************************/
int
driver_obs_obsdaq
::
init_run
(
double
freq
){
// The receive buffer
char
buf
[
200
];
// A command to send
char
cmd
[
20
];
// Index of the selected frequency
int
freq_sel
;
// ADC calibration
int
adc_scale
,
adc_offset
;
/////////////////////////////////////////////////////////////////////
//
// Set frequency.
//
/////////////////////////////////////////////////////////////////////
// Set triggering off
send
(
"#PP00000000"
);
usleep
(
1e6
);
// The receive buffer
char
buf
[
200
];
// A command to send
char
cmd
[
20
];
// Index of the selected frequency
int
freq_sel
;
//
Find the closest possible valid frequency lower or equal to the one
// requested.
for
(
int
i
=
0
;
i
<
valid_filter_rates_num
;
i
++
){
if
(
valid_filter_rates
[
i
]
>
freq
){
freq_sel
=
i
;
break
;
}
}
//
ADC calibration
int
adc_scale
,
adc_offset
;
/////////////////////////////////////////////////////////////////////
//
// Set frequency.
//
/////////////////////////////////////////////////////////////////////
// Set range to +10V and set frequency of digital filter
for
(
int
i
=
0
;
i
<
3
;
i
++
){
sprintf
(
cmd
,
"$%1dWS020102%s"
,
i
,
filter_cmds
[
freq_sel
]);
send
(
cmd
);
waitanswer
(
5
);
// Find the closest possible valid frequency.
for
(
int
i
=
0
;
i
<
valid_filter_rates_num
;
i
++
){
if
(
valid_filter_rates
[
i
]
>=
freq
){
freq_sel
=
i
;
break
;
}
}
// Print used and requested frequency
fprintf
(
stderr
,
"Frequency set to: %6.2f Hz. "
"Requested frequency: %6.2f Hz.
\n
"
,
valid_filter_rates
[
freq_sel
],
freq
);
// Set the frequency
driver_obs
::
freq
=
valid_filter_rates
[
freq_sel
];
/////////////////////////////////////////////////////////////////////////
//
// Calibrate.
//
/////////////////////////////////////////////////////////////////////////
// Set range to +10V and set frequency of digital filter
for
(
int
i
=
0
;
i
<
3
;
i
++
){
sprintf
(
cmd
,
"$%1dWS020102%s"
,
i
,
filter_cmds
[
freq_sel
]);
send
(
cmd
);
waitanswer
(
5
);
}
// Iterate over all three channels
for
(
int
i
=
0
;
i
<
3
;
i
++
){
// Print used and requested frequency
fprintf
(
stderr
,
"Frequency set to: %6.2f Hz. "
"Requested frequency: %6.2f Hz.
\n
"
,
valid_filter_rates
[
freq_sel
],
freq
);
/////////////////////////////////////////////////////////////////////////
//
// Calibrate.
//
/////////////////////////////////////////////////////////////////////////
int
config
=
0
;
// Get current 24-bit configuration (Manual 12.4.9)
sprintf
(
cmd
,
"$%1dRS"
,
i
);
send
(
cmd
);
receive
(
buf
,
sizeof
(
buf
),
1
);
fprintf
(
stderr
,
"REC_CONFIG: %s
\n
"
,
buf
);
// Iterate over all three channels
for
(
int
i
=
0
;
i
<
3
;
i
++
){
// Get the last four bytes ("ccdd") and add channel number
config
=
(
i
<<
16
)
+
strtoul
(
&
buf
[
7
],
NULL
,
16
);
int
config
=
0
;
// Check if calibration for the given config
// was pre-determined
if
(
driver_obs
::
cal
->
get_adc_calibrate
(
&
adc_offset
,
&
adc_scale
,
config
)
<
0
){
// Get current 24-bit configuration (Manual 12.4.9)
usleep
(
0.5
*
1e6
);
flush
();
sprintf
(
cmd
,
"$%1dRS"
,
i
);
send
(
cmd
);
receive
(
buf
,
sizeof
(
buf
),
1
);
fprintf
(
stderr
,
"REC_CONFIG: %s
\n
"
,
buf
);
// Automatic Calibration
auto_calibrate
(
i
,
1
);
// Get the last four bytes ("ccdd") and add channel number
config
=
(
i
<<
16
)
+
strtoul
(
&
buf
[
7
],
NULL
,
1
6
);
}
else
{
// Check if calibration for the given config
// was pre-determined
if
(
driver_obs
::
cal
->
get_adc_calibrate
(
&
adc_offset
,
&
adc_scale
,
config
)
<
0
){
// Set the pre-determined calibration constant
sprintf
(
cmd
,
"$%1dWO%06X"
,
i
,
adc_offset
);
send
(
cmd
);
waitanswer
(
5
);
sprintf
(
cmd
,
"$%1dWF%06X"
,
i
,
adc_scale
);
send
(
cmd
);
waitanswer
(
5
);
// Automatic Calibration
// auto_calibrate(i,1);
}
}
else
{
//printf("============ GOT: %06X %06X\n",adc_offset,adc_scale);
// Set the pre-determined calibration constant
sprintf
(
cmd
,
"$%1dWO%06X"
,
i
,
adc_offset
);
send
(
cmd
);
waitanswer
(
5
);
sprintf
(
cmd
,
"$%1dWF%06X"
,
i
,
adc_scale
);
send
(
cmd
);
waitanswer
(
5
);
}
//printf("============ GOT: %06X %06X\n",adc_offset,adc_scale);