November 26, 2024, 09:48:47 AM

News:

You can now use Vixen to program your Prop-1 and Prop-2 controllers!  Get started quickly and easily, without having to learn PBASIC.  Details in the Library forum.


Serial communications for and AP-16 connection

Started by migman, December 20, 2010, 10:49:37 AM

Previous topic - Next topic

migman

I have an AP-16 that will be controlled by the SX.  I looked at the Servos6digital11 program and found a communications program using port "A" in that code but it appears to be much more than what I wound need to send the basic commants to the AP-16.  I was planning on using bit 7 of the "C" port I/O as a serI/O like on the Prop -1 connections but would like some example code for the SX that would do the output job at a minimum.  I don't think that I'll really need any of the input information from the status or version commands.  I think that the SET commands will provide everything I what to do with the AP-16

JonnyMac

The problem with a demo for the SX is that it's like to interfere with what you're already doing.  If you have other serial processes in play, or things like servos, it all gets very complicated as these processes need to be interleaved with serial control to the AP-16+. 

So... what do you want your program to do, other than send messages to the AP-16+? The answer will dictate how the code is constructed.
Jon McPhalen
EFX-TEK Hollywood Office

migman

Controlling 5 servos synched to the audio selected.  There are subroutines to read and move at the most three servo's at the same time in a loop.  There is a pre program delay selected by a pot read subroutine, a set of a solenoid to activate a pneumatic cylinder then servo commands interleived with the starting of the AP-16 audio, sychronized servo movements to the audio,  then setting the solenoid to off.  This is followed by a pot read for a post delay timer.

JonnyMac

Jon McPhalen
EFX-TEK Hollywood Office

migman

Out_In          PIN     RC
Sio            PIN     RC.7                    ' SETUP = UP; NO ULN
Trigger        PIN     RC.6                    ' SETUP = DN; NO ULN
PreDlayPot     PIN     RC.5                    ' SETUP = OUT; NO ULN
PostDlayPot    PIN     RC.4                    ' SETUP = OUT; NO ULN
GrnLED         PIN     RC.3 OUTPUT             ' Green LED for PreDlayPot
YelLED         PIN     RC.2 OUTPUT             ' Yellow LED for PostDlayPot
C_IO1          PIN     RC.1                    ' unused C_IO1
C_IO0          PIN     RC.0                    ' unused C_IO0

UpSol           PIN     RB.7 OUTPUT             ' solenoid UP coil
DownSol         PIN     RB.6 OUTPUT             ' solenoid DOWN coil

ServoCtrl       PIN     RB   OUTPUT             ' servo control pins
Servo5         PIN     RB.5                    ' unused P5/B_OUT5
Servo4         PIN     RB.4                    ' use P4
Servo3         PIN     RB.3                    ' use P3
Servo2         PIN     RB.2                    ' use P2
Servo1         PIN     RB.1                    ' use P1
Servo0         PIN     RB.0                    ' use P0

'TX              PIN     RA.3 OUTPUT             ' to PC
'RX              PIN     RA.2 INPUT              ' from PC
'SCL             PIN     RA.1 INPUT              ' EE clock line (I2C)
'SDA             PIN     RA.0 INPUT              ' EE data line (I2C)

JonnyMac

December 22, 2010, 11:20:08 AM #5 Last Edit: December 22, 2010, 11:22:29 AM by JonnyMac
Here's something to work with.  PLEASE remember that SX code is never easy when dealing with background processes and one cannot simply cut-and-paste code from program A to program B.  

For example, the last demo I wrote for you ran the interrupt at 10us but that's not fast enough for 38.4K baud comms so I had to change that to 3.33us.  This means working through all the code to adjust the timing.

So... proceed carefully, but this should get you a long way down the road.  Note that this is TX only code, do not use the "V" or "G" commands with the AP-16+.

' =========================================================================
'
'   File......
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Conditional Compilation Symbols
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

ID              "Migman_2"

DEVICE          SX28, OSCHS2, BOR42
FREQ            50_000_000


' -------------------------------------------------------------------------
' I/O Pins
' -------------------------------------------------------------------------

Out_In          PIN     RC
Sio            PIN     RC.7                    ' SETUP = UP; NO ULN
Trigger        PIN     RC.6                    ' SETUP = DN; NO ULN
PreDlayPot     PIN     RC.5                    ' SETUP = OUT; NO ULN
PostDlayPot    PIN     RC.4                    ' SETUP = OUT; NO ULN
GrnLED         PIN     RC.3 OUTPUT             ' Green LED for PreDlayPot
YelLED         PIN     RC.2 OUTPUT             ' Yellow LED for PostDlayPot
C_IO1          PIN     RC.1                    ' unused C_IO1
C_IO0          PIN     RC.0                    ' unused C_IO0


