PiC16F690 Code Livolo Glas Sensor Schalter

Bitte nutzt dieses Forum um eure eigenen Projekte vorzustellen oder um selbst entwickelten Code zur Verfügung zu stellen.

PiC16F690 Code Livolo Glas Sensor Schalter

#1

Beitrag DG0JG » 3. Jan 2019, 02:17

Hallo,

Ich habe hier die Livolo Glastaster Dual also mit zwei Sensor Tasten die mit einem PIC16F690
ausgerüstet sind.
Es gibt in Github ein bzw. zwei Projekte wo die Firmware neu geschrieben
wurde da die Orginale nicht auslesbar ist wegen Security Bit im PIC.
Leider funktioniert der Code nicht so richtig da nur einer Sensortaste funktioniert

So jetzt zu meiner Frage da ich noch nichts mit dem PIC und PICBasic Pro
bzw. MPLab X gemacht habe, habe ich keinerlei Überblick wie ich diese
Firmware anpassen kann damit Sie richtig so funktioniert mit der Version
meiner Livolo Schalter VL-C701x-2

Im Moment geht von dem Glas Sensoren nur eine Sensortaste und die zweite
funktioniert nicht.
Was ist der Hintergrund der Anpassung
Ich möchte die Firmware so anpassen das die Tasten keine Schalter
sondern später Taster werden um Sie in einer KNX Installation
einzusetzen.
Es wäre gut wenn mir jemand beim Code etwas helfen könnte bzw. wenn sich
jemand mit PicBasic Pro oder MPLab X IDE und die programmierung der
PIC16 auskennt und mir einen Tip geben könnte woran es liegen mag.

Hier der Link zu den zwei Projekten
Mit Picbasic Pro erstellt
https://github.com/RB3rg/Livolo-Mod
Mit C unter MPLab X erstellt
https://github.com/jamarju/livolo-firmware

Hier der eine Code mit PicBasic Pro geschrieben

Code: Alles auswählen

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''									
' 	LANGUAGE:		PicBasic Pro											
'	PROJECT:		Livolo-Mod
'	AUTHOR:			Douglas Schafer	
'                   		Rhaurison Bergamin							
'	REVISION:		REV 2.1													
' 	DESCRIPTION:	Livolo Touch Switch Mod
'					This program allows the sensor board of the Livolo switch to output serial commands to devices.														
'																			
' 	DEVICE:			PIC16F690											
' 	FUSE SETTINGS:	OSC = INTRC_IO, MCLRE = Disable							
'																			
'    		PIC16F688:           +--v--+                                       
'   					+5V VDD >[     ]< VSS 0v                                 
'   						 A5 <[     ]> A0 
'   						 A4 <[     ]> A1 LED2                   
'   						 A3 <[     ]> A2 TCHARGE
'   						 C5 <[     ]> C0 
'   						 C4 <[     ]< C1 TOUCH1               
'   						 C3 <[     ]< C2 TOUCH2
'   						 C6 <[     ]> B4 LED1
'   		 	 1KR		 C7 <[     ]< B5 RX                 
'   		---/\/\/\/--- TX B7 <[     ]> B6                
'                                +-----+   
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'==================================================
'=========   CONFIG FOR 1 AND 2 Gang   =============
Channels con 1 ; Define number of LIVOLO Channels (Gang): 1 or 2
LED_0    	var 	PortC.5    ; L3 
LED_1    	var 	PortB.6    ; L2     x
LED_2    	var 	PortC.5    ; L1
LED_3    	var 	PortB.6    ; A3
TRISC 		= %00001010
'=========   CONFIG FOR 3 Gang   ===================
;Channels con 3  ; Define number of LIVOLO Channels (Gang): 3
;LED_0    	var 	PortA.5    ; L2
;LED_1    	var 	PortA.1    ; L1
;LED_2    	var 	PortA.0    ; A3
;LED_3    	var 	PortB.4    ; L3 A0
;TRISC 		= %00001110
'=====================================================
RELAY_A    var     PortC.7    ; SW1
RELAY_B    var     PortA.1    ; SW2
RELAY_C    var     PortC.6    ; SW3

@ ERRORLEVEL -306                                  
DEFINE OSC 4		' Define Oscilator as 4Mhz
DEFINE  HSER_BAUD 1200  ' We Use 1200 baud to increase the distance range
DEFINE  HSER_CLROERR 1  ' Auto clear over-run errors
DEFINE HSER_RCSTA 90h   ' Enable serial port & continuous receive 	          
'define HSER_TXSTA 24H  ''Enable transmit, BRGH = 1   (for baud >=9600 only)
define HSER_TXSTA 20H   ' for 1200 bps
;DEFINE HSER_SPBRG 25                                 '   routine when you get data.
; OSCCON		= %01110001			' set OSC fuse bits to 8MHz
OSCCON		= %01100001			' set OSC fuse bits to 4MHz
;OSCCON		= %01010001			' set OSC fuse bits to 2MHz
ANSEL		= %00000000			' Analogue select 'off'
ANSELH 		= %00000000			' Analogue select 'off'
WPUA 		= %00000000    		' Set Pullups PortA 'off'
WPUB 		= %00000000    		' Set Pullups PortB 'off'
IOCA		= %00000000			' Interupt on change 'off'
INTCON      = %00000000         'initialize INTCON register, Enable Int
OPTION_REG 	= %10110001
CM1CON0		= %10010101			' Comparator C1 Control Register 0
CM2CON0		= %10100101			' Comparator C2 Control Register 0
CM2CON1		= %00000000			' Comparator C2 Control Register 1
SRCON		= %11110000			' SR Latch Control Register
VRCON		= %10000111			' Voltage Ref Control Register
PORTA 		= %00000000
TRISA 		= %00000100			' bit2 is for Timer input
PORTB 		= %00000000
TRISB 		= %00000000	        ' port B5 is RX input
PORTC 		= %00000000
'TXSTA  = %00100100
'RCSTA  = %10010000
;BAUDCTL = %00000000
;ADCON1      = %00001111    'Set up ADCON1 register no matter what you're doing!
SW_ON		var		Bit[4]
SW_ON[0] = 0	; L3 (Left)							' SWITCH.0 select 1 if used, 0 if not: GANG TYPE, 4,
SW_ON[1] = 0    ; L1 (right)						' SWITCH.1 select 1 if used, 0 if not: GANG TYPE, 4, 2, and 1
SW_ON[2] = 0	; L2 (left/Center)					' SWITCH.2 select 1 if used, 0 if not: GANG TYPE, 4, 2,
SW_ON[3] = 0	; L4								' SWITCH.3 select 1 if used, 0 if not: GANG TYPE, 4,
'''''''''''''''''''''''''''''''''''''''    DEFINE VARIABLES    '''''''''''''''''''''''''''''''''''''''''''''''''''
SW_raw		var		Word[4]
SW_average	var		Word[4]
debounce	var		Byte[4]
sense_time	var		Word[4]
sense       var     word
ch			var		Byte
i			var		Byte
b1          var     byte
docalibrate var     word
MLED1       var     byte
clear
; devine how sensitivy it is. 
;increase to less sensitive, decrease makes it more sensitive
; 20 is a good number.
sense = 20

if channels = 1 then
    SW_ON[1] = 1
endif
if channels = 2 then
    SW_ON[1] = 1
    SW_ON[2] = 1
endif
if channels = 3 then
    SW_ON[1] = 1
    SW_ON[2] = 1
    SW_ON[3] = 1
endif
RELAY_A = 0
RELAY_B = 0
RELAY_C = 0
LED_0 = 0
LED_1 = 0
LED_2 = 0
LED_3 = 0
docalibrate=0

for i=0 to 9
    toggle LED_1
    pause 100
next
LED_1 = 0

for i=0 to 9
    toggle LED_2
    pause 100
next
LED_2 = 0

for i=0 to 9
    toggle LED_3
    pause 100
next
LED_3 = 0

'''''''''''''''''''''''''''''''''''''''''    USER NOTES    ''''''''''''''''''''''''''''''''''''''''''''''''''''
;; WARNING:  THIS PROGRAM HAS BEEN TESTED ON 1 Gang, 2 GANG, AND 3 GANG SWITCH'S ;;

GoSub CALIBRATE
hserout[13,10]
hserout[13,10]
hSerout["CH1:",DEC LED_1,",CH2:",dec LED_2,",CH3:",dec LED_3,",CH4:",dec LED_0,13,10]
''''''''''''''''''''''''''''''''''''''''''    MAIN PROGRAM    ''''''''''''''''''''''''''''''''''''''''''''''''''''

START:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECK SW0
ch=0
If SW_ON[ch]=0 Then SKIP0	
GoSub CHECK_SW
If debounce[ch] = 1 Then
	Toggle LED_0
		If LED_0=1 Then
		  hSerout ["CH0:1",13,10]
		  hSerout ["CH0:1",13,10]
		  hSerout ["CH0:1",13,10]
		Else
		  hSerout ["CH0:0",13,10]
		  hSerout ["CH0:0",13,10]
		  hSerout ["CH0:0",13,10]
		EndIf
EndIf
'Serout2 TX, 84, ["RAW", DEC1 ch, ": ", DEC5 SW_raw[ch], ",   AVE", DEC1 ch, ": ", DEC5 SW_average[ch], ",   TIME", DEC1 ch, ": ", DEC5 sense_time[ch], ",   "] ;THIS IS USED FOR TESTING
SKIP0:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECK SW1
ch=1
If SW_ON[ch]=0 Then SKIP1
GoSub CHECK_SW
If debounce[ch] = 1 Then
	Toggle LED_1
	'docalibrate = docalibrate + 1
		If LED_1=1 Then
			hSerout ["CH1:1",13,10]			' Turn light OFF comand for external device
			hSerout ["CH1:1",13,10]         ' send it 3 times to ensure comms
			hSerout ["CH1:1",13,10]
			RELAY_A = 1
		Else
			hSerout ["CH1:0",13,10]			' Turn light ON comand for external device
			hSerout ["CH1:0",13,10]
			hSerout ["CH1:0",13,10]
			RELAY_A = 0
		EndIf
EndIf
'Serout2 TX, 84, ["RAW", DEC1 ch, ": ", DEC5 SW_raw[ch], ",   AVE", DEC1 ch, ": ", DEC5 SW_average[ch], ",   TIME", DEC1 ch, ": ", DEC5 sense_time[ch], ",   "] ;THIS IS USED FOR TESTING
SKIP1:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECK SW2
ch=2
If SW_ON[ch]=0 Then SKIP2	
GoSub CHECK_SW
If debounce[ch] = 1 Then
	Toggle LED_2
		If LED_2=1 Then
			hSerout ["CH2:1",13,10]			' Turn light OFF comand for external device
			hSerout ["CH2:1",13,10]
			hSerout ["CH2:1",13,10]
			RELAY_B = 1
		Else
			hSerout ["CH2:0",13,10]			' Turn light ON comand for external device
			hSerout ["CH2:0",13,10]
			hSerout ["CH2:0",13,10]
			RELAY_B = 0
		EndIf
EndIf
'Serout2 TX, 84, ["RAW", DEC1 ch, ": ", DEC5 SW_raw[ch], ",   AVE", DEC1 ch, ": ", DEC5 SW_average[ch], ",   TIME", DEC1 ch, ": ", DEC5 sense_time[ch], ",   "] ;THIS IS USED FOR TESTING
SKIP2:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECK SW3
ch=3
If SW_ON[ch]=0 Then SKIP3
GoSub CHECK_SW
If debounce[ch] = 1 Then
	Toggle LED_3
		If LED_3=1 Then
         	hSerout ["CH3:1",13,10]			' Turn light OFF comand for external device
         	hSerout ["CH3:1",13,10]
         	hSerout ["CH3:1",13,10]
			RELAY_C = 1
		Else
         	hSerout ["CH3:0",13,10]			' Turn light OFF comand for external device
         	hSerout ["CH3:0",13,10]
         	hSerout ["CH3:0",13,10]
			RELAY_C = 0
		EndIf
EndIf
SKIP3:
b1=10
hserin 50,Timeout,[b1]
'pause 50
' Once Received in the Serial:
' 0 -> Return the Status
' 1 -> turn CH1 on
' 2 -> turn CH2 on
' 3 -> turn CH3 on
' 4 -> Reserved
' 5 -> turn CH1 off
' 6 -> turn CH2 off
' 7 -> turn CH3 off
' 8 -> Reserved
' 9 -> Calibrate
if b1 <> 10 then
    IF b1 = "0" THEN 
    	   hSerout["CH1:",DEC LED_1,",CH2:",dec LED_2,",CH3:",dec LED_3,",CH4:",dec LED_0,13,10]
           'hSerout["CH2:",DEC LED_2,13,10]
           'hSerout["CH3:",DEC LED_3,13,10]
           'hSerout["CH4:",DEC LED_0,13,10]			
    endif
    IF b1 = "1" THEN 
        LED_1 = 1
        hSerout["CH1:",DEC LED_1,13,10]
        hSerout["CH1:",DEC LED_1,13,10]
        RELAY_A = 1			
    endif
    IF b1 = "5"   THEN 
        LED_1 = 0
        hSerout ["CH1:",dec LED_1,13,10]
        hSerout ["CH1:",dec LED_1,13,10]			  
        RELAY_A = 0
    endif
    IF (b1="2") and (SW_ON[2]=1) THEN 
        LED_2 = 1
	    hSerout["CH2:",dec LED_2,13,10]
        hSerout["CH2:",dec LED_2,13,10]			 
	    RELAY_B = 1
    endif
    IF (b1="6") and (SW_ON[2]=1) THEN 
        LED_2 = 0
        hSerout ["CH2:",dec LED_2,13,10]
        hSerout ["CH2:",dec LED_2,13,10]		   
        RELAY_B = 0
    endif
    IF (b1="3") and (SW_ON[3]=1) THEN 
        LED_3 = 1
	    hSerout["CH3:",dec LED_3,13,10]	
        hSerout["CH3:",dec LED_3,13,10]		 
	    RELAY_C = 1
    endif
    IF (b1="7") and (SW_ON[3]=1) THEN 
        LED_3 = 0
        hSerout ["CH3:",dec LED_3,13,10]
        hSerout ["CH3:",dec LED_3,13,10]		   
        RELAY_C = 0
    endif
    IF (b1="4") and (SW_ON[0]=1) THEN 
        LED_0 = 1
	    hSerout["CH0:",dec LED_0,13,10]	
        hSerout["CH0:",dec LED_0,13,10]		 
	    ;RELAY_CH3 = 1
    endif
    IF (b1="8") and (SW_ON[0]=1) THEN 
        LED_0 = 0
	    hSerout["CH0:",dec LED_0,13,10]	
        hSerout["CH0:",dec LED_0,13,10]		 
	    ;RELAY_CH3 = 0
    endif
    IF (b1="9") THEN 
         hSerout ["CH0:",dec LED_0,13,10]
         pause 20	
         hSerout ["CH1:",dec LED_1,13,10]
         pause 20
         hSerout ["CH2:",dec LED_2,13,10]
         pause 20
         hSerout ["CH3:",dec LED_3,13,10]
         pause 20
         MLED1 = LED_1
         GoSub CALIBRATE
         for i=0 to 9
            toggle LED_1
            pause 200
        next
        LED_1 = MLED1	   
    endif
endif
GoTo START

Timeout:
    goto START

'''''''''''''''''''''''''''''''''''''''''    CHECK SWITCHES    '''''''''''''''''''''''''''''''''''''''''''''''''''
CHECK_SW:
    CM1CON0.0 = ch.0								' change to correct input ch (bit 0)
    CM1CON0.1 = ch.1								' change to correct input ch (bit 1)
    CM2CON0.0 = ch.0								' change to correct input ch (bit 0)
    CM2CON0.1 = ch.1								' change to correct input ch (bit 1)
    TMR0 = 0										' Reset the Timer 0
    PauseUs sense_time[ch]							' Pause for appropriate time to get default 200 cycles
    SW_raw[ch] = TMR0								' Get count value from Timer0
    SW_raw[ch] = SW_raw[ch]*10						' Do some averaging
    ; SW_average[ch] = (SW_average[ch]*9)+SW_raw[ch]
    ; SW_average[ch] = SW_average[ch]/10
    ; SW_average[ch] = SW_average[ch] + (SW_raw[ch] - SW_average[ch])/10
    SW_average[ch] = (9*SW_average[ch]+SW_raw[ch])/10

    ; If SW_raw[ch] < (SW_average[ch]-10) Then	;	 Check if switch is touched
    If SW_raw[ch] < (SW_average[ch]- sense) Then ; 
	   debounce[ch] = debounce[ch] + 1				' Debounce switch
    Else
	   debounce[ch] = 0
    EndIf
Return

'''''''''''''''''''''''''''''''''''''''''    CHECK SWITCHES    '''''''''''''''''''''''''''''''''''''''''''''''''''
CALIBRATE:
For ch=1 to 3
	If SW_ON[ch]=1 Then
	    sense_time[ch] = 0 ;it need a start point???  
        ;SW_average[ch] = 0 inicial 
		CAL_LOOP:
		sense_time[ch]=sense_time[ch]+1
		GoSub CHECK_SW
		If SW_raw[ch]<2000 Then
			GoTo CAL_LOOP
		EndIf
	EndIf
next
Return

END


und hier noch die Schaltung dazu
VL-C701X-2.JPG
Gruß
DG0JG

Re: PiC16F690 Code Livolo Glas Sensor Schalter

#2

Beitrag Peter » 3. Jan 2019, 12:39

Wo kommt denn der Schaltplan her ?
D1 und D2 werden nie leuschten.
Und ich glaube auch nicht das der Controller läuft, bei
der hohen Beschaltung von MCLR.


Re: PiC16F690 Code Livolo Glas Sensor Schalter

#4

Beitrag DG0JG » 3. Jan 2019, 22:02

Hallo Peter,

Sorry der Schaltplan kommt von mir und du hast natürlich recht. D1 und D2 müssen gedreht werden und die habe ich falsch eingezeichnet. Ich werde es nochmals richtig stellen. Die obeere Bezeichnung ist von J3-1 bis J3-5 keine Jumper sondern ein Connector.
Der Controller läuft auch mit den 10M gegen VCC.
Mir geht eigentlich um den Code da der zweite Sensor an RC3 nicht funktioniert. Irgendwie geht es wohl mit den Komperator nicht richtig. Der PIC16F690 hat doch zwei ?

Gruß
DG0JG
Dateianhänge
VL-C701X-2.JPG

Re: PiC16F690 Code Livolo Glas Sensor Schalter

#5

Beitrag pic18 » 4. Jan 2019, 20:52

ich habe mal das C-Programm überflogen, da ist mir aufgefallen das nur Relais 1 (RC7, RC6) in switch.c programmiert ist.
In capsensor.c ist:
// C1OE --0----- no output on pin
// C1POL ---1---- inverse pol
programmiert, somit dürfte nur c2 laufen:
// C2OE --1----- connected to pin
// C2POL ---0---- normal pol

mit den Widerständen im Schaltplan habe wegen der Richtigkeit meine Bedenken. Es sind keine Normwerte und 10MOhm für R5 ist sehr hoch?! Auch die Vorwiderstände R1 und R2 sind zu hoch? Es würde bei 5V weniger als 400uA fließen. (D3 und D4). Als C6 sollte man einen Kerko von 100nF nehmen.

Re: PiC16F690 Code Livolo Glas Sensor Schalter

#6

Beitrag Peter » 4. Jan 2019, 22:24

Ja ist mir auch schon aufgefallen das da was im Programm fehlt.
Ausserdem sind die Kommentare die im Programm stehen, ein wenig
undurchsichtig oder falsch. Vielleicht mal den Autor anschreiben, was er
dazu zu sagen hat. Wie kommst du darauf die LEDs so an zu schließen ?
Laut Code liegen sie anders. Und wie schon geschrieben stimmen die Widerstände
nicht.

Re: PiC16F690 Code Livolo Glas Sensor Schalter

#7

Beitrag DG0JG » 4. Jan 2019, 23:07

Hallo,

Also der Schaltplan ist von mir und ist auch so ausgemessen. Diese Schalter gibt es auf dem Markt und sind von Livolo VL-C701x-2. Die Widerstände sind wohl so (gerade nochmals nachgemessen sogar 12k) weil diese Schaltung eigentlich dirket im Netz über Lastwiderstände hängt (3V) und somit sollen die Leuchtdioden so wenig wie möglich Strom verbrauchen.
Ich schaue mir den C Code nochmals an und teste noch mal.

ich danke schon mal für die Tips

Gruß
DG0JG

Re: PiC16F690 Code Livolo Glas Sensor Schalter

#8

Beitrag DG0JG » 4. Jan 2019, 23:36

Hallo,

Ich habe mir den Code angeschaut und die Änderung in der capsensor.c vorgenommen. Leider funktioniert noch immer nur der Sensoreingang der an RC3 angeschlossen ist. Der Sensor der an RC1 angeschlossen ist funktioniert nicht.
Das Relaisboard habe ich nicht angeschlossen und betreibe die Schaltung mit 5V bzw 3.3V. Zur Kontrolle ob die Sensoreingänge gehen dienen die LED´s als Indikator.

Was ich im Code auch noch nicht verstehe, wie wird unterschieden in der switch.c welcher Sensoreingang gedrückt wurde. Vor allem wo ist das definiert ?

Leider hat der Entwickler keine Zeit um seinen Code nochmals nachzusehen da hatte ich schon nachgefragt.
Ich danke schon mal für die Tips

Gruß
DG0JG
Dateianhänge
13a5ed.jpg
04ae5d.jpg

Re: PiC16F690 Code Livolo Glas Sensor Schalter

#9

Beitrag pic18 » 5. Jan 2019, 10:36

Der Sensor der an RC1 angeschlossen ist funktioniert nicht.
Der ist in switch.c auch nicht programmiert. (Relais 2).
Auf dem Bild kann man jetzt deutlich die Widerstandswerte sehen. ;)

Re: PiC16F690 Code Livolo Glas Sensor Schalter

#10

Beitrag DG0JG » 5. Jan 2019, 22:05

Hi pic18

Ja hätte auch umrechnen könne und die Werte eintragen können im Schlatplan :)

Wäre nett wenn Du mir verraten könntest wie und wo der erste Sensor defineirt ist dann könnte ich den 2 Sensor im Code eintragen. Es müsste ja irgendwo der RC3 Sensoreingang definiert sein da dieser ja funktioniert.
In der switch.c ist ja die Zeile switch_status = SWITCH_ON; die Abfragt ob der Sensor gedrückt wurde nur sehe ich nicht wo SWITCH_ON am Sensor Eingang gebunden ist.

Gruß

DG0JG

Antworten