Horizontal update tearing

These are my settings.

#define MATRIX_REFRESH_RATE 100
#define COLOR_DEPTH_RGB 24
#define DMA_BUFFER_NUMBER_OF_ROWS 4
#define LATCH_TIMER_PULSE_WIDTH_NS 438
#define MIN_BLOCK_PERIOD_NS 10000

You’re right that it should be happening at row zero for the output. Are you sure the buffer flip is happening at the right time? Are you displaying data from USB or from a pin?

I suppose it’s possible you’re spending too much time in interrupts or something and getting out of sync from that. I’ve made a few optimizations in my fork of SmartMatrix which might help if that’s the issue: GitHub - ecurtz/SmartMatrix: SmartMatrix Library for Teensy 3 .

I am waiting for a full frame from USB then fire the swapBuffer(true) method. I assumed if mid updating the display the method would block until safe to swap?
I will take a look at your fork see if I can find some clues.

Thanks

This is my test. if you run this do you get a perfectly straight vertical line? Or is it tearing half way?

int cnt = 0;
void loop(){
matrix.fillScreen({0,0,0});
matrix.fillRectangle(cnt, 0, cnt, 31, {255,0,0});
matrix.swapBuffers(true);
cnt++;
cnt%=128;
}

I swapped to 96mhz, i played around with all the different refresh rates and other various settings. Nothing seems to remove the tear. What I find interesting is the tear is exactly where the two sub displays meet. As this display is 1/16 scan its actually doing to scans to create the image (dual at same time) And the tear is where they meet. I have also noticed it looks like the vertical line is very slightly leaning and then gets cut then slightly leans again. Its like the separate scans are going out of sync as they draw each row? Or some thing along these lines?

Sorry for the delayed response. Yes, I get “broken” lines using this code. It might be because you have no delays and it’s executing multiple times per screen refresh? In fact I still get broken lines until I put in a pretty large delay (80ms +) It looks like a bug in the screen refresh code to me.

I think this is caused by the multiplexing in the panel. There are two lines driven at a time, spaced 16 rows apart, and the code scans from top to bottom. If the line is going from right to left and moving one pixel left per frame, pixels (31,15) and (31,31) are lit just before pixels (30,0) and (30,16) are lit.

Try rotating the screen in software before running the same code, you’ll likely see this go away or at least look different at rotations 90 and 270.

Response to a similar report: Major Refactoring - SmartMatrix 3.x · Issue #25 · pixelmatix/SmartMatrix · GitHub

Wouldn’t that mean that row 0 and row 16 should appear on the same column, since they are refreshed together? It may just be an optical illusion, but row 0 visually seems to be 2 columns behind, then 1-15, then 16-31.

I’ll have to take a look later this week. I’m traveling right now without access to a panel. What you’re describing sounds like an off-by-one bug I’ll need to fix

The row zero thing is because the row increments after the row zero test in matrixCalculations() it could be fixed by moving up the currentRow increment.

    // do once-per-frame updates
    if (!currentRow) {
        ...
    }

    // enqueue row
    if (++currentRow >= matrixRowsPerFrame)
        currentRow = 0;

Still don’t know why the top and bottom half are out of sync, but it almost seems like it might be a hardware issue, given that those are written out at the same time, and it only occurs at higher frame rates.

EDIT: Actually that’s not true, it still happens at very low frame rates, but doesn’t happen at high frame rates with delays. The difference being number of screen refreshes per data change I assume.

Did any one have any luck with this issue (on V3) I had a look at the source code and its a bit over my head (quite new to .c).

I just committed @eli_curtz’s fix:

This fixes the tearing-on-the-first-line issue. It doesn’t fix the tearing-halfway issue, because that’s a result of the panel hardware and there’s no fix for it. You can rotate by 90 or 270, and you’ll see horizontal lines don’t tear. Here’s your test code, updated for SmartMatrix3:

#include <SmartMatrix3.h>
#include <FastLED.h>

