DeleteCriticalSection could not locate dll - c++

I am trying to recompile an old Win32 software package in order to bring small modifications.
The package is part of the MT SDK from Xsens and allows to get output from a inertial sensor (available here https://content.xsens.com/hubfs/Downloads/Software/mtsdk3.3_setup.zip). Example of a C++ routine using a DLL file responsible for the communication with hardware is located in Program Files\Xsens\MT SDK\Software Developpement\Examples\CMT Example Dll.
From directory I recompiled the source code, linking the DLL such as
i686-w64-mingw32-g++ -o test main.cpp -L. -lxsens_cmt
It requires changing a few scanf_s calls to scanf but compiled properly into test.exe.
However, when I try to run that executable in Windows I get the following error:
enter image description here
On the net I could find recommendation to compile with the following options but none could resolve my issue :
-static
-static-libstdc++
-static-libgcc
Examples folder of the MTSDK can be downloaded here if you don't want to install the software :
https://gitlab.com/lenhofed/mtsdk_modifs.git
main.cpp
/* demo key, replace this key with your own */
#define KEY "b8r6RCoGjQJVsytwUMo8WCRiJiVCCdoL11cCj4HqnaKPHtTn"
#include <stdio.h> // Needed for printf etc
#include <objbase.h> // Needed for COM functionality
#include "xsens_cmt.h"
#include <conio.h> // included for _getch and _kbhit
#include "main.h"
// this macro tests for an error and exits the program with a message if there was one
#define EXIT_ON_ERROR(res,comment) if (res != XRV_OK) { printf("Error %d occurred in " comment ": %s\n",res,cmtGetResultText(res)); exit(1); }
long instance = -1;
// used to signal that the user initiated the exit, so we do not wait for an extra keypress-
int userQuit = 0;
CmtOutputMode mode;
CmtOutputSettings settings;
unsigned short mtCount = 0;
int screenSensorOffset = 0;
int temperatureOffset = 0;
CmtDeviceId deviceIds[256];
CmtVector positionLLA;
int main(void)
{
XsensResultValue res = XRV_OK;
short screenSkipFactor = 10;
short screenSkipFactorCnt = screenSkipFactor;
// Set exit function
atexit(exitFunc);
// lets create the Xsens CMT instance to handle the sensor(s)
printf("Creating an XsensCMT instance\n");
char serialNumber[] = KEY;
if (strcmp(serialNumber,"b8r6RCoGjQJVsytwUMo8WCRiJiVCCdoL11cCj4HqnaKPHtTn") == 0)
printf("Warning: Using the demo key as a serial code will limit CMT functionality to 1000 calls. Enter your own serial code for unlimited CMT functionality.\n");
instance = cmtCreateInstance(serialNumber);
if (instance != -1)
printf("CMT instance created\n\n");
else {
printf("Creation of CMT instance failed, probably because of an invalid serial number\n");
exit(1);
}
// Perform hardware scan
doHardwareScan();
// Give user a (short) chance to see hardware scan results
Sleep(2000);
//clear screen present & get the user output mode selection.
clrscr();
getUserInputs();
// Set device to user input settings
doMtSettings();
// Wait for first data item(s) to arrive. In production code, you would use a callback function instead (see cmtRegisterCallback function)
Sleep(20);
//get the placement offsets, clear the screen and write the fixed headers.
calcScreenOffset();
clrscr();
writeHeaders();
// vars for sample counter & temp.
unsigned short sdata;
double tdata;
//structs to hold data.
CmtCalData caldata;
CmtQuat qat_data;
CmtEuler euler_data;
CmtMatrix matrix_data;
while(!userQuit && res == XRV_OK)
{
//get the bundle of data
res = cmtGetNextDataBundle(instance);
Sleep(10);
//get sample count, goto position & display.
res = cmtDataGetSampleCounter(instance, &sdata, deviceIds[0] ,NULL);
gotoxy(0,0);
printf("Sample Counter %05hu\n", sdata);
if (screenSkipFactorCnt++ == screenSkipFactor) {
screenSkipFactorCnt = 0;
for (unsigned int i = 0; i < mtCount; i++) {
// Output Temperature
if ((mode & CMT_OUTPUTMODE_TEMP) != 0) {
gotoxy(0,4 + i * screenSensorOffset);
res = cmtDataGetTemp(instance, &tdata, deviceIds[i],NULL);
printf("%6.2f", tdata);
}
gotoxy(0,5 + temperatureOffset + i * screenSensorOffset); // Output Calibrated data
if ((mode & CMT_OUTPUTMODE_CALIB) != 0) {
res = cmtDataGetCalData(instance, &caldata, deviceIds[i]);
printf("%6.2f\t%6.2f\t%6.2f" , caldata.m_acc.m_data[0], caldata.m_acc.m_data[1], caldata.m_acc.m_data[2]);
gotoxy(0,7 + temperatureOffset + i * screenSensorOffset);
printf("%6.2f\t%6.2f\t%6.2f", caldata.m_gyr.m_data[0], caldata.m_gyr.m_data[1], caldata.m_gyr.m_data[2] );
gotoxy(0,9 + temperatureOffset + i * screenSensorOffset);
printf("%6.2f\t%6.2f\t%6.2f",caldata.m_mag.m_data[0], caldata.m_mag.m_data[1], caldata.m_mag.m_data[2]);
gotoxy(0,13 + temperatureOffset + i * screenSensorOffset);
}
if ((mode & CMT_OUTPUTMODE_ORIENT) != 0) {
switch(settings & CMT_OUTPUTSETTINGS_ORIENTMODE_MASK) {
case CMT_OUTPUTSETTINGS_ORIENTMODE_QUATERNION:
// Output: quaternion
res = cmtDataGetOriQuat(instance, &qat_data, deviceIds[i]);
printf("%6.3f\t%6.3f\t%6.3f\t%6.3f\n", qat_data.m_data[0], qat_data.m_data[1],qat_data.m_data[2],qat_data.m_data[3]);
break;
case CMT_OUTPUTSETTINGS_ORIENTMODE_EULER:
// Output: Euler
res = cmtDataGetOriEuler(instance, &euler_data, deviceIds[i]);
printf("%6.1f\t%6.1f\t%6.1f\n", euler_data.m_roll,euler_data.m_pitch, euler_data.m_yaw);
break;
case CMT_OUTPUTSETTINGS_ORIENTMODE_MATRIX:
// Output: Cosine Matrix
res = cmtDataGetOriMatrix(instance, &matrix_data, deviceIds[i],NULL);
printf("%6.3f\t%6.3f\t%6.3f\n", matrix_data.m_data[0][0],matrix_data.m_data[0][1], matrix_data.m_data[0][2]);
printf("%6.3f\t%6.3f\t%6.3f\n", matrix_data.m_data[1][0],matrix_data.m_data[1][1], matrix_data.m_data[1][2]);
printf("%6.3f\t%6.3f\t%6.3f\n", matrix_data.m_data[2][0],matrix_data.m_data[2][1], matrix_data.m_data[2][2]);
break;
default:
;
}
}
if ((mode & CMT_OUTPUTMODE_POSITION) != 0) {
/* output position */
printf("\n\n");
if (cmtDataContainsPositionLLA(instance, deviceIds[i]) != 0) {
res = cmtDataGetPositionLLA(instance, &positionLLA, deviceIds[i]);
if (res != XRV_OK) {
printf("error %ud", res);
}
for (int i = 0; i < 2; i++) {
double deg = positionLLA.m_data[i];
double min = (deg - (int)deg)*60;
double sec = (min - (int)min)*60;
printf("%3d\xa7%2d\'%2.2lf\"\t", (int)deg, (int)min, sec);
}
printf(" %3.2lf\n", positionLLA.m_data[2]);
} else {
printf("No position data available\n");
}
}
}
}
if (_kbhit())
userQuit = 1;
}
clrscr();
cmtClose(instance);
return 0;
}
//////////////////////////////////////////////////////////////////////////
// doHardwareScan
//
// Checks available COM ports and scans for MotionTrackers
void doHardwareScan()
{
XsensResultValue res;
CmtPortInfo portInfo[256];
uint32_t portCount = 0;
printf("Scanning for connected Xsens devices...");
res = cmtScanPorts(portInfo, &portCount, 0);
EXIT_ON_ERROR(res,"cmtScanPorts");
printf("done\n");
if (portCount == 0) {
printf("No MotionTrackers found\n\n");
exit(0);
}
for(int i = 0; i < (int)portCount; i++) {
printf("Using COM port %d at %d baud\n\n",
(long) portInfo[i].m_portNr, portInfo[i].m_baudrate);
}
printf("Opening ports...");
//open the port which the device is connected to and connect at the device's baudrate.
for(int p = 0; p < (int)portCount; p++){
res = cmtOpenPort(instance, portInfo[p].m_portNr, portInfo[p].m_baudrate);
EXIT_ON_ERROR(res,"cmtOpenPort");
}
printf("done\n\n");
//get the Mt sensor count.
printf("Retrieving MotionTracker count (excluding attached Xbus Master(s))\n");
res = cmtGetMtCount(instance,&mtCount);
EXIT_ON_ERROR(res,"cmtGetMtCount");
printf("MotionTracker count: %i\n\n",mtCount);
// retrieve the device IDs
printf("Retrieving MotionTrackers device ID(s)\n");
for(unsigned int j = 0; j < mtCount; j++ ){
res = cmtGetMtDeviceId(instance, &deviceIds[j], j);
EXIT_ON_ERROR(res,"cmtGetDeviceId");
printf("Device ID at index %i: %08x\n",j,(long) deviceIds[j]);
}
// make sure that we get the freshest data
printf("\nSetting queue mode so that we always get the latest data\n\n");
res = cmtSetQueueMode(instance,CMT_QM_LAST);
EXIT_ON_ERROR(res,"cmtSetQueueMode");
}
//////////////////////////////////////////////////////////////////////////
// getUserInputs
//
// Request user for output data
void getUserInputs()
{
mode = 0;
while (mode < 1 || mode > 6) {
printf("Select desired output:\n");
printf("1 - Calibrated data\n");
printf("2 - Orientation data and GPS Position (MTi-G only)\n");
printf("3 - Both Calibrated and Orientation data\n");
printf("4 - Temperature and Calibrated data\n");
printf("5 - Temperature and Orientation data\n");
printf("6 - Temperature, Calibrated and Orientation data\n");
printf("Enter your choice: ");
scanf("%d", &mode);
// flush stdin
while (getchar() != '\n') continue;
if (mode < 1 || mode > 6) {
printf("\n\nPlease enter a valid output mode\n");
}
}
clrscr();
switch(mode)
{
case 1:
mode = CMT_OUTPUTMODE_CALIB;
break;
case 2:
mode = CMT_OUTPUTMODE_ORIENT | CMT_OUTPUTMODE_POSITION;
break;
case 3:
mode = CMT_OUTPUTMODE_CALIB | CMT_OUTPUTMODE_ORIENT;
break;
case 4:
mode = CMT_OUTPUTMODE_TEMP | CMT_OUTPUTMODE_CALIB;
break;
case 5:
mode = CMT_OUTPUTMODE_TEMP | CMT_OUTPUTMODE_ORIENT;
break;
case 6:
mode = CMT_OUTPUTMODE_TEMP | CMT_OUTPUTMODE_CALIB | CMT_OUTPUTMODE_ORIENT;
break;
}
if ((mode & CMT_OUTPUTMODE_ORIENT) != 0) {
do{
printf("Select desired output format\n");
printf("1 - Quaternions\n");
printf("2 - Euler angles\n");
printf("3 - Matrix\n");
printf("Enter your choice: ");
scanf("%d", &settings);
// flush stdin
while (getchar() != '\n') continue;
if (settings < 1 || settings > 3) {
printf("\n\nPlease enter a valid choice\n");
}
}while(settings < 1 || settings > 3);
// Update outputSettings to match data specs of SetOutputSettings
switch(settings) {
case 1:
settings = CMT_OUTPUTSETTINGS_ORIENTMODE_QUATERNION;
break;
case 2:
settings = CMT_OUTPUTSETTINGS_ORIENTMODE_EULER;
break;
case 3:
settings = CMT_OUTPUTSETTINGS_ORIENTMODE_MATRIX;
break;
}
}
else{
settings = 0;
}
settings |= CMT_OUTPUTSETTINGS_TIMESTAMP_SAMPLECNT;
}
//////////////////////////////////////////////////////////////////////////
// doMTSettings
//
// Set user settings in MTi/MTx
// Assumes initialized global MTComm class
void doMtSettings(void)
{
XsensResultValue res;
// set sensor to config sate
res = cmtGotoConfig(instance);
EXIT_ON_ERROR(res, "cmtGotoConfig");
unsigned short sampleFreq;
res = cmtGetSampleFrequency(instance, &sampleFreq, deviceIds[0]);
// set the device output mode for the device(s)
printf("Configuring your mode selection");
for (int i=0; i < mtCount; i++) {
if (cmtIdIsMtig(deviceIds[i])) {
res = cmtSetDeviceMode(instance, mode,settings, sampleFreq, deviceIds[i]);
} else {
res = cmtSetDeviceMode(instance, mode & 0xFF0F, settings, sampleFreq, deviceIds[i]);
}
EXIT_ON_ERROR(res, "setDeviceMode");
}
// start receiving data
res = cmtGotoMeasurement(instance);
EXIT_ON_ERROR(res, "cmtGotoMeasurement");
}
//////////////////////////////////////////////////////////////////////////
// writeHeaders
//
// Write appropriate headers to screen
void writeHeaders()
{
for (unsigned int i = 0; i < mtCount; i++) {
gotoxy(0, 2 + i * screenSensorOffset);
printf("MotionTracker %d\n", i + 1);
if ((mode & CMT_OUTPUTMODE_TEMP) != 0) {
temperatureOffset = 3;
gotoxy(0,3 + i * screenSensorOffset);
printf("Temperature");
gotoxy(7,4 + i * screenSensorOffset);
printf("degrees celcius");
gotoxy(0,6 + i * screenSensorOffset);
}
if ((mode & CMT_OUTPUTMODE_CALIB) != 0) {
gotoxy(0,3 + temperatureOffset + i * screenSensorOffset);
printf("Calibrated sensor data");
gotoxy(0,4 + temperatureOffset + i * screenSensorOffset);
printf(" Acc X\t Acc Y\t Acc Z");
gotoxy(23, 5 + temperatureOffset + i * screenSensorOffset);
printf("(m/s^2)");
gotoxy(0,6 + temperatureOffset + i * screenSensorOffset);
printf(" Gyr X\t Gyr Y\t Gyr Z");
gotoxy(23, 7 + temperatureOffset + i * screenSensorOffset);
printf("(rad/s)");
gotoxy(0,8 + temperatureOffset + i * screenSensorOffset);
printf(" Mag X\t Mag Y\t Mag Z");
gotoxy(23, 9 + temperatureOffset + i * screenSensorOffset);
printf("(a.u.)");
gotoxy(0,11 + temperatureOffset + i * screenSensorOffset);
}
if ((mode & CMT_OUTPUTMODE_ORIENT) != 0) {
printf("Orientation data\n");
switch(settings & CMT_OUTPUTSETTINGS_ORIENTMODE_MASK) {
case CMT_OUTPUTSETTINGS_ORIENTMODE_QUATERNION:
printf(" q0\t q1\t q2\t q3\n");
break;
case CMT_OUTPUTSETTINGS_ORIENTMODE_EULER:
printf(" Roll\t Pitch\t Yaw\n");
printf(" degrees\n");
break;
case CMT_OUTPUTSETTINGS_ORIENTMODE_MATRIX:
printf(" Matrix\n");
break;
default:
;
}
}
if ((mode & CMT_OUTPUTMODE_POSITION) != 0) {
printf("\nLongitude\tLatitude\t Altitude\n");
}
}
}
//////////////////////////////////////////////////////////////////////////
// calcScreenOffset
//
// Calculates offset for screen data with multiple sensors.
void calcScreenOffset()
{
// 1 line for "Sensor ..."
screenSensorOffset += 1;
if ((mode & CMT_OUTPUTMODE_TEMP) != 0)
screenSensorOffset += 3;
if ((mode & CMT_OUTPUTMODE_CALIB) != 0)
screenSensorOffset += 8;
if ((mode & CMT_OUTPUTMODE_ORIENT) != 0) {
switch(settings & CMT_OUTPUTSETTINGS_ORIENTMODE_MASK) {
case CMT_OUTPUTSETTINGS_ORIENTMODE_QUATERNION:
screenSensorOffset += 4;
break;
case CMT_OUTPUTSETTINGS_ORIENTMODE_EULER:
screenSensorOffset += 4;
break;
case CMT_OUTPUTSETTINGS_ORIENTMODE_MATRIX:
screenSensorOffset += 6;
break;
default:
;
}
if ((mode & CMT_OUTPUTMODE_POSITION) != 0)
screenSensorOffset += 4;
}
}
//////////////////////////////////////////////////////////////////////////
// clrscr
//
// Clear console screen
void clrscr()
{
#ifdef WIN32
CONSOLE_SCREEN_BUFFER_INFO csbi;
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord = {0, 0};
DWORD count;
GetConsoleScreenBufferInfo(hStdOut, &csbi);
FillConsoleOutputCharacter(hStdOut, ' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
SetConsoleCursorPosition(hStdOut, coord);
#else
int i;
for (i = 0; i < 100; i++)
// Insert new lines to create a blank screen
putchar('\n');
gotoxy(0,0);
#endif
}
//////////////////////////////////////////////////////////////////////////
// gotoxy
//
// Sets the cursor position at the specified console position
//
// Input
// x : New horizontal cursor position
// y : New vertical cursor position
void gotoxy(int x, int y)
{
#ifdef WIN32
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
#else
char essq[100]; // String variable to hold the escape sequence
char xstr[100]; // Strings to hold the x and y coordinates
char ystr[100]; // Escape sequences must be built with characters
/*
** Convert the screen coordinates to strings
*/
sprintf(xstr, "%d", x);
sprintf(ystr, "%d", y);
/*
** Build the escape sequence (vertical move)
*/
essq[0] = '\0';
strcat(essq, "\033[");
strcat(essq, ystr);
/*
** Described in man terminfo as vpa=\E[%p1%dd
** Vertical position absolute
*/
strcat(essq, "d");
/*
** Horizontal move
** Horizontal position absolute
*/
strcat(essq, "\033[");
strcat(essq, xstr);
// Described in man terminfo as hpa=\E[%p1%dG
strcat(essq, "G");
/*
** Execute the escape sequence
** This will move the cursor to x, y
*/
printf("%s", essq);
#endif
}
//////////////////////////////////////////////////////////////////////////
// exitFunc
//
// Closes cmt nicely
void exitFunc(void)
{
// if we have a valid instance, we should get rid of it at the end of the program
if (instance != -1) {
// Close any open COM ports
cmtClose(instance);
cmtDestroyInstance(instance);
}
// get rid of keystrokes before we post our message
while (_kbhit()) _getch();
// wait for a keypress
if (!userQuit)
{
//printf("Press a key to exit\n");
//_getch();
}
}
main.h
void doHardwareScan();
void doMtSettings(void);
void getUserInputs(void);
void clrscr(void);
void writeHeaders(void);
void gotoxy(int x, int y);
void calcScreenOffset(void);
void exitFunc(void);

Related

(Arduino) Can I skip multiple characters in a parseInt()?

Pretty much what the title says. From the arduino website:
Syntax
Serial.parseInt()
Serial.parseInt(char skipChar)
Parameters
skipChar: used to skip the indicated char in the search. Used for example to skip thousands divider.
Am I able to use a charmap or something similar to skip multiple characters?
Maybe you could read from Serial, but take digits only? And then parse string? Dirty example:
val = 0;
while (Serial.available() > 0) {
int c = Serial.read();
if (isDigit(c)) {
val = val * 10 + c; // Thanks to #Danny_ds for this
}
}
// Print *val*
I ended up using a very different method to get it working by using char arrays and not relying on timing. So far it has worked perfectly. I was using this to get my arduino to work as a temp monitor.
How it communicates the temperatures
PC > OpenHardwaremonitor > WMI > Batch Script (shown below) > COM Port > Arduino > LCD
This was the only way that I could get cpu temps correctly because it's so old
Batch code:
#echo off
mode COM3: baud=9600 data=8 >nul
wmic /namespace:\\root\openhardwaremonitor path sensor where "Identifier='/intelcpu/0/temperature/0' or Identifier='/nvidiagpu/0/temperature/0'" get Value /every:2|findstr [0-9]>COM3
Arduino code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
bool sounded = false;
int cpu = 0;
int gpu = 0;
char invalids[3] = {10, 32, '\0'}; // line feed, space
boolean newData = false;
const byte numChars = 8;
char charMap[numChars];
char tempChars[numChars];
void setup() {
pinMode(6, OUTPUT); // character intensity
pinMode(8, OUTPUT); // buzzer
pinMode(10, OUTPUT); // backlight
lcd.begin(16, 2);
Serial.begin(9600);
analogWrite(6, 100); // set intensity without POT
analogWrite(10, 168); // ~3.3v
analogReference(EXTERNAL);
lcd.print("CPU: ");
lcd.print((char)223);
lcd.print("C AIR:");
lcd.setCursor(0, 1);
lcd.print("GPU: ");
lcd.print((char)223);
lcd.print("C ");
lcd.print((char)223);
lcd.print("F");
}
void loop() {
recvWithoutWhitespace();
if (newData == true) {
parseData();
lcd.setCursor(4, 0);
lcd.print(cpu);
lcd.setCursor(4, 1);
lcd.print(gpu);
int reading = analogRead(A0);
float degreesF = (((reading * 3.3 / 1024 - 0.5) * 100) * 1.8) + 32.0;
lcd.setCursor(11, 1);
lcd.print((int)(degreesF+0.5));
if(!sounded && (cpu > 75 || gpu > 85)) { // used for buzzer alarm
tone(8, 500);
delay(250);
noTone(8);
delay(250);
tone(8, 500);
delay(250);
noTone(8);
delay(250);
tone(8, 500);
delay(250);
noTone(8);
sounded = true;
} else if(sounded && (cpu <= 75 && gpu <= 85)) {
sounded = false;
}
newData = false;
}
}
void recvWithoutWhitespace() {
static byte ndx = 0;
static byte control = 0; // switch control variable
char endMarker = 13; // ASCII code for carriage return
char rc;
char * check;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
check=strchr(invalids,rc); //checks if any spaces or line feeds get in
if (check==NULL){
if (rc != endMarker) {
charMap[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
switch(control) { // expect 4 CRs in format: (num)CRCR(num)CRCR
case 0:
control = 1; // skip first of 2 CRs
break;
case 1:
charMap[ndx] = 44; // put comma in place of CR between numbers as delimeter
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
control = 2;
break;
case 2:
control = 3; // skip first of 2 CRs
break;
case 3:
charMap[ndx] = '\0'; // string terminator in place of last CR
ndx = 0;
control = 0;
newData = true;
break;
}
}
}
}
}
void parseData() {
strcpy(tempChars, charMap); //strtok is destructive so copy string temporarily
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ",");
cpu = atoi(strtokIndx); // convert cpu to an integer
strtokIndx = strtok(NULL, ",");
gpu = atoi(strtokIndx); // convert gpu to an integer
}

Why when I change the value (file in linux belong to gpio pin) from 1 to 0, nothing changed?

I have a matrix relay with a nanopi fire (like rasperry pi). I connected this relay to my device and want to change gpio value.(my device has multi gpio pin. first I should create gpio(echo 95 > /sys/class/gpio/export) and then change direction folder "out" (echo "out" > /sys/class/gpio/gpio95/direction) and with changing value the relay should turn on and off.)
this is my code:
bool GPIOClass::ChangeValue(QString IO, QString port)
{
QString gpio;
QString comand;
// comand=" echo ";
// comand.append(QIO);
// comand.append(" > ");
// gpio=config->GpioFromPort(port);
// if(gpio.length()==0)
// return false;
// //IO should be 1 or 0
QString src=IdenGPIOSrc(gpio);//src is /sys/class/gpio/gpio95
src.append("/value");
// comand.append(src);
// qDebug()<<port<<gpio<<"with src:"
// <<src <<"with command:"<<comand;
// system(comand.toStdString().c_str());
///===========================================================
QFile file(src);
if ( file.open(QIODevice::WriteOnly) )
{
//clear the content
// file.resize(0);
file.seek(0);
file.write(QByteArray::number(IO.toInt()),1);
}
if(GetValue(port)==IO.toInt())
{
return true;
}
else
return false;
}
the relay is not changed, but when I run the executable sample the relay is turn on and off:
int main(int argc, char ** argv)
{
int pin = GPIO_PIN(7);
int i, value, board;
int ret = -1;
if ((board = boardInit()) < 0) {
printf("Fail to init board\n");
return -1;
}
if (board == BOARD_NANOPI_T2)
pin = GPIO_PIN(15);
if (argc == 2)
pin = GPIO_PIN(atoi(argv[1]));
if ((ret = exportGPIOPin(pin)) == -1) {
printf("exportGPIOPin(%d) failed\n", pin);
}
if ((ret = setGPIODirection(pin, GPIO_OUT)) == -1) {
printf("setGPIODirection(%d) failed\n", pin);
}
for (i = 0; i < STATUS_CHANGE_TIMES; i++) {
if (i % 2) {
value = GPIO_HIGH;
} else {
value = GPIO_LOW;
}
if ((ret = setGPIOValue(pin, value)) > 0) {
printf("%d: GPIO_PIN(%d) value is %d\n", i+1, pin, value);
} else {
printf("setGPIOValue(%d) failed\n", pin);
}
sleep(1);
}
unexportGPIOPin(pin);
return 0;
}
in that code also the value in that address changed like my code (change value file to 1 and 0 ) and the relay is working. where is the diffrence between my code and that code? both of them change the value content.
where is my code problem?

some error(maybe about pointer) when writing shell

what I expect: it will store the last ten commands entered in the terminal. And you can see them when you press ctrl+c. If you want to exit, just press ctrl+d.
So I implemented with queue to store commands. But after 'length = read(STDIN_FILENO, inputBuffer, MAX_LINE);', all the elements in queue are the newest command.(e.g. COMMAND->date queue:date; COMMAND->cal queue:cal cal)
It was normal before the 'read'. But it doesn't help when I replaced it with 'fgets(inputBuffer,MAX_LINE,stdin);'.And in this way, I don't know how to catch 'ctrl+d' because there is no signal corresponding to it(like SIGINT and ctrl+c) so I had to check if the length equals to 0.
how to solve this problem?
#include <signal.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <sys/wait.h>
#include <queue>
using namespace std;
#define BUFFER_SIZE 50
#define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
struct mes{
char* _args[MAX_LINE/2+1];
int len;
int bg;
int erno;
mes(){
len = 0;
bg = false;
memset(_args,0,sizeof(_args));
}
mes(char* new_args[],int _len,int _bg){
len = _len;
bg = _bg;
for(int i = 0; i < len; ++i){
_args[i] = new_args[i];
}
_args[len] = NULL;
}
void show(){
if(erno==-1) cout<<"ERROR:";
for(int i=0;i<len;i++)
cout<<_args[i]<<" ";
if(bg) cout<<"&"<<endl;
else cout<<endl;
}
~mes(){
memset(_args,0,sizeof(_args));
// for(int i=0; i<len && args[i]; i++){
// delete args[i];
// args[i]=NULL;
// }
// delete[] args;
// args=NULL;
}
};
queue <mes*> rec, quetmp;
static int reclen = 0;
static int totlen = 0;
void readSplit(char inputBuffer[], char *args[], int * background){
int length, /* # of characters in the command line */
i, /* loop index for accessing inputBuffer array */
start, /* index where beginning of next command parameter is */
ct; /* index of where to place the next parameter into args[] */
ct = 0;
if(!rec.empty()){
cout<<"before read"<<endl;
cout<<rec.front()->_args[0]<<endl;
cout<<"size:"<<sizeof(rec.front()->_args[0])<<'\n';
for(int k = 0; k < sizeof(rec.front()->_args[0]); ++k)
cout<<'*'<<rec.front()->_args[0][k]<<endl;
cout<<"end"<<endl;
}
/* read what the user enters on the command line */
// char *tmp = fgets(inputBuffer,MAX_LINE,stdin);
length = read(STDIN_FILENO, inputBuffer, MAX_LINE);
if(!rec.empty()){
cout<<"after read"<<endl;
cout<<rec.front()->_args[0]<<'\n';
cout<<"size:"<<sizeof(rec.front()->_args[0])<<'\n';
for(int k = 0; k < sizeof(rec.front()->_args[0]); ++k)
cout<<'*'<<rec.front()->_args[0][k]<<endl;
cout<<"end"<<endl;
}
start = -1;
if (length == 0){
write(STDOUT_FILENO,inputBuffer,strlen(inputBuffer));//write the last instruction
exit(0); /* ^d was entered, end of user command stream */
}
if (length < 0){
perror("error reading the command");
exit(-1); /* terminate with error code of -1 */
}
/* examine every character in the inputBuffer */
for (i=0;i<length;i++) {
switch (inputBuffer[i]){
case ' ':
case '\t' : /* argument separators */
if(start != -1){
args[ct] = &inputBuffer[start]; /* set up pointer */
ct++;
}
inputBuffer[i] = '\0'; /* add a null char; make a C string */
start = -1;
break;
case '\n': /* should be the final char examined */
if (start != -1){
args[ct] = &inputBuffer[start];
ct++;
}
inputBuffer[i] = '\0';
args[ct] = NULL; /* no more arguments to this command */
break;
default : /* some other character */
if (start == -1)
start = i;
if (inputBuffer[i] == '&'){
*background = 1;
inputBuffer[i] = '\0';
}
}
}
args[ct] = NULL; /* just in case the input line was > 80 */
// mes* pmes = new mes(args, ct, *background);
}
/**
* setup() reads in the next command line, separating it into distinct tokens
* using whitespace as delimiters. setup() sets the args parameter as a
* null-terminated string.
*/
//args end with NULL
//only deal with splitted command
void setup(char inputBuffer[], char *args[],int *background)
{
readSplit(inputBuffer, args, background);
int len = 0;
while(args[len]) ++len;
mes* pmes = new mes(args, len, *background);
int * p_errno=(int*)mmap(NULL,sizeof(int)*2,PROT_READ|PROT_WRITE,\
MAP_SHARED|MAP_ANONYMOUS,-1,0);
int * p_errno;
int pid = fork();
if(pid == 0){
int erno = execvp(args[0], args);
*p_errno = erno;
_exit(0);
}
else{
if(!(*background)){
waitpid(pid, NULL, 0);
}
// }
pmes->erno = 1;
pmes->erno = *p_errno;
if(reclen < 10){
rec.push(pmes);
++reclen;
}
else{
rec.pop();
rec.push(pmes);
}
++totlen;
}
void handle_SIGINT(int sig){// ctrl+c
int num = totlen - reclen, index = 0;
mes* ls[10];
cout<<endl;
while(!rec.empty()){
cout<<++num<<": ";
rec.front()->show();
quetmp.push(rec.front());
ls[index++] = rec.front();
rec.pop();
}
while(!quetmp.empty()){
rec.push(quetmp.front());
quetmp.pop();
}
cout<<"Exit record input \"q\", repeat command,\
input \"r\" or \"r x\"(x is the prefix of command)"<<endl;
char buffer[MAX_LINE];
char *arguments[MAX_LINE/2+1];
int flag;
int exeNum = index - 1;
while(true){
readSplit(buffer, arguments, &flag);
int num_arg = 0;
while(arguments[num_arg]) ++num_arg;
if(num_arg == 0) continue;
if(strcmp(arguments[0], "p") == 0) break;
if(strcmp(arguments[0], "r") != 0){
cout<<"No such command"<<endl;
continue;
}
if(num_arg == 1){
}
else if(num_arg != 2 || strlen(arguments[1]) != 1){
cout<<"invalid input"<<endl;
continue;
}
else{
for(; exeNum >= 0; --exeNum){
if(ls[exeNum]->args[0][0] == arguments[1][0]){
break;
}
}
}
if(exeNum >= 0){
ls[exeNum]->show();
if(ls[exeNum]->erno == -1){
cout<<"It is an error command"<<endl;
}
else{
setup(buffer, ls[exeNum]->args, & (ls[exeNum]->bg));
}
}
}
cout<<"record has quitted"<<endl;
}
int main(void)
{
char inputBuffer[MAX_LINE]; /* buffer to hold the command entered */
int background; /* equals 1 if a command is followed by '&' */
char *args[MAX_LINE/2+1];/* command line (of 80) has max of 40 arguments */
// signal(SIGINT,handle_SIGINT);
while (1){ /* Program terminates normally inside setup */
background = 0;
printf("COMMAND->");
fflush(stdout);
// readSplit(inputBuffer, args, &background);
setup(inputBuffer,args,&background); /* get next command */
}
}

cap_libv4l.cpp v4l2_buffer->timestamp is always 0

I am using OpenCv 2.4.8 on Linux, and obtaining a USB webcam (logitech C200) capture for further processing. I have determined that the capture uses cap_libv4.cpp (present in modlules/highgui) to capture the image. I had to modify the said file to add support for timestamps.
I have tried it with a number of webcams, and noticed it only gives correct timestamps if the flags field in the structure v4l2_buffer is 0. If it is equal to 2, which corresponds to V4L2_BUF_FLAG_TIMESTAMP MONOTONIC, it gives 0. I am wondering if it is a problem with my code modification, or with the libv4l drivers.
The function read_frame_v4l2 reads the buffer, and updates the timestamp. The timestamp can be read using the function icvGetPropertyCAM_V4L. The modified codes for these two functions are as below:
icvGetPropertyCAM_V4L:
static double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture,
int property_id ) {
char name[32];
int is_v4l2_device = 0;
/* initialize the control structure */
switch (property_id) {
case CV_CAP_PROP_FRAME_WIDTH:
case CV_CAP_PROP_FRAME_HEIGHT:
CLEAR (capture->form);
capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) {
/* display an error message, and return an error code */
perror ("VIDIOC_G_FMT");
if (v4l1_ioctl (capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) < 0) {
fprintf (stderr, "HIGHGUI ERROR: V4L: Unable to determine size of incoming image\n");
icvCloseCAM_V4L(capture);
return -1;
} else {
int retval = (property_id == CV_CAP_PROP_FRAME_WIDTH)?capture->captureWindow.width:capture->captureWindow.height;
return retval / 0xFFFF;
}
}
return (property_id == CV_CAP_PROP_FRAME_WIDTH)?capture->form.fmt.pix.width:capture->form.fmt.pix.height;
case CV_CAP_PROP_BRIGHTNESS:
sprintf(name, "Brightness");
capture->control.id = V4L2_CID_BRIGHTNESS;
break;
case CV_CAP_PROP_CONTRAST:
sprintf(name, "Contrast");
capture->control.id = V4L2_CID_CONTRAST;
break;
case CV_CAP_PROP_SATURATION:
sprintf(name, "Saturation");
capture->control.id = V4L2_CID_SATURATION;
break;
case CV_CAP_PROP_HUE:
sprintf(name, "Hue");
capture->control.id = V4L2_CID_HUE;
break;
case CV_CAP_PROP_GAIN:
sprintf(name, "Gain");
capture->control.id = V4L2_CID_GAIN;
break;
case CV_CAP_PROP_EXPOSURE:
sprintf(name, "Exposure");
capture->control.id = V4L2_CID_EXPOSURE;
break;
case CV_CAP_PROP_POS_MSEC:
if (capture->FirstCapture) {
return 0;
} else {
return 1000 * capture->timestamp.tv_sec + ((double) capture->timestamp.tv_usec) / 1000;
}
break;
default:
sprintf(name, "<unknown property string>");
capture->control.id = property_id;
}
if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &capture->control) == 0) {
/* all went well */
is_v4l2_device = 1;
} else {
fprintf(stderr, "HIGHGUI ERROR: V4L2: Unable to get property %s(%u) - %s\n", name, capture->control.id, strerror(errno));
}
if (is_v4l2_device == 1) {
/* get the min/max values */
int v4l2_min = v4l2_get_ctrl_min(capture, capture->control.id);
int v4l2_max = v4l2_get_ctrl_max(capture, capture->control.id);
if ((v4l2_min == -1) && (v4l2_max == -1)) {
fprintf(stderr, "HIGHGUI ERROR: V4L2: Property %s(%u) not supported by device\n", name, property_id);
return -1;
}
/* all was OK, so convert to 0.0 - 1.0 range, and return the value */
return ((float)capture->control.value - v4l2_min) / (v4l2_max - v4l2_min);
} else {
/* TODO: review this section */
int retval = -1;
switch (property_id) {
case CV_CAP_PROP_BRIGHTNESS:
retval = capture->imageProperties.brightness;
break;
case CV_CAP_PROP_CONTRAST:
retval = capture->imageProperties.contrast;
break;
case CV_CAP_PROP_SATURATION:
retval = capture->imageProperties.colour;
break;
case CV_CAP_PROP_HUE:
retval = capture->imageProperties.hue;
break;
case CV_CAP_PROP_GAIN:
fprintf(stderr, "HIGHGUI ERROR: V4L: Gain control in V4L is not supported\n");
return -1;
break;
case CV_CAP_PROP_EXPOSURE:
fprintf(stderr, "HIGHGUI ERROR: V4L: Exposure control in V4L is not supported\n");
return -1;
break;
}
if (retval == -1) {
/* there was a problem */
return -1;
}
/* all was OK, so convert to 0.0 - 1.0 range, and return the value */
return float (retval) / 0xFFFF;
}
}
read_frame_v4l2:
static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index)
{
static int autoindex;
autoindex = 0;
char deviceName[MAX_DEVICE_DRIVER_NAME];
if (!numCameras)
icvInitCapture_V4L(); /* Havent called icvInitCapture yet - do it now! */
if (!numCameras)
return NULL; /* Are there any /dev/video input sources? */
//search index in indexList
if ( (index>-1) && ! ((1 << index) & indexList) )
{
fprintf( stderr, "HIGHGUI ERROR: V4L: index %d is not correct!\n",index);
return NULL; /* Did someone ask for not correct video source number? */
}
/* Allocate memory for this humongus CvCaptureCAM_V4L structure that contains ALL
the handles for V4L processing */
CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L));
if (!capture) {
fprintf( stderr, "HIGHGUI ERROR: V4L: Could not allocate memory for capture process.\n");
return NULL;
}
#ifdef USE_TEMP_BUFFER
capture->buffers[MAX_V4L_BUFFERS].start = NULL;
#endif
/* Select camera, or rather, V4L video source */
if (index<0) { // Asking for the first device available
for (; autoindex<MAX_CAMERAS;autoindex++)
if (indexList & (1<<autoindex))
break;
if (autoindex==MAX_CAMERAS)
return NULL;
index=autoindex;
autoindex++;// i can recall icvOpenCAM_V4l with index=-1 for next camera
}
/* Print the CameraNumber at the end of the string with a width of one character */
sprintf(deviceName, "/dev/video%1d", index);
/* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */
memset(capture,0,sizeof(CvCaptureCAM_V4L));
/* Present the routines needed for V4L funtionality. They are inserted as part of
the standard set of cv calls promoting transparency. "Vector Table" insertion. */
capture->FirstCapture = 1;
/* set the default size */
capture->width = DEFAULT_V4L_WIDTH;
capture->height = DEFAULT_V4L_HEIGHT;
if (_capture_V4L2 (capture, deviceName) == -1) {
icvCloseCAM_V4L(capture);
capture->is_v4l2_device = 0;
if (_capture_V4L (capture, deviceName) == -1) {
icvCloseCAM_V4L(capture);
return NULL;
}
} else {
capture->is_v4l2_device = 1;
}
return capture;
}; /* End icvOpenCAM_V4L */
#ifdef HAVE_CAMV4L2
static int read_frame_v4l2(CvCaptureCAM_V4L* capture) {
struct v4l2_buffer buf;
CLEAR (buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl (capture->deviceHandle, VIDIOC_DQBUF, &buf)) {
switch (errno) {
case EAGAIN:
return 0;
case EIO:
/* Could ignore EIO, see spec. */
/* fall through */
default:
/* display the error and stop processing */
perror ("VIDIOC_DQBUF");
return -1;
}
}
assert(buf.index < capture->req.count);
#ifdef USE_TEMP_BUFFER
memcpy(capture->buffers[MAX_V4L_BUFFERS].start,
capture->buffers[buf.index].start,
capture->buffers[MAX_V4L_BUFFERS].length );
capture->bufferIndex = MAX_V4L_BUFFERS;
//printf("got data in buff %d, len=%d, flags=0x%X, seq=%d, used=%d)\n",
// buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused);
#else
capture->bufferIndex = buf.index;
#endif
if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf))
perror ("VIDIOC_QBUF");
//set timestamp in capture struct to be timestamp of most recent frame
/** where timestamps refer to the instant the field or frame was received by the driver, not the capture time*/
capture->timestamp = buf.timestamp; //
printf("Flags %0x.X, timestamp = %ld, %ld", buf.flags, buf.timestamp.tv_sec, buf.timestamp.tv_usec);
//prints 0 if the flags is of the 4th nibble from LSB is 2 i.e. of the form .....2xxx H
return 1;
}
I need the timestamp so as to determine velocity of an object I am detecting in the image. I have searched a lot and have not found any solution.

