Quantcast
Channel: Henriks bits n pieces » XC32
Viewing all articles
Browse latest Browse all 4

Interfacing WS2812B (WS2811) RGB leds with a PIC32MX (250F128B) micro controller source update

$
0
0

This code has been abandoned and updated in another blog post. Click here to see the newer version that I’m currently working on

I have continued working on controlling the WS2812B leds and enhanced the source with a few neat features like draw line, circle and alpha blending.

This code has been tested with a Microchip PIC32MX250F128B micro controller, and XC32 C++ with optimization set to 1

Running this code you should get something like this:

/*
 * File:   main.cpp
 * Author: Henrik Thulin
 *
 * Created on den 2 may 2014, 02:26
 *
 * xc32-g++ optimizer should be set to 1
 */

#pragma config POSCMOD=XT
#pragma config FSOSCEN=OFF
#pragma config FNOSC=PRIPLL
#pragma config OSCIOFNC=ON
#pragma config FPLLODIV=DIV_1
#pragma config FPLLMUL=MUL_20
#pragma config FPLLIDIV=DIV_1
#pragma config FWDTEN=OFF
#pragma config FPBDIV=DIV_1
#pragma config CP=OFF
#pragma config BWP=OFF
#pragma config PWP=OFF

#define SYS_FREQ    (80000000L)
#define GetPeripheralClock()  (FYC/(1 << OSCCONbits.PBDIV))
#define GetInstructionClock()  (FYC)

// For 8x8 leds
#define ROWS 8
#define COLS 8

// B5 is here used as output pin
#define LEDPORT IOPORT_B
#define LEDPIN BIT_5
#define LEDHIGH mPORTBSetBits(LEDPIN);
#define LEDLOW mPORTBClearBits(LEDPIN);

#include 
#include 

unsigned int bitmapBuffer[ROWS*COLS];

// For these timings to be correct, optimization 1 should be used

void sendBitmapPixel(unsigned int x) {

    char i = 24;

    do {
        if ((x >> --i) & 1) {
            LEDHIGH
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            LEDLOW
        } else {
            LEDHIGH
            Nop();
            Nop();
            LEDLOW
            Nop();
            Nop();
            Nop();
            Nop();
        }
    } while (i > 0);

}

void sendBitmapBuffer() {

    for (int i = 0; i < COLS * ROWS; i++)
        sendBitmapPixel(bitmapBuffer[i]);

}

// returns alpha, green, red, blue that'll work with the WS2811, but for simplicity is called ARGB

unsigned int getARGB(unsigned char alpha, unsigned char r, unsigned char g, unsigned char b) {

    return (alpha << 24) | (g << 16) | (r << 8) | b;

}

// converts alpha, red, green and blue to alpha, green, red and blue

unsigned int getARGB(unsigned int i) {

    return (i & 0xff000000) | ((i & 0x00ff0000) >> 8) | ((i & 0x0000ff00) << 8) | (i & 0x000000ff);
}

unsigned int getPixel(char x, char y) {

    return bitmapBuffer[y * COLS + x];

}

unsigned int addAlphaColor(char x, char y, unsigned int add) {

    unsigned int original = getPixel(x, y);

    float alpha = (float) ((add & 0xff000000) >> 24) / 0xff;

    unsigned char green = (((float) ((original >> 16) & 0xff) * (1 - alpha)) + ((float) ((add >> 16) & 0xff) * alpha));
    unsigned char red = (((float) ((original >> 8) & 0xff) * (1 - alpha)) + (((float) ((add >> 8) & 0xff)) * alpha));
    unsigned char blue = (((float) (original & 0xff) * (1 - alpha)) + ((float) ((add & 0xff) * alpha)));

    return (green << 16 | red << 8 | blue);

}

void setPixel(char x, char y, unsigned int color) {

    if (x < 0 || y < 0 || x >= COLS || y >= ROWS) return; // pixels outside the boundaries are ignored

    if (color >> 24 == 0xff) // when full alpha, no need to do any RGB calculations
        bitmapBuffer[y * COLS + x] = color;
    else
        bitmapBuffer[y * COLS + x] = addAlphaColor(x, y, color);

}

void setBackground(unsigned int color) {

    for (int i = 0; i < COLS * ROWS; i++)
        bitmapBuffer[i] = color;

}

void fillRectangle(char x1, char y1, char x2, char y2, unsigned int color) {

    for (int x = x1; x <= x2; x++)
        for (int y = y1; y <= y2; y++)
            setPixel(x, y, color);

}

void drawLine(char x1, char y1, char x2, char y2, unsigned int color) {

    if (x2 < x1) {
        char temp = x1;
        x1 = x2;
        x2 = temp;
    }

    if (y2 < y1) {
        char temp = y1;
        y1 = y2;
        y2 = temp;
    }

    float xPosInc = (x2 - x1 > y2 - y1) ? 1 : (float) (x2 - x1) / (float) (y2 - y1);
    float yPosInc = (y2 - y1 > x2 - x1) ? 1 : (float) (y2 - y1) / (float) (x2 - x1);

    float xpos = x1;
    float ypos = y1;

    for (int i = 0; i <= ((x2 - x1) > (y2 - y1) ? x2 - x1 : y2 - y1); i++) {

        setPixel(xpos, ypos, color);

        xpos += xPosInc;
        ypos += yPosInc;
    }

}

void drawRectangle(char x1, char y1, char x2, char y2, unsigned int color) {

    drawLine(x1, y1, x2, y1, color); // top
    drawLine(x1, y2, x2, y2, color); // bottom
    drawLine(x1, y1, x1, y2, color); // left
    drawLine(x2, y1, x2, y2, color); // right

}

// Not optimized but does the job

void drawCircle(char x, char y, char radius, unsigned int color) {

    for (float angle = 0; angle < 3.142 * 2; angle += 0.1) {

        setPixel(x + round(radius * cos(angle)), y + round(radius * sin(angle)), color);
    }

}

int main() {

    SYSTEMConfigPerformance(80000000L);
    SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
    mJTAGPortEnable(DEBUG_JTAGPORT_OFF);

    PORTSetPinsDigitalOut(LEDPORT, LEDPIN);

    OpenTimer1(T1_ON | T1_PS_1_256, 0xffffff);

    unsigned char r[ROWS][COLS];

    unsigned char i;

    while (1) {
        WriteTimer1(0);

        setBackground(getARGB(0xff000002));

        if (i++ % 2) {
            char s1 = rand() % COLS;
            char s2 = rand() % ROWS;
            if (r[s1][s2] == 0)
                r[s1][s2] = 1;
        }

        for (int y = 0; y < ROWS; y++)
            for (int x = 0; x < COLS; x++) {
                if (r[y][x] > 0) {

                    r[y][x]++;

                    if (r[y][x] < 128)
                        setPixel(x, y, getARGB(r[y][x], 0, 155, 0));
                    else
                        setPixel(x, y, getARGB(0xff - r[y][x], 0, 155, 0));
                }
            }

        sendBitmapBuffer();

        while (ReadTimer1() < 0x3ff) Nop();

    }

    return 0;
}


Viewing all articles
Browse latest Browse all 4

Latest Images

Trending Articles



Latest Images