Processing Frequency of Color Sensor TCS230 with Microcontroller AT89S51

Posted on

The TCS230 programmable color light-to-frequency converter combines configurable silicon photodiodes and a current-to-frequency converter on single monolithic CMOS integrated circuit. The output is a square wave (50% duty cycle) with frequency directly proportional to light intensity (irradiance). The full-scale output frequency can be scaled by one of three preset values via two control input pins. Digital inputs and digital output allow direct interface to a microcontroller or other logic circuitry. Output enable (OE) places the output in the high-impedance state for multiple-unit sharing of a microcontroller input line.

The light-to-frequency converter reads an 8 x 8 array of photodiodes. Sixteen photodiodes have blue filters, 16 photodiodes have green filters, 16 photodiodes have red filters, and 16 photodiodes are clear with no filters. The four types (colors) of photodiodes are interdigitated to minimize the effect of non-uniformity of incident irradiance. All 16 photodiodes of the same color are connected in parallel and which type of photodiode the device uses during operation is pin-selectable. Photodiodes are 120 mm x 120 mm in size and are on 144-mm centers.

Functional Block Diagram

Terminal Function

Terminal
Name

No

I/O

Description

GND 4 Power supply ground. All voltages are referenced to GND.
OE 3 In Enable for fo (active low).
OUT 6 Out Output frequency (fo).
S0, S1 1,2 In Output frequency scaling selection inputs.
S2,S3 7,8 In Photodiode type selection inputs.
VDD 5 Supply voltage

 

S0

S1

Output Frequency Scaling ( fc )

 

S2

S3

Photodiode Type

L

L

Power Down

L

L

Red

L

H

2%

L

H

Blue

H

L

20%

H

L

Clear ( No Filter )

H

H

100%

H

H

Green

APPLICATION INFORMATION
Power supply considerations
Power-supply lines must be decoupled by a 0.01-mF to 0.1-mF capacitor with short leads mounted close to the device package.

Input interface
A low-impedance electrical connection between the device OE pin and the device GND pin is required for improved noise immunity.

Output interface
The output of the device is designed to drive a standard TTL or CMOS logic input over short distances. If lines greater than 12 inches are used on the output, a buffer or line driver is recommended.

Photodiode type (color) selection
The type of photodiode (blue, green, red, or clear) used by the device is controlled by two logic inputs, S2 and S3 (see Table 1).

Output frequency scaling
Output-frequency scaling is controlled by two logic inputs, S0 and S1. The internal light-to-frequency converter generates a fixed-pulsewidth pulse train. Scaling is accomplished by internally connecting the pulse-train output of the converter to a series of frequency dividers. Divided outputs are 50%-duty cycle square waves with relative frequency values of 100%, 20%, and 2%. Because division of the output frequency is accomplished by counting pulses of the principal internal frequency, the final-output period represents an average of the multiple periods of the principle frequency. The output-scaling counter registers are cleared upon the next pulse of the principal frequency after any transition of the S0, S1, S2, S3, and OE lines. The output goes high upon the next subsequent pulse of the principal frequency, beginning a new valid period. This minimizes the time delay between a change on the input lines and the resulting new output period. The response time to an input programming change or to an irradiance step change is one period of new frequency plus 1 mS. The scaled output changes both the full-scale frequency and the dark frequency by the selected scale factor. The frequency-scaling function allows the output range to be optimized for a variety of measurement techniques. The scaled-down outputs may be used where only a slower frequency counter is available, such as low-cost microcontroller, or where period measurement techniques are used.

Measuring the frequency
The choice of interface and measurement technique depends on the desired resolution and data acquisition rate. For maximum data-acquisition rate, period-measurement techniques are used. Output data can be collected at a rate of twice the output frequency or one data point every microsecond for full-scale output. Period measurement requires the use of a fast reference clock with available resolution directly related to reference clock rate. Output scaling can be used to increase the resolution for a given clock rate or to maximize resolution as the light input changes. Period measurement is used to measure rapidly varying light levels or to make a very fast measurement of a constant light source. Maximum resolution and accuracy may be obtained using frequency-measurement, pulse-accumulation, or integration techniques. Frequency measurements provide the added benefit of averaging out random- or high-frequency variations (jitter) resulting from noise in the light signal. Resolution is limited mainly by available counter registers and allowable measurement time. Frequency measurement is well suited for slowly varying or constant light levels and for reading average light levels over short periods of time. Integration (the accumulation of pulses over a very long period of time) can be used to measure exposure, the amount of light present in an area over a given time period.

 

Schematic Diagram System

microcontroller 8051 application TCS230 LCD Characater

 

