DIY Remote Control XBee controller for Robotics

Calibrate, you do need to hit enter, if it is saying error, than one of the Analog inputs has not been moved through enough for it to be happy. Usually I forget to do the Sliders.

A quick look at the code, it expects that thanalogog inputs on pins:
AtoDOrder bytetable 3, 2, 1, 0, 19, 18

have been moved through the range. It sort of assumes the first 4 are the joysticks of our DIY controls and don’t have a full range 0-1024, so it assumes the minimum for these must be < 450 and the maxs must be > 575. It assumes the sliders have a larger range and the min must be < 50 and the max > 975. These should be table driven, but…

If the Right … is not working, how about the amain page, do all of the values appear to change properly?

Got to run
Kurt

Hi Kurt,

I’ve got the communication running with help of your XBEE THex version you’ve posted. I left something in for the PS2 remote which caused all the problems. :blush:

Now, when I turn on the THex it will start walking automatically. So I started to dig deeper in to your DIY remote XBEE code. While fiddling around with the code, I got the strangest compiler error of all…

When I enable the DEBUG = 1 variable in the “diy transmitter.bas” file. (remove the ') The compiler gives an error

Build

Preparing files... D:\DIY\XBEE_TASERIAL_DEFINES.BAS D:\DIY\DIY TRANSMITTER.BAS D:\DIY\XBEE_TASERIAL_SUPPORT.BAS Compiling... Linking... C:\Program Files\BasicMicro\Basic Micro Studio\bin\ld.exe : region text is full (d:\diy\diy transmitter.bas section .text Errors DetectedWhen I double click on the error line, the Workspace opens an extra file “ld.exe” with the text “MZ” in it. When disable the DEBUG variable again, the program builds like a charm.

Did you see this behavior before?

Thanks, Xan

Hi,

I’m not sure but I think I’ve seen something similar. You are not running out of memory space on the BAP28? Just a guess…

EDIT: lynxmotion.net/viewtopic.php?f=4&t=5463&p=62063&hilit=region+text+is+full#p62063

Ah I see, This explains a lot.

Thanks! :slight_smile:

Just sucessfully calibrated the remote. Nice Piece of programming work Kurt!
The THex still is walking on it’s own. I’ll hook up my logic analyzer Thursday to see what’s going over the “line”. Now it’s time to go to bed (23:20 alread :frowning: )

The rule is already in position to allow you to change which software you are going to management. Zenta revealed it in function in has newest Podcast

modified to match KeyPad . 5 x 4 matrix Keypad Rowb added .See the next post

original source code from here: winpicprog.co.uk/pic_tutorial9.htm modified here

I use RA,1 for RowB (output configuration)

;Tutorial 9.2 - Nigel Goodwin 2003
;Keypad reading with RS232 output

LIST p=16F628 ;tell assembler what chip we are using
include "P16F628.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__config 0x3D18 ;sets the configuration settings (oscillator type etc.)
;internal io clock


cblock 0x20 ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
tmp1 ;temporary storage
tmp2

key
rows
index
Xmit_Byte ;holds byte to xmit
Rcv_Byte ;holds received byte 
Bit_Cntr ;bit counter for RS232
Delay_Count ;delay loop counter 
endc

SER_PORT Equ PORTA
SER_TRIS Equ TRISA
SER_OUT Equ 0x06
ROWB Equ 0x00
KEY_PORT Equ PORTB ;keypad port
KEY_TRIS Equ TRISB
Col1 Equ 0 ;pins used for keypad inputs
Col2 Equ 1
Col3 Equ 2
Col4 Equ 3

org 0x0000
goto Start

Key_Table   ADDWF   PCL   , f

;RETLW   0x57   ;rowb
;RETLW   0x58  ;rowb
;RETLW   0x59  ;rowb
;RETLW   0x5A  ;rowb
RETLW   0x44 ;0x43
RETLW   0x45 ;0x42 
RETLW   0x46 ;0x30
RETLW   0x30 ;0x41
RETLW   0x43 ;0x44
RETLW   0x39
RETLW   0x38
RETLW   0x37
RETLW   0x42 ;0x45
RETLW   0x36
RETLW   0x35
RETLW   0x34
RETLW   0x41 ;0x46
RETLW   0x33
RETLW   0x32
RETLW   0x31


Start movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)

Initialise clrf count
clrf PORTA
clrf PORTB

SetPorts bsf  STATUS, RP0 ;select bank 1
movlw B'00000001';0x00 ;make all pins outputs, ROWB input
movwf SER_TRIS
movlw 0x0F ;set keypad pins
movwf KEY_TRIS ;half in, half out
bcf  STATUS, RP0 ;select bank 0

call SER_INIT ;setup serial port
call Delay255 ;a;;ow time to settle


clrf count ;set counter register to zero

Main movlw 0x0F
movwf KEY_PORT ;set all output pins low

Loop call Chk_Keys ;check keys
movf key, w ;restore key pressed
call XMIT_RS232 ;display as ASCII
movlw 0x0D ;CR
call XMIT_RS232
goto Loop

;Keypad subroutine

Chk_Keys movlw 0x00 ;wait until no key pressed
movwf KEY_PORT ;set all output pins low
movf KEY_PORT, W
andlw 0x0F ;mask off high byte
sublw 0x0F
btfsc STATUS, Z ;test if any key pressed
goto Keys ;if none, read keys
call Delay20
goto Chk_Keys ;else try again

Keys    call    Scan_Keys
movlw   0x10 ;check for no key pressed
subwf   key, w
btfss   STATUS, Z
goto    Key_Found
call Delay20
goto Keys
Key_Found   movf    key, w
andlw 0x0f ; maybe change 0x0f to 0x13--> 19 dec
call Key_Table ;lookup key in table 
movwf key ;save back in key
return ;key pressed now in W

Scan_Keys   clrf    key
movlw 0xF0 ;set all output lines high
movwf   KEY_PORT
movlw   0x04
movwf   rows ;set number of rows
bcf STATUS, C ;put a 0 into carry
Scan    rrf KEY_PORT, f
bsf STATUS, C ;follow the zero with ones
btfss   KEY_PORT, Col4
goto    Press
incf    key, f
btfss   KEY_PORT, Col3
goto    Press
incf    key, f
btfss   KEY_PORT, Col2
goto    Press
incf    key, f
btfss   KEY_PORT, Col1
goto    Press
incf    key, f
decfsz  rows, f
goto    Scan
Press    return

;end of keypad subroutines.


;Serial routines

SER_INIT
BSF STATUS, RP0  ;select bank 1
BCF SER_TRIS, SER_OUT ;set A6 as an output
;BSF SER_TRIS, ROWB  ;set A0 as an input
BCF STATUS, RP0  ;select bank 0
BSF SER_PORT, SER_OUT ;set SER_OUT high
RETURN

XMIT_RS232   MOVWF   Xmit_Byte    ;move W to Xmit_Byte
MOVLW   0x08    ;set 8 bits out
MOVWF   Bit_Cntr
BCF SER_PORT, SER_OUT
CALL    Bit_Delay
Ser_Loop RRF Xmit_Byte , f ;send one bit
BTFSS   STATUS    , C
BCF SER_PORT, SER_OUT
BTFSC   STATUS    , C
BSF SER_PORT, SER_OUT
CALL    Bit_Delay
DECFSZ  Bit_Cntr  , f ;test if all done
GOTO    Ser_Loop
BSF SER_PORT, SER_OUT
CALL    Bit_Delay
RETURN

Start_Delay  MOVLW   0x0C
MOVWF   Delay_Count
Start_Wait   NOP
DECFSZ  Delay_Count , f
GOTO    Start_Wait
RETURN

Bit_Delay    MOVLW   0x18
MOVWF   Delay_Count
Bit_Wait NOP
DECFSZ  Delay_Count , f
GOTO    Bit_Wait
RETURN


;End of serial routines


Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xC7 ;delay 1mS
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0

decfsz count1 ,f
goto d1
retlw 0x00


end



Sorry, but I have never done PIC assembly programming, so I am anot sure how much help I can be. These days mostly working with Linux boxes or Teensy boards…

Kurt

What, something Kurt doesn’t know about ?
That might be a first time here… :wink:

Probably a better idea to use another board than PIC anyway…

74HC4067 Multiplexer

I use servo’s potmeter

maybe re-code in a better way :wink:

'(MUX 74HC4067E) BASICATOM PRO(BASIC -MICRO CODE STUDIO)*
s0   con P10
s1   con P11
s2   con P12
s3   con P13
sig_PIN    con P16

controlPin bytetable  s0, s1, s2, s3 
muxs0Channel bytetable 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1 's0
muxs1Channel bytetable 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1 's1
muxs2Channel bytetable 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1 's2
muxs3Channel bytetable 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1 's3

Pot var sword(15) 
i var byte    ;index

output s0
low s0 
output s1 
low s1 
output s2 
low s2 
output s3
low s3 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main:
  for i = 0 to 2
  gosub readMux*
  Pot(i) =(500+(Pot(i)*2))
  serout s_out,i9600,"Channel ",DEC i," is : ",SDEC Pot(i),13]
  ;serout s_out,i9600,"Addr:",DEC muxs0Channel(i),DEC muxs1Channel(i), DEC muxs2Channel(i),DEC muxs3Channel(i),13]
