Tenma 72-7735 DMM: Serial interface with Python

The Tenma 72-7735 is a lower end DMM that comes with quite a few handy features including an opto-isolated serial output. This serial communication is over a cable with a male db-9 rs-232 serial connector on one end and a connector housing a photo-diode that fits into the multimeter on the other end. Here is a picture of the cable:

Multimeter serial cable

Multimeter serial cable

rs232 cable plugged into multimeter

rs232 cable plugged into multimeter

Software is provided by Tenma that offers a gui with that can do things like datalogging, generate graphs and show real time data. The problem is that this program only works on windows and my computer doesn’t have a serial port. Also it would be nice if it was possible to read this serial data using some kind of microcontroller based embedded system and do something cool with it.

First step was to take apart the photodiode housing:

Circuitry inside serial cable

Circuitry inside serial cable

The original idea was to cut off the db-9 connector on the other end of the cable and hook up the wires to the correct voltages to get serial data out. This turned out to be problematic due to that fact that rs232 voltages are bi-polar. See the image of the reverse engineered circuit below:

Reverse engineered circuit diagram

Reverse engineered circuit diagram

These wire were attached to the following rs232 pins:
DCD – yellow
RxD – orange
Txd – white
DTR – brown
RTS – green

This particular cable was missing several components from the internal PCB. It only seemed to have the parts needed to receive data, not send it. The TxD (white) wire is soldered to the PCB but doesn’t seem to be connected to anything. It turns out that it is possible to power very low current (roughly 10mA max) devices over rs-232, some older computer mice would have been powered this way. This is usually done using the RTS and DTR lines to generate +5V and then using the TxD line as the negative voltage. Not wanting to go messing about with negative voltages I tried to get the circuit to work with just ttl voltage levels but it didn’t work out. In the end I just de-soldered the photo-diode from the PCB and made a much simpler circuit that easily works with 5v logic levels. The quick and easy circuit looks like this:

Photodiode circuit diagram

Photodiode circuit diagram


This serial data is sent to a computer via a pl2303 based usb to serial converter.

Here is a picture of the new and improved circuit stuffed inside the housing:

new circuit inside housing

new circuit inside housing

Picture of the output from this circuit on an oscilloscope below. It looks a bit non-square but it didn’t seem to affect the data being read correctly:

Serial data output on a scope

Serial data output on a scope

All that is left now is to read the serial data and do cool things with it. Only problem is the serial protocol is fairly poorly documented. A protocol outline can be found here. Despite the documentation being pretty confusing, the protocol is extremely simple.The serial data sent out is the LCD table which tells us which parts of the LCD are on and which are not. This makes it slightly more difficult to decode the data on the other end than if it just sent values of voltage or current but it’s not that big of a deal. The data is sent out in 14 byte packets ( this means 14 bytes, short pause then another 14 bytes etc). The upper nibble (upper 4 bits) of each byte is the bytes location within the packet. EG the first byte in a packet will be 0001XXXX, the second one 0010XXXX etc. The XXXX’s or the lower nibble of each byte is what we are interested in. There is a table provided in the datasheet that outlines what these lower 4 bits mean.

Serial protocol for multimeter

Serial protocol for multimeter

This table is so unnecessarily confusing. What does COM 1-4 Mean? I still have no idea. The way to look at it is just ignore columns 1-4, just pay attention to the seg colummns (seg1 – seg14). There are 14 seg columns and 14 bytes in a packet. This is because each bytes lower nibble corresponds to the lcd sections in one of those columns. If for example the first byte in a packet was 00010111, the upper nibble is 0001 which means it refers to column seg1. The lower nibble is 0111, each bit of this nibble tells us if that particular symbol is currently showing on the LCD. 1 means on and 0 means off. So for example in this case 0111 means the following

0 – AC OFF
1 – Auto ON
1 – DC ON
1 – RS232 ON

This process repeats for the full 14 byte packet and by knowing which parts of the LCD are on, you can then work out what numbers are being displayed on the screen and so on. See below for a python script I wrote to do this (click to expand):

import serial
import time
import binascii

ser = serial.Serial(
	port='/dev/ttyUSB0',
	baudrate=2400,
	timeout = 0.1,
	stopbits=serial.STOPBITS_ONE,
	bytesize=serial.EIGHTBITS
)

