example for yaml-cpp 0.5.3 in linux - linux

I am pretty new to yaml-cpp. After did tutorials, that tutorials are fine. But When I try to Parse my own yaml file, it's a litte difficult for me. I am confused with "operator" and "node".
yaml file is shown below.
Device:
DeviceName: "/dev/ttyS2"
Baud: 19200
Parity: "N"
DataBits: 8
StopBits: 1
Control:
Kp: 5000
Ki: 8
FVF: 100
VFF: 1962
Could you anyone give me an example to get data from that yaml file? thanks for your help.
Also i followed this question , I can build it. But When I run it, I got Segmentation fault (core dumped)
Code:
#include <yaml-cpp/yaml.h>
#include <string>
#include <iostream>
using namespace std;
int main()
{
YAML::Node config = YAML::LoadFile("init.yaml");
//read device
std::string DeviceName = config["Device"][0]["DeviceName"].as<std::string>();
int Baud = config["Device"][1]["Baud"].as<int>();
std::string Parity = config["Device"][2]["Parity"].as<std::string>();
int DataBits = config["Device"][3]["DataBits"].as<int>();
int StopBits = config["Device"][4]["StopBits"].as<int>();
//read control
int Kp = config["Control"][0]["Kp"].as<int>();
int Ki = config["Control"][1]["Ki"].as<int>();
int FVF = config["Control"][2]["FVF"].as<int>();
int VFF = config["Control"][3]["VFF"].as<int>();
cout <<"DeviceName" << DeviceName << endl;
cout <<"Baud" << Baud << endl;
cout <<"Parity" << Parity << endl;
cout <<"DataBits" << DataBits << endl;
cout <<"StopBits" << StopBits << endl;
cout <<"Kp" << Kp << endl;
cout <<"Ki" << Ki << endl;
cout <<"FVF" << FVF << endl;
cout <<"VFF" << VFF << endl;
return 0;
}

your code above results in a bad conversion exception because you access the map items in a wrong way.
instead of
std::string DeviceName = config["Device"][0]["DeviceName"].as<std::string>();
just write
std::string DeviceName = config["Device"]["DeviceName"].as<std::string>();
best regards
robert

Related

I'm trying to use I2C with beaglebone but I cannot write more than 1 byte

I'm trying to control DAC5571 with Beaglebone Black. My kernel version is:
Linux beaglebone 4.14.108-ti-r137 #1stretch SMP PREEMPT Tue Aug 25 01:48:39 UTC 2020 armv7l GNU/Linux
I can partially the control the DAC IC. As you can see here, you need to send 3 bytes; Slave Address, CTRL/MSB and LSB. The IC recognizes Slave address bytes and CTRL/MSB. I can read and confirm the output of the output pin. But when I start increasing the voltage value slowly as Vout += 0.05, output increasing as 0.2, 0.4, 0.6, etc...
I've checked with my oscilloscope and I can confirm that the third byte is being transmitted as 0x00 no matter what its the actual value is.
Here is my source code:
int DAC5571::writeI2CDeviceByte(int value)
{
cout << "Starting DAC5571 I2C sensor state write" << endl;
char namebuf[MAX_BUS];
snprintf(namebuf, sizeof(namebuf), "/dev/i2c-%d", I2CBus);
int file;
if ((file = open(namebuf, O_RDWR)) < 0) {
cout << "Failed to open DAC5571 Sensor on " << namebuf << " I2C Bus" << endl;
return(1);
}
if (ioctl(file, I2C_SLAVE, I2CAddress) < 0) {
cout << "I2C_SLAVE address " << I2CAddress << " failed..." << endl;
return(2);
}
int buffer[2];
buffer[0] = value>>8;
buffer[1] = value & 0xFF;
cout << "buffer [0] is " << buffer[0] << endl;
cout << "buffer [1] is " << buffer[1] << endl;
if (write(file, buffer, 2) != 2) {
cout << "Failure to write values to I2C Device address." << endl;
return(3);
}
close(file);
cout << "Finished DAC5571 I2C sensor state write" << endl;
return 0;
}
Here is the console output:
Starting DAC5571 I2C sensor state write
buffer [0] is 3
buffer [1] is 128
Finished DAC5571 I2C sensor state write
I've seen on my research there is a header file called as "i2c-core.h" but I could not include into my projects which has a block write function. Not sure if that would help in my situation.
Can anyone please help me to solve my issue about not being able to transmit LSB part of the data?
Thank you.
int buffer[2];
buffer[0] = value>>8;
buffer[1] = value & 0xFF;
if ( write(file, buffer, 2) != 2) { ... }
The elements of buffer are of type int, which is 4 bytes long. So when you write buffer with a length of 2, you write 2 bytes, which are the first two bytes of the integer buffer[0]. In your example buffer[0] is 3, so since this machine is little-endian, it consists of the bytes 03 00 00 00 and you write out 03 00.
You probably want unsigned char buffer[2]; or maybe uint8_t buffer[2];, so that each element is a byte.

How to scan strings with spaces in cpp in a new line?

enter image description here3(no of cases)
hello world
a b c d
data structures and algorithms.
Let say above is the given input format.Each string starts in a new line.Can i know how to read in the above way in cpp.I tried with getline function.It didn't work.
The getline method should work just fine. The following code works fine.
#include <iostream>
using namespace std;
int main(){
string s[3];
getline(cin, s[0]);
getline(cin, s[1]);
getline(cin, s[2]);
cout << s[0] << endl << s[1] << endl << s[2];
return 0;
}
EDIT:
After your clarification, it seems that the problem is actually that the buffer is not being cleared properly. So just use cin.ignore(); after cin >> t;
Refer to the code below:
#include <iostream>
using namespace std;
int main(){
int t;
cin >>t;
cin.ignore(); // This should clear the input buffer
string s;
getline(cin, s);
cout << s << endl;
return 0;
}

