Is there an easy way to do PWM yet?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
User avatar
UltraBob
Posts: 43
Joined: Mon Jul 28, 2014 1:18 pm
Location: Zushi, Japan
Contact:

Is there an easy way to do PWM yet?

Post by UltraBob » Mon Jul 28, 2014 1:25 pm

HI all,

I think I pledged to a project above my pay grade as far as knowledge about workijng with mocricontrollers goes. I've successfully used the tutorials to get a cool little lego car to run around and entertain my kids, but I want to figure out how to make the board do more than control the internal leds, respond to the on board button, and control hobby servos. I thought a good way to do this would be to run through some getting started with arduino tutorials and figure out how to convert them over to the micropython board. I don't expect the python language to be a problem for me initially, I think I've got enough skill with python to get myself in at least a little ways. The thing that has me stopped at exercise 2 in the arduino series I'm looking at is PWM. I thought there must be a reasonable way of doing PWM on the board, given that a lot of the pins are labelled as PWM, but I can't find anything in the documentation, the forum, or even the github wiki that lays out example code as to how to do it. Am I missing it or does it not exist? Can anyone help me figure out how I would use PWM on the KS micropython board?

fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: Is there an easy way to do PWM yet?

Post by fma » Mon Jul 28, 2014 2:52 pm

Frédéric

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Is there an easy way to do PWM yet?

Post by dhylands » Mon Jul 28, 2014 3:16 pm

I've been working on timer stuff, but first I needed to get the alternate functions working properly. I just created a pull request to get the alternate function stuff landed and once its available, then I can continue working on timer functions (and PWM is a timer function).

PinkInk
Posts: 65
Joined: Tue Mar 11, 2014 3:42 pm

Re: Is there an easy way to do PWM yet?

Post by PinkInk » Mon Jul 28, 2014 4:20 pm

