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

main.cpp

Committer:
frankvnk
Date:
2014-04-05
Revision:
1:ee2692588275
Parent:
0:5e18eb7da208

File content as of revision 1:ee2692588275:

/************************************************************************************************
*
* NXP MCU I2C RGB LED DEMO (6 x PCA9635)
* Code ported from http://mbed.org/users/JimCarver/code/RGB2/
* Changes : Created a library for the LED DEMO board
* LED control GUI : http://mbed.org/users/JimCarver/notebook/rgb-led-control-gui/
*
************************************************************************************************/

#include "mbed.h"
#include "USBHID.h"
#include "PCA9635_6.h"

// We declare a USBHID device. By default input and output reports are 64 bytes long.
// Note : HID connection on the KL25Z board is marked with 'USB'
USBHID hid( 9, 1, 0x1Fc9, 0x0003, 0x0100, 1); // output_report_length, input_report_length, vendor_id, product_id, product_release

//Ledboard with 6 x PCA9635 - NXP MCU I2C RGB LED DEMO
PCA9635_6 ledboard(PTE0, PTE1, PTD7); //SDA, SCL, EN

DigitalIn SW6(PTD0);    // Pull low to run the test pattern at startup.
DigitalIn SW5(PTD5);    // Status of this pin is written to send_report.data[0]

//This report will contain data to be sent
HID_REPORT send_report;
HID_REPORT recv_report;

uint8_t dflag, tflag;

int dval;

typedef struct {
    uint8_t r, g, b;
    } RB_type;

RB_type Rainbow[] = {
    255,   0,   0,
    255,  23,   0,
    255,  64,   0,
    255, 127,   0,
    255, 193,   0,
    255, 255,   0,
    193, 255,   0,
    127, 255,   0,
    127, 255,   0,
    63, 255,   0,
    0, 255,   0,
    0, 255,   7,
    0, 255,  15,
    0, 255,  31,
    0, 255,  63,
    0, 255,  91,
    0, 255, 127,
    0, 255, 193,
    0, 255, 255,
    0, 193, 255,
    0, 127, 255,
    0,  63, 255,
    0,   0, 255,
    31,   0, 255,
    63,   0, 255,
    127,   0, 255,
    193,   0, 255,
    255,   0, 255,
    255,   0, 193,
    255,   0, 127,
    255,   0,  63,
    255,   0,  15
};

void rainbow_LED( void)
{
    int i;
    for(i=0; i<32; i++) ledboard.set_LED( i, Rainbow[i].r, Rainbow[i].g, Rainbow[i].b );
}

void ripple_LED( void )
{
    uint32_t  m;
    uint8_t LEDn, R, G, B, tR, tG, tB;
    if( dflag) {   // Ripple LEDs to the right
        ledboard.read_LED( 0, &tR, &tG, &tB);    // Save the first LED value
        for(LEDn = 0 , m = 1; LEDn < 31; LEDn++) {
            ledboard.read_LED( LEDn+1, &R, &G, &B);
            ledboard.set_LED(  LEDn, R, G, B);
            m = m << 1;
        }
        ledboard.set_LED(  31, tR, tG, tB);
    } else {  // Ripple LEDs to the left
        ledboard.read_LED( 31, &tR, &tG, &tB);
        for(LEDn = 31, m = 0x80000000 ; LEDn > 0; LEDn--) {
            ledboard.read_LED( LEDn - 1, &R, &G, &B);
            ledboard.set_LED(  LEDn, R, G, B);
            m = m >> 1;
        }
        ledboard.set_LED(  0, tR, tG, tB);
    }
}


void test_pattern(void)
{
    int l, r, g, b;
    // Dim Blue Color (from min to max)
    ledboard.Init_Buffers();
    for (r = 0, g = 0, b = 0; b < 0xFF; b++) {
        for(l = 0; l < 32; l++) {
            ledboard.set_LED( l, r, g, b);
        }
        ledboard.update_LED();
    }
    // Mix from Only Blue (Max going to off) to Only Green (off to Max)
    for (r = 0, g = 0, b = 0xFF; b >= 0x00; b--) {
        for(l = 0; l < 32; l++) {
            ledboard.set_LED( l, r, g, b);
        }
        ledboard.update_LED();
        g++;
    }
    // Mix from Only Green (Max going to off) to Only Red (off to Max)
    for (r = 0, g = 0xFF, b = 0; g >= 0x00; g--)  {
        for (l = 0; l < 32; l++) {
            ledboard.set_LED( l, r, g, b);
        }
        ledboard.update_LED();
        r++;
    }
    // Mix from Only Red (Max going to off) to Only Blue (off to Max)
    for (r = 0xFF, g = 0, b = 0; r >= 0x00; r--) {
        for (l = 0; l < 32; l++) {
            ledboard.set_LED( l, r, g, b);
        }
        ledboard.update_LED();
        b++;
    }
    rainbow_LED();
    ledboard.update_LED();
}

void SetOutReport (void)
{
    int LEDn;
    uint32_t led, m;
    uint8_t  R, G, B, seq;

    /* Check the bits of the "OutReport" data from the PC
     * and set the output port status. */
    seq = recv_report.data[0];
    //LED_Report = (LED_Report_type *) &recv_report.data[1];
    ledboard.set_global_intensity(recv_report.data[8]);
    if(seq) {
        tflag = 2;
        dflag = seq & 1;
        dval = (seq & 0xFC) >> 1; // sets a range from 0x00 to 0x7E
    } else {
        led = recv_report.data[4];
        led <<= 8;
        led |= recv_report.data[3];
        led <<= 8;
        led |= recv_report.data[2];
        led <<= 8;
        led |= recv_report.data[1];

        R = recv_report.data[5];
        G = recv_report.data[6];
        B = recv_report.data[7];
        for(LEDn=0, m=1; LEDn < 32; LEDn++, m <<= 1) {
            if(led & m) {
                ledboard.set_LED( LEDn, R, G, B);
            }
        }
        tflag = 1;
    }
}

/***********************************************************************
DESCRIPTION:   Main function
INPUT(S):      None
RETURNS:       Nothing
************************************************************************/
int main (void)
{
    if(!SW6) test_pattern();
    dflag = 0;
    dval = 10;
    tflag = 0;
    send_report.length = 1;
    while (1) {
        send_report.data[0] = SW5;
        hid.send(&send_report);
        if(hid.readNB(&recv_report)) SetOutReport();
        if(tflag == 2) {
            ripple_LED();
            ledboard.update_LED();
            ledboard.LED_INTENSITY();
            wait_ms(dval);
        }

        if(tflag == 1) {
            ledboard.update_LED();
            ledboard.LED_INTENSITY();
            tflag = 0;
        }
    }
}