Probelm with bit and byte interpretation

Thread Starter

allahjane

Joined Sep 19, 2012
75
Hi all,

I know this may be wrong section for this but my problem is Microcontroller programming specific (AVR mostly)!

I am sending bytes between two AVR atmega8 using Uart where each bit in the byte stands for something and only one bit is 1 in each byte sent

So if I want to check, say for example, 5th bit in the received byte then if write it as follows:
Rich (BB code):
short byte=UDR;
if(byte&(1<<5))
{
// do stuff for bit 5
}
Then it works fine always

BUT, if I write it as this:

Rich (BB code):
short byte=UDR;
if(byte==0b00100000)

OR
short byte=UDR;
if(byte==0x20)
Then it won't work , also it fails if I use Switch-case instead of if-else
I can't understand the problem, does the compiler interprets it as signed no and 7th Bit as sign?
or something else?

If someone asks I also have LEDs on the receiver that shows received byte
and so I know the byte received is correct but for some reason I cannot compare it for conditions! still can there some noise that causes bits to be misunderstood by the Uart and thus changing the actual byte received?

Help !
 

kubeek

Joined Sep 20, 2005
5,795
Lets say the byte you get in is 0b0010 0001, is this equal to 0b0010 0000? No it´s not.
Rich (BB code):
if(byte&(1<<5))
does this: 1<<5 is 0b00100000, and 0b00100000 & 0b00100001 result in 0b00100000. In conditions 0 is false and anything else is true and that is why the first example works the way it does.
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
Lets say the byte you get in is 0b0010 0001, is this equal to 0b0010 0000? No it´s not.
Rich (BB code):
if(byte&(1<<5))
does this: 1<<5 is 0b00100000, and 0b00100000 & 0b00100001 result in 0b00100000. In conditions 0 is false and anything else is true and that is why the first example works the way it does.
Thanks for your Input but I am sending 0b00100000 not 0b00100001 :mad: so there should not be a one at the LSB.

There's a reson I've highlighted it in red

also will declaring byte as unsigned help?
 

t06afre

Joined May 11, 2009
5,934
Then working with micro controllers bit twiddling. So this is for sure provided in the C-compiler you use. However, how this is solved may vary from compiler to compiler. I suggest you refer to the manual about this.
I am sure some use of Google may solve your problems. I suggest "bit twiddling c" and "bit twiddling avr" as candidates for search terms.
 

kubeek

Joined Sep 20, 2005
5,795
Just beacause you´re sending something doesn´t mean you receive the same. Try using the first example you posted for all bit positions and check what are you actually receiving.
 

ErnieM

Joined Apr 24, 2011
8,377
Just to state the obvious, if you ask your compiler "does byte equal {something}" and it says NO... then they are not equal.

Do you have access to a debugger? If so, add a watch for this variable and stop to see what it really contains.

It's part of your education... and even us old hands get re-educated from time to time.

Sorry I don't work with AVR things to be any more specific.
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
Just beacause you´re sending something doesn´t mean you receive the same. Try using the first example you posted for all bit positions and check what are you actually receiving.
Finally I watched those 8 LED's and it came out that the byte is exactly what I sent still there is some problem.. please help me sort it out
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
Something here is like PARANORMAL :eek:

Finally I have cornered the area of problem

The LEDs represent (1<<5) as 0b00100000 that's ok as its what I sent :)

BUT

the LED assigned to glow on receiving 0b00100000 does not glow!

FTW MAN!:eek:

I'm damn sure the received byte is correct ..but something's wrong with if-else and switch-case comparision
 

t06afre

Joined May 11, 2009
5,934
You have to use the debugger/simulator tool to trace down the error. Add some watches, set some breakpoints, and also use the singlestepper.
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
You have to use the debugger/simulator tool to trace down the error. Add some watches, set some breakpoints, and also use the singlestepper.
I have reviewed the code hundred times

still see this is the code
Rich (BB code):

 if(byte==(1<<5))
 {dpadSelective(1,1);}
	 else
 for(int i=0;i<8;i++)
 {
	 if(byte&(1<<i))
	 dpadSelective(i+1,1);
 else
 dpadSelective(i+1,0);
 }
so essentialy the red part glows led 1 if byte==0x20

if it is false then the blue (else part) glows all the LED corresponding to the respective bits

now here the 5th led glows everytime representing only bit 5 is high while the led 1 is off


:eek::eek::eek::eek::eek::eek:
 

kubeek

Joined Sep 20, 2005
5,795
I don´t know what dpadSelective is, but do you have 8 leds? Then you could simply put PORTA=byte; and see the byte light up.
Also you can try putting byte=0x20; in front of the first if and see if the checking code then does what you expect.
 

tshuck

Joined Oct 18, 2012
3,534
Try posting your whole code, or at least, a test case so that we can see where it is you are going wrong.
You may not even be using the correct baud rate as far as we know.

Simply posting that it is wrong doesn't help. Post what your debugger is saying. Post your code so that we can see what is happening, not a comparison and then say your LEDs light up weird. You aren't outputting anything as far as we know. dpadSelective() doesn't tell us anything.
 

ErnieM

Joined Apr 24, 2011
8,377
I have reviewed the code hundred times

still see this is the code
<snip>
so essentialy the red part glows led 1 if byte==0x20

if it is false then the blue (else part) glows all the LED corresponding to the respective bits

now here the 5th led glows everytime representing only bit 5 is high while the led 1 is off
I honestly have no idea what you are trying to say.

I do note that the indentation of your code does not follow convention as to what it is doing:
Rich (BB code):
  if(byte==(1<<5))
  {
    dpadSelective(1,1);
  }
  else
    for(int i=0;i<8;i++)
    {
      if(byte&(1<<i))
        dpadSelective(i+1,1);
      else
        dpadSelective(i+1,0);
    }
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
I don´t know what dpadSelective is, but do you have 8 leds? Then you could simply put PORTA=byte; and see the byte light up.
Also you can try putting byte=0x20; in front of the first if and see if the checking code then does what you expect.
Yes I have 8 LEDs whether I manually assign the byte to 0x20 or It is received from Uart both shows only 5th bit LED on so that part is correct:confused:


and yes sorry I didn't explained that earlier
"dpadSelective(short LEDno,short on/off)" sets an LED at LEDno to on or off state defined by on/off
 

thatoneguy

Joined Feb 19, 2009
6,359
What is the transmitting UART? Another uC?

Are you using the hardware UART on either or both units?

Without that info, no help can really be given. Hardware UARTs may pad until the buffer is full, sometimes reading incorrectly (which you are thinking is correct). bit banged uart on the other hand, we need to know details of both the sending side and receiving side to have an idea.

Do you have a logic analyzer or an in circuit debugger to see what is being moved on the wire or in the registers?
 

WBahn

Joined Mar 31, 2012
30,060
In C, at least for hosted implementations, a short is required to be at least 16 bits (IIRC). You are only working and looking at the lower byte of it. What is the upper byte equal to?

Try this:

byte = byte & 0xFF;
if (byte == 0x20)
...

and see if that makes a difference.
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
Let me cut down to the center of the problem

Does complimenting a byte then sending it and complimenting it again after receiving gives same byte back? (~ operator)

There are 8 led they show off off on off off off off off

thus they show the data received is what I sent i.e 0x20 or 0b00100000 or 1<<5 whatever you say it is. So I repeat the receiver is OK

NOTE:- I send the byte in complimented form using ~ operator

but the part


if(byte==0x20) doesn't come true no matter what

but if manually write byte=0x20; then it is true

here I'm posting the full code also I am using code optimisation Os (optimize for size)


Important parts in RED


Rich (BB code):
#define USART_BAUDRATE 2400
#define F_CPU 1000000
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>
short processComplete=0;

int readByte(){
while (( UCSRA & (1 << RXC )) == 0) {};
return UDR ;
}



//lights up 8 LED as per you like

void dpadSelective(int key,int on){
	if(on){
switch(key)
{
case 1:
PORTC|=(1<<PC5);//1
break;
case 2:
PORTC|=(1<<PC3);//2
break;
case 3:
PORTC|=(1<<PC2);//3
break;
case 4:
PORTC|=(1<<PC4);//4
break;
case 5:
PORTD|=(1<<PD3);//5
break;
case 6:
PORTD|=(1<<PD2);//6
break;
case 7:
PORTD|=(1<<PD5);//7
break;
case 8:
PORTB|=(1<<PB5);//8
break;

};
}//if on
else{
switch(key)
{
case 1:
PORTC&=~(1<<PC5);//1
break;
case 2:
PORTC&=~(1<<PC3);//2
break;
case 3:
PORTC&=~(1<<PC2);//3
break;
case 4:
PORTC&=~(1<<PC4);//4
break;
case 5:
PORTD&=~(1<<PD3);//5
break;
case 6:
PORTD&=~(1<<PD2);//6
break;
case 7:
PORTD&=~(1<<PD5);//7
break;
case 8:
PORTB&=~(1<<PB5);//8
break;

};
}

}

void dpadAll(short on){
	if(on){
PORTC|=0b00111100;
PORTB|=(1<<PD5);
PORTD|=((1<<PD3)|(1<<PD2)|(1<<PD5));
	}
	else
	{
PORTC&=~0b00111100;
PORTB&=~(1<<PD5);
PORTD&=~((1<<PD3)|(1<<PD2)|(1<<PD5));
	}
}

void setReceiver(){
UCSRB |= (1 << RXEN )|(1<<RXCIE);
UCSRC |= (1<<URSEL)| (1 << UCSZ1 )|(1 << UCSZ0 );
UBRRH = ( BAUD_PRESCALE>> 8); 
UBRRL = BAUD_PRESCALE ;
}

void setMotor(short on){
if(on){
	PORTD|=1<<PD7;
	PORTB|=1<<PB4;
}	
else
{
PORTD&=0b01111111;
PORTB&=0b11101111;
}
	
	
}


void processByte(unsigned short bytr){

processComplete=0;
  byte=~byte;

if(byte==(1<<5))
{dpadSelective(1,1);}
else{
 for(int i=0;i<8;i++)
 {
	 if(byte&(1<<i))
	 dpadSelective(i+1,1);
 else
 dpadSelective(i+1,0);
 }
} 
processComplete=1;
}//end process



void setupIO(){
DDRB=0xff;
DDRD=0xff;

DDRC=0xff;
}


int  main(){
setupIO();
sei();
processComplete=1;

setReceiver();

while(1){
	//processByte(readByte);
}//end while(1)

}
ISR(USART_RXC_vect) 
{ 
	if(processComplete)
	processByte(UDR);
}
something more I did was take the received byte and construct its equivalent by checking each bit (effectively binary to dcimal conversion)

Results were always 1 less than original byte (my algorithm sucks?:confused:)
 

WBahn

Joined Mar 31, 2012
30,060
But none of this is going to deal with the equality problem you are seeing if the variable byte is 16 bits and there is something in those upper bits.

Another thing to try is read a value in from the UART into byte (just like you have been and which you hope is 0x20) and then use

byte = byte >> 8;

and then apply that to your LEDs and see if any of them light up. If any of them do, then something is getting stored in the upper byte.
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
THANKS TO ALL IT FINALYY WORKED OUT :D:D:D:D

AND BIG SORRY because I didn't thought of it earlier!

the compliment operation (~ ) is the culprit (please note I sent a complimented byte and complimented it again after it was received thinking it would yield the original byte)

I thought it just inverted the bits like 0b00001111 becomes 0b11110000 after using ~ operator ..

BUT NO! something is wrong here it won't do that , its something I don't understand yet !

can someone please explain it to me? Does it makes the byte to its 1s or 2s compliment instead of just inverting bits?
 
Top