iZsh fail0verflow / Mbed 2 deprecated BarcodeLED

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BarcodeLED.cpp Source File

BarcodeLED.cpp

00001 /* Copyright (c) 2010 iZsh - izsh at fail0verflow.com
00002  *
00003  * This program is free software: you can redistribute it and/or modify
00004  * it under the terms of the GNU General Public License as published by
00005  * the Free Software Foundation, either version 3 of the License, or
00006  * (at your option) any later version.
00007  * 
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 #include "BarcodeLED.h"
00017 
00018 const char * BarcodeLED::m_Barcode39[] = {
00019   "1113313111", "3113111131", "1133111131", "3133111111", "1113311131", "3113311111", "1133311111",
00020   "1113113131", "3113113111", "1133113111", "3111131131", "1131131131", "3131131111", "1111331131",
00021   "3111331111", "1131331111", "1111133131", "3111133111", "1131133111", "1111333111", "3111111331",
00022   "1131111331", "3131111311", "1111311331", "3111311311", "1131311311", "1111113331", "3111113311",
00023   "1131113311", "1111313311", "3311111131", "1331111131", "3331111111", "1311311131", "3311311111",
00024   "1331311111", "1311113131", "3311113111", "1331113111", "1313131111", "1313111311", "1311131311",
00025   "1113131311", "1311313111"
00026 };
00027 
00028 const char * BarcodeLED::m_Barcode128[] = {
00029   "212222", "222122", "222221", "121223", "121322", "131222", "122213", "122312", "132212",
00030   "221213", "221312", "231212", "112232", "122132", "122231", "113222", "123122", "123221",
00031   "223211", "221132", "221231", "213212", "223112", "312131", "311222", "321122", "321221",
00032   "312212", "322112", "322211", "212123", "212321", "232121", "111323", "131123", "131321",
00033   "112313", "132113", "132311", "211313", "231113", "231311", "112133", "112331", "132131",
00034   "113123", "113321", "133121", "313121", "211331", "231131", "213113", "213311", "213131",
00035   "311123", "311321", "331121", "312113", "312311", "332111", "314111", "221411", "431111",
00036   "111224", "111422", "121124", "121421", "141122", "141221", "112214", "112412", "122114",
00037   "122411", "142112", "142211", "241211", "221114", "413111", "241112", "134111", "111242",
00038   "121142", "121241", "114212", "124112", "124211", "411212", "421112", "421211", "212141",
00039   "214121", "412121", "111143", "111341", "131141", "114113", "114311", "411113", "411311",
00040   "113141", "114131", "311141", "411131", "211412", "211214", "211232", "2331112"
00041 };
00042 
00043 BarcodeLED::BarcodeLED(const PinName Led, const CodeType Codetype, const int BaseDelay)
00044  : m_Led(DigitalOut(Led)), m_Codetype(Codetype), m_BaseDelay(BaseDelay), m_Verbose(false)
00045 {
00046     m_Led = 1;
00047 }
00048     
00049 BarcodeLED::CodeType BarcodeLED::GetCodetype()
00050 {
00051     return m_Codetype;
00052 }
00053 
00054 void BarcodeLED::SetCodetype(const CodeType Codetype)
00055 {
00056     m_Codetype = Codetype;
00057 }
00058 
00059 int BarcodeLED::GetBaseDelay()
00060 {
00061     return m_BaseDelay;
00062 }
00063 
00064 void BarcodeLED::SetBaseDelay(const int BaseDelay)
00065 {
00066     m_BaseDelay = BaseDelay;
00067 }
00068 
00069 int BarcodeLED::GetVerbose()
00070 {
00071     return m_Verbose;
00072 }
00073 
00074 void BarcodeLED::SetVerbose(const bool Verbose)
00075 {
00076     m_Verbose = Verbose;
00077 }
00078 
00079 void BarcodeLED::Emit(const char Str[])
00080 {
00081     switch (m_Codetype) {
00082     case Code128a:
00083     case Code128b:
00084     case Code128c:
00085         EmitCode128(Str);
00086         break;
00087     case Code39:
00088     default:
00089         EmitCode39(Str);
00090         break;
00091     }
00092 }
00093 
00094 void BarcodeLED::EmitCode39(const char Str[])
00095 {
00096     if (m_Verbose)
00097         printf("sending \"%s\"\r\n", Str);
00098     // Let's build a sequence string
00099     // We do that (instead of sending the chars on the fly
00100     // because that's probably better timing-wise (not relying
00101     // on inlining) and because it gets easier that way to reverse
00102     // the sequence (to increase reliabilty)
00103     int len = strlen(Str);
00104     // Reserve the memory on the stack. Hopefully no one will
00105     // call this function with an insane string length
00106     int size = (len + 2) * 10 + 1; // |start|seq|stop|null|
00107     char seq[size];
00108     memset(seq, '\0', size);
00109     // And build the seq
00110     strncat(seq, "1311313111", size - 1); // Code39 start
00111     for (int i = 0; i < len; ++i)
00112         strncat(seq, m_Barcode39[ASCII2Code39(Str[i])], size - (i + 1) * 10 - 1);
00113     strncat(seq, "1311313111", size - (len + 1) * 10 - 1); // Code39 stop
00114     if (m_Verbose)
00115         printf("=> %s\r\n", seq);
00116     
00117     // Emit
00118     m_Led = 1;
00119     wait_us(m_BaseDelay * 100); // long whitespace
00120     FlashSeq(seq);              // Seq
00121     m_Led = 1;
00122     wait_us(m_BaseDelay * 25);  // short whitespace
00123     FlashSeq(RevStr(seq));      // Rev Seq
00124     m_Led = 1;
00125     wait_us(m_BaseDelay * 100); // long whitespace
00126 }
00127 
00128 void BarcodeLED::EmitCode128(const char Str[])
00129 {
00130     if (m_Verbose)
00131         printf("sending \"%s\"\r\n", Str);
00132     int len = strlen(Str);
00133     int size = len * 6 + 6 * 2 + 7 + 1; // |start|seq|checksum|stop|null|
00134     char seq[size];
00135     memset(seq, '\0', size);
00136     // build the seq
00137     strncat(seq, m_Barcode128[m_Codetype], size - 1); // Code128 start
00138     for (int i = 0; i < len; ++i)
00139         strncat(seq, m_Barcode128[ASCII2Code128(Str[i])], size - (i + 1) * 6 - 1);
00140     strncat(seq, m_Barcode128[Code128Checksum(Str)],  size - (len + 1) * 6 - 1);
00141     strncat(seq, "2331112", size - (len + 2) * 6 - 1); // Code128 stop
00142     if (m_Verbose)
00143         printf("=> %s\r\n", seq);
00144     
00145     // Emit
00146     m_Led = 1;
00147     wait_us(m_BaseDelay * 100); // long whitespace
00148     FlashSeq(seq);              // Seq
00149     m_Led = 1;
00150     wait_us(m_BaseDelay * 25);  // short whitespace
00151     FlashSeq(RevStr(seq));      // Rev Seq
00152     m_Led = 1;
00153     wait_us(m_BaseDelay * 100); // long whitespace
00154 }
00155 
00156 // Convert an ASCII code to Code39
00157 // It doesn't support the full ascii table yet
00158 // That would need to use a sequence of two Code39 for that
00159 // See http://en.wikipedia.org/wiki/Code_39
00160 int BarcodeLED::ASCII2Code39(const char C)
00161 {
00162     if (C >= '0' && C <= '9')
00163         return C - '0';
00164     // Case is ignored for now
00165     if (C >= 'A' && C <= 'Z')
00166         return C - 55;
00167     if (C >= 'a' && C <= 'z')
00168         return C - 87;
00169     // Punctuation and alike
00170     switch (C) {
00171     case '-':
00172         return 36;
00173     case '.':
00174         return 37;
00175     case ' ':
00176         return 38;
00177     case '$':
00178         return 39;
00179     case '/':
00180         return 40;
00181     case '+':
00182         return 41;
00183     case '%':
00184         return 42;
00185     case '*':
00186         return 43;
00187     }
00188     return 0;
00189 }
00190 
00191 int BarcodeLED::ASCII2Code128(const char C)
00192 {
00193     if (C == ' ')
00194         return 0;
00195     if (C >= 33 && C <= 126)
00196         return C - 32;   
00197     if (C >= 145)
00198         return C - 50;
00199     if (C <= 31)        // Code128a
00200         return C + 64;
00201     return 0;
00202 }
00203 
00204 char * BarcodeLED::RevStr(char Str[])
00205 {
00206     int len = strlen(Str);
00207     int s = 0;
00208     int e = len - 1;
00209     while (s < e) {
00210         char c = Str[s];
00211         Str[s] = Str[e];
00212         Str[e] = c;
00213         ++s;
00214         --e;
00215     }
00216     return Str;
00217 }
00218 
00219 void BarcodeLED::FlashSeq(const char Seq[])
00220 {
00221     int b = 0;
00222     for (int i = 0; Seq[i] != '\0'; ++i) {
00223         m_Led = b;
00224         wait_us(m_BaseDelay * (Seq[i] - '0'));
00225         b = !b;
00226     }
00227 }
00228 
00229 int BarcodeLED::Code128Checksum(const char Str[])
00230 {
00231   long checksum = m_Codetype;
00232   for (int i = 0; Str[i] != '\0'; ++i)
00233     checksum += (i + 1) * ASCII2Code128(Str[i]);
00234   return checksum % 103;
00235 }
00236 
00237