16x16 led matrix calculator and mapping - tiny bug!!

I think I got this 99.99% done, but suddenly when testing the code, it shook me that it's a mess, and I have reviewed my code over and over, can't find this tiny bug!!! I am not sure if the problem came from my 16x16 led matrix calculator or the code itself.

16x16 led matrix calculator: http://flyandance.atspace.cc/Others/matrix/matrix_2.0.html

Output mess:

Code:

/*
Minimal Setup for 16x16 Juno Matrix

Flyandance Apr 17 2017
DS1302 (RTC)
Rst= A5 D7 (D25)
I/0= A4 D6 (D24)
Sclk= A3 D5 (D23)

3 buttons >> G0, G1, G2 (26, 27, 36)

buzzer >> G3 (16)

4x 8x8 Ports A, B, C, E
common cathode Port F (Active LOW)

Minimial Setup

 */
 
//16x16=256 led
unsigned int led[16]; 
byte counter;         //For multiplexing
unsigned long t1,t2;

unsigned int led_buffer[]={0x8001, 0x4002, 0x2004, 0x1008, 0x800, 0x400, 0x200, 0x100, 0x80, 0x8040, 0x4020, 0x2010, 0x1008, 0x2804, 0x4402, 0x8201}; 

//##########################################################
void setup() {
DDRA=0xff; // Output Mode
DDRB=0xff;
DDRC=0xff;
DDRE=0xff;
DDRF=0xff; //Active Low

}


void loop() {

/*
led[0]=0xff;    //0b0000000011111111  this is first row, so the right 8 leds will be ON
led[1]=0xffff;  //0b1111111111111111  this is second row. All LED will be ON.
led[15]=0xeeee; //0b1110111011101110  this is last row. only 4 led will be OFF.
*/

for (byte x=0; x<16; x++) led[x]=led_buffer[x];
//##########################################################

for (byte i=0; i<16; i++) led[i]=flip(led[i]);

t1=micros();
if(t1-t2>=100){


  if( counter<8 && counter >-1)    {   PORTE=0;PORTA=0; PORTF=~led[counter]; PORTA=(1<<0+(counter%8));  }
  if( counter<16 && counter >7)    {   PORTA=0;PORTB=0; PORTF=~(led[counter-8]>>8); PORTB=(1<<0+(counter%8));  }
  if( counter<24 && counter >15)   {   PORTB=0;PORTC=0; PORTF=~led[counter-8]; PORTC=(1<<0+(counter%8)); }
  if( counter<32 && counter >23)   {   PORTC=0;PORTE=0; PORTF=~(led[counter-16]>>8); PORTE=(1<<0+(counter%8));  }

  counter++;
  if( counter==32 ) {
    counter=0;
    for (byte x=0; x<16; x++) led[x]=0x0;
  }
  t2=t1;  
  
  }
  
}

///////////////////////////////////////////////////////////////////////////

int flip( unsigned int v){
  unsigned int r = v;
  int s;
  for (s=15 ; v; v >>= 1)
  {   
    r <<= 1;
    r |= v & 1;
    s--;
  }
  r <<= s;
  return r;
  }