pauseus(1000);'maybe more
   next

pause 1000

goto main

channel var    byte    
readMux[channel]:
   ;   digitalWrite(controlPin*, muxChannel[channel]*);
  if muxs0Channel(channel)=0 then
    Low controlPin(0)
    else
    high controlPin(0)
endif
if muxs1Channel(channel)=0 then
    Low controlPin(1)
    else
    high controlPin(1)
endif
if muxs2Channel(channel)=0 then
    Low controlPin(2)
    else
    high controlPin(2)
endif
if muxs3Channel(channel)=0 then
    Low controlPin(3)
    else
    high controlPin(3)
endif
  adin SIG_pin,Pot(channel)
return




ROWB added successfully ! don’t unerstand all in asm but it works.

keypad_rs232.zip (29.6 KB)

no Carry Return or other line in code , just ASCII char to match with remote control

;  5x4  Keypad reading with RS232 output

LIST    p=16F628    ;tell assembler what chip we are using
include "P16F628.inc"    ;include the defaults for the chip
ERRORLEVEL    0,    -302    ;suppress bank selection messages
__config 0x3D18   ;sets the configuration settings (oscillator type etc.)



cblock    0x20   ;start of general purpose registers
count   ;used in looping routines
count1   ;used in delay routine
counta   ;used in delay routine
countb   ;used in delay routine
tmp1   ;temporary storage
tmp2