;====================================================
;FREQUENCY COUNTER BASE ON MICROCONTROLLER 89S51 ;
;1.This Program is to count frequency from T0, by using mode 1 Counter 16 bit, then counter will overflow after 65.535d or FFFFh pulse
;2.Counter resets every 1 second that generated by timer 1, configured as timer 16 bit trough ; TF1 interrupt ;3.Every 1 second data will show on LCD Character and data saved on RAM address 30h trough 6fh for 30 data
;4.Subrutine SearchMax, used to find the biggest data betwen 30 data that already saved
;
;by: Triwiyanto, S.Si.,MT ; www.mytutorialcafe.com

;======================================================
; dispclr equ 00000001b funcset equ 00111000b entrmod equ 00000110b
dispon equ 00001100b ones equ 71h tens equ 72h hundreds equ 73h thousands
equ 74h tenthousands equ 75h Count10 equ 76h DataCounter_MaxL equ 77h
DataCounter_MaxH equ 78h DataCounter_nextL equ 79h DataCounter_nextH
equ 7ah DataRAMCounterL equ 7bh DataRAMCounterH equ 7ch DataFlowRateL
equ 7dh DataFlowRateH equ 7eh NewDataL equ 7fh NewDataH equ 70h ; RS
bit P3.0 EN bit P3.1 PortLCD equ P0 button bit P2.3 ;Ram 30h s/d 4fh
;Ram 50h s/d 6fh ; ; org 0h sjmp start ; org 0bh ; address interrupt
for timer0 ljmp Timer_Interupsi0 ; long jump to timer interrupt 0 TF0
;
start:
call ResetRAM
call Init_LCD AgainD:
call lcd_demo jb button,AgainD
jnb button,$ ; setb P2.0; mode no filter TCS230
clr P2.1 ; mode no filter TCS230
clr P2.2 ; output enable TCS230
call init_lcd call init_interupsi_Timer0 ; call LCD_Flow Forever: call
DisplayFlowRate jb button, Forever jnb button,$ call lcd_Search call
ldelay call init_lcd call LCD_maxFLow Finish: call DisplayFlowRateMax
call stopcounter jb button,Finish jnb button,$ call resetcounter sjmp
start ; DisplayFlowRate: mov DataFlowRateL,NewDataL mov DataFlowRateH,NewDataH
; call Hex16toBCD ; mov R3,#086h call write_inst mov R3,tenthousands
call write_data ; mov R3,#087h call write_inst mov R3,thousands call
write_data ; mov R3,#088h call write_inst mov R3,hundreds call write_data
; mov R3,#089h call write_inst mov R3,tens call write_data ; mov R3,#08ah
call write_inst mov R3,ones call write_data ret ; DisplayFlowRateMax:
call SearchingMax ; mov DataFlowRateL,DataCounter_MaxL mov DataFlowRateH,DataCounter_MaxH
; call Hex16toBCD ; mov R3,#0c6h call write_inst mov R3,tenthousands
call write_data ; mov R3,#0c7h call write_inst mov R3,thousands call
write_data ; mov R3,#0c8h call write_inst mov R3,hundreds call write_data
; mov R3,#0c9h call write_inst mov R3,tens call write_data ; mov R3,#0cah
call write_inst mov R3,ones call write_data ret ; ;==========================================================
;Subroutine Hex16toBCD
;===========================================================
;To convert hex 16 bit to 5 digit decimal
;input Data 8 High byte = R1
;input Data 8 Low byte = R2
;
;Output tenthousands = R7
;Output thousands = R6
;Output hundreds = R5
;Output tens = R4
;Output ones = R3
;
;Contoh:
1A2C h —-> 06799 d
;=======================================================

Hex16toBCD:

        ANL PSW,#11101111b ; Aktivate bank 1 MOV R1,DataFlowRateH;

        MSByte

        MOV R2,DataFlowRateL; LSByte

        MOV R3,#00D

        MOV R4,#00D

        MOV R5,#00D

        MOV R6,#00D

        MOV R7,#00D
        MOV B,#10D

        MOV A,R2

        DIV AB

        MOV R3,B ;

        MOV B,#10 ; R7,R6,R5,R4,R3

        DIV AB

        MOV R4,B

        MOV R5,A

        CJNE R1,#0H,HIGH_BYTE ; CHECK FOR HIGH BYTE

        SJMP ENDD

HIGH_BYTE:

        MOV A,#6

        ADD A,R3

        MOV B,#10

        DIV AB

        MOV R3,B

        ADD A,#5

        ADD A,R4

        MOV B,#10

        DIV AB

        MOV R4,B

        ADD A,#2

        ADD A,R5

        MOV B,#10

        DIV AB

        MOV R5,B

        CJNE R6,#00D,ADD_IT

        SJMP CONTINUE

ADD_IT:

        ADD A,R6

CONTINUE:

        MOV R6,A

        DJNZ R1,HIGH_BYTE

        MOV B, #10D

        MOV A,R6

        DIV AB

        MOV R6,B

        MOV R7,A

