Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

IR airplane equipment test help

Status
Not open for further replies.

jeremygaughan

New Member
Hi again, I am still building this infrared airplane system. I have a code here to test to see if my equipment is working properly, but it's not. The transmitter sends the 38khz and the receiver picks it up. My problem is that the receiver is supposed to keep the led on whenever it receives a 38khz pulse. It flashes every time I hit the switch but won't stay on when I leave the switch pressed. here are my codes. Can anyone see a logic flaw in my programs that would cause this to be happening.

(it has adc in the real code this is just a on off deal to test the equipment)
Code:
;1 channel transmitter using IR and ADC on a 12f675


	list P=12f675
#include <p12f675.inc>
	__config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF 
	ERRORLEVEL -302
	
	cblock		20h
	counterslow, counterslow2, counterfast, counterfast2, counterslow3, counterslow4, counterfast3, counterfast4
	endc
	
	bsf	STATUS,RP0		;bank 1
	movlw	0x00
	movwf	ANSEL
	movlw	0x30
	movwf	TRISIO		;set I/O
	bcf	STATUS,RP0
	movlw	0x07		;turn off comparitors
	movwf	CMCON

start
	btfsc	GPIO,5
	goto	$-1
	call	IRpulse
	goto	start


IRpulse	
	BSF		GPIO,0		;27 commands makes 38khz
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	BCF		GPIO,0
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	return

	end

Code:
;1 channel receiver using IR and ADC on a 12f675


	list P=12f675
#include <p12f675.inc>
	__config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF 
	ERRORLEVEL -302
	
	cblock		20h
	pulseontime, pulsegap, pwmhighcounter, pwmlowcounter, pwmtimer
	endc
	
	bsf	STATUS,RP0		;bank 1
	movlw	0x00
	movwf	ANSEL
	movlw	0x08
	movwf	TRISIO		;set I/O
	bcf	STATUS,RP0
	movlw	0x07		;turn off comparitors
	movwf	CMCON

start
	bcf		GPIO,0
	btfsc	GPIO,3
	goto	$-1
	bsf		GPIO,0
	bsf		GPIO,4
	bsf		GPIO,5
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	start

	end
 
Here's a pretty rough drawing of my set up
 

Attachments

  • IR system.JPG
    IR system.JPG
    24.3 KB · Views: 248
I stole it from an old VCR, I don't know what it is. The only thing it has on it is CS stamped on the back. I have another one that I will try from a mini helicopter.
 
Hook the output of the IR detector to your PICkit2 and use the Logic Analyzer, you can then see exactly what the PIC sees when you hit the transmit button.
 
Most IR receivers have automatic-gain-control. They expect to see data, not continuous 38kHz interference from a compact fluorescent light bulb.

Data is sent in bursts of 10 to 70 cycles of 38kHz pulses.
There should be a gap of at least 14 cycles of 38khz between bursts.

If these rules are not followed then the AGC reduces the gain to avoid interference.

Your IR receiver sees the 38kHz and turns on your LED. Then it doesn't get bursts and doesn't get gaps then it reduces the gain so that it doesn't respond anymore and turns off your LED.
 
Audio, that solved it! thanks for the knowledge.
blueroom, that is the tool I've been waiting for, now I can problem solve my IR code. It's like having a mini oscilloscope. I'll post the first one channel IR indoor airplane control when I get the bugs out of the code. Thanks again
 
Hi jeremygaughan try my code it will allow you to turn on the output while you press & hold your transmitter button.

Code:
start		btfss	GPIO,3		;Is IR pulse coming?
		goto	Do_Output	;yes,Pulse coming
		
		decfsz	Count,F		;no,Pulse read as zero
		goto	start
		movlw	XX		;delay has expired
		movwf	Count		
		bcf	GPIO,0		;turn off output
		goto	Start
	
		
Do_Output	bsf	GPIO,0		;turn on output
		goto	start

The delay value must greater than your time intervals.
 
Last edited:
Your right it's a 4k7. Actually, I got it working well as far as testing the equipment is concerned, and now I'm trying to send a pulse then read the time until the next pulse starts, then use that in a PWM for dimming an led or and in the end speeding up a motor. The transmitter sends a pulse then makes a delay based upon an adc reading. Then another pulse to tell the receiver to stop counting. So far it's not working but I'm still trying. Here it is, it's in it's first stages but if you got any ideas I could use the help.

Code:
;1 channel transmitter using IR and ADC on a 12f675


	list P=12f675
