I said in my previous post there is probably a more elegant way to write this code. I used a combination of shiftin and shiftout along with some bit setting and reduced the number of lines of code compared to my previous post.
Feel free to contact me if you have any questions.
This code works for the MLX90614:
'************************************************* ***************
'* Name : MLX90614_shifts.BAS
'* Author : Tom Baraniak
[email protected]
'* Notice : Copyright (c) 2015 [select VIEW...EDITOR OPTIONS]
'* : All Rights Reserved
'* Date : 4/5/2015
'* Version : 1.0
'* Notes :
'* :
'************************************************* ***************
'
' MLX90614 test using PIC16F688 at 8MHz
'
' DOES WORK!!!
'
DEFINE OSC 8 '8 MHz clock frequency, others not supported by PBP
define HSER_RCSTA 90h 'enable the serial port receiver
define HSER_TXSTA 24h 'set up the serial port, enable transmit for fast clock
define HSER_BAUD 9600 'select the baud rate, run slow for the RF xmitter
define HSER_CLROERR 1 'automatically clear the buffer overrun error
DEFINE SHIFT_PAUSEUS 20 'slow down the shift in clock
reg var word
addr var byte
templo var byte
temphi var byte
temp var byte[3]
TLOW var byte
THI var byte
sa var byte
sb var byte
sc var byte
sd var byte
tir var word
j var byte
command var byte
ACK var byte
tout var word
TEMPIR var word
SDA var portc.2
SCL var portc.1
TxD var portc.4 'transmitted data - hardware serial port
RxD var portc.5 'received data
CMCON0 = %00000111 'comparator off
OSCCON = %01110111 'runs at 8 MHz internal clock
ADCON0 = %10000000 'ADC is disabled
ANSEL = %00000000 'all digital
TRISA = %11111111 'set up port A where 1 = input, 0 = output
TRISC = %11101001 'set up port C where 1 = input, 0 = output
'================================================= ================================================== =======================================
'
'
' IR GROUND TEMPERATURE SENSOR
'
' The RAM address 0x07 contains the linearied object temperature data, low byte first
' The slave address that is the MLX90614 is 0xB4
'
'
sda = 1 'at the start
scl = 1
pause 1000
luup:
hserin 1000, luup, [command] 'used for testing, not part of the actual MLX code
if command = "B" then
call bitbang
endif
goto luup
'================================================= ================================================== =======================================
bitbang:
SDA = 0 'start
call wate
SCL = 0 'clock idles low
call wate
reg = $07
addr = $B4 'B4 sets W = 0 too
shiftout sda, scl, 1, [addr] 'shift the address B4, 8 bits where LSB is W = 0
'clock idles low mode!!
input sda 'make sda an input for acknowledge A
call wate
scl = 1
call wate
scl = 0
call wate
output sda 'make sda an output again for 07
shiftout sda, scl, 1, [reg] 'register is 07, clock idles low
input sda 'make sda an input for acknowledge A
call wate
scl = 1
call wate
scl = 0
call wate
output sda 'make sda an output again for S
call wate
sda = 1
call wate
scl = 1
call wate
sda = 0
call wate
scl = 0
call wate
addr = $B5
shiftout sda, scl, 1, [addr] 'shift the address B5, 8 bits where LSB is R = 1, clock idles low
call wate
input sda 'make sda an input for acknowledge A part of sequence. It remains an input heading into shiftin
call wate
scl = 1
call wate
scl = 0
call wate
shiftin SDA, SCL, 0, [TLOW, ack\1, thi] 'Now we can use the shiftin command to read the 8 least significant bits, the single acknowledge
'bit, and the 8 most significant bits. clock idles low
tempir = thi * $100 'shifts 8 bits to the left to move this byte to the upper 8 bits of a word
tempir = tempir + tlow 'add the lower byte to the upper byte to make a word
tout = tempir/50 'each bit is .02 degrees K so either multiply by .02 or divide by 50
tout = tout - 273 'subtract 273.15 (to get temperature in degrees C
hserout ["T = ", 9, dec tout, 9, dec tempir, 9, dec THI, 9, dec TLOW, 13]
pause 1000
trisc.1 = 0 'both sda and scl are outputs
trisc.2 = 0
sda = 1 'they both start high
scl = 1
pause 100
return
'================================================= ================================================== =======================================
wate:
pauseus 15 'use a subroutine for the 15 usec dealy - less compiled code
return
end