I cannot run my There is always an error sign next to my getline function and I don't know and understand how to fix it?

# include <iostream>
# include <cmath>
using namespace std;
int main();
{
string color, plural noun, celebrity;
cout << "Enter a color: ";
getline(cin, color);
return 0;
}
There are errors in your code. Firstly, have you included #include <string> and #include <iostream> directives. Moreover, your code is as follows:
int main();{
string color, plural noun, celebrity;
cout<<"Enter a color: ";
getline(cin, color);
return 0;
}
However, if you notice, you have placed a semicolon (;) after the int main function, which might be giving you an error.
Also, as you were discussing in the comment section, declare plural noun as pluralNoun or plural_noun; never leave a space. I addition, a string is never called as cout<<"Roses are {color}"<<endl;, strings have to be called as:
#include<iostream>
#include <string>
int main();{
string color, pluralNoun, celebrity;
cout << "Enter a color: ";
getline(cin, color);
cout << "Roses are " << color << endl;
cout << "Enter a plural noun: ";
getline(cin,pluralNoun);
cout << pluralNoun << "are blue" << endl;
return 0;
}
The code above and your latter code; if executed in the same way as above will definitely not give you an error. Hope this helped you overcome the problem! :)

Multiples threads running on one core instead of four depending on the OS

I am using Raspbian on Raspberry 3.
I need to divide my code in few blocks (2 or 4) and assign a thread per block to speed up calculations.
At the moment, I am testing with simple loops (see attached code) on one thread and then on 4 threads. And executions time on 4 threads is always 4 times longer, so it looks like this 4 threads are scheduled to run on the same CPU.
How to assign each thread to run on other CPUs? Even 2 threads on 2 CPUs should make big difference to me.
I even tried to use g++6 and no improvement. And using parallel libs openmp in the code with "#pragma omp for" still running on one CPU.
I tried to run this code on Fedora Linux x86 and I had the same behavior, but on Windows 8.1 and VS2015 i have got different results where time was the same one one thread and then on 4 threads, so it was running on different CPUs.
Would you have any suggestions??
Thank you.
#include <iostream>
//#include <arm_neon.h>
#include <ctime>
#include <thread>
#include <mutex>
#include <iostream>
#include <vector>
using namespace std;
float simd_dot0() {
unsigned int i;
unsigned long rezult;
for (i = 0; i < 0xfffffff; i++) {
rezult = i;
}
return rezult;
}
int main() {
unsigned num_cpus = std::thread::hardware_concurrency();
std::mutex iomutex;
std::vector<std::thread> threads(num_cpus);
cout << "Start Test 1 CPU" << endl; // prints !!!Hello World!!!
double t_start, t_end, scan_time;
scan_time = 0;
t_start = clock();
simd_dot0();
t_end = clock();
scan_time += t_end - t_start;
std::cout << "\nExecution time on 1 CPU: "
<< 1000.0 * scan_time / CLOCKS_PER_SEC << "ms" << std::endl;
cout << "Finish Test on 1 CPU" << endl; // prints !!!Hello World!!!
cout << "Start Test 4 CPU" << endl; // prints !!!Hello World!!!
scan_time = 0;
t_start = clock();
for (unsigned i = 0; i < 4; ++i) {
threads[i] = std::thread([&iomutex, i] {
{
simd_dot0();
std::cout << "\nExecution time on CPU: "
<< i << std::endl;
}
// Simulate important work done by the tread by sleeping for a bit...
});
}
for (auto& t : threads) {
t.join();
}
t_end = clock();
scan_time += t_end - t_start;
std::cout << "\nExecution time on 4 CPUs: "
<< 1000.0 * scan_time / CLOCKS_PER_SEC << "ms" << std::endl;
cout << "Finish Test on 4 CPU" << endl; // prints !!!Hello World!!!
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
while (1);
return 0;
}
Edit :
On Raspberry Pi3 Raspbian I used g++4.9 and 6 with the following flags :
-std=c++11 -ftree-vectorize -Wl--no-as-needed -lpthread -march=armv8-a+crc -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -funsafe-math-optimizations -O3

What could be the possible reasons for segmentation fault?

The code snippet is following:
ValueMapIter valueIter;
for (valueIter = activeValues->begin(); valueIter !=activeValues->end(); ++valueIter)
{
cout << "Before First" << endl;
cout << "sizeactivevalue:" << activeValues->size() << endl;
cout << "first:" << valueIter->first << "Second:" << valueIter->second << endl;
}
The PROGRAM output while running with gdb is:
The program outputs
Before First
sizeactivevalue:10
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x2aaaac8ad940 (LWP 8346)]
0x000000000043e732 in ValueManager::InsertModValue (this=0xd455c90, Id=4615, PId=7753, eId=1100000010570903, iId=2, inId=44301, pe=830795, t=25, bl=2, ste=3, sde=2)
at /home/pathtofile/valuemanager.cpp:304
304 cout << "first:" << valueIter->first << "Second:" << valueIter->second << endl;
How can it receive a segmentation fault, while I have a local copy of ValueMapIter and it ran on the code correctly previously.
The program is multithreaded; there is only one activeValues map. The snippet is inside the InsertModValues function.
The size of the activeValue map is 10 then How can the iter not have a valid first element ?

Resources