#include <p12f675.inc>
	__config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF 
	ERRORLEVEL -302
	
	cblock		20h
	pulseontime, pulsegaptime, pulsegaptime1, leadpause
	endc
	
	bsf	STATUS,RP0		;bank 1
	movlw	0x34
	movwf	ANSEL
	movlw	0x04
	movwf	TRISIO		;set I/O
	bcf	STATUS,RP0
	
	movlw	0x07		;turn off comparitors
	movwf	CMCON

	movlw	0x09
	movwf	ADCON0

start
	call	startadc
	call	IR
	call	pulsegappause
	call	IR
	call	pulsegappause
	call	IR
	call	pulsegappause
	call	IR
	call	pulsegappause
	call	IR
	call	pulsegappause
	call	IR
	goto	start
	
startadc
	bsf		ADCON0,1

waiting
	btfsc	ADCON0,1
	goto	waiting
	movf	ADRESH,0
	movwf	pulsegaptime1
	return

IR
	movlw	0x1e
	movwf	pulseontime	;send 30 cycles of pulse

IRpulse	
	BSF		GPIO,0		;27 commands makes 38khz
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	BCF		GPIO,0
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	pulseontime,1
	goto	IRpulse
	movf	pulsegaptime1,0	;set pulse gap value
	movwf	pulsegaptime
	return

pulsegappause
	movlw	0x0e
	movwf	leadpause

pulsegap					;lead pause to make sure a 0 at lease waits a while
	nop
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	leadpause,1
	goto	pulsegap

pause						;pulse gap to be counted by receiver
	nop
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	pulsegaptime,1
	goto	pause
	return

	end

Code:
;1 channel receiver using IR and ADC on a 12f675


	list P=12f675
#include <p12f675.inc>
	__config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF 
	ERRORLEVEL -302
	
	cblock		20h
	pause, pulseontime, pulsegap, pwmhighcounter, pwmlowcounter, pwmtimer
	endc
	
	bsf	STATUS,RP0		;bank 1
	movlw	0x00
	movwf	ANSEL
	movlw	0x08
	movwf	TRISIO		;set I/O
	bcf	STATUS,RP0
	movlw	0x07		;turn off comparitors
	movwf	CMCON

start
	call	readpulsegap
	call	pwm
	goto	start

pwm
	movf	pulsegap,0
	movwf	pwmhighcounter
	movwf	pwmlowcounter
	movlw	0x22
	movwf	pwmtimer

pwmhigh
	bsf		GPIO,1
	bsf		GPIO,0
	decfsz	pwmhighcounter,1
	goto	$-1

pwmlow
	bcf		GPIO,1
	bcf		GPIO,0
	incfsz	pwmlowcounter,1	
	goto	$-1
	decfsz	pwmtimer,1
	goto	pwm
	return

readpulsegap
	clrf	pulsegap
	btfsc	GPIO,3
	goto	$-1
	nop
	nop
	nop
	nop

wait
	btfss	GPIO,3
	goto	$-1
	movlw	0x0f
	movwf	pause

leadpause
	nop
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	pause,1
	goto	leadpause

wait2
	btfsc	GPIO,3
	goto	$+1
	goto	$+1
	goto	$+1
	incf	pulsegap,1
	goto	wait2
	return

	end
 
Cant you send the pulsegaptime1 along with the IRpulse routine?

I mean if AD reads the value 10, the pulsegaptime1 value will be 10.Now do the IR (38khz) routine 10 times (decrement via a loop).

So from the receiver side count the number of times the IRpulse has done.

Is it ok with that method?
 
I thought about that before. The problem is that I would have to sacrifice either time or resolution. However I should test the motor I'm using to see how much resolution it needs anyway. I think other people are only using 16 points. I don't think that wouldn't be too slow. But then again that would involve changing the 256 ADC values into smaller pieces because the IR receptor can have a max of only 70 pulses. When I'm back from work I'll rework the program.
 
thanks for all the help. finally it works!!!! Using the logic tool suggested by Blueroom I found the bugs in the program. Granted it's probably the roughest IR out there it still works. The next step is to put the ADC acquisition and IR reception in interrupt routines so the main programs can run more smoothly. I'm thinking timer1 to give about 4 times a second acquisitions and receptions. Here are the rough drafts.
These programs run a single motor airplane. The plane goes up with more throttle and down with less while always going in a circle because a little permanent left rudder.

