Pages: [1]   Go Down
Author Topic: Generating barcodes on LCD display  (Read 2064 times)
0 Members and 1 Guest are viewing this topic.
Washington
Offline Offline
God Member
*****
Karma: 30
Posts: 780
Firefox & Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This demonstrates generation of Code-39 barcodes on an LCD display.
LCD display is this http://www.sparkfun.com/products/9351
With http://sourceforge.net/projects/serialglcd/?source=directory and http://sourceforge.net/projects/serialglcdlib/?source=directory
Text 7 characters or less can be generated on screen. The barcode is perfectly readable with Zbar.
The code is somewhat rough:
Code:
#include <serialGLCD.h>
#include <ctype.h>
  serialGLCD lcd;
  char ctl[]="NwNnWnWnN";
  char zero[]="NnNwWnWnN";
  char one[]="WnNwNnNnW";
  char two[]="NnWwNnNnW";
  char three[]="WnWwNnNnN";
  char four[]="NnNwWnNnW";
  char five[]="WnNwWnNnN";
  char six[]="NnWwWnNnN";
  char seven[]="NnNwNnWnW";
  char eight[]="WnNwNnWnN";
  char nine[]="NnWwNnWnN";
  char A[]="WnNnNwNnW";
  char B[]="NnWnNwNnW";
  char C[]="WnWnNwNnN";
  char D[]="NnNnWwNnW";
  char E[]="WnNnWwNnN";
  char F[]="NnWnWwNnN";
  char G[]="NnNnNwWnW";
  char H[]="WnNnNwWnN";
  char I[]="WnNnNwWnN";
  char J[]="WnNnNwWnN";
  char K[]="WnNnNnNwW";
  char L[]="NnWnNnNwW";
  char M[]="WnWnNnNwN";
  char N[]="NnNnWnNwW";
  char O[]="WnNnWnNwN";
  char P[]="NnWnWnNwN";
  char Q[]="NnNnNnWwW";
  char R[]="WnNnNnWwN";
  char S[]="NnWnNnWwN";
  char T[]="NnNnWnWwN";
  char U[]="WwNnNnNnW";
  char V[]="NwWnNnNnW";
  char W[]="WwWnNnNnN";
  char X[]="NwNnWnNnW";
  char Y[]="WwNnWnNnN";
  char Z[]="NwWnWnNnN";
  char sp[]="NwWnNnWnN";
  int xc = 1;
   void intr(char *c){
    int n;
    for(n = 0;n < 9;n++){
      switch(c[n]){
        case 'W': lcd.drawLine(xc, 0, xc, 64, 0); delay(7); lcd.drawLine(xc+1, 0, xc+1, 64, 0); delay(6); xc+=2; break;
        case 'N': lcd.drawLine(xc, 0, xc, 64, 0); delay(7); xc++; break;
        case 'w': xc+=2; break;
        case 'n': xc++; break;
      }
     if(xc > 128){Serial.println("OVRFLW");}
    }
    xc++;
  }
  void str(char *s){
    char a;
    char *x;
    for(a = 0;a < strlen(s);a++){
       switch(tolower(s[a])){
         case '*': x=ctl; break;
         case 'a': x=A; break;
         case 'b': x=B; break;
         case 'c': x=C; break;
         case 'd': x=D; break;
         case 'e': x=E; break;
         case 'f': x=F; break;
         case 'g': x=G; break;
         case 'h': x=H; break;
         case 'i': x=I; break;
         case 'j': x=J; break;
         case 'k': x=K; break;
         case 'l': x=L; break;
         case 'm': x=M; break;
         case 'n': x=N; break;
         case 'o': x=O; break;
         case 'p': x=P; break;
         case 'q': x=Q; break;
         case 'r': x=R; break;
         case 's': x=S; break;
         case 't': x=T; break;
         case 'u': x=U; break;
         case 'v': x=V; break;
         case 'w': x=W; break;
         case 'x': x=X; break;
         case 'y': x=Y; break;
         case 'z': x=Z; break;
         case ' ': x=sp; break;
         case '0': x=zero; break;
         case '1': x=one; break;
         case '2': x=two; break;
         case '3': x=three; break;
         case '4': x=four; break;
         case '5': x=five; break;
         case '6': x=six; break;
         case '7': x=seven; break;
         case '8': x=eight; break;
         case '9': x=nine; break;
         default : x=sp;
       }
       intr(x);
    }
  }
void setup(){
  Serial.begin(115200);
  delay(1500);
  lcd.resetLCD();
  delay(250);
  unsigned char x,y;
  for(x = 0;x < 128;x++){
    for(y = 0;y < 64;y++){
      lcd.togglePixel(x, y, 1);
    }
  }
  str("*TEST*");
}
void loop(){

}


* Cam0Pic12-05-04_23.21.59.jpg (50.02 KB, 640x480 - viewed 66 times.)
Logged

Avoid throwing electronics out as you or someone else might need them for parts or use.
Solid state rectifiers are the only REAL rectifiers.
Resistors for LEDS!

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pretty cool. smiley
Logged

Washington
Offline Offline
God Member
*****
Karma: 30
Posts: 780
Firefox & Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pretty cool. smiley
Yes! And easier to implement then I thought.
But the code needs alot of work, including more efficient lookup table packing and putting the huge tables in PROGMEM.
Logged

Avoid throwing electronics out as you or someone else might need them for parts or use.
Solid state rectifiers are the only REAL rectifiers.
Resistors for LEDS!

