Arduino and PWM Board Not Interacting Properly

Problem: After reuploading the Arduino code, the Tlc5940 PWM board was no longer giving a true ‘off’ signal. Even using a simple test code that Brandon gave me, where it would send a signal to turn on an LED on vial 3 for 1 second, and then turn it off for 1 second, the LED would only go to about half brightness rather than turning fully off.

Test Code:

#include <Tlc5940.h>

void setup()
  Tlc.init(RIGHT_PWM,4095); // initialise TLC5940 and set all channels off
void loop()

  Tlc.set(RIGHT_PWM,3, 0);

  Tlc.set(RIGHT_PWM,3, 4095);

Solution: There was a problem with the interaction between my version of the SAMD21 libraries.

My original versions:
> Arduino SAMD Boards (32-bits ARM Cortex-M0+) = 1.8.1 (latest version)
> Sparkfun SAMD Boards Library = 1.7.5
> Arduino IDE = 1.8.13

Brandon was Using:
> Arduino SAMD Boards (32-bits ARM Cortex-M0+) = 1.6.17
> Sparkfun SAMD Boards Library = 1.4.0
> Arduino IDE = 1.8.12

After switching to Brandon’s versions for all of these everything worked!

1 Like

OK scratch that, it only worked because we had switched our PWM to the left instead of right slot controlled by the Arduino.

Apparently there is a bug in the Tlc5940 code where you can only use the LEFT slot for the PWM board. I found these things in the code (found in \evolver-arduino\libraries\Tlc5490_SAMD)

I found this code in the tlc5940.h file:

//PWM Board position defines

#define left_PWM 1

#define right_PWM 2

But these variables don’t seem to be called anywhere else in that file. I’m probably missing how that’s output into another file though.

Later in that same file:

PORT_PMUX_PMUXE_E; REG_TCC1_CC1 = 1; while (TCC1->SYNCBUSY.bit.CC1)  //These are a problem

There’s an annotation saying These are a problem. This is only true for the right PWM, the left one works fine.

Also, from tlc5940.cpp:

/* PWM positions:

   1 -> PWM in left slot

   2 -> PWM in right slot

   3 -> PWM in both slots


void Tlc5940::init(uint8_t pwm_val, uint16_t initialValue)


  // set global PWM position values

  pos_1 = pwm_val & 0x1;

pos_2 = pwm_val & 0x2;

There isn’t a value set anywhere for both PWM = 3, leading me to believe that having two PWMs plugged in at one time was never implemented.

Our solution is to only use the left arduino controlled slot for the PWM, which works fine for our purposes. The right one can be the ADC board.

I don’t think this is entirely true - the fluidics module has exclusively PWM boards plugged in, and only uses LEFT_PWM in the arduino code. I haven’t gotten the chance to deep dive into the TLC lib code but hopefully I can help in a few weeks. All of the PWM chips are daisy chained together and connected to the same control lines on the arduino, so the individual PWM channels are accessed through increasing the address index.

1 Like

Ok yes, this makes sense. The PWMs on the normal motherboard are not daisy chained, so there could be a problem here. It’s likely a really simple fix by just updating some of the registers. I won’t have time to look into this for a few days at least, but if you wanted to look at the datasheet and try to figure it out the problem is likely exactly where you identified.

1 Like

I was also facing this problem of not getting a true OFF signal from the PWM board on the RIGHT slot. But after changing the arduino it worked and I could get the full range of LED intensities from complete OFF to fully ON. Apparently these samd21 mini arduinos are not as robust as normal uno ones and by tweaking it a lot I think I messed it up a bit. Other than that, I do see an issue…the full range of LED intensities are not mapped fully to 4095 PWM values. For example, the LED is totally OFF at mid value ~2050 and fully ON at 4095 so basically the resolution is halved. This seems to me like a register setting issue on the PWM chip or I might be missing something here.

Hi @skumar,

This actually makes sense - LEDs are not linear devices, there is a threshold that must be crossed before they will conduct and see light, and current is exponentially dependent on voltage. So if the average voltage is below this threshold, you probably won’t see anything. The 0 - 4095 range covers the entire PWM range of the TLC devices (think totally OFF or totally ON), it’s not tuned particularly for LED PWM requirements, as this is just a generic chip. Also, depending on the LEDs used, the minimum PWM required would probably vary, so it’s up to the user to figure out the tuning.


1 Like

Issue is opened here.

1 Like

The issue of controlling two PWM boards with the same arduino is resolved here with updated Tlc5940 library: updated-evolver-arduino

To use two (left and right slot) PWM boards, one has to initialize Tlc as (initial value in [0,4095]):
Tlc.init(LEFT_PWM | RIGHT_PWM, initialValue)



Thanks so much Sant! Can you make a pull request to the RC/hotfix branch of the main repo? I plan to do a release this week.

Ok, I just made a PR to the rc branch!