Having trouble slowing my screen display

Hi, this is my first attempt at writing code. The goal seemed quite modest but I’m getting bogged down. I’m reading tabular data from a csv file, and writing to the screen one row of the table at the time. What I’d like to do at this point is write the first row at the top, wait a specified amount of time, then write the next, and so forth. I’ve tried using frameRate, and millis below but it’s getting me tied in knots! Any help getting past this obstacle, and onto the next, would be appreciated.

Table table;
PFont f;
int previousDisplayTime;
int deltaTime;

void setup() {

f = createFont(“Arial”,16,true);
textFont(f,18);
fill(0);
fullScreen();
background (255);
Integer vertical = 25;
table = loadTable(“data.csv”, “header”);
line(width/2,0,width/2,height);

deltaTime = 2000;
previousDisplayTime = 0;

if (millis() > previousDisplayTime + deltaTime) {

for (int i=0; i<table.getRowCount(); i++){

  for (int j=0; j<table.getColumnCount(); j++){
  
    text(table.getInt(i,j), width/2-70+j*40,vertical);
  }
vertical = vertical+30;
}

}
}

Hello,

I suggest you start by working through the tutorials and examples here:

See the references for each function you are using and understand setup() and draw():


:)

Hi @luigipasto

Setup() runs only once, so it and only draws all at once when the code is completed.
draw() on the contrary is a loop that draws, when not specifically determined by frameRate(), or including timers, around 60 times per second. So the executing code with the timer you have to put there, in draw(). Reading the links provided above is really necessary to give you a more detailed explanation.

Hello,

You were given some pointers to start your journey.

In the future please format your code before posting:

https://discourse.processing.org/faq#format-your-code

Simplify it, understand it and then integrate code.

Try writing just a timer first.

Your example did not display text to screen as is.
This is a first pass at your efforts and formatted as an example of how to post code and do some debugging:

Table table;
PFont f;
int previousDisplayTime;
int deltaTime;

void setup() 
  {
  //f = createFont(“Arial”,16,true);  //Replaced
  //textFont(f,18); //Replaced:
  textSize(18);
  fill(0);
  //fullScreen(); //Replaced:
  size(400, 400);
  background (255);
  //Integer vertical = 25; //Why did you do this? Replaced:
  int vertical = 25;
  table = loadTable ("data.csv", "header");
  line(width/2,0,width/2,height);
  
  deltaTime = 2000;
  previousDisplayTime = 0;
  
  println("d1");
  
  //if (millis() > previousDisplayTime + deltaTime) //Try this uncommented
    {
    for (int i=0; i<table.getRowCount(); i++)
      {
      for (int j=0; j<table.getColumnCount(); j++)
        {
        text(table.getInt(i,j), width/2-70+j*40,vertical);
        }
      vertical = vertical+30;
      }
    }
  println("d2");  
  }

data.csv:

c1,c2
1,1
2,2
3,3

I then added a draw(), moved some code and was able to integrate a timer.
Your timer is not working yet.
Use some println() statements to see what your timer is doing.

Comment code with a // to help debugging; see my example.

This forum has plenty of timer examples to search for if you need some insight; I encourage you to try this on your own first.

:)

Thank you for your suggestions. The reason I wrote the code in the Setup() section is that the concept of 2 loops (getting values from tabular data) within a loop (Draw()) is really confusing to me. I’ll give it a try, and likely will return with more issues :slight_smile:

Some minimal modifications to get you started.

Uses frameRate(1).

Table table;
int vertical = 25;

int i = 0;

void setup() 
  {
  size(200, 200);
  fill(0);
  background (255);
  table = loadTable("data.csv", "header");
  line(width/2, 0, width/2, height);
  
  frameRate(1);
  }
  
void draw()
  { 
  background(255);  //Try it with and without background.
  
  //for (int i=0; i<table.getRowCount(); i++)
    {
    for (int j=0; j<table.getColumnCount(); j++)
      {
      text(table.getInt(i,j), width/2-70+j*40,vertical);
      }
    vertical = vertical+30;
    }
  
  i++; //Starts to replace the *for loop* but needs some work!
  }    

Use the table in previous example.
This will crash and you can add code to correct that.

:)

Thanks glv, I appreciate your help with this. I took your advice and completed started from scratch. The code now does everything I want it to do in the most simple way I can come up with, except the timing part. I’m playing with both millis() and your last suggestion of getting rid of a loop in draw() and using frameRate(). So far, no go. I’ll post my latest efforts sometime tomorrow for some more wisdom from the community. I’m spent now :slight_smile:

Hello,

There are many ways to do a timer and I have tried them all at one time or another.

You can use millis(), frameCount, Time & Date functions (see reference), counter, Java timer class, etc.

Slowing down frameRate us useful for slowing things down and I often use it for debugging or as required.

The default frameRate for draw() (stated in the reference) can be used as is or set and is used for animation or as required.

It is important to understand the flow of setup() and draw() before integrating a “timer” in your code.

Some good stuff here:

Example timer with millis():

You can add more println() statements to see value of variables as it progresses:

Timer < Expand for code
int whattimeisitnow;
int whattimeisitatstartofstopwatch;
int timepassedtoresetstopwatch = 1000;

//setup runs once
void setup()
  {
  whattimeisitatstartofstopwatch = millis();  
  println(whattimeisitatstartofstopwatch);
  }

//draw loops 60 frames per sec  
void draw()
  {
  whattimeisitnow = millis();
  if (whattimeisitnow > whattimeisitatstartofstopwatch + timepassedtoresetstopwatch)  
    {
    println("1000 ms have passed! Time elapsed (ms): ", whattimeisitnow);
    whattimeisitatstartofstopwatch = millis();                     //reset stopwatch and start over
    }
  }

:)

