I need 6 distinct PWM outputs, multiple simultaneously. I’m able to use pins 0-3 just fine, however when also using any pin 4-10 the board becomes unresponsive and I need to get it into bootloader mode for recovery. The board is connected via USB and has nothing connected to its pins.
I realised that pins 4-5, 6-7 and 8-10 are used for I2C, UART and SPI respectively and thought that writing to them might mess up some internal communication. But when just using one of these pins without also using pins 0-3, everything is fine.
Here’s a small example sketch for reproducing the issue:
const int TEST_PIN = 10; // MOSI for SPI
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(TEST_PIN, OUTPUT);
}
void loop() {
byte value = millis() % 255;
digitalWrite(LED_BUILTIN, value < 128 ? HIGH : LOW);
analogWrite(0, value);
analogWrite(1, value);
analogWrite(2, value);
analogWrite(3, value);
//analogWrite(TEST_PIN, value); // this will make the board unresponsive
}
Commenting in the last analog write will cause the issue. I don’t understand what’s going on here, any clarification would be appreciated.
Hi,
Correct me If I am wrong, but I think analogWrite in Arduino means a PWM output on digital pins and potentially an analog output on DAC pins. So issue can be with timers or PWM generators so this can be a bug. Check if all pins of your XIAO can generate PWM.
It has nothing to do with analog pins at all until you try to analogRead them.
And it’s working fine as long as the pins are used individually. But that’s not enough for my use case.
Besides an explanation for why that’s the case, I’d also appreciate any workaround ideas that allow me to output more PWM signals than I have usable pins (I don’t have much experience with electronics hardware).
I already considered using an 8 channel analog multiplexer, however that seems to only allow me to control one output at a time. I then checked if I could make use of an 8 bit shift register which allows simultaneous outputs, but these seem to not work well with PWM signals. Is there some other integrated circuit that works like a mix between these two?
I consulted the Nordic webpage. The issue is the nRF52840 has only 4 hardware PWM generators. Maybe someone did not implement error handling correctly, so if you try to use more, the program crashes. You can try to find software-generated PWM or explore PWM generation using timers. It will not be as precise as PWM generators.
If you will not drive a larger load with the PWM signal, the manufacturer is not so important, the IC is. So you can find a PCA9685 breakout board that suits your needs. This is not the only solution you can use, there are more solutions around to generate PWM. You can try to google them.
Shouldn’t be a problem if nothing is connected to the pins I guess?
Thanks for investigating, that checks out! I modified my example sketch to verify if I can use pins 4-10 as long as I don’t use more than 4 pins in total - and I can!
Unfortunately I don’t understand what that means, could you elaborate? I tried running your example but only got an error from TinyUSB telling me that the board (Seeed XIAO BLE Sense - nRF52840) is not supported.
Thanks for pointing me to this. As @electry suggested, I opted for an IC not manufactured by Adafruit, as I can get 5 for the same price on AliExpress.
I appreciate the input from everyone! To sum up:
It seems to not be possible to output more than 4 PWM signals due to hardware limitations. To work around that, either generate the PWM signal using software or use an external IC like the PCA9685.
Unfortunately I don’t understand what that means, could you elaborate?
XIAO_nRF52840 has two different BSP(Board Service Package)…
If you search for “nRF52” in the ArduinoIDE Board Manager, you will find “Seeed nRF52 Boards (non-mbed)” and “Seeed nRF52 mbed-enabled Boards (mbed)”.
The “Seeed nRF52 Boards (non-mbed)” will run 16 PWMs. On my desk XIAO is running 8 PWMs with 2 modules (4 channels/module).
which could be resolved by manually granting the permission using chmod.
And then I finally ended up with this issue, which I wasn’t motivated enough to resolve yet:
Man, why is the Arduino related tooling always such a pain to work with. Glad that I’m used to quirky issues from developing Android apps since a decade
I compiled it with ArduinoIDE 2.3.2 on Linux and it uploaded without any problems. The only thing is that I did the following operation when I installed IDE2.3.2.
Traceback (most recent call last):
File "__main__.py", line 317, in <module>
File "click/core.py", line 1134, in __call__
File "click/core.py", line 1040, in main
File "click/_unicodefun.py", line 100, in _verify_python_env
RuntimeError: Click will abort further execution because Python was configured to use ASCII as encoding for the environment. Consult https://click.palletsprojects.com/unicode-support/ for mitigation steps.
This system lists some UTF-8 supporting locales that you can pick from. The following suitable locales were discovered: af_ZA.UTF-8, am_ET.UTF-8, be_BY.UTF-8, bg_BG.UTF-8, ca_ES.UTF-8, cs_CZ.UTF-8, da_DK.UTF-8, de_AT.UTF-8, de_CH.UTF-8, de_DE.UTF-8, el_GR.UTF-8, en_AU.UTF-8, en_CA.UTF-8, en_GB.UTF-8, en_IE.UTF-8, en_NZ.UTF-8, en_US.UTF-8, es_ES.UTF-8, et_EE.UTF-8, eu_ES.UTF-8, fi_FI.UTF-8, fr_BE.UTF-8, fr_CA.UTF-8, fr_CH.UTF-8, fr_FR.UTF-8, he_IL.UTF-8, hr_HR.UTF-8, hu_HU.UTF-8, hy_AM.UTF-8, is_IS.UTF-8, it_CH.UTF-8, it_IT.UTF-8, ja_JP.UTF-8, kk_KZ.UTF-8, ko_KR.UTF-8, lt_LT.UTF-8, nl_BE.UTF-8, nl_NL.UTF-8, no_NO.UTF-8, pl_PL.UTF-8, pt_BR.UTF-8, pt_PT.UTF-8, ro_RO.UTF-8, ru_RU.UTF-8, sk_SK.UTF-8, sl_SI.UTF-8, sr_YU.UTF-8, sv_SE.UTF-8, tr_TR.UTF-8, uk_UA.UTF-8, zh_CN.UTF-8, zh_HK.UTF-8, zh_TW.UTF-8
[38295] Failed to execute script __main__
exit status 1
Compilation error: exit status 1
It’s an open issue in the Arduino IDE issue tracker since 2022:
Setting values for LC_ALL and LANG (as suggested by the page linked in the error message) did nothing. Downgrading the Arduino IDE seems to work, but the less drastic fix turned out to be replacing the adafruit-nrfutil executable that is shipped by Seeed nRF52 Boards with the one that comes with Seeed nRF52 mbed-enabled Boards. In my case, these were located here:
I initially tried overwriting it with the version you get from pip install --user adafruit-nrfutil as suggested by @msfujino and also with the versions from the official GitHub releases, but none of these worked for me. Luckily the version that ships with mbed 2.9.2 did the trick.