16 segment display library for mbed This routine support 4, 6 and 8 digit anode-common or cathode-common LED.

Dependents:   16segmentLED_test

Committer:
morecat_lab
Date:
Sun Feb 08 11:51:48 2015 +0000
Revision:
0:420d710da1c5
1st release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
morecat_lab 0:420d710da1c5 1 /*
morecat_lab 0:420d710da1c5 2 Stnseg.cpp - mbed library for 4/6/8 digit Sixteen (16) segment LED driver.
morecat_lab 0:420d710da1c5 3 Copyright 2015 by morecat_lab
morecat_lab 0:420d710da1c5 4
morecat_lab 0:420d710da1c5 5 This library is distributed in the hope that it will be useful,
morecat_lab 0:420d710da1c5 6 but WITHOUT ANY WARRANTY; without even the implied warranty of
morecat_lab 0:420d710da1c5 7 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
morecat_lab 0:420d710da1c5 8 */
morecat_lab 0:420d710da1c5 9
morecat_lab 0:420d710da1c5 10 #include "Stnseg.h"
morecat_lab 0:420d710da1c5 11 #include <Timer.h>
morecat_lab 0:420d710da1c5 12
morecat_lab 0:420d710da1c5 13 const uint16_t Stnseg::numConv[] = {
morecat_lab 0:420d710da1c5 14 NUM_PAT16_0, NUM_PAT16_1, NUM_PAT16_2, NUM_PAT16_3,
morecat_lab 0:420d710da1c5 15 NUM_PAT16_4, NUM_PAT16_5, NUM_PAT16_6, NUM_PAT16_7,
morecat_lab 0:420d710da1c5 16 NUM_PAT16_8, NUM_PAT16_9, NUM_PAT16_A, NUM_PAT16_B,
morecat_lab 0:420d710da1c5 17 NUM_PAT16_C, NUM_PAT16_D, NUM_PAT16_E, NUM_PAT16_F};
morecat_lab 0:420d710da1c5 18
morecat_lab 0:420d710da1c5 19
morecat_lab 0:420d710da1c5 20 // 4 digit
morecat_lab 0:420d710da1c5 21 Stnseg::Stnseg(PinName data,PinName clock, PinName latch,PinName dp,
morecat_lab 0:420d710da1c5 22 PinName d1,PinName d2, PinName d3, PinName d4) :
morecat_lab 0:420d710da1c5 23 _dataPin(data), _clockPin(clock), _latchPin(latch), _dpPin(dp),
morecat_lab 0:420d710da1c5 24 _digPins(d1, d2, d3, d4)
morecat_lab 0:420d710da1c5 25 {
morecat_lab 0:420d710da1c5 26 _numOfDigs = 4;
morecat_lab 0:420d710da1c5 27 _updateInterval = (8333 / 4);
morecat_lab 0:420d710da1c5 28 _zeroSupress = true;
morecat_lab 0:420d710da1c5 29 _kcommon = false;
morecat_lab 0:420d710da1c5 30 }
morecat_lab 0:420d710da1c5 31
morecat_lab 0:420d710da1c5 32 // 6 digit
morecat_lab 0:420d710da1c5 33 Stnseg::Stnseg(PinName data,PinName clock, PinName latch,PinName dp,
morecat_lab 0:420d710da1c5 34 PinName d1,PinName d2, PinName d3, PinName d4,
morecat_lab 0:420d710da1c5 35 PinName d5,PinName d6) :
morecat_lab 0:420d710da1c5 36 _dataPin(data), _clockPin(clock), _latchPin(latch), _dpPin(dp),
morecat_lab 0:420d710da1c5 37 _digPins(d1, d2, d3, d4, d5, d6)
morecat_lab 0:420d710da1c5 38 {
morecat_lab 0:420d710da1c5 39 _numOfDigs = 6;
morecat_lab 0:420d710da1c5 40 _updateInterval = (8333 / 6);
morecat_lab 0:420d710da1c5 41 _zeroSupress = true;
morecat_lab 0:420d710da1c5 42 _kcommon = false;
morecat_lab 0:420d710da1c5 43 }
morecat_lab 0:420d710da1c5 44
morecat_lab 0:420d710da1c5 45 // 8 digit
morecat_lab 0:420d710da1c5 46 Stnseg::Stnseg(PinName data,PinName clock, PinName latch,PinName dp,
morecat_lab 0:420d710da1c5 47 PinName d1,PinName d2, PinName d3, PinName d4,
morecat_lab 0:420d710da1c5 48 PinName d5,PinName d6, PinName d7, PinName d8) :
morecat_lab 0:420d710da1c5 49 _dataPin(data), _clockPin(clock), _latchPin(latch), _dpPin(dp),
morecat_lab 0:420d710da1c5 50 _digPins(d1, d2, d3, d4, d5, d6, d7, d8)
morecat_lab 0:420d710da1c5 51 {
morecat_lab 0:420d710da1c5 52 _numOfDigs = 8;
morecat_lab 0:420d710da1c5 53 _updateInterval = (8333 / 8);
morecat_lab 0:420d710da1c5 54 _zeroSupress = true;
morecat_lab 0:420d710da1c5 55 _kcommon = false;
morecat_lab 0:420d710da1c5 56 }
morecat_lab 0:420d710da1c5 57
morecat_lab 0:420d710da1c5 58
morecat_lab 0:420d710da1c5 59 void Stnseg::begin(void) {
morecat_lab 0:420d710da1c5 60 timer.start();
morecat_lab 0:420d710da1c5 61 clear();
morecat_lab 0:420d710da1c5 62 }
morecat_lab 0:420d710da1c5 63
morecat_lab 0:420d710da1c5 64 void Stnseg::setAcommon(void) {
morecat_lab 0:420d710da1c5 65 _kcommon = false;
morecat_lab 0:420d710da1c5 66 }
morecat_lab 0:420d710da1c5 67
morecat_lab 0:420d710da1c5 68 void Stnseg::setKcommon(void) {
morecat_lab 0:420d710da1c5 69 _kcommon = true;
morecat_lab 0:420d710da1c5 70 }
morecat_lab 0:420d710da1c5 71
morecat_lab 0:420d710da1c5 72 uint16_t Stnseg::segCh(char i) {
morecat_lab 0:420d710da1c5 73 return numConv[i];
morecat_lab 0:420d710da1c5 74 }
morecat_lab 0:420d710da1c5 75
morecat_lab 0:420d710da1c5 76 void Stnseg::setDot(int d) {
morecat_lab 0:420d710da1c5 77 _buffer[d] |= 0x010000;
morecat_lab 0:420d710da1c5 78 }
morecat_lab 0:420d710da1c5 79
morecat_lab 0:420d710da1c5 80 void Stnseg::clearDot(int d) {
morecat_lab 0:420d710da1c5 81 _buffer[d] &= 0xfffe0000;
morecat_lab 0:420d710da1c5 82 }
morecat_lab 0:420d710da1c5 83
morecat_lab 0:420d710da1c5 84 void Stnseg::writeNum(int n) {
morecat_lab 0:420d710da1c5 85 if (_numOfDigs == 4) {
morecat_lab 0:420d710da1c5 86 writeNum4(n);
morecat_lab 0:420d710da1c5 87 } else if (_numOfDigs == 6) {
morecat_lab 0:420d710da1c5 88 writeNum6(n);
morecat_lab 0:420d710da1c5 89 } else if (_numOfDigs == 8) {
morecat_lab 0:420d710da1c5 90 writeNum8((long)n);
morecat_lab 0:420d710da1c5 91 }
morecat_lab 0:420d710da1c5 92 }
morecat_lab 0:420d710da1c5 93
morecat_lab 0:420d710da1c5 94
morecat_lab 0:420d710da1c5 95 void Stnseg::writeNum4(int n) {
morecat_lab 0:420d710da1c5 96 if (n < 10000) {
morecat_lab 0:420d710da1c5 97 _buffer[0] = segCh((n % 10000) / 1000);
morecat_lab 0:420d710da1c5 98 _buffer[1] = segCh((n % 1000) / 100);
morecat_lab 0:420d710da1c5 99 _buffer[2] = segCh((n % 100) / 10);
morecat_lab 0:420d710da1c5 100 _buffer[3] = segCh(n % 10);
morecat_lab 0:420d710da1c5 101 supressZero();
morecat_lab 0:420d710da1c5 102 } else {
morecat_lab 0:420d710da1c5 103 _buffer[0] = _buffer[1] = _buffer[2] = _buffer[3] = NUM_PAT16_MINUS;// overflow
morecat_lab 0:420d710da1c5 104 }
morecat_lab 0:420d710da1c5 105 }
morecat_lab 0:420d710da1c5 106
morecat_lab 0:420d710da1c5 107 void Stnseg::writeNum6(int n) {
morecat_lab 0:420d710da1c5 108 if (n < 10000) {
morecat_lab 0:420d710da1c5 109 _buffer[0] = segCh((n % 1000000) / 100000);
morecat_lab 0:420d710da1c5 110 _buffer[1] = segCh((n % 100000) / 10000);
morecat_lab 0:420d710da1c5 111 _buffer[2] = segCh((n % 10000) / 1000);
morecat_lab 0:420d710da1c5 112 _buffer[3] = segCh((n % 1000) / 100);
morecat_lab 0:420d710da1c5 113 _buffer[4] = segCh((n % 100) / 10);
morecat_lab 0:420d710da1c5 114 _buffer[5] = segCh(n % 10);
morecat_lab 0:420d710da1c5 115 supressZero();
morecat_lab 0:420d710da1c5 116 } else {
morecat_lab 0:420d710da1c5 117 _buffer[0] = _buffer[1] = _buffer[2] = _buffer[3] = NUM_PAT16_MINUS;// overflow
morecat_lab 0:420d710da1c5 118 }
morecat_lab 0:420d710da1c5 119 }
morecat_lab 0:420d710da1c5 120
morecat_lab 0:420d710da1c5 121 void Stnseg::writeNum8(int n) {
morecat_lab 0:420d710da1c5 122 if (n < 1000000) {
morecat_lab 0:420d710da1c5 123 _buffer[0] = segCh((n % 100000000) / 10000000);
morecat_lab 0:420d710da1c5 124 _buffer[1] = segCh((n % 10000000) / 1000000);
morecat_lab 0:420d710da1c5 125 _buffer[2] = segCh((n % 1000000) / 100000);
morecat_lab 0:420d710da1c5 126 _buffer[3] = segCh((n % 100000) / 10000);
morecat_lab 0:420d710da1c5 127 _buffer[4] = segCh((n % 10000) / 1000);
morecat_lab 0:420d710da1c5 128 _buffer[5] = segCh((n % 1000) / 100);
morecat_lab 0:420d710da1c5 129 _buffer[6] = segCh((n % 100) / 10);
morecat_lab 0:420d710da1c5 130 _buffer[7] = segCh(n % 10);
morecat_lab 0:420d710da1c5 131 supressZero();
morecat_lab 0:420d710da1c5 132 } else {
morecat_lab 0:420d710da1c5 133 _buffer[0] = _buffer[1] = _buffer[2] = _buffer[3] = _buffer[4] = _buffer[5] = NUM_PAT16_MINUS;// overflow
morecat_lab 0:420d710da1c5 134 }
morecat_lab 0:420d710da1c5 135 }
morecat_lab 0:420d710da1c5 136
morecat_lab 0:420d710da1c5 137 void Stnseg::writeNum(char d1, char d2) {
morecat_lab 0:420d710da1c5 138 _buffer[0] = segCh(d1);
morecat_lab 0:420d710da1c5 139 _buffer[1] = segCh(d2);
morecat_lab 0:420d710da1c5 140 supressZero();
morecat_lab 0:420d710da1c5 141 }
morecat_lab 0:420d710da1c5 142
morecat_lab 0:420d710da1c5 143 void Stnseg::writeNum(char d1, char d2, char d3, char d4) {
morecat_lab 0:420d710da1c5 144 _buffer[0] = segCh(d1);
morecat_lab 0:420d710da1c5 145 _buffer[1] = segCh(d2);
morecat_lab 0:420d710da1c5 146 _buffer[2] = segCh(d3);
morecat_lab 0:420d710da1c5 147 _buffer[3] = segCh(d4);
morecat_lab 0:420d710da1c5 148 supressZero();
morecat_lab 0:420d710da1c5 149 }
morecat_lab 0:420d710da1c5 150
morecat_lab 0:420d710da1c5 151 void Stnseg::writeNum(char d1, char d2, char d3, char d4,
morecat_lab 0:420d710da1c5 152 char d5, char d6, char d7, char d8)
morecat_lab 0:420d710da1c5 153 {
morecat_lab 0:420d710da1c5 154 _buffer[0] = segCh(d1);
morecat_lab 0:420d710da1c5 155 _buffer[1] = segCh(d2);
morecat_lab 0:420d710da1c5 156 _buffer[2] = segCh(d3);
morecat_lab 0:420d710da1c5 157 _buffer[3] = segCh(d4);
morecat_lab 0:420d710da1c5 158 _buffer[4] = segCh(d5);
morecat_lab 0:420d710da1c5 159 _buffer[5] = segCh(d6);
morecat_lab 0:420d710da1c5 160 _buffer[6] = segCh(d7);
morecat_lab 0:420d710da1c5 161 _buffer[7] = segCh(d8);
morecat_lab 0:420d710da1c5 162 supressZero();
morecat_lab 0:420d710da1c5 163 }
morecat_lab 0:420d710da1c5 164
morecat_lab 0:420d710da1c5 165 void Stnseg::writeHex(long n) {
morecat_lab 0:420d710da1c5 166 if (_numOfDigs == 4) {
morecat_lab 0:420d710da1c5 167 _buffer[0] = segCh((n >> 12) & 0xf);
morecat_lab 0:420d710da1c5 168 _buffer[1] = segCh((n >> 8) & 0xf);
morecat_lab 0:420d710da1c5 169 _buffer[2] = segCh((n >> 4) & 0xf);
morecat_lab 0:420d710da1c5 170 _buffer[3] = segCh(n & 0xf);
morecat_lab 0:420d710da1c5 171 } else if (_numOfDigs == 6) {
morecat_lab 0:420d710da1c5 172 _buffer[0] = segCh((n >> 20) & 0xf);
morecat_lab 0:420d710da1c5 173 _buffer[1] = segCh((n >> 16) & 0xf);
morecat_lab 0:420d710da1c5 174 _buffer[2] = segCh((n >> 12) & 0xf);
morecat_lab 0:420d710da1c5 175 _buffer[3] = segCh((n >> 8) & 0xf);
morecat_lab 0:420d710da1c5 176 _buffer[4] = segCh((n >> 4) & 0xf);
morecat_lab 0:420d710da1c5 177 _buffer[5] = segCh(n & 0xf);
morecat_lab 0:420d710da1c5 178 } else if (_numOfDigs == 8) {
morecat_lab 0:420d710da1c5 179 _buffer[0] = segCh((n >> 28) & 0xf);
morecat_lab 0:420d710da1c5 180 _buffer[1] = segCh((n >> 24) & 0xf);
morecat_lab 0:420d710da1c5 181 _buffer[2] = segCh((n >> 20) & 0xf);
morecat_lab 0:420d710da1c5 182 _buffer[3] = segCh((n >> 16) & 0xf);
morecat_lab 0:420d710da1c5 183 _buffer[4] = segCh((n >> 12) & 0xf);
morecat_lab 0:420d710da1c5 184 _buffer[5] = segCh((n >> 8) & 0xf);
morecat_lab 0:420d710da1c5 185 _buffer[6] = segCh((n >> 4) & 0xf);
morecat_lab 0:420d710da1c5 186 _buffer[7] = segCh(n & 0xf);
morecat_lab 0:420d710da1c5 187 }
morecat_lab 0:420d710da1c5 188 supressZero();
morecat_lab 0:420d710da1c5 189 }
morecat_lab 0:420d710da1c5 190
morecat_lab 0:420d710da1c5 191 void Stnseg::setZeroSupress(bool t) {
morecat_lab 0:420d710da1c5 192 _zeroSupress = t;
morecat_lab 0:420d710da1c5 193 }
morecat_lab 0:420d710da1c5 194
morecat_lab 0:420d710da1c5 195 void Stnseg::supressZero() {
morecat_lab 0:420d710da1c5 196 int i;
morecat_lab 0:420d710da1c5 197 if (_zeroSupress ) {
morecat_lab 0:420d710da1c5 198 for (i = 0 ; i < (_numOfDigs-1) ; i++) {
morecat_lab 0:420d710da1c5 199 if (_buffer[i] == segCh(0)) {
morecat_lab 0:420d710da1c5 200 _buffer[i] = _buffer[i] & 0x1000;
morecat_lab 0:420d710da1c5 201 } else {
morecat_lab 0:420d710da1c5 202 break;
morecat_lab 0:420d710da1c5 203 }
morecat_lab 0:420d710da1c5 204 }
morecat_lab 0:420d710da1c5 205 }
morecat_lab 0:420d710da1c5 206 }
morecat_lab 0:420d710da1c5 207
morecat_lab 0:420d710da1c5 208 void Stnseg::writeRawData(uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4) {
morecat_lab 0:420d710da1c5 209 _buffer[0] = d1;
morecat_lab 0:420d710da1c5 210 _buffer[1] = d2;
morecat_lab 0:420d710da1c5 211 _buffer[2] = d3;
morecat_lab 0:420d710da1c5 212 _buffer[3] = d4;
morecat_lab 0:420d710da1c5 213 }
morecat_lab 0:420d710da1c5 214
morecat_lab 0:420d710da1c5 215 void Stnseg::writeRawData(uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4,
morecat_lab 0:420d710da1c5 216 uint32_t d5, uint32_t d6) {
morecat_lab 0:420d710da1c5 217 _buffer[0] = d1;
morecat_lab 0:420d710da1c5 218 _buffer[1] = d2;
morecat_lab 0:420d710da1c5 219 _buffer[2] = d3;
morecat_lab 0:420d710da1c5 220 _buffer[3] = d4;
morecat_lab 0:420d710da1c5 221 _buffer[4] = d5;
morecat_lab 0:420d710da1c5 222 _buffer[5] = d6;
morecat_lab 0:420d710da1c5 223 }
morecat_lab 0:420d710da1c5 224 void Stnseg::writeRawData(uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4,
morecat_lab 0:420d710da1c5 225 uint32_t d5, uint32_t d6, uint32_t d7, uint32_t d8) {
morecat_lab 0:420d710da1c5 226 _buffer[0] = d1;
morecat_lab 0:420d710da1c5 227 _buffer[1] = d2;
morecat_lab 0:420d710da1c5 228 _buffer[2] = d3;
morecat_lab 0:420d710da1c5 229 _buffer[3] = d4;
morecat_lab 0:420d710da1c5 230 _buffer[4] = d5;
morecat_lab 0:420d710da1c5 231 _buffer[5] = d6;
morecat_lab 0:420d710da1c5 232 _buffer[6] = d7;
morecat_lab 0:420d710da1c5 233 _buffer[7] = d8;
morecat_lab 0:420d710da1c5 234 }
morecat_lab 0:420d710da1c5 235
morecat_lab 0:420d710da1c5 236 void Stnseg::write(uint8_t d, uint32_t value) {
morecat_lab 0:420d710da1c5 237 _buffer[d] = value;
morecat_lab 0:420d710da1c5 238 }
morecat_lab 0:420d710da1c5 239
morecat_lab 0:420d710da1c5 240 void Stnseg::clear(void) {
morecat_lab 0:420d710da1c5 241 int i;
morecat_lab 0:420d710da1c5 242 for(i=0;i<8;i++){
morecat_lab 0:420d710da1c5 243 _buffer[i] = 0;
morecat_lab 0:420d710da1c5 244 }
morecat_lab 0:420d710da1c5 245 _dig = _numOfDigs - 1;
morecat_lab 0:420d710da1c5 246 _digPins = ( _kcommon) ? 0xff : 0;
morecat_lab 0:420d710da1c5 247 }
morecat_lab 0:420d710da1c5 248
morecat_lab 0:420d710da1c5 249 void Stnseg::turnOff(void) {
morecat_lab 0:420d710da1c5 250 if ( _kcommon) {
morecat_lab 0:420d710da1c5 251 _digPins = 0xff; // set HIGH
morecat_lab 0:420d710da1c5 252 } else {
morecat_lab 0:420d710da1c5 253 _digPins = 0; // set LOW
morecat_lab 0:420d710da1c5 254 }
morecat_lab 0:420d710da1c5 255 }
morecat_lab 0:420d710da1c5 256
morecat_lab 0:420d710da1c5 257 void Stnseg::turnOn(void) {
morecat_lab 0:420d710da1c5 258 if ( _kcommon) {
morecat_lab 0:420d710da1c5 259 _digPins = ~(1 << _dig); // set LOW
morecat_lab 0:420d710da1c5 260 } else {
morecat_lab 0:420d710da1c5 261 _digPins = (1 << _dig); // set HIGH
morecat_lab 0:420d710da1c5 262 }
morecat_lab 0:420d710da1c5 263 }
morecat_lab 0:420d710da1c5 264
morecat_lab 0:420d710da1c5 265 void Stnseg::updateSeg(void) {
morecat_lab 0:420d710da1c5 266 if( (++_dig) >= _numOfDigs)
morecat_lab 0:420d710da1c5 267 _dig = 0;
morecat_lab 0:420d710da1c5 268 _latchPin = 0;
morecat_lab 0:420d710da1c5 269 for (int col = 0 ; col < 16 ; col++) { // forward order
morecat_lab 0:420d710da1c5 270 _clockPin = 0;
morecat_lab 0:420d710da1c5 271 if(_buffer[_dig] & (1 << col)){
morecat_lab 0:420d710da1c5 272 _dataPin = 1;
morecat_lab 0:420d710da1c5 273 } else {
morecat_lab 0:420d710da1c5 274 _dataPin = 0;
morecat_lab 0:420d710da1c5 275 }
morecat_lab 0:420d710da1c5 276 _clockPin = 1;
morecat_lab 0:420d710da1c5 277 }
morecat_lab 0:420d710da1c5 278 _latchPin = 1;
morecat_lab 0:420d710da1c5 279 if ((_buffer[_dig] & 0x10000) != 0) {
morecat_lab 0:420d710da1c5 280 _dpPin = 1;
morecat_lab 0:420d710da1c5 281 } else {
morecat_lab 0:420d710da1c5 282 _dpPin = 0;
morecat_lab 0:420d710da1c5 283 }
morecat_lab 0:420d710da1c5 284 }
morecat_lab 0:420d710da1c5 285
morecat_lab 0:420d710da1c5 286 void Stnseg::updateWithDelay(int ms) {
morecat_lab 0:420d710da1c5 287 timer.reset(); // to avoid overflow 32bit counter (~=30min)
morecat_lab 0:420d710da1c5 288 int start = timer.read_ms();
morecat_lab 0:420d710da1c5 289 _dig = _numOfDigs - 1;
morecat_lab 0:420d710da1c5 290 turnOff();
morecat_lab 0:420d710da1c5 291 do {
morecat_lab 0:420d710da1c5 292 for (int i = 0 ; i < _numOfDigs ; i++) {
morecat_lab 0:420d710da1c5 293 updateSeg();
morecat_lab 0:420d710da1c5 294 turnOn();
morecat_lab 0:420d710da1c5 295 wait(0.001f); // wait 1ms
morecat_lab 0:420d710da1c5 296 turnOff();
morecat_lab 0:420d710da1c5 297 }
morecat_lab 0:420d710da1c5 298 if ((timer.read_ms() - start) >= ms) {
morecat_lab 0:420d710da1c5 299 break;
morecat_lab 0:420d710da1c5 300 }
morecat_lab 0:420d710da1c5 301 } while(1);
morecat_lab 0:420d710da1c5 302 }
morecat_lab 0:420d710da1c5 303
morecat_lab 0:420d710da1c5 304 void Stnseg::updateOnce(void) {
morecat_lab 0:420d710da1c5 305 uint8_t i;
morecat_lab 0:420d710da1c5 306 _dig = _numOfDigs - 1;
morecat_lab 0:420d710da1c5 307 turnOff();
morecat_lab 0:420d710da1c5 308 for (i = 0 ; i < _numOfDigs ; i++) {
morecat_lab 0:420d710da1c5 309 updateSeg();
morecat_lab 0:420d710da1c5 310 turnOn();
morecat_lab 0:420d710da1c5 311 wait(0.001f); // wait 1ms
morecat_lab 0:420d710da1c5 312 turnOff();
morecat_lab 0:420d710da1c5 313 }
morecat_lab 0:420d710da1c5 314 }
morecat_lab 0:420d710da1c5 315
morecat_lab 0:420d710da1c5 316 // EOF