Espruino with Glediator & LED matrix

Posted on
Page
of 2
/ 2
Next
  • I'm trying to use Espruino as the controller to take LED matrix data from the Glediator over USB and output it onto an RGB LED matrix.
    The Matrix is made up on 16x8 WS2812B pixels. I've attached the example code from Glediator for using an Arduino as the controller which I've tried ported to JS (see below).
    I've tried using the example USART code from here: http://www.espruino.com/USART along with other code I found on the forum but so far nothing has worked. Is there something I'm missing in the code below? I'm unsure if data is being received but Espruino as I can't connect while data is being sent to check.

        function onInit() {
          SPI2.setup({baud:3200000, mosi:B15});
          var m = Graphics.createArrayBuffer(16,8,24,{zigz­ag:true,color_order:'bgr'});
          m.flip = function(){ SPI2.send4bit(m.buffer, 0b0001, 0b0011); }; // Not sure if I need this line?
          USB.setup(115200);
          portData();
        }
    
        function portData() {
          USB.on('data', function (data) {
            USB.print(data); 
            cmd+=data;
            var idx = cmd.indexOf("\r");
            while (idx>=0) { 
              var line = cmd.substr(0,idx);
              cmd = cmd.substr(idx+1);
              var s = "'"+line+"' = "+eval(line); 
              print(s);
              USB.println(s);
              idx = cmd.indexOf("\r");
              SPI2.send4bit(cmd, 0b0001, 0b0011);
            }
          });
        }
    

    1 Attachment

  • Well, I think the main one is that Espruino's 'console' works over the same USB connection as you're trying to send data on, so you want to move it out of the way. Maybe try Serial1.setConsole() in onInit.

    When you do that you might want to avoid using save() though (just manually run onInit()), as then you'd have to reflash the board to get access to the console again.

    You are also printing quite a lot of data - I guess it's for debugging, but that could slow things down a lot.

    To help you out, you might want to get a USB-TTL converter and attach it to Serial1 (B6/B7 on the Pico). You can then interact with the Pico and debug it while using the USB connection to receive data.

    ... or you can do it the other way (might be easier to debug) - send the data from Glediator to the USB-TTL converter on Serial1, and then keep using USB to uploading code and debugging.

  • I do have a USB-TTL converter, I'll give that a good tonight after work.

  • I've tried a few different things but nothing fully working yet. I've confirmed that serial data is being correctly sent out of the PC, Espruino just can't seem to read it.
    I have changed my setup to use a USB-TTL. The Espruino USB is now being use for code uploading and console. All serial data is being sent to the USB-TTL and then into Espruino on the following pins. I'm using the original Espruino board for now and my wiring for the USB-TTL Converter is RXD > C10 & TXD > C11
    I don't think I can use A9&10 as I have a bluetooth module attached.

    After running my test code .on('data' still isn't receiving anything. As a basic test I tried the following code with nothing connected and the results are strange, am I doing something wrong?

    function onInit() {
      //Serial1.setup(115200);
      Serial3.setup(9600);
      Serial3.on('data', function (data) { console.log("<Serial3> "+data); });
      Serial3.print("Hello World");
      console.log('Code is running.');
    }
    onInit();
    

    After uploading code:

    >echo(0);
    Code is running.
    =undefined
    

    Nothing is outputted?

    After entering save():

    Running onInit()...
    Code is running.
    <Serial3> 
    <Serial3> 
    > 
    

    Serial3 is outputted but not the "Hello world"
    If I set a baud rate of 115200 Serial3 isn't outputted.

  • I'm not quite sure I understand. You'd expect Hello World to appear on the terminal program connected to your USB-TTL - but it doesn't? Have you checked that the baud rate of the connected terminal program is set to the same baud rate you set for Serial3?

    Or you've left C10/C11 completely disconnected and you were expecting things to be echoed back?

    It might be worth trying:

    Serial3.on('data', function (data) { console.log("<Serial3> "+JSON.stringify(data)); });
    

    That'll make sure that if there are nonprintable characters, they get escaped so you can see them.

    Are you using an up to date (1v81) firmware? Some of the older ones had issues with Serial3/4.

  • Part success!
    I've got Serial3 receiving data, issue appeared to be that I needed to give the pins in Serial3.setup
    I ran many tests and passed it simple test strings to confirm that it was working and the while() loop would wait until it saw \r
    Now I've begun passing it the matrix data from Glediator and..part success. The serial data is being received and using SPI2.send4bit I push it out onto the matrix. But the matrix lights up crazy, see the photo below.

    Now as crazy as it is, the movement of the pixels and overall colour does match that from Glediator so I'm thinking the issue is more to do with me not correctly finding the beginning of the data. If it is not \r what else could it be?
    Or is there something else I'm missing completely? I've attached my full code below:

      function onInit() {
        SPI2.setup({baud:3200000, mosi:B15});
        var m = Graphics.createArrayBuffer(15,15,24,{zig­zag:true,color_order:'bgr'});
        m.flip = function(){ SPI2.send4bit(m.buffer, 0b0001, 0b0011); };
        
        var cmd = "";
        Serial3.setup(1000000, {tx:C10,rx:C11});
        Serial3.on('data', function (data) {
          cmd+=data;
          var idx = cmd.indexOf("\r");
          while (idx>=0) {
            var line = cmd.substr(0,idx);
            cmd = cmd.substr(idx+1);
            idx = cmd.indexOf("\r");
            SPI2.send4bit(line, 0b0001, 0b0011);    
          }
        });
      }
      onInit(); 
    
  • Can you confirm that serial is seeing sensible data? maybe console.log(line); in there?

  • I've tried console.log(line) but when Serial3 is being sent data USB don't respond. The only time I got something back from Espruino it was a "Out of memory" warning.

  • Maybe it's not an issue with detecting the line ending but rather then matrix encoding. Do you know what format SPI2.send4bit() expects?

  • It expects an array of bytes which are to be sent.

  • Using an SD card I saved the raw data of "line" to a file and have attached it here. Does it make any sense to anyone?


    1 Attachment

  • The 'out of memory' error sounds like you're not getting a newline, so are just making a huge string with all the data from multiple frames?

    Actually, if you look at that Arduino file you sent, it seems to me like it's sending binary data and is using a simple 1 as the 'new frame' character (line 110) - presumably it ensures that it just never sends '1' normally.

    Try:

    function onInit() {
        SPI2.setup({baud:3200000, mosi:B15});    
        var cmd = "";
        Serial3.setup(1000000, {tx:C10,rx:C11});
        Serial3.on('data', function (data) {
          cmd+=data;
          var idx = cmd.indexOf("\1");
          while (idx>=0) {
            var line = cmd.substr(0,idx);
            cmd = cmd.substr(idx+1);
            idx = cmd.indexOf("\1");
            SPI2.send4bit(line, 0b0001, 0b0011);    
          }
        });
      }
      onInit(); 
    
  • Just to add that you could also be having some electrical issues if you get flickering - I think there's a note on the WS2811 page about using a pullup resistor and putting SPI into Open Drain mode? It might be needed if you're running the panel off a separate 5v supply.

    ... finally I don't know if Glediator handles the zig-zag pattern of the LEDs? It could be a pain to try and re-order them quickly. About the only thing I can think is to use Graphics with drawImage of the image data you received.

  • Success! You're a genius Gordon \1 was it! It works perfectly and with great frame rates.
    I had a problem with random colours appearing when powering the Espruino directly off 5V and not the PC but I fixed that by simple grounding the USB-TTL to the 5V supply.
    https://www.youtube.com/watch?v=Yk55bTqT­VDY

  • Wow, that works well! So is your finished code literally just what was posted above?

    And glediator handles the zig-zag automatically?

  • I had a to change a few little bits. For example I had to remove the call to onInit(); other wise the serial on(data) was getting fired twice on boot which messed up the output.
    I also added a frame per second counter for testing and I get a steady 25 fps!
    My next task maybe to try and get this working over USB alone but if I need console access this might not be possible. maybe I could move console onto Bluetooth..
    Here is the full code used in the video:

      var fps = 0;
      function onInit() {
        SPI2.setup({baud:3200000, mosi:B15});
        var cmd = "";
        Serial3.setup(1000000, {tx:C10,rx:C11});
        Serial3.on('data', function (data) {
          cmd+=data;
          var idx = cmd.indexOf("\1");
          while (idx>=0) {
            var line = cmd.substr(0,idx);
            cmd = cmd.substr(idx+1);
            idx = cmd.indexOf("\1");
            SPI2.send4bit(line, 0b0001, 0b0011);
            fps++;
          }
        });
        
        var fps = setInterval(function() {
          console.log('fps: ' + fps);
          fps = 0;
        }, 1000);
      }
    
  • Thanks! Yes, making it all work off USB would be great - I think it would work fine.

    ... if at some point you move it to an Espruino Pico, you'll basically have everything you need right in the USB plug!

  • It got 256 WS2812b RGB LEDs soldered, and found that at the end of chain, LEDs start looking dimmed (they become orange, like loose blue and some green), like not much power left, especially if they all white. It is plugged to espruino (power, data, ground). As I understand I should move power and ground to external source?

  • Yes - with 256 LEDs you're looking at potentially 256*3*0.02A if all LEDs are lit - which is 15 amps! :)

    You'll want to connect GND and Data to Espruino, and GND + Power to an external 5v power supply.

    Also, it's worth connecting Power and GND right from the end of your LEDs, back to the beginning. That'll really help with the dimming you're seeing. If you want to do it really nicely you could connect the power and GND of each row back to one place...

  • Sorry to reopen topic but I think it's the best place. Since my last post here I've built a much bigger RGB LED matrix (15x15) and beginning to run into some serial data issues.
    On my 15x15 board I can easily output the first 168 pixels but any more and it all goes wrong. I'm not sure if this is an issue with Glediator, USB2Serial, Espruino reading the serial data or Espruino outputting the SPI data?
    I don't believe Espruino is the issue but I'm really not sure what is. The code below does the same as above but outputs the "line" length (the graphic SPI data). For 15x15 it should always be 675 but rarely is..

    function onInit() {
      SPI2.setup({baud:3200000, mosi:B15});
      var cmd = "";
      Serial1.setup(1000000, {tx:B6,rx:B7});
      Serial1.on('data', function (data) {
        cmd+=data;
        var idx = cmd.indexOf("\1");
        while (idx>=0) {
          var line = cmd.substr(0,idx);
          cmd = cmd.substr(idx+1);
          idx = cmd.indexOf("\1");
          console.log(line.length);
          SPI2.send4bit(line, 0b0001, 0b0011);
        }
      });
    }
    

    And the console returns:

    Running onInit()... 
    0 
    675 
    504 
    664 
    504 
    504 
    602 
    504 
    504 
    504 
    545 
    504 
    1002 
    219 
    504 
    504 
    504 
    504 
    504 
    504 
    504 
    504 
    504 
    504 
    504 
    1076 
    147 
    504 
    504 
    833 
    390 
    504 
    504 
    504 
    725 
    1128 
    88 
    504 
    504 
    504 
    661 
    504 
    504 
    1077 
    144 
    504 
    504 
    504 
    504 
    504 
    834 
    389 
    504 
    504 
    504 
    904 
    895 
    

    675 only appears a couple of time while 504 appears many but again there are lots of other seemly random lengths.
    Is the problem the serial data that's being sent from Glediator or the way I'm detecting a new frame "\1" ?
    Let me know if there is anything I can try to debug this or if the magic length 504 means anything? Thanks

  • Check E.getErrorFlags() - is it overflowing the buffer?

  • Running E.getErrorFlags() at random times almost always returns FIFO_FULL.
    What does this mean and how to I fix the issue?

    >E.getErrorFlags();
    =[
      "FIFO_FULL"
     ]
    
  • It means that Espruino isn't able to process the data that's coming in fast enough, and it's had to drop some of it.

    Your best bet would be to reduce the Serial baud rate from 1000000 to something a bit slower - then Espruino should be able to deal with the data as it comes in.

    If you need that baus rate you might also be able to reduce the amount of characters you check for \1 (for instance you could check data rather than cmd) - if you've got 15*15*3=675 bytes, repeatedly scanning it for \1 will probably take a while.

    Potentially you could also dump that into an array rather than appending to a string...

    var buf = new Uint8Array(1000);
    var bufIdx = 0;
    
      Serial1.on('data', function (data) {
        buf.set(data, bufIdx);
        var idx = bufIdx+data.indexOf("\1");
        bufIdx += data.length;
        if (idx>=0) {
          var line = new Uint8Array(buf.buffer, 0, idx);
          console.log(idx);
          SPI2.send4bit(line, 0b0001, 0b0011);
          buf.set(new Uint8Array(buf.buffer, idx, bufIdx-idx), 0);
          bufIdx -= idx;
        }
      });
    

    Not tested, but something like that might be quicker.

  • Hi Gordon,
    I understand the idea but can't get it to work. It is outputting mostly random colours and the idx.length looks too small. My guess is it's receiving the data but doesn't know where the frame begins or perhaps the frame break "\1" is being included in the output.
    I've tweaked your code a bit to get it working but with the problems above.
    PS. I've been running this code on both the Pico and orgional Espruino with the same results on both.

    /**
    Glediator settings
    Driver: Glediator
    Baud 115200
    Colour order: GRB
    Pixel order:  HS_TL
    */
    var fps = 0,
        buf = new Uint8Array(15*15*3),
        bufIdx = 0,
        cmd = "";
    
    function onInit() {
      SPI1.setup({baud:3200000, mosi:A7});
      
      Serial1.setup(115200, {tx:B6,rx:B7});
      Serial1.on('data', function (data) {
        
        buf.set(data, bufIdx);
        bufIdx += data.length;
        
        if (data.indexOf("\1") >= 0) {
          var idx = bufIdx + data.indexOf("\1");
          var line = new Uint8Array(buf.buffer, 0, idx);
          console.log(idx);
          
          SPI1.send4bit(line, 0b0001, 0b0011);
          buf.set(new Uint8Array(buf.buffer, idx, bufIdx-idx), 0);
          bufIdx -= idx;
          fps++;
        }
      });
        
      var fps = setInterval(function() {
        console.log('fps: ' + fps);
        fps = 0;
      }, 1000);
    }
    
    onInit();
    

    This outputs the following:

      594  
      594  
      593  
      593  
      594  
      593  
      594  
      594  
      594  
      594  
      594  
      593  
      fps: 12  
      593  
      594  
      593  
      593  
      593  
      594  
      593  
      594  
      593  
      593  
      594  
      fps: 11  
    
  • The first thing I noticed was you changed:

        buf.set(data, bufIdx);
        var idx = bufIdx+data.indexOf("\1");
        bufIdx += data.length;
    

    to

        buf.set(data, bufIdx);
        bufIdx += data.length;
        
        if (data.indexOf("\1") >= 0) {
          var idx = bufIdx + data.indexOf("\1");
    

    Obviously that's going to change the value of idx, so is a good place to start :)

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

Espruino with Glediator & LED matrix

Posted by Avatar for Owen @Owen

Actions