UpSol          PIN     RB.7 OUTPUT             ' solenoid UP coil
DownSol        PIN     RB.6 OUTPUT             ' solenoid DOWN coil

ServoCtrl       PIN     RB                      ' servo control pins
Servo5         PIN     RB.5 OUTPUT             ' use P5
Servo4         PIN     RB.4 OUTPUT             ' use P4
Servo3         PIN     RB.3 OUTPUT             ' use P3
Servo2         PIN     RB.2 OUTPUT             ' use P2
Servo1         PIN     RB.1 OUTPUT             ' use P1
Servo0         PIN     RB.0 OUTPUT             ' use P0

TX              PIN     RA.3 INPUT PULLUP       ' to PC
RX              PIN     RA.2 INPUT PULLUP       ' from PC
SCL             PIN     RA.1 INPUT              ' EE clock line (I2C)
SDA             PIN     RA.0 INPUT              ' EE data line (I2C)


' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

IsOn            CON     1
IsOff           CON     0

Yes             CON     1
No              CON     0


' Bit dividers for 3.33 uS interrupt

Baud2400        CON     125
Baud38K4        CON     8

Baud1x0         CON     Baud38K4                ' 1 bit period (ISR counts)
Baud1x5         CON     Baud1x0 * 3 / 2         ' 1.5 bit periods

TAB             CON     9
LF              CON     10
FF              CON     12                      ' like CLS for terminals
CR              CON     13


LO_LIMIT        CON     60                      ' to prevent servo burn-up
CENTER          CON     150
HI_LIMIT        CON     240


' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

flags           VAR     Byte                    ' (keep global)
isrFlag        VAR     flags.0
us10Flag       VAR     flags.1


tmpB1           VAR     Byte
tmpB2           VAR     Byte
tmpB3           VAR     Byte
tmpB4           VAR     Byte
tmpW1           VAR     Word
tmpW2           VAR     Word


' define arrays after simple variables

txSerial        VAR     Byte (16)               ' tx serial data
txBuf          VAR     txSerial(0)             ' eight-byte buffer
txCount        VAR     txSerial(8)             ' tx bit count
txDivide       VAR     txSerial(9)             ' bit divisor timer
txLo           VAR     txSerial(10)            ' holds start bit
txHi           VAR     txSerial(11)            ' tx output reg
txHead         VAR     txSerial(12)            ' buffer head (write to)
txTail         VAR     txSerial(13)            ' buffer tail (read from)
txBufCnt       VAR     txSerial(14)            ' # bytes in buffer

svoData         VAR     Byte (16)               ' bank servo data
pos            VAR     svoData(0)              ' position table
pos0           VAR     svoData(0)
pos1           VAR     svoData(1)
pos2           VAR     svoData(2)
pos3           VAR     svoData(3)
pos4           VAR     svoData(4)
pos5           VAR     svoData(5)
pos6           VAR     svoData(6)
pos7           VAR     svoData(7)
svoTix         VAR     svoData(8)              ' isr divider
svoFrame_LSB   VAR     svoData(9)              ' frame timer
svoFrame_MSB   VAR     svoData(10)
svoIdx         VAR     SvoData(11)             ' active servo pointer
svoTimer       VAR     svoData(12)             ' pulse timer
svoPin         VAR     svoData(13)             ' active servo pin


' =========================================================================
 INTERRUPT NOPRESERVE 300_000                  ' (4)   run every 3.33 uS
' =========================================================================

Mark_ISR:
 \ SETB  isrFlag                               ' (1)


' -------
' TX UART
' -------
'
' UART code by C. Gracey, A. Williams, et al
' -- buffer mods by Jon Williams
'
Transmit:
 ASM
   BANK  txSerial                              ' (1)
   TEST  txCount                               ' (1)   transmitting now?
   JZ    TX_Buffer                             ' (2/4) if txCount = 0, no
   DEC   txDivide                              ' (1)   update bit timer
   JNZ   TX_Done                               ' (2/4) time for new bit?
   MOV   txDivide, #Baud1x0                    ' (2)   yes, reload timer
   STC                                         ' (1)   set for stop bit
   RR    txHi                                  ' (1)   rotate TX char buf
   RR    txLo                                  ' (1)
   DEC   txCount                               ' (1)   update the bit count
   MOVB  TX, txLo.6                            ' (4)   output the bit
   JMP   TX_Done                               ' (3)

