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.
main.cpp@1:ee2692588275, 2014-04-05 (annotated)
- 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?
User | Revision | Line number | New 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 | } |