EmbeddedRelated.com
Forums

Problems with PIC167872 sending data from sensors to computer through usb module gigatechnology usbmod2

Started by clement April 7, 2004
Hi am trying to send data from 2 sharp GP2D02 proximity sensors and 2
devantech srf04 ultrasonic sensors being controlled by a PIC16F872
through gigatechnology's usbmod2 (Serial To Usb module) to my
computer. I have given the code below that I am using but
unfortunately I cannot get it working. A very strange thing happens
when I connect a wire between VSS pin 19 and OSC2 pin 10, once I turn
on the power I pull this wire out. When I do this and check the pins
on a oscilloscope I get the correct measurements for example a 10us
trigger going to the srf04 and output from the GP2D02 going from low
to high although I do not get the correct information into the
computer. Due to this I think most of my code is correct and it may be
something very small stopping the PIC from working correctly. Please
help me if you can as I've been trying to get this working for weeks
with no success.

;	pin assignments
;	portB 0-7 = USB D0-D7 normally inputs, switched to outputs when
;				writing to usb

;	portC.7 = output USBWR normally low - pulse high to write

;	portC.6 = input USBTXF low means ok to write
;	portC.5 = output USBRD normally high - pulse low to read
;	portC.4 = input USBRXF low means ok to read

;	portC.3 = output SRF1Trigger normally low
;	portC.2 = input SRF1Echo - time high pulse following trigger
;	portC.1 = output SRF2Trigger
;	portC.0 = input SRF2Echo
;             pulse trigger hi for 10usec to start conversion
;             Echo duration 100usec to 36000usec
;             divide by 58 for millimeters or 148 for inches
;             range of 1(1.7) to 620 cm = 0(0.67) to 243 inches

