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.
Revision 0:55c62e840faf, committed 2015-12-19
- Comitter:
 - amateusz
 - Date:
 - Sat Dec 19 13:30:30 2015 +0000
 - Commit message:
 - Use a 7-segment display with any (eh, sort of) number of digits. Display connected with shift registers, e.g. 4094. More details and picture in header file.
 
Changed in this revision
| LED7segmDual4094.cpp | Show annotated file Show diff for this revision Revisions of this file | 
| LED7segmDual4094.h | Show annotated file Show diff for this revision Revisions of this file | 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LED7segmDual4094.cpp	Sat Dec 19 13:30:30 2015 +0000
@@ -0,0 +1,242 @@
+#include "mbed.h"
+#include "LED7segmDual4094.h"
+
+signed char LED7segmDual4094::digitORascii2char (char input, bool dot) {
+  signed char return7seg = 0;
+  switch (input) {
+    case 0:
+    case '0':
+    case 'O':
+      return7seg =  0b00111111;
+      break;
+    case '1':
+    case 1:
+      return7seg =  0b00000110;
+      break;
+    case '2':
+    case 2:
+    case 'z':
+    case 'Z':
+      return7seg =  0b01011011;
+      break;
+    case 3:
+    case '3':
+      return7seg =  0b01001111;
+      break;
+    case 4:
+    case '4':
+      return7seg =  0b01100110;
+      break;
+    case 5:
+    case '5':
+      return7seg =  0b01101101;
+      break;
+    case 6:
+    case '6':
+      return7seg =  0b01111100;
+      break;
+    case 7:
+    case '7':
+      return7seg =  0b00000111;
+      break;
+    case 8:
+    case '8':
+      return7seg =  0b01111111;
+      break;
+    case 9:
+    case '9':
+      return7seg = 0b01100111;
+      break;
+    case 'a':
+    case 'A':
+      return7seg = 0b01110111;
+      break;
+    case 'b':
+    case 'B':
+      return7seg = 0b01111100;
+      break;
+    case 'c':
+      return7seg = 0b01011000;
+      break;
+    case 'C':
+      return7seg = 0b00111001;
+      break;
+    case 'd':
+    case 'D':
+      return7seg = 0b01011110;
+      break;
+    case 'e':
+      return7seg = 0b01111011;
+      break;
+    case 'E':
+      return7seg = 0b01111001;
+      break;
+    case 'f':
+    case 'F':
+      return7seg = 0b01110001;
+      break;
+    case 'g':
+      return7seg = 0b01101111;
+    case 'G':
+      return7seg = 0b00111101;
+      break;
+    case 'h':
+      return7seg = 0b01110100;
+      break;
+    case 'H':
+      return7seg = 0b01110110;
+      break;
+    case 'i':
+      return7seg = 0b00010000;
+      break;
+    case 'I':
+      return7seg = 0b00110000;
+      break;
+    case 'j':
+      return7seg = 0b00001111;
+      break;
+    case 'J':
+      return7seg = 0b00011111;
+      break;
+    case 'k':
+      return7seg = 0b01111000;
+      break;
+    case 'l':
+      return7seg = 0b00110000;
+      break;
+    case 'L':
+      return7seg = 0b00111000;
+      break;
+    case 'm':
+    case 'n':
+      return7seg = 0b01010100;
+      break;
+    case 'N':
+    case 'M':
+      return7seg = 0b00110111;
+      break;
+    case 'o':
+      return7seg = 0b01011100;
+      break;
+    case 'p':
+    case 'P':
+      return7seg = 0b01110011;
+      break;
+    case 'r':
+    case 'R':
+      return7seg = 0b01010000;
+      break;
+    case 's':
+    case 'S':
+      return7seg = 0b01101101;
+      break;
+    case 'q':
+    case 'Q':
+      return7seg = 0b01100111;
+      break;
+    case 't':
+    case 'T':
+      return7seg = 0b01111000;
+      break;
+    case 'u':
+      return7seg = 0b00011100;
+      break;
+    case 'U':
+      return7seg = 0b00111110;
+      break;
+    case 'v':
+    case 'V':
+      return7seg = 0b00111100;
+      break;
+    case 'w':
+    case 'W':
+      return7seg = 0b01001001;
+      break;
+    case 'x':
+    case 'X':
+      return7seg = 0b01110110;
+      break;
+    case 'y':
+    case 'Y':
+      return7seg = 0b01101110;
+      break;
+    case ' ':
+      return7seg = 0b00000000;
+      break;
+    default:
+      return7seg =  -1;
+      break;
+  }
+  if (dot) return7seg |= (1 << 7);
+  // else clearing the dot ?
+  return return7seg;
+}
+
+LED7segmDual4094::LED7segmDual4094(PinName data, PinName clock, PinName strobe, char numOfSegments): _data(data), _clock(clock), _strobe(strobe) {
+  whichSegmMux = 0;
+  _numOfSegments = numOfSegments;
+  fb = new char [_numOfSegments];
+  _anodesBitMask = new unsigned int[_numOfSegments];
+  for (unsigned int i = 0; i < numOfSegments; i++)
+    _anodesBitMask[i] = ( 1 << i );
+}
+void LED7segmDual4094::setAnodesBitMask(unsigned int *tab) {
+  for (char i = 0; i < _numOfSegments; i++)
+    _anodesBitMask[i] = tab[i];
+};
+void LED7segmDual4094::draw(void){ // a version with no arguments is for internal (i.e. private) use only. the other one is exposed publicly.
+  if (_anodesActiveState)
+	load = 0;
+  else load = ~0;
+  for (char i = 0; i < 8; i++) {
+    if ((fb[whichSegmMux] >> i) & 0x1) load |= 1 << ( 8 + i);
+	else load &= ~(1 << (8+i)); 
+  }
+  if (!_anodesActiveState) {
+    load &= ~_anodesBitMask[(_numOfSegments-1) - whichSegmMux];
+	/*for (int i = 0; i < _numOfSegments; i++)
+      if (whichSegmMux != (_numOfSegments - 1) - i) // when ""if(whichSegmMux != i)"" then reverse direction of printing.
+        load |= _anodesBitMask[i];
+    //load &= ~(_anodesBitMask[(_numOfSegments-1) - whichSegmMux]);
+	*/
+  } else
+    load |= 1 << (_numOfSegments - whichSegmMux); // sets a bit indicating which segment to light up (connect kathode (or anode, I mean positive rail))
+  send4094(load);
+  if (++whichSegmMux > (_numOfSegments - 1)) whichSegmMux = 0;
+}
+/* void LED7segmDual4094::draw(char *tab) {
+  // whichSegmMux equals 0 on start thanks to the header file. || which segment for multiplexing
+  if (_anodesActiveState)
+	load = 0;
+  else load = ~0;
+  for (char i = 0; i < 8; i++) {
+    if ((tab[whichSegmMux] >> i) & 0x1) load |= 1 << ( 8 + i);
+	else load &= ~(1 << (8+i)); 
+  }
+  if (!_anodesActiveState) {
+    load &= ~_anodesBitMask[(_numOfSegments-1) - whichSegmMux];
+	//for (int i = 0; i < _numOfSegments; i++)
+    //  if (whichSegmMux != (_numOfSegments - 1) - i) // when ""if(whichSegmMux != i)"" then reverse direction of printing.
+    //    load |= _anodesBitMask[i];
+    //load &= ~(_anodesBitMask[(_numOfSegments-1) - whichSegmMux]);
+	//
+  } else
+    load |= 1 << (_numOfSegments - whichSegmMux); // sets a bit indicating which segment to light up (connect kathode (or anode, I mean positive rail))
+  send4094(load);
+  if (++whichSegmMux > (_numOfSegments - 1)) whichSegmMux = 0;
+}
+*/
+
+void LED7segmDual4094::send4094(unsigned short _load) { // this shit is straight from the datasheet, just loading these 16bits to two daisy-chained 4094 shift registers
+  _strobe = 0;
+  for (signed char _i = 15; _i >= 0; _i--) {
+    _data =  (_load >> _i) & 0x1 ;
+    _clock = 0;
+    _clock = 1;
+  }
+  _strobe = 1;
+}
+
+void LED7segmDual4094::setAnodesActiveState(bool state) {
+  _anodesActiveState = state;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LED7segmDual4094.h	Sat Dec 19 13:30:30 2015 +0000
@@ -0,0 +1,39 @@
+/* This library lets to use a led display made of at most 8 segments as a screen buffer device. Like this one: https://www.dropbox.com/s/a3rvqahxhvpj0w3/general.jpg?dl=0
+The dispaly has to be made of two shift registers - i used 4094 and they are guaranteed to work, but others may also without any change to the code. The 8 digits limit can be easily overcomed daisy-chaining more shift registers. Have in mind though that it will cause the dispaly to be dimmer.
+This library lets you treat the display as a screen buffer device i.e. each digit is a byte-sized and bits are ordered as usual ABCDEFG scheme goes. Object has a field fb, which is the size you have it initialized.
+Size 4 by default. So just write to object.fb[n] whatever you want. You can do all sorts of bitwise operations. And then you have to take care of calling the draw() method periodcaly to update the display. (preffered way: use systick or timer).
+There is also provided function to convert most ASCII characters to bitmasked segments: digitORascii2char. It also allows to toggle a dot. Hope you like it.
+There is a bonus feature: you can arrange the common cathodes/anodes in any way in the shift registers, because you can initialise the library with given order of them.
+The same with segments. (in progress). Moreover there can be different layout of segments between each digit (also not done). Whoa!
+*/
+#include "mbed.h"
+
+#ifndef LED7segmDual4094_h
+#define LED7segmDual4094_h
+	
+class LED7segmDual4094{
+	private:
+		char _numOfSegments;
+		unsigned int *_anodesBitMask;
+		unsigned int _segmentsBitMask;
+		bool _anodesActiveState;
+		DigitalOut _data;
+		DigitalOut _clock;
+		DigitalOut _strobe;
+		void send4094(unsigned short _load);
+	public:
+		LED7segmDual4094(PinName data, PinName clock, PinName strobe, char numOfSegments = 4);
+		char *fb;
+		void draw();
+		void setAnodesBitMask(unsigned int *tab);
+		void setAnodesActiveState(bool state);
+//		void draw(char *tab);
+		unsigned short load;
+		//char i;
+		char whichSegmMux;			
+		signed char digitORascii2char(char input, bool dot=0);
+//		signed char return7seg;
+	
+};
+		
+#endif
\ No newline at end of file