Table table;
int LineSpacing;
int interval;
int previousTime;
int currentTime;

void setup() 
{
  textSize(18);
  fill(0);
  size(500, 600);
  background (255);
  table = loadTable ("data2.csv");
  interval=2000; //2 second delay
  previousTime=0;
  noLoop();
}

void draw()
{
  LineSpacing=10;
  line(width/2, 0, width/2, height); //draw line down center of screen
  
  //currentTime=millis();
  //while (millis() - previousTime <= interval)
  //{
  //  // wait for interval value to be exceeded
  //}  
  
  for (int i=0; i<table.getRowCount(); i++)
  {
    for (int j=0; j<table.getColumnCount(); j++) 
    {
      text(table.getFloat(i, j), width/2-170+j*180, height-LineSpacing);
      if (j<1)
      {
        text("Latitude", width/2-90+j*110, height-LineSpacing);
      } else
      {
        text("longitude", width/2-15+j*110, height-LineSpacing);
      }
    }
    if (height-LineSpacing<=0)
    {  
      background(255);
      LineSpacing=10;
      line(width/2, 0, width/2, height);
    } else
    {
      LineSpacing = LineSpacing+25;
    }
  }
}

data2.csv contains 2 columns of numbers and any number of rows.
The code actually does what I want, except for the timing. It reads from data2.csv, then sends one row at a time to the screen and formats. You’ll note that I added noLoop() to the setup(), as the looping in draw() is killing me. I want the code to go through the tabular data once and write to screen each row one at a time. Without the noLoop() the font gets darker as the code is run repeatedly in draw(). I’ve tried the different strategies proposed, the commented section is my last attempt (failure). The delay is added at the begining but then the rows all appear at the same time. I’m lost!

By the way, you’ve been extremely patient with me, and I am appreciative.

A delay and a timer are two different things.

I provided an example that slows down the frameRate to 1 fps (frame per second) to allow you to see what is happening.

You can use the default frameRate which is 60 fps and a timer of your choice to increment the i variable every 2000ms.

In my previous example the variable i is no longer in a for loop so you have to add some code to test for conditions:

if (i>=5)
{
i = 0;
noLoop();
}

This is your project and I am working with your code.

There are many ways to work with tables and timers; you have to start slowly and build on that.

See the processing website for references, tutorials and examples:

And the Coding Train may have a tutorial.

:)

If you do not clear the background at the start of each loop() if will continue to paint over it (keep adding to canvas) and start to do this. It does not draw perfectly over each frame with each cycle of draw() and appears to get darker.

Read this to understand:

It takes a while to grasp the flow of setup() and draw() for new programmers.
You just have to work through this.

:)

If I clear the background will I loose the last row printed to screen? I need the rows to cumulate one at the time from the bottom of the screen to the top. I may be misunderstanding a lot here.

Regarding delay vs timer, I considered that a delay of a specific time is a timer. I’m not sure how these are different conceptually but of course I believe you that they are different in code. I’ll keep thinking about this…

Yes

Example 1 with frameRate(1) and no background
int sec = 1;
int y;

void setup()
  {
  size(300, 300);
  frameRate(1);
  background(255); 
  }
  
void draw()
  {
  //background(255);  //Try with and without background()
  println("f: ", frameCount);
  
  //for (int y=0; y<5; y++)   //rows
      {
      for (int x=0; x<5; x++)    //columns
        {
        //println(x,y);
        String s = str(x) + ", " + str(y); //x and y in a string for text()
        
        //text
        fill(0);
        textSize(16);
        textAlign(CENTER, CENTER);
        text(s, 50*x+50, 50*y+50);  //Spacing and offset
        
        ///point
        stroke(255, 0, 0);
        strokeWeight(2);
        point(x*5, y*5);
        }
      }
  
  y++;   //Will keep incrementing each draw() cycle; needs some code to set a limit.
  println("y: ", y);
  
  if (y>=5) 
    {
    y = 0;
    noLoop();
    }  
  }
Example 2 with frameRate timer and a background
int sec = 1;
int y;
int yLimit = 0;

void setup()
  {
  size(300, 300);
  //frameRate(1); //Default is 60 when this is commented
  background(255); 
  }
  
void draw()
  {
  background(255);  //Try with and without background()
  println("f: ", frameCount);
  
  if (frameCount%60 == 0) //This is the modulo operator
    {
    yLimit++;  
    println(yLimit);
    if (yLimit>=5) 
      { 
      noLoop();
      }
    }
  
  
  for (int y=0; y<yLimit; y++)   //rows
      {
      for (int x=0; x<5; x++)    //columns
        {
        //println(x,y);
        String s = str(x) + ", " + str(y); //x and y in a string for text()
        
        //text
        fill(0);
        textSize(16);
        textAlign(CENTER, CENTER);
        text(s, 50*x+50, 50*y+50);  //Spacing and offset
        
        ///point
        stroke(255, 0, 0);
        strokeWeight(2);
        point(x*5, y*5);
        }
      }
  
  //y++;   //Will keep incrementing each draw() cycle; needs some code to set a limit.
  //println("y: ", y);
  
  //if (y>=5) 
  //  {
  //  y = 0;
  //  noLoop();
  //  }  
  }

Delays should not be used in draw():

Use a timer and time events to update as required.

Try to integrate a millis() timer.

Use println() statements to see variables as code is executed.

Timer examples:

Note:
timer = millis() should also be in setup() in Amnon examples above; if you use a println() to see value you will see why.

:)

A simple countdown/delay library: :stopwatch:

It’s a wrapper for class TimerTask:

Thanks again. I think I’ll put this aside for a few weeks and come back to it when my mind is a little clearer. I have 120 term papers to correct and I’m not looking forward to it…

Thanks again for all you suggestions.