Skip to content

HardwareTimer library is not working #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
karstengit opened this issue Feb 20, 2020 · 14 comments · Fixed by #21
Closed

HardwareTimer library is not working #20

karstengit opened this issue Feb 20, 2020 · 14 comments · Fixed by #21
Assignees
Labels

Comments

@karstengit
Copy link

I tried out the new HardwareTimer library but it seems not work on an BluePill.
This is a very good idea.

Specially the example compiles with no error but does not do anything:
https://github.com/stm32duino/STM32Examples/blob/master/examples/Peripherals/HardwareTimer/PWM_FullConfiguration/PWM_FullConfiguration.ino

Has the STM32 core 1.8.0 been rolled back?

@ABOSTM
Copy link
Contributor

ABOSTM commented Feb 20, 2020

Hi @karstengit,
HardwareTimer works well on BluePill with core 1.8.0
But it is true that the example doesn't work out of the box for this board:
the example try to use LED_BUILTIN as PWM output to have visual effect,
unfortunately, for this board, LED_BUILTIN = PC13 and PC13 doesn't have HardwareTimer capability.

So, for this board, you need to modify the pin used to have the HardwareTimer capability.
ex: #define pin PA0

I will add a note in the examples about this.

@karstengit
Copy link
Author

Yes, but when i connect an LED with resistor to PA8 this does not work too.

/*
  All-in-one setPWM
  This example shows how to configure a PWM with HardwareTimer in one single function call.
  PWM is generated on `LED_BUILTIN` if available.
  No interruption callback used: PWM is generated by hardware.
  Once configured, there is no CPU load.
*/

#define pin  PA8

void setup()
{
  // no need to configure pin, it will be done by HardwareTimer configuration
  // pinMode(pin, OUTPUT);

  // Automatically retrieve TIM instance and channel associated to pin
  // This is used to be compatible with all STM32 series automatically.
  TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pin), PinMap_PWM);
  uint32_t channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin), PinMap_PWM));


  // Instantiate HardwareTimer object. Thanks to 'new' instantiation, HardwareTimer is not destructed when setup() function is finished.
  HardwareTimer *MyTim = new HardwareTimer(Instance);

  // Configure and start PWM
  // MyTim->setPWM(channel, pin, 5, 10, NULL, NULL); // No callback required, we can simplify the function call
  MyTim->setPWM(channel, pin, 5, 10); // 5 Hertz, 10% dutycycle
}


void loop()
{
  /* Nothing to do all is done by hardware. Even no interrupt required. */
}

With 1.8.0. the programming with stm32flash is missing too?

@ABOSTM
Copy link
Contributor

ABOSTM commented Feb 20, 2020

I checked on PA8 on my side with your exact sketch above (with an oscillo), it is well working.
Please check your setup.
Warning only 10% duty cycle is configured it may be insufficient for your LED.

Yes stm32flash has been replaced by cubeProgrammer since core 1.6.0:
https://github.com/stm32duino/wiki/wiki/Upload-methods#serial

@karstengit
Copy link
Author

Thanks for your support.
I tested now with an osci too - but the pin is constant on +3.3.
I tried with a higher frequency but the result is the same.
MyTim->setPWM(channel, pin, 50, 50);

Maybe the Blue-Pill is broken?
I will try it with another one, but at this time i will not believe it.

Maybe the compilation output is wrong?
PWM-Test.zip
Can you flash this or maybe you can give me yours?

Ah - cubeProgrammer is new. O.K. sounds good, but
a) it is not Opensource
b) it needs Java to run?
c) Java itself seems to get not free anymore
Java
(I need an update, because my system has only V1.7 installed)

How can i use the old stm32flash instead that is very small and quick in Linux?

@ABOSTM
Copy link
Contributor

ABOSTM commented Feb 21, 2020

Hi @karstengit,
With your binary I got nothing on PA8.
Here is mine which is well working (official 1.8.0 version with your sketch above)
arduino_build_560972.zip

