iceblu3710
Member level 3
Hello all!
I have just started creating components for Proteus VSM and am having some troubles with the coding. I have gotten a basic digital decive to work and now am working on a combo V/A meter with animations to get the hang of graphics but I can only display info from RTVPROBE or RTIPROBE but not both at the same time.
Does anybody know how to do this? Under my new device 'Primitive' I have 'ANALOG, RTVPROBE' or "ANALOG, RTIPROBE' but it will not let me use 'ANALOG, RTVPROBE, RTIPROBE' which I think I will need. Or do I need to do the calculations based off spice input by hand?
Here is my code:
I have just started creating components for Proteus VSM and am having some troubles with the coding. I have gotten a basic digital decive to work and now am working on a combo V/A meter with animations to get the hang of graphics but I can only display info from RTVPROBE or RTIPROBE but not both at the same time.
Does anybody know how to do this? Under my new device 'Primitive' I have 'ANALOG, RTVPROBE' or "ANALOG, RTIPROBE' but it will not let me use 'ANALOG, RTVPROBE, RTIPROBE' which I think I will need. Or do I need to do the calculations based off spice input by hand?
Here is my code:
Code:
#include <windows.h> // All windows apps need this
#include <stdio.h> // printf() & scanf() functions
#include <math.h> // fabs() and others
#include "VSM.HPP"
class UM_METER : public IACTIVEMODEL
{
public:
VOID initialize (ICOMPONENT *cpt);
ISPICEMODEL *getspicemodel (CHAR *device);
IDSIMMODEL *getdsimmodel (CHAR *device);
VOID plot (ACTIVESTATE state);
VOID animate (INT element, ACTIVEDATA *newstate);
BOOL actuate (WORD key, INT x, INT y, DWORD flags);
private:
ICOMPONENT *component;
POINT volts;
POINT amps;
HTEXTSTYLE textstyle;
CHAR readout_v[10];
CHAR readout_a[10];
};
// The create & delete functions, Ignore licencing authorization to make components avalible to any licence
extern "C" __declspec(dllexport) IACTIVEMODEL *createactivemodel (CHAR *device, ILICENCESERVER *ils) { return new UM_METER; }
extern "C" VOID __declspec(dllexport) deleteactivemodel (IACTIVEMODEL *model) { delete (UM_METER *)model; }
VOID UM_METER::initialize (ICOMPONENT *cpt)
// Store ICOMPONENT interface and initialize.
{
component = cpt;
// Get entire component(-1) origin
BOX textbox;
cpt->getsymbolarea(-1, &textbox);
// Do some math to position the readouts properly
volts.x = (textbox.left+textbox.right)/2;
volts.y = (textbox.top+textbox.bottom)/2-100;
amps.x = (textbox.left+textbox.right)/2;
amps.y = (textbox.top+textbox.bottom)/2+100;
// Create a new text style in 'Templates' menu or other objects get funky
// Still makes other meters readouts conform to his style, how to use properly??
textstyle = cpt->createtextstyle("UM_METER");
// Initial readout:
strcpy(readout_v, " 00.0");
strcpy(readout_a, " 0.00");
}
VOID UM_METER::plot (ACTIVESTATE state)
// This is called to display the component when not simulating
{
// Draw entire component on the screen
component->drawsymbol(-1);
// Draw symbol 0 overtop components
component->drawsymbol(0);
// Place the default readouts on the screen
component->drawtext(volts.x, volts.y, 0, TXJ_CENTRE|TXJ_MIDDLE, readout_v);
component->drawtext(amps.x, amps.y, 0, TXJ_CENTRE|TXJ_MIDDLE, readout_a);
}
VOID UM_METER::animate (INT element, ACTIVEDATA *data)
// Animate function - this is called whenever an event is
// produced by the simulator model.
{
// Check which element has called for an update
// Element ID is N/A , 0 , 1
// Device primitive is "ANALOG,RTVPROBE,RTIPROBE"
if (element == 0) // Volts
{
DOUBLE absval = fabs(data->realval);
CHAR sign;
CHAR result[10];
// Decide whether to prefix with a +, a - or nothing:
if (data->realval > 0.001)
sign = '+';
else if (data->realval < -0.001)
sign = '-';
else
sign = ' ';
// Now we work out where to place the decimal point:
if (absval >= 1000)
sprintf(result, "%cMAX", sign);
else if (absval >= 100)
sprintf(result, "%c%3.0f", sign, absval);
else if (absval >= 10)
sprintf(result, "%c%4.1f", sign, absval);
else
sprintf(result, "%c%4.2f", sign, absval);
// Store the new value
strcpy(readout_v, result);
}
if (element == 1) // Amps
{
DOUBLE absval = fabs(data->realval);
CHAR sign;
CHAR result[10];
// Decide whether to prefix with a +, a - or nothing:
if (data->realval > 0.001)
sign = '+';
else if (data->realval < -0.001)
sign = '-';
else
sign = ' ';
// Now we work out where to place the decimal point:
if (absval >= 1000)
sprintf(result, "%cMAX", sign);
else if (absval >= 100)
sprintf(result, "%c%3.0f", sign, absval);
else if (absval >= 10)
sprintf(result, "%c%4.1f", sign, absval);
else
sprintf(result, "%c%4.2f", sign, absval);
// Store the new value
strcpy(readout_a, result);
}
// Draw entire component on the screen
component->drawsymbol(-1);
// Draw symbol 0 overtop components
component->drawsymbol(0);
// Re-draw the displayed value with the new results
component->drawtext(volts.x, volts.y, 0, TXJ_CENTRE|TXJ_MIDDLE, readout_v);
component->drawtext(amps.x, amps.y, 0, TXJ_CENTRE|TXJ_MIDDLE, readout_a);
}
// As the class is 'abstract' you must impliment ALL functions even if they are not used!
ISPICEMODEL *UM_METER::getspicemodel (CHAR *) { return NULL; }
IDSIMMODEL *UM_METER::getdsimmodel (CHAR *) { return NULL; }
BOOL UM_METER::actuate (WORD key, INT x, INT y, DWORD flags) { return FALSE; }