Nicla Vision PWM Output plus UART

Based on the Nicla Vision User Manual on the Arduino website, PA09 and PE11 both use Timer 1 Channel 2, and PA10 and PE12 both use Timer 1 Channel 3. Is there any issue using UART on PA09 and PA10 and using PE11 and PE12 for PWM outputs? If I set the frequency for a timer object in Python (say for Timer 1), does that actually change the hardware timer frequency, or does the software object just tick at that frequency based on the frequency of the hardware timer?

Thanks!!

Hi, the pins are multiplexed. So, as long as you don’t try to use the same feature in two places you are fine.

If I set the frequency for a timer object in Python (say for Timer 1), does that actually change the hardware timer frequency, or does the software object just tick at that frequency based on the frequency of the hardware timer?

This depends on which interface you use. You can use the pyb module. However, it’s not actively maintained. It’s recommended you use the machine module.

class PWM – pulse width modulation — MicroPython 1.23 documentation (openmv.io)

If you use the pyb module you’ll have to directly interface with timers and set the PWM output: class Timer – control internal timers — MicroPython 1.23 documentation (openmv.io)

Thank you for the quick response! I did have some trouble previously but I think I was using the pyb module which would explain why. I will try again with the machine library.

When I try to run the “from machine import PWM” code I get an error “ImportError: can’t import name PWM”, and based on some Google Searching it looks like that isn’t supported for STM32 boards; at least not the Nicla Vision. I can still get 4 pins working over PWM using the pyb library, but it’s not ideal. I was going to use PE11+PE12+PE13+PE14, but PE12 & PE13 are both on Timer1 Channel 2. I can use PB8/9 which are on Timer 4 Channel 3/4, but that means I can’t use UART4 on those pins.

You should be able to use PE13, PE14, and PE11 on Timer1 without issue. The 4th PWM output is the tricky one to find. TIM1_CH3N isn’t a fully different channel than CH3.

Ideally I would like to use the 3N channel the same way as channel 3, but I cannot find a ton of information on it or how it is different.

I can use pins PB8/PB9, but then I cannot use them for UART or I2C which I would like to do. Would it be possible to use the HRTIM on PG12 or just use a virtual timer for PWM on pins PE11/12/13/14? As long as I can control the pulse-width I don’t really care about frequency/period all that much.

Either that, or would it be possible to use PWM on PB8/PB9 and use the ESLOV connector for I2C?

Hi, MicroPython supports SoftI2C (master) and SoftSPI (master) on any pin. So, as long as you have 2 extra pins you can be an I2C master via the machine module.

The 3N channel is the same as the N channel but inverted. The timer can be setup to apply a dead-band between the non-inverted and inverted channels. This feature is there to drive power MOSFETs (P/N). Otherwise, it’s not useful as the regular and N channels are combined.

I’ve been experimenting with both I2C (pins PB8 & PB9) and SoftI2C (pins PE12 & PE13), and while I can successfully scan my I2C devices on the regular I2C I cannot see anything with the SoftI2C. Unfortunately I need PB8 & PB9 to drive some PWM motors because of which timers are allocated to which pins. Is it possible to use the High Resolution Timer HRTIM_EEV5 or Low Power Timer LPTIM1_IN1 on pin PG12? That would free up the “hard” I2C and give me just the right number of pins without having to use an external API→PWM driver. Beyond that are there any suggestions on making the SoftI2C more reliable? I tried a number of combinations between pullup/down resistors, frequencies, etc. to no avail.

Alternatively would it be reasonable to attach a 50mil header to PB3 on the underside and use Timer2_Channel2?

Hi, there should be no reason why SoftI2C doesn’t work… that controls the I/O pins directly via the processor: micropython/extmod/machine_i2c.c at master · micropython/micropython

Do you have a logic analyzer like this: Saleae Logic Analyzers

While expensive, it’s pretty essential to buy one of these if you want to do custom embedded system stuff with I2C/SPI/etc. It’s super hard to debug what the issue is otherwise. With it you can just see what’s happening on the I2C bus which will help isolate the issue quickly.

There are less expensive logic analyzers too. But, I can’t comment on how well they work.

Is it possible to use the High Resolution Timer HRTIM_EEV5 or Low Power Timer LPTIM1_IN1 on pin PG12?

Yes, but, you need to modify the code in C and debug how to get that working.

Alternatively would it be reasonable to attach a 50mil header to PB3 on the underside and use Timer2_Channel2?

This may be easier for you since it just requires soldering super small pins between the larger pads.

I do have a logic analyzer. It’s a cheap one from Amazon, but it seems to do the trick. When I look at the pins when using PE12+PE13 it seems to me that the pins have a hard time being pulled low. When I run a scan with PB8+PB9 I get a single consistent [correct] address, but when I run with the others I get a list of address that are not real. I’m using the MMC5603 magnetometer breakout from Adafruit & it has 10k pullups on both SCL and SDA.

##################################################
import time
from machine import SoftI2C

i2c = SoftI2C(scl = ‘PB8’, sda = ‘PB9’, freq=250000)
#i2c = SoftI2C(scl = ‘PE12’, sda = ‘PE13’, freq=250000)

i = 0
print(’ ‘)
while True:
print(’{:03d}'.format(i), i2c.scan())
time.sleep(0.2)
##################################################
004 [35, 52, 54, 59, 64, 90, 116]
005 [21, 42, 48, 59, 65, 99, 101, 103, 105]
006 [23, 25, 29, 31, 53, 59, 61, 64, 70, 104, 110, 114, 116]
007 [27, 31, 43, 46, 61, 88, 113]
008 [28, 39, 43, 46, 92, 105, 110]
009 [27, 37, 39, 41, 62, 66, 93, 100, 104, 107]
010 [43, 53, 71, 73, 77, 79, 88, 114]
011 [31, 41, 58, 60, 72, 82, 85, 102, 119]
012 [31, 49, 53, 60, 67, 95, 110, 116]
013 [25, 30, 32, 37, 39, 51, 63, 65, 104, 106, 112, 114]
014 [31, 39, 41, 43, 65, 69, 119]
015 [65, 81, 85, 87, 88, 100]
016 [23, 30, 32, 36, 64, 82, 88, 90, 96, 98, 112]
017 [52, 55, 57, 64, 73, 81, 83, 107, 109, 111]
018 [19, 22, 34, 36, 40, 48, 50, 55, 61, 67, 70, 72, 78, 86, 102, 106, 112]
##################################################


P.S. I really appreciate the help. :slight_smile:

PB8 and PB9 have a very nice level shifter on them to talk to the outside world.

However… PE12+PE13 have a level shifter… but, it’s not meant for open-drain: TXB0108 8-Bit Bidirectional Voltage-Level Translator with Auto-Direction Sensing and ±15-kV ESD Protection datasheet (Rev. H)

Even though it’s bidirectional it is push/pull only which is not supported for I2C. Sorry I didn’t catch this before. The part choice here blocks I2C on all pins except PB8/PB9.

So, what you want to do will not work. You’re going to have to take the alternative approach you mentioned above.

I went ahead and purchased an SPI → PWM(x12) breakout board that I will use on on PE11-14. As long as this TXB0108 level shifter doesn’t get in the way of SPI I should be just fine.

Thank you for all of the help!

Yes, it should be fine for SPI.