;	portA.3 = output IR1Clock pulse hi 10usec to start conversion
;	portA.2 = input IR1Data - time high pulse following trigger
;	portA.1 = output IR2Clock
;	portA.0 = input IR2Data
;             drop clock low to start conversion and wait for data
;             to go high (about 70 milliseconds 
;             set clock high for 2 usec then low and read Data bit,
;             after 2usec set clock high again
;             repeat for 7 additional bits
;             end with clock high.


	list P=16F872
	#include <p16f872.inc>
;=====================
; Declaration
#define USBWR 	PORTC,7
#define USBTXF 	PORTC,6
#define USBRD 	PORTC,5
#define USBRXF 	PORTC,4

#define SRF1Trigger PORTC,3
#define SRF1Echo 	PORTC,2
#define SRF2Trigger PORTC,1
#define SRF2Echo 	PORTC,0

#define	USBData		PORTB

#define IR1Clock 	PORTA,3
#define IR1Data		PORTA,2
#define IR2Clock	PORTA,1
#define IR2Data		PORTA,0

#define LED1		PORTA,5
#define LED2		PORTA,4

		;start general purpose registers
N	equ 	0x20	;simple counter counts 1 second periods
T	equ		0x21	;counts 4 ms periods for the 1 second counter
U	equ		0x22	;stores value read from USB port
I	equ		0x23	;general purpose temp variable
J	equ		0x24	;general purpose temp varaible

	org		0x0000
	goto 	Init

	org		1ch
Init
	movlw	0x10
	movwf	T1CON		;Timer1	- prescale 1:2, oscillator disabled, internal
clock, not running,
						;set for 1 usec. rate
	clrf 	INTCON 		; Disable all interrupts and clear T0IF
	clrf	PORTA		;set all outputs low
	clrf	PORTB
	clrf	PORTC		;except...
	bsf		USBRD		;normally high
	bsf		IR1Clock	;normally high
	bsf		IR2Clock	;normally high
	bsf 	STATUS, RP0 ; Bank1
	movlw 	0xc4 		; PortB pull-ups are disabled
	movwf 	OPTION_REG 	; Interrupt on rising edge of RB0 - interrrupts
are not enabled
						; Timer0 increment from internal clock
						; with a prescaler of 1:16 - will count at 8usec rate.
						; wdt will timeout at 18msec.

	movlw	0x06
	movwf	ADCON1		;port A is all digital i/o - no a/d
	movlw	b'11000101'	;1,3,4 and 5 are outputs
	movwf	TRISA
	movlw	b'11111111'
	movwf	TRISB
	movlw	b'01010101'	;1,3,5 and 7 are outputs
	movwf	TRISC
	bcf 	STATUS, RP0 ; Bank0

	bsf		USBRD		;normally high
	bcf		USBWR		;normally low
	bsf		IR1Clock	;normally high
	bsf		IR2Clock	;normally high
	bcf		SRF1Trigger	;normally low
	bcf		SRF2Trigger	;normall low

	clrf	N	;start at 0
	clrf	T
	clrf	U
;*******************************************************************
;main program loop here

;output sequence will be 0,0,SRF1Hi,SRF1Lo,IR1,SRF2Hi,SRF2Lo,IR2,
repeat...
;can synchronize by waiting for two zero values in fast succession,
;less than 1ms apart
Loop
	movlw	0
	call	WriteUSB
	movlw	0
	call	WriteUSB

	call 	ReadSRF1	;returned in Timer1 - 1 to 36 ms
	movfw	TMR1H
	call	WriteUSB
	movfw	TMR1L
	call	WriteUSB

	call	ReadIR1		;returned in W      - 70 ms
	call	WriteUSB

	call	ReadSRF2	;returned in Timer1 - 1 to 36 ms
	movfw	TMR1H
	call	WriteUSB
	movfw	TMR1L
	call	WriteUSB

	call	ReadIR2		;returned in W      - 70 ms
	call	WriteUSB

	goto	Loop
;*******************************************************************

ReadUSB		;if USBRXF is low, read usb port to W
	btfsc	USBRXF
	goto	ReadUSBDone
	bcf		USBRD	;RD low
	nop
	nop		;pause a little
	movf	USBData,W	;data from USB
	movwf	U		;save it in U
	bsf		USBRD	;RD back to high
ReadUSBDone
	return
;*******************************************************************
WriteUSB	;if USBTXF is low, write W to usb port
	btfsc	USBTXF
	goto	WriteUSBDone ;if USBTXF is high, skip writing
	movwf	USBData	;W to data port
	bsf		STATUS,RP0
	movlw	0x00
	movwf	TRISB	;data port to output mode
	bcf		STATUS,RP0
	bsf		USBWR	;WR high
	nop				;pause just a little
	nop
	bcf		USBWR	;WR low
	bsf		STATUS,RP0
	movlw	0xff
	movwf	TRISB	;data port back to input mode
	bcf		STATUS,RP0
WriteUSBDone
	return
;*******************************************************************
			;Reads IR1 Sensor, returns value in W, takes about 70 milliseconds
			;uses temp variables I and J
;set clock low
;wait for data to go low
;set clock high then low
;read data bit - rotate bit into J
;repeat for rest of 8 bits
;set clock high
ReadIR1
	bcf		IR1Clock
	btfsc	IR1Data
	goto	$-1		;wait for IR1Data low
	
	clrwdt			;keep watch dog happy
	btfss	IR1Data
	goto	$-2		;wait for IR1Data high
	
	movlw	.8
	movwf	I		;counter for 8 bits

ReadIR1Loop
	bsf		IR1Clock	;set clock high
	nop
	nop					;pause a little
	bcf		IR1Clock	;set clock low
	nop
	nop					;pause a little
	bcf		STATUS,C	;clear carry bit
	btfsc	IR1Data
	bsf		STATUS,C	;if data is high, set carry bit
	rlf		J			;shift carry bit into J
	
	decfsz	I
	goto	ReadIR1Loop	;repeat for all 8 bits
	movfw	J
	bsf		IR1Clock	;set clock high again
	return
;*******************************************************************
ReadIR2
	bcf		IR2Clock
	btfsc	IR2Data
	goto	$-1		;wait for IR2Data low
	
	clrwdt			;keep watch dog happy
	btfss	IR2Data
	goto	$-2		;wait for IR2Data high
	
	movlw	.8
	movwf	I		;counter for 8 bits

ReadIR2Loop
	bsf		IR2Clock	;set clock high
	nop
	nop					;pause a little
	bcf		IR2Clock	;set clock low
	nop
	nop					;pause a little
	bcf		STATUS,C	;clear carry bit
	btfsc	IR2Data
	bsf		STATUS,C	;if data is high, set carry bit
	rlf		J			;shift carry bit into J
	
	decfsz	I
	goto	ReadIR2Loop	;repeat for all 8 bits
	movfw	J
	bsf		IR2Clock	;set clock high again
	return
;*******************************************************************
;set SRF1Trigger high
;wait at least 10us
;set SRF1Trigger low
;wait for SRF1Echo to go high
;time until SRF1Echo goes low (100 to 36000 usec.)
ReadSRF1
	bsf		SRF1Trigger	;set trigger high

	movlw	.7
	movwf	I
	decfsz	I
	goto	$-1			;delay 11.5 usec.

	bcf		SRF1Trigger	;set trigger low
	bcf		T1CON,0		;stop timer1
	clrf	TMR1H
	clrf	TMR1L		;and set it to zero

	clrwdt				;keep watch dog happy
	btfsc	SRF1Echo
	goto	$-2			;wait for echo low

						;echo is now high
	bsf		T1CON,0		;start timer1
	clrwdt
	btfss	SRF1Echo
	goto	$-2			;wait for echo low again

	bcf		T1CON,0		;stop timer1
						;timer1 contains echo pulse in usec.
	return
;*******************************************************************
ReadSRF2
	bsf		SRF2Trigger	;set trigger high

	movlw	.7
	movwf	I
	decfsz	I
	goto	$-1			;delay 11.5 usec.

	bcf		SRF2Trigger	;set trigger low
	bcf		T1CON,0		;stop timer1
	clrf	TMR1H
	clrf	TMR1L		;and set it to zero

	clrwdt				;keep watch dog happy
	btfsc	SRF2Echo
	goto	$-2			;wait for echo low

						;echo is now high
	bsf		T1CON,0		;start timer1
	clrwdt
	btfss	SRF2Echo
	goto	$-2			;wait for echo low again

	bcf		T1CON,0		;stop timer1
						;timer1 contains echo pulse in usec.
	return
;*******************************************************************
SetLED1	;turns LED1 on or off according to low bit of N
	btfsc	N,0
	goto	SetLED1On
SetLED1Off
	bcf		LED1
	return
SetLED1On
	bsf		LED1
	return
;*******************************************************************
SetLED2	;turns LED2 on or off according to low bit of U
	btfsc	U,0
	goto	SetLED2On
SetLED2Off
	bcf		LED2
	return
SetLED2On
	bsf		LED2
	return
;*******************************************************************

 END
<big snip>

Sounds to me like you haven't set up the config bytes for the PIC correctly.
i.e. oscillator type, reset, etc etc
Hi Clement,

As already told, it look like the config bits are wrong.
See the __CONFIG command in MPLAB help.
You'll need the datasheet of that PIC also.

May be you can tell your programmer manually to set the config bits.

HTH
Wolfgang

-- 
From-address is Spam trap
Use: wolfgang (dot) mahringer (at) sbg (dot) at

Thanks a lot you were right about the configuration bits I had not
turned brown out detect on and that was the problem. I am now
receiving information into the computer but unfortunately it does not
appear to be correct. I should first of all be receiving two zeros to
help me synchronize the data, following this 1 byte for the data from
infrared sensor 1, 2 bytes for ultrasonic sensor 1, 1 byte from
infrared sensor 2 followed by 2 bytes for ultrasonic sensor 2. I'm not
even getting the 2 zeros into the computer. If I program the PIC just
to send out a zero I get 11 (oB in hex) into the computer and for 1 I
get 31 (1F in hex). What do you think could be the problem? Could it
be a timing issue between the PIC and the USB module? Below is the
data that I am receiving at the computer with ultrasonic sensor 2
turned off as it's not working. Thanks

#31#31#63#31#31#31#63#31#31#31#31#31#31#31#31#31#31#31#31#63#31#31#31#31#31#11#31#11#31#31#31#31#31#27#31#31#31#31#31#31#31#31#31#31#31#31#31#11#31#31#31#11#63#31#11#31#31#63#31#31#11#63#63#63#63#31#11#31#31#31#31#31#31#63#31#31#31#11#11#31#31#31#31#31#11#31#31#31#31#31#31#31#31#31#31#31#31#11#31#31#63#31#63#63#31#31#31#31#31#31#31#63#63#31#31#31#31#31#31#63#11#31#63#31#63#31#31#31#31#31#31#31#31#
1#31#31#31#31#11#31#31#31#31#31#11#31#31#31#31#31#31#31#31#27#31#31#31#31#63#31#31#31#31#31#31#63#31#63#31#31#27#31#31#11#31#11#31#31#31#31#31#31#31#11#31#31#31#63#31#31#31#31#31#27#31#31#31#31#31#31#31#31#31#11#11#31#31#63#31#27#31#31#31#31#63#63#31#31#31#63#31#31#11#31#31#31#63#31#31#31#31#31#31#31#31#31#31#31#31#31#31#31#31#63#31#31#11#31#31#11#31#31#63#63#31#31#31#31#31#63#31#11#31#31#31#31#31
31#31#31#31#11#31#31#31#11#11#11#31#31#31#11#31#31#31#31#31#31#63#31#31#31#31#31#31#63#31#63#63#31#31#31#11#31#31#11#31#31#31#63#11#63#31#31#27#31#31#63#31#11#31#31#31#31#31#31#31#31#31#31#11#31#31#31#31#31#31#31
clement wrote:
> > Thanks a lot you were right about the configuration bits I had not
...snip ...
> #31#31#63#31#31#31#63#31#31#31#31#31#31#31#31#31#31#31#31#63#31#31#31#31#31#11#31#11#31#31#31#31#31#27#31#31#31#31#31#31#31#31#31#31#31#31#31#11#31#31#31#11#63#31#11#31#31#63#31#31#11#63#63#63#63#31#11#31#31#31#31#31#31#63#31#31#31#11#11#31#31#31#31#31#11#31#31#31#31#31#31#31#31#31#31#31#31#11#31#31#63#31#63#63#31#31#31#31#31#31#31#63#63#31#31#31#31#31#31#63#11#31#63#31#63#31#31#31#31#31#31#31#31#
What is this stupid nonsense? Get rid of it. -- Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net) Available for consulting/temporary embedded and systems. <http://cbfalconer.home.att.net> USE worldnet address!