Serielle Schnittste für UT70A           

 von Arne Rossius                        
Elektronik-Labor  Projekte   AVR   T13-Contest

 

Eine serielle Schnittstelle fuer das Multimeter "UT70A" von Uni-T (zu bekommen bei Pollin für 35 Eur).  Der im Multimeter verwendete Chip des Typs CJ7108F (anscheinend kompatibel zum SH7108F, Datenblatt: http://www.datasheetarchive.com/SH7108F-datasheet.html) bietet eine SPI-ähnliche Schnittstelle an, um die Messwerte auszulesen. Sie ist im Multimeter ungenutzt, also habe ich dort einen ATtiny13 angeschlossen, welcher die Daten nach jeder Messung (ca. 3x pro Sekunde) einliest und per RS232 mit 9600 Baud z.B. an einen PC sendet. Glücklicherweise lässt sich sogar die Position des Dezimalpunkts auslesen, so dass den Daten nur noch die Einheit fehlt ;-). Der ATtiny13 wird mit 40kHz getaktet, da dieser Takt im Multimeter vorhanden ist und der interne Oszillator des Tiny13 nicht genau genug für eine RS232-Uebertragung ist.



Die serielle Schnittstelle ist galvanisch getrennt vom Multimeter, so dass trotz Verbindung zum PC auch an anderen Potentialen und sogar Netzspannung gemessen werden kann. Dabei ist natürlich zu beachten, dass die Verbindungen zur seriellen Schnittstelle innerhalb des Multimeters ausreichend gut isoliert sind. Ich habe unten im Multimeter einen Schlitz gefeilt und dort eine 4-polige Buchsenleiste eingeklebt, so dass man bei Bedarf von außen ein Kabel zur seriellen Schnittstelle einstecken kann. Anstelle der RS232-Schnittstelle kann man mit einem FT232 natürlich auch einfach eine USB-Schnittstelle realisieren. Der Optokoppler muss dann nicht-invertierend geschaltet werden (LED zwischen PB2 und Masse), die Stromversorgung des Optokopplers wird auch einfacher, die Z-Diode und die Vorwiderstände können wegfallen. Derzeit wird Pin 3 (TxD) als negative und Pin 7 (RTS) als positive Versorgungsspannung verwendet, die Z-Diode begrenzt die Betriebsspannung des Optokopplers auf unter 20V. An der USB-Schnittstelle wird TxD durch Masse und RTS durch +5V ersetzt.



Der Controller verbringt die meiste Zeit im Schlafmodus und verbraucht natürlich dank der niedrigen Taktfrequenz auch im Wachzustand nur wenig Strom. Der größte Verbraucher ist die LED des Optokopplers, die aber so wie gezeigt nur während des Sendens mal leuchtet. Insgesamt steigt die Stromaufnahme des Multimeters durch die Tiny13-Schaltung also nur sehr geringfügig. Wird die LED für den Betrieb mit einem FT232 wie oben beschrieben anders angeschlossen, leuchtet sie dauerhaft, wenn nicht gesendet wird und erhöht den Stromverbrauch dann deutlich. Ggf. ist es sinnvoller, die LED zu lassen wie sie eingezeichnet ist und einen invertierenden Optokoppler zu verwenden (z.B. H11L1 mit 270 Ohm Pull-up am Ausgang) oder einen zusätzlichen Inverter zwischen Optokoppler und FT232 einzubauen.


Download: UT70A.zip


;RS232 Data Output for 3,5-digit LCD digital multimeters
;ATtiny13 @ 40 kHz (external clock from multimeter), lfuse=0x78, hfuse=0xFF
;This version is compatible with these multimeters:
; Manufacturer | Type | Multimeter Chip
; ----------------------+------------+-------------------
; Uni-Trend | UT70A | CJ7108F = SH7108F
;
;PORTS:
; Pin Port Function
; 1 (PB5) #RESET
; 2 (PB3) 40 kHz input
; 3 PB4 Conversion Complete input (from SH7108F Pin 39 [EOC])
; 4 GND
; 5 PB0 SPI Clock output (to SH7108F Pin 36 [CLK])
; 6 PB1 SPI Data input (from SH7108F Pin 37 [SDO])
; 7 PB2 RS232 Tx output (idle = high)
; 8 V_CC = +5V
;
;VERSIONS
; 2012-12-16 Arne Rossius
; * first version

.include "tn13def.inc"

.def temp = R16
.def temp2 = R17
.def count = R18
.def uart_space = R19
.def uart_mark = R20
.def dataL = R21
.def dataH = R22
.def dp = R23

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

.org 0x000
rjmp reset

.org PCI0addr
reti

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

reset:
;set stackpointer
ldi temp, RAMEND
out SPL, temp

;init ports
ldi temp, 0x05
out DDRB, temp
ldi temp, 0x04
out PORTB, temp

;disable analog comparator
ldi temp, 1<<ACD
out ACSR, temp

;init pin change interrupt (for wake-up on conversion complete)
ldi temp, 0x10 ;select PB4 for pin change interrupt
out PCMSK, temp
ldi temp, 1<<PCIE ;enable pin change interrupt
out GIMSK, temp
sei ;enable interrupts

;init registers
ldi uart_mark, 0x04 ;UART line idle
ldi uart_space, 0x00 ;UART line active

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

loop:
;sleep (power-down mode)
ldi temp, 1<<SE | 1<<SM1
out MCUCR, temp
sleep

;check if "conversion complete" is high
sbis PINB, 4
rjmp loop

;read data from SPI
ldi count, 16
spi_read:
sbi PORTB, 0
lsl dataL
rol dataH
sbic PINB, 1
ori dataL, 0x01
cbi PORTB, 0
dec count
brne spi_read

;convert and output data
mov temp, dataH
andi temp, 0x7C
cpi temp, 0x7C
breq loop ;no data yet
cpi temp, 0x70
breq overflow ;positive or negative overflow
;find dp
mov dp, dataL
andi dp, 0x03
;align data
lsr dataH
ror dataL
lsr dataH
ror dataL
;sign
ldi temp, '-'
sbrc dataH, 5
ldi temp, '+'
;first digit (MSB)
rcall putc
ldi temp, '0'
sbrc dataH, 4
ldi temp, '1'
rcall putc
;dp3
ldi temp, '.'
cpi dp, 3
brne PC+2
rcall putc
;second digit (3rd LSD)
mov temp, dataH
andi temp, 0x0F
ori temp, 0x30
rcall putc
;dp2
ldi temp, '.'
cpi dp, 2
brne PC+2
rcall putc
;third digit (2nd LSD)
mov temp, dataL
swap temp
andi temp, 0x0F
ori temp, 0x30
rcall putc
;dp1
ldi temp, '.'
cpi dp, 1
brne PC+2
rcall putc
;fourth digit (LSD)
mov temp, dataL
andi temp, 0x0F
ori temp, 0x30
rcall putc
newline:
ldi temp, 0x0d
rcall putc
ldi temp, 0x0a
rcall putc
rjmp loop

overflow:
ldi temp, 'O'
rcall putc
ldi temp, 'v'
rcall putc
ldi temp, 'e'
rcall putc
ldi temp, 'r'
rcall putc
ldi temp, 'f'
rcall putc
ldi temp, 'l'
rcall putc
ldi temp, 'o'
rcall putc
ldi temp, 'w'
rcall putc
rjmp newline

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

putc:
;send char via RS232 (software UART)
out PORTB, uart_space ;start bit
mov temp2, uart_mark
sbrs temp, 0
mov temp2, uart_space
out PORTB, temp2 ;bit 0
mov temp2, uart_mark
sbrs temp, 1
mov temp2, uart_space
out PORTB, temp2 ;bit 1
mov temp2, uart_mark
sbrs temp, 2
mov temp2, uart_space
out PORTB, temp2 ;bit 2
mov temp2, uart_mark
sbrs temp, 3
mov temp2, uart_space
nop
out PORTB, temp2 ;bit 3
mov temp2, uart_mark
sbrs temp, 4
mov temp2, uart_space
out PORTB, temp2 ;bit 4
mov temp2, uart_mark
sbrs temp, 5
mov temp2, uart_space
out PORTB, temp2 ;bit 5
mov temp2, uart_mark
sbrs temp, 6
mov temp2, uart_space
out PORTB, temp2 ;bit 6
mov temp2, uart_mark
sbrs temp, 7
mov temp2, uart_space
out PORTB, temp2 ;bit 7
rjmp PC+1
nop
out PORTB, uart_mark ;stop bit & idle
ret


Elektronik-Labor  Projekte   AVR   T13-Contest