Bit rotation

Hi, i've been trying to solve this problem for about 2 or 3 days and i can't find a solution. My english isn't that good, but i will try to explain it.

So the problem is as follows: i have to input a number from 1 to 8 with a BCD Thumbswitch, the arduino has to read it and it has to compute this: let's say i set the thumbswitch on 4, it has to display something like this

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 1
0 0 0 0 0 1 1 1
0 0 0 0 1 1 1 1
0 0 0 1 1 1 1 0
0 0 1 1 1 1 0 0
0 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 1
1 1 0 0 0 0 1 1
0 0 0 0 0 1 1 1
0 0 0 0 1 1 1 1

and it musn't stop, in other words, it has to rotate the bits without losing any of them.

I tried to do like this just for number 2, but then i realized it was wrong,

byte num=0,i;
bool n0,n1,n2,n3;
void setup(){
for(i=6;i<14;i++)
pinMode(i,OUTPUT);

}
bool convierteBit (byte n, byte indice){
n=n>>indice;
bool binario =n%2;
return binario;
}

void displaya (byte digito)
{
for(i=13;i>=6;i--)
{
digitalWrite(i,digito%2);
digito=digito>>1;
}
delay(500);
}

void loop()
{
n0=digitalRead(0);
n1=digitalRead(1);
n2=digitalRead(2);
n3=digitalRead(3);
num=8n0+4n1+2*n2+n3;

if(num==2)
{
byte dato=B00000011;

delay(300);
for(int k=0;k<8;k++)
{displaya(dato);
dato=dato<<1;
delay(300);
}
}
}

This is the circuit

is something like this you trying to achieve?

(showing only the part I altered)

void displaya (byte digito, byte shift)
{
  byte output_pin,dato = digito+shift;

  for (i = 0; i <8; ++i)
  {
    output_pin = 13-i;

    if(i<shift){
      digitalWrite(output_pin, LOW);
    }
    else if(i<dato){
      digitalWrite(output_pin, HIGH);
    }
    else{
      digitalWrite(output_pin, LOW);
    }    
  }
  delay(500);
}

void loop()
{
  n0 = digitalRead(0);
  n1 = digitalRead(1);
  n2 = digitalRead(2);
  n3 = digitalRead(3);

  num = 8 * n0 + 4 * n1 + 2 * n2 + n3;

  for (int k = 0; k < 8; k++) {
    displaya(num, k);
    delay(300);
  }

}

Uhmmm nope, i tried it but it doesnt move.
I dont know why i cant upload an image, but this is what im trying to achieve:

And this is my circuit:

I just realized i misunderstood the problem x.x

There is no rotate instruction, which is what you need.
Left shifting dato loses the leftmost bit, you need to add it back to the rightmost bit location.

Just need to change one line in your code from:

    for (int k = 0; k < 8; k++)
    { displaya(dato);
      dato = dato << 1;
      delay(300);
    }

to this:

    for (int k = 0; k < 8; k++)
    { displaya(dato);
      dato = ((dato & B10000000) >> 7) | (dato << 1);
      delay(300);
    }

Also, it is a bad idea to use digital pins 0 and 1 if you don't have to, they are used for the serial communications on the UNO, so your BCD thumbswitch can interfere with programming the sketch into the UNO.

david_2018:
There is no rotate instruction, which is what you need.
Left shifting dato loses the leftmost bit, you need to add it back to the rightmost bit location.

Just need to change one line in your code from:

    for (int k = 0; k < 8; k++)

{ displaya(dato);
     dato = dato << 1;
     delay(300);
   }




to this:



for (int k = 0; k < 8; k++)
   { displaya(dato);
     dato = ((dato & B10000000) >> 7) | (dato << 1);
     delay(300);
   }





Also, it is a bad idea to use digital pins 0 and 1 if you don't have to, they are used for the serial communications on the UNO, so your BCD thumbswitch can interfere with programming the sketch into the UNO.

Yes, i know that, thanks for reminding me, but this is just a simulation i have to do.
Uhm i tried replacing it, but it just works for num=2.

I think i already solved the problem with this, i think it will be a lot of code because i have to do it for every number from 1 to 8, but this is my solution just for num=5:

byte num,i,j,k,l;
bool n0,n1,n2,n3;
byte intro[]={0,1,3,7,15,31,63,127,255};
void setup()
{
 for(i=6;i<14;i++)
 pinMode(i,OUTPUT);
 for(j=0;j<4;j++)
 pinMode(j,INPUT);  
}

