Changing Freq on three(3) Timers (FR446RE)

Post here first, or if you can't find a relevant section!
Post Reply
killacycle
Posts: 14
Joined: Tue Nov 19, 2024 1:59 am

Changing Freq on three(3) Timers (FR446RE)

Post by killacycle »

I am setting three separate frequencies on three separate timers, and using the outputs to run three steppers.
Runs great _until_ I attempt to change the frequency.
When I call "MyTimx->setPWM(channelx, pins[x], ..." to set a new frequency, the first and third timers change frequency perfectly, but the second timer simply stops.

When I run the code below, initially, all three stepper motors run perfectly at the initially assigned speeds, 200, 100, and 80 Hz.
When I then toggle the Hauler switch OFF, the first and third steppers speed up, and the second one simply stops.
The first and third steppers revert to their default speeds when I toggle the Hauler switch back ON, and the second stepper remains stopped.

Does anyone have any clues, hints, or tips? (I have been scratching my head over this for a week.)

Thank you so much, in advance,
Bill D.

Here is my code:

Code: Select all

// Three pulse timer outputs
// Nucleo 64 FR446RE 

  #define VER 4
  #include <Bounce2.h> // Used to debounce switches. Seems to work quite well indeed. 
  Bounce HaulerSwitch = Bounce();
  #define ENABLE_HAULER    PB4  

  // Define Stepper pins
#define STEP0 PC6  // Stepper Pulse #0 signal (white with black stripe) Spool stepper pulse
#define DIR0 PC5  // Stepper Direction #0 (yellow)
#define ENA0 PA11  // Stepper Enable #0 (white)

#define STEP1 PB1  // Stepper Pulse #1 signal (white with gray stripe) Roller stepper pulse
#define DIR1  PB15 // Stepper Direction #1 (yellow)
#define ENA1  PB14 // Stepper Enable #1  (white)

#define STEP2 PB2  // Stepper Pulse #2 signal (white with brown stripe) Guide stepper pulse
#define DIR2  PC7  // Stepper Direction #2 (yellow)
#define ENA2  PA9  // Stepper Enable #2 (white)
 
unsigned int FreqFourValue;

// Set up parameters for F446RE timers to run stepper pulses

  #define NUM_OF_PINS  3 // ( sizeof(pins) / sizeof(uint32_t) )
  uint32_t pins[NUM_OF_PINS] = { STEP0, STEP1, STEP2 }; // These pins seem to work for timers
  // 50% and 50% 50%
  uint32_t dutyCycle[NUM_OF_PINS] = { 50, 50, 50 }; // Set duty Cycle for STEP0, STEP2, STEP2
  // Set to MinPPS, to start with
  uint32_t freq[NUM_OF_PINS] = { 200, 100, 80 }; // Set Starting Frequency for STEP0, STEP2, STEP2

  // Set up hardware timers to make stepper pulses for MyTim0, MyTim1, MyTim2 on pins STEP0, STEP1, and STEP2
  // Use "MyTimx->setPWM(channelx, pins[x], ..." Substitute new integer freq in Hz for "freq[x]" and the pin will make that freq
  
  TIM_TypeDef *Instance0 = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pins[0]), PinMap_PWM);
  uint32_t channel0 = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pins[0]), PinMap_PWM));
  HardwareTimer *MyTim0 = new HardwareTimer(Instance0);
   
  TIM_TypeDef *Instance1 = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pins[1]), PinMap_PWM);
  uint32_t channel1 = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pins[1]), PinMap_PWM));
  HardwareTimer *MyTim1 = new HardwareTimer(Instance1);
 
  TIM_TypeDef *Instance2 = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pins[2]), PinMap_PWM);
  uint32_t channel2 = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pins[2]), PinMap_PWM));
  HardwareTimer *MyTim2 = new HardwareTimer(Instance2);

void setup()
{ 
  
//  Set the timer parameters
    MyTim0->setPWM(channel0, pins[0], freq[0], dutyCycle[0]);
    MyTim1->setPWM(channel1, pins[1], freq[1], dutyCycle[1]);
    MyTim2->setPWM(channel2, pins[2], freq[2], dutyCycle[2]); 
  
  // Set up pins for SpoolA STEP0 Direction and Enable
  pinMode(DIR0,OUTPUT);
  digitalWrite(DIR0, LOW); // Set to cw
  pinMode(ENA0,OUTPUT);
  digitalWrite(ENA0,LOW); // enable pin is inverted, HIGH = OFF

  // Set up pins for Roller STEP1 Direction and Enable
  pinMode(DIR1,OUTPUT);
  digitalWrite(DIR1, LOW); // Set to CW
  pinMode(ENA1,OUTPUT);
  digitalWrite(ENA1,LOW); // enable pin is inverted, LOW = enabled
 
  // Set up pins for Guide STEP2 Direction and Enable 
  pinMode(DIR2,OUTPUT);
  digitalWrite(DIR2, LOW); // Set to cc
  pinMode(ENA2, OUTPUT); 
  digitalWrite(ENA2,LOW);  // enable pin is inverted 

  HaulerSwitch.attach(ENABLE_HAULER, INPUT_PULLUP ); // Debounce setup for ENABLE_HAULER 
  HaulerSwitch.interval(50); // HaulerSwitch sampling interval in ms
  HaulerSwitch.update( );
  delay(100);

} // end setup()