transmitter
Code:
;1 channel transmitter using IR and ADC on a 12f675


	list P=12f675
#include <p12f675.inc>
	__config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF 
	ERRORLEVEL -302
	
	cblock		20h
	irpulse, datagap, min, trimpwm, trimpwm2, pwmcounter
	endc
	
	bsf	STATUS,RP0		;bank 1
	movlw	0x34
	movwf	ANSEL
	movlw	0x1c
	movwf	TRISIO		;set I/O
	bcf	STATUS,RP0
	movlw	0x07		;turn off comparitors
	movwf	CMCON
	movlw	0x09
	movwf	ADCON0

start
	btfss	GPIO,3
	call	trim
	call	adc
	call	IRpulse
	call	data1
	call	IRpulse
	call	data1
	call	IRpulse
	call	data1
	call	IRpulse
	call	data1
	call	IRpulse
	call	data1
	call	IRpulse
	call	data1
	call	IRpulse
	call	data1
	call	IRpulse
	call	data1
	call	IRpulse
	goto	start

adc
	bsf		ADCON0,1

waiting
	btfsc	ADCON0,1
	goto	waiting
	return

IRpulse	
	movlw	0x0f
	movwf	min
	movlw	0x1e
	movwf	irpulse

IRpulse2
	BSF		GPIO,1		;27 commands makes 38khz
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	BCF		GPIO,1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	irpulse,1
	goto	IRpulse2

minpause
	NOP					;27 commands makes 38khz
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	NOP
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	min,1
	goto	minpause
	return

data1
	movf	ADRESH,0
	movwf	datagap
data2
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	datagap,1
	goto	data2
	return

trim
	call	adc
	movlw	0x20
	movwf	pwmcounter

pwmstart
	movf	ADRESH,0
	movwf	trimpwm
	movwf	trimpwm2

pwm
	bsf		GPIO,5
	decfsz	trimpwm,1
	goto	$-1
	bcf		GPIO,5
	incfsz	trimpwm2,1
	goto	$-1
	decfsz	pwmcounter,1
	goto	pwmstart
	btfss	GPIO,3
	goto	trim
	return
	end

receiver

Code:
;1 channel receiver using IR and ADC on a 12f675


	list P=12f675
#include <p12f675.inc>
	__config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF 
	ERRORLEVEL -302
	
	cblock		20h
	pause, pulseontime, pulsegap, pwmhighcounter, pwmlowcounter, pwmtimer
	endc
	
	bsf	STATUS,RP0		;bank 1
	movlw	0x00
	movwf	ANSEL
	movlw	0x08
	movwf	TRISIO		;set I/O
	bcf	STATUS,RP0
	movlw	0x07		;turn off comparitors
	movwf	CMCON

start
	call	readpulsegap
	call	pwm
	call	pwm
	goto	start

pwm
	movlw	0x22
	movwf	pwmtimer
pwm2
	movf	pulsegap,0
	movwf	pwmhighcounter
	movwf	pwmlowcounter

pwmhigh
	bsf		GPIO,1
	bsf		GPIO,0
	decfsz	pwmhighcounter,1
	goto	$-1

pwmlow
	bcf		GPIO,1
	incfsz	pwmlowcounter,1	
	goto	$-1
	decfsz	pwmtimer,1
	goto	pwm2
	return

readpulsegap
	clrf	pulsegap
	btfsc	GPIO,3
	goto	$-1
	nop
	nop
	nop

wait
	btfss	GPIO,3
	goto	$-1
	movlw	0x0f
	movwf	pause

leadpause
	NOP					;27 commands makes 38khz
	goto	$+1
	NOP
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	pause,1
	goto	leadpause

wait2
	btfss	GPIO,3
	return
	nop
	nop
	nop
	nop
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	incf	pulsegap,1
	goto	wait2


	end

edit: this code has been polished and a switch added to the transmitter on GPIO 3 so the ADC can be adjusted by a potentiometer. If you push the switch a led on GPIO 5 will fade with the movement of the ADC
 
Last edited:
So you are sending fix IR pulses along with the AD values?

Code:
	call	IRpulse
	call	data1
	call	IRpulse
	call	data1

The data1 routine contains your data but its time is adding to the low part (minpause) of your IR routine is it?

Its ok its happening the last cycle in the min variable.

I just read your Transmitting part & trying to understand your receiving section.
 
