devices almost work

This commit is contained in:
Глеб Луговцов 2022-11-28 18:31:51 +03:00
parent 4a67a9aefa
commit e655d0e747
17 changed files with 175375 additions and 341 deletions

View File

@ -1,2 +1,45 @@
#include "Generator.hpp" #include "Generator.hpp"
#include <fstream>
Generator::Generator() : m_channel("C1")
{
std::string response = query("*IDN?");
response.erase(0, response.find(',') + 1);
response.erase(response.find(','));
// name = response;
}
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,17 +1,22 @@
#pragma once #pragma once
#include "Device.hpp"
class Generator : public Device #include <string>
#include <iostream>
#include "Utils.hpp"
class Generator
{ {
public: public:
Generator(std::string path_name) : Device(path_name), m_channel("C1") {} Generator();
void set_channel(size_t channel) void command(std::string const &comm) const;
std::string query(std::string const &comm) const;
void set_channel(channels ch)
{ {
if (channel == 1 || channel == 2) m_channel = "C" + std::to_string(static_cast<ind_t>(ch));
m_channel = "C" + std::to_string(channel);
else
std::cerr << "Invalid channel" << std::endl;
} }
void buzz() void buzz()
@ -50,5 +55,6 @@ public:
} }
private: private:
std::string m_root_path;
std::string m_channel; std::string m_channel;
}; };

View File

@ -4,19 +4,16 @@ EXECUTABLE=start
all: $(EXECUTABLE) all: $(EXECUTABLE)
$(EXECUTABLE): main.o Device.o Generator.o Oscilloscope.o $(EXECUTABLE): main.o Generator.o Oscilloscope.o
$(CC) main.o Device.o Generator.o Oscilloscope.o -o main $(CC) main.o Generator.o Oscilloscope.o -o main
main.o: main.cpp main.o: main.cpp
$(CC) $(CFLAGS) main.cpp $(CC) $(CFLAGS) main.cpp
Device.o: Device.cpp Generator.o: Generator.cpp Generator.hpp
$(CC) $(CFLAGS) Device.cpp
Generator.o: Generator.cpp
$(CC) $(CFLAGS) Generator.cpp $(CC) $(CFLAGS) Generator.cpp
Oscilloscope.o: Oscilloscope.cpp Oscilloscope.o: Oscilloscope.cpp Oscilloscope.hpp
$(CC) $(CFLAGS) Oscilloscope.cpp $(CC) $(CFLAGS) Oscilloscope.cpp
clean: clean:

View File

@ -1 +1,128 @@
#include "Oscilloscope.hpp" #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,61 +1,70 @@
#pragma once #pragma once
#include "Device.hpp" #include <iostream>
#include "Measurement.hpp"
#include <string> #include <string>
#include <unistd.h> #include <exception>
#include <fstream>
class Oscilloscope : public Device #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: public:
Oscilloscope(std::string path_name) : Device(path_name), m_channel("C1") {} Oscilloscope(std::string server_ip = "10.11.13.220", port_t server_port = 5024);
void set_channel(size_t channel) size_t command(std::string const &comm)
{ {
if (channel == 1 || channel == 2) return send(m_client_side, comm.c_str(), comm.length(), 0);
m_channel = "C" + std::to_string(channel);
else
std::cerr << "Invalid channel" << std::endl;
} }
Measurement get_pkpk() std::string request();
size_t request(char *buf, size_t msg_size);
std::string query(std::string const& comm);
void set_channel(channels ch)
{ {
comm_param_custom("PKPK"); m_channel = "C" + std::to_string(static_cast<ind_t>(ch));
comm_param_stat(1);
// size_t count = 0;
// while (count <= 20)
// {
// std::string response = quer_param_value("STAT1");
// size_t count_ind = response.find("count,") + 5;
// std::string count_str = response.substr(count_ind);
// std::cerr << count_str;
// comm_param_stat(0);
// count = std::stoi(count_str);
// }
std::string response = quer_param_value("STAT1");
comm_param_stat(0);
std::cout << response << std::endl;
return Measurement(response, 1);
} }
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: private:
void comm_param_custom(std::string param) int m_client_side;
{
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; std::string m_channel;
}; };

View File

