Skip to main content
BMara.1
Associate
December 11, 2019
Question

Waveform Widget

  • December 11, 2019
  • 2 replies
  • 1097 views

I’m creating a waveform widget in TouchGFX, but unsure how best to loop the waveform back to zero at the end because there are three frame buffers so you have to invalidate over an area three times or you get flickering . How would you handle looping the array back to start (x=0).

The main issue is my code originally assumed there was only one frame buffer. I think my code needs to be refactored for three framebuffers or add the ability to write directly to the frame buffer. Any hints would be greatly appreciated. 

bool Graph::drawCanvasWidget(const Rect& invalidatedArea) const

{

if (numPoints < 3)

{

// A graph line with a single (or not even a single) point is invisible

return true;

}

else{

Canvas canvas(this, invalidatedArea);

for (int index = 0; index < (numPoints-1); index++)

{

canvas.moveTo(points[index].x,points[index].y);

canvas.lineTo(points[index].x,points[index+1].y);

canvas.lineTo(points[index+1].x,points[index+1].y);

canvas.lineTo(points[index+1].x,points[index].y);

}

return canvas.render(); // Shape above automatically closed

}

return true;

}

void Graph::newPoint(int y)

{

if(numPoints==501){

numPoints=0;

}else if ((maxPoints-numPoints)<=20){

points[numPoints].x = numPoints;

points[numPoints].y = y;

Rect minimalRect(480,0,20,100);

invalidateRect(minimalRect);

numPoints++;

}else{

points[numPoints].x = numPoints;

points[numPoints].y = y;

Rect minimalRect(numPoints-3,0,20,100);

invalidateRect(minimalRect);

numPoints++;

}

}

This topic has been closed for replies.

2 replies

BMara.1
BMara.1Author
Associate
December 16, 2019

https://community.st.com/s/question/0D50X0000AqBQlsSQG/why-using-canvaswidget-class-to-draw-lines-encounter-flicking-problem

It looks like this question has come up before. Any guidance would be greatly appreciated.

BMara.1
BMara.1Author
Associate
December 16, 2019

Writing to the framebuffer is likely the solution for speed where the above is more suited for static data. any guidance would be greatly appreciated

Robin Zhou
Associate II
December 17, 2019

Hi, BMara. Here is my solution for the problem refer to https://community.st.com/s/question/0D50X0000AqBQlsSQG/why-using-canvaswidget-class-to-draw-lines-encounter-flicking-problem

bool CircularGraph::drawCanvasWidget(const Rect& invalidatedArea) const

{

  if (0 > curWriteIdx || invalidatedArea.width == getWidth())

  {

    return true;

  }

   

  uint16_t endIdx = curWriteIdx;

  uint16_t startIdx = (0 == endIdx) ? (maxPoints - 1) : (endIdx - 1);

  uint8_t cnt = 0;

  Rect rectArea = invalidatedArea;

  // Draw two times for the data at the right end of the graph

  if (points[startIdx].x > points[endIdx].x)

  {

    endIdx = startIdx;

    startIdx = (0 == endIdx) ? (maxPoints - 1) : (endIdx - 1);

    rectArea = lastMinimalRect;

  }

   

  // Don't draw data not in invalidateRect Area

  while (points[startIdx].x < points[endIdx].x && rectArea.x <= (widgetXindex(endIdx) + lineWidth / 2).to<int16_t>())

  {

    ++cnt;

    endIdx = startIdx;

    startIdx = (0 == endIdx) ? (maxPoints - 1) : (endIdx - 1);

  }

   

  if ( 0 == cnt)

  {

    return true;

  }

   

  Canvas canvas(this, rectArea);

  startIdx = endIdx;

  endIdx = (startIdx >= maxPoints - 1) ? 0 : (startIdx + 1);

  canvas.moveTo(xAboveOutgoing(startIdx), yAboveOutgoing(startIdx));

  canvas.lineTo(xAboveIncoming(endIdx), yAboveIncoming(endIdx));

  for (int i = 0; i < cnt - 1; ++i)

  {

    startIdx = endIdx;

    endIdx = (startIdx >= maxPoints - 1) ? 0 : (startIdx + 1);

    canvas.lineTo(xAboveOutgoing(startIdx), yAboveOutgoing(startIdx));

    canvas.lineTo(xAboveIncoming(endIdx), yAboveIncoming(endIdx));

  }

  for (int i = cnt - 1; i >= 0; --i)

  {

    canvas.lineTo(xBelowIncoming(endIdx), yBelowIncoming(endIdx));

    canvas.lineTo(xBelowOutgoing(startIdx), yBelowOutgoing(startIdx));

    endIdx = startIdx;

    startIdx = (0 == endIdx) ? (maxPoints - 1) : (endIdx - 1);

  }

  /*

  bool flag = canvas.render();

  if (flag == false)

  {

    flag = flag;

  }

   

  return flag;

  */

   

  return canvas.render();

}