Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize with different options #113

Open
gbkwiatt opened this issue Dec 28, 2020 · 2 comments
Open

Initialize with different options #113

gbkwiatt opened this issue Dec 28, 2020 · 2 comments

Comments

@gbkwiatt
Copy link

I am having difficulties trying to make it work.
I used C library previously with settings for my stripe:

#define LED_PIN 19 //#GPIO pin connected to the pixels(18 uses PWM !).
//LED_PIN         10      // # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
#define LED_FREQ_HZ 800000 //#LED signal frequency in hertz(usually 800khz)
#define LED_DMA 10         // # DMA channel to use for generating signal (try 10)
#define LED_BRIGHTNESS 255 // # Set to 0 for darkest and 255 for brightest
#define LED_INVERT 0       //True to invert the signal(when using NPN transistor level shift)
#define LED_CHANNEL 1      // # set to '1' for GPIOs 13, 19, 41, 45 or 53

That was working fine in Cpp

No I am trying to convert that to this library but I can't make it to work.
I can't test it on default gpio 18 because I broke it ;)

how do you properly set it up ? Tried that:

const options = {
        dma: config.leds.dma,
        freq: config.leds.freq,
        channels: [
            { count: 20, gpio: 19, invert: false, brightness: 255, stripType: 'ws2812' },
            { count: 20, gpio: 19, invert: false, brightness: 128, stripType: 'ws2812' }
        ]
    };

and that:

const options = {
        dma: config.leds.dma,
        freq: config.leds.freq,
        gpio: 19,//config.leds.gpio,
        invert: config.leds.invert,
        brightness: config.leds.brightness,
        stripType: 'ws2812'
    };
@gbkwiatt
Copy link
Author

OK I've made v1.x work with node14.

Had to update "nan": "^2.14.2", to the latest in package.json

And because some functions are deprecated I had to modify rpi-ws281x.cc as below.
Then npm install works, and I was amble to initilize LEDs like this (and use channel 1 for GPIO 19):

 const options = {
        dma: config.leds.dma,
        freq: config.leds.freq,
        channels: [
            { count: 20, gpio: 18, invert: false, brightness: 255, stripType: ws281x.stripType.WS2812 },
            { count: 20, gpio: 19, invert: false, brightness: 255, stripType: ws281x.stripType.WS2812 }
        ],
    };
    // ---- trap the SIGINT and reset before exit
    process.on('SIGINT', function () {
        ws281x.reset();
        log.debug("Reseting Leds on exit...")
        process.nextTick(function () { process.exit(0); });
    });
    const channel = ws281x.init(options);
// Rainbow test on channel 1
    var offset = 0;
    setInterval(function () {
        for (var i = 0; i < 20; i++) {
          channel[1].array[i] = colorwheel((offset + i) % 256);
        }
        offset = (offset + 1) % 256;

        ws281x.render();
      }, 1000 / 30);
//rpi-ws281x.cc
#include <nan.h>

#include <v8.h>

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include <algorithm>

extern "C" {
#include "rpi_ws281x/ws2811.h"
}

using namespace v8;

#define DEFAULT_TARGET_FREQ 800000
#define DEFAULT_GPIO_PIN 18
#define DEFAULT_DMANUM 10

#define PARAM_FREQ 1
#define PARAM_DMANUM 2
#define PARAM_GPIONUM 3
#define PARAM_COUNT 4
#define PARAM_INVERT 5
#define PARAM_BRIGHTNESS 6
#define PARAM_STRIP_TYPE 7

ws2811_t ws281x;

/**
 * ws281x.setParam(param:Number, value:Number)
 * wrap setting global params in ws2811_t
 */
void setParam(const Nan::FunctionCallbackInfo<v8::Value> &info)
{
  if (info.Length() != 2)
  {
    Nan::ThrowTypeError("setParam(): expected two params");
    return;
  }

  if (!info[0]->IsNumber())
  {
    Nan::ThrowTypeError("setParam(): expected argument 1 to be the parameter-id");
    return;
  }

  if (!info[1]->IsNumber())
  {
    Nan::ThrowTypeError("setParam(): expected argument 2 to be the value");
    return;
  }

  const int param = Nan::To<int32_t>(info[0]).FromJust();
  const int value = Nan::To<int32_t>(info[1]).FromJust();

  switch (param)
  {
  case PARAM_FREQ:
    ws281x.freq = value;
    break;
  case PARAM_DMANUM:
    ws281x.dmanum = value;
    break;

  default:
    Nan::ThrowTypeError("setParam(): invalid parameter-id");
    return;
  }
}
/**
 * ws281x.setChannelParam(channel:Number, param:Number, value:Number)
 *
 * wrap setting params in ws2811_channel_t
 */
