Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Simple Question: Does an output counter clear once task is stopped by not cleared?

We are two mechanical engineering students encountering difficulties with interfacing a L296 H-bridge and a PWM generator currently off Dev1/ctr0 on a pci6035E using DAQmx.   Since I'm the C programmer of the group, I'm tasked with writing the software interface.
 
The device works well for a while and suddenly the current drawn goes up and fries the device and we've cooked two of them so far.  The module is limited to 60 Hz operation so we set the frequency of our counter to 45 Hz operation.
 
In order to avoid back emf problems or when the direction suddenly is required to change, we stop the PWM task if either we get a speed change request (to change the duty cycle) or if the direction is changed from the previous time the function is called.  The motor control function also traps 0 and 1 duty cycle conditions, preserves direction, compares direction and acts accordingly.  It is also run by a LabWindows Timer control set to 150ms operation.
 
What we are wondering is maybe the output is latched and the PWM continues to operate even if the task is stopped.
 
Could we be harming the device by constantly changing the duty cycle when the motor is running?
 
void MotorRun(double speed)
{
 int cur_direction;
 
 cur_direction = (speed > 0) ? BACKWARD : FORWARD;
 
 //
 // LabWindows/CVI does not like it when you set the duty
 // cycle at 0 or at 1.  The '1' condition is prevented by
 // the dial.
 //
 // Here is where we trap the PWM 0 duty cycle condition.
 //
 
 if ((speed == 0) && (running == TRUE))
  {
   running = FALSE;
   DAQmxStopTask(pwmHandle);
  }
   
 if ((speed != 0) && (running == FALSE))
  {
   running = TRUE;
   DAQmxStartTask(pwmHandle);
  }
 
 //
 // Here is where we trap the PWM 1 duty cycle condition.
 //
 
 if (speed > 1) speed = 0.999;
 
 //
 // Gets rid of the minus sign so we can pass directly to PWM.
 //
 if (speed < 0) speed *= -1;  
 
 //
 // Precaution to stop DC motor if direction changes
 // It also updates the speed.
 //
 if (running)
  {
  DAQmxStopTask(pwmHandle);
  DAQmxSetCOPulseDutyCyc(pwmHandle, pwmchan, speed);  
  DAQmxStartTask(pwmHandle);
  }
 DAQmxWriteRaw (dirHandle, 1, 0, 1, &cur_direction, 0, 0);
 
 SetCtrlVal(motorTab, MOT_TAB_DIRECTION, cur_direction);
 
 direction = cur_direction;
}
 
0 Kudos
Message 1 of 9
(4,914 Views)

I believe we figured it out.

The boards were are using have their enable bits set low, and I believe when we have to change or "idle" variable to HIGH to avoid back emf problems through the L296.

As for the question about latching, correct me if I'm wrong, but it looks like it is latched through software.  I'm assuming that's what the "idle" variable is for.  I'm also assuming that when the task is stopped, the value on the PWM, Dev1/ctr0, is HIGH (10192) or whatever, correct?

I should have posted the setup of our PWM task (we change idel from LOW to HIGH):

void SetupPWM(void)
{
 double frequency = 45;
 double duty = 0.0001;
 unsigned int idle = 10192; // HIGH is 10192
 char *msg = "PWM output on CTR0 OUT is ready.  Frequency = 45Hz.";

 DAQmxCreateTask("",&pwmHandle);
 DAQmxCreateCOPulseChanFreq(pwmHandle, pwmchan, "", DAQmx_Val_Hz,
   idle, 0, frequency, duty);
 DAQmxCfgImplicitTiming(pwmHandle,DAQmx_Val_ContSamps,1000);
 DAQmxStartTask(pwmHandle);
 Delay(1/frequency);

 InsertTextBoxLine (optionsTab, OPT_TAB_SYSSTAT, ++nlines, msg);
 
 ProcessSystemEvents();
}

Message Edited by Patrickw on 03-29-2007 08:05 AM

Message Edited by Patrickw on 03-29-2007 08:08 AM

0 Kudos
Message 2 of 9
(4,911 Views)

Just some guesses:

1.  Typically, motor drives will protect the drive transistors from back-emf by putting in dissipative diodes around the output transistors -- these are often referred to as "flyback diodes."  After only a quick look at an L296 datasheet, I'm not so sure this chip is designed to handle motor back-emf.  This is one thing to look into.

