Shop OBEX P1 Docs P2 Docs Learn Events
Array over serial transmission — Parallax Forums

Array over serial transmission

joethumphreyjoethumphrey Posts: 25
edited 2011-03-08 13:51 in Propeller 1
Where can I find info on sending an array over a serial connection?

I'm using the FullDuplex module . I can send various variables in separate lines but is there a way to just send the entire array with one call?
comms.dec(arr[0])
comms.dec(arr[1])
comms.dec(arr[2])

to something like
comms.dec(arr[%])

and get the whole array sent?

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2011-03-01 07:35
    There's no way to send the whole array. You have to do it one element at a time like you showed in the first code box, but use a REPEAT loop rather than having separate statements for each element. You also need some kind of punctuation or fixed format so that the receiving end can tell where one number ends and the next one starts. Try something like:
    repeat i from 0 to maxArr-2
       comms.dec(arr[ i ])
       comms.tx(" ")
    comms.dec(arr[ maxArr-1 ])
    comms.tx(13)
    
    This will send all the values, each separated from the other by a space and the whole set ended with a carriage return.
  • joethumphreyjoethumphrey Posts: 25
    edited 2011-03-01 13:48
    Thank you. I am using commas as field separators . I was more worried with not being able to find anything on the array, but you've answered that.

    Using the repeat for testing but I have to have an "if" wrapper based on array fill for the send function.

    Reading about locks right now.
  • joethumphreyjoethumphrey Posts: 25
    edited 2011-03-03 12:47
    I seem to be having variable leakage.
    PUB runTest
      dira[19]~~
      dira[22]~~
    
      if comms.start(rxPin, txPin,2,9600)
      outa[19] := true
    
    
      waitcnt(30_000_000+cnt)
    
    repeat
      if trigger == 1
        comms.dec(arr[0])
        comms.tx(",")
        comms.dec(arr[1])
        comms.tx(",")
        comms.hex(cnt,8)
        comms.tx(",")
        comms.dec(counter)
        comms.tx(",")
        comms.dec(arr[4])
        comms.tx(13)
        trigger:= 0
    

    With "trigger" being set elsewhere I seem to be getting a wiggle in the output.

    In another cog, I set
    trigger:= 1
    
    once a threshold is hit. Happens to be a comparison of a 3202 return, check for trailing edge of a signal.

    What could be causing this sporadic variable?
  • joethumphreyjoethumphrey Posts: 25
    edited 2011-03-03 12:51
    Seems I missed the listing the issue troubleshooting steps used.

    I keep getting sporadic output unless I run the qualifier
    if trigger ==1
    
    to beyond 1.

    Like "2" or higher, then the random outputs to serial line quits.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-03-03 12:59
    I don't understand what you mean nor what you're trying to do. How about attaching your source code rather than snippets? Often the problem is in the portions not shown. What do you mean by "wiggle" and "sporadic output"?
  • joethumphreyjoethumphrey Posts: 25
    edited 2011-03-03 13:58
    Sorry about that. What I mean by variable leakage is the variable "trigger" seems to, well, vary between states vs an either/or state.

    With it (variable 'trigger') set as 0 or 1 , shouldn't it be one or the other?
    Because I keep getting random data dumped on the serial out line with it checked on an if statement. If set the check number on the if statement higher I get no random data dumping. I labeled the if statement in bold.


    CON
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      bits =12
      chipDin =1    'to pin  5
      chipClk =3    'to pin  7
      chipSel =0    'to pin  1
      chipDout=2    'to pin  6
      BitsRead=12
      rxPin = 5
      txPin = 6
      threshold = 95/100   ' devider for difference between squential reads
    VAR
      long Cog
      long stack2[10]
      long counter        'encoder accumulator
      long card           'card pulse accu
      byte detect         'card detect
      long val            'amplitude
      long arr[5]         'results
      long PotReading
      long DataRead
      byte input
      'byte threshold
      long oldread
      byte trigger
    
    OBJ
    
      
      comms : "FullDuplexSerial"
    PUB start|Count
      text.start(16)
      cognew(Go,@stack2)
      cognew(runTest,2000)
      cognew(@entry,@arr[4])
      cognew(@detecter,@detect)
    
    PUB Go
    
      DIRA[chipDin]~~     '19 data set up to the chip
      DIRA[chipClk]~~     '20 oscillates to read in data from internals
      DIRA[chipSel]~~     '21 osc once to set up 3202
      DIRA[chipDout]~     '22 data from the chip to the Propeller
      repeat
        oldread:= DataRead
        DataRead:=0             'Clear out old data
        'waitcnt(1000+cnt)       'Wait for things to settle down, but not needed
        outa[chipSel]~~         'Chip select has to be high to start off
        outa[chipSel]~          'Go low to start process
    
        outa[chipClk]~          'Clock needs to be low to lead data
        outa[chipDin]~~         'must start with Din low to set up 3202
        outa[chipClk]~~         'Clock low to read data in
    
        outa[chipClk]~          'Low to load
        outa[chipDin]~~         'High single mode
        outa[chipClk]~~         'High to read
    
        outa[chipClk]~          'Low to load
        outa[chipDin]~          'Odd = channel 0
        outa[chipClk]~~         'High to read
    
        outa[chipClk]~          'Low to load
        outa[chipDin]~~         'msbf high = MSB first
        outa[chipClk]~~         'High to read
    
        outa[chipDin]~          'making line low for rest of cycle
    
        outa[chipClk]~          'Low to load
                                'Read the null bit, we dont need to store it
        outa[chipClk]~~         'High to read
    
        repeat BitsRead          'Reads the data into DataRead in 12 steps
          outa[chipClk]~         'Low to load
          DataRead:=DataRead+ina[chipDout]  'Xfer the data from pin chipDout
          outa[chipClk]~~        'High to read
          DataRead <<= 1         'Move data by shifting left 1 bit. Ready for next bit
    
        outa[chipSel]~~          'Put chip to sleep, low power
          DataRead >>= 1         'Shift data right 1 bit to cancel last "bad" shift
          PotReading:=DataRead   'Finished data read for display
          arr[4]:= DataRead
        if oldread > DataRead * threshold
          trigger:= 1
          arr[4]:= oldread
    
    
    PUB runTest
      dira[19]~~
      dira[22]~~
    
      if comms.start(rxPin, txPin,2,230400)
      outa[19] := true
    
    
      waitcnt(30_000_000+cnt)
    
    repeat
     if arr[4] > 1
      if trigger == 1          [B]<-- here, if I set this number higher it stops dumping data[/B]
        comms.dec(arr[0])
        comms.tx(",")
        comms.dec(arr[1])
        comms.tx(",")
        comms.hex(cnt,8)
        comms.tx(",")
        comms.dec(counter)
        comms.tx(",")
        comms.dec(arr[4])
        comms.tx(13)
        trigger:= 0
    
        'waitcnt(100_000+cnt)
    DAT
    
                                    org     0
    
    entry                   waitpeq ina, SENSE_PIN                  ' wait for high
                            nop
                            waitpne ina, SENSE_PIN                  ' wait for low
                            rdlong  mycount, par                    ' get count from hub
                            add     mycount, #1                     ' increment
                            wrlong  mycount, par                    ' put it back
                            jmp     #entry
    
    
    SENSE_PIN               long    1 << 4                          ' p4
    
    mycount                 res     1
    
                                    org      0
    detecter                waitpeq ina, dectectPin
                            wrbyte  n1,par                          ' wait for high
                            waitpne ina, dectectPin                  ' wait for low
                            wrbyte  n2,par                    ' put it back
                            jmp     #detecter
    
    
    dectectPin              long    1 << 6                          ' p4
    n1                      long    1
    n2                      long    0
    meddct                 res     1
    
                                    org      0
    cardmes                 waitpeq ina, cardPin                  ' wait for high
                            waitpne ina, cardPin                  ' wait for low
                            rdlong  cardct, par                    ' get count from hub
                            add     cardct, #1                     ' increment
                            wrlong  cardct, par                    ' put it back
                            jmp     #cardmes
    
    
    cardPin              long    1 << 1                          ' p4
    
    cardct                 res     1
    
    
                  org       0
    asm           mov       dira,asm_dira                   'make pins 8 (ADC) and 0 (DAC) outputs
    
                  movs      ctra,#5                         'POS W/FEEDBACK mode for CTRA
                  movd      ctra,#3
                  movi      ctra,#%01001_000
                  mov       frqa,#1
    
                  mov       asm_cnt,cnt                     'prepare for WAITCNT loop
                  add       asm_cnt,asm_cycles
    
    
    :spot         waitcnt   asm_cnt,asm_cycles              'wait for next CNT value (timing is determinant after WAITCNT)
    
                  mov       asm_sample,phsa                 'capture PHSA and get difference
                  sub       asm_sample,asm_old
                  add       asm_old,asm_sample
    
                  wrlong    asm_sample, par
    
                  jmp       #:spot                          'wait for next sample period
    
    asm_cycles    long      |< bits - 1                     'sample time
    asm_dira      long      |< 3                        'output mask
    
    asm_cnt       res       1
    asm_old       res       1
    asm_sample    res       1
    
                            org 0
    arrasm
    
    
    
  • Mike GreenMike Green Posts: 23,101
    edited 2011-03-03 14:34
    Your COGNEW(runtest,2000) is probably causing parts of your program to be overwritten. You need a separate stack space for this cog. What's happening is that the 2000 is being used as the address of a stack area for runtest and that's probably in the middle of your program or variables area. Even though runtest doesn't use much stack space, it uses some and that code or those variables are being overwritten. Do you really want to start up a separate cog for runtest or do you want to do something like:
    cognew(Go,@stack2)
      cognew(@entry,@arr[4])
      cognew(@detecter,@detect)
      runtest
    
  • Ding-BattyDing-Batty Posts: 302
    edited 2011-03-03 16:17
    I believe you have another problem in your code. In the CON section you have:
    threshold = 95/100   ' devider for difference between squential reads
    
    But that sets the threshold constant to zero, because Spin uses integer math. So later, when you say:
    if oldread > DataRead * threshold
           trigger:= 1
          arr[4]:= oldread
    
    the value of oldread will probably be greater than DataRead * 0 almost all the time.

    You might have to do something like this:
    CON
      threshold_numerator = 95
      threshold_denominator = 100
    
    ... and later...
    
        if oldread > (DataRead * threshold_numerator) / threshold_denominator
    
  • joethumphreyjoethumphrey Posts: 25
    edited 2011-03-08 13:51
    Yes that was it.
    datacheck:= (DataRead * numo) / denom
    

    Also
    cognew(runTest,@stack3)
    

    Took care of most of the random failures.

    I can get fairly steady output now but anything faster than 115200 baud and it starts getting sporadic data over serial to a terminal.

    Is there a way to get clean outputs at higher serial line rates?




    Also, is there a way to pass multiple variables to a cog in ASM?

    Like
    cognew(@detecter,@detect,[B]detect2[/B])
    
    .

    Or if I pass it a variable array , how do I interact with the variables in ASM.

    Like
    cognew(@detecter,@detect[2])
    
    DAT
    
    detecter                waitpeq ina, dectectPin
                            wrbyte  n1,par                          ' wait for high     [B]<-- here I'm calling par for the passed variable[/B]
                            waitpne ina, dectectPin                  ' wait for low
                            wrbyte  n2,par                    ' put it back
                            jmp     #detecter
    
    
    dectectPin              long    1 << 7                          ' p4
    n1                      long    1
    n2                      long    0
    
    


    What would I use in the ASM side to interact with the different variables in the array?
Sign In or Register to comment.