Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Nov 11 19:00
    jbreizh opened #306
  • Nov 07 23:36
    Makuna closed #305
  • Nov 07 23:35
    Makuna updated the wiki
  • Nov 07 23:31
    Makuna updated the wiki
  • Nov 07 23:16
    Makuna labeled #305
  • Nov 07 22:38
    jbreizh opened #305
  • Nov 02 19:11
    Makuna labeled #303
  • Nov 02 19:11
    Makuna assigned #303
  • Nov 02 19:04
    Makuna closed #304
  • Nov 02 19:02
    Makuna opened #304
  • Nov 02 15:14
    siedi opened #303
  • Oct 27 21:01
    perigalacticon opened #302
  • Oct 27 16:09
    Makuna updated the wiki
  • Oct 16 06:31
    Makuna closed #174
  • Oct 16 06:29
    Makuna closed #297
  • Oct 16 06:29
    Makuna unlabeled #297
  • Oct 16 06:18
    Makuna closed #301
  • Oct 16 06:18
    Makuna opened #301
  • Oct 10 00:08
    Makuna closed #300
  • Oct 10 00:08
    Makuna opened #300
sticilface
@sticilface
void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixels, uint8_t* end, uint8_t pin)
{
    const uint32_t pinRegister = _BV(pin);
    uint8_t mask;
    uint8_t subpix;
    uint32_t cyclesStart;
    // trigger emediately
    cyclesStart = _getCycleCount() - 800000;
    do
    {
     uint32_t savedPS = xt_rsil(15);  // disable interrupts and save state... 
        subpix = *pixels++;
        for (mask = 0x80; mask != 0; mask >>= 1)
        {
            // do the checks here while we are waiting on time to pass
            uint32_t cyclesBit = ((subpix & mask)) ? CYCLES_800_T1H : CYCLES_800_T0H;
            uint32_t cyclesNext = cyclesStart;
            uint32_t delta;

            // after we have done as much work as needed for this next bit
            // now wait for the HIGH
            do
            {
                // cache and use this count so we don't incur another 
                // instruction before we turn the bit high
                cyclesStart = _getCycleCount();
            } while ((cyclesStart - cyclesNext) < CYCLES_800);


            // set high
            GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinRegister);

            // wait for the LOW
            do
            {
                cyclesNext = _getCycleCount();
            } while ((cyclesNext - cyclesStart) < cyclesBit);

            // set low
            GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
        }

    xt_wsr_ps(savedPS); // restore the state

    } while (pixels < end);

    // while accurate, this isn't needed due to the delays at the 
    // top of Show() to enforce between update timing
    // while ((_getCycleCount() - cyclesStart) < CYCLES_800);
}

i tried to add something, to get the send function to bail out if an interrupt fired during sending! I tried this

 if (_getCycleCount() - Endcyclecount > 13) { break; }

with Endcyclecount being set at the end after interrupts have been re-enabled... but it was actually more glitchy.. this works though, only occasional flashes..