2. You refer to an H-bridge which would makes sense for a bipolar (bidirectional) DC motor drive -- but the L296 appears to me to be unipolar.  What's the rest of the circuit you use?

3. I had an app where I had to individually switch the power transistors of a motor drive and one key consideration was the need to guarantee a short delay when switching current direction.  This was needed because of the response time of the power transistors themselves.  If you were to instantly switch from \ to /, you risk allowing short-circuit conduction straight down one leg | of the H-bridge.  That would definitely let some smoke out.

I'm only a LabVIEW progammer, but can follow the main logic of your code and have some ideas.

a. some of the code used to start and stop the pwm task seems redundant.  You have several independent if/then's which may cause you to do a start or stop, then later another if/then may cause you to redo or undo it.  I think some careful nesting of your logic would be more appropriate.

b. *KEY IDEA*  While you stop your pwm task to change duty cycle (may not be strictly necessary, btw), you update the direction bit while pwm is on.  I don't see an advantage to this, and it may put you at risk for thought #3 above.  I would set the direction bit between the time you stop the pwm and when you restart it.

c. I don't really know what the following line is supposed to do, but it appears that it may not have anything to do with your DAQ tasks.   If it does, please explain.

                                        SetCtrlVal(motorTab, MOT_TAB_DIRECTION, cur_direction);

-Kevin P.

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 3 of 9
(4,908 Views)

