-
• #27
Please can you change console.log so it outputs buf.length and line.length as well? And can you paste up the code you used and the results? It'd be handy to see the data that was in
line
too - but I imagine printing it all out might overwhelm the Espruino :(Also, do you still get the FIFO_FULL errors? It might be that even with this, you still have the same problem.
-
• #28
I've attached the exact code I used and below is the console output.
idx 4 buf 1000 line 4 idx 109 buf 1000 line 109 idx 2 buf 1000 line 2 idx 109 buf 1000 line 109 idx 2 buf 1000 line 2 idx 109 buf 1000 line 109 idx 4 buf 1000 line 4 idx 111 buf 1000 line 111 idx 4 buf 1000 line 4 idx 110 buf 1000 line 110 idx 4 buf 1000 line 4 idx 110 buf 1000 line 110 idx 2 buf 1000 line 2 idx 110 buf 1000 line 110 idx 4 buf 1000 line 4 idx 110 buf 1000 line 110 idx 5 buf 1000 line 5 idx 110 buf 1000 line 110 idx 4 buf 1000 line 4 idx 110 buf 1000 line 110 idx 4 buf 1000 line 4 idx 109 buf 1000 line 109 idx 3 buf 1000 line 3 idx 110 buf 1000 line 110 idx 2 buf 1000 line 2
With the attached code "line" is only 4 bits in length;
JSON.stringify(line) "new Uint8Array([37,0,37,32])"
Using the original working code I managed to get a complete frame of data in line which I've pasted below.
>USB.print(JSON.stringify(line)); "?\x00?D\x00DD\x00D?\x00?9\x0094\x004/\x00/*\x00*$\x00$ \x00 \x1B\x00\x1B\x17\x00\x17\x13\x00\x13\x0F\x00\x0F\f\x00\f\f\x00\f\x0F\x00\x0F\x13\x00\x13\x17\x00\x17\x1B\x00\x1B \x00 $\x00$*\x00*/\x00/4\x0049\x009?\x00?D\x00DD\x00D?\x00??\x00?D\x00DD\x00D?\x00?9\x0094\x004/\x00/*\x00*$\x00$ \x00 \x1B\x00\x1B\x17\x00\x17\x13\x00\x13\x0F\x00\x0F\f\x00\f\f\x00\f\x0F\x00\x0F\x13\x00\x13\x17\x00\x17\x1B\x00\x1B \x00 $\x00$*\x00*/\x00/4\x0049\x009?\x00?D\x00DD\x00D?\x00??\x00?D\x00DD\x00D?\x00?9\x0094\x004/\x00/*\x00*$\x00$ \x00 \x1B\x00\x1B\x17\x00\x17\x13\x00\x13\x0F\x00\x0F\f\x00\f\f\x00\f\x0F\x00\x0F\x13\x00\x13\x17\x00\x17\x1B\x00\x1B \x00 $\x00$*\x00*/\x00/4\x0049\x009?\x00?D\x00DD\x00D?\x00??\x00?D\x00DD\x00D?\x00?9\x0094\x004/\x00/*\x00*$\x00$ \x00 \x1B\x00\x1B\x17\x00\x17\x13\x00\x13\x0F\x00\x0F\f\x00\f\f\x00\f\x0F\x00\x0F\x13\x00\x13\x17\x00\x17\x1B\x00\x1B \x00 $\x00$*\x00*/\x00/4\x0049\x009?\x00?D\x00DD\x00D?\x00??\x00?D\x00DD\x00D?\x00?9\x0094\x004/\x00/*\x00*$\x00$ \x00 \x1B\x00\x1B\x17\x00\x17\x13\x00\x13\x0F\x00\x0F\f\x00\f\f\x00\f\x0F\x00\x0F\x13\x00\x13\x17\x00\x17\x1B\x00\x1B \x00 $\x00$*\x00*/\x00/4\x0049\x009?\x00?D\x00DD\x00D?\x00??\x00?D\x00DD\x00D?\x00?9\x0094\x004/\x00/*\x00*$\x00$ \x00 \x1B\x00\x1B\x17\x00\x17\x13\x00\x13\x0F\x00\x0F\f\x00\f\f\x00\f\x0F\x00\x0F\x13\x00\x13\x17\x00\x17\x1B\x00\x1B \x00 $\x00$*\x00*/\x00/4\x0049\x009?\x00?D\x00DD\x00D?\x00??\x00?D\x00DD\x00D?\x00?9\x0094\x004/\x00/*\x00*$\x00$ \x00 \x1B\x00\x1B\x17\x00\x17\x13\x00\x13\x0F\x00\x0F\f\x00\f\f\x00\f\x0F\x00\x0F\x13\x00\x13\x17\x00\x17\x1B\x00\x1B \x00 $\x00$*\x00*/\x00/4\x0049\x009?\x00?D\x00DD\x00D?\x00??\x00?D\x00DD\x00D?\x00?9\x0094\x004/\x00/*\x00*$\x00$ \x00 \x1B\x00\x1B\x17\x00\x17\x13\x00\x13\x0F\x00\x0F\f\x00\f"=undefined >
-
• #29
I'm not sure the code is attached - please could you try to attach it again?
And sorry - when I said
buf.length
, I actually meantbufIdx
:) -
• #30
Here is the full output for two seconds: http://pastebin.com/M5Gien3D
After doing some more research I don't think there is anything wrong with the code and that it's been optimised as much as it can be the problem is there just isn't memory to process so many pixels fast enough. "FIFO_FULL" keeps poping up if I try and send more than around 150 pixels at 25fps.
1 Attachment
-
• #31
So it works if you lower the data rate? Is it possible to just lower the Baud rate on Serial then?
Also, if you remove the print statements, that should help a lot.
The Pico has a 512 byte input buffer I think - I guess it's possible that so much data is arriving while the last data is being sent to the LEDs that it gets full up...
150 pixels * 24 bits = 3600, and each bit takes 1.25us to send, so that's 4.5ms. If you're receiving data at 1000000 baud then that's 100,000 bytes/sec, so in 4.5ms you're receiving 450 bytes.
Add some overhead for executing JS and you're dangerously close to overflowing that buffer... So the solution would either be to:
- Reduce the baud rate
- Somehow ensure that the transmitter left a gap in transmission while data was being sent to the LEDs.
- Compile your own Pico firmware with a larger input buffer (without actually making big changes, you could get up to 1024 bytes).
- Reduce the baud rate
-
• #32
The slowest baud-rate Glediator has is 115200 which might still be too fast.
I guess it just comes down to too many pixels to process at once. In my 15x15 matrix that is 255 pixels.
225 * 24 bits = 5400 bits
5400 bits * 1.25us = 6.75msIf I could get Glediator to pause after each frame to allow Espruino to shift out the data it might work better but I don't think that's possible. You can't even limit the frame-rate from Glediator which may also be causing problems.
Increasing the Picos input buffer size might work but I've no idea how to do that. -
• #33
115200 would be a huge help - the maximum frame rate Glediator could send over that would be 51fps (20ms), but it only takes 6.75ms to send it to the LEDs - so I think you stand a good chance with that.
-
• #34
You could also try using USB, rather than serial. USB has some rate-limiting built in, so you shouldn't have the FIFO_FULL error.
To do USB, you just swap
Serial1
toUSB
in your code, and addSerial1.setConsole()
to move Espruino's console over toSerial1
(to get it out of the way of USB). -
• #35
Success! I've got it running the full 225 pixels at 25fps!
I kept tweaking the code and optimising as must as I could with no real change even at 115200. Then I change Serial1 to USB and boom full board working at full fps.
Changing to USB doesn't make it easy to work with but now I have a plug-n-play matrix output stick. -
• #36
Great! You can always do something like:
function onInit() { Serial1.setConsole(); setTimeout(function() { if (BTN.read()) USB.setConsole(); }, 1000); }
So if you've saved and want to debug again, you can just plug the board in with the button pressed down, and you'll get access to the console again.
-
• #37
Hi Owen, could you post the finished code? I am just starting with Espruino, LED Matrix projects and glediator, it would be wonderful not to reinvent the color wheel :-) Thanks!
-
• #38
Hi,
I think this is the working code but haven't tested it in a while. Read the comment at the top for the wiring, matrix and Glediator settings.
Let me know if that works or not. I was using the Pico but it shouldn't matter which espruino you use./** Glediator settings Driver: Glediator COM6 Baud 1000000 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();
I changed that because idx will always been greater than -1 after the first loop because it's get added the value of bufIdx.
The output now is a very low number of idx, basically every bit of data received. The fps count jumps way up to over 200. See the example output below: