antonpup / Aurora

Unified lighting effects across multiple brands and various games.
http://www.project-aurora.com/
MIT License
1.83k stars 367 forks source link

Arduino WS2812b script implementation #1476

Open Wail3Y opened 5 years ago

Wail3Y commented 5 years ago

I recently bought a 30 LED WS2812b strip and connected it to my arduino nano. I found a script that allows me to control my strip with Aurora but it can only send the colour of one key to the strip. I tried modifying it but it doesnt seem to work as intended. I'm a beginner at programming so I have no clue how to fix it. Thanks in advance.

Aurora script

using Aurora;
using Aurora.Devices;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Linq;

public class LEDStripDeviceScript {
 public string devicename = "LED Strip";
 public bool enabled = true; //Switch to True, to enable it in Aurora

 private Color device_color = Color.Black;
 private Color col_black = Color.Black;
 private Color col_white = Color.Red;
 private Color col_green = Color.Green;
 private static SerialPort port;

 public bool Initialize() {
  try {
   port = new SerialPort("COM6", 115200, Parity.Even, 8, StopBits.One); // Check the COM port your device is connected to and change accordingly
   port.Open();
   SendColorToDevice(col_green, true);
   return true;
  } catch (Exception exc) {
   return false;
  }
 }

 public void Reset() {
  SendColorToDevice(col_white, true); // just for debugging
 }

 public void Shutdown() {
  SendColorToDevice(col_black, true);
  port.Close();
 }

 public bool UpdateDevice(Dictionary < DeviceKeys, Color > keyColors, bool forced) {
  try {
   foreach(KeyValuePair < DeviceKeys, Color > key in keyColors) {
    //Iterate over each key and color and send them to your device

    if (key.Key == DeviceKeys.A) {
     // Set to E to show overwatch ability cooldown
     SendColorToDevice(key.Value, forced);
    }
    if (key.Key == DeviceKeys.B) {
     SendColorToDeviceB(key.Value, forced);
    }
   }

   return true;
  } catch (Exception exc) {
   return false;
  }
 }

 //Custom method to send the color to the device
 private void SendColorToDevice(Color color, bool forced) {
  //Check if device's current color is the same, no need to update if they are the same
  if (!device_color.Equals(color) || forced) {

   byte[] ba = {
    0,
    color.R,
    color.G,
    color.B
   };
   port.Write(ba, 0, 4);
   //Update device color locally
   device_color = color;
  }
 }
 private void SendColorToDeviceB(Color color, bool forced) {
  //Check if device's current color is the same, no need to update if they are the same
  if (!device_color.Equals(color) || forced) {

   byte[] ba = {
    1,
    color.R,
    color.G,
    color.B
   };
   port.Write(ba, 0, 4);
   //Update device color locally
   device_color = color;
  }
 }

}

Arduino code

#include <Adafruit_NeoPixel.h> 
#define PIN 6
#define NUMPIXELS 30

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();
  Serial.begin(115200, SERIAL_8E1);
}

void loop() {
  if (Serial.available()) {
    byte rgb[4];
    Serial.readBytes(rgb, 4);
    uint32_t i = int(rgb[0]);
    uint32_t r = int(rgb[1]);
    uint32_t g = int(rgb[2]);
    uint32_t b = int(rgb[3]);
    pixels.setPixelColor(i, r, g, b);
    pixels.show();
  }
}
Wibble199 commented 5 years ago

When you say it "doesnt seem to work as intended", what exactly does it do?

From the looks of the code, it should be setting the first LED to match the color of the A key and the second LED should be the color of the B key. Is that not what's happening?

One thing to note though is that the local color that you are comparing against before sending the color is the same for both keys. You will need to store this color on a per-LED basis (if you are using each LED independently) which you probably want to do in an array.

Wail3Y commented 5 years ago

It lights up the first three leds and three random others at the end of the strip and the colours don't match what I set in Aurora.

When I was just using only one led corresponding to only one key it was working fine.

Fade97 commented 4 years ago

Working with ws2812b strips and using serial communication is not recommended. During the update of the LEDs all interrupts are disabled. Hence the serial port won't receive anything during that time. To prevent this from happening you would have to implement a custom protocol like "XON XOFF".