Go Down

Topic: Generating barcodes on LCD display (Read 2788 times) previous topic - next topic

smeezekitty

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: [Select]

#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(){

}
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!

Nick Gammon

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

smeezekitty


Pretty cool. :)

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.
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!

sth77

My android device with the Barcode Scanner was able to scan the photo. It's the text TEST, right? ;)
Mein Arduino-Blog: http://www.sth77.de/ - letzte Eintr├Ąge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

robtillaart

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: [Select]

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


Rob Tillaart

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

smeezekitty

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: [Select]

#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(){

}

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!

Coding Badly


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?

smeezekitty



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.
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!

robtillaart

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 -
Rob Tillaart

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

Go Up