#define COLOR_DEPTH 24                  // known working: 24, 48 - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24
const uint8_t kMatrixWidth = 32;        // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 32;       // known working: 16, 32, 48, 64
const uint8_t kRefreshDepth = 36;       // known working: 24, 36, 48
const uint8_t kDmaBufferRows = 4;       // known working: 2-4, use 2 to save memory, more to keep from dropping frames and automatically lowering refresh rate
const uint8_t kPanelType = SMARTMATRIX_HUB75_32ROW_MOD16SCAN;   // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels
const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_NONE);      // see http://docs.pixelmatix.com/SmartMatrix for options
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);

SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);

void setup()
{
    Serial.begin(9600);

    // Initialize Matrix
    matrix.addLayer(&backgroundLayer); 
    matrix.begin();

    matrix.setBrightness(255);
    matrix.setRefreshRate(255);

    //matrix.setRotation(rotation270);
}

int cnt = 0;
void loop(){
    backgroundLayer.fillScreen({0,0,0});
    backgroundLayer.fillRectangle(cnt, 0, cnt, 31, {255,0,0});
    backgroundLayer.swapBuffers(true);
    cnt++;
    cnt%=128;
}

Ah I see its the middle tear that effects me as I have scrolling text in this area. Not that noticeable at lower scroll speeds but faster really is obvious.

Could you explain a bit more how the hardware causes this issue? Some sort of lag in the shift registers or something? I still do not completely understand what causes the tearing. If you only swap the buffer after a completed scan of the display how can it be out of sync?

Regards
Russell

I explained it above:

Cool project, how are you loading data on the display? I’m guessing you wrote your own scrolling text classes that have multiple colors and scroll vertically (with masking). Looks great!

Ok i sort of understand what’s going on. So if this is an hardware issue do all the big video screens using these panels suffer the same tearing mid panel.

Thanks :slight_smile:

Data is being loaded via a esp8266 module connected to the teensy via uart. It receives the train departure data from a uk train departure board api so its all real time data.

I had the font in byte array form and it is not fixed width so decided to write my own font method to draw my font. It returns the lenth of the text drawn making it easy to draw the next text. I added a vertical mask as well to allow you to scroll it without over writing other graphics above or below.

Another method i added was matrix.stop(); this is needed to literally kill the matrix timer interrupt. I need this when running a dfu routine which updates the flash and the two did not play happy together hehe.

I have not looked at the v3 source in a while is there plans to add (or might be already there?) support for none fixed width fonts. And if the draw text method could return the lenth of drawn string is very useful.

Regards
Russell

Probably at least to some extent. They may refresh the panels at a high refresh rate, probably higher than SmartMatrix, and update the content at a lower refresh rate, e.g. 30fps.

There’s probably some relevant info in this video:

Do you have a writeup or source code shared for your project? I’m starting a new blog on internet connected displays, and your project would be a good fit for a post on the blog.

I added GitHub issues for matrix.stop() and for drawText to return length. If you want to submit either as a pull request or just link to your source (if it’s open source), that would help for sure.

There’s a GitHub issue for font improvements, feel free to take a look and add comments or a link to your source there.

No write up. I can send you some information about the project if you like though.

Yes i can give you the source for the new text methods. I forgot to mention they also include a alignment param which is extremely useful when centering text. I will upload these methods source when i get into work.

Here is the source for my text methods
http://54.148.129.10/source.cpp

Regards
Russell

Thanks, I pasted your code into the GitHub issue so I wouldn’t lose it.

If you have time and want to share more, please send me some info, or just create a new post here. I don’t think I’ve seen anyone else connect up an ESP8266 to the SmartMatrix, so I’m interested to learn more.

Ok cool :smile:

I am in the process of finishing the configuration tool that is used to initially set up the wifi and adjust various delays / animation speeds and colours the departure board uses. Once I have everything working correctly I will post more information about the project. Also waiting for my custom PCB to turn up :smile:

Regards
Russell

This tearing at scan boundaries has been annoying me. For my 64 row matrix, there’s ~4ms between row 32 and row 31 being lit. I figured a different scan order could reduce the maximum period between adjacent rows to 0.25ms, and eliminate that annoying offset in the middle. To test that theory out, I made this change.

Here are before and after photos of this sketch, along with exaggerated impressions of how a fast moving vertical line looks to my eyes.

I find this much less jarring than the original discontinuity.