Dead-band module not working properly for EPWM1 (TMS320F28335) - c

I am working on vector control of PMSM. I've got a problem with the dead-band module, and I don't understand what I'm actually doing wrong here. The register setting for EPWM modules 1 and 2 is given as follows:
For EPWM module 1 configuration
EPwm1Regs.TBPRD = PERIOD;// Period = TBCLK counts
EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM1A
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
EPwm1Regs.DBFED = DEAD_TIME; //
EPwm1Regs.DBRED = DEAD_TIME; //
For EPWM Module 2 Configuration
EPwm2Regs.TBPRD = PERIOD; // Period = 1600 TBCLK counts
EPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM2A
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
EPwm2Regs.DBFED = DEAD_TIME; //
EPwm2Regs.DBRED = DEAD_TIME; //
I'm following an example (3.4) from the technical manual "sprug04a."
the compare values are initially initialized as
EPwm1Regs.CMPA.half.CMPA = 0; // adjust duty for output EPWM1A
EPwm2Regs.CMPA.half.CMPA = 0; // adjust duty for output EPWM2A
and compare values are updated in the code like:
EPwm1Regs.CMPA.half.CMPA = PERIOD - Sa;
EPwm2Regs.CMPA.half.CMPA = PERIOD - Sb;
where S_ab are the values obtained from modulation technique.
EPWM2 module is working well but EPWM1 isn't working. we are suppose to have EPWM1A complimentary signal across EPWM1B but EPWM1B shows same as EPWM1A. The scope is attached for better understanding. Need recommendation in this regards.EPWM1A&B EPWM2A&B reference, what should i need to check? as i checked technical manual and example codes but still i didnt get what i am doing wrong. Your suggestions will be valuable in this regards.

Related

Loop within STACK question in moodle using jsxgraph

I am trying to create a moodle-STACK question with an interactive element via jsxgraph.
Within the [[jsxgraph]] ... [[/jsxgraph]] tags, I am plotting a curve with two databases, each with 6 elements.
Since I would like students to add error bars for both scales, I added a loop within the jsxgraph-element:
var plot = function() {
var j, xr0, yr0, xr1, yr1, xr2, yr2, err1, err2;
board.suspendUpdate();
for (j=0; j<6;j++) {
const v1 = Number(input1.Value());
const v2 = Number(input2.Value());
xr1 = dataX[j]-v1;
yr1 = dataY[j]+v2;
xr2 = dataX[j]+v1;
yr2 = dataY[j]-v2;
xr0 = dataX[j];
yr0 = dataY[j];
err1 = board.create('line',[[xr1,yr0],[xr2,yr0]],{straightFirst:false,straightLast:false, fixed:true});
err2 = board.create('line', [[xr0,yr1],[xr0,yr2]],{straightFirst:false,straightLast:false, fixed:true});
}
};
Since the jsxgraph code is within the HTML-text field of the STACK-question in moodle, the < sign is converted to < and now the loop cant be executed.
Is there a way to use a < sign within the HTML-field of moodle? If not, how can I get past this problem?
I already wrote a running Javascript-Code that shows what I want to create within moodle:
https://jsfiddle.net/Furfinator/3q8yk7hp/15/

How to add time delay to process more than 15 second in Actionscript?