Last edited:
I should have put some notes out to the side of the program. When I fix it later I'll write a lot of side notes. Here's my logic
transmitter:
Do ADC. Send a fixed IR signal followed by a minimum gap for whenever you send a value close to zero. (if not the IR receiver will turn up the gain and stop receiving)
wait an amount of time based on the ADC, then send another IRpulse to tell the receiver to stop counting.

receiver:
listen for the IR receptor to drive the pin low, wait for pin to be high again and start counting. First count the minimum gap time, then start counting the value to be used in the main program. When the pin is driven low again stop counting. Do PWM.

So I hope that helps this to be clearer. Now I'm doing two channels...send a pulse then data1 then a pulse then data2 then a pulse.....but now I need some kind of really long pulse to lead the data to let the receiver know to start counting data1 then data2.
 
Hi jeremy are you with me?

Yes I think you are with me.I have written a code for you specially the transmitter part.But I haven't checked it yet.

I'm sending a data packet through IR LED.Don't know whether you like it or not but I have to do.Just go through it.

Code:
GP0=button (active low)
GP1=IR TX LED

;*************************************
;Che_But - sends one packet at a time
;*************************************

Che_But	btfss	GPIO,GP0	;has the button pressed?
	goto	$+2		;yes,
	goto	Che_But		;no,then wait until press
	call	Transmit	;transmit the packet
	btfss	GPIO,GP0	;button still pressed?
	goto	$-1		;yes,
	goto	Che_But		;no,has released,

;********************************************************
;Transmit - routine sends data in the packet (brightness)
;********************************************************

Transmit
	call	Check_AD
	movlw	.8
	movwf	Counter		;makes counter for 8 bit
Loop3	bcf	STATUS,C
	rlf	Brightness,F
	btfss	STATUS,C
	goto	Do_Zero
	goto	Do_Ones

Do_Ones	movlw	d'22'
	movwf	Highpulse	;makes 600uS high time
	goto	$+3
Do_Zero	movlw	d'12'		;makes 300 + low time
	movwf	Highpulse
	call	Do_Logic	;transfer the logic
	call	Do_Gap		;transfer fix gap time
	decfsz	Counter,F	;repeat for other bits
	goto	Loop3
	return

;**************************************
;Check_AD returns the brightness value
;**************************************

Check_AD
	bsf	ADCON0,GO
	btfsc	ADCON0,GO
	goto	$-1
	movf	ADRESH,W
	movwf	Brightness	;brightness contains dim level
	return

;********************************************
;Do_Logic - logic high time > logic low time
;********************************************

Do_Logic
Loop1	BSF	GPIO,1		;27 commands makes 38khz
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	BCF	GPIO,1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	Highpulse,F
	goto	Loop1
	return

;*****************************************
;Do_Gap - a fix gap time min 300us needed
;*****************************************

Do_Gap
	movlw	D'12'		;makes a fix gap after burst = 300uS
	movwf	Lowpulse		
Loop2	nop			;27 commands makes 38khz
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	nop
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	Lowpulse,F
	goto	Loop2
	return
 
very nice. I like the roll folder left to transmit exactly the value you want. Looks like a good way to get a precise number. I'm just counting the gap, whereas you are sending the 8 bit number one bit at a time. One thing I see is that you need to send a unique pulse before the whole thing so the receiver knows that it's the beginning of the packet being sent. I see that you have the button so that it only sends one packet at a time, but if it catches it in the middle or gets the first bit of interference from a light in the house it will be out of sequence. I'm crazy busy at work lately, but I'm going to build your code and try it when I get a moment. Also, I've almost got my two channel code going. Big long IR pulse to mark the start of the packet then gap, small pulse, gap, small pulse. Then I'm going to use a lightened micro servo to turn it. Soon I'll have control of this foam, pager motor pulling, scotch tape, toothpick braced junker.
 
jeremygaughan said:
but I'm going to build your code and try it when I get a moment. Also, I've almost got my two channel code going. Big long IR pulse to mark the start of the packet then gap, small pulse, gap, small pulse.

Oh you have stolen my packet transferring codes:D

A similar technic that I used in my IR projects.Thats a clever technic.So you no need to worry about the resolution or time takes to transfer.

8 bit resolution is more than enouth to dim a LED smoothly or to speed control a DC motor.
 
IR with interrupts

it's been a while since I could work on this, but now it works pretty well. It was really difficult to figure out the pwm to run two motors with varying speeds at the same time. Maybe there is a better way that someone knows. Please feel free to criticize if you know about that. The problem I'm having now is that the motor pulses about 5 times per second. Which as far as I can tell doesn't coincide with my interrupt timing. Right now that is my biggest problem, Any ideas?