Input invisible c++ Maze Game

So I have most of my game finish up however, I want to save the score and name of the player to a text file and display it. So far the user input works and does save to a text file named score.txt however the input is invisible and you can't see what you are typing. Does anyone know why this is happening?
Main
int main()
{
DWORD mode; /* Preserved console mode */
INPUT_RECORD event; /* Input event */
BOOL EXITGAME = FALSE; /* Program termination flag */
unsigned int counter = 0; /* The number of times 'Esc' is pressed */
/* Get the console input handle */
HANDLE hstdin = GetStdHandle( STD_INPUT_HANDLE );
/* Preserve the original console mode */
GetConsoleMode( hstdin, &mode );
/* Set to no line-buffering, no echo, no special-key-processing */
SetConsoleMode( hstdin, 0 );
srand ( time(NULL) ); //initialize the random seed
// Variables
int health = 2;
// Declare variable positions
player.x=1;
player.y=1;
treasure.x = 20;
treasure.y = 5;
treasure.z= 0;
traps.x = 1;
traps.y = 7;
traps.z = 0;
lives.x = 1;
lives.y = 9;
ofstream file;
int score = 0;
string name;
string line;
/*
while(treasure.z < 2)
{
treasure.x = (rand() % 24);
treasure.y = (rand() % 16);
if(treasure.x == 0 && treasure.y == 0)
{
treasure.z++;
}
}
while(traps.z < 3)
{
traps.x = (rand() % 24);
traps.y = (rand() % 16);
if(traps.x == 0 && traps.y == 0)
{
traps.z++;
}
}
while(lives.z < 2)
{
lives.x = (rand() % 24);
lives.y = (rand() % 16);
}
*/
clrscr();
setcolor(15);
while (!EXITGAME)
{
if (WaitForSingleObject( hstdin, 0 ) == WAIT_OBJECT_0) /* if kbhit */
{
DWORD count; /* ignored */
/* Get the input event */
ReadConsoleInput( hstdin, &event, 1, &count );
/* Only respond to key release events */
if ((event.EventType == KEY_EVENT)
&& !event.Event.KeyEvent.bKeyDown)
clrscr();
putmenu();
gotoxy(6,20);
cout<<"Lives: " << health;
gotoxy(6,22);
cout<<"Score: " << score;
Sleep(50);
switch (event.Event.KeyEvent.wVirtualKeyCode)
{
case VK_ESCAPE:
clrscr();
putend();
EXITGAME = TRUE;
break;
case VK_LEFT:
// left key move player left
moveleft();
break;
case VK_RIGHT:
// right key move player right
moveright();
break;
case VK_UP:
// up key move player up
moveup();
break;
case VK_DOWN:
// down key move player down
movedown();
break;
case VK_A:
// left key move player left
moveleft();
break;
case VK_D:
// right key move player right
moveright();
break;
case VK_W:
// up key move player up
moveup();
break;
case VK_S:
// down key move player down
movedown();
break;
}//switch
puttreasure();
puttraps();
putlives();
putplayer();
if((player.x == lives.x) && (player.y == lives.y))
{
health++;
lives.x = 0;
lives.y = 0;
}
if((player.x == traps.x) && (player.y == traps.y))
{
health--;
traps.x = 0;
traps.y = 0;
}
if((player.x == treasure.x)&& (player.y == treasure.y))
{
score += 100;
EXITGAME = true;
}
else if(health == 0)
{
EXITGAME = true;
}
if(EXITGAME == true)
{
score = score + (health * 100);
}
}
}
if(EXITGAME == true)
{
// clear screen
clrscr();
}
setcolor(10);
cout << "Enter your name ";
cin >> name;
ofstream out("score.txt");
out << name;
out << "\n";
out << score;
out.close();
/* if(file.is_open())
{
while( getline (file, line))
cout << line << '\n';
}*/
gotoxy(1,23);cout<<" ";
SetConsoleMode( hstdin, mode );
return 0;
}
/* Set to no line-buffering, no echo, no special-key-processing */
You turned off echo - means that the user wont see what they type