21 Replies Latest reply on Dec 23, 2013 11:20 AM by vsluiter

    Any ideas on how to count pulses and shut off a PWM


      TL;DR version: How do I count pulses with programmable digital and use the count to shut off 5 PWMs. The count to shut off and the frequency of the PWMs would have to be set in software for each iteration.


      I'm trying to figure out a good way to use programmable digital of the PSoC 4 on the pioneer kit to do coordinated stepper moves. Setting up a PWM module was pretty easy, I just need something to shut it off after a set number of pulses. The black box description is this, the software sets the pulse frequency for several modules, 5 in this case, with the timing already calculated so that they will finish their pulses in the same amount of time, then it starts them at the same time, then they all shut off when they're done and signal (probably via interrupt) back to the software that the move is done and they are ready for the next. I'm thinking the architecture would use one PWM module as the master, if there are not timing glitches they would all finish together, it would stop them, and interrupt that the move was done.


      So far I have found that I can easily set a PWM module for a certain frequency from the software, but I'm not sure how to make a counter shut it off. The algorithm is pretty simple for these moves, you have a known speed in pulses at which each axis can move given the electrical and mechanical limitations of the system, given the number of steps required for a move on each axis and that speed you can find which one will take the longest, and divide the number of pulses for all the others to make them happen in that amount of time. At that point most controllers just use timers to generate and count those pulses, I'd like to figure out a nice efficient way to do it in programmable digital. I think it should be pretty simple if I can just figure out how to count pulses with a counter, then I would have it trigger an interrupt and stop the PWMs when the target is reached, can someone show me how to do that? I'd also be interested in other hardware architectures that can do this.


      As a note, this is for the smarter life challenge, I'm not really worrying about my competitors seeing my code. If I win I want it to be by making the coolest project, not because they got stuck.


      Thanks for reading

        • Re: Any ideas on how to count pulses and shut off a PWM

          Hi Paul,


          I believe that you can set up counters and status registers inside the PSOC.

          I think that you can turn the PWM outputs on and off by using a status/control register from the software side.

          Inside the IDE, you should be able to activate the software S/C register to work off either interrupt or other triggers.

          You should be able to configure the output pins to provide inputs for PSOC counters.


          Note, I have read about this capability in the documentation, but I have not implemented it.  I bring it to your attention so you can check the documentation on interfacing the software side of the PSOC with the HW programmable side.



            • Re: Any ideas on how to count pulses and shut off a PWM

              Thanks Dab, I have something like that in mind, I was trying to do it largely in programmable digital to better use the psoc and offload some work from the mcu. I think a counter unit could do the job but I'm not sure how to count pulses, when I tried I seemed to be counting clock pulses and my cc didn't switch. I could certainly use a variable incremented in an isr, but if I just new how to set a counter device to do it, it would be so fast an efficient and it would be a way that no other Microcontroller could do it, so it would really showcase the psoc capabilities.

            • Re: Any ideas on how to count pulses and shut off a PWM

              Hi Paul...


              You just need to count the number of pulses, and store the value in some integer and when that value reaches your desired value set a command to stop the PWM.. i have done this with Arduino and it works, i think that would also do the job for you.. best of luck..

              • Re: Any ideas on how to count pulses and shut off a PWM

                A PWM can be configured to have an enable input. This can be used for disabling it. Then use an additional counter for counting the pulses of the PWM. The compare output of the counter can then drive the enables signal to stop the PWM.


                Or, if the frequency of your PWM is not so high, you can trigger an interrupt at the end of each period and count there.

                1 of 1 people found this helpful
                • Re: Any ideas on how to count pulses and shut off a PWM

                  My solution was to use a lower frequency clock to drive a PWM(acting as a counter) just to generate a time-base during which the other 4 PWMs could generate the required number of pulses. We then use a bunch of glue logic to gate the signals.


                  I only show 2 PWMs below, to demonstrate how it will work with both fixed function PWMs and UDB PWMs.



                  #define CLOCK_RESET_KHZ             100     //the input clock for the reset PWM
                  #define CLOCK_STEPPER_KHZ           12000   //the input clock for the stepper PWMs
                  #define PULSE_INCREMENT_INTERVAL1   10      //increment pulse1 count by this each time around (minimum of ~10 with these clocks)
                  #define PULSE_INCREMENT_INTERVAL2   5       //increment pulse2 count by this each time around
                  #define PULSE_TRAIN_LENGTH_MS       50      //length of time for each co-ordinated move
                  #define SW_DELAY_MS                 100     //delay by this much after starting the co-ordinated move
                  uint8 newMoveFlag = 0xff;
                  int main()
                      // Declare variables
                      uint16 pulsesPerPeriod1 = 0;
                      uint16 pulse1CounterPeriod;
                      uint16 pulsesPerPeriod2 = 0;
                      uint16 pulse2CounterPeriod;    
                      uint16 resetCounterPeriod;
                      // Start components
                      // Set reset counter period (this could change at runtime also)
                      resetCounterPeriod = (CLOCK_RESET_KHZ * PULSE_TRAIN_LENGTH_MS);
                      CyGlobalIntEnable; /* Uncomment this line to enable global interrupts. */
                          // Only update the configuration if a new co-ordinated move is desired. 
                          // This flag is set in the PWM_Reset TC ISR
                              // Calculate the new PWM periods
                              // Stepper 1
                              pulsesPerPeriod1 += PULSE_INCREMENT_INTERVAL1;
                              pulse1CounterPeriod = ((uint32)CLOCK_STEPPER_KHZ/CLOCK_RESET_KHZ)* resetCounterPeriod / pulsesPerPeriod1;
                              if(pulse1CounterPeriod < 2) // Check for rollover
                                  pulsesPerPeriod1 = PULSE_INCREMENT_INTERVAL1;
                                  pulse1CounterPeriod = ((uint32)CLOCK_STEPPER_KHZ/CLOCK_RESET_KHZ)* resetCounterPeriod / pulsesPerPeriod1;
                              // Stepper 2
                              pulsesPerPeriod2 += PULSE_INCREMENT_INTERVAL2;
                              pulse2CounterPeriod = ((uint32)CLOCK_STEPPER_KHZ/CLOCK_RESET_KHZ)* resetCounterPeriod / pulsesPerPeriod2;
                              if(pulse2CounterPeriod < 2) // Check for rollover
                                  pulsesPerPeriod2 = PULSE_INCREMENT_INTERVAL2;
                                  pulse2CounterPeriod = ((uint32)CLOCK_STEPPER_KHZ/CLOCK_RESET_KHZ)* resetCounterPeriod / pulsesPerPeriod2;
                              // Disable the counters
                              // Reset the counters
                              // Set the period of the pulse counters
                              // Stepper 1 (UDB PWM)
                              // Stepper 2 (Fixed Function TCPWM)
                              // Enable the counters. pulses start here.
                              // Clear the flag and wait for the next update
                              newMoveFlag = 0x00;
                  /* [] END OF FILE */
                  • Re: Any ideas on how to count pulses and shut off a PWM

                    I'm going to finish the project for the contest this way, but a interesting idea occurred to me. It seems like feedback servo control could also be done in hardware, the encoder can be read by a decoder or a counter and that can be fed into a comparison. I haven't worked out the details, but it has potential. I'm not just talking about basic potentiometer feedback servos like an RC car, but high speed precision ones like you would use in an industrial robot, the kind with 1024 or more counts per rev. I wonder how fast you could go, the ones we buy at my job usually cost about $700 because they can update the torque command at 4 MHz. It almost seems like a PSoC could do that, though getting the curve just right would be tricky and of course it would still need the power amplification stage. It can't handle 10A to 50A, but then you can't blame them for that, some good size high frequency Mosfets in an H-bridge could take care of it. Just food for thought.