TX_Buffer:
   TEST  txBufCnt                              ' (1)   anything in buffer?
   JZ    TX_Done                               ' (2/4) exit if empty
   MOV   W, #txBuf                             ' (2)   point to buffer tail
   ADD   W, txTail                             ' (1)
   MOV   FSR, W                                ' (1)
   MOV   txHi, IND                             ' (2)   move byte to TX reg
   CLR   txLo                                  ' (1)   clear for start bit
   MOV   txCount, #10                          ' (2)   start + 8 + 1 stop
   INC   txTail                                ' (1)   update tail pointer
   CLRB  txTail.3                              ' (1)   keep 0..7
   DEC   txBufCnt                              ' (1)   update buffer count

TX_Done:
 ENDASM


' ----------------
' Servo Processing
' ----------------
'
Test_Servo_Tix:
 ASM
   BANK  svoData                               ' (1)
   INC   svoTix                                ' (1)   update divider
   CJNE  svoTix, #3, Servo_Done                ' (4/6) svoTix = 3?
   CLR   svoTix                                ' (1)   yes, reset for next

' Code below this point runs every 10 uS

   SETB  us10Flag                              ' (1)   set every 10us

Check_Frame_Timer:
   CJNE  svoFrame_LSB, #2000 & 255, Inc_FrTmr  ' (4/6) svoFrame = 2000 (20 ms)?
   CJNE  svoFrame_MSB, #2000 >>  8, Inc_FrTmr  ' (4/6)
   CLR   svoFrame_LSB                          ' (1)   yes, reset
   CLR   svoFrame_MSB                          ' (1)
   MOV   svoPin, #%0000_0001                   ' (2)   start servo sequence
   CLR   svoIdx                                ' (1)   point to servo 0
   MOV   FSR, #pos                             ' (2)
   MOV   svoTimer, IND                         ' (2)
   JMP   Refesh_Servo_Outs                     ' (3)

Inc_FrTmr:
   INC   svoFrame_LSB                          ' (1)   DEC svoFrame
   ADDB  svoFrame_MSB, Z                       ' (2)

Check_Servo_Timer:
   TEST  svoPin                                ' (1)   any servos on?
   SNZ                                         ' (1)
    JMP  Servo_Done                            ' (1)   no, exit
   DEC   svoTimer                              ' (1)   yes, update timer
   SZ                                          ' (1)   still running?
    JMP  Servo_Done                            ' (1)   yes, exit

Reload_Servo_Timer:
   INC   svoIdx                                ' (1)   point to next servo
   MOV   W, #pos                               ' (1)   get pulse timing
   ADD   W, svoIdx                             ' (1)
   MOV   FSR, W                                ' (1)
   MOV   W, IND                                ' (1)
   MOV   svoTimer, W                           ' (1)   move to timer

Select_Next_Servo:
   CLC                                         ' (1)
   RL    svoPin                                ' (1)
   AND   svoPin, #%0011_1111                   ' (2)   limit servo channels

Refesh_Servo_Outs:
   AND   ServoCtrl, #%1100_0000                ' (2)   clear last
   OR    ServoCtrl, svoPin                     ' (2)   update outputs

Servo_Done:
 ENDASM


ISR_Exit:
 RETURNINT                                     ' (4)


' =========================================================================
' Subroutine / Function / Task Declarations
' =========================================================================

DELAY_MS        SUB     2, 2, Word, Word        ' shell for PAUSE

RD_PREPOT       FUNC    1, 0                    ' read on time pot
RD_POSTPOT      FUNC    1, 0                    ' read off time pot

TX_BYTE         SUB     1                       ' transmit a byte
TX_STR          SUB     2, 2, Word              ' transmit a string


' =========================================================================
 PROGRAM Start
' =========================================================================

Start:
 PUT pos, CENTER, CENTER, CENTER, CENTER, CENTER, CENTER

Main:
 tmpB1 = 0

Check_Trigger:
 DELAY_MS 1
 INC tmpB1
 IF Trigger = IsOff THEN Main
 IF tmpB1 < 100 THEN Check_Trigger


Program_Code:

 ' SEROUT Sio, Baud, ("!AP16", %00, "PW", "WOLF", 13, 1)

 TX_STR  "!AP16"
 TX_BYTE %00
 TX_STR  "PW"
 TX_STR  "WOLF"
 TX_BYTE CR
 TX_BYTE 1

 DELAY_MS 5_000

 GOTO Main