key
rows
index
Xmit_Byte   ;holds byte to xmit
Rcv_Byte   ;holds received byte 
Bit_Cntr   ;bit counter for RS232
Delay_Count   ;delay loop counter    
endc

SER_PORT    Equ    PORTA
SER_TRIS    Equ    TRISA
SER_OUT    Equ    0x06
KEY_PORT    Equ    PORTB   ;keypad port
KEY_TRIS    Equ    TRISB
Col1    Equ    0   ;pins used for keypad inputs
Col2    Equ    1
Col3    Equ    2
Col4    Equ    3

org    0x0000
goto    Start

Key_Table  ADDWF   PCL   , f

RETLW   0x44    ;row4    (D)    
RETLW   0x45    
RETLW   0x46    
RETLW   0x30    
RETLW   0x43    ;row3    (C)
RETLW   0x39
RETLW   0x38
RETLW   0x37
RETLW   0x42    ;row2    (B)
RETLW   0x36
RETLW   0x35
RETLW   0x34
RETLW   0x41    ;row1    (A)
RETLW   0x33
RETLW   0x32
RETLW   0x31
RETLW   0x57    ;ROWB    (Z)
RETLW   0x58
RETLW   0x59
RETLW   0x5A


Start   movlw    0x07
movwf    CMCON   ;turn comparators off (make it like a 16F84)

Initialise    clrf    count
clrf    PORTA
clrf    PORTB

SetPorts    bsf STATUS,    RP0    ;select bank 1
movlw    B'00000000';0x00   ;make all pins outputs
movwf    SER_TRIS
movlw    0x0F   ;set keypad pins
movwf    KEY_TRIS    ;half in, half out
bcf STATUS,    RP0    ;select bank 0

call    SER_INIT    ;setup serial port
call    Delay255    ;a;;ow time to settle


clrf    count   ;set counter register to zero

Main   movlw    0x0F
movwf    KEY_PORT    ;set all output pins low

Loop   call    Chk_Keys    ;check keys
movf    key, w   ;restore key pressed
call    XMIT_RS232    ;display as ASCII
;movlw    0x0D   ;CR
;call    XMIT_RS232
goto    Loop

;Keypad subroutine


Chk_Keys    