In response to item 1, I do not believe there are any diode protection for the drive or L296 itself.  From what I remember of the board (it's being replaced) is that the diode arrays were protecting the inputs but I don't want to say for sure.

In response to item 2, I'm pretty sure the L296 handles both motor directions.  On the schematic, it appears as a pretty standard 4 transistor H-bridge.  The board itself, provided by the department, has a four pin breakout (2 direction, 1 enable, 1 GND).

In response to item 3, I thought of that as well.  I think what happened was that our enable bit was set to low (there is a PUN though) so when the direction changed, the motor was NOT in high impedance and the resulting back emf created a current surge right through the L296.  I think because our counter/PWM was not set to HIGH during the transition, this is what caused our device fail.

---

For the if statements, I know I could use an XOR set up but I'm not sure how to do that when using data types other than simple logic (TRUE FALSE).

We keep getting errors when we change the duty cycle if we do not stop the task first, I think you may also be correct and we should send the digital write into the if(running).  No reason why it should execute each time through unless something changed...

The SetCtrlVal() is simply there to display what is currently written to the bits.  We grew tired of using a voltmeter and too lazy  to slap in some transistor and LEDS.  Well, not lazy, it's just the extra wiring is a bit much on the prototyping board.

 

Thanks for the info.  We should be getting our new H-bridge board in a few hours.

0 Kudos
Message 4 of 9
(4,904 Views)

Back to your original query: I'm not at hardware to verify, but I'm >95% sure that when you Stop a counter output task, the output will go to idle state.  By default, counter idle states tend to be low. 

What I'm less sure about is whether the low output state is the same for a running task vs. a stopped task.  What I mean by that is that when the task is stopped, it may be that the pin is not *driven* low, but merely floats low with a weak pull-down resistor.  If so, then there's a chance external circuitry may override the weak pull-down and cause the state to float high while the task is stopped.

Very speculative on my part, just a couple thoughts that may be useful.

-Kevin P.

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 5 of 9
(4,902 Views)
It appears we may have fried our THIRD L296, I think.  I tried hard-wiring the device up twice one one set of inputs and it didn't work while it would work on the other.  I left the lab in frustration but I'll check more thouroughly in the coming days.

We've check the PSU powering our circuitry and nothing seems amiss on that end.

So much for DAQmx.  It goes *bye bye*.

I refuse to drop back to Traditional NI DAQ because it's less friendly when it comes to counters (meaning we have to implement a lot in s/w, which I refuse to do on a Windows box) and there is a time constraint.  Looks like I might just take my PIC18F4550 (if I can get the PWM frequency down to 45Hz, that is.  Not sure I can get the frequency that low on a PIC without external h/w), grind out some code in MPLAB and PIC-C and use that instead.  PIC does give me an advantage over the DAQ board as I can get PWM output and two counters (we have a quadrature encoder on the motor).  Rigt now with the DAQ we only get PWM and one encoder channel so we keep track of direction by global variable.

There is something fundamentally wrong we are doing with our PWM code, which we basically purloined from the Example Finder I may add.  Since none of the other groups are experiencing ANY problems with their PWMs, and since we're the only ones using DAQmx, it really seems clear where the problems are coming from.

Our experiences with NI have not been pleasant, to put it mildly.  Usually, we are the first group done but now we are falling behind, badly.

Here is what we did (removed all the calls to controls and such as well as velocity calculations from the other counter):

void MotorRun(double speed)
{
    uInt8 bits[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
    unsigned int j, k;
    unsigned int samples;
   
    if (speed > 0)
        {
        bits[0] = 1;
        bits[1] = 0;
        cur_direction = FORWARD;         // Just a global variable so we can keep track of direction.
        }
        else
            {
            bits[0] = 0;
            bits[1] = 1;
            cur_direction = BACKWARD;  
            }


    if ((count == old_count)  && (running))
    {
        //
        // EMERGENCY STOP!
        //
    }
   
    //
    // LabWindows/CVI does not like it when you set the duty cycle at 0 or at 1.  The '1' condition is prevented by the dial.
    //
    if ((speed == 0) && (running == TRUE))
        {
            running = FALSE;
            DAQmxStopTask(pwmHandle);
        }
           
    if ((speed != 0) && (running == FALSE))
        {
            running = TRUE;
            DAQmxStartTask(pwmHandle);
        }
   
    //
    // Here is where we trap the PWM 1 duty cycle condition.
    //
    if (speed > 1) speed = 0.999;
   
    //
    // Gets rid of the minus sign so we can pass directly to PWM.
    //
    if (speed < 0) speed *= -1;       

    if (running)
        {       
        DAQmxStopTask(pwmHandle);
        DAQmxWriteDigitalLines(dirHandle,1,1,10.0,
                DAQmx_Val_GroupByChannel,bits,NULL,NULL); 
        DAQmxSetCOPulseDutyCyc(pwmHandle, pwmchan, speed); 
        DAQmxStartTask(pwmHandle);
        }

}

Message Edited by Patrickw on 03-29-2007 08:17 PM

0 Kudos
Message 6 of 9
(4,895 Views)

Just a friendly thought:  I've used DAQmx for some pretty high-intensity apps, and far more often than not, the layer of abstraction it offers has been a significant benefit compared to doing things with raw bit twiddling on a micro.  Not trying to talk you out of using the PIC -- you've got a deadline, so do what you gotta do.  Just realize that an awful lot of people have managed to successfully use NI boards and DAQmx in a wide range of apps.  Granted, there's a non-trivial learning curve getting used to it, and right now you may not have that time to spare.

Have you done any signal checking to answer questions you raised?  If you step through your code line-by-line in debug mode, what state is the counter output in when you stop the task?  Is it always the same or does it vary from run to run?  Are you sure the counter's idle state corresponds to the "OFF" state for the drive circuit?

One last possible tidbit: I know that from LabVIEW, there's a quirk about changing a pulse train's duty cycle.  The freq and duty cycle settings get committed when you write to the freq property.  If you only write to the duty cycle property, it may not commit.  (These rules apply when trying to change freq/duty cycle on the fly.  Don't know if they apply in a case like yours with the task temporarily stopped.)  There's a chance that your attempts to change duty cycle never "take".

Here's a link.  Another one here.  One more.  And finally...   And yes, I agree, that's a DAQmx quirk that's worth grumbling about.  Meanwhile, good luck with the PIC.

-Kevin P.

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 7 of 9
(4,875 Views)
I think the best way to proceed is to program the PIC, it's not like it's going to kill me, and then Tuesday get an oscilliscope to see the PWM output on the screen.

We are rather far into the project to simply restart the entire thing with Traditional APIs...  this is the only real item preventing us from completing.


0 Kudos
Message 8 of 9
(4,870 Views)
I'm seriously thinking that our problem lies outside DAQmx assuming that setting our idle to HIGH is functioning correclty (our high-impedance mode is HIGH, we *think*). Since the chip is frying with idle either set to HIGH or LOW, I'm having trouble seeing what else can destroy the chip...

It's getting me thinking, the provided truth table does not EXPLICITLY say what combination is high-impedance mode, just says that we have a forward bit, backward bit, and an "enable" bit where all bits are active low...

Usually, all H-bridges don't really care about the input direction bits when in high-impedance. Usually they are "don't care".
0 Kudos
Message 9 of 9
(4,845 Views)