Shift register + Stupidity = Problem

Hey chaps.

I'm pretty stupid and have bitten off more I can chew with a project I'm doing. I have a shift register that is controlling some LED's using the tutorial here http://arduino.cc/en/Tutorial/ShiftOut. Unfortunately I'm an idiot and have nearly a hundred LED's which are wired the wrong way so my grounds go to the pins on the register. This means that the LEDs are on when they should be off etc. Is there anyway around this problem that doesn't involve me having to resolder 100 leds?

Thanks
Richard

Invert the bits you are shifting out. In other words, instead of shifting out a 1 to turn an LED on, shift out a zero, and vice-versa.

You can simply invert the bits with an EXCLUSIVE OR operation.
So if you are going to shift out a 2 byte int value in a variable called va then before you do invert all the bits:-
var = var ^ 0xffff;
or even:-
Edit - see below, wrong about the following

var = var ^ var;
that can be done even more concisely with:-
var ^= var;

I think not, Mike.

void setup ()
{
  Serial.begin (115200);
  byte foo = 42;
  foo ^= foo;
  Serial.print (foo, DEC); 
}

void loop () {}

Output:

0

Your first suggestion of xor'ing with 0xFF would be the one to go with (for each byte).

Negating works, that is, taking the 1s complement:

void setup ()
{
  Serial.begin (115200);
  Serial.println ();
  byte foo = 42;
  Serial.println (foo, BIN); 
  foo = ~foo;
  Serial.println (foo, BIN); 
}

void loop () {}

Output:

101010
11010101

Manually adding leading zeros:

00101010
11010101

Negating works, that is, taking the 1s complement:

Negating is taking the 2s complement.
Is the 1s complement operation ~ (hard to see in this font but it is a Tilda)

Wow I'm stupider than I realised as I understood 4% of those replies. More reading to do I guess .

Thanks for the input.

Grumpy_Mike:
Negating is taking the 2s complement.

Taking a two's complement actually involves two steps: negating each bit, and adding 1 to the result (carrying as needed). Taking a one's complement involves just negating each bit.

Taking a two's complement actually involves two steps:.........

And your point is?

Grumpy_Mike:

Taking a two's complement actually involves two steps:.........

And your point is?

You said "Negating is taking the 2s complement" so my point was correcting the error lest it confuse someone. I was also hoping it would solve world hunger, but I'm not sure if it worked.

You said "Negating is taking the 2s complement"

Yes I did and it is.

so my point was correcting the error lest it confuse someone

There is no error, the negative of 1 is the same as it's two''s complement. The fact that to generate a two's complement you have to do two operations in some low level languages is besides the point.

Grumpy_Mike:

You said "Negating is taking the 2s complement"

Yes I did and it is.

so my point was correcting the error lest it confuse someone

There is no error, the negative of 1 is the same as it's two''s complement. The fact that to generate a two's complement you have to do two operations in some low level languages is besides the point.

I'm not going to keep going with this after this reply because it doesn't make a difference - especially to the OP, and I don't want to seem argumentative, but a single bit doesn't have a two's complement. Only a number, which can be positive or negative, can have a two's complement representation.

Take the number 5. It's represented in binary as 0101. The two's complement of 5 is not 1010 (the negation of each bit), rather it's 1011 (assuming a 4 bit representation for your numbers). That fact is independent of the programming language you use.

The OP's question really has nothing to do with two's complement.

but a single bit doesn't have a two's complement

I never said it did.

We were talking about inverting a variable before passing it to shift out.

The OP's question really has nothing to do with two's complement.

Part of the solution it was mentioned that negating the variable would work to do the inverting.
I pointed out that it wouldn't because that would be a two's complement and what the OP required was a one's complement.
Then you jumped in correcting me.

Where you are going wrong is that you think the term negating a value is the same as inverting it, this is not the case. Negating is putting a negative sign in front of the value like:-
5 negated is -5

This is the same as taking a two's complement.
Inverting the number is taking a one's complement.

You are confusing logical inversion with arithmetic negation.

Grumpy_Mike:

Negating works, that is, taking the 1s complement:

Negating is taking the 2s complement.
Is the 1s complement operation ~ (hard to see in this font but it is a Tilda)

Wow, I apologize for starting a flame war about the meaning of the word "negating".

As you can see from reply #4, I used the ~ operator:

  foo = ~foo;

I stand by my use of the word "negating", as in logical negation, because of this page in Wikipedia:

To quote from that:

The bitwise NOT, or complement, is a unary operation that performs logical negation on each bit, forming the ones' complement of the given binary value. Digits which were 0 become 1, and vice versa. For example:

NOT 0111  (decimal 7)

= 1000  (decimal 8)

(My emphasis).

So, calm down everyone. I was suggesting to the original poster, that if he negated what he wanted to send, using the ~ operator in C, he would turn 0 into 1 and 1 into 0, thus solving his problem.

because of this page in Wikipedia:

Ah well that is a source noted for it's linguistic accuracy isn't it.

Another word in the language goes down the pan.

Thanks for the input guys especially over the Christmas period. Just to close the thread I did this foo = ~foo; to sort the problem out. I had other issues caused by my stupidity which meant I wasn't sure if stuff was working. Lesson to be learnt is check really obvious simple stuff before assuming something more complicated is the issue :wink:

Thanks again.