cancel
Showing results for 
Search instead for 
Did you mean: 

Waveform Widget

BMara.1
Associate II

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++;

}

}

3 REPLIES 3
BMara.1
Associate II

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.

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

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();

}