ENDD:

        Mov A,R3

        Add A,#30h

        MOV ones,A

        ;

        Mov A,R4

        Add A,#30h

        Mov tens,A

        ;

        Mov A,R5

        Add A,#30h

        Mov hundreds,A

        ;

        Mov A,R6

        Add A,#30h

        Mov thousands,A

        ;

        Mov A,R7

        Add A,#30h

        Mov tenthousands,A

        ANL PSW,#11100111b ;Aktivasi Bank 0

        ret

;============================================================

;Subrutine Timer_Interupsi0

;===================================================

;This subruoutine is to give an interruption and will overflow

;every  0.05 second or 50000 u second.

;and data that loadee is 65.536-50.000=15536 d = ( 3CB0h )

;B0 h loaded to TL1 and data 3C loaded to TH1

;

;Each this subroutine read,  pencacah20 will  decrement till Pencacah20=0

;this will happen every 20 X 50000 uS = 20 X 0,05s = 1 s,and then

;subrutine updatedata-stopcounter-savedatacounter

;dan resetcounter will call.

;==========================================================

Timer_Interupsi0:

        mov tl0,#0B0h

        mov th0,#03ch

        djnz Count10,EndInterupsi

        mov Count10,#20

        call UpdateData

        call StopCounter

        call SaveDataCounter

        call ResetCounter

EndInterupsi:

        reti

        ;

;=====================================================

;Subrutine Init_interupsi_timer0

;=====================================================

;This subroutine is used to initiate RAM  low byte and  RAM  high byte

;Initiate mode timer: timer 0 is  functioned as timer 16 bit mode 1

;timer 1 is functioned as counter 16 bit mode 1

;Initiate register counter TL0 dan TH0: with  data 3CB0h so  counter  will over

;flow every 0,05 second

;Initiate register counter TL1 dan TH1: with  data 0000h so  counter

;start rock and roll in start condition  0000

;Initate Timer0 Interrupt

;=====================================================

Init_interupsi_Timer0:

       mov DataRamCounterL,#30h

       mov DataRAMCounterH,#50h

       mov Count10,#20

;Initiate for counter down 10 x 0.05 = 0.5 second

       mov tl0,#0B0h

       mov th0,#03ch

       mov tl1,#00h

       mov th1,#00h

       Mov TMOD,#01010001b

;timer0 = as timer 16 bit, timer1 = as counter16 bit

       setb ET0 ; Enable timer 0 interruption

       Setb EA  ; Master Enable All Interuppt

       setb TR0 ; start rock and roll timer 0

       setb TR1 ; start rock and roll timer 1

       ret

       ;

UpdateData:

       mov NewDataL,TL1

       mov NewDataH,TH1

       ret

       ;

StopCounter:

       clr TR0

       clr TR1

       ret

       ;

;=======================================================

;Subrutine Savedatacounter

;=======================================================

;This subruoutine is to save data to register counter 16 bit TL1 and TH1

;Data register TL1 is saved in RAM with address 30h s/d 4fh

;Data register TH1 is saved in RAM with address 50h s/d 6fh

;this subroutine will be called every  timer 0 over flow each  20x 0.05 second = 1second

;after data is saved than address RAM will increment

;

;Index Transfer Data : mov @R0,Data1

;                                      mov Data2,@R0

; Example:

;         org 0h

;         mov R0,#30h

;start:mov DataADC,P2 ;gets data from ADC

;         mov @R0,DataADC ; saves data ADC in addresss 30h

;         inc R0 ; increment, R0:= R0 + 1, to save the next data

;         call delay ; next address is  31h

;         sjmp start

;======================================================

SaveDataCounter:

        mov R0,DataRamCounterL

        mov @R0,TL1

        mov R1,DataRAMCounterH

        mov @R1,TH1

        inc DataRAMCounterL

        inc DataRAMCounterH

        mov A,DataRAMCounterL

        cjne A,#50h,QuitSDC

        mov DataRamCounterL,#30h; Reset to base Address 30h

        mov DataRamCounterH,#50h; Reset to base Address 50h

QuitSDC:

        ret

        ;

ResetCounter:

        mov TL1,#0

        mov TH1,#0

        Setb TR0

        Setb TR1

        ret

        ;

ResetRAM:

        mov R1,#64

        mov R0,#30h

NextRam:mov @R0,#0

        inc R0

        djnz R1,NextRam

        ret

        ;

delay:  mov R6,#25

del1:   mov R5,#255

        djnz R5,$

        djnz R6,del1

        ret

        ;

ldelay: mov R7,#30

ldel1:  call delay

        djnz R7,ldel1

        ret

;==========================================================

; Subrutine SearchingMax ( Oleh: Triwiyanto )

;==========================================================

;This subroutine is to search data 16 bit betwen 30 data