The goal eventually with the second channel is to run an actuator. I only know a little about them so it's going to be a while before I figure them out. Here are the codes for the transmitter and the receiver. The receiver is 12f629 because I only had one 12f675 in my collection. It doesn't need to do adc so I went with it on the receiver. Cool thing is it runs with the 12f675's code so I didn't have to do anything to it. There is some redundancy that can be removed from the code and I'm on that right now, but I'm really interested in making it stop pulsing the motor.

Code:
;1 channel receiver using IR and ADC on a 12f629


	list P=12f629
#include <p12f629.inc>
	__config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF 
	ERRORLEVEL -302
	
	cblock		20h
	longpulse, pause, pulseontime, pulsegap, pulsegap2, pwmhighcounter, pwmlowcounter, pwmhighcounter2, pwmlowcounter2, pwmtimer
	endc

	ORG		0000h
	goto	start1
	
	ORG		0004h
	call	readpulsegap
	BCF		PIR1,0
	RETFIE
	

start1
	bsf		STATUS,RP0		;bank 1
	movlw	0x08
	movwf	TRISIO		;set I/O
	BSF		PIE1,0		;something for interrupts
	bcf		STATUS,RP0
	movlw	0x07		;turn off comparitors
	movwf	CMCON
	movlw	0xc0
	movwf	INTCON		;set interrupt time
	movlw	0x21
	movwf	T1CON

start
	call	pwm			;runs motor the whole time while waiting for the interrupt
	call	pwm			;that will read the IR signal
	call	pwm
	call	pwm
	call	pwm
	call	pwm
	goto	start

pwm
	movlw	0xff		;sets the length of pwm interval
	movwf	pwmtimer	
pwm2
	movf	pulsegap,0	;takes the pulse gap read in the interrupt and puts in in the pwm counter
	movwf	pwmhighcounter
	movf	pulsegap2,0
	movwf	pwmhighcounter2

pwmrun
	bsf		GPIO,1		;turn pwm on 
	bsf		GPIO,0
	decfsz	pwmhighcounter,1
	goto	$+2			;count dowm channel 1 if still counting skip turning it off
	bcf		GPIO,1		;if done counting turn off channel 1
	decfsz	pwmhighcounter2,1
	goto	$+2			;count down channel 2 if still counting skip turning it off
	bcf		GPIO,0		;if done counting turn off channel2
	decfsz	pwmtimer,1	;count down rest of time to make 256 cycles total
	goto	pwmrun
	return

readpulsegap			;start reading pulse gap
	clrf	pulsegap
	movlw	0x28		;sets value that counts IR pulse length that makes sure the 
	movwf	longpulse	;pulse length is the long one that signals start of data

readpulsegap1
	goto	$+1			;wait at least 29 commands
	goto	$+1
	goto	$+1
	goto	$+1	
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	btfsc	GPIO,3		;keep testing the IR reveiver to make sure it is constantly reading a pulse
	goto	readpulsegap;if the pulse isn't long enough start counting the next pulse
	decfsz	longpulse,1
	goto	readpulsegap1

wait
	btfss	GPIO,3		;wait for pulse to stop being sent
	goto	$-1
	movlw	0x0e
	movwf	pause

leadpause
	NOP					;27 commands makes 38khz
	goto	$+1			;count off minimum pause
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	NOP
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	pause,1
	goto	leadpause

wait2
	btfss	GPIO,3		;if still no pulse then start counting the length of the pulse gap
	goto	betweenchannels
	goto	$+1			;keep counting until pulse starts again
	goto	$+1
	goto	$+1			;goto commands used to recompress the long pause into an 8 bit number
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	incf	pulsegap,1
	goto	wait2

betweenchannels			;wait until pulse stops to continue
	btfss	GPIO,3
	goto	$-1
	nop 
	nop

wait3					;count second pulse same as counting the first pulse
	btfss	GPIO,3
	return
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	incf	pulsegap2,1
	goto	wait3
	return

	end

Code:
;1 channel transmitter using IR and ADC on a 12f675


	list P=12f675
#include <p12f675.inc>
	__config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF 
	ERRORLEVEL -302
	
	cblock		20h
	datauno, datados, temp, irpulse, datagap, datagap2, min, trimpwm, trimpwm2, pwmcounter
	endc

	ORG		0000h
	goto	start1
	
	ORG		0004h	
	call	adc
	BCF		PIR1,0
	RETFIE

