Shop OBEX P1 Docs P2 Docs Learn Events
Using a DAT block to provide a sequence of commands and values — Parallax Forums

Using a DAT block to provide a sequence of commands and values

LoopyonionLoopyonion Posts: 24
edited 2013-09-18 15:57 in Propeller 1
Hi,

Ive been having a look if this is possible, and thought i'd ask the experts out there, before i pour countless hours into why it wouldnt work. Basically, id like to have a DAT block, that i could use to feed a series of instructions and values.
Think of it like a CNC program, where I can state:-

move to position 1, wait 100ms, perform this action, wait 200ms.. and so on.

Heres my principle:-
'P = POSITION'W = WAIT


G1    WORD "P",2,"W",100,"P",1,255


The aim would be POSITION 2, WAIT for 100ms, then POSITION 1. When 255 is read, then thats the end of the line. Could I use something different for end of line, as the values i need to use will be between 0 and 5000 as thats the longest time in millisecs i would want to wait for. Maybe a character?

then calling:-
PUB pattern_sequence | Step, Command, Value

 Repeat until Step := 255
  Step := 0
  Command := word[G1][Step]
  Step++
  Value := word[G1][Step] 
  Step++


  case Command 
    POSITION : pos(Value) ' POSITION SUBROUTINE
    WAIT : wait(Value) ' WAIT TIME SUBROUTINE



Is it possible, or am i barking up the totally wrong tree?

It would be nice to have a command sequence more like CNC, ie p002, w100,p001 etc..

Help and advice welcome ! thanks again.:)

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2013-09-15 10:46
    You've got the right idea, but the program fragment is wrong. Try something like this:
    CON endCmd = $FF << 24
        posCmd = "P" << 24
        waitCmd = "W" << 24
    DAT
    G1   long   posCmd+2, waitCmd+100, posCmd+1, endCmd
    PUB pattern_sequence(table)  |  entry, command, value
       entry := 0   ' start at the beginning of the table
       repeat
          command := long[table][entry++]   ' get the table entry
          value := command & $FFFFFF   ' extract the value portion
          case command & $FF000000   ' execute the command
             endCmd: return
             posCmd: position(value)
             waitCmd: wait(value)
    
    You'd call this with "pattern_sequence(@G1)". Depending on the parameter values you want to pass, you could store these commands in words with different amount of bits for the command and value, like 3 bits for the command and 13 bits for the value.
  • LoopyonionLoopyonion Posts: 24
    edited 2013-09-15 12:25
    Ah, that would work so much better. Thanks! The commands and values are in one block.

    Would you mind explaining the :-
    [COLOR=#333333][FONT=Parallax]CON endCmd = $FF << 24[/FONT][/COLOR]
    posCmd = "P" << 24    
    waitCmd = "W" << 24
    

    Using posCmd, instead of "P" would not be an issue, and aid future debugging.

    The aim is, in future, to be able to use a serial transmitted string of command sequences, from a pc to the prop, the prop to store these in data blocks by writing them into memory, then on reboot, recall and execute them. ( more on this later):)

    It may have been done ( more than likely) and its a multi stage project.

    This I consider to be the foundation :)
  • Mike GreenMike Green Posts: 23,101
    edited 2013-09-15 12:39
    Essentially it's storing the command in the most significant byte of the long value (bits 31..24) and the parameter in the other bytes (bits 23..0). These constant definitions simply give a convenient name to specific commands as they're stored in the longs.

    Note that these command sequences can be very complicated. For example, you could have a repeat command that repeats the following command (or commands) a specified number of times, possibly varying the parameter used in the next command as it repeats. You could have test commands that check for some condition and skip the next command if false. You could also have a relative jump command that would jump backwards or forwards a specified number of steps. That's enough to be able to write programs in your CNC-like control language.
  • edited 2013-09-15 13:52
    Loopyonion wrote: »
    Hi,

    Ive been having a look if this is possible, and thought i'd ask the experts out there, before i pour countless hours into why it wouldnt work. Basically, id like to have a DAT block, that i could use to feed a series of instructions and values.
    Think of it like a CNC program, where I can state:-

    move to position 1, wait 100ms, perform this action, wait 200ms.. and so on.

    If all your commands require a single parameter then you could use letters for commands followed by numbers for the parameter and finish of the list with Z 0 or something unique.
    G1    WORD "P",2,"W",100,"P",1,"Z",0
    

    I'm not that familiar with spin but Step gets set to zero at the beginning of the loop so only the first two words will be retrieved.

    Regards,
    Sandy
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-09-15 14:50
    I'm working with a friend on an animatronics project that has four servos: two Dynamixel servos and two standard servos. He asked me if we could come up with a way of scripting moves and calling them -- which is very much what you seem to want to do here. As I started my embedded life with the BS1 (the grandfather of the Propeller), I try to conserve memory when I can so I'm using bytes instead of words, which means a little extra work with 2-byte values in a command sequence. By putting just one command per line in the DAT section I think I can minimize errors.
    dat
    
      ' Format of command string:
      ' ** "P" { position }
      '    -- device #
      '    -- low byte of position
      '    -- high byte of position
      '
      ' ** "W" { wait }
      '    -- low byte of delay (milliseconds)
      '    -- high byte of delay
      '
      ' ** "X" { eXit command sequence }
    
    
      CmdTest1              byte    "P", 1,  600 & $FF,  600 >> 8
                            byte    "P", 2, 2400 & $FF, 2400 >> 8
                            byte    "W",    1000 & $FF, 1000 >> 8
                            byte    "P", 1, 2400 & $FF, 2400 >> 8
                            byte    "W",    1500 & $FF, 1500 >> 8    
                            byte    "X"
    


    I've attached a demo program that reads and displays a command sequence (and holds when a Wait is specified).
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-09-15 17:20
    Well, maybe words are a better way to go with this.
    CmdTest2              word    "P" | (1 << 8),  600
                            word    "P" | (2 << 8), 2400
                            word    "W",            1000
                            word    "P" | (1 << 8), 2400
                            word    "W",            1500
    

    pub run_command_demo2(p_src) | ofs, work, cmd, id, value
    
    '' Extract commands from DAT string at p_src
    '' -- uses word format
    
      ofs := 0                                                      ' offset into data
    
      repeat
        work := word[p_src][ofs++]                                  ' get command & id
        cmd  := work.byte[0]                                        ' extract
        id   := work.byte[1]
    
        case cmd
          "p", "P":
            value := word[p_src][ofs++]                             ' get position
             
            term.str(string("Position: #"))
            term.dec(id)
            term.str(string(", "))
            term.dec(value)
            term.tx(CR) 
             
          "w", "W":
            value := word[p_src][ofs++]                             ' get wait time
             
            term.str(string("Wait: "))
            term.dec(value)
            term.str(string("ms", CR, CR))
            pause(value)
    
          other:                                                    ' "X" or bad cmd value
            return
    
  • LoopyonionLoopyonion Posts: 24
    edited 2013-09-18 14:51
    Thanks very much for the help so far, I'm going to try both the methods over the weekend.

    Ill see where I end up ;)
  • Ray0665Ray0665 Posts: 231
    edited 2013-09-18 15:57
    Go have a look at my object in the obex "mother of all led sequencers" for some additional ideas I have recently added an all spin object there as well.
Sign In or Register to comment.