;with metode, to compare data betwen now and next data

;RAM have capacity ony 1 byte so low byte will be saved to 30h .. 40h

;and high byte will be saved on 50h..61h

;by using the algorith from high programmming language then :

;===========================================================

;DataMax:=DataNext[0]

;for i:=1 to 30 do

;  begin

;   if DataNext[i] > DataMax then DataMax := DataNext[i]

;  end

;=======================================================

;How to detect if a data is bigger then others, is

; by using instruction SUBB A,Data and JNC Label

; for example A=19, Data=20 then  C = 1

;             A=21, Data=20 then  C = 0

;=======================================================

SearchingMax:

         mov R7,#30

;number address ram is 2 x 30 address

         mov R0,#30h

         mov R1,#50h

         mov DataCounter_MaxL,@R0

         mov DataCounter_MaxH,@R1

NextData:

         inc R0

         inc R1

         mov DataCounter_NextL,@R0

         mov DataCounter_NextH,@R1

         ;

         mov A,DataCounter_NextL

         clr C

         subb A,DataCounter_MaxL

         mov A,DataCounter_NextH

         subb A,DataCounter_MaxH

         ;

         jnc SaveDataCounterMax

         djnz R7,NextData

         Sjmp QuitS

SaveDataCounterMax:

         mov DataCounter_MaxL,DataCounter_NextL

         mov DataCounter_MaxH,DataCounter_NextH

         djnz R7,NextData

QuitS:   ret

         ;

init_lcd:

         mov R3,#dispclr

         acall write_inst

         mov R3,#funcset

         acall write_inst

         mov R3,#dispon

         acall write_inst

         mov R3,#entrmod

         acall write_inst

         ret

         ;

Write_inst:

       Clr RS         ; mode write instruction

       Mov PortLCD,R3 ; D7 s/d D0 = P0 = R1

       Setb EN        ; EN = 1 = Enable data

       Acall delay    ; calldelay time

       Clr EN         ; EN = 0

       ret

       ;

Write_data:

       Setb RS        ; mode write instruction

       Mov PortLCD,R3 ; D7 s/d D0 = P0 = R1

       Setb EN        ; EN = 1

       Acall delay    ; call delay time

       Clr EN         ; EN = 0       ret

       ;

LCD_Demo:

       mov dptr,#writeDemo; DPTR = [ writean1 ]

       mov r7,#16   ; R3=16,Number character to display

       mov r3,#080h ; R1=80h,character position row=1,col=1

       acall write_inst

;

Demo:  clr a ; A = 0

       movc a,@a+dptr ; A = [A+ DPTR]

       mov r3,A ; R1 = A

       inc dptr ; DPTR = DPTR +1

       acall write_data

       djnz r7,Demo ;R3=R3-1,jump to write1 if  R3 = 0

       ret

       ;

LCD_Flow:

       mov dptr,#writeFlow; DPTR = [ writean1 ]

       mov r7,#16 ;  R3= 16, Number character to display

       mov r3,#080h ;R1= 80h,character position row=1, col=1

       acall write_inst

Flow:  clr a ; A = 0

       movc a,@a+dptr ; A = [A+ DPTR]

       mov r3,A ; R1 = A

       inc dptr ; DPTR = DPTR +1

       acall write_data

       djnz r7,Flow ; R3 = R3-1,jump to write1 if R3=0

       ret

       ;

LCD_Search:

       mov dptr,#writeSearch; DPTR = [ writean1 ]

       mov r7,#16 ;  R3=16,Number character to display

       mov r3,#080h ;R1=80h,character position row=1,col=1

       acall write_inst

;

Search:clr a ; A = 0

       movc a,@a+dptr ; A = [A+ DPTR]

       mov r3,A ; R1 = A

       inc dptr ; DPTR = DPTR +1

       acall write_data

       djnz r7,Search ; R3 = R3-1,jump to write1 if R3=0

       ret

       ;

LCD_MaxFlow:

       mov dptr,#writeFlow; DPTR = [ writean1 ]

       mov r7,#16  ;R3=16,Number character to display

       mov r3,#0c0h;R1=80h,character position row=1, col=1

       acall write_inst

MaxFlow:

       clr a ; A = 0

       movc a,@a+dptr ; A = [A+ DPTR]

       mov r3,A ; R1 = A

       inc dptr ; DPTR = DPTR +1

       acall write_data

       djnz r7,MaxFlow ;R3=R3-1,jump to write1 if R3=0

       ret

       ;

writeDemo:

       DB 'Spirometer 89s51'

writeFlow:

       DB 'FLowR: ml/s'

writeSearch:

       DB 'Searching...Max '

       ;

      end

source: mytutorialcafe.com

Gravatar Image
Robotics Technology , Tutorial and News

Leave a Reply

Your email address will not be published. Required fields are marked *