1

I wanted to install a 5 LED strip underneath my PC's front panel. I want to send color over PC so it can change when i open different apps, with temperature or etc!

So all I think the best way to do this is to just use Arduino to set the LED Values!

But I have had some troubles creating a good communication protocol for this, I've been just simply sending 45 digits (15 3 digit numbers) to my Arduino with serial. here's code: Arduino :

#include "Adafruit_NeoPixel.h"
#include "WS2812_Definitions.h"

#define PIN 4
#define LED_COUNT 5

struct pixel {
  int R = 0;
  int B = 0;
  int G = 0;
};

Adafruit_NeoPixel leds = Adafruit_NeoPixel(LED_COUNT, PIN, NEO_GRB + NEO_KHZ800);

char count = 1;
int pixelNumber = 0;
struct pixel tempPixel;
//struct pixel Pixels[LED_COUNT];

void setup()
{
  Serial.begin(9600);
  Serial.println("Init");
  leds.begin();  // Call this to start up the LED strip.
  clearLEDs();   // This function, defined below, turns all LEDs off...
  leds.show();   // ...but the LEDs don't actually update until you call this.
}

void loop() {
  if(Serial.available() > 0) {
    if(count == 1) {
      tempPixel.R = PC_Receive();
    } else if (count == 2) {
      tempPixel.G = PC_Receive();
    } else if (count == 3) {
      tempPixel.B = PC_Receive();
      count = 0;

      setPixelColor(pixelNumber, tempPixel);
      Serial.println(pixelNumber);
      leds.show();
//      Pixels[pixelNumber] = tempPixel;
      if(++pixelNumber >= LED_COUNT) {
        pixelNumber = 0;
      }
    }
    count++;
  }

//  if(pixelNumber == 0) {
//    for(int i = 0; i < LED_COUNT; i++ ) {
//       setPixelColor(i, Pixels[i]); 
//    }
//    
//    leds.show();
//  }
}

void setPixelColor(int a, struct pixel P)
{
  leds.setPixelColor(a, P.R, P.G, P.B);
}

char PC_Receive() {
  int result = 0;

  while(Serial.available() == 0);
  result += ((int)Serial.read() - '0') * 100;

  while(Serial.available() == 0);
  result += ((int)Serial.read() - '0') * 10;

  while(Serial.available() == 0);
  result += ((int)Serial.read() - '0');

  Serial.println(result);
  return result;
}







void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {
  for(int i = 0; i < LED_COUNT; i++) {
    leds.setPixelColor(i, red, green, blue);
  }
  leds.show();
 }

And here's PC's dirty code in python:

import serial
import time
import random

class Pixel:

    def __init__(self, R, G, B):
        self.R = R
        self.G = G
        self.B = B

def clearAll():
    for i in range(0,5):
        ser.write("000000000")

def sendPixel(pixels):
    for i in range(0,5):
        ser.write(str(pixels[i].R).zfill(3))
        ser.write(str(pixels[i].B).zfill(3))
        ser.write(str(pixels[i].G).zfill(3))


ser = serial.Serial('/dev/ttyACM2', 9600)

little = [0,0,0,0,0]

for i in range(0,5): 
    little[i] = Pixel(0,255,50)
sendPixel(little)

time.sleep(0.5)
clearAll()

the problem is it isn't stable, i think i should just use an \n at end or send back OK or something to confirm it, but that would make it slow if i did it for each value! (and checking only once after all 5 leds are send would mean sending more values until i receive the ok and clearing and sending them again!)

Can you recommend me a better way?

Thanks!

EDIT: Just wanted to say! it's almost done! It does change color when i open chrome, and i think at 115200 baud rate it's fast enough to not notice a delay (although at 9600 i felt like it's slower then my (xxx/xxx/xxx....) protocol but it's better and works at 115200

i will add some basic functions to my python side and add a rainbow effect I will also add GPU temperature and etc... it's not going to be really hard on linux but windows, im not sure :D

2
  • Please edit your question and include the Arduino's setup() function as well. The code doesn't make sense when includes, variable declarations, and initialization code isn't shown. That is not to say it will make sense when they are shown :), merely that without them it doesn't. Jan 4, 2016 at 19:34
  • I don't think you need to worry about speed or data size from what you've described. Prioritise for ease of coding and reliability. Forget all the binary stuff. Send whole bytes. Start with a known sequence, and end with a known sequence of bytes and take advantage of the arduino's readBytesUntil function to find those start and end sequences. This avoids problems with the arduino getting out of sync and picking up the data stream partway through, causing lighting mayhem
    – Greg Woods
    Jan 5, 2016 at 11:44

2 Answers 2

1

I would recommend a similar solution as DaveX with a small modofication.

If you bitmask your LEDS, and leave room for a possible additional 3, you can mask any combination of them in the space of 00-FF. then you could send to the arduino a single string of 0xFFFFFFFF FF(LED bitmask),FF(Red value), FF(Green Value), FF(Blue Value).

so LED 1 {00000001 =01} all red {FF0000} would be 0x01FF0000

LED 2 and 4 {00001010 =0A} all green {00FF00} would be 0x0A00FF00

LED 5 and 1 {00010001 =11} all blue {0000FF} would be 0x110000FF

ALL LEDS off would be 0xFF000000

All LEDS onn full white would be 0xFFFFFFFF

6
  • my led's are barely going to be the same color, so is it still worth using this? I think sending them in a chunk (but still binarry to reduce the size) will be easier! but im not sure how to convert a hex string to integer in arduino side, also im not sure how i can turn a int into hex string in python but i guess that one will be easy! Jan 5, 2016 at 9:36
  • AFAIK C++ treats all numeric values as binary to start with, so if you say that rgbRED=127 it's the same as saying rgbRED = 0x7F Jan 5, 2016 at 14:33
  • Here is a file with some likely colors as well as an interactive RGB slider and LED picker so you can generate the values you would need.. marvinfrancois.com/19228.php Jan 5, 2016 at 15:49
  • Thanks a lot! as I'm inexperienced with these kind of stuff it will take em a lot of time, and googling :) but i will try to do it :) thanks a lot! Jan 5, 2016 at 16:04
  • btw, just wanted to say, it's underneath my pc pointed to gound, it's a 5 strip led which EACH led has 3 colors, so it can be 5 different colors Jan 5, 2016 at 16:06
0

I'd recommend adding digits to a digit register, setting the an R,B,G register with R,B,G and setting values of led a-e to the RBG registers when you get an a-e, ignoring whitespace, and clearing the register otherwise. So:

 ser.write("xRBGabcde\n")  # clear all the LEDs
 ser.write("x127RBb")       # make led b half-purple, relying on prior state 
 ser.write("x255Gc")        # make led c greenish-white    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.