Quadcopters | PWM interface to a PIC 12F629 Microcontroller
S.BUS Protocol
In this webpage we explain how we connected an X4R to an Arduino and a processing.org sketch as part of PoC to intereface our 360 degree IR proximity sensor to an UAV, Drone, Quadcopter.
S.BUS and PWM configuration on Flgiht controllers
You can configure the CC3D, Naze32 and other flight controller to read the 16 channel S.BUS protocol from the FrSKy XR4 and a the same time also leaving 2 PWM channels (CH9&CH10) available for direct servo connection (you just need to bridge the channel 2&3 - signal pins before binding with the Taranis radio).
Using the CC3D flight controller in our project we didn't have a Buzzer output on the controller so we was thinking how we could get the buzzer to be controlled from the CH9 and 10 on the X4R, but also leaving some other control available. We played around with a PIC12F629 to see if we could get some additional programmable logic by reading both the PWM channels 9&10 with some logic .
We could have done this directly with the Arduino reading the S.BUS, but for fun we wanted to see what we could do with a very small microcontroller.
Example of how we programmed the PIC 12F629
We saw that by combining the logic of both channel 9 & 19 we could still run 1 serovs proportionally ; as though it was directly connected to the XR4 - but we also got additional "virtual channels" by reading the channel 9 switch position. We mapped this to a 3-way switch. but if channel 10 were mapped to the slider on the Taranis, then this could be proportional to the position of the slider. Using the offset on the Taranis and mapping another slider and switch to Ch9 we were actually able to get 2 servos working with reduced travel.
I'm using the PROTON IDE and BASIC compiler from Crownhill Associates Ltd.
This PIC is very small and the SMD version is even much smaller. The main driver for using this chip is that it doesn't require any further components to drive it, so it could fit within the shrink sleeve of the cable connected to the X4R. If we ever make one we'll publish it here.
PIC Code in BASIC
;****************************************************************************
; Test of use of LED as Light Sensor within a Complementary LED display
;****************************************************************************
Device = 12F629
Optimiser_Level = 3 ' Set for maximum optimiser level
Xtal = 4
Config CP_OFF ,CPD_OFF ,BODEN_OFF ,MCLRE_OFF ,WDT_OFF ,PWRTE_ON ,INTRC_OSC_NOCLKOUT
Declare Serial_Baud = 9600
Declare Rsout_Pin = GPIO.0
Declare Rsin_Pin = GPIO.1
Declare Rsout_Mode = TRUE
Declare Rsout_Pace = 10000
;****************************************************************************
;Comments
;****************************************************************************
'Bit column ;543210 ; TRIS configuration
;LED0TRIS= %001111
;LED1TRIS= %001111
;LED2TRIS= %101011
;LED3TRIS= %101011
;LED4TRIS= %011011
;LED5TRIS= %011011
;LED6TRIS= %111001
;LED7TRIS= %111001
;LED8TRIS= %011101
;LED9TRIS= %011101
'LED10TRIS= %101101
'LED11TRIS= %101101
'Bit column ;543210
'LED0ON= %010000 ; Port GPIO configuration
'LED1ON= %100000
'LED2ON= %010000
'LED3ON= %000100
'LED4ON= %100000
'LED5ON= %000100
'LED6ON= %000100
'LED7ON= %000010
'LED8ON= %100000
'LED9ON= %000010
'LED10ON= %010000
'LED11ON= %000010
'-------[MAIN PROGRAM LOOP STARTS HERE]----------------------------------
Dim INDEX As Byte
Dim PULSE_LENGTH As Word ' TOF (Time Of Flight) value
Dim SWAP_OCCURED As Bit
Dim SWAPTMP As Word
Dim MEDIAN As Word
Dim CALIBRATION_TIMER As Byte
Dim CALIBRATION_CHECK As Byte
Dim ServoPos1 As Byte
OPTION_REG.7 =0 ;enable pull-up setting
CMCON = 7 ' PORTA to digital
TRISIO = %111101
ServoPos1 = 0
INDEX = 250
;****************************************************************************
'[MAIN PROGRAM LOOP STARTS HERE]
;****************************************************************************
While 1 = 1 ' Create an infinite loop
x xx
ServoPos1 = PulseIn GPIO.1,0
RSOut " SERVO PWM = " , Dec ServoPos1,13 ;Print results of input to the serial monitor
;GoSub SCAN_COLUMNS
If ServoPos1 > 110 And ServoPos1 < 135 Then ;Mid Swtich Position
GoSub Led4
GPIO.5 = 0 ; turn off Buzzer
DelayMS 500
GPIO.5 = 1 ; turn on Buzzer
DelayMS 1000
GPIO.5 = 0 ; turn off Buzzer
DelayMS 500
EndIf
If ServoPos1 >135 Then ;Top Switch Position
GoSub Led4
TRISIO =%000001
GPIO.5 = 0 ; turn off Buzzer
Else
GoSub Led2
DelayMS 100
GPIO.5 = 1 ; turn on Buzzer
EndIf
ServoPos1 = 0
Wend
;****************************************************************************
ROW1_SHOW:
;****************************************************************************
For INDEX=10 To 5 Step -1
GoSub Led3
DelayMS INDEX ' Delay between samples
GoSub Led7
DelayMS INDEX
GoSub Led11
DelayMS INDEX
GoSub Led10
DelayMS INDEX
GoSub Led6
DelayMS INDEX
GoSub Led2
DelayMS INDEX
GoSub Led11
Next INDEX
Return
;****************************************************************************
;LED0 - D0
;****************************************************************************
Led0:
TRISIO =%001111
GPIO = %010000
Return
;****************************************************************************
;LED1 - D1
;****************************************************************************
Led1:
TRISIO =%001111
GPIO = %100000
Return
;****************************************************************************
;LED2 - D2
;****************************************************************************
Led2:
TRISIO = %101011
GPIO = %010000
Return
;****************************************************************************
;LED3 - D3
;****************************************************************************
Led3:
TRISIO = %101011
GPIO = %000100
Return
;****************************************************************************
;LED4 - D4
;****************************************************************************
Led4:
TRISIO = %011011
GPIO = %100000
Return
;****************************************************************************
;LED5 - D5
;****************************************************************************
Led5:
TRISIO = %011011
GPIO = %000100
Return
;****************************************************************************
;LED6 - D6
;****************************************************************************
Led6:
TRISIO = %111001
GPIO = %000100
Return
;****************************************************************************
;LED7 - D7
;****************************************************************************
Led7:
TRISIO = %111001
GPIO = %000010
Return
;****************************************************************************
;LED8 - D8
;****************************************************************************
Led8:
TRISIO = %011101
GPIO = %100000
Return
;****************************************************************************
;LED9 - D9
;****************************************************************************
Led9:
TRISIO = %011101
GPIO = %000010
Return
;****************************************************************************
;LED10 - D10
;****************************************************************************
Led10:
TRISIO = %101101
GPIO = %010000
Return
;****************************************************************************
;LED11 - D11
;****************************************************************************
Led11:
TRISIO = %101101
GPIO = %000010
Return
;****************************************************************************
;sub routine to scan LEDs
;****************************************************************************
;****************************************************************************
SCAN_COLUMNS:
;****************************************************************************
For INDEX=10 To 5 Step -1
GoSub Led0
DelayMS INDEX
GoSub Led1
DelayMS INDEX
GoSub Led2
DelayMS INDEX
GoSub Led3
DelayMS INDEX
GoSub Led4
DelayMS INDEX
GoSub Led5
DelayMS INDEX
GoSub Led6
DelayMS INDEX
GoSub Led7
DelayMS INDEX
GoSub Led8
DelayMS INDEX ' Delay between samples
GoSub Led9
DelayMS INDEX
GoSub Led10
DelayMS INDEX
GoSub Led11
DelayMS INDEX
Next INDEX
Return
;****************************************************************************
SCAN_ROWS:
;****************************************************************************
For INDEX=10 To 5 Step -1
GoSub Led0
DelayMS INDEX
GoSub Led4
DelayMS INDEX
GoSub Led8
DelayMS INDEX
GoSub Led1
DelayMS INDEX
GoSub Led5
DelayMS INDEX
GoSub Led9
DelayMS INDEX
GoSub Led2
DelayMS INDEX
GoSub Led6
DelayMS INDEX
GoSub Led10
DelayMS INDEX ' Delay between samples
GoSub Led3
DelayMS INDEX
GoSub Led7
DelayMS INDEX
GoSub Led11
DelayMS INDEX
Next INDEX
Return
http://www.protonbasic.co.uk/content.php/935-Proton-IDE#proginteg