movlw    0x00   ;wait until no key pressed
movwf    KEY_PORT    ;set all output pins low
movf    KEY_PORT,    W
andlw    0x0F   ;mask off high byte
sublw    0x0F
btfsc    STATUS, Z    ;test if any key pressed
goto    Keys   ;if none, read keys
call    Delay20
goto    Chk_Keys    ;else try again

Keys call    Scan_Keys
movlw   0x14;0x10;    ;check for no key pressed
subwf   key, w
btfss   STATUS, Z
goto    Key_Found
call    Delay20
goto    Keys

Key_Found    movf    key, w
andlw    B'00011111';0x0f;
call    Key_Table    ;lookup key in table    
movwf    key   ;save back in key
return  ;key pressed now in W

Scan_Keys clrf    key
BSF SER_PORT,2
movlw    0xF0   ;set all output lines high 
movwf   KEY_PORT
bcf STATUS, C    ;put a 0 into carry
Scan rrf KEY_PORT, f
bsf STATUS, C    
btfss   KEY_PORT, Col4
goto    Press
incf    key, f
btfss   KEY_PORT, Col3
goto    Press
incf    key, f
btfss   KEY_PORT, Col2
goto    Press
incf    key, f
btfss   KEY_PORT, Col1
goto    Press
incf    key, f

rrf KEY_PORT, f
bsf STATUS, C    
btfss   KEY_PORT, Col4
goto    Press
incf    key, f
btfss   KEY_PORT, Col3
goto    Press
incf    key, f
btfss   KEY_PORT, Col2
goto    Press
incf    key, f
btfss   KEY_PORT, Col1
goto    Press
incf    key, f

rrf KEY_PORT, f
bsf STATUS, C    
btfss   KEY_PORT, Col4
goto    Press
incf    key, f
btfss   KEY_PORT, Col3
goto    Press
incf    key, f
btfss   KEY_PORT, Col2
goto    Press
incf    key, f
btfss   KEY_PORT, Col1
goto    Press
incf    key, f

rrf KEY_PORT, f
bsf STATUS, C    
btfss   KEY_PORT, Col4
goto    Press
incf    key, f
btfss   KEY_PORT, Col3
goto    Press
incf    key, f
btfss   KEY_PORT, Col2
goto    Press
incf    key, f
btfss   KEY_PORT, Col1
goto    Press
incf    key, f


BCF  SER_PORT,2
rrf KEY_PORT, f
bsf STATUS, C    
btfss   KEY_PORT, Col4
goto    Press
incf    key, f
btfss   KEY_PORT, Col3
goto    Press
incf    key, f
btfss   KEY_PORT, Col2
goto    Press
incf    key, f
btfss   KEY_PORT, Col1
goto    Press
incf    key, f


Press return

;end of keypad subroutines.


;Serial routines

SER_INIT
BSF STATUS, RP0  ;select bank 1
BCF SER_TRIS, SER_OUT ;set A6 as an output
;BSF SER_TRIS, SER_IN  ;set A7 as an input
BCF STATUS, RP0  ;select bank 0
BSF SER_PORT, SER_OUT ;set SER_OUT high
RETURN

XMIT_RS232  MOVWF   Xmit_Byte    ;move W to Xmit_Byte
MOVLW   0x08    ;set 8 bits out
MOVWF   Bit_Cntr
BCF SER_PORT, SER_OUT
CALL    Bit_Delay
Ser_Loop    RRF Xmit_Byte , f ;send one bit
BTFSS   STATUS    , C
BCF SER_PORT, SER_OUT
BTFSC   STATUS    , C
BSF SER_PORT, SER_OUT
CALL    Bit_Delay
DECFSZ  Bit_Cntr  , f ;test if all done
GOTO    Ser_Loop
BSF SER_PORT, SER_OUT
CALL    Bit_Delay
RETURN

Start_Delay MOVLW   0x0C
MOVWF   Delay_Count
Start_Wait  NOP
DECFSZ  Delay_Count , f
GOTO    Start_Wait
RETURN

Bit_Delay   MOVLW   0x18
MOVWF   Delay_Count
Bit_Wait    NOP
DECFSZ  Delay_Count , f
GOTO    Bit_Wait
RETURN


;End of serial routines


