Shop OBEX P1 Docs P2 Docs Learn Events
Sending cnt in bytes — Parallax Forums

Sending cnt in bytes

QuadrtrFlyrQuadrtrFlyr Posts: 73
edited 2013-02-12 12:18 in Propeller 1
Hello folks,

Once again I have come back with a question and I would really appreciate your help!

I am trying to send the System Counter register (cnt) through a serial line in bytes to a device that needs some sort of time update. However cnt is 32 bits (long) and I need to split it up since I am sending 8bit packets (1 byte) at a time. I am not too good with bit shifting so could someone lend a helping a hand on how to split up this 32 bit long variable into 4 separate bytes?

Looking at the parallax propeller manual on page 219 it states that if I am using a 5MHz crystal than 50,000 cycles is about 10 ms (1/100th second) of time. So is it safe to assume that 1 cycle is equal to .2 microseconds? (1cycle*(10ms/50,000cycles)=.0002ms = .2 microseconds?

Thank you,
Robert

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-02-11 20:03
    Using FullDuplexSerial:
    value := cnt
      repeat 4
        fds.tx(value)
        value >>= 8    ' LSB first
    
    or
    value := cnt
      repeat n from 0 to 3
        fds.tx(value.byte[n])
    
    Looking at the parallax propeller manual on page 219 it states that if I am using a 5MHz crystal than 50,000 cycles is about 10 ms (1/100th second) of time. So is it safe to assume that 1 cycle is equal to .2 microseconds? (1cycle*(10ms/50,000cycles)=.0002ms = .2 microseconds?
    Assuming you actually run @5MHz then yes, this is correct. Usually PLL is added as well which will give you 80MHz (12.5ns).
  • QuadrtrFlyrQuadrtrFlyr Posts: 73
    edited 2013-02-11 20:48
    Good catch on the PLL! I would have forgotten about that. and thank you for the code. I added this code to the Parallax Servo Controller firmware but am not getting the correct results. Could you take a look at it.
    long value
    
    PUB SendDataByte(Data)          '' Sends a serial data BYTE to two seperate locations
        if ina[USB_Rx] == 0         '' Check to see if USB port is powered
           outa[USB_Tx] := 0        '' Force Propeller Tx line LOW if USB not connected
        else
           COMport1.tx(Data)
        COMport2.tx(Data)
    
    
    PUB VersionRequest | n
        if U_Flag == 0               '' Normal version reply
           SendDataString(string("1.0"))
    ------------------------------------
           value := cnt
           repeat n from 0 to 3
              SendDataByte(value.byte[n])
    ------------------------------------
        else                           
           U_Flag := 0               '' Make the PSC compatible with the PSCI
           SendDataString(string("!SCVER?",13,"1.0"))
    
  • Mike GreenMike Green Posts: 23,101
    edited 2013-02-11 20:57
    Your code looks correct. What are you expecting on the other end? You're sending the least significant byte first (little-endian order) and you're sending it in 8-bit binary. Is that what you want?
  • QuadrtrFlyrQuadrtrFlyr Posts: 73
    edited 2013-02-11 21:16
    Yes that is what I want, I am reading in C:
    int currenttime;
    char version[8]   = {0x21,0x53,0x43,0x56,0x45,0x52,0x3F,'\r'}; //!SCVER? \r
    write(tty_fd1,version,8);
     if (read(tty_fd1,buffer1,19)>0)
    {
        if(buffer1[0] == '1' && buffer1[1] == '.' && buffer1[2] == '0')  //check for snp packets and euler angles data type
        {
             currenttime = (int)(buffer1[3]+(buffer1[4]<<8)+(buffer1[5]<<16)+(buffer1[6]<<24));
             printf("v1.0 %d\n\r",currenttime);
        }
    }
    

    Any ideas? I think I am shifting all the bits back into their correct location. The code reads the 1.0 (checked) but not the currenttime..
  • Mike GreenMike Green Posts: 23,101
    edited 2013-02-11 21:22
    Can't tell you without some information like what you're sending and what you're receiving (preferably in hex). Given that, you can probably figure that out yourself by looking at the byte values. The code you've shown looks like it should work. That's the problem with only showing the code that you think is important. Often the problem is somewhere else that you're not showing.
  • QuadrtrFlyrQuadrtrFlyr Posts: 73
    edited 2013-02-11 21:38
    I updated the code above to include what I am sending (in hex) and receiving. Take a look if you are interested. But yes I see what you mean... hmm I guess I will keep scratching my head over it. But I believe the code on the C side is correct, are you sure the parallax code is good?
  • kuronekokuroneko Posts: 3,623
    edited 2013-02-11 21:52
    But I believe the code on the C side is correct, ...
    What is the actual result of the read function? Just because you ask for 19 bytes doesn't mean you get that many.
  • QuadrtrFlyrQuadrtrFlyr Posts: 73
    edited 2013-02-11 22:01
    It was printing out 1's, 0's, and random byte decimals occasionaly. HOWEVER, it now works perfectly! Very very simple mistake, I accidentally set the variable "value" in the parallax propeller code as a byte instead of a long. Thank you for all of the help. Once again you guys proved to be the best forum help on the planet :smile:
  • QuadrtrFlyrQuadrtrFlyr Posts: 73
    edited 2013-02-11 22:07
    One last question! How could I add all of these bytes including the 1, . , 0, and bytes to create a checksum in the propeller code?

    Is this correct:
    long chksum
    PUB VersionRequest | n
        if U_Flag == 0               '' Normal version reply
           SendDataString(string("1.0"))
           value := cnt
           repeat n from 0 to 3
              SendDataByte(value.byte[n])
              chksum := chksum + value.byte[n]
           repeat n from 0 to 1
              SendDataByte(chksum.byte[n])
    
  • kuronekokuroneko Posts: 3,623
    edited 2013-02-11 22:35
    You should initialise chksum with the sum of the three bytes making up the string "1.0" ($8F).
  • AribaAriba Posts: 2,690
    edited 2013-02-11 22:45
    kuroneko wrote: »
    You should initialise chksum with the sum of the three bytes making up the string "1.0" ($8F).

    Something like that:
    PUB VersionRequest | n, chksum
        if U_Flag == 0               '' Normal version reply
           SendDataString(string("1.0"))
           chksum := "1" + "." + "0"
           value := cnt
           repeat n from 0 to 3
              SendDataByte(value.byte[n])
              chksum += value.byte[n]
           SendDataByte(chksum.byte[0])
    
    Usually only one byte for the checksum is used (the lowest byte of the sum). This has enough information to verify the correct transmission.

    Andy
  • QuadrtrFlyrQuadrtrFlyr Posts: 73
    edited 2013-02-12 12:18
    Many thanks! The propeller side of things is sending serial data flawlessly. Figured out the C part too! Thank you!
Sign In or Register to comment.