I let @fpistm comment about CubeProgrammer.

@fpistm
Copy link
Member

fpistm commented Feb 21, 2020

a) it is not Opensource

No, but multi OS and mainly it supports all STM32 series while STM32Flash not.

b) it needs Java to run?

Yes

c) Java itself seems to get not free anymore

You can use the OPENJDK

How can i use the old stm32flash instead that is very small and quick in Linux?

You will have to do ii your own.
You can create a platform.local.txt and boards.local.txt to override the default one with you new upload method:
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#platformlocaltxt
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#boardslocaltxt
or have a look here:
https://github.com/stm32duino/wiki/wiki/Custom-board-based-on-a-core

@karstengit
Copy link
Author

The reason for this problem can be found here: stm32duino/Arduino_Core_STM32#948

@karstengit
Copy link
Author

Hi @karstengit,
With your binary I got nothing on PA8.

Then there was really a problem with the build of the binary.

Here is mine which is well working (official 1.8.0 version with your sketch above)
arduino_build_560972.zip

Thanks - it is working here too.

@karstengit
Copy link
Author

a) it is not Opensource
No, but multi OS and mainly it supports all STM32 series while STM32Flash not.

Yes - that's fine.

b) it needs Java to run?
Yes

128 MB instead of 27 KB for st-flash - is there something more to say?

c) Java itself seems to get not free anymore
You can use the OPENJDK

The problem is that CubeProgrammer could be installed but is not running on my Debian 8 or 10.
At my beginner level i don't need the functionality of this tool - i just want to flash some BluePills.

How can i use the old stm32flash instead that is very small and quick in Linux?
You will have to do ii your own.

It was already implemented.
How can i get the old implementation out of the git?

You can create a platform.local.txt and boards.local.txt to override the default one with you new upload method:
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#platformlocaltxt
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#boardslocaltxt
or have a look here:
https://github.com/stm32duino/wiki/wiki/Custom-board-based-on-a-core

This is the longer way.

It would be fine if the old programming modes would be still available and CubeProgrammer will be additional.
It can't be shipped with stm32duino - but the other small tools where no problem.

@karstengit
Copy link
Author

Regarding the example #20 (comment)
What must be done to alter the PWM in the main loop?

PWM-Test.ino: In function 'void loop()':
PWM-Test:81:5: error: 'MyTim' was not declared in this scope
   81 |     MyTim->setPWM(channel, PWM_PIN, frequency, percent); // Setting PWM
      |     ^~~~~

As you can see the declaration is not known outside of setup.

@fpistm
Copy link
Member

fpistm commented Feb 22, 2020

@karstengit
It seems clear you didn't define MyTim...

What is your full sketch...

For this kind of support, please the the forum...

@karstengit
Copy link
Author

You mean https://www.stm32duino.com/ ?
It is not so easy to become member and post there.

This sketch is working fine and shows how 2 channel-pins can be controlled with one timer.

// There are 2 LED's connected each to PA8 and PA11 over an resistor to +3.3V

#define PWM_FREQ  100
#define PWM_PIN_A   PA8
#define PWM_PIN_B   PA11

void setup() {
	pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
	// Here it is noc clear how the Instance must be defined to use mulitple channels
	TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(PWM_PIN_A), PinMap_PWM);

	// This works somehow when it is defined in the main loop
	static uint32_t channel_a = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(PWM_PIN_A), PinMap_PWM));
	static uint32_t channel_b = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(PWM_PIN_B), PinMap_PWM));
	HardwareTimer *MyTim = new HardwareTimer(Instance);

	while (1) {
		for(int i = 0; i < 100; i ++) {
			MyTim->setPWM(channel_a, PWM_PIN_A, PWM_FREQ, i, NULL, NULL); // Set PWM
			MyTim->setPWM(channel_b, PWM_PIN_B, PWM_FREQ, 100 - i, NULL, NULL); // Set PWM
			delay(5);
		}
		digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // See direction
		for(int i = 100; i > 0; i --) {
			MyTim->setPWM(channel_a, PWM_PIN_A, PWM_FREQ, i, NULL, NULL); // Set PWM
			MyTim->setPWM(channel_b, PWM_PIN_B, PWM_FREQ, 100 - i, NULL, NULL); // Set PWM
			delay(5);
		}
		digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // See direction
	}
}

