C-Block Sample&Hold Block (possibly stupid) question

Hi,
I am somehow stuck with a seemingly simple task.
I have already set up a quite big simulation model of a phase shifted full bridge converter, first with analog control, then I adapted RDunn/KSKelvin’s PID controller algorithm to a 2p2z one, which works fine.
Now I wanted to implement the effect the sample and hold has on the phase of the control loop, but I can’t get it working. First I tried to implement it in my 2p2z C code which didn’t work, so I tried to do it on a minimal working example.

I created the code with the structure template and wrote the code similar to the C Code Block Basics.
I expect the output to assert the input value at each rising edge of the clock, but nothing happens, it just stays low.
When I remove the “”&& inst->clk_n1" part of the if statement, the output is equal to the input for the high duration of the pulse. So I assume something is not working with the edge detection in the if statement?
But what could it be, can anyone help me?

#include <malloc.h>

extern "C" __declspec(dllexport) void (*bzero)(void *ptr, unsigned int count)   = 0;

union uData
{
   bool b;
   char c;
   unsigned char uc;
   short s;
   unsigned short us;
   int i;
   unsigned int ui;
   float f;
   double d;
   long long int i64;
   unsigned long long int ui64;
   char *str;
   unsigned char *bytes;
};

// int DllMain() must exist and return 1 for a process to load the .DLL
// See https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain for more information.
int __stdcall DllMain(void *module, unsigned int reason, void *reserved) { return 1; }

// #undef pin names lest they collide with names in any header file(s) you might include.
#undef in
#undef out
#undef clk

struct sSNH
{
  // declare the structure here
  bool clk_n1; // clk[n-1]
};

extern "C" __declspec(dllexport) void snh(struct sSNH **opaque, double t, union uData *data)
{
   double  in  = data[0].d; // input
   bool    clk = data[1].b; // input
   double &out = data[2].d; // output

   if(!*opaque)
   {
      *opaque = (struct sSNH *) malloc(sizeof(struct sSNH));
      bzero(*opaque, sizeof(struct sSNH));
   }
   struct sSNH *inst = *opaque;

// Implement module evaluation code here:

if (clk && !inst->clk_n1)
{
  out=in;
  inst->clk_n1 = clk;
}

}

extern "C" __declspec(dllexport) void Destroy(struct sSNH *inst)
{
   free(inst);
}

move this outside if conditon

1 Like

Aah, you got it. Thank you a lot.

Regards

Hello r65

I can see you’ve accepted a solution but, I’m curious: did the native S&H block not provide the needed functionality, or is there a different reason?

Vlad

Hi Vlad,

to be honest, I didn’t know it already existed. So thanks for the tip.

Alex

I also have z-domain custom block set. If just simple discrete function, you can consider that.
Z-domain discrete time control subcircuit symbols library - QSPICE - Qorvo Tech Forum

Haven’t seen these so far, thanks.
QSPICE is really powerful and benefits a lot from your input here as well, thanks for that!

1 Like