' -------------------------------------------------------------------------
' Subroutine / Function / Task Code
' -------------------------------------------------------------------------

' Use: DELAY_MS milliseconds
' -- replaces PAUSE

SUB DELAY_MS
 '{$IFUSED DELAY_MS}
 ms            VAR     __WPARAM12
 msTix         VAR     __WPARAM34

 DO WHILE ms > 0
   msTix = 300                                 ' set for 1ms
   DO WHILE msTix > 0                          ' run 1ms timer
     \ CLRB  isrFlag                           ' clear flag
     \ JNB   isrFlag, @$                       ' wait for next
       DEC   msTix                             ' update msTix count
   LOOP
   DEC ms                                      ' update ms count
 LOOP
 '{$ENDIF}
 ENDSUB

' -------------------------------------------------------------------------

' Use: value = RD_PREPOT
' -- duplicates BS1 POT function
' -- remove ULN influence and SETUP jumpers from pin

FUNC RD_PREPOT
 '{$IFUSED RD_PREPOT}
 potTix        VAR     __PARAM1

 HIGH PreDlayPot                               ' charge RC circuit
 DELAY_MS 10
 potTix = 0                                    ' clear measurement
 DO
   LOW PreDlayPot                              ' discharge a little
   \ CLRB  us10Flag                            ' clear flag
   \ JNB   us10Flag, @$                        ' wait for next
   INPUT PreDlayPot                            ' release to check
   INC potTix
   IF potTix = 0 THEN EXIT                     ' abort if stuck
 LOOP UNTIL OnPot = 0                          ' wait until discharged

 RETURN potTix
 '{$ENDIF}
 ENDFUNC

' -------------------------------------------------------------------------

' Use: value = RD_POSTPOT
' -- duplicates BS1 POT function
' -- remove ULN influence and SETUP jumpers from pin

FUNC RD_POSTPOT
 '{$IFUSED RD_POSTPOT}
 potTix        VAR     __PARAM1

 HIGH PostDlayPot                              ' charge RC circuit
 DELAY_MS 10
 potTix = 0                                    ' clear measurement
 DO
   LOW PostDlayPot                             ' discharge a little
   \ CLRB  us10Flag                            ' clear flag
   \ JNB   us10Flag, @$                        ' wait for next
   INPUT PostDlayPot                           ' release to check
   INC potTix
   IF potTix = 0 THEN EXIT                     ' abort if stuck
 LOOP UNTIL PostDlayPot = 0                    ' wait until discharged

 RETURN potTix
 '{$ENDIF}
 ENDFUNC

' -------------------------------------------------------------------------

' Use: TX_STR [String | Label]
' -- pass embedded string or DATA label

SUB TX_STR
 '{$IFUSED TX_STR}
 strAddr       VAR     tmpW1
 sChar         VAR     __PARAM1

 strAddr = __WPARAM12                          ' get offset/base

 DO
   READINC strAddr, sChar                      ' read a character
   IF sChar = 0 THEN EXIT                      ' if 0, string complete
   TX_BYTE sChar                               ' send the byte
 LOOP
 '{$ENDIF}
 ENDSUB

' -------------------------------------------------------------------------

' Use: TX_BYTE aByte
' -- moves "aByte" to 8-byte circular buffer (when space is available)
' -- will wait if buffer is presently full
' -- txBufCnt holds byte count of transmit buffer (0 to 8)

SUB TX_BYTE
 '{$IFUSED TX_BYTE}
 ASM
   MOV   FSR, #txSerial                        ' point to tx vars
   JB    txBufCnt.3, $                         ' prevent buffer overrun
   MOV   W, #txBuf                             ' point to buffer head
   ADD   W, txHead
   MOV   FSR, W
   MOV   IND, __PARAM1                         ' move byte to tx buf
   INC   txHead                                ' update head pointer
   CLRB  txHead.3                              ' keep 0..7
   INC   txBufCnt                              ' update buffer count
   MOV   FSR, #__DEFAULT
 ENDASM
 '{$ENDIF}
 ENDSUB

' -------------------------------------------------------------------------


' =========================================================================
' User Data
' =========================================================================
Jon McPhalen
EFX-TEK Hollywood Office

migman

January 26, 2011, 04:30:11 PM #6 Last Edit: January 27, 2011, 02:06:17 PM by migman
Jon, The code that you provided looks like what I wanted but there are a couple of things that I wanted to clear up.  I made the change to the Delay_MS subroutine to make the msTix VAR a word and set it to 300 as would be needed for a 3.33 ms interrupt cycle. When I did this everyting stopped working.  I tried several things and found that if the value of the msTix is greater than 255 the routine never exits. It is like the DEC command doesn't work on a word value.  I tried several different combinations with word and byte values and found that it doesn't matter what I use for a word VAR anything over 255 cause the subroutine to hang.  Any comments?