But it does not compile when the definition is made in the setup:

// There are 2 LED's connected each to PA8 and PA11 over an resistor to +3.3V

#define PWM_FREQ  100
#define PWM_PIN_A   PA8
#define PWM_PIN_B   PA11

void setup() {
	pinMode(LED_BUILTIN, OUTPUT);

	// Here it is noc clear how the Instance must be defined to use mulitple channels
	TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(PWM_PIN_A), PinMap_PWM);

	// This works somehow when it is defined in the main loop
	static uint32_t channel_a = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(PWM_PIN_A), PinMap_PWM));
	static uint32_t channel_b = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(PWM_PIN_B), PinMap_PWM));
	HardwareTimer *MyTim = new HardwareTimer(Instance);
}

void loop() {

	for(int i = 0; i < 100; i ++) {
		MyTim->setPWM(channel_a, PWM_PIN_A, PWM_FREQ, i, NULL, NULL); // Set PWM
		MyTim->setPWM(channel_b, PWM_PIN_B, PWM_FREQ, 100 - i, NULL, NULL); // Set PWM
		delay(5);
	}
	digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // See direction
	for(int i = 100; i > 0; i --) {
		MyTim->setPWM(channel_a, PWM_PIN_A, PWM_FREQ, i, NULL, NULL); // Set PWM
		MyTim->setPWM(channel_b, PWM_PIN_B, PWM_FREQ, 100 - i, NULL, NULL); // Set PWM
		delay(5);
	}
	digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // See direction

	
}
/PWM-Test.ino: In function 'void loop()':
PWM-Test:22:4: error: 'MyTim' was not declared in this scope
   22 |    MyTim->setPWM(channel_a, PWM_PIN_A, PWM_FREQ, i, NULL, NULL); // Set PWM
      |    ^~~~~
PWM-Test:22:18: error: 'channel_a' was not declared in this scope
   22 |    MyTim->setPWM(channel_a, PWM_PIN_A, PWM_FREQ, i, NULL, NULL); // Set PWM
      |                  ^~~~~~~~~
PWM-Test:23:18: error: 'channel_b' was not declared in this scope
   23 |    MyTim->setPWM(channel_b, PWM_PIN_B, PWM_FREQ, 100 - i, NULL, NULL); // Set PWM
      |                  ^~~~~~~~~
PWM-Test:28:4: error: 'MyTim' was not declared in this scope
   28 |    MyTim->setPWM(channel_a, PWM_PIN_A, PWM_FREQ, i, NULL, NULL); // Set PWM
      |    ^~~~~
PWM-Test:28:18: error: 'channel_a' was not declared in this scope
   28 |    MyTim->setPWM(channel_a, PWM_PIN_A, PWM_FREQ, i, NULL, NULL); // Set PWM
      |                  ^~~~~~~~~
PWM-Test:29:18: error: 'channel_b' was not declared in this scope
   29 |    MyTim->setPWM(channel_b, PWM_PIN_B, PWM_FREQ, 100 - i, NULL, NULL); // Set PWM
      |                  ^~~~~~~~~


@fpistm
Copy link
Member

fpistm commented Feb 22, 2020

But it does not compile when the definition is made in the setup:

Seriously?
In loop there is no reference to MyTim and this is normal as it is a local one to Setup. Same for channel_a, channel_b 😩 I could not spent my time to correct and explain how to code. This is purely C++ coding.

About:

You mean https://www.stm32duino.com/ ?
It is not so easy to become member and post there.

