Commit bf824f44 authored by Achim Morschhauser's avatar Achim Morschhauser
Browse files

Structure and makefile updated

parent d86ddbac
......@@ -51,6 +51,7 @@ Obs_Calibration_Vector::Obs_Calibration_Vector(
}
}
/*
adc_config.push_back(0x000203);
adc_scale.push_back(0x324944);
adc_offset.push_back(0xFFF35B);
......@@ -62,6 +63,7 @@ Obs_Calibration_Vector::Obs_Calibration_Vector(
adc_config.push_back(0x020203);
adc_scale.push_back(0x32427C);
adc_offset.push_back(0xFFF598);
*/
}
......
......@@ -102,4 +102,6 @@ data_obs buffer_obs_pipe::pop(){
********************************************************************************/
int buffer_obs_pipe::init() {
return(0);
}
/********************************************************************************
* WRITTEN BY ACHIM MORSCHHAUSER, GFZ POTSDAM, April 2016 *
* mors//gfz-potsdam.de *
* *
* This class provides the driver for a GemSys GSM-19 proton magnetometer. *
* *
* It is based on the abstract observatory driver class driver_obs. *
* *
********************************************************************************/
// C headers
#include <time.h> // System time functions
#include <unistd.h> // usleep
#include <stdio.h> // printf
// Custom C++ headers
#include <buffer_obs.hpp>
#include <data_obs_scalar.hpp>
#include <driver_obs_gsm.hpp>
/********************************************************************************
*********************************************************************************
* *
* Constructors. *
* *
*********************************************************************************
********************************************************************************/
driver_obs_gsm::driver_obs_gsm(std::string port, buffer_obs* buffer,
const char* init_char) :
Driver_Obs_Serial(port,buffer) {
set_term();
set_baud(init_char);
}
driver_obs_gsm::driver_obs_gsm(std::string port, buffer_obs* buffer, int baud) :
Driver_Obs_Serial(port,buffer) {
set_term();
set_baud(baud);
}
/********************************************************************************
*********************************************************************************
* *
* Public Methods. *
* *
*********************************************************************************
********************************************************************************/
/********************************************************************************
* *
* Run the GSM in freerun mode. This is only for recording, the measurement *
* must be started with the child classes. *
* *
********************************************************************************/
int driver_obs_gsm::freerun(int freq) {
// Time of measurement
struct timespec recv_time;
// Receive buffer
char buf[100];
// Data
double value;
int quality;
// Data container
data_obs_scalar data;
// Infinite Loop
while (1) {
// Wait for answer
if (receive(buf, sizeof(buf), 3, &recv_time) >= 0) {
// Parse data from answer
sscanf(buf, "%lf %d", &value, &quality);
// Store to data structure
data.set_data(value, quality);
data.set_time(&recv_time);
// Write measurement to buffer
buffer->put(&data);
}
}
return (0);
}
/********************************************************************************
* *
* Run the GSM in triggered mode. *
* - The GSM-19 must be set to remote mode. *
* *
*******************************************************************************/
int driver_obs_gsm::run(int freq) {
////////////////////////////////////////////////////////////////////////////////
//
// Some variables.
//
////////////////////////////////////////////////////////////////////////////////
// Time of measurement
struct timespec time, time_recv;
// The data
data_obs_scalar data;
////////////////////////////////////////////////////////////////////////////////
//
// Find the time which the GSM needs to measure
//
////////////////////////////////////////////////////////////////////////////////
// Time of received signal
int start_sec = 0;
int start_msec = 0;
// Current time
clock_gettime(CLOCK_REALTIME, &time);
// Wait for full 5-second
while (time.tv_sec % freq != 0 || (int) (time.tv_nsec / 1e6) != 0) {
usleep(10);
clock_gettime(CLOCK_REALTIME, &time);
}
// Do the measurement
get(&data);
// Get the epoch seconds of measurement
data.get_time(&time_recv);
// Calculate the delay
start_sec = freq - (data.get_sec() % freq);
start_msec = 1000 - data.get_msec();
if (start_msec < 1000) {
start_sec = start_sec - 1;
}
// Measurement time
double mtime = (double) (time_recv.tv_sec - time.tv_sec)
+ time_recv.tv_nsec / 1e9;
printf("Measurement time of GSM: %f\n",mtime);
// Check if frequency is supported by measurement time
if (mtime > freq) {
printf("WARNING: freq must be larger than measurement time: %fs\n",
mtime);
return (-1);
}
////////////////////////////////////////////////////////////////////////////////
//
// Start continuous measurement
//
////////////////////////////////////////////////////////////////////////////////
// Infinite loop
while (1) {
// Get the current time
clock_gettime(CLOCK_REALTIME, &time);
// Wait for correct time to measure. We want to measure at full seconds.
while ((time.tv_sec % freq != start_sec)
|| (((int) (time.tv_nsec / 1e6)) != start_msec)) {
clock_gettime(CLOCK_REALTIME, &time);
usleep(10);
}
// Do the measurement
get(&data);
// Clean the measurement time
data.smooth_msec(2);
// Write measurement to buffer
buffer->put(&data);
// Check start time for measurement and adjust if necessary
if ((data.get_sec() % freq == 0) && (data.get_msec() > 1)) {
start_msec -= data.get_msec();
if (start_msec < 0) {
start_msec = -start_msec;
start_sec = (freq + start_sec - 1) % freq;
}
} else if ((data.get_sec() % freq != 0) && (data.get_msec() < 999)) {
start_msec += 1000 - data.get_msec();
if (start_msec >= 1000) {
start_msec = start_msec - 1000;
start_sec = (start_sec + 1) % freq;
}
}
}
}
/********************************************************************************
* *
* Take a single measurement. *
* *
* A method to return data_obs must be provided (specified in driver_obs.hpp). *
* Only pass the timestamp, as data_obs can't store data values. *
* *
********************************************************************************/
int driver_obs_gsm::get(data_obs* data) {
data_obs_scalar fdata = data_obs_scalar();
get(&fdata);
data->set_time(&fdata);
return (0);
}
/********************************************************************************
* *
* Take a single measurement. *
* *
********************************************************************************/
int driver_obs_gsm::get(data_obs_scalar* data) {
////////////////////////////////////////////////////////////////////////////////
//
// Some variables.
//
////////////////////////////////////////////////////////////////////////////////
// Time of measurement
struct timespec recv_time;
// Receive buffer
char buf[100];
// Data
double value;
int quality;
////////////////////////////////////////////////////////////////////////////////
//
// Do the measurement.
//
////////////////////////////////////////////////////////////////////////////////
// Send F
send("F");
// Wait for answer
if (receive(buf, sizeof(buf), 3, &recv_time) >= 0) {
// Parse data from answer
sscanf(buf, "%lf %d", &value, &quality);
// Store to data structure
data->set_data(value, quality);
data->set_time(&recv_time);
return (0);
}
return (-1);
}
/********************************************************************************
* *
* Stop the running mode of the GSM. *
* *
********************************************************************************/
int driver_obs_gsm::stop() {
return (0);
}
/********************************************************************************
*********************************************************************************
* *
* Private Methods. *
* *
*********************************************************************************
********************************************************************************/
int driver_obs_gsm::set_term() {
static int termlen=2;
char term[termlen]={13,10};
return(Driver_Obs_Serial::set_term(term,termlen));
}
......@@ -353,9 +353,9 @@ int driver_obs_obsdaq::stop() {
char buf[100];
// Stop free-run mode
send("||||||||||||||||||||||||");
send("|||||||||||||||||||||||||||||||||||||||||");
while (receive_raw(buf, sizeof(buf), 0.2) > 5) {
send("||||||||||||||||||||||||");
send("||||||||||||||||||||||||||||||||||||||||||||");
}
return (0);
......@@ -481,25 +481,6 @@ int driver_obs_obsdaq::auto_calibrate(int channel, int repeat){
std::cerr << " " << scale/repeat << " " << cmd << std::endl;
/////////////////////////////////////////////////////////////////////////
//
// Set the scaling parameter (Manual 12.5.1).
//
/////////////////////////////////////////////////////////////////////////
//TODO Automatically set the calibration parameters
// Set the conversion parameters
//FULLSCALE=42.5; // Self-Gain calibration
//FULLSCALE=40.0; // System-Gain calibration
//GAIN=4.0; // +/- 10V range
//GAIN=8.0; // +/- 5V range
M = 40.0 / 4.0 / (double) 0x800000;
//printf("M: %f\n",M);
return(0);
}
......@@ -711,12 +692,12 @@ int driver_obs_obsdaq::parse_data_ascii(data_obs_vector* data, char* buf) {
// Channels 1-3
char tmp[7];
num = (uint32_t) 0x800000L;
num = (int32_t) 0x800000L; // was uint32_t
while (i < 3) {
strncpy(tmp, &buf[pos], 6);
tmp[6] = 0;
pos += 6;
n32 = (uint32_t) strtoul(tmp, NULL, 16);
n32 = (int32_t) strtol(tmp, NULL, 16); // was strtoul // was uint32_t
n[i++] = ((double) ((int32_t) ((n32 ^ num) - num))) * M;
}
......@@ -1073,5 +1054,24 @@ int driver_obs_obsdaq::init_run(double freq){
}
/////////////////////////////////////////////////////////////////////////
//
// Set the scaling parameter (Manual 12.5.1).
//
/////////////////////////////////////////////////////////////////////////
//TODO Automatically set the calibration parameters
// Set the conversion parameters
//FULLSCALE=42.5; // Self-Gain calibration
//FULLSCALE=40.0; // System-Gain calibration
//GAIN=4.0; // +/- 10V range
//GAIN=8.0; // +/- 5V range
M = 40.0 / 4.0 / (double) 0x800000;
//printf("M: %f\n",M);
}
/********************************************************************************
* 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. *
* *
********************************************************************************/
// C headers
#include <time.h> // System time functions
#include <unistd.h> // usleep
#include <stdio.h> // printf
#include <stdlib.h> // itoa
#include <string.h> // strcmp
// C++ headers
#include <sstream>
#include <iostream>
#include <iomanip>
// Custom C++ headers
#include <buffer_obs.hpp>
#include <data_obs_vector.hpp>
#include <driver_obs_obsdaq.hpp>
/********************************************************************************
*********************************************************************************
* *
* Constructors. *
* *
*********************************************************************************
********************************************************************************/
driver_obs_obsdaq::driver_obs_obsdaq(std::string port, buffer_obs* buffer,
int addr): Driver_Obs_Serial(port,buffer){
char addr_str[2];
// Set the termination characters for serial port driver
set_term();
// Set the RS485 address
RS485_addr=addr;
sprintf(addr_str,"%02d",addr);
RS485_addrstr=std::string(addr_str);
// Check for baud rate with the right address
std::string baud_cmd="$" + RS485_addrstr + "M";
set_baud(baud_cmd.c_str());
// Initialize the OBSDAQ
init();
}
driver_obs_obsdaq::driver_obs_obsdaq(std::string port, buffer_obs* buffer) :
Driver_Obs_Serial(port,buffer) {
set_term();
RS485_addr=1;
RS485_addrstr=std::string("01");
set_baud("$01M");
// Initialize the OBSDAQ
init();
}
driver_obs_obsdaq::driver_obs_obsdaq(std::string port, buffer_obs* buffer,
int baud, int addr) :
Driver_Obs_Serial(port, buffer) {
char addr_str[2];
set_term();
// Set the RS485 address
RS485_addr=addr;
sprintf(addr_str,"%02d",addr);
RS485_addrstr=std::string(addr_str);
set_baud(baud);
init();
}
/********************************************************************************
*********************************************************************************
* *
* Public Methods. *
* *
*********************************************************************************
********************************************************************************/
/********************************************************************************
* *
* Run the OBSDAQ in freerun mode. *
* *
********************************************************************************/
int driver_obs_obsdaq::freerun(int freq) {
return (0);
}
/********************************************************************************
* *
* Run the OBSDAQ in triggered mode. *
* *
********************************************************************************/
int driver_obs_obsdaq::run(int freq) {
////////////////////////////////////////////////////////////////////////////////
//
// Some variables.
//
////////////////////////////////////////////////////////////////////////////////
// Time of measurement
struct timespec recv_time, time;
// The data
data_obs_vector data;
////////////////////////////////////////////////////////////////////////////////
//
// Start continuous measurement
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Listen to continuous measurement
//
////////////////////////////////////////////////////////////////////////////////
// Infinite loop
while (1) {
// Get the current time
clock_gettime(CLOCK_REALTIME, &time);
// Write measurement to buffer
buffer->put(&data);
}
}
/********************************************************************************
* *
* Take a single measurement. *
* *
* A method to return data_obs must be provided (specified in driver_obs.hpp). *
* Only pass the timestamp, as data_obs can't store data values. *
* *
********************************************************************************/
int driver_obs_obsdaq::get(data_obs* data) {
data_obs_vector fdata = data_obs_vector();
get(&fdata);
data->set_time(&fdata);
return (0);
}
/********************************************************************************
* *
* Take a single measurement. *
* *
********************************************************************************/
int driver_obs_obsdaq::get(data_obs_vector* data) {
////////////////////////////////////////////////////////////////////////////////
//
// Some variables.
//
////////////////////////////////////////////////////////////////////////////////
// Time of measurement
struct timespec recv_time;
// Receive buffer
char buf[100];
// Data
int quality;
double value;
////////////////////////////////////////////////////////////////////////////////
//
// Do the measurement.
//
////////////////////////////////////////////////////////////////////////////////
// Send F
send("F");
// Wait for answer
if (receive(buf, sizeof(buf), 1, &recv_time) >= 0) {
// Parse data from answer
sscanf(buf, "%lf %d", &value, &quality);
//data->set_data(value,quality);
data->set_time(&recv_time);
return (0);
}
return (-1);
}
/********************************************************************************
* *
* Initialize the GSM. *
* *
* Auto-determine baud rate and set termination characters.
* *
********************************************************************************/
int driver_obs_obsdaq::init() {
////////////////////////////////////////////////////////////////////////////////
//
// Get the quartz crystal frequency.
//
////////////////////////////////////////////////////////////////////////////////
std::string recv;
checked_send("$QF","R",1,1,&recv);
std::cout << "Received: " << recv << std::endl;
////////////////////////////////////////////////////////////////////////////////
//
// Set the 24-bit channel configuration (Manual 12.4.8).
//
////////////////////////////////////////////////////////////////////////////////
// Set triggering off
send("#PP00000000");
usleep(1e6);
// Set range to +10V and set frequency of digital filter