• Hi Robin,

    Thank you very for replying and helping.

    I set them to setInterval and that error does not occur anymore.

    I believe I am using the hardware SPI and this is my SPI set up

    function SPI_setup()
    {
      SPI1.setup
      ({sck:A5,
         miso:A6,
         mosi:A7,
         baud: 10000000,
         mode: 0,
         order:'msb',
         bits:8
        });
    }
    

    The read time is to read the timestampes from the IMU, which is part of the data collection from the IMU.
    the readtime Code looks like this:

    function readtime(ss)
    {
            hi = SPI_read(FIFO_DATA_OUT_L,ss);
            hi2 = SPI_read(FIFO_DATA_OUT_H,ss);
            non = SPI_read(FIFO_DATA_OUT_L,ss);
            lo = SPI_read(FIFO_DATA_OUT_H,ss);
            step = SPI_read(FIFO_DATA_OUT_L,ss);
            step = SPI_read(FIFO_DATA_OUT_H,ss);
            hi2 = hi2 << 16;
            hi = hi << 8;
            Value = hi2 | hi | lo;
            return Value;
    }
    

    I checked the time needed to collect one set of data is fixed at .029ms, IMU generate each set of data at 833Hz = 1/833 ~=0.0012, the time for the IMU to generate one set the data is a lot faster than the program excution. I think the problem is when the FIFO is full, the pattern will be messed up.

    I am not very sure why PICO takes so long to read a set of data. I tried to look up the default system clock rate and it seems 84MHz already based on this E.setClock(Correct me if I am wrong), is there a way to improve the program execution/reading speed?

    Changed version code

    function extraction()
    {
              st = getTime();
              s2 = SPI_read(FIFO_STATUS2,ss);
              if(((s2)&0b00010000) != 0b00010000)
              {
                 console.log( omx = read_FIFO(FIFO_DATA_OUT_H,FIFO_DATA_OUT_­L,ss),
                  omy = read_FIFO(FIFO_DATA_OUT_H,FIFO_DATA_OUT_­L,ss),
                  omz = read_FIFO(FIFO_DATA_OUT_H,FIFO_DATA_OUT_­L,ss),
                  ax  = read_FIFO(FIFO_DATA_OUT_H,FIFO_DATA_OUT_­L,ss),
                  ay  = read_FIFO(FIFO_DATA_OUT_H,FIFO_DATA_OUT_­L,ss),
                  az  = read_FIFO(FIFO_DATA_OUT_H,FIFO_DATA_OUT_­L,ss),
                  temp = read_FIFO(TEMP_OUT_H, TEMP_OUT_L, ss),
                  tm = readtime(ss), getTime()-st);
              }
    }
    
    setInterval(extraction,0.00000000001);
    

    Output:

    ///////////////The last number is the excution time//////////////
    8273 -829 -15075 -77 -53 4231 -562 7840166 0.02954864501
    6509 -2139 -9095 -88 -57 4253 -513 7840215 0.02941513061
    5273 -2745 -8939 -86 -61 4244 -548 7840264 0.02940368652
    4831 -2701 -8543 -84 -57 4250 -548 7840312 0.02936649322
    4447 -2693 -8315 -89 -64 4251 -553 7840361 0.02934265136
    4105 -2713 -7793 -85 -55 4250 -527 7840409 0.02941608428
    3779 -2715 -6983 -86 -63 4240 -541 7840458 0.02939796447
    3465 -2695 -5959 -90 -56 4245 -542 7840506 0.02937698364
    ////////////Data start to have wrong pattern//////////////
    ////////////Data start to have wrong pattern//////////////
    3191 -2637 343 -267 -337 -45 -548 16699391 0.02938270568
    -21 21 53 -9 255 43 -548 5888 0.02933788299
    29 21 3 17 5 17 -541 4864 0.02938842773
    -249 9 15 255 5 15 -535 4352 0.02937221527
    

    Spi:

    function SPI_write(addr,data,ss)
    {
      SPI1.send([WRITE|addr,data],ss);       //write to address
    }
    
    
    function SPI_read(addr,ss)
    {
      result=SPI1.send([addr|READ,0x00],ss)[1]­;
      return result;
    }
    
  • I don't know the maximum speed of the Pico, but UART may be a bottleneck.

    I haven't used that IMU, but looks like you can read multiple bytes in a single operation. That definitely will be faster.

    The number of characters you execute has a direct effect on execution speed. For example

    return SPI1.send([addr|READ,0x00],ss)[1];
    

    is almost surely faster than

      result=SPI1.send([addr|READ,0x00],ss)[1]­;
      return result;
    

    Related to that, read_FIFO(FIFO_DATA_OUT_H,FIFO_DATA_OUT_­L,ss) is "terribly long" , but you can try minification and pretokenisation, as those speed up execution, and most likely you won't have to manually shorten function and variable names.

  • Mon 2019.11.04

    Thank you for posting the upgraded snippets @user101931

    Big DISCLAIMER here - I didn't research the parts here, nor even what the SPI traffic is doing. One line stuck out so just provided a quick untested response


    'I believe I am using the hardware SPI '

    Yes. Based on the setup function snippet, as there isn't an assignment to a var used to declare the software SPI pinout such as

    var spi = new SPI();
    spi.setup({mosi:B5, miso:B4, sck:B3});
    spi.write([1,2,3,4])
    

    and the use of Espruino defined SPI1 SPI2 SPI3 hardware constants.



    The following reference from image 3 from #14

    I like the new extraction() function.

    I do see a possible area of contention. L18 has an argument (the value of the interval parameter) for setInterval() that is waaaaaay out of range. I did some quick look up, but can't locate the range of the low end, although the Espruino docs from #13 link do indicate the upper end. As the value needs to specify msec, experience tells me that approaching a value of 20 may start to show signs of struggle. Normal ranges, 30sec down to 20msec, would equate to a value in the 30000 - 20 range.



    My S.W.A.G. guess is that the decimal value is getting rounded to an integer, and that is still too small a value in an attempt to fetch the SPI payload. Shouldn't this be more like a sampling request every second or so, and the SPI traffic from the device would then be able to respond timely? This is akin to having an attempt to fetch that is 100-1000 times faster than the data that actually is attempted to be fetched. The requests are queueing up and eventually running out of room/time to perform the actual task. As I said, just a quick S.W.A.GG'd response. That would explain why a few accurate lines of data do in fact get through, then the whole works gets bogged down. (I'll have more time to dig deeper this weekend)


    for @AkosLukacs

    'is almost surely faster than'

      result=SPI1.send([addr|READ,0x00],ss)[1]­;
      return result;
    

    One reason might have been to enable the debugger to return a value for human viewing, before actually returning that value. I fall victim to that requirement and sometimes overlook and catch during code cleanup. Point well taken though.

  • Tue 2019.11.05

    @user101931

    'I am not very sure why PICO takes so long to read a set of data'

    To help us better visualize the actual duration, modify the extraction() function by commenting out the other lines, such that only one line is executed and lets time that to see what the actual duration is. Something like:

        var t = getTime();
        var elapsed = 0;
        console.log( "start of SPI call " + (getTime()-t) + " " + t );
    
    
    // The call to the extraction() function here
    extraction();
    // With only this line uncommented for timing
    omz = read_FIFO(FIFO_DATA_OUT_H,FIFO_DATA_OUT_­L,ss);
    
    
        elapsed = getTime()-t;
        console.log( "elapsed " + elapsed );
    



    It would be nice if a table of duration times could be generated for each of the vars there. This would give us an idea of where the bottleneck might be.



    Posting the code for function read_FIFO() might assist here, and it may be timing for the guts of that function might be needed also, if the duration test(s) above are much greater than several msec.

    To show the delay using the embedded console.log() statement is taking, place a single console.log() statement beside the var being tested and run two tests, the other commenting out the log() statement. It is likely that continuous writing to the Left-Hand console side is bogging down the works. Your test will help us identify.

About

Avatar for user101931 @user101931 started