ser.close()
ser.open()

ser.flush()

hex_vals = []
temp_str = ''
bin_vals = []
dmm_data = ''
lower_nibbles = []
for i in range (0, 14):       # make lists to store hex and binary values
	hex_vals.append('0')
	bin_vals.append(0)
	lower_nibbles.append(0)
	
	
def get_lower_nibbles(bin_vals):            # only keep the lower part of nibble
	for i in range(0, len(bin_vals)):
		temp_str = str(bin_vals[i])
		lower_nibbles[i] = str(temp_str[4:8])
	
	return(lower_nibbles)

a=[]
b=[]
c=[]
d=[]
digit = 0

for h in range(8):  # make a list for each digit to record which parts of seven segment are on or off
	a.append('0')
	b.append('0')
	c.append('0')
	d.append('0')
	
def lcd_get_num(lcd_array):                 ##  each digit corresponds to certain parts of seven segment display being on
	digit = 0
	if lcd_array == '1010000' : digit = 1
	if lcd_array =='1101101' : digit = 2
	if lcd_array == '1111001' : digit = 3
	if lcd_array == '0110011' : digit = 4
	if lcd_array == '1011011' : digit = 5
	if lcd_array == '1011111' : digit = 6
	if lcd_array == '1110000' : digit = 7
	if lcd_array == '1111111' : digit = 8
	if lcd_array == '1111011' : digit = 9
	if lcd_array == '1111110' : digit = 0
	
	return str(digit)
	
	
def decode_data(lower_nibbles):             #this function works out what numbers are being displated based on 
	for i in range(1, len(lower_nibbles)):  # which parts of each seven segment digit are turned on
		temp_reg = lower_nibbles[i]
	#	print temp_reg
	#	print len(a)
		if (i==1):         ## first digit
			#print temp_reg[3]
			a[1] = temp_reg[3]
			a[6] = temp_reg[2]
			a[5] = temp_reg[1]
		if (i==2):
			a[2] = temp_reg[3]
			a[7] = temp_reg[2]
			a[3] = temp_reg[1]
			a[4] = temp_reg[0]
			
		if (i==3):
			b[1] = temp_reg[3]
			b[6] = temp_reg[2]
			b[5] = temp_reg[1]
			
		if (i==4):
			b[2] = temp_reg[3]
			b[7] = temp_reg[2]
			b[3] = temp_reg[1]
			b[4] = temp_reg[0]
			
		if (i==5):
			c[1] = temp_reg[3]
			c[6] = temp_reg[2]
			c[5] = temp_reg[1]
		
		if (i==6):
			c[2] = temp_reg[3]
			c[7] = temp_reg[2]
			c[3] = temp_reg[1]
			c[4] = temp_reg[0]
		
		if (i==7):
			d[1] = temp_reg[3]
			d[6] = temp_reg[2]
			d[5] = temp_reg[1]
		
		if (i==8):
			d[2] = temp_reg[3]
			d[7] = temp_reg[2]
			d[3] = temp_reg[1]
			d[4] = temp_reg[0]
	a.pop(0)
	b.pop(0)
	c.pop(0)
	d.pop(0)
	achar = ''.join(a)
	bchar = ''.join(b)
	cchar = ''.join(c)
	dchar = ''.join(d)	
	a.append('0')	
	b.append('0')
	c.append('0')              # this terrible piece of code would probably make                          
	d.append('0')             # Guido van Rossum cry  
	
	d1 = lcd_get_num(achar)
	d2 = lcd_get_num(bchar)
	d3 = lcd_get_num(cchar)
	d4 = lcd_get_num(dchar)
	print d1+d2+d3+d4              #print numbers displayed on LCD screen
	
	return(achar, bchar, cchar, dchar)
		
			
		
dmm_data = ""

while True:
	dmm_data = ""
	ser.flush()
	while dmm_data == "":                                #wait for a packet
		dmm_data = str(binascii.hexlify(ser.read(14)))


	g = 0                                               # concert hex values into binary
	for i in range(0, len(dmm_data), 2):
		bin_vals[g] = str( bin(int(dmm_data[i:i+2], 16))[2:].zfill(8)) 
		g=g+1

	#print bin_vals

	get_lower_nibbles(bin_vals)                       # only interested in lower nibble of each byte
	#print lower_nibbles

	decode_data(lower_nibbles)                        # from this data work out what numbers are displayed on screen
	time.sleep(0.5)                               