int flip( unsigned int v){

Why does this function take an unsigned value, manipulate it as an unsigned value, and then return it as a signed value?

PaulS:

int flip( unsigned int v){

Why does this function take an unsigned value, manipulate it as an unsigned value, and then return it as a signed value?

both v and r are unsigned int;

int flip( unsigned int v){
  unsigned int r = v;
....
  return r;

both v and r are unsigned int;

I know that. But that is NOT what the function returns.

PaulS:
I know that. But that is NOT what the function returns.

So what exactly does it returns?

output:

Original: 1010101010101111
Flipped : 1111010101010101

Test example:

/*
Bit Flips Reverse

Apr. 17. 2017
Flyandance
*/

byte input[8];
byte output[8];

unsigned int in=0xAAAF, out;

void setup (){
  Serial.begin(9600);
  Serial.println("START:");  
  out=flip(in);
  
  Serial.print("Original: ");    
  Serial.println(in, BIN);  
  Serial.print("Flipped : ");   
  Serial.println(out, BIN);  
  Serial.println("Enter Your Bits:");      
   }
  
void loop  (){

while (Serial.available()>0) { 
  unsigned int input = Serial.parseInt();
  out = flip(input);
  Serial.println(input, BIN);  
  Serial.println(out, BIN);      
  }
  
  }  

/// This function reverse the direction of bits
/// ie. 0b11110000 >> 0b00001111

unsigned int flip( unsigned int v){
  unsigned int r = v;
  int s;
  for (s=15; v; v >>= 1)
  {   
    r <<= 1;
    r |= v & 1;
    s--;
  }
  r <<= s;
  return r;
  }

So what exactly does it returns?

It returns a SIGNED int.

Change the return type to unsigned int, to match what you are actually returning.

PaulS:
It returns a SIGNED int.

Change the return type to unsigned int, to match what you are actually returning.

I don't know how r became a SIGNED int suddenly

While s is an signed int, this shift bitwise operation doesn't convert r into an signed int.

  r <<= s;

so maybe just help me out, fix the bug for me and I will test it on my end to see if the bug is gone or not?

int flip( unsigned int v){
  unsigned int r = v;
  int s;
  for (s=15 ; v; v >>= 1)
  {   
    r <<= 1;
    r |= v & 1;
    s--;
  }
  r <<= s;
  return r;
  }

Don't you need to perform some kind of check on v in the middle here, otherwise the for loop never ends?

for (s=15 ; v; v >>= 1)

Like v >= something, or v <= something?

CrossRoads:
Don't you need to perform some kind of check on v in the middle here, otherwise the for loop never ends?

for (s=15 ; v; v >>= 1)

Like v >= something, or v <= something?

That is a good point, but if you run the serial program that I wrote, then it should be problem free.

The reason: for (s=15 ; v; v >>= 1); (V>>=1) is really shifting out v, making it zero after 16 loop or less, and so when v==0, the for loop ends.

I don't know how r became a SIGNED int suddenly

Because that is the type that the function returned.

If the function return type was shit, you wouldn't plan to eat the output, would you?

Quit arguing and change the damned return type to match what you are actually returning.

PaulS:
Because that is the type that the function returned.

If the function return type was shit, you wouldn't plan to eat the output, would you?

Quit arguing and change the damned return type to match what you are actually returning.

Maybe someone is too arrogant to help. My question is simple, how does an unsigned int suddenly become a signed int when returned? The unsigned int r to me is always an unsigned int, so I don't know what to change, and I highly doubt my tiny bug is from this piece of code because it's written by someone from stanford, someone actually not dumb and not helpful. Also, the fact that I have written a serial code to test that function, and it turns out running correctly, tells anyone who a brain whom is really arguing.

flyandance:
My question is simple, how does an unsigned int suddenly become a signed int when returned?

Right here
int flip( unsigned int v){

flyandance:
Maybe someone is too arrogant to help. My question is simple, how does an unsigned int suddenly become a signed int when returned?

Kind Sir,

It is simply cast to match what the (very smart) programmer decided to return, in this case a signed integer (int).

it all happens very suddenly.

You can argue that the code was written by a very smart programmer until you are blue in the face. NO ONE with half a brain cell still functioning defines a function that returns an int, and then uses a return statement that returns an unsigned int. Get over it.

You have spend far more time trying to prove, without a shred of evidence, that the function works perfectly than you would have spent simply changing the return type to unsigned int, and then running the code.

Either there is no change, or the problem is solved. YOU are expected to make a modicum of effort. If you don't intend to, do not bother posting here again.

I didn't bother to reverse engineer the function flip() "written by someone from stanford, someone actually not dumb and not helpful", but tried it out.

The output certainly does not resemble what the comment would lead one to expect, regardless of whether the return type is unsigned int or signed int.

Conclusion: the person from stanford was indeed not helpful, as the OP suggested.

Unsigned int code:

/// This function reverse the direction of bits
/// ie. 0b11110000 >> 0b00001111

unsigned int flip( unsigned int v){
  unsigned int r = v;
  int s;
  for (s=15 ; v; v >>= 1)
  {   
    r <<= 1;
    r |= v & 1;
    s--;
  }
  r <<= s;
  return r;
  } 
  
  void setup() {
  Serial.begin(9600);
  unsigned int in=1;
  unsigned int out = flip(in);
  Serial.print("in: ");
  Serial.println(in,BIN);
  Serial.print("out: ");
  Serial.print(out,BIN);
   
}

void loop() {}

Result for "unsigned int":

in: 1
out: 1100000000000000

Result for "signed int":

in: 1
out: 11111111111111111100000000000000