Second thing was that I had hoped to use bit 7 of the "C" port as the serial communications connection rather than the "A" port which I am at a lose as to what the "A" port connection is?  One program that I looked at had the "A" port defined with a little more info as the DB9 connector but I still have been unable to find any definition as to which pins are which on the DB9 connector

JonnyMac

I'm confused.  This declaration promotes any value you use with DELAY_MS to a word:

DELAY_MS        SUB     2, 2, Word, Word        ' shell for PAUSE

And this code is setup for 300 cycles per millisecond which matches the interrupt rate.

' Use: DELAY_MS milliseconds
' -- replaces PAUSE

SUB DELAY_MS
  '{$IFUSED DELAY_MS}
  ms            VAR     __WPARAM12
  msTix         VAR     __WPARAM34

  DO WHILE ms > 0
    msTix = 300                                 ' set for 1ms
    DO WHILE msTix > 0                          ' run 1ms timer
      \ CLRB  isrFlag                           ' clear flag
      \ JNB   isrFlag, @$                       ' wait for next
        DEC   msTix                             ' update msTix count
    LOOP
    DEC ms                                      ' update ms count
  LOOP
  '{$ENDIF}
  ENDSUB


The DEC used for decrementing msTix is the SX/B version which will work with works so there should be no issue (the \ in front of an instruction is used for inline Assembly).

The transmit routine in the interrupt uses the pin defined as TX; if you change this is the pin definitions to RC.7 then it will transmit from P15 on the board.  This code only has transmit capability, so do not use commands that expect a response.

Jon McPhalen
EFX-TEK Hollywood Office

migman

Yep, I missed that subtle change to the DelayMS routine.  I changed msTix from param3 to wparam34 and the preset value from 100 to 300 but missed the "\" removal from the DEC line.  You the man!

migman

Well I'm stumped.  I have connected a O scope up to the TX output pin and I get nothing when I try and call a !AP16 function.  I decided to see if I could get any thing by just writing directly to the TX pin.  I commented out the Transmit interrupt code and programed a do loop that writes a 1 to TX (\ MOVB TX, 1) then waits 1 ms (DELAY_MS 1) then writes  a 0 to TX then waits another 1 ms.  The loop continues until I reset the board.  Still nothing on the TX pin.  I even changed the define of TX to a spare pin on the "C" port (0).  I checked the pins that are being pulsed for the servos and I can see those pulses.  Any Ideas?

JonnyMac

You're using TX only code so you need to make the pin that's transmitting an output.
Jon McPhalen
EFX-TEK Hollywood Office

migman

January 29, 2011, 10:29:16 AM #11 Last Edit: January 29, 2011, 10:53:18 AM by migman
Since I'm using pin 7 of the "C" port for TX,  should it be pulled up or pulled down or left to float.  Currently it is junpered to pullup.  I was able to get the commands to the AP16 to start the different sound tracks but I noticed that the very first time the routine runs after powerup that the first command to the AP16 fails.  Should there be some initial setup with the txserial ?

JonnyMac

With that code you can pull it up or let it float.  The output is driven (so DO NOT request the version or status from the AP-16+).  If you want to talk back and forth you need a half-duplex, open-drain driver.  I have one (used in the FC-4).
Jon McPhalen
EFX-TEK Hollywood Office

migman

January 29, 2011, 11:12:08 AM #13 Last Edit: January 29, 2011, 11:16:40 AM by migman
I'm not sure if I should ask this here or in the AP-16 forum but I have a question about how to send the "R" of the relay command.  Should that be a TX_BYTE "R" or a TX_STR "R" command for the SX.  I've downloaded the new version 1.7 but the relay command as described in the AP-16 PDF file doesn't seem to activate the relay.  I have the command set up as TX_STR "R".
TX_STR "!AP16"
TX_BYTE %00
TX_STR "R"
TX_BYTE 1  ' to turn it on  TX_BYTE 0  'to turn it off

Does there need to be any kind od an IDLE delay between commands to the AP-16?

JonnyMac

For single characters you would use TX_BYTE.  Change the TX_STR "R" to TX_BYTE "R"

The AP-16+ has a 64-byte buffer that is checked every 50ms, so long as you don't overrun that you'll be okay without delays.
Jon McPhalen
EFX-TEK Hollywood Office