void displaya (byte digito)
{
  for(i=13;i>=6;i--)
  {
     digitalWrite(i,digito%2);
     digito=digito>>1;
  }
}

void loop()
{
  n0=digitalRead(0);
  n1=digitalRead(1);
  n2=digitalRead(2);
  n3=digitalRead(3);
  num=8*n0+4*n1+2*n2+n3;   

if(num==5)
{
 for(k=0;k<(num);k++)
 {  
   displaya(intro[k]);
   delay(500);
 }  
byte dato=intro[5];
 
for(k=0;k<8;k++)
 {    
   displaya(dato);
   dato=dato<<1;
   delay(500);
 }
}
}

Now with that i have to do this :

I think i just have to add some pows or something.

DarkCygnus:
Uhmmm nope, i tried it but it doesnt move.

Yeah... apologies! I realised what bulls**t that code was afterwards and only was able to update my post now with what I think could be an alternative .

sherzaad:
Yeah... apologies! I realised what bulls**t that code was afterwards and only was able to update my post now with what I think could be an alternative .

Thank you for that :D.

Btw, i triend adding this to the new problem i have to solve:

byte dato=15;
displaya(dato);
delay(500);
dato2=15+pow(2,5)
displaya(dat2);

but it doesnt display the new dat2, i dont know if im doing something wrong:

void loop()
{
   n0=digitalRead(0);
   n1=digitalRead(1);
   n2=digitalRead(2);
   n3=digitalRead(3);
   num=8*n0+4*n1+2*n2+n3;   

if(num==4)
{
byte dato=data[num];
displaya(dato);
delay(300);
byte dato2=dato+pow(2,5);
 displaya(dato2);
 delay(300);
}
}

A simple way to rotate a byte with carry round is this

if ((datao & B10000000) > 0) {    //Bitwise and your data with binary 10000000 to test if bit 8 is set. It will return B10000000 which is greater than 0 
    datao = datao << 1;           // Shift datao 1 bit left
    datao++;                      // Place a 1 in the least significant bit by adding 1 to datao
} else {                          // Otherwise
    datao = datao << 1;           // Just shift datao 1 bit left
}

If you decide to shift right instead of left change the change the bitwise and from B10000000 to B1 and change datao++ to datao = datao + B10000000.

By the way you want to avoid using pins 0 and 1 as these are used by the serial port for programming the device. If the thumb wheel switch ties either to VCC or GND then it can stop you programming your board.

Change your setup code from this:-

void setup()
{
 for(i=6;i<14;i++)
 pinMode(i,OUTPUT);
 for(j=0;j<4;j++)
 pinMode(j,INPUT);  
}

To this:-

void setup()
{
 for(i=6;i<14;i++)
 pinMode(i,OUTPUT);
 for(j=2;j<6;j++)
 pinMode(j,INPUT);  
}

Then wire your thumbwheel to pins 2-5.

Hope this helps

Ian

You can use bitwise shift.

To fill the n rightmost bits with 1:

byte num;
byte n;
num = 255 >> (8 - n);

To rotate num one bit left with carry:

byte num;
num = (num << 1) | (num >> 7);

Thank you so much, i appreciate your help :D.

There is something that is bothering me right now, im trying to do this:

if(num==4)
{
byte dato=data[num];
 displaya(dato);
delay(500);
dato=dato+pow(2,3);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,4);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,5);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,6);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,2);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,3);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,4);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,5);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,1);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,2);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,3);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,4);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,0);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,1);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,2);
 displaya(dato);
 delay(500);
 dato=dato+pow(2,3);
 displaya(dato);
 delay(500);
}

into a double for:

if(num==4)
{
byte dato=data[num];
displaya(dato);
delay(500);
for(int p=0;p<num;p++)
  {
  for(int q=0;q<num;q++)
  {
    dato=dato+pow(2,3-p+q);
    displaya(dato);
    delay(500);
  }
  }   
}

But i dont understand why it is not working right, i mean the first iteration this happens

It goes from 00001111 to 00010110 it should go like this:

0 0 0 0 1 1 1 1
0 0 0 1 0 1 1 1
0 0 1 0 0 1 1 1
0 1 0 0 0 1 1 1
1 0 0 0 0 1 1 1
1 0 0 0 1 0 1 1
1 0 0 1 0 0 1 1
1 0 1 0 0 0 1 1
1 1 0 0 0 0 1 1
...
1 1 1 1 0 0 0 0

.<