Shop OBEX P1 Docs P2 Docs Learn Events
Working with 8 bit gray code and Prop 1 — Parallax Forums

Working with 8 bit gray code and Prop 1

I have an 8-bit absolute encoder that I'd like to use with a wind direction indicator. Does Propeller 1 know about gray code ;) . My previous try used a total of 8 magnet/switches to get 16 8-bit hex outputs. I'm not sure how to start with this or if I wasted my money. Help
Aaron

Comments

  • @AGCB said:
    I have an 8-bit absolute encoder that I'd like to use with a wind direction indicator. Does Propeller 1 know about gray code ;) . My previous try used a total of 8 magnet/switches to get 16 8-bit hex outputs. I'm not sure how to start with this or if I wasted my money. Help
    Aaron

    Well, you do not tell too much here.
    I would read the 8 bits and then perhaps use some kind of converter, perhaps a table. Then you will perhaps need some low pass filter for the direction. Language? Application of result?

  • jmgjmg Posts: 15,155

    You will need some simple code to gray to binary.
    A lookup table, or one Gray code pattern can decode with XOR gates.
    See
    https://www.elprocus.com/code-converter-binary-to-gray-code-and-gray-code-to-binary-conversion/

  • I was hoping there might be a prewritten OBJECT for conversion. Otherwise, I may have to attempt a lookup table or something.
    Aaron

  • JonnyMacJonnyMac Posts: 8,963
    edited 2023-11-18 23:15

    I was hoping there might be a prewritten OBJECT

    You shouldn't do that -- not everyone cares about what we care about, and writing a library takes time. Time you seem unwilling to take and then share with everyone else. Am I wrong?

    No worries, I'll bite. What's the device you want code for? That detail is important when you're hoping others have written code so you don't have to. I need a rainy Saturday mental challenge so I'll see what I can do. No promises, though.

    A few moments later...

    Never mind. The neat thing about the Internet is with a bit of searching you can find algorithms for anything. I found one that explained converting Gray Code to binary and implemented it in Spin. I tested with all 4-bit Gray Code values and it works. I also plugged in %10000000 which returns %11111111 as expected. The choice is yours. You can use a look-up table if speed is more of a concern than program space. If speed is not an issue, this routine compiles to 36 bytes according to Propeller Tool.

    pub gray2bin(value, msb) : result | n, last
    
    '' Convert gray code value to binary
    '' -- msb is highest bit of value (e.g., 7 for byte)
    
      result := last := (value >> msb) & 1
    
      repeat n from msb-1 to 0
        if ((value >> n) & 1)
          last ^= 1                                
        result := (result << 1) | last
    
  • Jon
    I'm not worried about time. If a wheel already exists, why reinvent it! I'd love to share with others (so yes you are wrong) but I'm not as good as 98% of the people on this forum. That being said, I want to get this thing working whatever it takes.

    I have a E6CP-AG5 encoder and was planning on using a 74HC165 shift register to send bytes to the propeller where it would be displayed on my big screen as wind direction. The SR and display already works but my home-made magnet and switches on the tower are not so good. I want 16 different outputs to coincide with cardinal directions plus the 4 in-betweens and 1/2 of those. (So North, Northwest and North-Northwest.) Everything in between (the other 239 bytes) is unused. I been reading the one I have about once every 3-5 seconds, so speed is not an issue.
    Thanks for your interest. I'll look at that code and see what I can do with it.
    Aaron

  • JonnyMacJonnyMac Posts: 8,963
    edited 2023-11-19 00:20

    Not that you asked, but this is what I'd do:

      deg10 := (360_0 * gray2bin(read_encoder, 7)) >> 8
    

    This will give you degrees in 0.1 units, with a resolution of 1.4 degrees.

    ...but I'm not as good as 98% of the people on this forum.

    Paraphrasing and old joke (How do you get to Carnegie Hall?"): code, code, code.

  • AGCBAGCB Posts: 327
    edited 2023-11-19 19:55

    I'm doing something wrong. For input of %10000000 I get 00000001, not 11111111.
    Changed var names to mine. What is deg10?
    Thanks What's the new way to post code??
    Aaron

    CON       
      _clkmode = xtal1 + pll16x      '80 MHz system clock
      _xinfreq = 5_000_000
    
    OBJ
      tv         :  "tv_text"    
    VAR
      long winput, gray, EncOut 
    PUB  main
        tv.start(0)
    
        EncOut:=%10000000        'also tried % and none
    
        repeat                     ' loop
          winput := (360_0 * gray2bin(EncOut, 7)) >> 8
          go(4,4)    'TV location on screen
          TV.bin(winput,8)      'also tried hex and dec
    
    
    
    pub gray2bin(value, msb) : result | n, last
    
    '' Convert gray code value to binary
    '' -- msb is highest bit of value (e.g., 7 for byte)
    
      result := last := (value >> msb) & 1
    
      repeat n from msb-1 to 0
        if ((value >> n) & 1)
          last ^= 1                                
        result := (result << 1) | last
    
    PRI go(x,y)
      TV.move(x,y)       
    
  • JonnyMacJonnyMac Posts: 8,963
    edited 2023-11-19 19:52

    I'm doing something wrong.

    Yes, you are. Here's proof the gray2bin() method works:

    For reasons known only to you, you're converting to tenths of degrees (that's what deg10 means above) and expecting to get 255. Why? The expression you're doing is

    360_0 * 255 / 256

    ...which results in 3585, or %1110_0000_0001 -- the last 8 bits are %00000001. Your code is working as you wrote it -- like this:

  • @AGCB said:
    What's the new way to post code??
    Aaron

    Use 3 backticks on the line before and the line after the code. I've edited your code above for you, so you can edit your own post to see how it's done!

  • With the following code I get %00000001 Should be %11111111, no?

    CON       
      _clkmode = xtal1 + pll16x      '80 MHz system clock
      _xinfreq = 5_000_000
    
    OBJ
      tv : "tv_text"    
    VAR
      long winput, EncOut 
    PUB  main
        tv.start(0)
    
       '
        EncOut:=%10000000        
    
        repeat                     
          winput := (360_0 * gray2bin(EncOut, 7))  >>8       
          go(4,4)   
          TV.bin(winput,8)     
    
    
    
    pub gray2bin(value, msb) : result | n, last
    
    '' Convert gray code value to binary
    '' -- msb is highest bit of value (e.g., 7 for byte)
    
      result := last := (value >> msb) & 1
    
      repeat n from msb-1 to 0
        if ((value >> n) & 1)
          last ^= 1                                
        result := (result << 1) | last
    
    PRI go(x,y)
      TV.move(x,y)  
    
  • With the following code I get %00000001 Should be %11111111, no?

    No! I explained why in great detail above.

    If you're dead set on seeing %11111111 on screen, change your code to:

        repeat                     
          winput := gray2bin(encOut, 7)
          go(4,4)   
          tv.bin(winput,8)  
    

    At that point you can hook up your encoder read circuit and you should see %00000000 -> %11111111 for one rotation. To convert the angular position to tenths of degrees, go back the the expression that you keep tripping over. Put it into a method so your code is more obvious. This will convert the gray code output from the encoder to tenths of degrees, 000_0 to 358_5, which each encoder count being worth 1.4 degrees (14 as tenths).

    pub gray2deg10(encGray) : result
    
      return (360_0 * gray2bin(encGray, 7)) >> 8
    
  • Jon
    In both working it by hand and looking at a conversion chart online, the binary equivalent of G10000000 is B11111111. I think the code you gave me is for B to G
    Aaron

  • JonnyMacJonnyMac Posts: 8,963
    edited 2023-11-19 23:04

    You mean like this (that I posted above):

    I think the code you gave me is for B to G

    No, it isn't. I did develop a method so I could verify both directions. You can see that below -- but this is the first time you're seeing binary to gray from me.

    Here, let me see if I can make it more obvious before I click the IGNORE button. I'll even output the numbers like you do in your post. Good luck with your project; I'm done.

  • Jon
    Thanks for all your time. I'll figure it out eventually. Probably what you said in the 1st place.
    Aaron

  • QUOTE If you're dead set on seeing %11111111 on screen, change your code to:

    repeat                     
      winput := gray2bin(encOut, 7)
      go(4,4)   
      tv.bin(winput,8)  
    

    That's all I wanted!!!

    Sorry for the confusion

Sign In or Register to comment.