void setChannelParam(const Nan::FunctionCallbackInfo<v8::Value> &info)
{
  if (info.Length() != 3)
  {
    Nan::ThrowTypeError("setChannelParam(): missing argument");
    return;
  }

  // retrieve channelNumber from argument 1
  if (!info[0]->IsNumber())
  {
    Nan::ThrowTypeError("setChannelParam(): expected argument 1 to be the channel-number");
    return;
  }

  const int channelNumber = Nan::To<int32_t>(info[0]).FromJust();
  if (channelNumber > 1 || channelNumber < 0)
  {
    Nan::ThrowError("setChannelParam(): invalid chanel-number");
    return;
  }

  if (!info[1]->IsNumber())
  {
    Nan::ThrowTypeError("setChannelParam(): expected argument 2 to be the parameter-id");
    return;
  }

  if (!info[2]->IsNumber() && !info[2]->IsBoolean())
  {
    Nan::ThrowTypeError("setChannelParam(): expected argument 3 to be the value");
    return;
  }

  ws2811_channel_t* channel = &ws281x.channel[channelNumber];
  const int param = Nan::To<int32_t>(info[1]).FromJust();
  const int value = Nan::To<int32_t>(info[2]).FromJust();

  switch (param)
  {
  case PARAM_GPIONUM:
    channel->gpionum = value;
    break;
  case PARAM_COUNT:
    channel->count = value;
    break;
  case PARAM_INVERT:
    channel->invert = value;
    break;
  case PARAM_BRIGHTNESS:
    channel->brightness = (uint8_t)value;
    break;
  case PARAM_STRIP_TYPE:
    channel->strip_type = value;
    break;

  default:
    Nan::ThrowTypeError("setChannelParam(): invalid parameter-id");
    return;
  }
}

/**
 * ws281x.setChannelData(channel:Number, buffer:Buffer)
 *
 * wrap copying data to ws2811_channel_t.leds
 */
void setChannelData(const Nan::FunctionCallbackInfo<v8::Value> &info)
{
  if (info.Length() != 2)
  {
    Nan::ThrowTypeError("setChannelData(): missing argument.");
    return;
  }

  // retrieve channelNumber from argument 1
  if (!info[0]->IsNumber())
  {
    Nan::ThrowTypeError("setChannelData(): expected argument 1 to be the channel-number.");
    return;
  }

  int channelNumber = Nan::To<int32_t>(info[0]).FromJust();
  if (channelNumber > 1 || channelNumber < 0)
  {
    Nan::ThrowError("setChannelData(): invalid chanel-number");
    return;
  }
  ws2811_channel_t channel = ws281x.channel[channelNumber];

  // retrieve buffer from argument 2
  if (!node::Buffer::HasInstance(info[1]))
  {
    Nan::ThrowTypeError("setChannelData(): expected argument 2 to be a Buffer");
    return;
  }
  v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
  auto buffer = info[1]->ToObject(context).ToLocalChecked();
  uint32_t *data = (uint32_t *)node::Buffer::Data(buffer);

  if (channel.count == 0 || channel.leds == NULL)
  {
    Nan::ThrowError("setChannelData(): channel not ready");
    return;
  }

  const int numBytes = std::min(
      node::Buffer::Length(buffer),
      sizeof(ws2811_led_t) * ws281x.channel[0].count);

  // FIXME: handle memcpy-result
  memcpy(channel.leds, data, numBytes);
}

/**
 * ws281x.init()
 *
 * wrap ws2811_init()
 */
void init(const Nan::FunctionCallbackInfo<v8::Value> &info)
{
  ws2811_return_t ret;

  ret = ws2811_init(&ws281x);
  if (ret != WS2811_SUCCESS)
  {
    Nan::ThrowError(ws2811_get_return_t_str(ret));
    return;
  }
}

/**
 * ws281x.render()
 *
 * wrap ws2811_wait() and ws2811_render()
 */
void render(const Nan::FunctionCallbackInfo<v8::Value> &info)
{
  ws2811_return_t ret;

  ret = ws2811_wait(&ws281x);
  if (ret != WS2811_SUCCESS)
  {
    Nan::ThrowError(ws2811_get_return_t_str(ret));
    return;
  }

  ret = ws2811_render(&ws281x);
  if (ret != WS2811_SUCCESS)
  {
    Nan::ThrowError(ws2811_get_return_t_str(ret));
    return;
  }
}

/**
 * ws281x.finalize()
 *
 * wrap ws2811_wait() and ws2811_fini()
 */
void finalize(const Nan::FunctionCallbackInfo<v8::Value> &info)
{
  ws2811_return_t ret;

  ret = ws2811_wait(&ws281x);
  if (ret != WS2811_SUCCESS)
  {
    Nan::ThrowError(ws2811_get_return_t_str(ret));
    return;
  }

  ws2811_fini(&ws281x);
}

/**
 * initializes the module.
 */
void initialize(Local<Object> exports)
{
  ws281x.freq = DEFAULT_TARGET_FREQ;
  ws281x.dmanum = DEFAULT_DMANUM;

  NAN_EXPORT(exports, setParam);
  NAN_EXPORT(exports, setChannelParam);
  NAN_EXPORT(exports, setChannelData);
  NAN_EXPORT(exports, init);
  NAN_EXPORT(exports, render);
  NAN_EXPORT(exports, finalize);
}

NODE_MODULE(rpi_ws281x, initialize)

// vi: ts=2 sw=2 expandtab

@ngrealish
Copy link

I am trying 19 on channel 1 with no results unfortunately. I've used your update to the rpi-ws281x.cc with no success. Any other hints or thoughts on this one? I cannot use 13. 18 is working for me, so I'd like to use 19 as a second set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants