mv project to lab-helper

This commit is contained in:
Глеб Луговцов 2022-12-05 13:29:26 +03:00
parent 1a273370a8
commit b4e13ad5b4
29 changed files with 1 additions and 1580109 deletions

View File

@ -939,7 +939,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.10.2" "version": "3.10.6"
} }
}, },
"nbformat": 4, "nbformat": 4,

6
project/.gitignore vendored
View File

@ -1,6 +0,0 @@
*test*
*tmp*
.vscode
*.exe
*.o
main

View File

@ -1,2 +0,0 @@
- [ ] Автоматическое подключение генератора
- [ ] Автоматическая резонансная кривая (данные в файл)

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
#include <complex>
#include <cmath>
#include <vector>
#include <iostream>
#include "pocketfft_hdronly.h"
using namespace std;
using namespace pocketfft;
// floating point RNG which is good enough for sinmple demos
// Do not use for anything important!
inline double simple_drand()
{
constexpr double norm = 1./RAND_MAX;
return rand()*norm;
}
template<typename T> void crand(vector<complex<T>> &v)
{
for (auto & i:v)
i = complex<T>(simple_drand()-0.5, simple_drand()-0.5);
}
template<typename T1, typename T2> long double l2err
(const vector<T1> &v1, const vector<T2> &v2)
{
long double sum1=0, sum2=0;
for (size_t i=0; i<v1.size(); ++i)
{
long double dr = v1[i].real()-v2[i].real(),
di = v1[i].imag()-v2[i].imag();
long double t1 = sqrt(dr*dr+di*di), t2 = abs(v1[i]);
sum1 += t1*t1;
sum2 += t2*t2;
}
return sqrt(sum1/sum2);
}
int main()
{
for (size_t len=1; len<8192; ++len)
{
shape_t shape{len};
stride_t stridef(shape.size()), strided(shape.size()), stridel(shape.size());
size_t tmpf=sizeof(complex<float>),
tmpd=sizeof(complex<double>),
tmpl=sizeof(complex<long double>);
for (int i=shape.size()-1; i>=0; --i)
{
stridef[i]=tmpf;
tmpf*=shape[i];
strided[i]=tmpd;
tmpd*=shape[i];
stridel[i]=tmpl;
tmpl*=shape[i];
}
size_t ndata=1;
for (size_t i=0; i<shape.size(); ++i)
ndata*=shape[i];
vector<complex<float>> dataf(ndata);
vector<complex<double>> datad(ndata);
vector<complex<long double>> datal(ndata);
crand(dataf);
for (size_t i=0; i<ndata; ++i)
{
datad[i] = dataf[i];
datal[i] = dataf[i];
}
shape_t axes;
for (size_t i=0; i<shape.size(); ++i)
axes.push_back(i);
auto resl = datal;
auto resd = datad;
auto resf = dataf;
c2c(shape, stridel, stridel, axes, FORWARD,
datal.data(), resl.data(), 1.L);
c2c(shape, strided, strided, axes, FORWARD,
datad.data(), resd.data(), 1.);
c2c(shape, stridef, stridef, axes, FORWARD,
dataf.data(), resf.data(), 1.f);
// c2c(shape, stridel, stridel, axes, POCKETFFT_BACKWARD,
// resl.data(), resl.data(), 1.L/ndata);
cout << l2err(resl, resf) << endl;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
#include "Generator.hpp"
#include <string>
#include <vector>
#include <fstream>
#include <filesystem>
namespace fs = std::filesystem;
Generator::Generator() : m_channel("C1")
{
auto devices_path = files_path("/dev/usbtmc");
bool success = false;
for (auto const &device_path : devices_path)
{
m_root_path = device_path;
std::string response = query("*IDN?");
response.erase(0, response.find(',') + 1);
response.erase(response.find(','));
if (response == "AKIP-3409-4")
{
success = true;
break;
}
}
if (!success)
throw std::runtime_error("Generator (AKIP-3409-4) is not available!");
}
void Generator::command(std::string const &comm) const
{
std::ofstream out;
out.open(m_root_path);
if (!out.is_open())
std::cerr << "**ERROR** file is not open to output." << std::endl;
else
{
out << comm;
out.close();
}
}
std::string Generator::query(std::string const &comm) const
{
command(comm);
std::string buffer;
std::ifstream in;
in.open(m_root_path);
if (!in.is_open())
std::cerr << "**ERROR** file is not open to input." << std::endl;
else
{
std::getline(in, buffer);
in.close();
}
return buffer;
}

View File

@ -1,60 +0,0 @@
#pragma once
#include <string>
#include <iostream>
#include "Utils.hpp"
class Generator
{
public:
Generator();
void command(std::string const &comm) const;
std::string query(std::string const &comm) const;
void set_channel(channels ch)
{
m_channel = "C" + std::to_string(static_cast<ind_t>(ch));
}
void buzz()
{
command("BUZZ ON");
}
void set_waveform(std::string waveform)
{
command(m_channel + ":BSWV WVTP," + waveform);
}
void set_frequency(double frequency)
{
command(m_channel + ":BSWV FRQ," + std::to_string(frequency));
}
void set_period(double period)
{
command(m_channel + ":BSWV PERI," + std::to_string(period));
}
void set_amplitude(double amplitude)
{
command(m_channel + ":BSWV AMP," + std::to_string(amplitude));
}
void set_offset(double offset)
{
command(m_channel + ":BSWV OFST," + std::to_string(offset));
}
void set_phase(double phase)
{
command(m_channel + ":BSWV PHSE," + std::to_string(phase));
}
private:
std::string m_root_path;
std::string m_channel;
};

View File

@ -1,23 +0,0 @@
CC=g++
CFLAGS=-c
EXECUTABLE=start
all: $(EXECUTABLE)
$(EXECUTABLE): main.o Generator.o Oscilloscope.o
$(CC) main.o Generator.o Oscilloscope.o -o main
main.o: main.cpp
$(CC) $(CFLAGS) main.cpp
Generator.o: Generator.cpp Generator.hpp
$(CC) $(CFLAGS) Generator.cpp
Oscilloscope.o: Oscilloscope.cpp Oscilloscope.hpp
$(CC) $(CFLAGS) Oscilloscope.cpp
clean:
rm -f main
rm -f *.o
.PNONY: all clean

View File

@ -1,128 +0,0 @@
#include "Oscilloscope.hpp"
Oscilloscope::Oscilloscope(std::string server_ip, port_t server_port) : m_channel("C1")
{
// setup a socket and connection tools
struct hostent *host = gethostbyname(server_ip.c_str());
sockaddr_in sendSockAddr;
bzero((char *)&sendSockAddr, sizeof(sendSockAddr));
sendSockAddr.sin_family = AF_INET;
sendSockAddr.sin_addr.s_addr =
inet_addr(inet_ntoa(*(struct in_addr *)*host->h_addr_list));
sendSockAddr.sin_port = htons(server_port);
m_client_side = socket(AF_INET, SOCK_STREAM, 0);
// try to connect...
int status = connect(m_client_side,
(sockaddr *)&sendSockAddr, sizeof(sendSockAddr));
if (status < 0)
throw std::runtime_error("Error connecting to oscilloscope!");
std::cout << "Connected to the oscilloscope!" << std::endl;
char *msg = new char[256];
recv(m_client_side, msg, 256, 0);
std::cout << msg << std::endl;
}
std::string Oscilloscope::request()
{
size_t msg_size = 256;
char buf[msg_size];
recv(m_client_side, buf, msg_size, 0);
return std::string(buf, strlen(buf));
}
size_t Oscilloscope::request(char *buf, size_t msg_size)
{
size_t bytes_read = 0;
while (bytes_read < msg_size)
bytes_read += recv(m_client_side, std::next(buf, bytes_read), msg_size - bytes_read, 0);
return bytes_read;
}
std::string Oscilloscope::query(std::string const &comm)
{
command(comm);
usleep(50000);
return request();
}
double Oscilloscope::parser(std::string const &comm, std::string const &to_find, std::string const &units)
{
std::string response = query(comm);
ind_t value_ind = response.find(to_find) + to_find.length() + 1;
response.erase(0, value_ind - 1);
ind_t units_ind = response.find(units);
response.erase(units_ind);
return std::stod(response);
}
void Oscilloscope::save_waveform(std::string file_name)
{
std::size_t const header_size = 23;
char *header = new char[header_size];
command(m_channel + ":WF? DAT2");
request(header, header_size);
// calculate bytes count to read
size_t pos = 14; // C1:WF DAT2,#9002800000
size_t number = header[13] - '0';
std::string bytes_count_str = std::string(header, header_size).substr(pos, number);
size_t bytes_count = std::stoi(bytes_count_str);
// request waveform
char *wf = new char[bytes_count];
request(wf, bytes_count);
// end values
usleep(100000);
auto endv = request();
if ((endv[0] != 10) || (endv[1] != 10) || (endv.length() != 2))
std::cerr << "Invalid end values: " << static_cast<int>(endv[0]) << ' ' << static_cast<int>(endv[1]) << std::endl;
// parse waveform
std::ofstream out;
out.open(file_name, std::ios_base::trunc | std::ios_base::out);
out << "voltage,time\n";
double vdiv = get_vdiv() / 25.0f;
double voffset = get_voffset();
double timebase = get_timebase();
double sampling_rate = get_sampling_rate();
double time_inter = 1.0f / sampling_rate;
double const grid = 14; // The grid numbers in horizontal direction
double time_value = -(timebase * grid / 2.0f);
std::cout
<< "Vdiv: " << vdiv << std::endl
<< "Voffset: " << voffset << std::endl
<< "Timebase: " << timebase << std::endl
<< "Sampling rate: " << sampling_rate << std::endl;
for (size_t i = 0; i < bytes_count; i++)
out << wf[i] * vdiv - voffset << ',' << time_value + time_inter * i << '\n';
out.close();
}
Oscilloscope::~Oscilloscope()
{
close(m_client_side);
std::cout << "Connection closed" << std::endl;
}

View File

@ -1,70 +0,0 @@
#pragma once
#include <iostream>
#include <string>
#include <exception>
#include <fstream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <fcntl.h>
#include "Utils.hpp"
class Oscilloscope
{
public:
Oscilloscope(std::string server_ip = "10.11.13.220", port_t server_port = 5024);
size_t command(std::string const &comm)
{
return send(m_client_side, comm.c_str(), comm.length(), 0);
}
std::string request();
size_t request(char *buf, size_t msg_size);
std::string query(std::string const& comm);
void set_channel(channels ch)
{
m_channel = "C" + std::to_string(static_cast<ind_t>(ch));
}
double parser(std::string const& comm, std::string const& to_find, std::string const& units);
double get_vdiv()
{
return parser(m_channel + ":VDIV?", "VDIV", "V");
}
double get_voffset()
{
return parser(m_channel + ":OFST?", "OFST", "V");
}
double get_timebase()
{
return parser("TDIV?", "TDIV", "S");
}
double get_sampling_rate()
{
return parser("SARA?", "SARA", "Sa/s");
}
void save_waveform(std::string file_name = "waveform.csv");
~Oscilloscope();
private:
int m_client_side;
std::string m_channel;
};

View File

@ -1,36 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include <filesystem>
namespace fs = std::filesystem;
using port_t = std::size_t;
using ind_t = std::size_t;
enum class channels
{
C1 = 1,
C2 = 2
};
std::vector<std::string> files_path(std::string const &path)
{
size_t file_ind = path.find_last_of('/') + 1;
std::string directory = path;
directory.erase(file_ind);
auto directory_iterator = fs::directory_iterator(directory);
std::vector<std::string> files_path;
for (const auto &directory_entry : directory_iterator)
{
auto filename = std::string(directory_entry.path());
std::cout << filename << std::endl;
if (!filename.find(path))
files_path.push_back(filename);
}
return files_path;
}

View File

@ -1,44 +0,0 @@
#include "Device.hpp"
Device::Device(std::string path_name) : root_path("/dev/" + path_name)
{
std::string response = query("*IDN?");
response.erase(0, response.find(',') + 1);
response.erase(response.find(','));
name = response;
}
void Device::command(std::string const &comm) const
{
std::ofstream out;
out.open(root_path);
if (!out.is_open())
std::cerr << "**ERROR** file is not open to output." << std::endl;
else
{
out << comm;
out.close();
}
}
std::string Device::query(std::string const &comm) const
{
command(comm);
std::string buffer;
std::ifstream in;
in.open(root_path);
if (!in.is_open())
std::cerr << "**ERROR** file is not open to input." << std::endl;
else
{
std::getline(in, buffer);
in.close();
}
return buffer;
}

View File

@ -1,22 +0,0 @@
#pragma once
#include<fstream>
#include<iostream>
#include<string>
class Device
{
public:
Device(std::string path_name);
std::string get_name()
{
return name;
}
void command(std::string const &comm) const;
std::string query(std::string const &comm) const;
};

View File

@ -1,28 +0,0 @@
#pragma once
#include <iostream>
#include <string>
#include "Oscilloscope.hpp"
class Measurement
{
public:
Measurement() = default;
Measurement(std::string name_) : name(name_) { }
Measurement(std::string stat_response, bool)
{
size_t name_start = stat_response.find(" C") + 5;
size_t name_end = stat_response.find(":");
name = stat_response.substr(name_start, name_end - name_start);
}
// private:
std::string name;
double mean;
double min;
double max;
double std_dev;
double count;
};

View File

@ -1 +0,0 @@
#include "Oscilloscope.hpp"

View File

@ -1,113 +0,0 @@
#pragma once
#include "Device.hpp"
#include "Measurement.hpp"
#include <string>
#include <unistd.h>
#include <exception>
#include <cassert>
class Oscilloscope : public Device
{
public:
Oscilloscope(std::string path_name) : Device(path_name), m_channel("C1") {}
void set_channel(unsigned int channel)
{
if (channel == 1 || channel == 2)
m_channel = "C" + std::to_string(channel);
else
std::cerr << "Invalid channel" << std::endl;
}
Measurement get_pkpk()
{
comm_param_custom("PKPK");
comm_param_stat(1);
std::string response = quer_param_value("STAT1");
comm_param_stat(0);
std::cout << response << std::endl;
return Measurement(response, 1);
}
void get_waveform()
{
command(m_channel + ":WF? DAT2");
usleep(1e7);
std::ifstream in;
std::ofstream out;
out.open("out.txt", std::ios_base::trunc | std::ios_base::binary | std::ios_base::out);
in.open(root_path, std::ios_base::binary);
// in.open(root_path, std::ios_base::binary | std::ios_base::in);
// if (!in.is_open())
// throw std::runtime_error("File is not enable to write!");
size_t buf_size = 1400026;
size_t cur_size = 0;
size_t upd = 0;
char *buffer = new char [buf_size];
while (in)
{
in.get(buffer + cur_size, buf_size);
cur_size += in.gcount();
if (upd != cur_size)
{
out.write(buffer + upd, cur_size - upd);
std::cout << cur_size << std::endl;
upd = cur_size;
}
}
// std::cout << in.gcount() << std::endl;
// char response = '0';
// while (response != '#')
// in >> response;
// char count_of_integers;
// in >> count_of_integers;
// size_t coi = count_of_integers - 48;
// assert(coi == 9);
// char *count_of_bytes = new char [coi];
// for (size_t i = 0; i < coi; i++)
// in >> count_of_bytes[i];
// size_t cob = std::stoi(count_of_bytes);
// signed char *data = new signed char [cob];
// for (size_t i = 0; i < cob; i++)
// in >> data[i];
// char endl;
// in >> endl;
// // assert(endl == 10);
// std::cout << cob << std::endl;
// std::cout << data[0] << std::endl;
in.close();
out.close();
}
private:
void comm_param_custom(std::string param)
{
command("PACU " + param + "," + m_channel);
}
void comm_param_stat(bool condition)
{
command("PASTAT " + condition ? "ON" : "OFF");
}
std::string quer_param_value(std::string custom)
{
return query("PAVA? " + custom);
}
std::string m_channel;
};

View File

@ -1,15 +0,0 @@
#include "Generator.hpp"
#include "Oscilloscope.hpp"
#include "Utils.hpp"
template <typename T>
void func(T arg)
{
}
int main()
{
return EXIT_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
## USB
1. FTDI
2. USBTMC
3. BULK

View File

@ -1,2 +0,0 @@
#!/bin/sh
gcc gds.c -o gds -g

View File

@ -1,473 +0,0 @@
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <getopt.h>
// Actually I don't know if oscilloscope tty is freely accessible by conventional users
#define SETUID
#define GDS_BUFFER_LENGTH 1400026
char gds_buffer[GDS_BUFFER_LENGTH];
int gds_buffer_length;
#define ERR_DEVICE_OPEN -1
#define ERR_DEVICE_READ -2
#define ERR_INP_FILE_OPEN -3
#define ERR_OUT_FILE_OPEN -4
#define ERR_INV_CHANNEL -5
struct record
{
char *keyword;
char *value;
};
// -------------------------------------------------------------------------
#define GDS_OPT_HELP 'h'
#define GDS_OPT_ASCII 'a'
#define GDS_OPT_BINARY 'b'
#define GDS_OPT_CONVERT 'c'
#define GDS_OPT_ACQUIRE 'g'
#define GDS_OPT_NO_HDR 'r'
#define GDS_OPT_INPUT 'i'
#define GDS_OPT_OUTPUT 'o'
#define GDS_OPT_DEVICE 'd'
#define GDS_OPT_CHANNEL 'n'
static const struct option gds_long_opt[] =
{
{"help", no_argument, NULL, GDS_OPT_HELP},
{"ascii", no_argument, NULL, GDS_OPT_ASCII},
{"binary", no_argument, NULL, GDS_OPT_BINARY},
{"convert", no_argument, NULL, GDS_OPT_CONVERT},
{"acquire", no_argument, NULL, GDS_OPT_ACQUIRE},
{"no-hdr", no_argument, NULL, GDS_OPT_NO_HDR},
{"input", required_argument, NULL, GDS_OPT_INPUT},
{"output", required_argument, NULL, GDS_OPT_OUTPUT},
{"device", required_argument, NULL, GDS_OPT_DEVICE},
{"channel", required_argument, NULL, GDS_OPT_CHANNEL},
{0,0,0,0}
};
static const char* gds_opt_str = "abcghri:o:d:n:";
// -------------------------------------------------------------------------
double gds_scan_double_key(char *str, struct record *keys, int max_keys)
{
int curr_key;
double result;
for (curr_key = 0; curr_key < max_keys; curr_key++)
{
if (!strcmp(keys[curr_key].keyword, str))
{
sscanf(keys[curr_key].value, "%lf", &result);
return result;
}
}
return 0;
}
// -------------------------------------------------------------------------
int gds_scan_int_key(char *str, struct record *keys, int max_keys)
{
int curr_key;
int result;
for (curr_key = 0; curr_key < max_keys; curr_key++)
{
if (!strcmp(keys[curr_key].keyword, str))
{
sscanf(keys[curr_key].value, "%d", &result);
return result;
}
}
return 0;
}
// -------------------------------------------------------------------------
int gds_acquire(char *dev_file_name, int channel_number)
{
int dev_fd;
int error;
#ifdef SETUID
int old_uid, old_gid;
int uid_changed = 0;
#endif // SETUID
struct termios old_dev_tio, new_dev_tio;
fd_set dev_read_fds;
struct timeval dev_tv;
char *dev_cmd_read_request = (channel_number == 1) ? "C1:WF? DAT2\n" : "C2:WF? DAT2\n";
int dev_data_index = 0;
int dev_read_len;
#ifdef SETUID
if ((dev_fd = open(dev_file_name, O_RDWR | O_NOCTTY)) < 0) // check if we have permissions
{
old_uid = getuid(); old_gid = getgid();
if (setuid(0) || setgid(0))
{
fprintf(stderr, "**Error**: You have no permissions to access \"%s\"\n"
" Setting UID and GID to root failed\n", dev_file_name);
return ERR_DEVICE_OPEN;
}
uid_changed = 1;
// already root:wheel
if ((dev_fd = open(dev_file_name, O_RDWR | O_NOCTTY)) < 0)
{
fprintf(stderr, "**Error**: Error opening device \"%s\"\n", dev_file_name);
setuid(old_uid); setgid(old_gid);
return ERR_DEVICE_OPEN;
}
}
#else // SETUID
if ((dev_fd = open(dev_file_name, O_RDWR | O_NOCTTY)) < 0)
{
fprintf(stderr, "**Error**: Error opening device \"%s\"\n", dev_file_name);
return ERR_DEVICE_OPEN;
}
#endif // SETUID
tcgetattr(dev_fd, &old_dev_tio);
bzero(&new_dev_tio, sizeof(new_dev_tio));
new_dev_tio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
new_dev_tio.c_iflag = IGNBRK | IXON | IXOFF;
new_dev_tio.c_oflag = 0;
new_dev_tio.c_lflag = 0;
new_dev_tio.c_cc[VTIME] = 5;
new_dev_tio.c_cc[VMIN] = 1;
new_dev_tio.c_ispeed = 13;
new_dev_tio.c_ospeed = 13;
tcflush(dev_fd, TCIFLUSH);
tcsetattr(dev_fd, TCSANOW, &new_dev_tio);
write(dev_fd, dev_cmd_read_request, strlen(dev_cmd_read_request));
FD_ZERO(&dev_read_fds);
FD_SET(dev_fd, &dev_read_fds);
while (1)
{
dev_tv.tv_sec = 0;
dev_tv.tv_usec = 200000;
error = select(dev_fd + 1, &dev_read_fds, NULL, NULL, &dev_tv);
switch(error)
{
case -1:
fprintf(stderr, "**Error**: Error reading from device: select() failed with errorcode %d\n", error);
close(dev_fd);
return ERR_DEVICE_READ;
case 0:
close(dev_fd);
gds_buffer_length = dev_data_index;
#ifdef SETUID
if (uid_changed) // reset uid/gid to create files belonging to current user but not root
{
setuid(old_uid);
setgid(old_gid);
}
#endif
return 0;
default:
dev_read_len = read(dev_fd, gds_buffer + dev_data_index, GDS_BUFFER_LENGTH - dev_data_index);
dev_data_index += dev_read_len;
}
}
}
// -------------------------------------------------------------------------
int gds_save_binary_file(char *filename)
{
int out_fd;
if ((out_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC)) < 0)
{
fprintf(stderr, "**Error**: Error opening output file %s\n", filename);
return ERR_OUT_FILE_OPEN;
} else
{
fchmod(out_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ); // set 644 mode
write(out_fd, gds_buffer, gds_buffer_length);
close(out_fd);
return 0;
}
}
// -------------------------------------------------------------------------
int gds_read_binary_file(char *filename)
{
int in_fd;
if ((in_fd = open(filename, O_RDONLY)) == 0)
{
fprintf(stderr, "**Error**: Error opening data file \"%s\"\n", filename);
return ERR_INP_FILE_OPEN;
} else
{
gds_buffer_length = read(in_fd, gds_buffer, GDS_BUFFER_LENGTH);
close(in_fd);
return 0;
}
}
// -------------------------------------------------------------------------
int gds_save_ascii_file(char *filename, int header_flag)
{
#define MAX_KEYS 30
struct record keys[MAX_KEYS];
char *data_ptr;
int i, header_length, curr_key, max_keys, max_key_len;
double curr_time;
FILE *out_file;
union {
short s;
char b[2];
} short_val;
int Memory_Length;
double Vertical_Scale;
double Horizontal_Position;
double Sampling_Period;
if (( out_file = fopen(filename, "wt")) == NULL)
{
printf("**Error**: Error opening output file \"%s\"\n", filename);
return ERR_OUT_FILE_OPEN;
} else
{
for(i = 0; i < GDS_BUFFER_LENGTH; i++)
{
if (gds_buffer[i] == 10)
{
gds_buffer[i] = 0;
header_length = i;
break;
}
}
for (curr_key = 0; curr_key < MAX_KEYS; curr_key++)
{
keys[curr_key].keyword = NULL;
keys[curr_key].value = NULL;
}
i = 0;
for(curr_key = 0; curr_key < MAX_KEYS; curr_key++)
{
keys[curr_key].keyword = gds_buffer + i;
for( ; ; i++)
{
if (gds_buffer[i] == 0)
{
max_keys = curr_key;
goto keys_done;
}
if (gds_buffer[i] == ',')
{
keys[curr_key].value = gds_buffer + i + 1;
gds_buffer[i] = 0;
}
if (gds_buffer[i] == ';')
{
keys[curr_key + 1].keyword = gds_buffer + i + 1;
gds_buffer[i] = 0;
i++;
break;
}
}
}
keys_done:
if (header_flag) // put header
{
max_key_len = 0;
for (curr_key = 0; curr_key < max_keys; curr_key++)
{
if (strlen(keys[curr_key].keyword) > max_key_len)
{
max_key_len = strlen(keys[curr_key].keyword);
}
}
for (curr_key = 0; curr_key < max_keys; curr_key++)
{
fprintf(out_file, "# \"%s\" ", keys[curr_key].keyword);
for (i = 0; i < max_keys - strlen(keys[curr_key].keyword); i++)
{
fprintf(out_file, " ");
}
fprintf(out_file, "\"%s\"\n", keys[curr_key].value ? keys[curr_key].value : "");
}
fprintf(out_file, "\n");
}
Memory_Length = gds_scan_int_key ("Memory Length", keys, max_keys);
Vertical_Scale = gds_scan_double_key("Vertical Scale", keys, max_keys);
Horizontal_Position = gds_scan_double_key("Horizontal Position", keys, max_keys);
Sampling_Period = gds_scan_double_key("Sampling Period", keys, max_keys);
curr_time = -(double)Memory_Length * Sampling_Period / 2.0 + Horizontal_Position;
data_ptr = gds_buffer + header_length + 10; // skip #72000000
fprintf(out_file, "# Time, s\tReading, raw\tReading, V\n");
for (i = 0; i < Memory_Length; i++)
{
short_val.b[0] = data_ptr[2*i+1];
short_val.b[1] = data_ptr[2*i];
fprintf(out_file, "%le\t%d\t\t%le\n", curr_time, short_val.s, short_val.s * Vertical_Scale * 10.0 / 256.0);
curr_time += Sampling_Period;
}
fclose(out_file);
return 0;
}
}
// -------------------------------------------------------------------------
void usage(void)
{
#ifdef SETUID
#define SETUID_STATE "SETUID"
#else // SETUID
#define SETUID_STATE
#endif // SETUID
printf("gds [-abcgh] [-i <filename>] [-o <filename>] [-d <devname>]\n"
"GDS-72302 oscilloscope data retrieving program " SETUID_STATE "\n"
"(C) S. Ambrozevich <s.ambrozevich@mail.ru>, LPI\n"
"v. 0.3 compiled " __DATE__ " " __TIME__ "\n\n"
"Options:\n"
" -c, --convert - convert previously saved binary data to ASCII form\n"
" -g, --acquire - gather data from oscilloscope (default)\n"
" -r, --no-hdr - do not store header information in ASCII output\n"
" -a, --ascii - generate output in ASCII form\n"
" -b, --binary - generate output in binary form (raw data)\n"
" -i, --input=file - input file to convert, default = stdin\n"
" -o, --output=file - output file to store data, default = stdout\n"
" -d, --device=dev - device tty to communicate with, default = /dev/ttyACM0\n"
" -n, --channel=n - channel number <1|2> to acquire, default = 2\n"
" -h, --help - prints this help\n\n"
"NOTE: \"gds -cb\" will only copy input binary stream to output\n");
}
// -------------------------------------------------------------------------
int main(int argc, char **argv)
{
int errorcode;
int ascii_flag = 1;
int convert_flag = 0;
int header_flag = 1;
int input_file_flag = 0;
int output_file_flag = 0;
int device_file_flag = 0;
int channel_number = 2;
int opt, opt_ind;
char *input_file;
char *output_file;
char *device_file;
if (argc == 1)
{
usage();
return 0;
}
while ((opt = getopt_long(argc, argv, gds_opt_str, gds_long_opt, NULL)) != -1)
{
switch(opt)
{
case GDS_OPT_ASCII:
ascii_flag = 1;
break;
case GDS_OPT_BINARY:
ascii_flag = 0;
break;
case GDS_OPT_CONVERT:
convert_flag = 1;
break;
case GDS_OPT_ACQUIRE:
convert_flag = 0;
break;
case GDS_OPT_NO_HDR:
header_flag = 0;
break;
case GDS_OPT_DEVICE:
device_file_flag = 1;
device_file = optarg;
break;
case GDS_OPT_INPUT:
input_file_flag = 1;
input_file = optarg;
break;
case GDS_OPT_OUTPUT:
output_file_flag = 1;
output_file = optarg;
break;
case GDS_OPT_CHANNEL:
sscanf(optarg, "%d", &channel_number);
if ((channel_number < 1) || (channel_number > 2))
{
fprintf(stderr, "**Error**: Invalid channel number %d\n", channel_number);
return ERR_INV_CHANNEL;
}
break;
default:
usage();
return 0;
}
}
argc -= optind;
argv += optind;
if (convert_flag)
{ // convert
if (errorcode = gds_read_binary_file(input_file_flag ? input_file : "/dev/stdin") != 0)
{
return errorcode;
}
} else
{ // read
if (errorcode = gds_acquire(device_file_flag ? device_file : "/dev/ttyACM0", channel_number) != 0)
{
return errorcode;
}
}
if (ascii_flag)
{ // write ascii
if (errorcode = gds_save_ascii_file(output_file_flag ? output_file : "/dev/stdout", header_flag) != 0)
{
return errorcode;
}
} else
{ // write binary
if (errorcode = gds_save_binary_file(output_file_flag ? output_file : "/dev/stdout") != 0)
{
return errorcode;
}
}
return 0;
}

View File

@ -1,2 +0,0 @@
# Time, s Reading, raw Reading, V

View File

@ -1,4 +0,0 @@
#!/bin/sh
#works only for ascii files with headers
#prints every 100th line
cat $1 | sed '1,/Waveform/d' | awk '!(NR%100)||(NR==2)'> $2