LED bus driver on any GPIO pin for addressable RGB LEDs (like NeoPixels or other WS2812 based LEDs)

Committer:
koengroener
Date:
Wed Jun 14 20:37:31 2017 +0000
Revision:
3:67e68c46daef
Parent:
2:735bb1b9cfc2
Added LEDArray class, for a more simplistic way of communcation with the LED strip

Who changed what in which revision?

UserRevisionLine numberNew contents of line
koengroener 0:1e68c70236a4 1 #include "LEDBus.h"
koengroener 0:1e68c70236a4 2
koengroener 2:735bb1b9cfc2 3 LEDBus::LEDBus(PinName wirePin, ColorByteOrder byteOrder, float t0h_us, float t0l_us, float t1h_us, float t1l_us, float tReset_us) : _wire(wirePin)
koengroener 0:1e68c70236a4 4 {
koengroener 0:1e68c70236a4 5 float ticksPerMicroSecond = SystemCoreClock/MICRO_SECOND;
koengroener 0:1e68c70236a4 6
koengroener 0:1e68c70236a4 7 _byteOrder = byteOrder;
koengroener 0:1e68c70236a4 8
koengroener 0:1e68c70236a4 9 _delayT1H = ticksPerMicroSecond * t1h_us;
koengroener 0:1e68c70236a4 10 _delayT0H = ticksPerMicroSecond * t0h_us;
koengroener 0:1e68c70236a4 11 _delayT1L = ticksPerMicroSecond * t1l_us;
koengroener 0:1e68c70236a4 12 _delayT0L = ticksPerMicroSecond * t0l_us;
koengroener 0:1e68c70236a4 13
koengroener 0:1e68c70236a4 14 _delayReset = ticksPerMicroSecond * tReset_us;
koengroener 0:1e68c70236a4 15
koengroener 0:1e68c70236a4 16 // Uncomment to see micro controller frequency and delays
koengroener 1:6119419c2730 17 // Serial pc(USBTX, USBRX);
koengroener 1:6119419c2730 18 // pc.printf("%d Hz\n\r", SystemCoreClock);
koengroener 1:6119419c2730 19 // pc.printf("%f ticks/us\n\r", ticksPerMicroSecond);
koengroener 1:6119419c2730 20 // pc.printf("T0H: %d ticks\n\r", _delayT0H);
koengroener 1:6119419c2730 21 // pc.printf("T1H: %d ticks\n\r", _delayT1H);
koengroener 1:6119419c2730 22 // pc.printf("T0L: %d ticks\n\r", _delayT0L);
koengroener 1:6119419c2730 23 // pc.printf("T1L: %d ticks\n\r", _delayT1L);
koengroener 1:6119419c2730 24 // pc.printf("Reset: %d ticks\n\r", _delayReset);
koengroener 0:1e68c70236a4 25
koengroener 0:1e68c70236a4 26 }
koengroener 0:1e68c70236a4 27
koengroener 0:1e68c70236a4 28 LEDBus::~LEDBus()
koengroener 0:1e68c70236a4 29 {
koengroener 0:1e68c70236a4 30 }
koengroener 0:1e68c70236a4 31
koengroener 0:1e68c70236a4 32 void LEDBus::write(uint8_t byte)
koengroener 0:1e68c70236a4 33 {
koengroener 0:1e68c70236a4 34 for (int b = 7; b >= 0; b--) {
koengroener 0:1e68c70236a4 35 bool bit = byte & (1 << b);
koengroener 0:1e68c70236a4 36
koengroener 0:1e68c70236a4 37 _wire = 1;
koengroener 0:1e68c70236a4 38
koengroener 0:1e68c70236a4 39 if (bit) {
koengroener 0:1e68c70236a4 40 delay(_delayT1H);
koengroener 0:1e68c70236a4 41 } else {
koengroener 0:1e68c70236a4 42 delay(_delayT0H);
koengroener 0:1e68c70236a4 43 }
koengroener 0:1e68c70236a4 44
koengroener 0:1e68c70236a4 45 _wire = 0;
koengroener 0:1e68c70236a4 46
koengroener 0:1e68c70236a4 47 if (bit) {
koengroener 0:1e68c70236a4 48 delay(_delayT1L);
koengroener 0:1e68c70236a4 49 } else {
koengroener 0:1e68c70236a4 50 delay(_delayT0L);
koengroener 0:1e68c70236a4 51 }
koengroener 0:1e68c70236a4 52 }
koengroener 0:1e68c70236a4 53 }
koengroener 0:1e68c70236a4 54
koengroener 2:735bb1b9cfc2 55 void LEDBus::delay(unsigned const int ticks)
koengroener 0:1e68c70236a4 56 {
koengroener 2:735bb1b9cfc2 57 //loop_ticks is empirically determined (aka: works on my machine...)
koengroener 2:735bb1b9cfc2 58 const int loop_ticks = 8;
koengroener 2:735bb1b9cfc2 59 for (unsigned volatile int i = 0; i <= ticks-(loop_ticks/2); i+=loop_ticks) {
koengroener 0:1e68c70236a4 60 /* nop */
koengroener 0:1e68c70236a4 61 }
koengroener 0:1e68c70236a4 62 }
koengroener 0:1e68c70236a4 63
koengroener 0:1e68c70236a4 64 void LEDBus::write(uint8_t* buffer, unsigned int size)
koengroener 0:1e68c70236a4 65 {
koengroener 0:1e68c70236a4 66 for (int i = 0; i < size; i++) {
koengroener 0:1e68c70236a4 67 write(buffer[i]);
koengroener 0:1e68c70236a4 68 }
koengroener 0:1e68c70236a4 69
koengroener 0:1e68c70236a4 70 delay(_delayReset);
koengroener 0:1e68c70236a4 71 }
koengroener 0:1e68c70236a4 72
koengroener 0:1e68c70236a4 73 void LEDBus::write(Color** buffer, unsigned int size)
koengroener 0:1e68c70236a4 74 {
koengroener 0:1e68c70236a4 75 for (int i = 0; i < size; i++) {
koengroener 0:1e68c70236a4 76 switch(_byteOrder) {
koengroener 0:1e68c70236a4 77 case RGB:
koengroener 0:1e68c70236a4 78 write(buffer[i]->red);
koengroener 0:1e68c70236a4 79 write(buffer[i]->green);
koengroener 0:1e68c70236a4 80 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 81 break;
koengroener 0:1e68c70236a4 82 case RBG:
koengroener 0:1e68c70236a4 83 write(buffer[i]->red);
koengroener 0:1e68c70236a4 84 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 85 write(buffer[i]->green);
koengroener 0:1e68c70236a4 86 break;
koengroener 0:1e68c70236a4 87 case GRB:
koengroener 0:1e68c70236a4 88 write(buffer[i]->green);
koengroener 0:1e68c70236a4 89 write(buffer[i]->red);
koengroener 0:1e68c70236a4 90 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 91 break;
koengroener 0:1e68c70236a4 92 case GBR:
koengroener 0:1e68c70236a4 93 write(buffer[i]->green);
koengroener 0:1e68c70236a4 94 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 95 write(buffer[i]->red);
koengroener 0:1e68c70236a4 96 break;
koengroener 0:1e68c70236a4 97 case BRG:
koengroener 0:1e68c70236a4 98 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 99 write(buffer[i]->red);
koengroener 0:1e68c70236a4 100 write(buffer[i]->green);
koengroener 0:1e68c70236a4 101 case BGR:
koengroener 0:1e68c70236a4 102 write(buffer[i]->blue);
koengroener 0:1e68c70236a4 103 write(buffer[i]->green);
koengroener 0:1e68c70236a4 104 write(buffer[i]->red);
koengroener 0:1e68c70236a4 105 break;
koengroener 0:1e68c70236a4 106 }
koengroener 0:1e68c70236a4 107
koengroener 0:1e68c70236a4 108 }
koengroener 0:1e68c70236a4 109
koengroener 0:1e68c70236a4 110 delay(_delayReset);
koengroener 0:1e68c70236a4 111 }
koengroener 0:1e68c70236a4 112
koengroener 0:1e68c70236a4 113
koengroener 0:1e68c70236a4 114 void LEDBus::update(ColorGenerator generator, unsigned int numberOfLEDs)
koengroener 0:1e68c70236a4 115 {
koengroener 0:1e68c70236a4 116 unsigned char buffer[numberOfLEDs*3];
koengroener 0:1e68c70236a4 117
koengroener 0:1e68c70236a4 118 for (int i = 0; i < numberOfLEDs; i++) {
koengroener 0:1e68c70236a4 119 Color* color = new Color();
koengroener 0:1e68c70236a4 120 generator(color, i);
koengroener 0:1e68c70236a4 121
koengroener 0:1e68c70236a4 122 int ir,ig,ib;
koengroener 0:1e68c70236a4 123
koengroener 0:1e68c70236a4 124 switch(_byteOrder) {
koengroener 0:1e68c70236a4 125 case RGB:
koengroener 0:1e68c70236a4 126 ir = 0;
koengroener 0:1e68c70236a4 127 ig = 1;
koengroener 0:1e68c70236a4 128 ib = 2;
koengroener 0:1e68c70236a4 129 break;
koengroener 0:1e68c70236a4 130 case RBG:
koengroener 0:1e68c70236a4 131 ir = 0;
koengroener 0:1e68c70236a4 132 ig = 2;
koengroener 0:1e68c70236a4 133 ib = 1;
koengroener 0:1e68c70236a4 134 break;
koengroener 0:1e68c70236a4 135 case GRB:
koengroener 0:1e68c70236a4 136 ir = 1;
koengroener 0:1e68c70236a4 137 ig = 0;
koengroener 0:1e68c70236a4 138 ib = 2;
koengroener 0:1e68c70236a4 139 break;
koengroener 0:1e68c70236a4 140 case GBR:
koengroener 0:1e68c70236a4 141 ir = 2;
koengroener 0:1e68c70236a4 142 ig = 0;
koengroener 0:1e68c70236a4 143 ib = 1;
koengroener 0:1e68c70236a4 144 break;
koengroener 0:1e68c70236a4 145 case BRG:
koengroener 0:1e68c70236a4 146 ir = 1;
koengroener 0:1e68c70236a4 147 ig = 2;
koengroener 0:1e68c70236a4 148 ib = 0;
koengroener 0:1e68c70236a4 149 case BGR:
koengroener 0:1e68c70236a4 150 ir = 2;
koengroener 0:1e68c70236a4 151 ig = 1;
koengroener 0:1e68c70236a4 152 ib = 0;
koengroener 0:1e68c70236a4 153 break;
koengroener 0:1e68c70236a4 154 }
koengroener 0:1e68c70236a4 155
koengroener 0:1e68c70236a4 156 buffer[i*3 +ir] = color->red;
koengroener 0:1e68c70236a4 157 buffer[i*3 +ig] = color->green;
koengroener 0:1e68c70236a4 158 buffer[i*3 +ib] = color->blue;
koengroener 0:1e68c70236a4 159
koengroener 0:1e68c70236a4 160 delete color;
koengroener 0:1e68c70236a4 161 }
koengroener 0:1e68c70236a4 162
koengroener 0:1e68c70236a4 163 write(buffer, numberOfLEDs*3);
koengroener 0:1e68c70236a4 164 }
koengroener 0:1e68c70236a4 165
koengroener 0:1e68c70236a4 166