start1	
	bsf	STATUS,RP0		;bank 1
	movlw	0x34
	movwf	ANSEL
	movlw	0x1c
	movwf	TRISIO		;set I/O
	BSF		PIE1,0
	bcf	STATUS,RP0
	movlw	0x07		;turn off comparitors
	movwf	CMCON
	movlw	0x09
	movwf	ADCON0		;set to read first pot of controller
	movlw	0xc0
	movwf	INTCON		;set interrupt timers
	movlw	0x21
	movwf	T1CON		;set interrupt timers
	call	adc			

start
	btfss	GPIO,3		;check if test button is pushed
	call	trim
	call	leadIRpulse	;send long pulse to let receiver know code is starting
	call	data1		;make a gap in the pulse to be counted by receiver for channel 1
	call	IRpulse		;send normal length pulse to to tell receiver data for first channel has ended
	call	data2		;make a gap in the pulse to be counted by receiver for channel 2
	call	leadIRpulse	;tells receiver that data for the second channel has ended and new data is coming
	call	data1		;repeats same stuff as before
	call	IRpulse
	call	data2
	call 	leadIRpulse
	call	data1
	call	IRpulse
	call	data2
	call	IRpulse		;send normal pulse this time to only tell the receiver that data for channel 2 has ended
	goto	start

adc
	movlw	0x09		;set to read channel 1 potentiometer
	movwf	ADCON0
	bsf		ADCON0,1	;start adc
waiting
	btfsc	ADCON0,1	;wait for adc to finish
	goto	waiting
	movf	ADRESH,0	;move adc reading to a file to use later
	movwf	datauno

	goto	$+1			;give time to let adc charge for channel 2
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1

	movlw	0x0d		;change to read channel 2 potentiometer
	movwf	ADCON0
	bsf	ADCON0,1

waiting2
	btfsc	ADCON0,1	;waiting for adc
	goto	waiting2
	movf	ADRESH,0
	movwf	datados		;move data to second channel 
	return

IRpulse					;set value for length of minimum gap time
	movlw	0x0f		;this way there is always a gap even if the 
	movwf	min			;data being sent is zero
	movlw	0x1e		;set time for the IR pulse length
	movwf	irpulse

IRpulse2
	BSF		GPIO,1		;27 commands makes aprox. 38khz
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	BCF		GPIO,1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	irpulse,1	;count down pulse length
	goto	IRpulse2

minpause
	NOP					;27 commands makes 38khz
	goto	$+1			;this is the pause that precedes every data pause or pulse gap
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	NOP
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	min,1		;count down minimum gap time
	goto	minpause	
	return

leadIRpulse				;set length of unique lead IR pulse to let receiver know that
	movlw	0x0f		;the data is about to start
	movwf	min	
	movlw	0x28
	movwf	irpulse

leadIRpulse2
	BSF		GPIO,1		;27 commands makes aprox. 38khz
	goto	$+1			;same IR pulse deal as before
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	BCF		GPIO,1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	irpulse,1
	goto	leadIRpulse2

minpause2
	NOP					;27 commands makes 38khz
	goto	$+1			;same minimum gap deal as before
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	NOP
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	min,1
	goto	minpause2
	return

data1					
	movf	datauno,0	;move the adc information from the channel one potentiometer to
	movwf	datagap		;a counter to send the gap between pulses which will be counted by the receiver
dataa
	goto	$+1			;goto commands used to make gap much longer than just the 8 bit adc value would
	goto	$+1			;if it were counted down by it self
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	datagap,1	
	goto	dataa
	return

data2
	movf	datados,0	;data gap being sent for channel 2
	movwf	datagap2
datab
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	datagap2,1
	goto	datab
	return

trim					;there is a switch in the circut that can be pushed to allow
	call	adc			;the adc to be trimed using extra 5k pots
	movlw	0x20		;note only trims channel one
	movwf	pwmcounter

pwmstart
	movf	datauno,0
	movwf	trimpwm
	movwf	trimpwm2

pwm
	bsf		GPIO,5
	decfsz	trimpwm,1
	goto	$-1
	bcf		GPIO,5
	incfsz	trimpwm2,1
	goto	$-1
	decfsz	pwmcounter,1
	goto	pwmstart
	btfss	GPIO,3
	goto	trim
	return
	end
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top