1

I've read the other posts on BitArray conversions and tried several myself but none seem to deliver the results I want.

My situation is as such, I have some c# code that controls an LED strip. To issue a single command to the strip I need at most 28 bits

1 bit for selecting between 2 led strips

6 for position (Max 48 addressable leds)

7 for color x3 (0-127 value for color)

Suppose I create a BitArray for that structure and as an example we populate it semi-randomly.

        BitArray ba = new BitArray(28);

        for(int i = 0 ;i < 28; i++)
        {
            if (i % 3 == 0)
                ba.Set(i, true);
            else
                ba.Set(i, false);
        }

Now I want to stick those 28 bits in 4 bytes (The last 4 bits can be a stop signal), and finally turn it into a String so I can send the string via USB to the LED strip.

All the methods I've tried convert each 1 and 0 as a literal char which is not the goal.

Is there a straightforward way to do this bit compacting in C#?

2 Answers 2

3

Well you could use BitArray.CopyTo:

byte[] bytes = new byte[4];
ba.CopyTo(bytes, 0);

Or:

int[] ints = new int[1];
ba.CopyTo(ints, 0);

It's not clear what you'd want the string representation to be though - you're dealing with naturally binary data rather than text data...

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Jon. I don't actually care about the string representation. The current system I use uses string encoding to communicate, but I end up sending 17 bytes to communicate the same information. I convert it to a string only because LibUsbDotNet's send method requests it. I'm going to work with the solution you provided this weekend and see if I can optimize the transmission.
1

I wouldn't use a BitArray for this. Instead, I'd use a struct, and then pack that into an int when I need to:

struct Led
{
    public readonly bool Strip;
    public readonly byte Position;
    public readonly byte Red;
    public readonly byte Green;
    public readonly byte Blue;

    public Led(bool strip, byte pos, byte r, byte g, byte b)
    {
        // set private fields
    }

    public int ToInt()
    {
        const int StripBit = 0x01000000;
        const int PositionMask = 0x3F; // 6 bits
        // bits 21 through 26
        const int PositionShift = 20;
        const int ColorMask = 0x7F;
        const int RedShift = 14;
        const int GreenShift = 7;

        int val = Strip ? 0 : StripBit;
        val = val | ((Position & PositionMask) << PositionShift);
        val = val | ((Red & ColorMask) << RedShift);
        val = val | (Blue & ColorMask);
        return val;
    }
}

That way you can create your structures easily without having to fiddle with bit arrays:

var blue17 = new Led(true, 17, 0, 0, 127);
var blah22 = new Led(false, 22, 15, 97, 42);

and to get the values:

int blue17_value = blue17.ToInt();

You can turn the int into a byte array easily enough with BitConverter:

var blue17_bytes = BitConverter.GetBytes(blue17_value);

It's unclear to me why you want to send that as a string.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.