@ -0,0 +1,10 @@
#pragma once
enum class channels
{
C1 = 1,
C2 = 2
};
using port_t = std::size_t;
using ind_t = std::size_t;

View File

@ -10,7 +10,7 @@ Device::Device(std::string path_name) : root_path("/dev/" + path_name)
name = response; name = response;
} }
void Device::command(std::string comm) void Device::command(std::string const &comm) const
{ {
std::ofstream out; std::ofstream out;
out.open(root_path); out.open(root_path);
@ -24,7 +24,7 @@ void Device::command(std::string comm)
} }
} }
std::string Device::query(std::string comm) std::string Device::query(std::string const &comm) const
{ {
command(comm); command(comm);

View File

@ -13,12 +13,9 @@ public:
return name; return name;
} }
void command(std::string comm); void command(std::string const &comm) const;
std::string query(std::string comm); std::string query(std::string const &comm) const;
protected:
std::string name;
std::string root_path;
}; };

View File

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

View File

@ -0,0 +1,113 @@
#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,36 +1,9 @@
#include "Generator.hpp" #include "Generator.hpp"
#include "Oscilloscope.hpp" #include "Oscilloscope.hpp"
#include <vector> #include "Utils.hpp"
#include <unistd.h>
int main() { int main()
{
// initialize generator and oscilloscope
std::string generator_path;
std::string oscilloscope_path;
for (size_t i = 0; i < 2; i++) {
auto path = "usbtmc" + std::to_string(i);
Device device(path);
if (device.get_name() == "AKIP-3409-4")
generator_path = path;
else if (device.get_name() == "AKIP-4131/1")
oscilloscope_path = path;
else {
std::cerr << "Devices not available!" << std::endl;
return EXIT_FAILURE;
}
}
Generator generator(generator_path);
Oscilloscope oscilloscope(oscilloscope_path);
// work with devices
std::cout << oscilloscope.query("C1:WF? DAT2").substr(1, 3) << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1,13 +0,0 @@
## Channel commands
TRA -- trace
VDIV -- vertical sensitivity
## MEASURE commands
PACU -- parameter custom
PAVA? -- parameter value
## WAVEFORM commands
#todo

File diff suppressed because one or more lines are too long

View File

@ -1,52 +0,0 @@
voltage[V],time[ns]
0.5049,0.0000
0.5592,1.0000
0.5913,2.0000
0.5997,3.0000
0.5843,4.0000
0.5456,5.0000
0.4851,6.0000
0.4053,7.0000
0.3093,8.0000
0.2010,9.0000
0.0847,10.0000
-0.0350,11.0000
-0.1533,12.0000
-0.2655,13.0000
-0.3671,14.0000
-0.4541,15.0000
-0.5229,16.0000
-0.5710,17.0000
-0.5962,18.0000
-0.5977,19.0000
-0.5754,20.0000
-0.5301,21.0000
-0.4637,22.0000
-0.3788,23.0000
-0.2788,24.0000
-0.1676,25.0000
-0.0499,26.0000
0.0699,27.0000
0.1869,28.0000
0.2965,29.0000
0.3942,30.0000
0.4762,31.0000
0.5392,32.0000
0.5808,33.0000
0.5991,34.0000
0.5936,35.0000
0.5644,36.0000
0.5128,37.0000
0.4406,38.0000
0.3510,39.0000
0.2473,40.0000
0.1337,41.0000
0.0149,42.0000
-0.1046,43.0000
-0.2199,44.0000
-0.3264,45.0000
-0.4199,46.0000
-0.4967,47.0000
-0.5537,48.0000
-0.5886,49.0000
-0.6000,50.0000
1 voltage[V] time[ns]
2 0.5049 0.0000
3 0.5592 1.0000
4 0.5913 2.0000
5 0.5997 3.0000
6 0.5843 4.0000
7 0.5456 5.0000
8 0.4851 6.0000
9 0.4053 7.0000
10 0.3093 8.0000
11 0.2010 9.0000
12 0.0847 10.0000
13 -0.0350 11.0000
14 -0.1533 12.0000
15 -0.2655 13.0000
16 -0.3671 14.0000
17 -0.4541 15.0000
18 -0.5229 16.0000
19 -0.5710 17.0000
20 -0.5962 18.0000
21 -0.5977 19.0000
22 -0.5754 20.0000
23 -0.5301 21.0000
24 -0.4637 22.0000
25 -0.3788 23.0000
26 -0.2788 24.0000
27 -0.1676 25.0000
28 -0.0499 26.0000
29 0.0699 27.0000
30 0.1869 28.0000
31 0.2965 29.0000
32 0.3942 30.0000
33 0.4762 31.0000
34 0.5392 32.0000
35 0.5808 33.0000
36 0.5991 34.0000
37 0.5936 35.0000
38 0.5644 36.0000
39 0.5128 37.0000
40 0.4406 38.0000
41 0.3510 39.0000
42 0.2473 40.0000
43 0.1337 41.0000
44 0.0149 42.0000
45 -0.1046 43.0000
46 -0.2199 44.0000
47 -0.3264 45.0000
48 -0.4199 46.0000
49 -0.4967 47.0000
50 -0.5537 48.0000
51 -0.5886 49.0000
52 -0.6000 50.0000

View File

@ -1,52 +0,0 @@
voltage[V],time[ns]
0.3637,0.0000
0.3234,1.0000
0.2702,2.0000
0.2062,3.0000
0.1340,4.0000
0.0564,5.0000
-0.0233,6.0000
-0.1022,7.0000
-0.1770,8.0000
-0.2447,9.0000
-0.3027,10.0000
-0.3486,11.0000
-0.3806,12.0000
-0.3975,13.0000
-0.3985,14.0000
-0.3836,15.0000
-0.3534,16.0000
-0.3091,17.0000
-0.2525,18.0000
-0.1858,19.0000
-0.1118,20.0000
-0.0332,21.0000
0.0466,22.0000
0.1246,23.0000
0.1976,24.0000
0.2628,25.0000
0.3175,26.0000
0.3595,27.0000
0.3872,28.0000
0.3994,29.0000
0.3957,30.0000
0.3763,31.0000
0.3418,32.0000
0.2938,33.0000
0.2340,34.0000
0.1648,35.0000
0.0892,36.0000
0.0099,37.0000
-0.0697,38.0000
-0.1466,39.0000
-0.2176,40.0000
-0.2799,41.0000
-0.3311,42.0000
-0.3691,43.0000
-0.3924,44.0000
-0.4000,45.0000
-0.3917,46.0000
-0.3677,47.0000
-0.3291,48.0000
-0.2774,49.0000
-0.2146,50.0000
1 voltage[V] time[ns]
2 0.3637 0.0000
3 0.3234 1.0000
4 0.2702 2.0000
5 0.2062 3.0000
6 0.1340 4.0000
7 0.0564 5.0000
8 -0.0233 6.0000
9 -0.1022 7.0000
10 -0.1770 8.0000
11 -0.2447 9.0000
12 -0.3027 10.0000
13 -0.3486 11.0000
14 -0.3806 12.0000
15 -0.3975 13.0000
16 -0.3985 14.0000
17 -0.3836 15.0000
18 -0.3534 16.0000
19 -0.3091 17.0000
20 -0.2525 18.0000
21 -0.1858 19.0000
22 -0.1118 20.0000
23 -0.0332 21.0000
24 0.0466 22.0000
25 0.1246 23.0000
26 0.1976 24.0000
27 0.2628 25.0000
28 0.3175 26.0000
29 0.3595 27.0000
30 0.3872 28.0000
31 0.3994 29.0000
32 0.3957 30.0000
33 0.3763 31.0000
34 0.3418 32.0000
35 0.2938 33.0000
36 0.2340 34.0000
37 0.1648 35.0000
38 0.0892 36.0000
39 0.0099 37.0000
40 -0.0697 38.0000
41 -0.1466 39.0000
42 -0.2176 40.0000
43 -0.2799 41.0000
44 -0.3311 42.0000
45 -0.3691 43.0000
46 -0.3924 44.0000
47 -0.4000 45.0000
48 -0.3917 46.0000
49 -0.3677 47.0000
50 -0.3291 48.0000
51 -0.2774 49.0000
52 -0.2146 50.0000

175001
project/hardware/waveform.csv Normal file

File diff suppressed because it is too large Load Diff