So I have the following script to get all combination of an array :
'''
var value = new Array(40)
for (var i=0;i<value.length;i++){
value[i]=i;
}
var comb_list = getAllComb(value,24);
trace(comb_list)
function getAllComb(values:Array, r:int):Array{
var n = values.length;
var result = new Array();
var a = new Array(r);
// initialize first combination
for (var i = 0; i < r; i++) {
a[i] = i;
}
i = r - 1; // Index to keep track of maximum unsaturated element in array
// a[0] can only be n-r+1 exactly once - our termination condition!
var count = 0;
while (a[0] < n - r + 1) {
// If outer elements are saturated, keep decrementing i till you find unsaturated element
while (i > 0 && a[i] == n - r + i) {
i--;
}
result.push(a.slice())// pseudo-code to print array as space separated numbers
count++;
a[i]++;
// Reset each outer element to prev element + 1
while (i < r - 1) {
a[i + 1] = a[i] + 1;
i++;
}
}
return result;
}
'''
Running above script will get me:
Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
How to add time delay each 14 seconds passed so that I can run the script? So, after 14 seconds passed, the program will wait for 50ms then continue.
Any help appreciated.
So, there's a simple (well, pretty much so) and working example of how to separate the heavy calculations part from the main thread so the main thread (which also handles UI and external events like user input) would run smoothly, while being able to read the progress and the results of the heavy calculations going under the hood. It also is in a form of a single class, this could be a bit confusing (until you understand how it works) but still easy to handle and modify.
Although the background AVM goes along the same execution flow (code execution > graphics rendering > code execution > graphics rendering > and so on), there are no graphics to render hence there's no need to anyhow limit the code execution time. As a result Worker thread is not a subject to 15 seconds limit, which, somehow, solves the problem.
package
{
import flash.events.Event;
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.concurrent.Mutex;
import flash.system.Worker;
import flash.system.WorkerDomain;
public class MultiThreading extends Sprite
{
// These variables are needed by both the main and
// subservient threads and will actually point to
// the very same object instances, though from
// the different sides of this application.
private var B:ByteArray;
private var W:Worker;
private var M:Mutex;
// Constructor method.
public function MultiThreading()
{
super();
// This property is 'true' for the main thread
// and 'false' for any Worker instance created.
if (Worker.current.isPrimordial)
{
prepareProgress();
prepareThread();
startMain();
}
else
{
startWorker();
}
}
// *** THE MAIN THREAD *** //
private var P:Sprite;
private var F:Sprite;
// Prepares the progress bar graphics.
private function prepareProgress():void
{
F = new Sprite;
P = new Sprite;
P.graphics.beginFill(0x0000FF);
P.graphics.drawRect(0, 0, 100, 10);
P.graphics.endFill();
P.scaleX = 0;
F.graphics.lineStyle(0, 0x000000);
F.graphics.drawRect(0, 0, 100, 10);
F.x = 10;
F.y = 10;
P.x = 10;
P.y = 10;
addChild(P);
addChild(F);
}
// Prepares the subservient thread and shares
// the ByteArray (the way to pass messages)
// and the Mutex (the way to access the shared
// resources in a multi-thread environment
// without stepping on each others' toes).
private function prepareThread():void
{
M = new Mutex;
B = new ByteArray;
B.shareable = true;
B.writeObject(incomingMessage);
W = WorkerDomain.current.createWorker(loaderInfo.bytes);
W.setSharedProperty("message", B);
W.setSharedProperty("lock", M);
}
// Starts listening to what the background thread has to say
// and also starts the background thread itself.
private function startMain():void
{
addEventListener(Event.ENTER_FRAME, onFrame);
W.start();
}
private var incomingMessage:Object = {ready:0, total:100};
private function onFrame(e:Event):void
{
// This method runs only 20-25 times a second.
// We need to set a lock on the Mutex in order
// to read the shared data without any risks
// of colliding with the thread writing the
// same data at the same moment of time.
M.lock();
B.position = 0;
incomingMessage = B.readObject();
M.unlock();
// Display the current data.
P.scaleX = incomingMessage.ready / incomingMessage.total;
P.alpha = 1 - 0.5 * P.scaleX;
// Kill the thread if it signalled it is done calculating.
if (incomingMessage.terminate)
{
removeEventListener(Event.ENTER_FRAME, onFrame);
W.terminate();
B.clear();
B = null;
M = null;
W = null;
}
}
// *** THE BACKGROUND WORKER PART *** //
// I will use the same W, M and B variables to refer
// the same Worker, Mutex and ByteArray respectively,
// but you must keep in mind that this part of the code
// runs on a different virtual machine, so it is the
// different class instance thus its fields are not
// the same quite as well.
// Initialization.
private function startWorker():void
{
W = Worker.current;
M = W.getSharedProperty("lock");
B = W.getSharedProperty("message");
// Before starting the heavy calculations loop
// we need to release the main thread which is
// presently on W.start() instruction. I tried
// without it and it gives a huuuge lag before
// actually proceeding to intended work.
addEventListener(Event.ENTER_FRAME, onWorking);
}
private function onWorking(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, onWorking);
var aMax:int = 10000000;
// Very very long loop which might run
// over the course of several seconds.
for (var i:int = 0; i < aMax; i++)
{
// This subservient thread does not actually need to
// write its status every single loop, so lets don't
// explicitly lock the shared resources for they
// might be in use by the main thread.
if (M.tryLock())
{
B.position = 0;
B.writeObject({ready:i, total:aMax});
M.unlock();
}
}
// Let's notify the main thread that
// the calculations are finally done.
M.lock();
B.position = 0;
B.writeObject({ready:i, total:aMax, terminate:true});
M.unlock();
// Release the used variables and prepare to be terminated.
M = null;
B = null;
W = null;
}
}
}
The error is not related to your script needing a time delay, the problem is your while loops are making your script unresponsive for more than 15 seconds, triggering the script timeout error. Action Script only allows 15 seconds for your script to execute.
Your first while loop looks problematic, and I'm unclear how the value of a[0] changes to end the loop. Add a break to the loop or make sure the condition changes to allow the loop to end, and you should solve your problem. You can also considering adding continue statements to your embedded while loops if they are only supposed to run one time after they find an unsaturated value.
Personally, since you are using ActionScript, I'd suggest using objects and listeners for value changes instead of iterating over arrays checking for changes.
You could also add a manual timeout for your while loop, but would need to include logic for it to pick up where it left off.
//Set timer to 14 seconds
timeout = getTimer() + 14000;
while(true && timeout > getTimer()){
trace("No Error");
}
If you were used Adobe Animate (Flash), you could change the "Script Time Limit" from Publish setting page.