UltraBob - that is a very, very good way of diving in ... it's exactly what I was doing, when I built my dead-bug motor controller (to be exact; Chapter 10 of 'Arduino Projects Book' accompaniment to "The Arduino Starter Kit"), albeit - I already knew that whilst the pyboard is perfectly capable of pwm, it isn't yet implemented (this is a Kickstarter/WIP, not a 100% complete project/product - however it's 1000% more accessible than Arduino already IMHO).

The rabbit hole of "need PWM" was deep, but working a way around it, however temporary (as I always was sure, as Dave Hylands has noted, that official support "is coming"), taught me more in 2 weeks of banging my head against the table than any manual ever would.

(a) for the moment you can the use the module I shared, that fma references, just copy the code into pwm.py on the pyboards drive, then import it
(b) 'proper' PWM and all the rest of the as yet unexposed MCU capabilities will undoubtedly be here, in due-course

Don't give up yet ;o)

User avatar
UltraBob
Posts: 43
Joined: Mon Jul 28, 2014 1:18 pm
Location: Zushi, Japan
Contact:

Re: Is there an easy way to do PWM yet?

Post by UltraBob » Tue Jul 29, 2014 12:01 pm

Thanks all!

Pink Ink, I appreciate the code, and the encouragement. I'll dig in and try that out tonight. I'm glad you banged your head against it cause I'm not sure I could put together a formidable enough time/brain cells team to tackle it. :)

User avatar
UltraBob
Posts: 43
Joined: Mon Jul 28, 2014 1:18 pm
Location: Zushi, Japan
Contact:

Re: Is there an easy way to do PWM yet?

Post by UltraBob » Tue Jul 29, 2014 2:30 pm

Brilliant, here that is powering an RGB led, though it turns out on the third setColor() because my blue led component seems to not be working. (I voltage tested, and there is more voltage getting through on that third pin than the others, so it seems not to be a problem of the board or the code.

Code: Select all

import pwm, pyb
redPin = pwm.PWM(pyb.Pin.board.Y3) #pass in desired pin, only Y3,Y4,Y7,Y8,Y9,Y10,X1,X2,X3,X4,X9,X10 known to work
greenPin = pwm.PWM(pyb.Pin.board.Y4)
bluePin = pwm.PWM(pyb.Pin.board.Y7)

def setColor(red, green, blue):
    redPin.duty(red)
    greenPin.duty(green)
    bluePin.duty(blue)
    
#pY3.duty(125) #range is 0 (off - 0v) to 255 (on - 3.3v)
#pY3.duty()
#125                #current set duty is returned

setColor(255,0,0)
pyb.delay(1000)
setColor(0,255,0)
pyb.delay(1000)
setColor(0,0,255)
pyb.delay(1000)
setColor(0,0,0)
I am far from an expert in electronics so maybe someone can tell me what this indicates:

I measured the voltages of all three pins straight to the multimeter with no leds or resistors in line and they all came to right around 3.3v. I measured the three pins at the pins going into the rgb led with a 220ohm resistor in line and got the following: With Y3 set to 255 I measured 2.276V, with Y4 at 255 I got 2.628V, and with Y7 at 255 I got
3.306 (Y7 is the blue pin that is not lighting up the led) is the voltage different because the blue element is burned out or does that indicate something else?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Is there an easy way to do PWM yet?

Post by dhylands » Tue Jul 29, 2014 5:01 pm

Different colors of LEDs have different forward voltage drops.

For example, with this LED you can see that Red is 2.1 to 2.5v an Green and Blue are both 3.8 to 4.5v
This All About LEDs page has some excellent background material.

Since the pyboard's output pins only go up to 3.3v, even at full voltage, you're probably going to get a dimmer output since the LED won't be fully on.

The normal solution to this is to use a MOSFET or transistor to switch the voltages and use a higher voltage to actually drive the LED. You typically need to do this anyways for driving more than a couple LEDs since you quickly exceed the current capability of the microcontroller.

Here's an example on the adafruit site for driving LED strips.

User avatar
UltraBob
Posts: 43
Joined: Mon Jul 28, 2014 1:18 pm
Location: Zushi, Japan
Contact:

Re: Is there an easy way to do PWM yet?

Post by UltraBob » Wed Jul 30, 2014 12:46 am

Thanks Dave,

That is really helpful. I have one of these.

It looks like it has resistors inline, do I still need to add my own resistors to the circuit?

At any rate, I'll read up on the MOSFET. There are a lot of things I really need to learn before I'll be semi-competent at this.

User avatar
UltraBob
Posts: 43
Joined: Mon Jul 28, 2014 1:18 pm
Location: Zushi, Japan
Contact:

Re: Is there an easy way to do PWM yet?

Post by UltraBob » Wed Jul 30, 2014 12:51 am

Also, if this is the LED used on the board I have, as it appears to be, it looks like the red is a lower voltage than the other two colors that are just a smidge below 3.3V

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Is there an easy way to do PWM yet?

Post by dhylands » Wed Jul 30, 2014 1:45 am

UltraBob wrote:Thanks Dave,

That is really helpful. I have one of these.

It looks like it has resistors inline, do I still need to add my own resistors to the circuit?
It mentions that those 3 resistors are the current limiting resistors, so you shouldn't need to add any more. It also says that it's a 12V device (and this would be the voltage that the current limiting resistors would have been sized for). You could probably use lower voltages (and get dimmer output).

If we assume Vf of 2.1v for Red, and 3.2V for G & B, then we can calculate the currents (@12v).

For those resistors, 101 = 100 ohms, 470 = 47 ohms (the last digit is a power so for 101 you get 10 x 10**1 = 10 x 10 = 100, and for 470 you get 47 x 10**0 = 47 x 1 = 47).

V = IR, so I = V/R.
For Red, V = 12 - 2.1 = 9.9v so I = 9.9 / 100 = 0.099 or about 100 mA.
For Green and Blue, V = 12 - 3.2 = 8.8, so I = 8.8/47 = 187 mA

I'm going to guess that the resistors were actually sized for 5v, so redoing the calcs:
Red: V = 5 - 2.1 = 2.9, so I = 2.9/100 = 0.029 or 29 mA
G/B: V = 5 - 3.2 = 1.8 so I = 1.8/47 = 0.038 or 38 mA

20 mA is pretty typical for LEDs (going a bit higher is ok. Going lots higher requires using PWM - your IR remote for your TV probably drives those LEDs around 1A, but they're getting a pulsed signal, not a steady on.

Finally, if we consider 3.3v output (like you'd get from directly connecting to the micropythin board, R works out to 12mA, and GB work out to 2 mA (which is probably why you're not seeing anything).

Of course you'll get different results if we picked the low end of the Vf range too. In my experience, Blue LEDs can have even higher Vf (like around 3.7v) which means that they may not even turn on if only supplied with 3.3v.

The point behind doing all of these calculations will become important when you want to size your MOSFETs. You can get really tiny surface mount MOSFETs that will deal with a couple hundred milliamps. You can also use a transistor (like the venerable 2n2222) instead of a MOSFET.

You should be able to connect your Blue LED upto the 5v on the USB connector to verify that the LED is actually working. On my board VIN was 4.77v.

Post Reply