Pro: Too slow code, please advice Speedimprovements.

Dear Community,

i am trying to make usage of Putty / Xterm 256 Color ANSI Escapecode-Mode and so on eg. Cursorlocating…, to get an improved Monitorcapabilities.
Maybe, somewhere in Future this could be a “ARTduino-Library” (related to ANSI-ART), but i worked only one day to get the following/upper result.

Its the base of my testing nothing more. I got a RGB Function which works to, but till now, there is a Speedproblem in my coding.

I think the IDE-Serialmonitor is a little bit slimed down, scrolling informations, overflowing on high speed on my mashine, Black and white… all in all in my opinion,
this could be slightly better… so yesterday i began to play around with putty terminal basics.

So i think a library in far future is a good attempt to get visual output a little bit better… maybe… i think there are many oppinions out there.
But also Putty/Xterm/etc. are compatible clients on MacOSX, Linux, Windows… Multiplatform, multicapability.

Ok, lets start:

I hacked a lousy code, to get an 46 Grayscale ANSI-Art, for Speedtesting,…
the result is a little bit frustrating… displaying it takes on my mashine 7 seconds.

I Tested some runs, and one of the bottlenecks is definitly the usage of Arrays, Strings, CharByChar translating.

I want to invest some much more time in this, but i think i have to speed up the basics at first.

I hope, somebody out there could please give me some hints, some improvements to make my attempt worth to go further.

I know, this isn’t a good code, but maybe some tipps could help to get it faster… and better.

int count=0;               // Multipurposecounter
int terminalheight=0;   // Lines in Terminal
int terminalwidth=0;    // Colums in Terminal
int asciiencodedvalue;  // Variable which holds the ASCIIval
String writebuffer;     // Serialwritebuffer storing 560 Chars
int buffercount=0;      // Counter to count chars in Buffer
int t1;

void setup() {
  Serial.begin(115200);
t1=millis();
  for (terminalheight=0;terminalheight<=28;terminalheight++){
    String actualsign=String(background[terminalheight]);
    for (terminalwidth=0;terminalwidth<=79;terminalwidth++){
      asciiencodedvalue=actualsign.charAt(terminalwidth);
      asciiencodedvalue=asciiencodedvalue,DEC;
      printgrayshade(int((asciiencodedvalue-35)/1.3)+1);
    }
  }
Serial.print(((millis()-t1)/100));

}

void loop() {
}

// simple output of black->white shades
// used a 560 Charbuffer in the hope to improve Speed

void printgrayshade(int grayvalue){
  writebuffer += gray[int(grayvalue)];
  buffercount++;

  if (buffercount==560){
    Serial.print(writebuffer);
    delay(50);
    writebuffer="";
    buffercount=0;
  }

}

Thank you for your attention.

Greetings
ChrisS

What is this line supposed to be doing?

      asciiencodedvalue=asciiencodedvalue,DEC;

My guess is that it is not doing what you think it is.

  writebuffer += gray[int(grayvalue)];

grayvalue is already an int. There is no reason to use the int() macro to cast it to an int.

The types of too many of your variables, like writebuffer, are undefined for us to be able to make any valid recommendations for ways to speed up the code.

The += in the statement, though, implies that writebuffer might be a String object. If that is the case, you might want to look at what that operator is actually doing.

A String object has a fixed amount of memory associated with it. When the memory is filled, more memory is allocated, the entire object is copied to that new location, and the original space is freed. Slow.

Using char arrays directly would be much faster.

I Tested some runs, and one of the bottlenecks is definitly the usage of Arrays, Strings, CharByChar translating.

I doubt that arrays are the bottleneck. Strings, most definitely.

Serial.print(((millis()-t1)/100));

millis() returns elapsed time since reset in milliseconds. Why are you dividing by 100, rather than 1000?

Wow, that are many hints.

Thanks for that.

I havn't posted complete code because it's big, and much memory consuming at the moment. I wont that any newbies upload and crash/hang their arduino.

You are right, dividing by 100 is a false i made last before i posted... shame ;)

Ok, the other things i will try, and measure the timeimprovement.

Really, thank you very much for this hints.

Greetings ChrisS

Can you just double check you aren't being limited by baud rates? (You can do this quickly by lowering the baud rate from 115200 to 57600. If your program now takes twice as long, you are limited by your baud rate. If it is the same speed, you are probably being limited by the String class being slow)

I say this because 115200 baud is 11520 characters per second (each character takes 10 bits - start bit, 8 data bits, stop bit). But an ASCII grayscale escape sequence takes 12 or more characters to send. So that slows you down to less than 1000 greys per second, and a terminal screen can be 2000-5000 character cells or more, so it's never going to get faster than 2 seconds just because of the baud rate.

A good and a bad news... :)

The good one is, removed the writebuffer completely... PaulS gave the hint of slow Strings... so i got rid of that for testingpurposes. And now displaying took 3 seconds.

