7 Segment LED Displaydriver, I2C interface, SAA1064

Dependents:   812_hello

Committer:
wim
Date:
Mon Sep 23 19:23:34 2013 +0000
Revision:
2:970360b29a2a
Parent:
1:79cb73f852da
Documentation updated

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 0:48adc4a70511 1 /* SAA1064 - I2C LED Driver used in multiplex mode (4x 7 Segments and Decimal Point)
wim 0:48adc4a70511 2 * Copyright (c) 2013 Wim Huiskamp
wim 0:48adc4a70511 3 *
wim 0:48adc4a70511 4 * Released under the MIT License: http://mbed.org/license/mit
wim 0:48adc4a70511 5 *
wim 0:48adc4a70511 6 * version 0.2 Initial Release
wim 2:970360b29a2a 7 * version 0.3 Improved Leading Zero suppress for writeInt
wim 0:48adc4a70511 8 */
wim 0:48adc4a70511 9 #include "mbed.h"
wim 0:48adc4a70511 10 #include "SAA1064.h"
wim 0:48adc4a70511 11
wim 1:79cb73f852da 12
wim 1:79cb73f852da 13 /** Create a SAA1064 LED displaydriver object using a specified I2C bus and slaveaddress
wim 1:79cb73f852da 14 *
wim 1:79cb73f852da 15 * @param I2C &i2c the I2C port to connect to
wim 1:79cb73f852da 16 * @param char deviceAddress the address of the SAA1064
wim 1:79cb73f852da 17 */
wim 1:79cb73f852da 18 SAA1064::SAA1064(I2C *i2c, uint8_t deviceAddress) : _i2c(i2c) {
wim 0:48adc4a70511 19
wim 0:48adc4a70511 20 _slaveAddress = deviceAddress;
wim 0:48adc4a70511 21 _init();
wim 0:48adc4a70511 22 };
wim 0:48adc4a70511 23
wim 1:79cb73f852da 24 /** Set segment brightness
wim 1:79cb73f852da 25 *
wim 1:79cb73f852da 26 * @param intensity intensity value, valid Range between 0-7, 0 = 0 mA/segment, 1 = 3 mA/segment etc
wim 1:79cb73f852da 27 */
wim 1:79cb73f852da 28 void SAA1064::setIntensity(uint8_t intensity) {
wim 1:79cb73f852da 29 uint8_t data[6];
wim 0:48adc4a70511 30
wim 0:48adc4a70511 31 intensity = (intensity & 0x07) << 4; // Valid Range between 0-7
wim 0:48adc4a70511 32 // 0 = 0 mA/segment, 1 = 3 mA/segment etc
wim 0:48adc4a70511 33 data[0] = SAA1064_CTRL; // Select Control Reg
wim 0:48adc4a70511 34 data[1] = SAA1064_CTRL_DEF | intensity; // Init Control Reg
wim 0:48adc4a70511 35
wim 0:48adc4a70511 36 // write data to the display
wim 1:79cb73f852da 37 _i2c->write(_slaveAddress, (char*) data, 2);
wim 0:48adc4a70511 38
wim 0:48adc4a70511 39 };
wim 0:48adc4a70511 40
wim 0:48adc4a70511 41
wim 1:79cb73f852da 42 /** Write digits
wim 1:79cb73f852da 43 *
wim 1:79cb73f852da 44 * @param digit1 LED segment pattern for digit1 (MSB)
wim 1:79cb73f852da 45 * @param digit2 LED segment pattern for digit2
wim 1:79cb73f852da 46 * @param digit3 LED segment pattern for digit3
wim 1:79cb73f852da 47 * @param digit4 LED segment pattern for digit4 (LSB)
wim 1:79cb73f852da 48 */
wim 1:79cb73f852da 49 void SAA1064::write(uint8_t digit1, uint8_t digit2, uint8_t digit3, uint8_t digit4) {
wim 1:79cb73f852da 50 uint8_t data[6];
wim 0:48adc4a70511 51
wim 0:48adc4a70511 52 data[0] = SAA1064_DIG1; // Select Digit1 Reg
wim 0:48adc4a70511 53 data[1] = digit1; // Digit 1
wim 0:48adc4a70511 54 data[2] = digit2; // Digit 2
wim 0:48adc4a70511 55 data[3] = digit3; // Digit 3
wim 0:48adc4a70511 56 data[4] = digit4; // Digit 4
wim 0:48adc4a70511 57
wim 0:48adc4a70511 58 // write data to the display
wim 1:79cb73f852da 59 _i2c->write(_slaveAddress, (char*) data, 5);
wim 0:48adc4a70511 60
wim 0:48adc4a70511 61 };
wim 0:48adc4a70511 62
wim 1:79cb73f852da 63
wim 1:79cb73f852da 64 /** Write Integer
wim 1:79cb73f852da 65 *
wim 1:79cb73f852da 66 * @param value integer value to display, valid range -999...9999
wim 1:79cb73f852da 67 * @param dp_digit digit where decimal point is set, valid range 1..4 (no DP shown for dp_digit = 0)
wim 1:79cb73f852da 68 * @param leading suppress leading zero (false=show leading zero, true=suppress leading zero)
wim 1:79cb73f852da 69 */
wim 1:79cb73f852da 70 void SAA1064::writeInt(int value, uint8_t dp_digit, bool leading) {
wim 1:79cb73f852da 71 uint8_t digit_value;
wim 1:79cb73f852da 72 uint8_t data[6];
wim 0:48adc4a70511 73
wim 0:48adc4a70511 74 data[0] = SAA1064_DIG1; // Select Digit1 Reg
wim 0:48adc4a70511 75
wim 0:48adc4a70511 76 // limit to valid range
wim 0:48adc4a70511 77 if (value >= 9999) value = 9999;
wim 0:48adc4a70511 78 if (value <= -999) value = -999;
wim 0:48adc4a70511 79
wim 0:48adc4a70511 80 if (value >= 0) {
wim 0:48adc4a70511 81 // value 0...9999
wim 0:48adc4a70511 82 digit_value = value/1000; // compute thousands
wim 0:48adc4a70511 83 value = value % 1000; // compute remainder
wim 2:970360b29a2a 84 if ((digit_value==0) && !(dp_digit==1) && leading )
wim 0:48adc4a70511 85 data[1] = SAA1064_BLNK; // suppress leading zero
wim 0:48adc4a70511 86 else {
wim 0:48adc4a70511 87 data[1] = SAA1064_SEGM[digit_value];
wim 0:48adc4a70511 88 leading = false; // dont suppress zero's
wim 0:48adc4a70511 89 }
wim 0:48adc4a70511 90 if (dp_digit==1) {data[1] |= SAA1064_DP;} // Set decimal point
wim 0:48adc4a70511 91
wim 0:48adc4a70511 92
wim 0:48adc4a70511 93 digit_value = value/100; // compute hundreds
wim 0:48adc4a70511 94 value = value % 100; // compute remainder
wim 2:970360b29a2a 95 if ((digit_value==0) && !(dp_digit==2) && leading)
wim 0:48adc4a70511 96 data[2] = SAA1064_BLNK; // suppress leading zero
wim 0:48adc4a70511 97 else {
wim 0:48adc4a70511 98 data[2] = SAA1064_SEGM[digit_value];
wim 0:48adc4a70511 99 leading = false; // dont suppress zero's
wim 0:48adc4a70511 100 }
wim 0:48adc4a70511 101 if (dp_digit==2) {data[2] |= SAA1064_DP;} // Set decimal point
wim 0:48adc4a70511 102
wim 0:48adc4a70511 103 digit_value = value/10; // compute tens
wim 0:48adc4a70511 104 value = value % 10; // compute remainder
wim 2:970360b29a2a 105 if ((digit_value==0) && !(dp_digit==3) && leading)
wim 0:48adc4a70511 106 data[3] = SAA1064_BLNK; // suppress leading zero
wim 0:48adc4a70511 107 else {
wim 0:48adc4a70511 108 data[3] = SAA1064_SEGM[digit_value];
wim 0:48adc4a70511 109 //leading = false; // dont suppress zero's
wim 0:48adc4a70511 110 }
wim 0:48adc4a70511 111 if (dp_digit==3) {data[3] |= SAA1064_DP;} // Set decimal point
wim 0:48adc4a70511 112
wim 0:48adc4a70511 113 //digit_value = value; // compute units
wim 0:48adc4a70511 114 data[4] = SAA1064_SEGM[value]; // never suppress units zero
wim 0:48adc4a70511 115 if (dp_digit==4) {data[4] |= SAA1064_DP;} // Set decimal point
wim 0:48adc4a70511 116
wim 0:48adc4a70511 117 }
wim 0:48adc4a70511 118 else {
wim 0:48adc4a70511 119 // value -999...-1
wim 0:48adc4a70511 120 value = -value;
wim 0:48adc4a70511 121 data[1] = SAA1064_MINUS; // Sign
wim 0:48adc4a70511 122 if (dp_digit==1) {data[1] |= SAA1064_DP;} // Set decimal point
wim 0:48adc4a70511 123
wim 0:48adc4a70511 124 digit_value = value/100; // compute hundreds
wim 0:48adc4a70511 125 value = value % 100; // compute remainder
wim 2:970360b29a2a 126 if ((digit_value==0) && !(dp_digit==2) && leading)
wim 0:48adc4a70511 127 data[2] = SAA1064_BLNK; // suppress leading zero
wim 0:48adc4a70511 128 else {
wim 0:48adc4a70511 129 data[2] = SAA1064_SEGM[digit_value];
wim 0:48adc4a70511 130 leading = false; // dont suppress zero's
wim 0:48adc4a70511 131 }
wim 0:48adc4a70511 132 if (dp_digit==2) {data[2] |= SAA1064_DP;} // Set decimal point
wim 0:48adc4a70511 133
wim 0:48adc4a70511 134 digit_value = value/10; // compute tens
wim 0:48adc4a70511 135 value = value % 10; // compute remainder
wim 2:970360b29a2a 136 if ((digit_value==0) && !(dp_digit==3) && leading)
wim 0:48adc4a70511 137 data[3] = SAA1064_BLNK; // suppress leading zero
wim 0:48adc4a70511 138 else {
wim 0:48adc4a70511 139 data[3] = SAA1064_SEGM[digit_value];
wim 0:48adc4a70511 140 //leading = false; // dont suppress zero's
wim 0:48adc4a70511 141 }
wim 0:48adc4a70511 142 if (dp_digit==3) {data[3] |= SAA1064_DP;} // Set decimal point
wim 0:48adc4a70511 143
wim 0:48adc4a70511 144 //digit_value = value; // compute units
wim 0:48adc4a70511 145 data[4] = SAA1064_SEGM[value]; // never suppress units zero
wim 0:48adc4a70511 146 if (dp_digit==4) {data[4] |= SAA1064_DP;} // Set decimal point
wim 0:48adc4a70511 147 }
wim 0:48adc4a70511 148
wim 0:48adc4a70511 149 // write data to the display
wim 1:79cb73f852da 150 _i2c->write(_slaveAddress, (char*) data, 5);
wim 0:48adc4a70511 151
wim 0:48adc4a70511 152 };
wim 0:48adc4a70511 153
wim 1:79cb73f852da 154 /** snake: show a short animation
wim 1:79cb73f852da 155 *
wim 1:79cb73f852da 156 * @param count number of times animation is repeated, valid range 0..15
wim 1:79cb73f852da 157 *
wim 1:79cb73f852da 158 */
wim 1:79cb73f852da 159 void SAA1064::snake(uint8_t count) {
wim 1:79cb73f852da 160 uint8_t i;
wim 1:79cb73f852da 161 const float step = 0.1;
wim 1:79cb73f852da 162 // const float loop = 0.1;
wim 1:79cb73f852da 163
wim 1:79cb73f852da 164 count = count & 0x0F; // Limit max count
wim 1:79cb73f852da 165
wim 1:79cb73f852da 166 for (i=0; i<count; i++) {
wim 1:79cb73f852da 167 write(0x00,0x00,0x00,0x01); wait(step);
wim 1:79cb73f852da 168 write(0x00,0x00,0x01,0x01); wait(step);
wim 1:79cb73f852da 169 write(0x00,0x01,0x01,0x01); wait(step);
wim 1:79cb73f852da 170 write(0x01,0x01,0x01,0x00); wait(step);
wim 1:79cb73f852da 171 write(0x21,0x01,0x00,0x00); wait(step);
wim 1:79cb73f852da 172 write(0x31,0x00,0x00,0x00); wait(step);
wim 1:79cb73f852da 173 write(0x38,0x00,0x00,0x00); wait(step);
wim 1:79cb73f852da 174 write(0x18,0x08,0x00,0x00); wait(step);
wim 1:79cb73f852da 175 write(0x08,0x08,0x08,0x00); wait(step);
wim 1:79cb73f852da 176 write(0x00,0x08,0x08,0x08); wait(step);
wim 1:79cb73f852da 177 write(0x00,0x00,0x08,0x0C); wait(step);
wim 1:79cb73f852da 178 write(0x00,0x00,0x00,0x0E); wait(step);
wim 1:79cb73f852da 179 write(0x00,0x00,0x00,0x06); wait(step);
wim 1:79cb73f852da 180 write(0x00,0x00,0x00,0x02); wait(step);
wim 1:79cb73f852da 181 write(0x00,0x00,0x00,0x00); wait(step);
wim 1:79cb73f852da 182
wim 1:79cb73f852da 183 // wait(loop)
wim 1:79cb73f852da 184 }
wim 0:48adc4a70511 185
wim 1:79cb73f852da 186 }
wim 1:79cb73f852da 187
wim 1:79cb73f852da 188
wim 1:79cb73f852da 189 /** splash: show a short animation
wim 1:79cb73f852da 190 *
wim 1:79cb73f852da 191 * @param count number of times animation is repeated, valid range 0..15
wim 1:79cb73f852da 192 *
wim 1:79cb73f852da 193 */
wim 1:79cb73f852da 194 void SAA1064::splash (uint8_t count){
wim 1:79cb73f852da 195 uint8_t i;
wim 1:79cb73f852da 196 const float step = 0.3;
wim 1:79cb73f852da 197 // const float loop = 0.1;
wim 1:79cb73f852da 198
wim 1:79cb73f852da 199 count = count & 0x0F; // Limit max count
wim 1:79cb73f852da 200
wim 1:79cb73f852da 201 for (i=0; i<count; i++) {
wim 1:79cb73f852da 202 write(0x00,0x40,0x40,0x00); wait(step);
wim 1:79cb73f852da 203 write(0x39,0x09,0x09,0x0F); wait(step);
wim 1:79cb73f852da 204
wim 1:79cb73f852da 205 // wait(loop)
wim 1:79cb73f852da 206 }
wim 1:79cb73f852da 207 write(0x00,0x00,0x00,0x00);
wim 1:79cb73f852da 208 }
wim 1:79cb73f852da 209
wim 1:79cb73f852da 210
wim 1:79cb73f852da 211 /** Initialise LED driver
wim 1:79cb73f852da 212 *
wim 1:79cb73f852da 213 */
wim 0:48adc4a70511 214 void SAA1064::_init() {
wim 1:79cb73f852da 215 uint8_t data[6];
wim 0:48adc4a70511 216
wim 0:48adc4a70511 217 data[0] = SAA1064_CTRL; // Select Control Reg
wim 0:48adc4a70511 218 data[1] = SAA1064_CTRL_DEF | SAA1064_INT3; // Init Control Reg
wim 0:48adc4a70511 219 data[2] = SAA1064_BLNK; // Digit 1: All Segments Off
wim 0:48adc4a70511 220 data[3] = SAA1064_BLNK; // Digit 2: All Segments Off
wim 0:48adc4a70511 221 data[4] = SAA1064_BLNK; // Digit 3: All Segments Off
wim 0:48adc4a70511 222 data[5] = SAA1064_BLNK; // Digit 4: All Segments Off
wim 0:48adc4a70511 223
wim 0:48adc4a70511 224 // data[2] = SAA1064_ALL; // Digit 1: All Segments On
wim 0:48adc4a70511 225 // data[3] = SAA1064_ALL; // Digit 2: All Segments On
wim 0:48adc4a70511 226 // data[4] = SAA1064_ALL; // Digit 3: All Segments On
wim 0:48adc4a70511 227 // data[5] = SAA1064_ALL; // Digit 4: All Segments On
wim 0:48adc4a70511 228
wim 0:48adc4a70511 229 // write data to the display
wim 1:79cb73f852da 230 _i2c->write(_slaveAddress, (char*) data, 6);
wim 0:48adc4a70511 231
wim 0:48adc4a70511 232 };