Michael Miller
@Makuna
@sticilface are you running at 40mhz or 80 mhz clock? Please try to double it with your change and try again. The issue is that the timing in the loop is pretty tight at the default speed, so the extra statements for rsil and wsr may cause an occasional glitch, but double speed would not. If it still glitches then the interrupt is taking more than 0.125us (the pixel error time per bit)
sticilface
@sticilface
i've always been running at 160mhz, 80mhz for flash... ever since we had the option!
sticilface
@sticilface
so with interrupts...the pixels are a total mess, completely unusable.. but if they are enabled and disabled per bit, then actually there is only the odd glitch... what i wanted was a way to find out if an interrupt has fired during the sending and then bail out on sending the rest, flag the strip as dirty so on the next show(), it tries again. it would probably not be noticed if the end pixels are not updated in one pass or the next. anyway....
bbx10
@bbx10
@sticilface I see glitches but no crashes after a few minutes. I was getting crashes but I forgot to remove the calls to noInterrupts()/interrupts(). Running with CPU clock 160 MHz and added xt_rsil and xt_wsr_ps as shown above. Reducing the ping frequency reduces the glitches. sudo ping -i 0.01 <ESP IP> results in 100 pings/sec which is probably closer to real life network activity.
Michael Miller
@Makuna
@sticilface I added methods to check the interrupt state register, ETS_INTR_PENDING() inside of ets.sys.h
sticilface
@sticilface
That might permit what I was trying to do. Cheers. Although I've no idea how to use it. Does it return 1 if there is the specific wifi interrupt pending? The one @bbx10 identified, 1 I think.
Michael Miller
@Makuna
It returns a unint32 that is a bit field for every interrupt, 0 bit is the first interrupt, 1 bit the next. I don't know the bit for the hidden problematic interrupt, but if you mask out the first two bits and then just check for non zero would be a start.
''' uint32_t intstate = ETS_INTR_PENDING ();
if (intstate & 0xfffffffc) break
Michael Miller
@Makuna
P.s. should be back from vacation by Monday, so I can be a little more involved again.
sticilface
@sticilface

I'll give that a go... I was also thinking of doing three things...
1) wrapping up each pixel so that you send the three bytes together... and having interrupts out side that. it might be better when combined with the break so that pixels stay in sync...
2) not sure about this one.. but adjusting the timing.. can we push it out faster and have a bigger inter pixel wait where interrupts can fire..
3) lodge a bug with expressive so they can undo whatever they have done!

enjoy ur holiday! i've got exams in 2 weeks so the procrastination should really stop!

sticilface
@sticilface
@Makuna You'll laugh.. i combined @bbx10 interrupt #define thingy...couldn't find your addition to gets.sys.h.. so it breaks if there is a pending interrupt.. but it only checks after it has sent out a whole pixel... and well... i have one pixel that lights up nicely... !! so it is breaking after every pixel!
bbx10
@bbx10
@sticliface I think bit 0 is the WiFi interrupt so I would try if (intstate & 0x1) break.
sticilface
@sticilface
Cheers I'll give that a go:)
sticilface
@sticilface
I might be on to something chaps.. I'm going to test it a bit more... so maybe later this weekend...
sticilface
@sticilface
@Makuna how do I call Dirty() from within the send function? Can't seem to do it. I want dirty if the strip did not complete due to pending wifi interrupt?
Michael Miller
@Makuna
Can't easily, as the method can't be a member due to the esp flash attrubute. Have it return a bool, and then have calling site use that to reset dirty if it completed.
sticilface
@sticilface
That is a good idea! Thanks!
sticilface
@sticilface

so i got that working, and it seems to work. the issue is that this interrupt seems to be present a lot, which makes pixels towards the end of a strip quite jittery... for 120LEDs. If you double the frequency of show() it seems to get round it. not the best method i'll admit and it will fail for progressively longer strips, but you can ping -f now and 1) there are no crashes. 2) even with a crazy number of pings, the lights go a bit jittery... but they do not flash! so they are usable..

I've added this function in esp8266.c

inline uint32_t _getItrrCount()
{
    uint32_t Icount;
    __asm__ __volatile__("esync; rsr %0,226; esync":"=a" (Icount));
    return Icount;
}

added this to the end of the bit send..

             if (_getItrrCount() & 0x1) return true;

and converted the send_pixels from void to bool.. then in the main file i added a check before reseting dirty..

    if (!SendFail) ResetDirty();
thanks @bbx10 for the interrupt mask.
This method will fail for progressively longer strips, though as you won't be able to push through another refresh fast enough, and the no interrupts will always have the wifi interrupt interrupting it.. this method keeps the standard nointurrupts() interrupts() from the original lib.
sticilface
@sticilface
it also does not work with serial streaming, i.e. ADAlight. I think the serial is setting of the interrupt so it never finishes...
sticilface
@sticilface

so i upgraded to staging, with SDK 1.3, replaced the nointurrupts with the savedPS, and it is looking pretty good. adding the bail out using _getItrrCount(), returning an error code from show(), and then using that to resend the pixels works really well, it works for my ADAlights too.. I thought i'd measure how often it was failing.. using 100 LEDs, it was failing 1-6 every 10 seconds or so, but not very much... use ping -f and you can see the effect on failed sends...

Send_Fail: count = 9, average/s = 0 
Send_Fail: count = 1, average/s = 0 
Send_Fail: count = 5, average/s = 0 
Send_Fail: count = 5, average/s = 0 
Send_Fail: count = 16, average/s = 1 
Send_Fail: count = 3, average/s = 0 
Send_Fail: count = 15666, average/s = 1566 
Send_Fail: count = 38463, average/s = 3846 
Send_Fail: count = 36641, average/s = 3664 
Send_Fail: count = 34176, average/s = 3417 
Send_Fail: count = 37629, average/s = 3762 
Send_Fail: count = 37509, average/s = 3750 
Send_Fail: count = 8399, average/s = 839 
Send_Fail: count = 5, average/s = 0 
Send_Fail: count = 4, average/s = 0

but the LEDs... worked smoothly, and the ESP did not crash at all, and actually with the new SDK it returned even better than the 1.2 SDK... with only 0.1% packet loss...

83903 packets transmitted, 83821 packets received, 0.1% packet loss
round-trip min/avg/max/stddev = 0.407/9.387/76.581/6.335 ms

put this up to 400 LEDs...

LmacRxBlk:1
Send_Fail: count = 201, average/s = 20 
LmacRxBlk:1
LmacRxBlk:1
LmacRxBlk:1
LmacRxBlk:1
LmacRxBlk:1
LmacRxBlk:1
LmacRxBlk:1
LmacRxBlk:1
LmacRxBlk:1
Send_Fail: count = 189, average/s = 18

and its about 18 fails per second! but they still work...

Shelby Merrick
@forkineye
i just got ws2811 working via UART. should be the end of interrupt issues!
hoping anyways. more testing to do, but looks good so far. implementing it now
sticilface
@sticilface
ooo.... now that is interesting.... it won't work for my adalight implementation though... unless u can do it by serial1?
Shelby Merrick
@forkineye
yeah, its on serial1. uses GPIO2
sticilface
@sticilface
good work!
Shelby Merrick
@forkineye
it uses the UART configured 6N1 and inverted at 3.2mbps. end up having to send 4 times the data to generate the waveform, but its only expanded when filling the FIFOs doesn't take a whole of memory
the stop and start bits become part of the 2811 signal
oh, and you want to do it at 160MHz, else it'll pause between frames sporadically for ~4us.
sticilface
@sticilface
I'm running at 160 anyways, can't see the point in 80mhz. batteries are dead anyway at that speed with the wifi demands!
sticilface
@sticilface
mine are actually all hooked up to GPIO 2 so i can do a field test. How easy would it be to encorporate into the neopixelbus lib?
Shelby Merrick
@forkineye
should be fairly easy to add it. i'm doing it from scratch as i don't need animations and stuff
i need to support other clockless pixels like GECE as well, so trying to make it my framework for that
i'm trying to keep the function calls similar though so it can be ported in easier
sticilface
@sticilface

@forkineye I've just tried out the microajax, and progmem methods you have for your web pages. I like it. Do you get a couple of second pause between each request when u load a page? for each of the page..1-2 sec.. microajax.js... 1-2 sec... style.css...1-2 sec...values...

occasionally i seem to get a crash as well... the stack dump pointed to 40101da4 <pvPortMalloc>:

i want to move my dynamic content over to ajax which is why I'm interested

Shelby Merrick
@forkineye
the web stuff needs some work. any other traffic causes serious lag in the interface. the biggest issue is multiple requests. i'm going to redo it in the future so it doesn't ahve to load the css each time
err. mean w/ each page
i just pushed changes to my ESPixelStick using the UART for driving ws2811. Will have it testing throughout the day. branch with the code is here - https://github.com/forkineye/ESPixelStick/tree/ws2811_uart
sticilface
@sticilface
Looks good. i will have a look at your UART stuff in due course..
bbx10
@bbx10
@forkineye Your UART code is extremely promising! I will give it try ASAP.
Shelby Merrick
@forkineye
@bbx10 it's been running for me the past couple of hours without any hiccups on 4 different modules. Only driving 40 pixels each though. Should be good for as many as you can throw at I'd think
my modules are actually outputting for 170 pixels each (1 full DMX universe), but only 40 pixels hooked up
bbx10
@bbx10
@forkineye I modified a program to use your UART driver ESPixelUART.cpp. The program drives an 8x8 array at 30 fps. No problem so far with crashes. 20 minutes of "sudo ping -A <IP addr>" does not crash it. Using git commit aafacdc (Aug 16) to build the program so this is very close to the latest. I should have another 8x8 next week so can try 128 LEDs at once.
Shelby Merrick
@forkineye
@bbx10 Sweet, thanks for testing it out!
sticilface
@sticilface
@forkineye it works... very well... good job.. took 5min to fit it into the neopixelbus lib!!
Shelby Merrick
@forkineye
@sticilface ah cool, great to hear! thanks!