void loop()
{
  if (HaulerSwitch.fell()) { //The "run" switch has transitioned OFF
    digitalWrite(ENA0, LOW);  // enable pin is inverted, LOW = Enabled
    digitalWrite(ENA1,LOW); // enable pin is inverted, LOW = Enabled
    digitalWrite(ENA2,LOW); // enable pin is inverted, LOW = Enabled
    
    FreqFourValue = 4*freq[0]; // Set all freq to 3 x the freq[0] starting value
    
    MyTim0->setPWM(channel0, pins[0], FreqFourValue, dutyCycle[0]); 
    MyTim1->setPWM(channel1, pins[1], FreqFourValue, dutyCycle[1]);
    MyTim2->setPWM(channel2, pins[2], FreqFourValue, dutyCycle[2]);
  }
  
  if (HaulerSwitch.rose()) { // The "run" switch has transitioned ON
    digitalWrite(ENA0, LOW);  // enable pin is inverted, LOW = Enabled
    digitalWrite(ENA1,LOW); // enable pin is inverted, LOW = Enabled
    digitalWrite(ENA2,LOW); // enable pin is inverted, LOW = Enabled
    
    // Restore the freq to their starting values
    MyTim0->setPWM(channel0, pins[0], freq[0], dutyCycle[0]);
    MyTim1->setPWM(channel1, pins[1], freq[1], dutyCycle[1]);
    MyTim2->setPWM(channel2, pins[2], freq[2], dutyCycle[2]);
  }  
  
  HaulerSwitch.update( );
} // end loop()
fpiSTM
Posts: 1946
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: Changing Freq on three(3) Timers (FR446RE)

Post by fpiSTM »

I would recommend to not use a negate channel. In your case PB1 is TIM1_CH3N.

You can try this:
STEP0 --> PC6_ALT1 --> TIM8_CH1
STEP1 --> PB1_ALT1 --> TIM3_CH4
STEP2 --> PB2 --> TIM2_CH4 (no change)


Tested and it works.
fpiSTM
Posts: 1946
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: Changing Freq on three(3) Timers (FR446RE)

Post by fpiSTM »

I've investigated the issue and found the root cause.
Could you file an issue on GitHub then I will fix it.

https://github.com/stm32duino/Arduino_Core_STM32/issues
killacycle
Posts: 14
Joined: Tue Nov 19, 2024 1:59 am

Re: Changing Freq on three(3) Timers (FR446RE)

Post by killacycle »

Thank you so much for your prompt reply.

I substituted:
#define STEP0 PC6
with
#define STEP0 PC6_AT1
and
#define STEP1 PB1
with
#define STEP1 PB1_ALT1

And the this modified code worked MARVELOUSLY!

Just out of curiosity, does adding "_ALT1" to the port label move you over one slot on the Alternate Function table?
If I had changed "#define STEP1 PB1_ALT1" to "#define STEP1 PB1_ALT2", would STEP1 become TIM8_CH3N?

I am a bit of a "script kiddy" when it comes to timers, etc. I just alter the published code a bit to suit. :oops: I code primarily in C and try not to stray too much into C++.

Again, thank you so much for your extremely helpful and prompt reply.

Bill D.
PS
How would I go about filing an issue on GitHub ArduinoCore_STM32/issues?
I would gladly do so if it would be helpful.
fpiSTM
Posts: 1946
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: Changing Freq on three(3) Timers (FR446RE)

Post by fpiSTM »

No link with alternate function. Just a way to get an other alternative possibility of a pin:
https://github.com/stm32duino/Arduino_C ... ins.c#L147

About creating an issue:
https://docs.github.com/en/issues/track ... g-an-issue
fpiSTM
Posts: 1946
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: Changing Freq on three(3) Timers (FR446RE)

Post by fpiSTM »

killacycle wrote: Tue Nov 19, 2024 10:23 pm Just out of curiosity, does adding "_ALT1" to the port label move you over one slot on the Alternate Function table?
If I had changed "#define STEP1 PB1_ALT1" to "#define STEP1 PB1_ALT2", would STEP1 become TIM8_CH3N?
Exactly, just pay attention to use pin number PYn (ex: PB1) and not PinName PY_n (ex: PB_1) which is not the same.
killacycle wrote: Tue Nov 19, 2024 10:23 pm How would I go about filing an issue on GitHub ArduinoCore_STM32/issues?
I would gladly do so if it would be helpful.
Sure it would be helpful.
If you Have a GitHub account simply click "New issue" in the provided link, if you don't then I will create it with the link to this topic.
fpiSTM
Posts: 1946
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: Changing Freq on three(3) Timers (FR446RE)

Post by fpiSTM »

I've created the issue and provice a fix. Note that it should improve the HardwareTimer usage and avoid glitch.
https://github.com/stm32duino/Arduino_C ... ssues/2575
killacycle
Posts: 14
Joined: Tue Nov 19, 2024 1:59 am

Re: Changing Freq on three(3) Timers (FR446RE)

Post by killacycle »

Thank you for fixing the GitHub reference code.

I am not a registered member of GitHub, so I was unable to make the request. :oops:

Sorry,
Bill D.
Post Reply

Return to “General discussion”