Scanning for BLE Devices from C/C++

from the "Bluetooth Device Access Guide", I've read that the Bluetooth API should be accessable from C or from C++. I've found some C-headers (IOBluetoothUserLib.h, Bluetooth.h) in the IOBluetooth framework that are related to Bluetooth and contain enumerations and data structured to define search creteria but I fail to find any function that takes such enumeration or data structure as parameter. According to the documentation I would have to create a CBCentralManager but I fail to find a way to do so from C or C++.
Background: We use OS/X as a developing plattform for devlopment of BLE enabled microcontrollers. To update firmware on this microcontrollers I want to write a BLE bootloader and I want to have a commandline client to update the firmware. All of the code is written in C++ and I wouldn't like to learn objectiv-C for this small task.
Any pointers, documentation, examples?
thank you
Torsten
According to the documentation I would have to create a CBCentralManager but I fail to find a way to do so from C or C++.
The documentation you refer to is for classic Bluetooth, for which the IOBluetooth framework has some functionality. CBCentralManager is the manager from CoreBluetooth, which is for Bluetooth LE only.
For classic Bluetooth, the manager you want is the HID Manager from the IOKit framework, documentation for which can be found here. If you search around, you'll find lots of examples of C++ usage of IOKit and IOHIDManager (1, 2).
IOKit may in fact give you all the functionality you need, but IOBluetooth supplies some Bluetooth specific features. From Developing Bluetooth Applications:
Although you don’t need to use the Bluetooth API to access a HID-class device, you may choose to use functions or methods from the Bluetooth framework to enhance the user’s experience. For example, your application can provide Bluetooth-specific information that lets the user know if a device doesn’t support a particular service.
I agreed with Henrik you'll need some glue. Look at RedBearLab guys work and precise to class.
ofxBLE. h/mm
// C++ interface //
// (Obj-C may be a superset of C, but this just makes interopability
// easier with oF)
class ofxBLE {
protected:
ofxBLEDelegate *btDelegate;
public:
ofxBLE();
~ofxBLE();
void scanPeripherals();
void sendPosition(uint8_t x, uint8_t y);
bool isConnected();
};
...
- (void)bleDidDisconnect {
NSLog(#"->Disconnected");
}
- (void)bleDidReceiveData:(unsigned char *)data length:(int)length {
}
#end
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// C++ class implementation
ofxBLE::ofxBLE() {
btDelegate = [[ofxBLEDelegate alloc] init];
}
ofxBLE::~ofxBLE() {
}
void ofxBLE::scanPeripherals(){
[btDelegate scanForPeripherals];
}
void ofxBLE::sendPosition(uint8_t x, uint8_t y) {
// position should be NORMALIZED to between 0 and 255 BEFORE
// passing into this method!
[btDelegate sendPositionX:x withY:y];
}

DirectShow Custom Source Pin

I am new to DirectShow. I, like many others, am trying to create a socket-based P2P streaming solution for a WPF-based card game. I want each player to be able to see each other via small video windows.
My questions are two-fold. The first is How do I lower the frame sample rate and resolution? I believe 320x200 x 15 to 20 fps should be fine. I am using the SampleGrabber callback to grab frame data and send it over the socket; which is actually working with no compression at 640x480 resolution.
My second question is, since each frame contains 921,600 bytes, this really bogs down and I get very slow rendering just across my local WiFi connected LAN. I added a simple MJPEG compression (wanting to switch to h.264 later) and I noticed the bytes drop to around 330-360k. Not a bad improvement.
On the receiving end Do I need to create a custom DirectShow Source Pin in order to serve up the bytes received from the socket so I can attach a decoder and render the bytes in a window?
I just wanted to ask this first since it seems like a lot of work to create a new COM object (haven't done that in about 15 years!), register it, and use/debug it.
Is there perhaps another way?
Also if that is the way to go, should I use a SampleGrabber on the receiving end and create a BitmapSource from the decompressed bytes, or should I allow DirectShow to create a child window? Thing is, I want to have more than one other player and I set an extra byte in the socket to tell what table position they are in. How do I render each position in turn?
For those that are interested, here is how you set the resolution and add an encoder/compressor:
// Create a graph builder
int hr = captureGraphBuilder.SetFiltergraph(graphBuilder);
// Find a capture device (WebCam) and attach it to the graph
sourceFilter = FindCaptureDevice();
hr = graphBuilder.AddFilter(sourceFilter, "Video Capture");
// Get the source output Pin
IPin sourcePin = DsFindPin.ByDirection((IBaseFilter)sourceFilter, PinDirection.Output, 0);
IAMStreamConfig sc = (IAMStreamConfig)sourcePin;
int count;
int size;
sc.GetNumberOfCapabilities(out count, out size);
VideoInfoHeader v;
AMMediaType media2 = null;
IntPtr memPtr = Marshal.AllocCoTaskMem(size);
for (int i = 0; i < count; ++i)
{
sc.GetStreamCaps(i, out media2, memPtr);
v = (VideoInfoHeader)Marshal.PtrToStructure(media2.formatPtr, typeof(VideoInfoHeader));
// Break when width is 160
if (v.BmiHeader.Width == 160)
break;
}
// Set the new media format t0 160 x 120
hr = sc.SetFormat(media2);
Marshal.FreeCoTaskMem(memPtr);
DsUtils.FreeAMMediaType(media2);
// Create a FramGrabber
IBaseFilter grabberF = (IBaseFilter)new SampleGrabber();
ISampleGrabber grabber = (ISampleGrabber)grabberF;
// Set the media type
var media = new AMMediaType
{
majorType = MediaType.Video,
subType = MediaSubType.MJPG
//subType = MediaSubType.RGB24
};
// The media sub type will be MJPG
hr = grabber.SetMediaType(media);
DsUtils.FreeAMMediaType(media);
hr = grabber.SetCallback(this, 1);
hr = graphBuilder.AddFilter(grabberF, "Sample Grabber");
IPin grabberPin = DsFindPin.ByDirection(grabberF, PinDirection.Input, 0);
// Get the MPEG compressor
Guid iid = typeof(IBaseFilter).GUID;
object compressor = null;
foreach (DsDevice device in DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory))//.MediaEncoderCategory))
{
if (device.Name == "MJPEG Compressor")
{
device.Mon.BindToObject(null, null, ref iid, out compressor);
hr = graphBuilder.AddFilter((IBaseFilter)compressor, "Compressor");
break;
}
string name = device.Name;
}
// This also works!
//IBaseFilter enc = (IBaseFilter)new MJPGEnc();
//graphBuilder.AddFilter(enc, "MJPEG Encoder");
// Get the input and out pins of the compressor
IBaseFilter enc = (IBaseFilter)compressor;
IPin encPinIn = DsFindPin.ByDirection(enc, PinDirection.Input, 0);
IPin encPinOut = DsFindPin.ByDirection(enc, PinDirection.Output, 0);
// Attach the pins: source to input, output to grabber
hr = graphBuilder.Connect(sourcePin, encPinIn);
hr = graphBuilder.Connect(encPinOut, grabberPin);
// Free the pin resources
Marshal.ReleaseComObject(sourcePin);
Marshal.ReleaseComObject(enc);
Marshal.ReleaseComObject(encPinIn);
Marshal.ReleaseComObject(encPinOut);
Marshal.ReleaseComObject(grabberPin);
// Create a render stream
hr = captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, null, grabberF);
Marshal.ReleaseComObject(sourceFilter);
Configure(grabber);

