Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Screen artifacts #61

Open
EB4FBZ opened this issue Oct 1, 2019 · 9 comments
Open

Screen artifacts #61

EB4FBZ opened this issue Oct 1, 2019 · 9 comments

Comments

@EB4FBZ
Copy link

EB4FBZ commented Oct 1, 2019

I have seen some screen artifacts from traces since the first firmware version i have tested. Has anyone paid attention to this?

photo5796658605267727050
photo6044092117866884827

@mrobertsn
Copy link

I noticed it too and reported it a while ago but I don't think it has been fixed.

#35 (comment)

@ssd2
Copy link

ssd2 commented Oct 17, 2019

It would be nice if there was a way to trigger a screen blank and redraw.

@Pmax65
Copy link

Pmax65 commented Feb 3, 2020

This is a workaround to clear the artifacts tapping the screen to get the menu and tapping again for remove it.

In file ui.c the function leave_ui_mode must be rewritten as follows

static void leave_ui_mode(void)
{
  if (ui_mode == UI_MENU) {
	request_to_redraw_grid();
	erase_menu_buttons();
	draw_frequencies();
	draw_cal_status();
//    request_to_draw_cells_behind_menu();
//    erase_menu_buttons();
  } else if (ui_mode == UI_NUMERIC) {
    request_to_draw_cells_behind_numeric_input();
    erase_numeric_input();
    draw_frequencies();
  }
}

Not a solution but clears those unwanted signs.

Have a great day.

Massimo IK1IZA

@DiSlord
Copy link
Contributor

DiSlord commented Feb 22, 2020

Screen artifacts

Screen update goes by cells size 32x32 pixels (processor can,t fast draw all screen)
Fore faster screen update used function mark_cells_from_index() for detect cell for update, and detect cells not need update. Some long lines made cell dirty, but cell marked as disabled for update (becose need do it faster, and made mistake in calc).

Fore fix it possible every n draws in mark_cells_from_index set redraw all cells

@Pmax65
Copy link

Pmax65 commented Feb 23, 2020

Hi DiSlord,
an alternative for a pseudo-real-time update to clear the screen from artifacts could be done defining a cell counter that every screen update adds to the cells already to update some unmarked-to-update cells. This way, considering the display resolution of a total of 80 cells (for a 320 by 240 pixels display), the worst case (no cells already to update at all) adding 8 cells a time the whole display will be fully cleared in 10 screen updates.

More in detail, considering that the top-left cell has index 0 (I don't investigate this in the current software, it's just an hypothesis) and the bottom-right cell has index 79, calling CleanupCounter the variable which holds the last cell forced to be updated and CellToMark the counter of the cells to add to the current update, the procedure to execute before every update should be as follows:

  1. CellToMark = 8
    1a) CellCount = 80
  2. CleanupCounter ++
    2a) CellCount --
    2b) if CellCount = 0 goto step 8
  3. if CleanupCounter = 80 then CleanupCounter = 0
  4. if Cell(CleanupCounter) is already marked to be updated return to step 2 else continue to step 5
  5. mark Cell(CleanupCounter) to be updated
  6. CellToMark --
  7. if CellToMark > 0 return to step 2
  8. exit the procedure

If adding 8 cells leads to a too slow screen refresh, the number of added cells could be reduced until the screen refresh time is acceptable.

I thought a little more and concluded that the algorithm proposed could fall into an infinite loop in case the number of cells not marked to update are less than the maximum value of CellToMark (for example after a call to request_to_redraw_grid() ).
So I edited the message adding CellCount (see bold steps above).
Note also that CleanupCounter must be a global or static variable.

Have a great day.

Massimo

@Pmax65
Copy link

Pmax65 commented Feb 23, 2020

I know that the solution should be investigating where the drawing function fails, this is just a workaround, anyways it seems to work fine on nanoVNA-H code
This must be added somewhere into plot.c:

int CleanupCounter=0;
static inline void Clean_markmap(void)
{
  int CellCount=80;
  int CellToMark=24;
  int x,y;
  while(1){
	  CleanupCounter++;
	  if (CleanupCounter==80) {
		  CleanupCounter=0;
	  }
	  CellCount--;
	  if (CellCount==0) {
		  return;
	  }
	  x=CleanupCounter>>3;
	  y=CleanupCounter&0x07;
	  if (!is_mapmarked(x,y)){
		  mark_map(x,y);
		  if(--CellToMark==0){
			  return;
		  }
	  }
  }
}

The above function Clean_markmap() should be placed at the first line of draw_all_cells() as follows:

static void draw_all_cells(bool flush_markmap)
{
  int m, n;
  Clean_markmap();
  for (m = 0; m < (area_width+CELLWIDTH-1) / CELLWIDTH; m++)
    for (n = 0; n < (area_height+CELLHEIGHT-1) / CELLHEIGHT; n++) {
      if (is_mapmarked(m, n))
        draw_cell(m, n);
    }

  if (flush_markmap) {
    // keep current map for update
    swap_markmap();
    // clear map for next plotting
    clear_markmap();
  }
}

With 4 traces on, I can't see any appreciable delay, while even with one trace on only, the artifacts are cleared in maximum 4 redraws (I initialized CellToMark to 24 cells per redraw).

Have a great day.

Massimo IK1IZA

@DiSlord
Copy link
Contributor

DiSlord commented Feb 25, 2020

in file plot.c
2 bit buffers for detect cell for clear and update
uint16_t markmap[2][MAX_MARKMAP_Y];

Then before screen render need cache line list for render in for all traces
static uint32_t trace_index[TRACES_MAX][POINTS_COUNT];

All work do in
plot_into_index(float measured[2][POINTS_COUNT][2])

Cache trace index data in screen coordinates
for (i = 0; i < sweep_points; i++) trace_index[t][i] = trace_into_index(t, i, measured[ch]);
And call
static void mark_cells_from_index(void)
This function must mark cell for update on screen, but do it not fully correct (aproximate resultfor speed)
in some cases cell in 1 run marked as need update, on second run cell marked as remove from update and run
draw_cell
from

static void draw_all_cells(bool flush_markmap){
  int m, n;

  for (m = 0; m < (area_width+CELLWIDTH-1) / CELLWIDTH; m++)
    for (n = 0; n < (area_height+CELLHEIGHT-1) / CELLHEIGHT; n++) {
      uint16_t bit = 1<<m;
      if ((markmap[0][n] & bit) || (markmap[1][n] & bit)){
        draw_cell(m, n);
      }
  if (flush_markmap) {
    // keep current map for update
    swap_markmap();
    // clear map for next plotting
    clear_markmap();
  }
}

if ((markmap[0][n] & bit) || (markmap[1][n] & bit)) one buffer mark as need erase, second as need update
in some cases on long lines
static void mark_cells_from_index(void)
made error in not mark cell as need update (long line), but cell marked as need erase, and
draw_cell
draw this line

And not update this cell

1 Solution - write more correct variant
static void mark_cells_from_index(void)

2 Solution in
static void draw_all_cells(bool flush_markmap)
Update some cells partially, for example every 2 run update one cell column anyway
add static counter mark= 0-n and add
if (mark == n || (markmap[0][n] & bit) || (markmap[1][n] & bit))

mark++;
if (mark == bottom) mark = 0;
Ore somthing.. this a little slowdown render speed.

@Pmax65
Copy link

Pmax65 commented Feb 25, 2020

Hi DiSlord,
My patch does more or less what you suggest in your solution 2 and seems to work.
Have a great day
Massimo

@DiSlord
Copy link
Contributor

DiSlord commented Mar 9, 2020

I fix this in #126
Use solution 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants