Go Down

Topic: LCD Bitmap - Updated v1.6 (Read 8374 times) previous topic - next topic

fm

#15
May 03, 2012, 10:49 pm Last Edit: May 04, 2012, 09:24 am by fm Reason: 1

Range checking was not done to make it faster and smaller.  What I figured is with only 20x16 pixels, it should be kind of hard to get too crazy anyway.  But, if range checking doesn't add much to the code, it would be a simple process to add.

That shouldn't add to much code, the only place that is needed is to avoid a division by zero which would cause the AVR to crash.

This is kind off in the line method, a simple if ( ( x2 - x1 ) == 0 ) to avoid the division by 0. One thing that strikes me is why do you use a float in the line method? You should be able to get away with just using a uint8_t or byte and would avoid having to pull in the floating point library.


Quote


Quote from: fm
modify the magic numbers that you have about the code by defines, #define BITMAP_X_SZ  20


I don't exactly follow what you mean by this.  Do you mean don't use 20, 16 and 8, etc. as they repeat in many places but instead use a define instead?  I assume the reason is for memory or speed for micro controllers?  

This is a bit more for clarity, readability and maintainability. It will not add any speed improvements, nor additional code but it will make things a bit easier to follow. For example:

Code: [Select]

byte chr[8][8];


by

Code: [Select]

#define USER_DEF_CHARS    8   // Number of LCD user defined characters
#define USER_CHAR_LEN     8   // Bitmap length for each LCD user defined character

byte chr[USER_DEF_CHARS][USER_CHAR_LEN];
...

for (byte c=0; c<USER_DEF_CHARS; c++)
{
  for (byte a=0; a<USER_CHAR_LEN; a++)
  {
     chr[c][a]=OFF;
  }
}


As I said, just being picky here.

Quote

Years of being the only programmer on projects had resulted in poor comment skills.  I typically don't add comments unless it's for me to remember how I did something.  It's hard for me to even read code with comments in it.  I typically remove comments from other people's code so I can see what is going on.  With that said, yes, I probably need some comments here and there.

I guess it is to help future users more than anything.

Quote

I downloaded and installed tortoisehg last night but haven't had a chance yet to look at it.  I sure hope it doesn't update the code on the site till I tell it to because I'm one to change source 500 times a day, delete entire pieces of code, rewrite it a different way, then erase everything and go back the way it was.

Nothing gets pushed to the repo unless you tell it to. The nice thing is that you can work on a file or two and if you don't want to commit the changes you can alway go back to the previous version. I think is a nice thing to use even for home hobby project.

The only optimization right now, is to save a bit on memory by having a true byte bitmap, nothing much.

I would remove from the examples, or from the library begin method, the duplicate, lcd.clear, ... In any case, when the LCD is initialized the screen is cleared, with no cursor, and with no blinking either. But that is not any performance improvement in the sense that the it is only done during initialization.

As an update, I have tried it on my LCD I2C backpack, it is not as speedy but the animations work great.
   

I'll try range checking to see what kind of hit it takes.

Quote from: fm
One thing that strikes me is why do you use a float in the line method?


Float is used to make a diagnal line.  If you dont use a float, the line won't be drawn on the correct path.  Because the pixels coordinates are so small I could use a different technique while still staying with a single byte variable.  I'll try it out and see how it works.

While adding comments I'll change the "magic numbers" to named constants for clarification.  Never heard the term "magic numbers" before, but I now get your meaning.

Your other suggestions are also being addressed.  Thanks!

Tim
Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

bperrybap

#17
May 05, 2012, 01:18 am Last Edit: May 05, 2012, 03:16 am by bperrybap Reason: 1
You could try the DrawLIne() function from the glcd library.
It is in the glcd.cpp module.
http://code.google.com/p/glcd-arduino/source/browse/trunk/glcd/glcd.cpp

Just modify the code to use your bitmap[][] array instead of calling SetDot()

--- bill

Update:

Curiosity got the best of me.
The glcd library DrawLine() function drops in and seems to work ok (at least for the demo code)
to replace the line() function.
It saves around 1600 bytes as it does not use floating point.
Tim, if you want it, PM me your email address and I'll email you code.

--- bill

robtillaart

Quote
Float is used to make a diagnal line.  If you dont use a float, the line won't be drawn on the correct path.  Because the pixels coordinates are so small I could use a different technique while still staying with a single byte variable.  I'll try it out and see how it works.


check - http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

bperrybap


Quote
Float is used to make a diagnal line.  If you dont use a float, the line won't be drawn on the correct path.  Because the pixels coordinates are so small I could use a different technique while still staying with a single byte variable.  I'll try it out and see how it works.


check - http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm


That is the algorithm the glcd library uses for its DrawLine() function, which is what I pulled into
the bitmap library. It saves 1600 bytes of code since it does not use floats.

--- bill



Quote
Float is used to make a diagnal line.  If you dont use a float, the line won't be drawn on the correct path.  Because the pixels coordinates are so small I could use a different technique while still staying with a single byte variable.  I'll try it out and see how it works.


check - http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm


That is the algorithm the glcd library uses for its DrawLine() function, which is what I pulled into
the bitmap library. It saves 1600 bytes of code since it does not use floats.


