(Referring to the last if statement)I have some code here that keeps giving me the T_High always the same as T. If I am looking for the highest temperature that the code has seen, I am not sure if I need to add another variable and adjust my code or what my current problem is. I have tried looking this up online about max and mins, but even with multiple different sources I was not able to get it to work. I understand that after my if statement I have them being equaled to each other, but I thought that the if statement would take care of this. This is in particle IDE (very similar to Arduino).`
#include <math.h>
const int thermistor_output = A1;
void setup() {
Serial.begin(9600);
}
void loop() {
float T_Low = 999;
float T_High;
int x=0;
int thermistor_adc_val;
double a,b,c,d,e,f,g,h,i,j,T;
double output_voltage, thermistor_resistance, therm_res_ln, temperature_celsius;
while (x < 10 )
{
thermistor_adc_val = analogRead(thermistor_output);
output_voltage = ( (thermistor_adc_val * 3.3) / 4095.0 );
thermistor_resistance = ( ( 3.3 * ( 10.0 / output_voltage ) ) - 10 ); /* Resistance in kilo ohms */
thermistor_resistance = thermistor_resistance * 1000 ; /* Resistance in ohms */
therm_res_ln = log(thermistor_resistance);
/* Steinhart-Hart Thermistor Equation: */
/* Temperature in Kelvin = 1 / (A + B[ln(R)] + C[ln(R)]^3) */
/* where A = 0.001129148, B = 0.000234125 and C = 8.76741*10^-8 */
temperature_celsius = ( 1 / ( 0.001129148 + ( 0.000234125 * therm_res_ln ) + ( 0.0000000876741 * therm_res_ln * therm_res_ln * therm_res_ln ) ) ); /* Temperature in Kelvin */
temperature_celsius = temperature_celsius - 273.15; /* Temperature in degree Celsius */
T = temperature_celsius * 1.8 + 29; /* Temperature in degree Fahrenheit */
delay(100);
x ++ ;
if (x==1){a=T;}
if (x==2){b=T;}
if (x==3){c=T;}
if (x==4){d=T;}
if (x==5){e=T;}
if (x==6){f=T;}
if (x==7){g=T;}
if (x==8){h=T;}
if (x==9){i=T;}
}
j=a+b+c+d+e+f+g+h+i;
T=j/9;
x=0;
delay(2000);
if (T > T_High) {
T_High = T;
}
Particle.publish ("Temp", String(T));
Particle.publish ("High", String(T_High));
}
`
T_High is a local variable in loop(). It exists only until the loop() function exits. In the next iteration there will be a new instance of the T_High variable that has no relation to the previous one. Therefore you are not saving T_High's value throughout calls to loop().
Move the variable into file scope (i.e. outside the function definitions), so that it has static storage duration and survives throughout the whole program execution.
Also, you never initialize T_High to a value or assign to it before you do the test T > T_High. At this point T_High has indeterminate value and using an indeterminate value in almost any way causes the program to have undefined behavior, as is the case here.
If you move the variable to file scope, this particular problem will be remedied automatically, because static storage duration objects are always zero-initialized, but still it is advisable to initialize T_High to a sensible value, e.g.:
float T_High = 0;
or whatever works for your use case.
Related
I encountered a strange behavior in my C++ program that I don't understand and I don't know how to search for more information. So I ask for advice here hoping someone might know.
I have a class Interface that has a 2 dimensional vector that I initialize in the header :
class Interface {
public:
// code...
const unsigned short int SIZE_X_ = 64;
const unsigned short int SIZE_Y_ = 32;
std::vector<std::vector<bool>> screen_memory_ =
std::vector<std::vector<bool>>(SIZE_X_, std::vector<bool>(SIZE_Y_, false));
// code...
};
Here I expect that I have a SIZE_X_ x SIZE_Y_ vector filled with false booleans.
Later in my program I loop at a fixed rate like so :
void Emulator::loop() {
const milliseconds intervalPeriodMillis{static_cast<int>((1. / FREQ) * 1000)};
//Initialize the chrono timepoint & duration objects we'll be //using over & over inside our sleep loop
system_clock::time_point currentStartTime{system_clock::now()};
system_clock::time_point nextStartTime{currentStartTime};
while (!stop) {
currentStartTime = system_clock::now();
nextStartTime = currentStartTime + intervalPeriodMillis;
// ---- Stuff happens here ----
registers_->trigger_timers();
interface_->toogle_buzzer();
interface_->poll_events();
interface_->get_keys();
romParser_->step();
romParser_->decode();
// ---- ------------------ ----
stop = stop || interface_->requests_close();
std::this_thread::sleep_until(nextStartTime);
}
}
But then during the execution I get a segmentation fault
[1] 7585 segmentation fault (core dumped) ./CHIP8 coin.ch8
I checked with the debugger and some part of the screen_memory_ cannot be accessed anymore. And it seems to happen at random time.
But when I put the initialization of the vector in the constructor body like so :
Interface::Interface(const std::shared_ptr<reg::RegisterManager> & registers, bool hidden)
: registers_(registers) {
// code ...
screen_memory_ =
std::vector<std::vector<bool>>(SIZE_X_, std::vector<bool>(SIZE_Y_, false));
// code ...
}
The segmentation fault doesn't happen anymore. So the solution is just to initialize the vector in the constructor body.
But why ? what is happening there ?
I don't understand what I did wrong, I'm sure someone knows.
Thanks for your help !
[Edit] I found the source of the bug (Or at least what to change so it doesnt give me a segfault anymore).
In my class Interface I use the SDL and SDL_audio libraries to create the display and the buzzer sound. Have a special look where I set the callback want_.callback, the callback Interface::forward_audio_callback and Interface::audio_callback. Here's the code :
// (c) 2021 Maxandre Ogeret
// Licensed under MIT License
#include "Interface.h"
Interface::Interface(const std::shared_ptr<reg::RegisterManager> & registers, bool hidden)
: registers_(registers) {
if (SDL_Init(SDL_INIT_AUDIO != 0) || SDL_Init(SDL_INIT_VIDEO) != 0) {
throw std::runtime_error("Unable to initialize rendering engine.");
}
want_.freq = SAMPLE_RATE;
want_.format = AUDIO_S16SYS;
want_.channels = 1;
want_.samples = 2048;
want_.callback = Interface::forward_audio_callback;
want_.userdata = &sound_userdata_;
if (SDL_OpenAudio(&want_, &have_) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Failed to open audio: %s", SDL_GetError());
}
if (want_.format != have_.format) {
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Failed to get the desired AudioSpec");
}
window = SDL_CreateWindow("CHIP8", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SIZE_X_ * SIZE_MULTIPLIER_, SIZE_Y_ * SIZE_MULTIPLIER_,
hidden ? SDL_WINDOW_HIDDEN : 0);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
bpp_ = SDL_GetWindowSurface(window)->format->BytesPerPixel;
SDL_Delay(1000);
// screen_memory_ = std::vector<std::vector<bool>>(SIZE_X_, std::vector<bool>(SIZE_Y_, false));
}
Interface::~Interface() {
SDL_CloseAudio();
SDL_DestroyWindow(window);
SDL_Quit();
}
// code ...
void Interface::audio_callback(void * user_data, Uint8 * raw_buffer, int bytes) {
audio_buffer_ = reinterpret_cast<Sint16 *>(raw_buffer);
sample_length_ = bytes / 2;
int & sample_nr(*(int *) user_data);
for (int i = 0; i < sample_length_; i++, sample_nr++) {
double time = (double) sample_nr / (double) SAMPLE_RATE;
audio_buffer_[i] = static_cast<Sint16>(
AMPLITUDE * (2 * (2 * floor(220.0f * time) - floor(2 * 220.0f * time)) + 1));
}
}
void Interface::forward_audio_callback(void * user_data, Uint8 * raw_buffer, int bytes) {
static_cast<Interface *>(user_data)->audio_callback(user_data, raw_buffer, bytes);
}
}
In the function Interface::audio_callback, replacing the class variable assignation :
sample_length_ = bytes / 2;
By an int creation and assignation :
int sample_length = bytes / 2;
which gives :
void Interface::audio_callback(void * user_data, Uint8 * raw_buffer, int bytes) {
audio_buffer_ = reinterpret_cast<Sint16 *>(raw_buffer);
int sample_length = bytes / 2;
int &sample_nr(*(int*)user_data);
for(int i = 0; i < sample_length; i++, sample_nr++)
{
double time = (double)sample_nr / (double)SAMPLE_RATE;
audio_buffer_[i] = (Sint16)(AMPLITUDE * sin(2.0f * M_PI * 441.0f * time)); // render 441 HZ sine wave
}
}
The class variable sample_length_ is defined and initialized as private in the header like so :
int sample_length_ = 0;
So I had an idea and I created the variable sample_length_ as public and it works ! So the problem was definitely a scope problem of the class variable sample_length_. But it doesn't explain why the segfault disappeared when I moved the init of some other variable in the class constructor... Did I hit some undefined behavior with my callback ?
Thanks for reading me !
I have written a debounce class to debounce inputs.
The idea was that a state of a certain input may be ON, OFF, FALLING or RISING.
the object.debounceInputs() is to be called with a fixed interval
With the the function object.readInput() the correct state of the object could be read in. A FALLING or RISING state only lasts for 1 interval time (usually set at 20ms) and these states can only be read once.
Ofcourse I tested the software and it worked without flaw, now I started using the software in other projects and a peculiar bug came to light.
The software works perfectly fine... if you have just one input object. If you debounce more than 1 object, the inputs are affecting each other which should not be possible as every object uses private variables.
The source code:
#include "debounceClass.h"
Debounce::Debounce(unsigned char _pin) {
pinMode(_pin, INPUT_PULLUP); // take note I use a pull-up resistor by default
pin = _pin;
}
unsigned char Debounce::readInput() {
byte retValue = state;
if(state == RISING) state = ON; // take note I use a pull-up resistor
if(state == FALLING) state = OFF; // rising or falling may be returned only once
return retValue;
}
void Debounce::debounceInputs() {
static bool oldSample = false, statePrev = false;
bool newSample = digitalRead(pin);
if(newSample == oldSample) { // if the same state is detected atleast twice in 20ms...
if(newSample != statePrev) { // if a flank change occured return RISING or FALLING
statePrev = newSample ;
if(newSample) state = RISING;
else state = FALLING;
}
else { // or if there is no flank change return PRESSED or RELEASED
if(newSample) state = ON;
else state = OFF;
}
}
oldSample = newSample;
return 255;
}
The corresponding header file:
#include <Arduino.h>
#ifndef button_h
#define button_h
//#define
#define ON 9 // random numbers, RISING and FALLING are already defined in Arduino.h
#define OFF 10
class Debounce {
public:
Debounce(unsigned char _pin);
unsigned char readInput();
void debounceInputs();
private:
unsigned char state;
unsigned char pin;
};
#endif
I have had this bug with 2 separate projects, so the fault definitely lies in my Debounce class.
An example program to illustrate the program:
#include "debounceClass.h"
const int pin3 = 3 ;
const int pin4 = 4 ;
Debounce obj1( pin3 ) ;
Debounce obj2( pin4 ) ;
byte previousState1, previousState2;
unsigned long prevTime = 0, prevTime1 = 0, prevTime2 = 0;
void setup()
{
Serial.begin( 115200 ) ;
// CONSTRUCTOR OF OBJECTS SETS THE PINMODE TO INPUT_PULLUP
pinMode( pin3, OUTPUT ) ;
pinMode( pin4, OUTPUT ) ;
}
const int interval = 20, interval1 = 1000, interval2 = 2000;
void loop() {
unsigned long currTime = millis() ;
if( currTime > prevTime + interval ) {
prevTime = currTime ;
obj1.debounceInputs(); // comment one of these 2 out, and the other debounces perfectly
obj2.debounceInputs();
#define printState(x) case x: Serial.print(#x); break
byte state = obj1.readInput() ;
if( state != previousState1 ) {
previousState1 = state ;
Serial.print("state of obj1 = ") ;
switch ( state ) {
printState( ON ) ;
printState( OFF ) ;
printState( RISING ) ;
printState( FALLING ) ;
}
Serial.println();
}
state = obj2.readInput() ;
if( state != previousState2 ) {
previousState2 = state ;
Serial.print("state of obj2 = ") ;
switch ( state ) {
printState( ON ) ;
printState( OFF ) ;
printState( RISING ) ;
printState( FALLING ) ;
}
Serial.println();
}
}
if( currTime > prevTime1 + interval1 ) {
prevTime1 = currTime ;
digitalWrite( pin3, !digitalRead( pin3 ) );
}
if( currTime > prevTime2 + interval2 ) {
prevTime2 = currTime ;
digitalWrite( pin4, !digitalRead( pin4 ) );
}
}
This program automatically toggles both pins so you do not need physical inputs. If you comment out one of the indicated lines, you'll see that the other pin is debounced just fine. But when both pins are debounced the result is catastrophic. There is a weird link between the 2 objects which I cannot explain. I have reached a point at which I start doubting the compiler, so that was the moment I realized that I need to ask others.
Why is this happening and what did I do wrong here?
I found the problem.
I cannot use a static variable within a class method. These static variables are seen by all objects which caused the problem.
I moved the static variables to the private variable section
This is mostly a copy-paste of the code I found on Google,
I want to make a project using 2 waterflow sensors in which inflow() which shows how many liters i have taken in and outflow() which shows how many liters flown out.
This is how far ive reached, Need help with the code please, I am not a advanced coder so descriptive code and support is HIGHLY appreciated.
also please see the maincode(), in that section i am trying to achieve a loop, i mean if sensor1 is high it should display sensor1(inflow()) output ,and if sensor 2 is high it should display sensor2(outflow()) output.
Problems faced: the output doesn't work when i call both the inflow() and outflow() together, one function works,(i think it has something to do with the Interrupt Pins of the board?).
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
char auth[] = "SECRET";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Wifi";
char pass[] = "password";
//byte statusLed = 13;
byte inFlowSensor = D2;
byte outFlowSensor= D3;
float calibrationFactor = 4.5;
BlynkTimer timer;
volatile byte pulseCount;
float inFlowRate; // V2 - inflowrate
float outFlowRate; // V4 - outFowRate
boolean sensorInput = 0;
unsigned int inFlowMilliLitres;
unsigned int outFlowMilliLitres;
unsigned long inTotalMilliLitres; // V1 - inTotalLitres
//unsigned long totalLitres;
unsigned long outTotalMilliLitres; // V3 - outTotalLitres
unsigned long oldTime;
BLYNK_CONNECTED() { // runs once at device startup, once connected to server.
Blynk.syncVirtual(V1); //gets last known value of V1 virtual pin
Blynk.syncVirtual(V3); //gets last known value of V4
}
BLYNK_WRITE(V1)
{
inTotalMilliLitres = param.asFloat();
}
BLYNK_WRITE(V2)
{
inFlowRate = param.asFloat();
}
BLYNK_WRITE(V3)
{
outTotalMilliLitres = param.asFloat();
}
BLYNK_WRITE(V4)
{
outFlowRate = param.asFloat();
}
BLYNK_WRITE(V5) { // reset all data with button in PUSH mode on virtual pin V4
int resetdata = param.asInt();
if (resetdata == 0) {
Serial.println("Clearing Data");
Blynk.virtualWrite(V1, 0);
Blynk.virtualWrite(V2, 0);
inFlowRate = 0;
outFlowRate = 0;
inFlowMilliLitres = 0;
outFlowMilliLitres = 0;
inTotalMilliLitres = 0;
outTotalMilliLitres = 0;
//totalLitres = 0;
//totalLitresold = 0;
}
}
ICACHE_RAM_ATTR void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
void inflow()
{
if((millis() - oldTime) > 1000) // Only process counters once per second
{
detachInterrupt(inFlowSensor);
inFlowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
inFlowMilliLitres = (inFlowRate / 60) * 1000;
// Add the millilitres passed in this second to the cumulative total
inTotalMilliLitres += inFlowMilliLitres;
unsigned int frac;
// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(int(inFlowRate)); // Print the integer part of the variable
Serial.print("."); // Print the decimal point
// Determine the fractional part. The 10 multiplier gives us 1 decimal place.
frac = (inFlowRate - int(inFlowRate)) * 10;
Serial.print(frac, DEC) ; // Print the fractional part of the variable
Serial.print("L/min");
// Print the number of litres flowed in this second
Serial.print(" Current Fuel Flowing: "); // Output separator
Serial.print(inFlowMilliLitres);
Serial.print("mL/Sec");
// Print the cumulative total of litres flowed since starting
Serial.print(" Input Fuel Quantity: "); // Input separator
Serial.print(inTotalMilliLitres);
Serial.println("mL");
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(inFlowSensor, pulseCounter, FALLING);
}
}
void outflow()
{
if((millis() - oldTime) > 1000) // Only process counters once per second
{
detachInterrupt(outFlowSensor);
outFlowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
outFlowMilliLitres = (outFlowRate / 60) * 1000;
// Add the millilitres passed in this second to the cumulative total
outTotalMilliLitres += outFlowMilliLitres;
unsigned int frac;
// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(int(outFlowRate)); // Print the integer part of the variable
Serial.print("."); // Print the decimal point
// Determine the fractional part. The 10 multiplier gives us 1 decimal place.
frac = (outFlowRate - int(outFlowRate)) * 10;
Serial.print(frac, DEC) ; // Print the fractional part of the variable
Serial.print("L/min");
// Print the number of litres flowed in this second
Serial.print(" Current Fuel Flowing: "); // Output separator
Serial.print(outFlowMilliLitres);
Serial.print("mL/Sec");
// Print the cumulative total of litres flowed since starting
Serial.print(" Out Fuel Quantity: "); // Input separator
Serial.print(outTotalMilliLitres);
Serial.println("mL");
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(outFlowSensor, pulseCounter, FALLING);
}
}
void sendtoBlynk() // In this function we are sending values to blynk server
{
Blynk.virtualWrite(V2, inFlowRate);
Blynk.virtualWrite(V1, inTotalMilliLitres);
Blynk.virtualWrite(V4, outFlowRate);
Blynk.virtualWrite(V3, outTotalMilliLitres);
}
void setup()
{
Serial.begin(9600); //38400
Blynk.begin(auth,ssid,pass);
Serial.println("Setup Started");
pulseCount = 0;
inFlowRate = 0.0;
outFlowRate = 0.0;
inFlowMilliLitres = 0;
outFlowMilliLitres = 0;
inTotalMilliLitres = 0;
outTotalMilliLitres = 0;
oldTime = 0;
attachInterrupt(inFlowSensor, pulseCounter, FALLING);
//attachInterrupt(outFlowSensor, pulseCounter, FALLING);
timer.setInterval(10000L, sendtoBlynk);
}
void maincode(){
inflow();
//outflow();
}
/**
* program loop
*/
void loop(){
Blynk.run();
timer.run();
Serial.println("Timer and Blynk Started");
Serial.println(inFlowSensor);
Serial.println(outFlowSensor);
maincode();
}```
Please help with my issue.
I am trying to avoid going out of the limit between 0 to 100 for the count up/down value in the program below;
I am using an 8051 microcontroller and 2x16 LCD to display a value between 0 and 100. when pressing the UP button the number increased by one, while when pressing down button it decreased by one.
my code keeps incrementing the value above 100 and less 0.
// This is a code in Embedded C written on MikroC compiler for 8051 microcontroller
// The microcontroller shall count up / down on the LCD when press up / down button.
unsigned int cntr=0; // counter value
char lcdv[6]; // Value to displau on lcd
sbit UP at P3.B7; // declare button UP at port 3 Bit 7.
sbit DN at P3.B6; // declare button UP at port 3 Bit 6.
// LCD module connections
sbit LCD_RS at P2_0_bit; // Declare LCD reset pin.
sbit LCD_EN at P2_1_bit; // Declare LCD Enable pin.
sbit LCD_D4 at P2_2_bit; // Declare LCD D4 pin.
sbit LCD_D5 at P2_3_bit; // Declare LCD D5 pin.
sbit LCD_D6 at P2_4_bit; // Declare LCD D6 pin.
sbit LCD_D7 at P2_5_bit; // Declare LCD D7 pin.
// End LCD module connections
char text[16]; // this is stored in RAM
void main() { // Main program
P3 = 255; // Configure PORT3 as input
Lcd_Init(); // Initialize LCD
cntr=0; // Starting counter value
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
while(1) {
while ((cntrset<=100)&&(cntrset>=0)) // Not sure how to limit Min and Max value.
{
wordTostr(cntrset,volset);
LCD_Out(2,1,volset);
if (UP==0)
cntrset ++;
while (UP==0);
if (DN==0)
cntrset=--;
while (DN==0);
}
}
}
if (UP==0 && cntrset < 100 ) cntrset++;
while (UP==0);
if (DN==0 cntrset > 0 ) cntrset--;
while (DN==0);
You may still have an issue with switch bounce causing a single press to result in the counter changing by more than one count. But that is a different question.
Regarding comment: If the increment is not by-one and the current value need not be a multiple of the increment, then it is easier to apply saturation instead:
if( UP == 0 ) cntrset += increment;
while (UP==0);
if( DN == 0 ) cntrset -= increment ;
while (DN==0);
if( cntrset < 0 ) cntrset = 0 ;
else if( cntrset > MAX_CNTRSET ) cntrset = MAX_CNTRSET ;
For that to work however you must change cntrset to signed int. If you'd rather not do that then (assuming 16 bit unsigned):
...
if( (cntrset & 0x8000u) != 0 ) cntrset = 0u ;
else if( cntrset > MAX_CNTRSET ) cntrset = MAX_CNTRSET ;
I work on a Linux 64 bits and I want to use a GUI (created with Matlab and deployed as a shared library thanks to the MCR) in a C++ Code, where are my calculus functions.
The problem is to share data between the GUI and the C++ Code.
I isolated the GUI and the calculus functions in two different threads in the C++ and I've been able to write in a named pipe from the GUI (after a click on a button which switch on a callback) while the C++ was reading.
Thus I get the data to give to the calculus functions, but then, when the GUI is going to read, all is blocked.
Here are some snippets of my code:
My thread for the GUI (C++):
static void *fn_gui(void *p_data)
{
std::cout << "the gui should launch now" << std::endl;
/* Call of the Matlab Gui*/
gui();
mclWaitForFiguresToDie(NULL);
return NULL;
}
My thread for the calculus (C++):
static void *fn_calculus(void *p_data)
{
mkfifo("mypipe1",S_IRWXU);
mkfifo("mypipe2",S_IRWXU);
/*****************/
/* READING */
/*****************/
/* Declaration of the input structures of the calculus functions */
const char * in_fieldnames[] = {"x","y"};
mwArray a(1,1,2,in_fieldnames);
mwArray b(1,1,2,in_fieldnames);
mwArray c(1,1,2,in_fieldnames);
/* Opening of the first fifo */
int mypipe1=open("mypipe1",O_RDONLY);
/* Determination of the length of the length of the data (1st character of the message) */
char * lc;
lc = (char*) malloc(sizeof(char));
read(mypipe1,lc,1);
int l = atoi(lc);
/* Determination of the length of the data (the l following characters) */
char * Lc;
Lc = (char*) malloc(l*sizeof(char));
read(mypipe1,Lc,l);
int L = atoi(Lc);
/* Memory allocation of the message and storage of the data (the L following characters)*/
char * message1;
message1 = (char*) malloc(L*sizeof(char));
read(mypipe1,message1,L);
close(mypipe);
std::cout << "message = " << message1 << std::endl;
/* Formatting of the data */
mwArray flow1(message1);
mwArray data;
split(1,data,flow1); /* Put the string "a:b:c:d" under the "a" "b" "c" "d" form */
/* temporary Matlab deployed function to improve */
/*****************/
/* CALCULUS */
/*****************/
/* Filling of the input structures */
a.Get(1,1).Set(data.Get(1,1));
a.Get(1,2).Set(data.Get(1,2));mkf
b.Get(1,1).Set(data.Get(1,3));
b.Get(1,2).Set(data.Get(1,4));
/* Call to the Matlab Calculus Function (it fills c) */
minpyt(1,c,a,b);
std::cout << "c = " << c << std::endl;
/* Formatting of the data */
double result[2];
c.Get("x",1,1).GetData(&result[0],1);
c.Get("y",1,1).GetData(&result[1],1);
int length=sizeof(result[0])+sizeof(result[1])+1; /* length of the two figures plus the extra ':' character between them */
int length2 = (int) log10(length) + 1; /* number of digits of the previous length */
char message2[length+length2+1]; /* length for the message and the 2 lengths */
sprintf(message2,"%d%d%f:%f",length2,length,result[0],result[1]);
/*****************/
/* WRITING */
/*****************/
int mypipe2 = open("mypipe2",O_WRONLY);
write(mypipe2,message2,sizeof(message2));
close(mypipe2);
return NULL;
}
the callback of my GUI (Matlab):
function buttonCallback(gcbf,data)
% Getting the data from the GUI
data = guidata(gcbf);
a.x = get(data.Ax,'String');
a.y = get(data.Ay,'String');
b.x = get(data.Bx,'String');
b.y = get(data.By,'String');
guidata(gcbf,data);
% Formatting the data
message = [a.x ':' a.y ':' b.x ':' b.y];
L = num2str(length(message));
l = num2str(length(L));
message = [l L message];
% WRITING
mypipe1 = fopen('mypipe1','w');
fwrite(mypipe1,message,'char');
fclose(pipe);
% READING
mypipe2 = fopen('mypipe2','r');
l = fread(mypipe2,1,'double');
L = fread(mypipe2,l,'double');
flow = fread(mypipe2,L,'*char');
fclose(mypipe2);
fprintf(1,'message read = %s\n',flow);
% Formatting the data
message = regexp(flow,':','split');
c.x = str2double(message{1,1});
c.y = str2double(message{1,2});
% Updating the GUI
set(data.Cx,'String',c.x);
set(data.Cy,'String',c.y);
plot(data.axes,[a.x;b.x;c.x;a.x],[a.y;b.y;c.y;a.y],'r-');
axis equal;
end
The GUI calls the callback function when I click on a button (after filling the values of a and b). The main function of the C++ just initialize the MCR and the proper libraries and launch the threads.
If anybody have an idea.
Thanks and regards