Any way to speed up this ASCII art clock on Raspberry Pi

Hi

I have this ascii art clock working. The point of the project is to run it on a raspberry pi with a phone sized screen and make it into a bedside clock with a concrete enclosure.

Sadly it runs quite slowly on the pi 4. Can anyone suggest any ways to speed the code up? Or am I just at the limit of processing on a pi?

The pi is running regular 32 bit raspian and I downloaded the processing install from here. The premade image for pi doesn’t work on pi 4.

int sw = 1920;                      // screen width
int sh = 1080;                      // screen height
int bw = 165;                        // number of characters in x (buffer width)
int bh = int(float(bw) * 0.5625);   // number of characters in y (buffer height)
float r = 0;                        // for rotations
PGraphics pg;
String chars = "   .o**OX@@";  // the pixels will be mapped to these characters by brightness
float factor;

int ts;                             // text size of pre render clock

float tw;                           // text width of pre render clock
float th;                           // text height of pre render clock
String time;
float rotate;
float rotate2;

float p;
//float q;

Boolean init = true;

void setup() {

  size(1920, 1080, P3D);
  //fullScreen(P3D);

  pg = createGraphics(bw, bh, P3D);
  factor = sw/bw;

  ts = int(float(bw)*0.35);
  textSize(sw/bw);
}

void draw() {

  background(0);
  drawText();

  pg.loadPixels();

  int c = 0;


  // iterate through pixels and map to characters

  for (int i = 0; i < bh; i ++) {
    for (int j = 0; j < bw; j++) {
      p = brightness(pg.pixels[c])/255*9;   // map the brightness value to something we can index the string with
      char l = chars.charAt(int(p));  // find the char at that index of the string
      text(l, j*factor, i*factor);          // draw that char at the right location
      c++;
    }
  }
}

void drawText() {

  pg.beginDraw();
  
  if (init) {
    pg.textSize(ts);
    tw = pg.textWidth(hour() + ":" + nf(minute(), 2));
    th = pg.textAscent()+pg.textDescent();
  }
  
  pg.background(65);
  pg.translate(bw/2, bh/2);
  time = hour() + ":" + nf(minute(), 2);
  rotate = sin(r*0.01);
  rotate2 = sin((r+0.5)*0.015);
  //pg.rotate(radians(rotate*15));
  pg.rotateY(radians(rotate*35));
  pg.rotateX(radians(rotate2*35));
  pg.text(time, -tw/2, th/4);
  r += 1;
  pg.endDraw();
  pg.filter(BLUR, 1);
}

Thanks!

Hello @arcadeperfect ,

I did some tests on my Windows 10 PC.

This is a cool effect but reduces frameRate:
pg.filter(BLUR, 1);

I tried a pseudo blur with:

pg.textSize(ts/5);
//...
pg.translate(bw/2, bh/2);
pg.scale(5);

I added this to see the image to get a sense of blur before processing:
image(pg, 0, 0);

You could set this after you initialize:
init = false;

I replaced your brightness with this to do only integer math:
int r = 9*(pg.pixels[c] & 0xFF)/255;

That’s all I got for now…

:)

1 Like

Ha whoops the whole point of that init condition was to set it to false after it ran… somehow I forgot to include that crucial line…

Thanks for the suggestions will test!

Hello @arcadeperfect ,

This is what I use (or some variation) to test performance:

void setup() 
  {
  size(200, 200);
  frameRate(60) // This is default on my PC and my monitor refresh rate
  //frameRate(500); // I set this higher for *testing only* to see what elements of code slow things down. 
  }

void draw() 
  {
  background(0);
  if(frameCount%15 == 0) //Every 15 frames
    {
    surface.setTitle(str(int(frameRate)));
    println(frameRate);
    }
  }

:)