How can I apply a low-shelving filter using Visualdsp++?

I'm very new to DSP. And have to solve the following problem: applying the low shelving filter for an array of data. The original data is displayed in fract16 (VisualDSP++).
I'm writing something as below but not sure it's correct or not.
Does the following code have any problem with overflow?
If 1 is true, how should I do to prevent it?
Any advice on this problem?
fract16 org_data[256]; //original data
float16 ArrayA[],ArrayB[];
long tmp_A0, tmp_A1, tmp_A2, tmp_B1, tmp_B2;
float filter_paraA[3], filter_paraB[3]; // correctness: 0.xxxxx
// For equalizing
// Low-Shelving filter
for ( i=0; i<2; i++)
{
tmp_A1 = ArrayA[i*2];
tmp_A2 = ArrayA[i*2+1];
tmp_B1 = ArrayB[i*2];
tmp_B2 = ArrayB[i*2+1];
for(j=0;j<256;j++){
tmp_A0 = org_data[j];
org_data[j] = filter_paraA[0] * tmp_A0
+ filter_paraA[1] * tmp_A1
+ filter_paraA[2] * tmp_A2
- filter_paraB[1] * tmp_B1
- filter_paraB[2] * tmp_B2;
tmp_A2 = tmp_A1;
tmp_B2 = tmp_B1;
tmp_A1 = tmp_A0;
tmp_B1 = org_data[j];
}
ArrayA[i*2] = tmp_A1;
ArrayA[i*2+1] = tmp_A2;
ArrayB[i*2] = tmp_B1;
ArrayB[i*2+1] = tmp_B2;
}
I don't know what the range is for fract16, just -1 to +1 approx?
The section that stands out to me as possibly generating an overflow is assigning org_data[j] but will be dependent on what you know about your input signal and your filter coefficients. If you can ensure that multiplying filter_paraA[2:0] to signal with values tmp_A2..1 = [1,1,1] is < max(fract16) you should be fine regardless of the 'B' side.
I would recommend adding some checks for overflow in your code. It doesn't necessarily have to fix it, but you would be able to identify an otherwise very tricky bug. Unless you need absolute max performance I would even leave the check code in place but with less output or setting a flag that gets checked.
macA = filter_paraA[0] * tmp_A0 + filter_paraA[1] * tmp_A1 \
+ filter_paraA[2] * tmp_A2;
macB = filter_paraB[1] * tmp_B1 - filter_paraB[2] * tmp_B2;
if((macA-macB)>1){
printf("ERROR! Overflow detected!\n");
printf("tmp_A[] = [%f, %f, %f]\n",tmp_A2,tmp_A1,tmp_A0);
printf("tmp_B[] = [%f, %f]\n",tmp_B1,tmp_B0);
printf(" i = %i, j = %i\n",i,j);
}

Resources