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