Delay255    movlw    0xff   ;delay 255 mS
goto    d0
Delay100    movlw    d'100'   ;delay 100mS
goto    d0
Delay50    movlw    d'50'   ;delay 50mS
goto    d0
Delay20    movlw    d'20'   ;delay 20mS
goto    d0
Delay5    movlw    0x05   ;delay 5.000 ms (4 MHz clock)
d0    movwf    count1
d1    movlw    0xC7   ;delay 1mS
movwf    counta
movlw    0x01
movwf    countb
Delay_0
decfsz    counta, f
goto    $+2
decfsz    countb, f
goto    Delay_0

decfsz    count1    ,f
goto    d1
retlw    0x00


end

works!

Taserin doesn’t work so


;==============================================================================
; [CheckKeypad] function modified for serial Keypad 
;
; Input Parameters:
;  FCheckModeChange: Should we do checks for mode change? Currently always true.
; 
; Variables updated: 
; keypress - the ascii value associated with that key.
;   rcv
;==============================================================================

fCheckModeChange var byte ; should we check for a mode change ?
CheckKeypad[fCheckModeChange]:



bPacket(0) = 0 ; assume no buttons pressed
bPacket(1) = 0
  keypress = " "
  CmdBtnsPrev = CmdBtns
  CmdBtns = 0 
if fCheckModeChange then
fTModeChanged = FALSE
endif


serin cPAD_IN, cPAD_BAUD,5500,timeout, [keypress]

timeout:



;Read buttons - New version reads multiple keys as well are down.
if keypress = "1" then 
bPacket(0).bit1 = 1
elseif  keypress = "2"  
bPacket(0).bit2 = 1 
elseif  keypress = "3"  
   bPacket(0).bit3 = 1
elseif keypress = "A" 
   bPacket(1).bit2 = 1 
elseif  keypress = "4"  
   bPacket(0).bit4 = 1 
elseif   keypress = "5"   
   bPacket(0).bit5 = 1 
elseif  keypress = "6" 
bPacket(0).bit6 = 1 
elseif  keypress = "B" 
bPacket(1).bit3 = 1 
elseif  keypress = "7"   
   bPacket(0).bit7 = 1 
elseif   keypress = "8" 
   bPacket(1).bit0 = 1 
elseif  keypress = "9"  
   bPacket(1).bit1 = 1 
elseif  keypress = "C"  
   bPacket(1).bit4 = 1 
elseif  keypress = "0"  
   bPacket(0).bit0 = 1 
elseif  keypress = "F"  
   bPacket(1).bit7 = 1 
elseif  keypress = "E" 
   bPacket(1).bit6 = 1 
elseif   keypress = "D" 
   bPacket(1).bit5 = 1 
elseif  keypress = "W"   
   CmdBtns.bit0 = 1 
elseif   keypress = "X" 
   CmdBtns.bit1 = 1 
elseif   keypress = "Y" 
   CmdBtns.bit2 = 1 
elseif   keypress = "Z" 
 CmdBtns.bit3 = 1
else
keypress=" "
endif 

; Check to see if the state of the command buttons has changed.
if fCheckModeChange and (CmdBtns <> CmdBtnsPrev) then ;
if (CmdBtns & CMD_UP_MASK) and ((CmdBtnsPrev & CMD_UP_MASK) = 0) then
; CmD Up button has been pressed
if TransMode = TMODE_MAX then
TransMode = 0
else
TransMode = TransMode + 1
endif
fTModeChanged = TRUE
elseif (CmdBtns & CMD_DOWN_MASK) and ((CmdBtnsPrev & CMD_DOWN_MASK) = 0)
; CmD Down button has been pressed
if TransMode = 0 then
TransMode = TMODE_MAX
else
TransMode = TransMode - 1
endif
fTModeChanged = TRUE
endif

if fTModeChanged then
gosub ClearLCDDisplay
bTDataLast = 0xff ; make sure we will display something when it changes.
endif
endif

return

Hi There,

I realise no one has posted on here in quite some time and may have moved onto other things but I’m looking to build one of these remotes myself for my own projects but really I am a beginner when it comes to coding as i am mostly someone who is good at building but not electronics or code .

I aim to have a remote with Xbee communication, two 4-axis joysticks (3 axis and a button), 2 slide pots, 16 keypad, LCD, and some buttons for menu navigation if needed all running on an Arduino Mega.

I have looked over the various bits of code that have been put on the forums and can understand some aspects, but was just curious if there is an up to date version of someone’s code I could study to learn why things are done so I can generate my own code?

Cheers,
Dynomyx