Live updating counter (need to use strings or array?)

Hello,
I’m having some trouble figuring out how to make a simple number counter that is connected to events in airtable.
Basically, i have a table which tracks at what time an event occured and i would like to have a counter appear in processing which counts each time that happens. So, say an event occured at 13:23, the counter in processing will show the number “1”, then at 14:30 another event occurs so the counter will increment +1 and show “2” and so on.

I found a code that works well for when you mousepressed

int score = 0;

PFont counter;

void setup (){
  size(574, 323);
  counter = createFont("Arial", 72, true);
  noLoop();
  smooth();
} 
 
void draw() {
  background(0);
  textFont(counter, 72);         // Specify font to be used
  fill(#ffffff);                // Specify font color 
  text(nf(score, 1), 125, 175);            // Display Text and Location
}

void mousePressed() {
 
  score = (score + 1);
  redraw();
  
}

but now i need to integrate it in a complicated code so that instead of updating when you press your mouse, it updates once an event in airtable is fetched. i think this is where i need to integrate something, an array? a string? using the “if()” function.

void forward() {
  if (selectedEvents.size() > 0) {
    println(frameCount + " PLAY");
    if (enemyPos < selectedEvents.size()-1)
      enemies.get(enemyPos).show = true;
      
    enemyPos ++;
  }

  if (currentDateTime >= starting_date.getTime() && currentDateTime < (starting_date.getTime() + oneweek_ms) - modeMS[mode]) {
    currentDateTime += modeMS[mode];
  } else {
    currentDateTime = starting_date.getTime();
  }
  reset();
}

So i thought of making a class

class AgeCounter {

    int num = 0;
  PFont agecounter;



  AgeCounter(int _num) {
    // Constructor
    num = _num;
  }

  void update() {
    num = (num + 1);
  redraw();
  }

  void display() {
    agecounter = createFont("Arial", 20, true);
  noLoop();
  smooth();
    
    textFont(agecounter, 72);         
  fill(#ffffff);               
  text(nf(num, 1), 125, 175);
    
  }
}

but now i don’t know if this is the right way to go about it because i don’t know if i should make use of an array or a string?
I hope i was clear enough in my question and that i put the right snippets of code for you to understand what my problem is haha ^^’ i’m sorry i don’t think the code is testable because otherwise i would have to upload the whole sketch which contains several classes and a lot of lines of code. however if you deem it necessary i’ll do that, no problem.
thanks in advance to anyone who replies,
Please help me T_T

I don’t know if I understand well, but let’s create an event with a thread() and just add a counter something like this. Where do you want to go from here?

long count;
String data = "";

void setup() {
  size(500, 150);
  textSize(18);
  start_time = millis();
}

void draw() {
  background(0);
  if (frameCount % 30 == 0) {
    thread("requestData");
  }
  text("Incoming data = "+data+"       Count: "+count, 50, 50); 
}

void requestData() {
  if(millis() - start_time > random(1000, 5000)) {
    count++;
    start_time = millis();
    data = "Xx"+random(100, 10000);
  }
}

Hi! thanks for replying!!

for what i need i think i would need to replace the

(frameCount % 30 == 0)

(every 30 frames it requests a new data if i understood well?? so in your code, the counter updates +1 every 30 frames, right?) with a function that could fetch data from an external source.

I tried to input your code in mine and it is working except the counter goes up very rapidly, like +50 at a time.

Here’s what i changed (selectedEvents is the array that is supposed to allow me to fetch the data from airtable i think)

void draw(){

if (selectedEvents.size() > 0) {
  thread("requestData");
}
text("incoming data= "+data+"   Count: "+count, 100,300);

}



void requestData() {
  
  //Parcourir les enregistrements 
  
 if(millis() - start_time > selectedEvents.size()) {
   
   count++;
    start_time = millis();
    data = "Xx";
   }
  
  
}

i don’t know if this has anything to do with it but would you mind explaining what the start_time is needed for?
btw i’m really sorry if this seems very convoluted and all im very new to processing and this is for a school project so the teacher did most of the coding and now i’m trying to figure some stuff out without having him do all the code ^^’

No, only when an event occurs. In my example a timelapse. thread() is often used for big file loading or long time taking events. It runs independently from draw(), but in draw() you can on a regular basis check if an event occurred, and then, when occurring, add one to the counter. This way you can run your other code in draw() at normal speed. The (frameCount % 30 == 0) is just a choice on what regular basis you check.

This is just a simple timer. Run this code and I think you’ll understand.

int x = 0;
int time_interval = 1000;
int start_time = 0;

void setup() {
  size(100, 100);
}

void draw() {
  if (millis()-start_time >= time_interval) {
    start_time = millis();
    println(x);
    x++;
  }
}

Maybe I understood wrong what you want. You want just to count when a value is reached in your table?

int m, h; 

void setup() {
  size(100, 100);
}

void draw() {  
  if (frameCount % 30 == 0) {
    m = minute();  
    h = hour(); 
    if (h == [value of your table list in hours] &&
      m == [value of your table list in minutes]) {
      count++;
      text("Count: "+count, 50, 50);
      // code to step one further in your table
    }
  }
}

yes, that’s what i would need…
Screenshot_2020-12-23 test Event - Airtable(1)|390x500
this is what the table looks like, and i already have the selectedEvents array that i can use to fetch those datas.
However i do not understand how that would work with the code you wrote here :thinking: would i need to calculate the ammount of time between the first value in the table and the last?
The other code you wrote the first time works well though!

I found out what was causing the couter to jump from 50 to 50, it’s because it is related to an int = 50 that is used with a frameCount to define at what speed the animation i have will play… i’m guessing there’s some sort of overlap problem? Would there be a way to separate the frameCounts and make them independent?

int playSpeed = 50;

void UpdateUI () {
if (frameCount % playSpeed == 0 && play)
    forward();
}

this is what’s controlling the animation speed. I think i can describe it as what is controlling the speed at which the program is going through each minute of the day to fetch the datas in the airtable.
i’m not sure if that’s very helpful to you haha… at least it means nothing to me ^^’ but just in case you recognize something.
Otherwise, you’ve already been a great help, thank you so much!!

Before going further I need more details. You are talking about an Airtable, which can be a very complex one with a great variety of different objects. On the other hand, you gave a link to a very simple database image, It would be very simple to make a counter that ticks on each time moment given in that table. But I need to know exactly the type of table that the program will access.

okay… so it’s a simple table which creates a new event everytime i press a widget on my phone. It gives details about how many times the widget has been used (ID), the time and date each event occured at (timestamp) and my location in latitude and longitude (i didn’t include those in the screenshot though so as to not give away where i live lol).
so i used the field types in airtable to automate that process of event creating. ID is “autonumber”, timestamp is “createdtime” and latitude and longitude is “latitude” and “longitude” respectively.

Well if you can’t give the link to your table let’s create a very simple csv table.
Just save this text in a file and give it the name “new.csv”

id,timestamp,name
0,24/12/2020 12:34 pm,Robert
1,24/12/2020 12:35 pm,Noel
2,24/12/2020 12:36 pm,Codestruggles

The following code is a very simple example, and of course, for a real working code, you’ll need a far more complex string search. Modify the timestamp to a time close to testing and add the time you are willing to wait to see the code working. The frameCount part is just to avoid the processor working all the time.

Table table, table1;
int y, m, d, h, mnt, yt, mt, dt, ht, mnt_t;
String str = "Waiting first message";
String id ="";

void setup() {
  size(500, 200);
  textAlign(CENTER);
  textSize(28);
  table = loadTable("new.csv", "header");
  println(table.getRowCount() + " total rows in table");
  for (TableRow row : table.rows()) {
    int id = row.getInt("id");
    String timestamp = row.getString("timestamp");
    String name = row.getString("name");
    println(name + " (" + timestamp + ") has an ID of " + id);
  }
}

void draw() {  
  background(255);
  fill(0);
  if (frameCount % 30 == 0) {
    y = year();
    m = month();
    d = day();  
    h = hour(); 
    mnt = minute();
    for (TableRow row : table.rows()) {
      String timestamp = row.getString("timestamp");
      // Split the timestamp in its components  
      dt = int(timestamp.substring(0, 2));
      mt = int(timestamp.substring(3, 5));
      yt = int(timestamp.substring(6, 10));
      ht = int(timestamp.substring(12, 14));
      mnt_t = int(timestamp.substring(15, 17));
      id = row.getString("id");
      if (d == dt && m == mt && y == yt && h == ht && mnt == mnt_t) {
        String name = row.getString("name");
        str = "Count: "+id+"    Name: "+name;
      }
    }
  }
  text(str, width/2, height/2);
}

uhh i don’t understand how to change the timestamp and where to add how long im willing to wait for the code to work…? ^^’ or what you mean by splitting the timestamp in its components…
(im so sorry i feel like im taking so much of your time)

imagining we have dates going from 15/12/2020 12:34 to 24/12/2020 13:23, would it be more like

dt = int(timestamp.substring(15, 24));
      mt = int(timestamp.substring(12, 12));
      yt = int(timestamp.substring(2020, 2020));
      ht = int(timestamp.substring(12, 13));
      mnt_t = int(timestamp.substring(34, 23));

or more like

dt = int(timestamp.substring(1, 5));
      mt = int(timestamp.substring(1, 2));
      yt = int(timestamp.substring(0, 2));
      ht = int(timestamp.substring(1, 3));
      mnt_t = int(timestamp.substring(2, 4));

since it uses only the numbers used to check the time between each “event”? Or nothing like that at all?? I was confused because the 15,17 for mnt_t returned “StringIndexOutOfBoundsException: String index out of range: 17”

by the way, Merry christmas if you celebrate that, and happy holidays if you don’t!

If you use the format exactly as written in this table the code works perfectly. (Same spaces etc.) To test it, you set the time a minute or two later. When I was testing this table, for example, the time was12:32 hrs. I saved the csv file and ran the program. I could have added more time by setting the order for instance 12:34 12:38 12:42 When these times occur the name of the person on that row will appear on the screen with the count number. (Set also the correct date!)
You will need to learn and read about more in the links below. Merry Christmas to you as well. :evergreen_tree: