3 Replies Latest reply on Apr 18, 2015 12:12 AM by LeonY

    Speed of GPIO using MRAA via Javascript GEN2 Galileo

    LeonY

      I am consistently hitting a brick wall with the GPIO on the Galileo Gen 2.

      I have created a version of shiftOut() in Javascript (here is the original Thread and my code)

      I managed to get a nice waveform out of Pin 2(the Clock pin in my example)

      gen28bit.jpg

      The above is nice, however its SLOW! I have to push out a large array of data (864 bytes) to drive a large LED array..and it takes 1 second to push out that many bits.

      I found out that you could enable mmap using something like

       

      var m = require('mraa');  
      console.log('MRAA Version: ' + m.getVersion());  
      var clockPin = new m.Gpio(2);  
      clockPin.useMmap(true);
      

       

      That gave me a much faster cycle, i didn't have time to run it through the oscilloscope. However ..

       

      No MMAP = 8 bits take 20ms

      Using MMAP = 8 bit stake 1-2ms

       

      Reading this thread I'm wondering if anyone knows of a way to insert inline assembler into Javsacript (if that's at all possible)?? Or is there some other way to increase the GPIO speed!

      I know its not a hardware limitation, because i have Arduino code that works perfectly on the same board.

      I'm also 100% sure the GPIO.write() is the culprit, if i leave the gpio.write() commands out, my programs executes with 0 delay.

        • 1. Re: Speed of GPIO using MRAA via Javascript GEN2 Galileo
          JPMontero_Intel

          Hi LeonY,

           

          Have you considered using the SPI pins, because you can set the SPI clock up to 25MHz? As far as I know there is no other function in the gpio library that allows to increase the performance of this signal further. Another option would be that you create a custom library to increase the speed of the clock. I hope this helps.

           

          Regards,
          JPMontero_Intel

          • 2. Re: Speed of GPIO using MRAA via Javascript GEN2 Galileo
            LeonY

            Hey Mate

            Thanks for SPI suggestion. I tried it out with mixed results:

            #include "SPI.h"
            const int nLEDs = 1*6*3;
            byte ledBar[nLEDs], maxValue=5;
            byte currCol[] = {0,0,0};
            short int innerCnt=0, rcnt=0, wsOut=0;
            short int globalDelay = 100;
            
            
            void setup()
            {
              SPI.begin();
              SPI.setBitOrder(MSBFIRST);
              SPI.setClockDivider(SPI_CLOCK_DIV64);  
              SPI.setDataMode(SPI_MODE1);
              clearSuit();
              delay(1000);
            }
            void loop()
            { 
                  //RED
                  for(rcnt=0; rcnt<maxValue; rcnt++)
                  {
                    for(innerCnt=0; innerCnt<nLEDs; innerCnt+=3)
                    {
                        ledBar[innerCnt]=rcnt;
                    }
                    loadWS2803SPI();
                    delay(globalDelay);
                  } 
                  for(rcnt=maxValue; rcnt>-1; rcnt--)
                  {
                    for(innerCnt=0; innerCnt<nLEDs; innerCnt+=3)
                    {
                        ledBar[innerCnt]=rcnt;
                    }
                    loadWS2803SPI();
                    delay(globalDelay);
                  }
            }
            
            
            void loadWS2803SPI()
            {
              SPI.transferBuffer(ledBar, NULL, nLEDs);
              delayMicroseconds(600);
            }
            
            
            void clearSuit()
            {
              for(wsOut = 0; wsOut < nLEDs; wsOut++)
              {
                ledBar[wsOut] = 0;
              }
              loadWS2803SPI();
            }
            

            above i used

             

            SPI.transferBuffer(ledBar, NULL, nLEDs);
            

             

            I got this out of an example on the forum. If i used SPI.transfer(BYTE) i would get gibberish! but the above worked in a limited capacity.

            I was able to get the LED Driver to function as required, however when i hooked up 2 in a chain(the way the ws2803 drivers work is that they pass bytes in a daisy chain until a delay is issues and the bytes are latched onto the drivers output channels) I got gibberish!!

            I hooked up my oscilloscope, the only thing i noticed, was that the DATA pin was only set to HIGH/LOW for a tiny frame of the CLOCKSs HIGH->LOW phase...

            • 3. Re: Speed of GPIO using MRAA via Javascript GEN2 Galileo
              LeonY

              Ok all good now. Thanks for your suggestions!

              SPI is now working perfectly. My Gen 1 board was just giving me garbage, but when I ran the below on the Gen 2 board i get perfect results:

               

              var m = require('mraa');
              var nLEDs = 48*6*3;
              var ledBar = new Buffer(nLEDs);
              var maxValue=10;
              var ledCnt=0, rcnt=0, innerCnt=0, globalDellay=50;
              x = new m.Spi(0);
              
              
              init();
              runMain();
              
              
              function init()
              {
                  x.frequency(5000000);
                  x.lsbmode(false);
                  x.mode(m.SPI_MODE0);
                  clearSuit();
              }
              
              
              function runMain()
              {
                while(true)
                {
                    for(ledCnt=0; ledCnt<3; ledCnt++)
                    {
                        for(rcnt=0; rcnt<maxValue; rcnt++)
                        {
                          for(innerCnt=0; innerCnt<nLEDs; innerCnt+=3)
                          {  
                             if(ledCnt==0){ledBar[innerCnt]=rcnt;}
                             else if(ledCnt==1){ledBar[innerCnt+1]=rcnt;}
                             else if(ledCnt==2){ledBar[innerCnt+2]=rcnt;}
                          }
                          loadWS2803SPI();
                          delay(globalDellay);
                        } 
                        for(rcnt=maxValue; rcnt>-1; rcnt--)
                        {
                          for(innerCnt=0; innerCnt<nLEDs; innerCnt+=3)
                          {
                             if(ledCnt==0){ledBar[innerCnt]=rcnt;}
                             else if(ledCnt==1){ledBar[innerCnt+1]=rcnt;}
                             else if(ledCnt==2){ledBar[innerCnt+2]=rcnt;}
                          }
                          loadWS2803SPI();
                          delay(globalDellay);
                        }
                    }
                }
              }
              
              
              function loadWS2803SPI()
              {
                  rcv = x.write(ledBar);
                  delay(2);
              }
              
              
              function clearSuit()
              {
                  for(var cnt=0; cnt<nLEDs; cnt++)
                  {
                      ledBar[cnt]=0;   
                  }
                  loadWS2803SPI();
              }
              
              
              function delay(milliseconds)
              {
                  var start = new Date().getTime();
                  for (var i = 0; i < 1e7; i++)
                  {
                      if ((new Date().getTime() - start) > milliseconds)
                      {
                          break;
                      }
                  }
              }
              
              1 of 1 people found this helpful