I'm more of a "roll my own" type instead of just pulling code from others.  My goal is to build something unique, not copy something existing.  I know others have other goals.  I appreciate everyone's suggestions, and the tip that using a float wastes a lot of code space was a very helpful.  I've modified my code to not use the float and use my own line algorithm and saved 1,820 bytes.  I may look at Bresenham's line algorithm to see if it yields any further speed or program size reduction.

I've also removed the "magic numbers", added a range checking option, and modified the code so it should work with 7 pixels high character displays (don't have one to test however).  Version 1.2 should be released shortly.

Tim
Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Version 1.2 released - Changes:

From the suggestion of Francisco Malpartida and bperrybap (author of the Graphical LCD library) I removed the float variables in the line function which reduced the compile size by 1820 bytes.  Also did some speed tweaks, added an option for range checking, and removed the "magic numbers".  Finally, I believe it now will work with 7 pixels high character displays (change the BITMAP_CHAR_H define to 7).  I don't have a display like this, so if someone can test and let me know that would be great.

Download LCDBitmap v1.2
Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

bperrybap

Something seems to have gone wrong when creating the v1.2 zip image.
The directories and file names in the zip image have CPM/DOS backward slashes in
their names rather than have subdirectories and files within the sub directories.

The previous 2 zip images were not like this.

--- bill


Something seems to have gone wrong when creating the v1.2 zip image.
The directories and file names in the zip image have CPM/DOS backward slashes in
their names rather than have subdirectories and files within the sub directories.

The previous 2 zip images were not like this.

--- bill


Strange, it works fine for me and all my ZIP apps show the files and directories in the same way.  Even old DOS PKUNZIP and Unix unzip extracts the files without a problem for me.  I created it on the same Windows 7 system as the previous releases.  The only thing I did differently was after I created the ZIP file I deleted the .hg directory and .hgignore file created by the Hg app.  What OS are you running?

Tim
Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

bperrybap

Something is very odd.
It works ok with Win7 (which I would expect). It also works with XP file manager and on XP using 7zip.
It does not work with Ubuntu 10.10 using Nautilus which uses the Gnome archiver File Roller v2.32.0
It does not work with Mint 11 using Gnome Archinve File Roller v2.32.2
It does not work with 7z  (from pk7zip-full version 9.04-dfsg.1.1 debian package) using the command line on Ubuntu.


Note: When I say "does not work" I mean that the files end up with backward slashes in them when viewing them
in a GUI and when extracted rather than shown/extracted in directories and subdirectories.

But the v1.1 zip works just fine.

--- bill

My guess is that it had something to do with deleting the files post ZIP file creation.  I'll delete the files first, then create the ZIP.  This time I'll also create the ZIP on my retro Windows 98 machine in my kitchen (had a 20 mile run today so I really don't feel like climbing the stairs to my office).  It's available for download (v1.2a).

On a side note, I looked at your source for the line function and the Bresenham's line algorithm.  It's surprisingly similar, except how I did the error correction with oversampling instead of using a float.  I played with the Bresenham's line algorithm that doesn't swap variable values and it's very fast and saves code size as well.  You may want to consider implementing it in your line code also as you're still using swaps.  You should also see a significant speed increase and reduced code size.  I need to test it out more, but I'll probably be adding it to v1.3.

Below is the code I'm experimenting with in my line code, it's probably easier to implement than the code on the Wiki site:

Code: [Select]

void LCDBitmap::line(byte x1, byte y1, byte x2, byte y2, boolean color, boolean update) {
#ifdef BITMAP_RANGE_CHK
  LCDBitmap::valueCheck(x1, y1, x2, y2);
#endif
  byte dx, dy, sx, sy;
  int err, e2;
  dx = abs(x2-x1);
  dy = abs(y2-y1);
  err = dx-dy;
  if (x1 < x2) sx = 1; else sx = -1;
  if (y1 < y2) sy = 1; else sy = -1;
  while (1) {
#ifdef BITMAP_RANGE_CHK
    LCDBitmap::rangeCheck(x1,y1,color);
#else
    bitmap[x1][y1]=color;
#endif
    if (x1 == x2 && y1 == y2) break;
    e2 = 2*err;
    if (e2 > -dy) {
      err = err - dy;
      x1 = x1 + sx;
    }
    if (e2 <  dx) {
      err = err + dx;
      y1 = y1 + sy ;
    }
  }
  if (update) LCDBitmap::update();
}


Also, for your variable swap you may want to use a^=b^=a^=b;  Maybe slightly faster, and I'd guess it saves a little code size without the third variable needed.
Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Version 1.3 released:

Many performance tweaks and reduced compiled code size. Optimization were enough to deprecate the lineHor and lineVert commands.  Both functions still work, there's just no longer any advantage in using them.  Thanks to robtillaart for suggesting the Bresenham line algorithm.  Modified range checking removing redundant checks.  Added new function barGraph that easily creates a 1 to 20 bar graph.

Be sure to check out the new example code that better show the functions and speed of the library.  I'll also update the video to show the new example code.

Download LCDBitmap Library v1.3

Tim Eckel
Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

fm

I'll give it a shot and let you know how it looks.

Cheers

fm
   

Version 1.4 was released, this release includes the following:

Fixed a few problems with the barGraph function. Further optimization with the range checking. Compatible with Arduino 0023.

Download LCDBitmap Library v1.4

Let me know if there's any issues or suggestions.

Tim
Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

fm

Hey Tim, that rocks, thanks for sharing.
   

Go Up