Logically invert the pin?

Posted on
of 3
First Prev
/ 3
  • ...just add one more neopixel in front of the chain and enclose it... sometimes 'the solution' is not really a solution but resolves the issue (@Robin: ...even thoug I looked at the fix in Makuna's code...).

  • Sun 2018.11.18

    Was going to suggest that, trying to avoid more tedious soldering, but remember, then it's 'option base one' for the remaining viewable Neo's

    Also, . . . . One could run a long data wire from the last of those beneath each Nixie to where B6 was to control the in-between Neo's

    See note #27 where software SPI may not work

    'those based on nRF52 chips can have SPI on any pins'

  • The LEDs are fine. I connected data line to Arduino and launched Adafruit's Neopixel demo sketch. Everything works beautifully.

    I don't think SPI is the only way to run Neopixels with STM32. Basically, SPI is sending 4x more data at 4x more speed to mimic the LED's protocol. Does Espruino allow controlling a pin with a CPU directly with tiny timings, like: "set HIGH to the pin, wait for 450 nanoseconds, set LOW etc.." or it is a too low-level task?

  • Sun 2018.11.18

    'I don't think SPI is the only way to run Neopixels'

    May I ask what the thought is, not using SPI? Are we still attempting to solve the why is the first Neo green here?

    ' or it is a too low-level task?'

    @George, honestly I'm not sure. I thought I read a post on how to do just that many months ago, but I've not been able to re-locate it. Was hoping to read over and provide some insight.

    Have confirmed that function digitalPulse(pin, value, time) is for millisecond pulses though.

    I'm wondering if 'inlineC' could be used for the speed part, but I'm not familiar enough with the 'C' libs at GitHub. This might be a place to poke around and parent folders, while waiting for a reply.


    'at 4x more speed'

    Guessing here, would changing some of the SPI setup params solve the speed issue perhaps?


  • I mentioned right at the start of this thread that there was a software solution, but it's hard-coded to a certain clock speed on an F405, which won't be yours. You could possibly recompile and change things if needed.

  • May I ask what the thought is, not using SPI? Are we still attempting to solve why is the first Neo green here?

    Yes, I am trying to solve this issue and another one at the same time: the second line of Neopixels is connected to a pin with no hardware SPI on it. Running a data line from the end of one line of LEDs to the beginning of another one feels terrible. This is why I am trying to workaround hardware SPI usage.

    What we've got now: The LEDs are not damaged, even the first one (which is always green when controlled by Espruino). When I poke a wire from Arduino to Neopixel's data line everything works perfectly. But Arduino is 5v.

    @Gordon, could you please tell me where can I find the code for the F405? I couldn't find it in Espruino sources. Is it outside of Neopixel lib or even deprecated?

  • Sure, yes - it's here:

    So it's only compiled in for WIO_LTE at the moment. I guess a more thoughtful implementation could be included for all boards though (for instance it could benchmark itself to figure out how many iterations it has to idle for - in fact STM32's jshDelayMicroseconds already does that).

  • I guess you're stuck as you have already made your board, however you could use optoisolators.

    Because the optoisolator's input is basically a LED you could connect all the anodes to the SPI output, with all the cathodes to GPIOs. You could then control which optoisolator output was active by fiddling with the GPIOs.

  • @allObjects, I finally managed to solder a second transistor as you offered. It looks terrible, but it works! Now the signal is not inverted. I also recompiled Espruino so that STM32 uses hardcoded timers and changed the timers from

    \#define PATTERN_PULSE_T0H() for(uint32_t i = 0; i < 17; i++) {__NOP();}
    \#define PATTERN_PULSE_T0L() for(uint32_t i = 0; i < 33; i++) {__NOP();}
    \#define PATTERN_PULSE_T1H() for(uint32_t i = 0; i < 30; i++) {__NOP();}
    \#define PATTERN_PULSE_T1L() for(uint32_t i = 0; i < 20; i++) {__NOP();}


    \#define PATTERN_PULSE_T0H() for(uint32_t i = 0; i < 7; i++) {__NOP();}
    \#define PATTERN_PULSE_T0L() for(uint32_t i = 0; i < 14; i++) {__NOP();}
    \#define PATTERN_PULSE_T1H() for(uint32_t i = 0; i < 13; i++) {__NOP();}
    \#define PATTERN_PULSE_T1L() for(uint32_t i = 0; i < 8; i++) {__NOP();}

    But no matter what I send, the LED's are always white. My thought was if F405 is 168 MHz and F103 is 72 MHz I should just scale the delay values proportionally. @Gordon, what am I missing here?

  • @George, thanks for the feedback... and sorry that the cool design now as a bit a sore spot... on the other hand, it is a reminder of all the effort that went it to push it thru, no matter what!

  • I think you really need to stick an oscilloscope on it and check what's being output.

    I believe the F4 chips actually execute more instructions per cycle than F1s in some cases (Cortex M4 vs M3) so that could be knocking your timings out.

  • Unfortunately i don't have one...

    I also found stm32's jshDelayMicroseconds function you were talking about earlier

    void jshDelayMicroseconds(int microsec) {
        int iter = (int)(((long long)microsec * (long long)JSH_DELAY_MULTIPLIER) >> 10);
      //  iter -= JSH_DELAY_OVERHEAD;
      if (iter<0) iter=0;
      while (iter--) __NOP();

    I see the logic of this function like this:

    iter = microsec * (how_fast_mc_is / how_fast_it_should_be)

    But i don't understand how to make this function work with nanoseconds.

  • I'm afraid that without an oscilloscope or Logic Analyser you're going to find this pretty much impossible - you're just stabbing around in the dark. At £15 something like this would be well worth the investment: https://www.amazon.co.uk/Hobby-Component­s-24MHz-Analyser-1-1-16/dp/B00DAYAREW

    Just get it, connect it and send the Neopixel signals - then see how long the signals actually are compared to what you want and divide the numbers accordingly.

    To use jshDelayMicroseconds for smaller numbers you'd have to make your own function for sending that used JSH_DELAY_MULTIPLIER and precalculated the numbers to count from for PATTERN_PULSE_Txx - but again it's not guaranteed.

  • @George,

    I do not know if this

    But there is an issue with the first LED. Its green part always turns on no matter what color I set it to.

    is still an issue for you...

    Because I just fooled around with the Neopixel LEDs I got as part of the PICO Kickstarter reward... and guess what: using my Espruino-Wifi, the string of 8 neopixels I connected to B15 showed the same green sickness... No matter what color I give, the last pixel (sent) just gets screw(ch)ed over.

    First I thought it was some coding issue... but no... since I did not set any pinModes, I felt that the convenient - or glorious - automode could be the culprit: and it IS. Setting the pinMode() to output just fixed the issue (I did not look into the Neopixel write implementation... may be it can be fixed there for good... waiting a bit longer with going back to auto or what...).

    Only a while after I fixed the issue it came back to me that you had a similar issue... ;-)

    Anyway... I know that you use a different chip, but one never knows until tried. Give setMode(<pin>,"output") a shot.

  • Anyway... I know that you use a different chip, but one never knows until tried. Give setMode(,"output") a shot.

    Good point @allObjects, this is what fixed first Neopixel issues on my side and if not just send twice.

  • Almost year passed and I solved the issue today. Unfortunately I had to drop Espruino and stick to low level HAL STM32 library. The LED pin is controlled by timer's PWM and DMA. If you invert the timer polarity simply changing one register everything starts working. I want to say a HUGE thanks to everyone who helped me with this problem. You guys are awesome. OMG I can finally finish my clock now, I am so happy!

    I will post the clock here as soon as I finish them.

  • ...glad and sad... glad that you got your project completed - I know the feeling that can drown every compromise take on the way to now - and sad that you had to go to low level libs and fiddle there. May be this is an option to be considered in Espruino's firmware to be able to choose polarity for output in general / have it configurable... since this is a standard function on every current micro controller...

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Logically invert the pin?

Posted by Avatar for George @George