Germany
Offline Offline
Edison Member
*
Karma: 44
Posts: 2261
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

My android device with the Barcode Scanner was able to scan the photo. It's the text TEST, right? smiley-wink
Logged

Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12483
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
including more efficient lookup table packing
The codes can be optimized quite easily

You have 4 codes
W = Wide line
N = narrow line
w= wide space
n = narrow space

char zero[]="NnNwWnWnN";

Because line and space are alternating you can replace this scheme with 2 codes if you keep track of the mode (Line | Space) in the code.

W = Wide
N = narrow

char zero[]="NNNWWNWNN";

2 codes ?? thats binary so we can replace W=1 and N=0

char zero[]="000110100";   

9 bits can be encoded in an int.

int zero = 0x0034;

Now make an array of ints of all the chars you want to support

int BCint[40] = {....TBD ...}
char BCchar[40] = "#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ";

lookup the index in the BCchar and use the index to find the corresponding int in thBCint array

This brings back the whole logic to something like this...
Code:
char text[] = "HELLO";

for (int i=0; i< strlen(text); i++)
{
  c = text[i];  // optionally do a toupper();
  int index = -1;
  for (int j=0; j<40; j++)   
  {
    if (BCchar[j] == c)
    {
      index = j;
      break;
    }
  }
  if (index > -1) printCode(BCint[index]);
}

int indexof(char c, char* ar)
{
  int rv = -1;
  for
searching the character in the BCchar array can be made faster by
- using binary search or
- order the chars based upon - http://en.wikipedia.org/wiki/Letter_frequency - (the ints should be ordered accordingly)
- use the ascii value of the char to display to calculate the index ==> isdigit() etc...

Succes


Logged

Rob Tillaart

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

Washington
Offline Offline
God Member
*****
Karma: 30
Posts: 780
Firefox & Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote from: sth77
My android device with the Barcode Scanner was able to scan the photo. It's the text TEST, right?
That is correct. It seems quite easy to decode.
Quote
including more efficient lookup table packing
The codes can be optimized quite easily
I was able to implement your method although its easier said then done  smiley-mr-green
Quote
searching the character in the BCchar array can be made faster by
- using binary search or
- order the chars based upon - http://en.wikipedia.org/wiki/Letter_frequency - (the ints should be ordered accordingly)
- use the ascii value of the char to display to calculate the index ==> isdigit() etc...

Succes



Speed is fairly uncritical because the LCD is slow.

Here is the new code:
Code:
#include <serialGLCD.h>
#include <ctype.h>
serialGLCD lcd;
char index[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*";
int code[]={52,289,97,352,49,304,112,37,292,100,265,73,328,25,280,88,13,268,76,28,259,67,322,19,274,82,7,262,70,22,385,193,448,145,400,208,133,388,196,168,162,138,42,148,0};
  int xc = 1;
   void intr(int c){
    int n;
    int mask = 256;
    char state = 1;
    for(n = 0;n < 9;n++){
        if(c & mask){
          if(state){
            lcd.drawLine(xc, 0, xc, 64, 0); delay(7); lcd.drawLine(xc+1, 0, xc+1, 64, 0); delay(6);
          }         
          xc+=2;
        } else {
          if(state){
            lcd.drawLine(xc, 0, xc, 64, 0); delay(7);
          }
          xc++;
        }
      mask /= 2;
      state = !state;
     if(xc > 128){Serial.println("OVRFLW");}
    }
    xc++;
  }
void str(char *s){
  char a;
  int r;
  for(a = 0;a < strlen(s);a++){
    for(r = 0;r < strlen(index);r++){
      if(toupper(s[a]) == index[r]){
       intr(code[r]);
       break;
      }
    }
  }
}
void setup(){
  Serial.begin(115200);
  delay(1500);
  lcd.resetLCD();
  delay(250);
  unsigned char x,y;
  for(x = 0;x < 128;x++){
    for(y = 0;y < 64;y++){
      lcd.togglePixel(x, y, 1);
    }
  }
  str("*TEST*");
}
void loop(){

}
Logged

Avoid throwing electronics out as you or someone else might need them for parts or use.
Solid state rectifiers are the only REAL rectifiers.
Resistors for LEDS!

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 178
Posts: 12288
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


I wonder if 2-D barcodes would readable from an LCD?

I have to ask: other than the coolness-factor why did you do this?
Logged

Washington
Offline Offline
God Member
*****
Karma: 30
Posts: 780
Firefox & Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


I wonder if 2-D barcodes would readable from an LCD?
Yes.
Quote
I have to ask: other than the coolness-factor why did you do this?

Who wouldn't want to generate a barcode with an Arduino and display it on an LCD?
Its mostly about the "coolness-factor".

Note the QR code was displayed but not generated. Generating QR codes is difficult.


* Cam0Pic12-05-05_16.38.29.jpg (34.71 KB, 640x480 - viewed 37 times.)
Logged

Avoid throwing electronics out as you or someone else might need them for parts or use.
Solid state rectifiers are the only REAL rectifiers.
Resistors for LEDS!

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12483
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Who wouldn't want to generate a barcode with an Arduino and display it on an LCD?
And with similar code it might be printed on a thermal printer (ok other drawline routine)


Quote
Note the QR code was displayed but not generated. Generating QR codes is difficult.
For those who want to try (no arduio code) check - http://fukuchi.org/works/qrencode/index.html.en -
Logged

Rob Tillaart

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

Pages: [1]   Go Up
Jump to: