Probelm with bit and byte interpretation

Discussion in 'Embedded Systems and Microcontrollers' started by allahjane, Jan 14, 2013.

  1. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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:
    Code ( (Unknown Language)):
    1.  
    2. short byte=UDR;
    3. if(byte&(1<<5))
    4. {
    5. // do stuff for bit 5
    6. }
    7.  
    Then it works fine always

    BUT, if I write it as this:

    Code ( (Unknown Language)):
    1.  
    2. short byte=UDR;
    3. if(byte==0b00100000)
    4.  
    5. OR
    6. short byte=UDR;
    7. if(byte==0x20)
    8.  
    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 !
     
  2. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    Lets say the byte you get in is 0b0010 0001, is this equal to 0b0010 0000? No it´s not.
    Code ( (Unknown Language)):
    1. 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.
     
  3. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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?
     
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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.
     
  5. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    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.
     
    allahjane likes this.
  6. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    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.
     
  7. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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
     
  8. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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
     
  9. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    You have to use the debugger/simulator tool to trace down the error. Add some watches, set some breakpoints, and also use the singlestepper.
     
  10. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    I have reviewed the code hundred times

    still see this is the code
    Code ( (Unknown Language)):
    1. [COLOR="Red"]
    2.  if(byte==(1<<5))
    3.  {dpadSelective(1,1);}[/COLOR][COLOR="Blue"]
    4.      else
    5.  for(int i=0;i<8;i++)
    6.  {
    7.      if(byte&(1<<i))
    8.      dpadSelective(i+1,1);
    9.  else
    10.  dpadSelective(i+1,0);
    11.  }[/COLOR]
    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:
     
  11. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    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.
     
  12. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    You can review the code a thousand times and still miss the obvious. Nothing can replace using your debugger. It will help you to find mistakes. It was the whole reason one was developed. Learn how to use it.
     
  13. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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.
     
  14. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    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:
    Code ( (Unknown Language)):
    1.  
    2.   if(byte==(1<<5))
    3.   {
    4.     dpadSelective(1,1);
    5.   }
    6.   else
    7.     for(int i=0;i<8;i++)
    8.     {
    9.       if(byte&(1<<i))
    10.         dpadSelective(i+1,1);
    11.       else
    12.         dpadSelective(i+1,0);
    13.     }
    14.  
     
  15. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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
     
  16. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    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?
     
  17. WBahn

    Moderator

    Mar 31, 2012
    17,760
    4,800
    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.
     
  18. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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


    Code ( (Unknown Language)):
    1.  
    2. #define USART_BAUDRATE 2400
    3. #define F_CPU 1000000
    4. #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    5. #include <avr/io.h>
    6. #include <util/delay.h>
    7. #include <avr/interrupt.h>
    8. #include <math.h>
    9. short processComplete=0;
    10.  
    11. int readByte(){
    12. while (( UCSRA & (1 << RXC )) == 0) {};
    13. return UDR ;
    14. }
    15.  
    16. [COLOR="red"]
    17.  
    18. //lights up 8 LED as per you like
    19.  
    20. void dpadSelective(int key,int on){
    21.     if(on){
    22. switch(key)
    23. {
    24. case 1:
    25. PORTC|=(1<<PC5);//1
    26. break;
    27. case 2:
    28. PORTC|=(1<<PC3);//2
    29. break;
    30. case 3:
    31. PORTC|=(1<<PC2);//3
    32. break;
    33. case 4:
    34. PORTC|=(1<<PC4);//4
    35. break;
    36. case 5:
    37. PORTD|=(1<<PD3);//5
    38. break;
    39. case 6:
    40. PORTD|=(1<<PD2);//6
    41. break;
    42. case 7:
    43. PORTD|=(1<<PD5);//7
    44. break;
    45. case 8:
    46. PORTB|=(1<<PB5);//8
    47. break;
    48.  
    49. };
    50. }//if on
    51. else{
    52. switch(key)
    53. {
    54. case 1:
    55. PORTC&=~(1<<PC5);//1
    56. break;
    57. case 2:
    58. PORTC&=~(1<<PC3);//2
    59. break;
    60. case 3:
    61. PORTC&=~(1<<PC2);//3
    62. break;
    63. case 4:
    64. PORTC&=~(1<<PC4);//4
    65. break;
    66. case 5:
    67. PORTD&=~(1<<PD3);//5
    68. break;
    69. case 6:
    70. PORTD&=~(1<<PD2);//6
    71. break;
    72. case 7:
    73. PORTD&=~(1<<PD5);//7
    74. break;
    75. case 8:
    76. PORTB&=~(1<<PB5);//8
    77. break;
    78.  
    79. };
    80. }
    81.  
    82. }[/COLOR]
    83.  
    84. void dpadAll(short on){
    85.     if(on){
    86. PORTC|=0b00111100;
    87. PORTB|=(1<<PD5);
    88. PORTD|=((1<<PD3)|(1<<PD2)|(1<<PD5));
    89.     }
    90.     else
    91.     {
    92. PORTC&=~0b00111100;
    93. PORTB&=~(1<<PD5);
    94. PORTD&=~((1<<PD3)|(1<<PD2)|(1<<PD5));
    95.     }
    96. }
    97.  
    98. void setReceiver(){
    99. UCSRB |= (1 << RXEN )|(1<<RXCIE);
    100. UCSRC |= (1<<URSEL)| (1 << UCSZ1 )|(1 << UCSZ0 );
    101. UBRRH = ( BAUD_PRESCALE>> 8);
    102. UBRRL = BAUD_PRESCALE ;
    103. }
    104.  
    105. void setMotor(short on){
    106. if(on){
    107.     PORTD|=1<<PD7;
    108.     PORTB|=1<<PB4;
    109. }  
    110. else
    111. {
    112. PORTD&=0b01111111;
    113. PORTB&=0b11101111;
    114. }
    115.    
    116.    
    117. }
    118.  
    119. [COLOR="Red"]
    120. void processByte(unsigned short bytr){
    121.  
    122. processComplete=0;
    123.   byte=~byte;
    124.  
    125. if(byte==(1<<5))
    126. {dpadSelective(1,1);}
    127. else{
    128.  for(int i=0;i<8;i++)
    129.  {
    130.      if(byte&(1<<i))
    131.      dpadSelective(i+1,1);
    132.  else
    133.  dpadSelective(i+1,0);
    134.  }
    135. }
    136. processComplete=1;
    137. }//end process
    138.  
    139. [/COLOR]
    140.  
    141. void setupIO(){
    142. DDRB=0xff;
    143. DDRD=0xff;
    144.  
    145. DDRC=0xff;
    146. }
    147.  
    148. [COLOR="red"]
    149. int  main(){
    150. setupIO();
    151. sei();
    152. processComplete=1;
    153.  
    154. setReceiver();
    155.  
    156. while(1){
    157.     //processByte(readByte);
    158. }//end while(1)
    159.  
    160. }
    161. ISR(USART_RXC_vect)
    162. {
    163.     if(processComplete)
    164.     processByte(UDR);
    165. }[/COLOR]
    166.  
    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:)
     
  19. WBahn

    Moderator

    Mar 31, 2012
    17,760
    4,800
    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.
     
  20. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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?
     
Loading...