Table outlining how to work out what digit is being displayed

Table outlining how to work out what digit is being displayed

The output from the Python script at the moment is just the numbers currently being displayed on the multimeter. This is a work in progress, data logging with a microcontroller is something to try out in the future.

Python script output

Python script output

Using a mini-oven for making homemade PCBs

The oven used for this is a value range mini-oven sold at Argos for €38.99. It is a 1000 watt oven with two elements ( one upper one lower ) and a temperature range of 100-230 degrees.

Here is a picture of the aforementioned toaster oven:

Mini_oven with multimeter measuring temperature

Mini_oven with multimeter measuring temperature

From looking at how other people on the internet have gone about using toaster ovens for pcb manufacture, it seems that it is not really neccessary to have a PID controller in place that can set the temperature to the nearest degree. Using a thermometer and manually turning the oven on and off to get the desired temperatures seems to work just fine. In my case I used a multimeter that has a temperature function and a k-type thermocouple capable of measuring a range from -20 to +2000 degrees. More than enough for this purpose.

First step in getting everthing ready is to know the reflow profile of the solder paste you are using. This information is normally provided in a datasheet and looks something like this:

reflow profile for the solder paste used

reflow profile for the solder paste used

I’m not really sure why there are two lines but its not all the important because once you are roughly in the right ballpark temperature everything seems to turn out ok. So for this reflow profile I would do the following:

1. put the board in the oven cold
2. Turn on oven until temperature reaches around 150 Degrees
3. Wait at this temperature for about 1 – 1.5 minutes
4. Increase temperature to 200 Degrees. Once this temperature is reached turn of the oven and let it slowly cool down

The next step is applying the solder paste to the board. This is fairly simple to do although it is time consuming if you have a lot of pads on the board. I made a complete shambles of applying the paste to my board as seen below:

Bare PCB

Bare PCB

PCB with solder paste applied

PCB with solder paste applied

Next step is to place all of the parts on the board. This step requires a steady hand and some patience with lining everything up correctly. The end result looked like this:

PCB with solder paste and components applied

PCB with solder paste and components applied

Now just gently place the board in the oven and follow the reflow profile of the solder paste, keeping an eye on the temperature and elapsed time. Here is a picture of the finished product:

PCB with USB to serial adapter plugged in

PCB with USB to serial adapter plugged in

PCB plugged into PICkit2

PCB plugged into PICkit2

It works! Despite making a balls of the solder paste it turned out all right so its a fairly rugged and reliable method for applying solder.

Homebrew PCBs first attempt

Here is the first PCB that came out alright:

Homemade PCB

Homemade PCB

There were several fails before this. This post will document some of the things I have learned so far. First off, in my limited experience, tracing paper is much better than transparencies for printing the artwork on to. I’m using a 1200×1200 dpi laser printer and when using the transparencies the artwork consistently came out of the printer blurred. I tried changing around some settings on the printer but the blurred images persisted. Then I tried tracing paper and it really is brilliant stuff. It looks like the ink can adhere to the tracing paper much easier than the transparencies so the images are much more sharply defined:

Artwork on tracing paper

Artwork on tracing paper

Blurred artwork on transparency

Blurred artwork on transparency

The next step was finding out how long the UV exposure box takes to fully expose a PCB. Under exposure will result in short circuits and over exposure will result in broken traces so finding the right amount of time is important. I found the right exposure time by trial and error. I knew it was probably somewhere between 2-8 minutes based on other UV boxes I’ve seen online. The way I found the perfect amount of time was by printing out some tqfp-44 packages onto tracing paper like so:

5 TQFP packages on tracing paper

5 TQFP packages on tracing paper

I’m using pre-sensitized fr4 boards at the moment. So I cut off a piece of the fr4 big enough for the 5 tqfp packages. I then exposed the whole thing to UV for 2 minutes and then every 30 seconds after that I blocked off one tqfp package from the UV using a piece of cardboard. That means for every tqfp footprint was 30 seconds of extra exposure. The first run I started from 2 minutes, then 30 seconds later blocked off one tqfp part and so on for 2 and a half minutes. This gave me exposure time from 2-4.5 minutes. This is the result:

Varied exposure times

Varied exposure times

The above image isn’t very clear but basically the rightmost tqfp footprint was exposed for 2mins, the next one for 2.5 mins and so on all the way up to 4.5 mins on the very left. I didn’t bother fully etching this board because it was obvious that around 4-4.5 mins was the minimum. I then repeated the experiment starting from 4.5 mins up to 7 mins. Here is the results of 4.5 – 7 mins. The best one is 4.5 and the most faded is 7 mins.

UV exposure varied from 4.5 - 7 mins

UV exposure varied from 4.5 – 7 mins

Looking at the left most footprint in the above image some of the pads were slightly over exposed. So I went with 4 minutes for exposure instead of 4.5. I then printed a test circuit seen on the stop of this page. Its just the top layer of a two layer board:
Selection_084

It’s got a ssop-16 package and a ssp-20 package which both have fairly small pin pitch and it etched out just fine. I used this guide on making PCBs made by Mike from mikeselectricstuff . It is an extremely useful guide and his methods give great results.

DIY UV PCB exposure box

UV exposure boxes sell for hundreds of euros from vendors such as RS electronics and Farnell when they can be built at home for approximately 70 euro. I used a plant pot to build mine because it was the only opaque container I could easily get my hands on.
2014-08-21 16.40.54

Here is a picture of the parts needed. Note that there should be two ballasts and not one.
Things needed for the build

Looking at the below picture of a close up of one of the ballasts you will notice that the circuit diagram printed on it shows that it can power two lamps (2x15W) in series. I tried doing it this way but could not get the lamps to start. So I bought a second ballast and wired a ballast to each lamp and it worked fine. This could just be due to the brand of ballast or the types of lamps I have.

Magnetic Ballast

Magnetic Ballast

This wiring diagram from wikimedia is very useful. This wiring layout is used for both lamps.
text4480

For the housing, a mirror on the base will help even the light distribution and increased the amount of light from the lamps that actually reaches the pcb. Also on top of the box you will want piece of glass or clear acrylic to sit the pcb on. I got a piece of mirror and glass cut for 10 euro from a local glass cutting company. Here is a picture of the mirror sitting in the plant pot:
2014-08-21 16.42.11

Next I added in the screwed the ballasts on the inside of the pot and made a hole for the mains connector which was just a three pin mains socket. From there just followed the wiring diagram above and ended up with this:

UV exposure box with electronics visible

UV exposure box with electronics visible

Plug in the mains after checking wiring to make sure everything works as expected:
2014-08-26 12.41.04

Hiding the electronics is the next step. This is for two reasons. The first being that the electronics look fairly unsightly (Not that I’m going for aesthetics here or anything). Secondly, it is better if the section of glass left visible is lined up with the center of the two lamps. So when you put down a board it is easy to line it up in the middle of both lamps for even light distribution. I used electrical tape to cover up part of the glass like so:
2014-08-26 12.52.24

I didn’t put a lid on the box because it really doesn’t seem necessary. I think just placing the board on the glass then maybe putting a piece of wood on top should do the job just fine. I didn’t add a timer either, I’m just going to use a smartphone timer app and manually turn off the power. Also, there is not switch because the power socket I use for this has a switch, or the cable could just be unplugged.

Bill of materials

Quantity
Part
Source
Price (Euros)
2Magnetic Ballast 30WRS electronics. Order No: 793468218
2T8 Fluorescent Lamp 10WEbay http://goo.gl/KAbd4J20
44 T8 Lamp holders/clipsElectrical wholesalers2
2 Fluorescent StartersElectrical wholesalers2
2Fluorescent starter holdersElectrical wholesalers2
1Mains power 3 pin socketElectrical wholesalers1.50
1Single core wire (3 metres)Electrical wholesalers2.50
1Piece of mirror (30cm x 20xm)Glass supplier and cutter5
1Piece of glass/acrylic (40cmx25cm)Glass supplier and cutter5
1Box/Container/Plant potHardware Shop10
Total : 68