Arduino DUE + NeoPixel library + Servo Library....software issue

Hallo Everyone,
I ask you again your help to solve an issue of my project.
For space reasons, I am using a 108 LEDs matrix (WS2812b) as indicator of the temperature and current of 6 fuel cells. Those fuel cells provide the power to run a servo-motor of 750 KVA. For me is critical to have an actual reference of current and temperature value to keep my fuel cells (extremely expensive) safe.
My problem comes when I tried to put everthing together. I can drive my motor using the servo library of the arduino and I can drive the LEDs using the NeoPixel library but they don't work together. As soon as I need to refresh the LEDs display, I lost the motor PWM Signal.
After some time I found this paragraph inside the NeoPixel library:

void Adafruit_NeoPixel::show(void) {

  if(!pixels) return;

  while((micros() - endTime) < 50L);
  // endTime is a private member (rather than global var) so that mutliple
  // instances on different pins can be quickly issued in succession (each
  // instance doesn't delay the next).

  // In order to make this code runtime-configurable to work with any pin,
  // SBI/CBI instructions are eschewed in favor of full PORT writes via the
  // OUT or ST instructions. It relies on two facts: that peripheral
  // functions (such as PWM) take precedence on output pins, so our PORT-
  // wide writes won't interfere, and that interrupts are globally disabled
  // while data is being issued to the LEDs, so no other code will be
  // accessing the PORT.  The code takes an initial 'snapshot' of the PORT
  // state, computes 'pin high' and 'pin low' values, and writes these back
  // to the PORT register as needed.

  noInterrupts(); // Need 100% focus on instruction timing

Since I have the Motor pin and the LEDs pin on the same port of the Arduino (See attachments), I changed the NeoPixel library trying to get a solution for my problem but I couldn't make it.

Until now my system runs without LEDs but is because I disabled the following lines:

  for ( int i = 0; i < 6; i++)
  {  
    if (currArray[i] != oldcurrArray[i])// || (tempArray[i] != oldtempArray[i]))
    {
// Only refresh if some value has changed.
//      RefreshLEDs();
//      leds.show();
      break;
    }
  }

My question is: What should I modify into the NeoPixel library to control my motor while at the same time I am refreshing my LEDs? That means what should I modify at the "show" function? or should I change my approach and look for another library? If that is the case, which one do you recommend me?

I attached you two files to check my hardware. But as I told you they work separately just fine. I also attached my software if you want to take a look, but I warn you it is huge.

Thanks for your help.

H2PU_mainV8.ino (47.5 KB)

I am not sure you can do anything to make them both work at the same time. The neopixels library needs the interrupts off and the servo library needs them on.

If it were me I would control the servo with an external chip.

Hello Mike (and everyone):
Do you think I could use another library? Obviously I can change the hardware or add some new components, but I would like to solve my problem with just a new software. My hardware is more or less fixed and my main PCB is not flexible so I want to avoid all this work and try a software solution. Perhaps with a different library for the servo (though I think this is not feasible)? or another led library?
I found this one

Thanks in advance for your help and attention.

but I would like to solve my problem with just a new software.

No you can't do that the two things are fundamentally incompatible.
The servo needs a regularly controlled pulse, so an interrupt makes sure this happens. The timing requirements on the neopixels means the software can not be interrupted otherwise the timing falls in pieces.

My hardware is more or less fixed

Any given hardware design does not have the god given right to work.

A clocked LED chipset like an APA102 or a LPD8806 would solve the problem, because for them you don't need to disable interrupts while writing LED data.

Yes that would work.

OK, I got it. I need a hardware redesign. Either ARDUINO MEGA + TiCoServo Library or change the LEDs or create an external circuit to generate an independent PWM servo drive signal.
Thanks to all of you for you help.

BTW. this topic is also answered here at the Adafruit Neopixel description :slight_smile:

If a hardware redesign is considered I suggest an easy solution: get an extra microcontroller only for the 2812s and just send data from your main controller to the extra controller which drives the leds.