#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
std::string GetFieldId(std::string sentenceId, int fieldIndex)
{
// Combine the sentence ID and field index to create the field ID
std::ostringstream oss;
oss << sentenceId << "-" << fieldIndex;
return oss.str();
}
std::vector<std::string> SplitString(std::string str, char delimiter)
{
std::vector<std::string> parts;
std::stringstream ss(str);
std::string part;
while (std::getline(ss, part, delimiter)) {
parts.push_back(part);
}
return parts;
}
std::map<std::string, std::string> ParseNmeaString(std::string nmeaString)
{
std::map<std::string, std::string> components;
if (nmeaString.length() < 7 || nmeaString[0] != '$' || nmeaString[nmeaString.length()-3] != '*') {
return components;
}
std::string sentence = nmeaString.substr(1, nmeaString.length()-4);
std::string checksum = nmeaString.substr(nmeaString.length()-2, 2);
std::vector<std::string> parts = SplitString(sentence, ',');
std::string sentenceId = parts[0];
for (int i = 1; i < parts.size(); i++) {
components[GetFieldId(sentenceId, i)] = parts[i];
}
return components;
}
int main()
{
std::string sentence = "$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76";
std::map<std::string, std::string> components = ParseNmeaString(sentence);
// Print the components to the console
for (auto const& component : components) {
std::cout << component.first << ": " << component.second << std::endl;
}
return 0;
}
Simple NMEA Parsing
C/C++ Programming Posted on 05 Apr, 2023 13:39:58- Comments(0) https://www.guivi.one/?p=228
- Share
On Mouse Leave MFC
C/C++ Programming, MFC Posted on 18 Feb, 2023 09:57:18simple article about how to use ON_WM_MOUSELEAVE leave on a button.
The button has to track the mouse while moues move (ON_WM_MOUSEMOVE) is called.
void CMYButton::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE|TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
m_point = point;
}
LRESULT CMYButton::OnMouseHover(WPARAM wparam, LPARAM lparam)
{
m_txtInfo->SetWindowText(m_strInformation);
return m_bTracking;
}
LRESULT CMYButton::OnMouseLeave(WPARAM wparam,LPARAM lparam)
{
m_txtInfo->SetWindowText("");
m_bTracking = FALSE;
return 0;
}
Source:
https://microsoft.public.vc.mfc.narkive.com/YBQSIfWf/on-mouseleave-and-cbutton-with-windows-xp-desktop-theme
- Comments(0) https://www.guivi.one/?p=219
- Share
fridge
Arduino, C/C++ Programming Posted on 19 Jul, 2022 22:01:48//----------------------Screen Bits
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void InitDisp(void)
{
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
// display.display();
// delay(2000); // Pause for 2 seconds
// Clear the buffer
display.clearDisplay();
}
void DisplayTemp(float cel)
{
display.clearDisplay();
display.setTextSize(2); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.cp437(true); // Use full 256 char 'Code Page 437' font
// Not all the characters will fit on the display. This is normal.
// Library will draw what it can and the rest will be clipped.
char buf[256];
int integerPart = (int)cel;
int decimalPart = ((int)(cel*100)%100);
sprintf(buf, "Temp:%d.%d", (int)cel, decimalPart);
for(int16_t i=0; i<strlen(buf); i++) {
display.write(buf[i]);
}
display.display();
}
//---------------------------------------------------------------------
//---------------------- Temperature Sensor
#include <OneWire.h>
OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary)
byte g_addr[8];
byte g_type_s;
void InitTemp(void)
{
if ( !ds.search(g_addr)) {
Serial.println("No addresse.");
Serial.println();
ds.reset_search();
delay(250);
while(true){};
}
Serial.print("ROM =");
for(int i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(g_addr[i], HEX);
}
if (OneWire::crc8(g_addr, 7) != g_addr[7]) {
Serial.println("CRC is not valid!");
while(true){};
}
Serial.println();
// the first ROM byte indicates which chip
switch (g_addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // or old DS1820
g_type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
g_type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
g_type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
}
//----------------------------------------------------------------------
//--------------------- Digital pins
const char SW1 = 2;
//---------------------- PROGRAM
void setup(void) {
Serial.begin(9600);
pinMode( SW1, OUTPUT);
digitalWrite(SW1, LOW);
InitTemp();
InitDisp();
}
void loop(void) {
byte i;
byte present = 0;
byte data[12];
float celsius, fahrenheit;
ds.reset();
ds.select(g_addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(g_addr);
ds.write(0xBE); // Read Scratchpad
/*
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
*/
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
/*
Serial.print(data[i], HEX);
Serial.print(" ");
*/
}
/*
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
*/
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (g_type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
// Do something with the temperature.
if (celsius <= 21)
digitalWrite(SW1, LOW);
else if (celsius > 21)
digitalWrite(SW1, HIGH);
// Display temperature
DisplayTemp(celsius);
}
- Comments(0) https://www.guivi.one/?p=186
- Share
Sharing serial ports
C/C++ Programming, Linux Posted on 22 Mar, 2022 21:15:39To share one serial port among a number of programs. Use socat to create some virtual ports to which the software are going to connect and then use the software below to organize the data flow.
Socat command to create interconnected virtual ports:
socat -d -d pty,raw,link=/home/user/serialThreeA,echo=0 pty,raw,link=/home/user/serialThreeB,echo=0
Source code of the data flow software:
// C library headers
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
#include <stdbool.h>
#include <pthread.h>
bool open_serial( char* serialport, int* serial_port)
{
if (serialport == NULL)
return 1;
(*serial_port) = open( serialport, O_RDWR);
// Create new termios struct, we call it 'tty' for convention
struct termios tty;
// Read in existing settings, and handle any error
if(tcgetattr((*serial_port), &tty) != 0) {
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
return 1;
}
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size
tty.c_cflag |= CS8; // 8 bits per byte (most common)
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
tty.c_lflag &= ~ICANON;
tty.c_lflag &= ~ECHO; // Disable echo
tty.c_lflag &= ~ECHOE; // Disable erasure
tty.c_lflag &= ~ECHONL; // Disable new-line echo
tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
// tty.c_oflag &= ~OXTABS; // Prevent conversion of tabs to spaces (NOT PRESENT ON LINUX)
// tty.c_oflag &= ~ONOEOT; // Prevent removal of C-d chars (0x004) in output (NOT PRESENT ON LINUX)
tty.c_cc[VTIME] = 10; // Wait for up to 1s (10 deciseconds), returning as soon as any data is received.
tty.c_cc[VMIN] = 0;
// Set in/out baud rate to be 9600
cfsetispeed(&tty, B9600);
cfsetospeed(&tty, B9600);
// Save tty settings, also checking for error
if (tcsetattr((*serial_port), TCSANOW, &tty) != 0) {
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
return 1;
}
return 0;
}
int serial_port_one, serial_port_two, serial_port_three;
void *thread_one(void *vargp)
{
while (true){
char read_buf [256];
int num_bytes = read(serial_port_one, &read_buf, sizeof(read_buf));
if (num_bytes > 0){
write(serial_port_two, read_buf, num_bytes);
write(serial_port_three, read_buf, num_bytes);
}
}
return NULL;
}
void *thread_two(void *vargp)
{
while (true){
char read_buf [256];
int num_bytes = read(serial_port_two, &read_buf, sizeof(read_buf));
if (num_bytes > 0){
write(serial_port_one, read_buf, num_bytes);
}
}
return NULL;
}
void *thread_three(void *vargp)
{
while (true){
char read_buf [256];
int num_bytes = read(serial_port_three, &read_buf, sizeof(read_buf));
if (num_bytes > 0){
write(serial_port_one, read_buf, num_bytes);
}
}
return NULL;
}
int main(int argc, char* argv[]) {
pthread_t threadone, threadtwo, threadthree;
// Open the serial port. Change device path as needed (currently set to an standard FTDI USB-UART cable type device)
//int serial_port_one;
if (open_serial(argv[1], &serial_port_one) != EXIT_SUCCESS)
return 1;
if (open_serial(argv[2], &serial_port_two) != EXIT_SUCCESS)
return 1;
if (open_serial(argv[3], &serial_port_three) != EXIT_SUCCESS)
return 1;
pthread_create(&threadone, NULL, thread_one, NULL);
pthread_create(&threadtwo, NULL, thread_two, NULL);
pthread_create(&threadthree, NULL, thread_three, NULL);
pthread_join(threadone, NULL);
pthread_join(threadtwo, NULL);
pthread_join(threadthree, NULL);
/*// Write to serial port
unsigned char msg[] = { 'H', 'e', 'l', 'l', 'o', '\r' };
write(serial_port_one, msg, sizeof(msg));
// Allocate memory for read buffer, set size according to your needs
char read_buf [256];
// Normally you wouldn't do this memset() call, but since we will just receive
// ASCII data for this example, we'll set everything to 0 so we can
// call printf() easily.
memset(&read_buf, '\0', sizeof(read_buf));
// Read bytes. The behaviour of read() (e.g. does it block?,
// how long does it block for?) depends on the configuration
// settings above, specifically VMIN and VTIME
int num_bytes = read(serial_port_one, &read_buf, sizeof(read_buf));
// n is the number of bytes read. n may be 0 if no bytes were received, and can also be -1 to signal an error.
if (num_bytes < 0) {
printf("Error reading: %s", strerror(errno));
return 1;
}
// Here we assume we received ASCII data, but you might be sending raw bytes (in that case, don't try and
// print it to the screen like this!)
printf("Read %i bytes. Received message: %s", num_bytes, read_buf);
printf("\r\n");*/
close(serial_port_one);
return 0; // success
};
- Comments(0) https://www.guivi.one/?p=179
- Share
Cross Compiling From Linux to Raspberry PI
C/C++ Programming, Linux, Pi Stuff Posted on 11 Jan, 2022 20:34:02Pre-requirements
Before you start you need to make sure the following is installed:
apt-get install git rsync cmake libc6-i386 lib32z1 lib32stdc++6
Let’s cross compile a Pie!
Start with making a folder in your home directory called raspberrypi
.
Go in to this folder and pull down the ENTIRE tools folder you mentioned above:
git clone https://github.com/raspberrypi/tools.git
You wanted to use the following of the 3 ones, gcc-linaro-arm-linux-gnueabihf-raspbian
, if I did not read wrong.
Go into your home directory and add:
export PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin
to the end of the file named ~/.bashrc
Now you can either log out and log back in (i.e. restart your terminal session), or run . ~/.bashrc
in your terminal to pick up the PATH
addition in your current terminal session.
Now, verify that you can access the compiler arm-linux-gnueabihf-gcc -v
. You should get something like this:
Using built-in specs. COLLECT_GCC=arm-linux-gnueabihf-gcc COLLECT_LTO_WRAPPER=/home/tudhalyas/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.2/lto-wrapper Target: arm-linux-gnueabihf Configured with: /cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.b uild/src/gcc-linaro-4.7-2012.08/configure –build=i686-build_pc-linux-gnu –host=i686-build_pc- linux-gnu –target=arm-linux-gnueabihf –prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-l inux-gnueabihf-raspbian-linux/install –with-sysroot=/cbuild/slaves/oort61/crosstool-ng/builds/ arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc –enable-languages=c,c++,fo rtran –disable-multilib –with-arch=armv6 –with-tune=arm1176jz-s –with-fpu=vfp –with-float= hard –with-pkgversion=’crosstool-NG linaro-1.13.1+bzr2458 – Linaro GCC 2012.08′ –with-bugurl= https://bugs.launchpad.net/gcc-linaro –enable-__cxa_atexit –enable-libmudflap –enable-libgom p –enable-libssp –with-gmp=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-rasp bian-linux/.build/arm-linux-gnueabihf/build/static –with-mpfr=/cbuild/slaves/oort61/crosstool- ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static –with-mpc =/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux- gnueabihf/build/static –with-ppl=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf -raspbian-linux/.build/arm-linux-gnueabihf/build/static –with-cloog=/cbuild/slaves/oort61/cros stool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static –wi th-libelf=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/a rm-linux-gnueabihf/build/static –with-host-libstdcxx=’-L/cbuild/slaves/oort61/crosstool-ng/bui lds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static/lib -lpwl’ –ena ble-threads=posix –disable-libstdcxx-pch –enable-linker-build-id –enable-plugin –enable-gol d –with-local-prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-li nux/install/arm-linux-gnueabihf/libc –enable-c99 –enable-long-long Thread model: posix gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 – Linaro GCC 2012.08 )
But hey! I did that and the libs still don’t work!
We’re not done yet! So far, we’ve only done the basics.
In your raspberrypi
folder, make a folder called rootfs
.
Now you need to copy the entire /lib
and /usr
directory to this newly created folder. I usually bring the rpi image up and copy it via rsync:
rsync -rl –delete-after –safe-links pi@192.168.1.PI:/{lib,usr} $HOME/raspberrypi/rootfs
where 192.168.1.PI
is replaced by the IP of your Raspberry Pi.
Now, we need to write a cmake
config file. Open ~/home/raspberrypi/pi.cmake
in your favorite editor and insert the following:
SET(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_SYSTEM_VERSION 1) SET(CMAKE_C_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc) SET(CMAKE_CXX_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++) SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/raspberrypi/rootfs) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Now you should be able to compile your cmake
programs simply by adding this extra flag: -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake
.
Using a cmake hello world example:
git clone https://github.com/jameskbride/cmake-hello-world.git cd cmake-hello-world mkdir build cd build cmake -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake ../ make scp CMakeHelloWorld pi@192.168.1.PI:/home/pi/ ssh pi@192.168.1.PI ./CMakeHelloWorld
I have taken the above from stackoverflow:
I did not managed to get the cmake to work as the pkg-config seem to have problems identifying where the libraries are and it was adding my libraries from teh host computer rather than the target ones. But following the same instructions it did worked fine when making my own call to the compiler and adding all the paths and libraries manually to the command.
- Comments(0) https://www.guivi.one/?p=172
- Share
Parsing results of a command line
C/C++ Programming, Linux Posted on 12 Nov, 2021 15:06:09#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <string>
using namespace std;
string exec(string command) {
char buffer[128];
string result = "";
// Open pipe to file
FILE* pipe = popen(command.c_str(), "r");
if (!pipe) {
return "popen failed!";
}
// read till end of process:
while (!feof(pipe)) {
// use buffer to read and add to result
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
int main() {
string ls = exec("ls");
cout << ls;
}
Taken from:
https://www.tutorialspoint.com/How-to-execute-a-command-and-get-the-output-of-command-within-Cplusplus-using-POSIX
- Comments(0) https://www.guivi.one/?p=168
- Share
OpenGL Things
C/C++ Programming Posted on 23 Aug, 2021 09:12:33Nice tutorials on modern OpenGL version 3:
https://github.com/SonarSystems/Modern-OpenGL-Tutorials
- Comments(0) https://www.guivi.one/?p=162
- Share
Email sending with libcurl
C/C++ Programming Posted on 23 Aug, 2021 09:00:24- Comments(0) https://www.guivi.one/?p=160
- Share