Honestly, I don't understand why it is not so easy just register and answer the question. If you have a trouble due to your mailbox then send a message to the admin and explain why.

128 MB instead of 27 KB for st-flash - is there something more to say?

Yes, this is the full package, you didn't need to install all. If you don't want use it I give you spome clue to do it. And as already said the main reason is multi OS and mainly it supports all STM32 series while STM32Flash not. In that case STM32Flash became useless and hard to maintain (user claims several time they could not flash some unsupported series of the tools but I'm not the maintainer of this tools moreover each time a new version was released I had to build for all hosts OS which is very time consuming.)

The problem is that CubeProgrammer could be installed but is not running on my Debian 8 or 10.
At my beginner level i don't need the functionality of this tool - i just want to flash some BluePills.

It could if you read the user manual as I already said.
For BP you can use the bootloader which allows to flash with DFU or as already said use *.local.txt to customize you setup.

It was already implemented.
How can i get the old implementation out of the git?

Well simply search in the commits or pull request. You can easily understand I can't do all for you. It is a community project and I'm not a dedicated resource to made code, user customisation or learn how to use git.

It would be fine if the old programming modes would be still available and CubeProgrammer will be additional.
It can't be shipped with stm32duino - but the other small tools where no problem.

No, as this not support all series and are not actively maintained. Again as said, you can use bootloader to flash over DFU or customize you configuration as other do. Or buy a Nucleo F103 RB which allow you to upload thanks a simple copy/past on the mass storage.

I lock this topic as issue should not be used for this kind of discussion --> forum.

@karstengit
Copy link
Author

You will have to do ii your own.
You can create a platform.local.txt and boards.local.txt to override the default one with you new upload method:
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#platformlocaltxt
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#boardslocaltxt
or have a look here:
https://github.com/stm32duino/wiki/wiki/Custom-board-based-on-a-core

That's really complicated.

I downloaded an older Release of STM32duino with
git clone https://github.com/stm32duino/Arduino_Core_STM32.git 1.4.0

The definitions can be found in the path .../arduino15/packages/STM32/hardware/stm32/1.8.0
So in boards.txt there is

# BLUEPILL_F103C8 board
GenF1.menu.pnum.BLUEPILL_F103C8=BluePill F103C8
GenF1.menu.pnum.BLUEPILL_F103C8.upload.maximum_size=65536
GenF1.menu.pnum.BLUEPILL_F103C8.upload.maximum_data_size=20480
GenF1.menu.pnum.BLUEPILL_F103C8.build.board=BLUEPILL_F103C8
GenF1.menu.pnum.BLUEPILL_F103C8.build.product_line=STM32F103xB
GenF1.menu.pnum.BLUEPILL_F103C8.build.variant=PILL_F103XX

And in platform.txt there is

# Uploader tool
# -------------------
...
# STM32CubeProgrammer upload
tools.stm32CubeProg.cmd=stm32CubeProg.sh
tools.stm32CubeProg.cmd.macosx=stm32CubeProg
tools.stm32CubeProg.cmd.windows=stm32CubeProg.bat
tools.stm32CubeProg.path.linux={runtime.tools.STM32Tools.path}/tools/linux
tools.stm32CubeProg.path.macosx={runtime.tools.STM32Tools.path}/tools/macosx
tools.stm32CubeProg.path.windows={runtime.tools.STM32Tools.path}/tools/win
tools.stm32CubeProg.upload.params.verbose=
tools.stm32CubeProg.upload.params.quiet=
tools.stm32CubeProg.upload.pattern="{path}/{cmd}" {upload.protocol} "{build.path}/{build.project_name}.bin" {upload.options}

But in the older release i can't find the definitions to program with the stm32flash or the scripts for it?

@stm32duino stm32duino locked as off-topic and limited conversation to collaborators Feb 22, 2020
@fpistm fpistm added the invalid label Feb 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants