IR Touch panel with ATtiny2313/90S2313 by Ger Langezaal
Schematic - control unit
Mechanical drawing
Detailed picture
Overview picture
Download complete documentation include .BAS here
BASCOM program :
'-------------------------------------------------------------------------------
' Filename :
IR-Touch Controller_20.bas
' Revision : 1.0
' Controller : AVR ATtiny2313 or AT90S2313
' Author : Ger
langezaal
' Compiler :
BASCOM-AVR Rev. 1.11.7.9
' Flash Used : 61%
'
'---[ Small program description
]-----------------------------------------------
'
' This program is written to create a infra-red touch
display controller.
' The 5x4 infra-red matrix for 20 buttons is scanned at a
rate of 50 Hz.
' As overlay on a graphic 320x240 LCD for finger or gloved
hand activation.
' The controller interface connects via the serial TX
port.
'
' If Auto Repeate = ON: (Pind.0=Low)
' The controller
will send the touch position (&H01 to &H14) and after 400ms
' the auto repeate
will start at a rate of 10Hz. No release code is send.
' If Auto Repeate = OFF: (Pind.0=High)
' The controller
will send the touch position (&H01 to &H14) one time and
' after releasing,
the code (&HF0) will be send one time.
'
' Schematic : IR-Touch Screen_sch.pdf
' Mechanical construction : IR-Touch Screen_cs.pdf
'
' IR receiver is the SFH 5110-36 (Conrad Artnr.153871)
' IR transmitter the SFH 4510 (Conrad Artnr.153742)
'
'---[ Disclaimer
]--------------------------------------------------------------
'
' This example is offered on an "AS IS" basis,
no warranty expressed or implied.
' The programmer disclaim liability of any damage
associated with the use of
' the software or hardware described herein.
'
'-------------------------------------------------------------------------------
'
' ATtiny2313
' ----__----
' -RESET -|1 20|- VCC
' (Auto Repeate On/Off) D0 -|2 19|- B7 (Y4) (SCK)
' (Serial
Out) TX -|3 18|- B6 (Y3) (MISO)
' XTAL2 -|4 17|- B5 (Y2) (MOSI)
' XTAL1 -|5 16|- B4 (Y1)
' (Valid
ind) D2 -|6 15|- B3 (36KHz IR Carrier)
' (Y
ind) D3 -|7 14|- B2 (X5)
' (X
ind) D4 -|8 13|- B1 (X4)
' (X1) D5 -|9 12|- B0 (X3)
' GND -|10 11|- D6 (X2)
' ----------
'
'-------------------------------------------------------------------------------
'
$regfile = "2313def.dat"
'$regfile = "attiny2313def.dat"
$crystal = 8000000
$baud = 19200
Dim X_count As Byte
Dim Y_count As Byte
Dim X_pos As Byte
Dim Y_pos As Byte
Dim X_axis As Byte
Dim Y_axis As Byte
Dim Touch_position As Byte
Dim Prev_touch_position As Byte
Dim Ir_rec_out As Bit
Dim First_scan_flag As Bit
Dim Release_flag As Bit
Dim Auto_rep_start_flag As Bit
Dim Auto_rep_start_del_cntr As Byte
Dim Print_flag As Bit
Dim First_print_flag As Bit
Config Portb = Output
Config Portd = Output
Config Portd.0 = Input
Portd.0 = 1 'pull-upp On
Config Watchdog = 1024
'---[ Aliasing
]----------------------------------------------------------------
'
Ir_carrier Alias Portb.3 '36KHz carrier frequency.
Valid_ind Alias Portd.2 'valid XY-axis indicator.
Auto_repeate Alias Pind.0 'auto repeate = 0
Y_ind Alias Portd.3 'Y-axis indicator.
X_ind Alias Portd.4 'X-axis indicator.
X1_inp Alias Pind.5
X1_out Alias Portd.5
X1_dir Alias Ddrd.5
X2_inp Alias Pind.6
X2_out Alias Portd.6
X2_dir Alias Ddrd.6
X3_inp Alias Pinb.0
X3_out Alias Portb.0
X3_dir Alias Ddrb.0
X4_inp Alias Pinb.1
X4_out Alias Portb.1
X4_dir Alias Ddrb.1
X5_inp Alias Pinb.2
X5_out Alias Portb.2
X5_dir Alias Ddrb.2
Y1_inp Alias Pinb.4
Y1_out Alias Portb.4
Y1_dir Alias Ddrb.4
Y2_inp Alias Pinb.5
Y2_out Alias Portb.5
Y2_dir Alias Ddrb.5
Y3_inp Alias Pinb.6
Y3_out Alias Portb.6
Y3_dir Alias Ddrb.6
Y4_inp Alias Pinb.7
Y4_out Alias Portb.7
Y4_dir Alias Ddrb.7
'---[ Constants
]---------------------------------------------------------------
'
Const Ir_output = 1 'port direction
Const Ir_input = 0 'port direction
Const Carrier_off = &B10000000 'PB3 (OC1A) low
Const Carrier_on = &B01000000 'Toggle OC1A
Const Burst_length = 498 'uS (18 periods of 36KHz)
Const Burst_gap = 450 'uS
Const Settle_time = 50 'uS
Const Framegap_length = 12 'mS
Const Auto_rep_start_delay = 3 '2=300mS, 3=400mS, 4=500mS
Const Release_char = &HF0
Const True = 1
Const False = 0
Const _on = 0
Const _off = 1
'---[ Config Timer1 for a 36kHz IR carrier frequency
]--------------------------
'
Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1
Timer1 = 0
' reload value Timer1:
' crystal (kHz) / carrier (kHz) / 2 (toggle) = reload
value
' 8000 / 36 / 2 = 111
Compare1a = 111 'reload value
'---[ Init portpin levels ]-----------------------------------------------------
Tccr1a = Carrier_off 'set PB3 (OC1A) low
X1_dir = Ir_output 'set port to output
X2_dir = Ir_output
X3_dir = Ir_output
X4_dir = Ir_output
X5_dir = Ir_output
Y1_dir = Ir_output
Y2_dir = Ir_output
Y3_dir = Ir_output
Y4_dir = Ir_output
Set X1_out 'set output high
Set X2_out
Set X3_out
Set X4_out
Set X5_out
Set Y1_out
Set Y2_out
Set Y3_out
Set Y4_out
Start Watchdog
'---[ Main loop
]---------------------------------------------------------------
'
Do
Gosub Scan_xy
Gosub Touch_check
Loop
End
'
'---[ Sub routines
]------------------------------------------------------------
'
'
'---[ Scan X and Y axis
]-------------------------------------------------------
'
Scan_xy:
X_count = 0 'reset X-beam interrupt counter
Y_count = 0 'reset Y-beam interrupt counter
X_pos = 0 'X-scan start position
Y_pos = 0 'Y-scan start position
X1_dir = Ir_output 'set pin to output
X1_out = 0 'set output low
Gosub Send_ir_burst_wave 'send IR burst
X1_dir = Ir_input 'set pin to input
Waitus Settle_time 'small delay
Ir_rec_out = X1_inp 'store IR receiver output level
Gosub Test_x 'test if IR beam is interrupted
X2_dir = Ir_output 'same as X1
X2_out = 0
Gosub Send_ir_burst_wave
X2_dir = Ir_input
Waitus Settle_time
Ir_rec_out = X2_inp
Gosub Test_x
X3_dir = Ir_output
X3_out = 0
Gosub Send_ir_burst_wave
X3_dir = Ir_input
Waitus Settle_time
Ir_rec_out = X3_inp
Gosub Test_x
X4_dir = Ir_output
X4_out = 0
Gosub Send_ir_burst_wave
X4_dir = Ir_input
Waitus Settle_time
Ir_rec_out = X4_inp
Gosub Test_x
X5_dir = Ir_output
X5_out = 0
Gosub Send_ir_burst_wave
X5_dir = Ir_input
Waitus Settle_time
Ir_rec_out = X5_inp
Gosub Test_x
'---
Y1_dir = Ir_output
Y1_out = 0
Gosub Send_ir_burst_wave
Y1_dir = Ir_input
Waitus Settle_time
Ir_rec_out = Y1_inp
Gosub Test_y
Y2_dir = Ir_output
Y2_out = 0
Gosub Send_ir_burst_wave
Y2_dir = Ir_input
Waitus Settle_time
Ir_rec_out = Y2_inp
Gosub Test_y
Y3_dir = Ir_output
Y3_out = 0
Gosub Send_ir_burst_wave
Y3_dir = Ir_input
Waitus Settle_time
Ir_rec_out = Y3_inp
Gosub Test_y
Y4_dir = Ir_output
Y4_out = 0
Gosub Send_ir_burst_wave
Y4_dir = Ir_input
Waitus Settle_time
Ir_rec_out = Y4_inp
Gosub Test_y
Waitms Framegap_length
Return
'---[ Pin PB3 (OC1A) send a 36kHz burst of 18 periods
]-------------------------
'
Send_ir_burst_wave:
Tccr1a = Carrier_on
Waitus Burst_length '18 periods
Tccr1a = Carrier_off
Return
'---[ X-axis test if not more then one beam is interrupted
]--------------------
'
Test_x:
If Ir_rec_out = 1 Then 'if X-beam is interrupted (output=high)
Incr X_count 'count number of interrupted X-beams
X_axis = X_pos + 1 'store position
End If
Incr X_pos 'next X position
Waitus Burst_gap 'delay to next X-axis
Return
'---[ Y-axis test if not more then one beam is interrupted
]--------------------
'
Test_y:
If Ir_rec_out = 1 Then 'if Y-beam is interrupted (output=high)
Incr Y_count 'count number of interrupted Y-beams
Y_axis = Y_pos 'store position
End If
Y_pos = Y_pos + 5 'next Y position
Waitus Burst_gap 'delay to next Y-axis
Return
'---[ If one X-axis and one Y-axis is interrupted then
position is valid ]------
'
Touch_check:
X_ind = _off 'X-axis indicator OFF
Y_ind = _off 'Y-axis indicator OFF
Valid_ind = _off 'valid indicator OFF
If X_count > 0 Then X_ind = _on 'X-axis indicator ON
If Y_count > 0 Then Y_ind = _on 'Y-axis indicator ON
If X_count = 0 And Y_count = 0 Then
Release_flag = True 'no touch detected
First_scan_flag = True
Auto_rep_start_flag = True
Auto_rep_start_del_cntr = 0
If Auto_repeate = _off Then Gosub Send_release_code
End If
If X_count > 1 Or Y_count > 1 Then Release_flag = False 'invalid touch
position
If Release_flag = True Then 'no touch was detected
If X_count = 1 And Y_count = 1 Then 'touch position is valid
Touch_position = Y_axis +
X_axis 'calculate button number
If Auto_repeate = _on Then Print_flag = True
Gosub Send_touch_position_code
End If
End If
Reset Watchdog
Return
'---[ When auto-repeate is off and touch is released then
send release code ]---
'
Send_release_code:
If Print_flag = False Then 'flag was reset after sending touch position code
Touch_position = Release_char 'copy a constant to a variable
Print Hex(touch_position); 'send release code
Print_flag = True
End If
Return
'---[ If touch is valid then send touch position
]------------------------------
'
Send_touch_position_code:
If First_scan_flag = True Then 'prevents activating buttons around if touch is sliding
If Auto_repeate = _off Then Print_flag = True 'set flag for only one print if autorepeate is OFF
Prev_touch_position = Touch_position 'save touch position after the first scan
First_scan_flag = False 'only after the first scan
End If
If Touch_position =
Prev_touch_position Then 'compare
touch position with previous position
If Auto_rep_start_del_cntr = 0 Then
If Print_flag = True Then Print Hex(touch_position); 'print hex notation (&H01 to &H14)
End If
If Auto_rep_start_flag = True Then
If Auto_rep_start_del_cntr < Auto_rep_start_delay Then
Incr Auto_rep_start_del_cntr
Else
Auto_rep_start_del_cntr = 0
Auto_rep_start_flag = False
End If
End If
Print_flag = False
Valid_ind = _on 'valid indicator ON
X_ind = _off 'X-axis indicator OFF
Y_ind = _off 'Y-axis indicator OFF
Waitms 80 'slow down (auto-repeate rate = 10x Sec)
Else 'no stable touch position
Release_flag = False 'stop printing
End If
Return
'-------------------------------------------------------------------------------
|