The bad One, ahm, tested on 19200, it tooks about 70 seconds. It semms to be no Baudrateproplem. So, result for now... it seems that speed is nearly at maximum, and this Test"picture" is very complex and big in Sequence.

So maybe 3 secs are ok... mmh, but waiting of it is little bit anyoing.

Thougt that a softwarebuffer which stores bigger chunks of the ansisequence has to be faster than printing char by char.

I will test now if i got something like an arraybuffer working.

Another possiblility is use one color and jump from "thiscolor"-destination to the next, because Cursorlocating is a littlebit slighter than changing fore and Backgroundcolor.

Thank you...

Greetings ChrisS

Thougt that a softwarebuffer which stores bigger chunks of the ansisequence has to be faster than printing char by char.

The data is still pushed out the serial port one byte at a time.

Think of it liking a shipping department. Each package that goes out is exactly the same size, and handled in exactly the same way. It doesn’t matter whether stuff arrives in the shipping department one package at a time, delivered by hand, or a whole pallet full, delivered by a forklift. The deliverer can not leave until the last package is accepted, whether that is one package or a pallet full being unloaded one package at a time.

The best you can do is improve the shipping personnel, which corresponds to increasing the baud rate.

Dear PaulS,

ok, then i don't have to do the array-writebuffer.

mmh, i will append the sketch for improvement testing by interessted people. To get this work, you have a 256-Color able Terminal-Client like Putty. Connect it to the Serial. Ahm, on your hardware you have to move the setup source into loop maybe. On my, i use RESET to refire the sketch. (So it's not looping in default).

ATTENTION! I don't know how it behaves on smaller memory... maybe your mcu / arduino hangs after booting. Solving is to reboot, and programm it with another sketch right at/after boot so the old sketch isn't able to run before reprogramming.

Actually this is a test, so there is no Linefeed. Terminal has to be 80 Chars wide or you will get many Trash on Screen ;)

ARTDUINO-STAGE0 ;) http://www.sturmfabrik.de/privat/ARTDUINO_STAGE0.pde

Greetings ChrisS

Ok, improved speed to 2secs.

I think this is 5secs less than 7 ;)

Done with something like an RLE... "if got the color in the last Pixel, simply do a space, instead of redefine color and output it".

Hello out there? I have no clue to get the charAt function for direct array usage. Howto?

Ahm, in the farest place in my brain... there could be somthing like a pointer to get single chars of an array?

ARTduino Stage0.1 http://www.sturmfabrik.de/privat/ARTDUINO_STAGE0_1.pde

Improvement: - Speed: 3 -> 2secs - No colorredefinement if not neccessary - Newline (Terminalsize doesn't matter any more)

Enough for today... tommorow the sun will be shine again... Thank you for support my idea.

Greetings ChrisS

Dear community, another day another error :slight_smile:

I have done the first steps in RGB and GrayRamp conversion.

But now, i have a bug i don’t see in Source.

How it looks like:

You will recognise, that the BLUE value increases in the second ramp well, but does not effect yellow in the first ramp. YELLOW HAS TO TURN WHITE ALSO.

I can’t see the bug in coding. PLEASE help.

int counter;

void setup() {
  Serial.begin(115200);

  for (counter=0;counter<=5;counter++){ 
    foreground(counter,0,0);
   }

  for (counter=0;counter<=5;counter++){ 
    foreground(5,counter,0);
  }

  for (counter=0;counter<=5;counter++){ 
    foreground(5,5,counter);
  }

  Serial.println("");

  for (counter=0;counter<=5;counter++){ 
    foreground(counter,0,0);
  }

  for (counter=0;counter<=5;counter++){ 
    foreground(5,0,counter);
  }

  for (counter=0;counter<=5;counter++){ 
    foreground(5,counter,5);
  }

}

void loop() {
}

void foreground(int foregroundr,int foregroundg,int foregroundb){
  char buffer[24];
  if (foregroundr&&foregroundg==foregroundr){
    if(foregroundr&&foregroundb==foregroundr){  
      sprintf (buffer, "\033[38;5;%dm", (foregroundr+232));
    }
  }
  else
  {
    sprintf (buffer, "\033[38;5;%dm",(16+((foregroundr*36)+(foregroundg*6)+foregroundb)));
  }
  Serial.print(buffer); //Set the color

 // Debugoutput
  Serial.print("RGB [");
  Serial.print(foregroundr);
  Serial.print("] [");
  Serial.print(foregroundg);
  Serial.print("] [");
  Serial.print(foregroundb);
  Serial.println("]");
}

PS: I know, the 5,5,5 Value is not ready at all, related to the grayramp of 23 colors instead of 6,this is acepted at the moment.

Greetings
ChrisS

Sorry I got it, Grayramp-Syntax messed it up.

Stay tuned! :)

Greetings ChrisS