This is a project to replace the 8051 on a existing RGB LED board and add USB functionality. The original board relied on 8051 firmware to control the LEDs so any changes required software development. This version provides a USB interface for LED control. The USB interface is implemented as a HID with a 9 byte OutReport. In conjunction with a simple GUI the RGB LED board can now be controlled to set color patterns, intensity and pattern sequencing.

Dependencies:   PCA9635-6 mbed USBDevice

RGB GUI - Windows program to control the PCA9635 board.

/media/uploads/JimCarver/rgb_led.jpg

Committer:
frankvnk
Date:
Sat Apr 05 12:27:10 2014 +0000
Revision:
1:ee2692588275
Parent:
0:5e18eb7da208
Reworked RGB2 - PCA9635-6 library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frankvnk 1:ee2692588275 1 /************************************************************************************************
frankvnk 1:ee2692588275 2 *
frankvnk 1:ee2692588275 3 * NXP MCU I2C RGB LED DEMO (6 x PCA9635)
frankvnk 1:ee2692588275 4 * Code ported from http://mbed.org/users/JimCarver/code/RGB2/
frankvnk 1:ee2692588275 5 * Changes : Created a library for the LED DEMO board
frankvnk 1:ee2692588275 6 * LED control GUI : http://mbed.org/users/JimCarver/notebook/rgb-led-control-gui/
frankvnk 1:ee2692588275 7 *
frankvnk 1:ee2692588275 8 ************************************************************************************************/
frankvnk 1:ee2692588275 9
user3736966508731826368 0:5e18eb7da208 10 #include "mbed.h"
user3736966508731826368 0:5e18eb7da208 11 #include "USBHID.h"
frankvnk 1:ee2692588275 12 #include "PCA9635_6.h"
user3736966508731826368 0:5e18eb7da208 13
frankvnk 1:ee2692588275 14 // We declare a USBHID device. By default input and output reports are 64 bytes long.
frankvnk 1:ee2692588275 15 // Note : HID connection on the KL25Z board is marked with 'USB'
frankvnk 1:ee2692588275 16 USBHID hid( 9, 1, 0x1Fc9, 0x0003, 0x0100, 1); // output_report_length, input_report_length, vendor_id, product_id, product_release
frankvnk 1:ee2692588275 17
frankvnk 1:ee2692588275 18 //Ledboard with 6 x PCA9635 - NXP MCU I2C RGB LED DEMO
frankvnk 1:ee2692588275 19 PCA9635_6 ledboard(PTE0, PTE1, PTD7); //SDA, SCL, EN
frankvnk 1:ee2692588275 20
frankvnk 1:ee2692588275 21 DigitalIn SW6(PTD0); // Pull low to run the test pattern at startup.
frankvnk 1:ee2692588275 22 DigitalIn SW5(PTD5); // Status of this pin is written to send_report.data[0]
user3736966508731826368 0:5e18eb7da208 23
user3736966508731826368 0:5e18eb7da208 24 //This report will contain data to be sent
user3736966508731826368 0:5e18eb7da208 25 HID_REPORT send_report;
user3736966508731826368 0:5e18eb7da208 26 HID_REPORT recv_report;
user3736966508731826368 0:5e18eb7da208 27
frankvnk 1:ee2692588275 28 uint8_t dflag, tflag;
user3736966508731826368 0:5e18eb7da208 29
user3736966508731826368 0:5e18eb7da208 30 int dval;
user3736966508731826368 0:5e18eb7da208 31
user3736966508731826368 0:5e18eb7da208 32 typedef struct {
user3736966508731826368 0:5e18eb7da208 33 uint8_t r, g, b;
user3736966508731826368 0:5e18eb7da208 34 } RB_type;
user3736966508731826368 0:5e18eb7da208 35
user3736966508731826368 0:5e18eb7da208 36 RB_type Rainbow[] = {
user3736966508731826368 0:5e18eb7da208 37 255, 0, 0,
user3736966508731826368 0:5e18eb7da208 38 255, 23, 0,
user3736966508731826368 0:5e18eb7da208 39 255, 64, 0,
user3736966508731826368 0:5e18eb7da208 40 255, 127, 0,
user3736966508731826368 0:5e18eb7da208 41 255, 193, 0,
user3736966508731826368 0:5e18eb7da208 42 255, 255, 0,
user3736966508731826368 0:5e18eb7da208 43 193, 255, 0,
user3736966508731826368 0:5e18eb7da208 44 127, 255, 0,
user3736966508731826368 0:5e18eb7da208 45 127, 255, 0,
frankvnk 1:ee2692588275 46 63, 255, 0,
frankvnk 1:ee2692588275 47 0, 255, 0,
frankvnk 1:ee2692588275 48 0, 255, 7,
frankvnk 1:ee2692588275 49 0, 255, 15,
frankvnk 1:ee2692588275 50 0, 255, 31,
frankvnk 1:ee2692588275 51 0, 255, 63,
frankvnk 1:ee2692588275 52 0, 255, 91,
frankvnk 1:ee2692588275 53 0, 255, 127,
frankvnk 1:ee2692588275 54 0, 255, 193,
frankvnk 1:ee2692588275 55 0, 255, 255,
frankvnk 1:ee2692588275 56 0, 193, 255,
frankvnk 1:ee2692588275 57 0, 127, 255,
frankvnk 1:ee2692588275 58 0, 63, 255,
frankvnk 1:ee2692588275 59 0, 0, 255,
frankvnk 1:ee2692588275 60 31, 0, 255,
frankvnk 1:ee2692588275 61 63, 0, 255,
user3736966508731826368 0:5e18eb7da208 62 127, 0, 255,
user3736966508731826368 0:5e18eb7da208 63 193, 0, 255,
user3736966508731826368 0:5e18eb7da208 64 255, 0, 255,
user3736966508731826368 0:5e18eb7da208 65 255, 0, 193,
user3736966508731826368 0:5e18eb7da208 66 255, 0, 127,
user3736966508731826368 0:5e18eb7da208 67 255, 0, 63,
user3736966508731826368 0:5e18eb7da208 68 255, 0, 15
frankvnk 1:ee2692588275 69 };
user3736966508731826368 0:5e18eb7da208 70
user3736966508731826368 0:5e18eb7da208 71 void rainbow_LED( void)
user3736966508731826368 0:5e18eb7da208 72 {
frankvnk 1:ee2692588275 73 int i;
frankvnk 1:ee2692588275 74 for(i=0; i<32; i++) ledboard.set_LED( i, Rainbow[i].r, Rainbow[i].g, Rainbow[i].b );
user3736966508731826368 0:5e18eb7da208 75 }
user3736966508731826368 0:5e18eb7da208 76
user3736966508731826368 0:5e18eb7da208 77 void ripple_LED( void )
user3736966508731826368 0:5e18eb7da208 78 {
frankvnk 1:ee2692588275 79 uint32_t m;
frankvnk 1:ee2692588275 80 uint8_t LEDn, R, G, B, tR, tG, tB;
frankvnk 1:ee2692588275 81 if( dflag) { // Ripple LEDs to the right
frankvnk 1:ee2692588275 82 ledboard.read_LED( 0, &tR, &tG, &tB); // Save the first LED value
frankvnk 1:ee2692588275 83 for(LEDn = 0 , m = 1; LEDn < 31; LEDn++) {
frankvnk 1:ee2692588275 84 ledboard.read_LED( LEDn+1, &R, &G, &B);
frankvnk 1:ee2692588275 85 ledboard.set_LED( LEDn, R, G, B);
frankvnk 1:ee2692588275 86 m = m << 1;
user3736966508731826368 0:5e18eb7da208 87 }
frankvnk 1:ee2692588275 88 ledboard.set_LED( 31, tR, tG, tB);
user3736966508731826368 0:5e18eb7da208 89 } else { // Ripple LEDs to the left
frankvnk 1:ee2692588275 90 ledboard.read_LED( 31, &tR, &tG, &tB);
frankvnk 1:ee2692588275 91 for(LEDn = 31, m = 0x80000000 ; LEDn > 0; LEDn--) {
frankvnk 1:ee2692588275 92 ledboard.read_LED( LEDn - 1, &R, &G, &B);
frankvnk 1:ee2692588275 93 ledboard.set_LED( LEDn, R, G, B);
frankvnk 1:ee2692588275 94 m = m >> 1;
user3736966508731826368 0:5e18eb7da208 95 }
frankvnk 1:ee2692588275 96 ledboard.set_LED( 0, tR, tG, tB);
user3736966508731826368 0:5e18eb7da208 97 }
frankvnk 1:ee2692588275 98 }
frankvnk 1:ee2692588275 99
frankvnk 1:ee2692588275 100
user3736966508731826368 0:5e18eb7da208 101 void test_pattern(void)
user3736966508731826368 0:5e18eb7da208 102 {
frankvnk 1:ee2692588275 103 int l, r, g, b;
frankvnk 1:ee2692588275 104 // Dim Blue Color (from min to max)
frankvnk 1:ee2692588275 105 ledboard.Init_Buffers();
frankvnk 1:ee2692588275 106 for (r = 0, g = 0, b = 0; b < 0xFF; b++) {
frankvnk 1:ee2692588275 107 for(l = 0; l < 32; l++) {
frankvnk 1:ee2692588275 108 ledboard.set_LED( l, r, g, b);
frankvnk 1:ee2692588275 109 }
frankvnk 1:ee2692588275 110 ledboard.update_LED();
frankvnk 1:ee2692588275 111 }
frankvnk 1:ee2692588275 112 // Mix from Only Blue (Max going to off) to Only Green (off to Max)
frankvnk 1:ee2692588275 113 for (r = 0, g = 0, b = 0xFF; b >= 0x00; b--) {
frankvnk 1:ee2692588275 114 for(l = 0; l < 32; l++) {
frankvnk 1:ee2692588275 115 ledboard.set_LED( l, r, g, b);
frankvnk 1:ee2692588275 116 }
frankvnk 1:ee2692588275 117 ledboard.update_LED();
frankvnk 1:ee2692588275 118 g++;
user3736966508731826368 0:5e18eb7da208 119 }
frankvnk 1:ee2692588275 120 // Mix from Only Green (Max going to off) to Only Red (off to Max)
frankvnk 1:ee2692588275 121 for (r = 0, g = 0xFF, b = 0; g >= 0x00; g--) {
frankvnk 1:ee2692588275 122 for (l = 0; l < 32; l++) {
frankvnk 1:ee2692588275 123 ledboard.set_LED( l, r, g, b);
user3736966508731826368 0:5e18eb7da208 124 }
frankvnk 1:ee2692588275 125 ledboard.update_LED();
frankvnk 1:ee2692588275 126 r++;
user3736966508731826368 0:5e18eb7da208 127 }
frankvnk 1:ee2692588275 128 // Mix from Only Red (Max going to off) to Only Blue (off to Max)
frankvnk 1:ee2692588275 129 for (r = 0xFF, g = 0, b = 0; r >= 0x00; r--) {
frankvnk 1:ee2692588275 130 for (l = 0; l < 32; l++) {
frankvnk 1:ee2692588275 131 ledboard.set_LED( l, r, g, b);
user3736966508731826368 0:5e18eb7da208 132 }
frankvnk 1:ee2692588275 133 ledboard.update_LED();
frankvnk 1:ee2692588275 134 b++;
user3736966508731826368 0:5e18eb7da208 135 }
frankvnk 1:ee2692588275 136 rainbow_LED();
frankvnk 1:ee2692588275 137 ledboard.update_LED();
user3736966508731826368 0:5e18eb7da208 138 }
user3736966508731826368 0:5e18eb7da208 139
user3736966508731826368 0:5e18eb7da208 140 void SetOutReport (void)
user3736966508731826368 0:5e18eb7da208 141 {
frankvnk 1:ee2692588275 142 int LEDn;
frankvnk 1:ee2692588275 143 uint32_t led, m;
frankvnk 1:ee2692588275 144 uint8_t R, G, B, seq;
user3736966508731826368 0:5e18eb7da208 145
user3736966508731826368 0:5e18eb7da208 146 /* Check the bits of the "OutReport" data from the PC
user3736966508731826368 0:5e18eb7da208 147 * and set the output port status. */
frankvnk 1:ee2692588275 148 seq = recv_report.data[0];
frankvnk 1:ee2692588275 149 //LED_Report = (LED_Report_type *) &recv_report.data[1];
frankvnk 1:ee2692588275 150 ledboard.set_global_intensity(recv_report.data[8]);
frankvnk 1:ee2692588275 151 if(seq) {
frankvnk 1:ee2692588275 152 tflag = 2;
frankvnk 1:ee2692588275 153 dflag = seq & 1;
frankvnk 1:ee2692588275 154 dval = (seq & 0xFC) >> 1; // sets a range from 0x00 to 0x7E
user3736966508731826368 0:5e18eb7da208 155 } else {
frankvnk 1:ee2692588275 156 led = recv_report.data[4];
frankvnk 1:ee2692588275 157 led <<= 8;
frankvnk 1:ee2692588275 158 led |= recv_report.data[3];
frankvnk 1:ee2692588275 159 led <<= 8;
frankvnk 1:ee2692588275 160 led |= recv_report.data[2];
frankvnk 1:ee2692588275 161 led <<= 8;
frankvnk 1:ee2692588275 162 led |= recv_report.data[1];
frankvnk 1:ee2692588275 163
frankvnk 1:ee2692588275 164 R = recv_report.data[5];
frankvnk 1:ee2692588275 165 G = recv_report.data[6];
frankvnk 1:ee2692588275 166 B = recv_report.data[7];
frankvnk 1:ee2692588275 167 for(LEDn=0, m=1; LEDn < 32; LEDn++, m <<= 1) {
frankvnk 1:ee2692588275 168 if(led & m) {
frankvnk 1:ee2692588275 169 ledboard.set_LED( LEDn, R, G, B);
user3736966508731826368 0:5e18eb7da208 170 }
user3736966508731826368 0:5e18eb7da208 171 }
frankvnk 1:ee2692588275 172 tflag = 1;
user3736966508731826368 0:5e18eb7da208 173 }
user3736966508731826368 0:5e18eb7da208 174 }
user3736966508731826368 0:5e18eb7da208 175
user3736966508731826368 0:5e18eb7da208 176 /***********************************************************************
frankvnk 1:ee2692588275 177 DESCRIPTION: Main function
frankvnk 1:ee2692588275 178 INPUT(S): None
frankvnk 1:ee2692588275 179 RETURNS: Nothing
user3736966508731826368 0:5e18eb7da208 180 ************************************************************************/
user3736966508731826368 0:5e18eb7da208 181 int main (void)
user3736966508731826368 0:5e18eb7da208 182 {
frankvnk 1:ee2692588275 183 if(!SW6) test_pattern();
frankvnk 1:ee2692588275 184 dflag = 0;
frankvnk 1:ee2692588275 185 dval = 10;
frankvnk 1:ee2692588275 186 tflag = 0;
frankvnk 1:ee2692588275 187 send_report.length = 1;
frankvnk 1:ee2692588275 188 while (1) {
frankvnk 1:ee2692588275 189 send_report.data[0] = SW5;
frankvnk 1:ee2692588275 190 hid.send(&send_report);
frankvnk 1:ee2692588275 191 if(hid.readNB(&recv_report)) SetOutReport();
frankvnk 1:ee2692588275 192 if(tflag == 2) {
frankvnk 1:ee2692588275 193 ripple_LED();
frankvnk 1:ee2692588275 194 ledboard.update_LED();
frankvnk 1:ee2692588275 195 ledboard.LED_INTENSITY();
frankvnk 1:ee2692588275 196 wait_ms(dval);
frankvnk 1:ee2692588275 197 }
user3736966508731826368 0:5e18eb7da208 198
frankvnk 1:ee2692588275 199 if(tflag == 1) {
frankvnk 1:ee2692588275 200 ledboard.update_LED();
frankvnk 1:ee2692588275 201 ledboard.LED_INTENSITY();
frankvnk 1:ee2692588275 202 tflag = 0;
frankvnk 1:ee2692588275 203 }
user3736966508731826368 0:5e18eb7da208 204 }
user3736966508731826368 0:5e18eb7da208 205 }