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

Interfacing WS2812B RGB LED with a Microchip PIC32MX250F128B

$
0
0

Been working on a bit-banging routine for WS2812B RGB LED for the last couple of hours. It has been pretty tricky getting the correct timings, but ultimately through trial and error the timings were right. At 600 kHz there was ocassional flickering but after lowering it to around 500 kHz I haven’t been able to detect any.

Microcontroller used is a PIC32MX250F128B, and the leds were purchased from eBay seller ws2811.

The output from the micro-controller currently looks like this:
RIGOL Print Screen2014-04-27 20_38_10,211

Here is a short video that I shot of 8 RGB leds in action:

For this code to run properly, you need to set the optimizer to 1. I will see if I can add inline assembler for this, but until then…

Compiler used is Microchip XC32 1.31. Code below is a draft, and can probably be optimized further, but hey it works! :-)

Hopefully I’ll get more work done next weekend. If you know a better way or have a suggestion I’d be happy to hear it

Click here to check out my new code with features such as alpha blending and pixel control

Source:

/*
 /*
 * File:   main.cpp
 * Author: Henrik Thulin
 *
 * Created on den 27 april 2014, 02:26
 *
 * In this example I'm interfacing 8 leds connected to PORTB5
 * 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)

#include 

void SendData(unsigned int x) {
    char i = 24;

    do {
        if ((x >> --i) & 1) {
            mPORTBSetBits(BIT_5);
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            mPORTBClearBits(BIT_5);
        } else {
            mPORTBSetBits(BIT_5);
            Nop();
            Nop();
            Nop();
            mPORTBClearBits(BIT_5);
            Nop();
            Nop();
            Nop();
            Nop();
        }
    } while (i > 0);
}

void SendMultiple(unsigned int length, const unsigned int* x) {
    while (length-- > 0)
        SendData(x[length]);
}

unsigned int GetRGB(unsigned char r, unsigned char g, unsigned char b) {
    return (g << 16) | (r << 8) | b;
}

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

    PORTSetPinsDigitalOut(IOPORT_B, BIT_5);
    OpenTimer1(T1_ON | T1_PS_1_256, 0xffff);

    // In this example I'm using a total of 8 leds
    unsigned int dataToSend[] = {0, 0, 0, 0, 0, 0, 0, 0};

    while (1) {
        for (int ledNumber = 0; ledNumber < 8; ledNumber++) {

            for (int i = 0; i < ledNumber; i++)
                dataToSend[i] = GetRGB(155, 0, 0);

            dataToSend[ledNumber] = GetRGB(0, 255, 0);

            for (int i = ledNumber + 1; i < 8; i++)
                dataToSend[i] = GetRGB(0, 0, 155);

            SendMultiple(8, dataToSend);

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

        for (int ledNumber = 7; ledNumber >= 0; ledNumber--) {

            for (int i = 0; i < ledNumber; i++)
                dataToSend[i] = GetRGB(155, 0, 0);

            dataToSend[ledNumber] = GetRGB(0, 255, 0);

            for (int i = ledNumber + 1; i < 8; i++)
                dataToSend[i] = GetRGB(0, 0, 155);

            SendMultiple(8, dataToSend);

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

    return 0;
}

Update #2

A slight modification that will speed up the frequency to around 560 kHz

void sendPixel(unsigned int x) {

    char i = 24;

    do {
        if ((x >> --i) & 1) {
            mPORTBSetBits(PIN);
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            mPORTBClearBits(PIN);
        } else {
            mPORTBSetBits(PIN);
            Nop();
            Nop();
            mPORTBClearBits(PIN);
            Nop();
            Nop();
            Nop();
            Nop();
        }
    } while (i > 0);
    
}


Viewing all articles
Browse latest Browse all 4

Trending Articles