Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Fri Jul 15 2022 20:45:35 by
1.7.2