diff --git a/TCR-3458A-R6581T-350B.py b/TCR-3458A-R6581T-350B.py new file mode 100644 index 0000000..f62878e --- /dev/null +++ b/TCR-3458A-R6581T-350B.py @@ -0,0 +1,228 @@ +import GPIBPrologix +import bme280 +import smbus2 +from requests import post +import pyvisa +import time + +## Initialize the temperature controller +USBCON = pyvisa.ResourceManager() +## Initialize GPIB adapter +GPIB = GPIBPrologix.ResourceManager("/dev/ttyACM0") +# Connect equipment +inst1 = GPIB.open_resource(16) +inst3 = GPIB.open_resource(25) +inst2 = USBCON.open_resource('ASRL/dev/ttyUSB1::INSTR') +# Initialize BME280 temperature/humidity sensor +bus = smbus2.SMBus(1) +## Configure equipment +# BME280 temperature/humidity sensor +calibration_params = bme280.load_calibration_params(bus, 0x76) +# HP 3458A {resistance readout} +inst3.write("END 2") +inst3.write("OFORMAT ASCII") +inst3.write("BEEP") +inst3.write("TRIG AUTO") +inst3.write("OHMF 1E4") +inst3.write("NRDGS 1,AUTO") +inst3.write("NPLC 100") +inst3.write("NDIG 9") +inst3.write("AZERO ON") +inst3.write("DISP MSG,' '") +# Newport 350B {temperature controller} +inst2.write("TEC:GAIN:PID 100:80:18") +inst2.write("TEC:T 23") +inst2.write("TEC:OUT 1") +# Advantest R6581T {temp sensor} +inst1.write("*RST") +inst1.write(":CONF:FRES") +inst1.write(":SENS:FRES:POW LO") +inst1.write(":SENS:FRES:DIG MAX") +inst1.write(":SENS:FRES:NPLC 10") +inst1.write(":SENS:ZERO:AUTO ON") +inst1.write(":INPut:GUARd LOW") +inst1.write(":DISP OFF") + +# Measurement functions +def readValue(instObj): + # Query the main measurement device, return DUT measurement value + out = "" + instObj.write("TARM SGL,1") + for i in range(10): + out = instObj.read() + if out: + break + return out +def readTemperature(instObj): + value = instObj.query("FETch?") #Query a measurement + value = round((float(value[:10])-100)/0.385,4) + return value +def setTemperature(instObj, inputVar): + # Set the DUT chamber temperature + instObj.write("TEC:T "+str(inputVar)) + time.sleep(25) + return inputVar +def getEnvironment(instObj, i2cbus): + # Get environmental values, return temperature, humidity and pressure + value = instObj.sample(i2cbus, 0x76, calibration_params) + return value +def findparabolaVertex(a,b,c): + # Get the vertex for the resulting polynomial + print ("Vertex: (",(-b/(2*a)),",",(((4*a*c)-(b*b))/(4*a)),")") + return -(-b/(2*a)) + +## Have gitpython pull in the repository +import os +import git +import shutil +username = input("Your 0xC6 git username: ") +password = input("Your 0xC6 git password: ") +remote = f"https://{username}:{password}@git.0xc6.com/xans/ResistorDatabase.git" +if not os.path.exists(os.getcwd()+"/ResistorDatabase"): + git.Repo.clone_from(remote, os.getcwd()+"/ResistorDatabase/") +else: + shutil.rmtree(os.getcwd()+"/ResistorDatabase/", ignore_errors=True) + git.Repo.clone_from(remote, os.getcwd()+"/ResistorDatabase/") + +## Get needed info to properly label everything +manufacturer = input("Manufacturer: ").lower() +restype = input("Resistor Type: ").upper() +nomValue = input("Nominal resistor value: ").upper() # Use R instead of dot +resdate = input("Manufactury date: ").upper() +resid = input("Personally assigned ID: ").upper() +shellyIp = input("If you use shelly for protection, enter the IP: ").upper() +if shellyIp and os.system("ping -c 1 " + shellyIp): + print("shelly not found") + quit() +if shellyIp: + url = "{}://{}:{}/relay/0?turn=on".format("http", "192.168.0.101", "80") + post(url) + +## Create proper directory structure +basePath = os.getcwd() + "/ResistorDatabase/" +if not os.path.exists(basePath+manufacturer): + os.makedirs(basePath+manufacturer) +if not os.path.exists(basePath+manufacturer+'/'+restype): + os.makedirs(basePath+manufacturer+'/'+restype) +if not os.path.exists(basePath+manufacturer+'/'+restype+"/data/"): + os.makedirs(basePath+manufacturer+'/'+restype+"/data/") +basePath = basePath+manufacturer+'/'+restype +print(basePath+"/data/") + +import csv +import time +import datetime +import numpy as np +import pandas as pd +from math import sin +## Create logfile +logFileName = restype+'-'+nomValue+'-'+resdate+'-'+resid+'.csv' +with open(basePath+"/data/"+logFileName, 'a') as f: + writer = csv.writer(f) + writer.writerow(["DateTime","Resistance","Box Temperature", "Set Temperature","Env Pressure","Env Temperature", "Env Humidity"]) +print(basePath+"/data/"+logFileName) + +sweep = np.append([23] * 25, np.arange(23,28,0.1)) +sweep = np.append(sweep, [28] * 25) +sweep = np.append(sweep, np.arange(28,23,-0.1)) +sweep = np.append(sweep, [23] * 25) +sweep = np.append(sweep, np.arange(23,18,-0.1)) +sweep = np.append(sweep, [18] * 25) +sweep = np.append(sweep, np.arange(18,23,0.1)) +sweep = np.append(sweep, [23] * 25) + +cntr = 0 +## Collect data +setPoint = setTemperature(inst2,round(sweep[0],3)) +time.sleep(600) +for x in sweep: + cntr = cntr + 1 + try: + #Set temp and let accimatize + setPoint = setTemperature(inst2,round(x,3)) + print(str(cntr)+'/'+str(len(sweep))) + time.sleep(15) + for i in range(3): + try: + time.sleep(5) + #Get DUT value + readout = readValue(inst3) + #Read the temperature + temperature = readTemperature(inst1) + #Get envirnmental values + data = getEnvironment(bme280, bus) + #Write to file + d = datetime.datetime.now() + dx = d - datetime.timedelta(microseconds=d.microsecond) + fields=[dx.strftime("%d-%m-%y %H:%M:%S"),float(readout),float(temperature),setPoint,round(data.humidity,2),round(data.temperature,2),round(data.pressure,2)] + print(fields) + with open(basePath+"/data/"+logFileName, 'a') as f: + writer = csv.writer(f) + writer.writerow(fields) + if shellyIp and float(temperature) > 30 or float(temperature) < 16: + url = "{}://{}:{}/relay/0?turn=off".format("http", "192.168.0.101", "80") + post(url) + except Exception as e: + print(e) + inst1.query("*RST") + time.sleep(3) + inst1.query("R3") #Resistance mode 3, PT100 1mA + inst1.query("F2") #Auto filter + inst1.query("T7") #Set integration time 4S + inst1.query("CN0") #Only data on query + inst1.query("O4") #4 Wire + inst1.query("U1") #Basic unit ON + inst1.query("AZA1") #Auto zero on + inst1.query("AZT0300")#Auto zero every 300seconds + inst1.query("MAR") #Front, Channel A, RTD + time.sleep(3) + inst1.query("U1") + time.sleep(33) + i = i-1 + except Exception as e: + print(e) + time.sleep(1) + +## Calculate TCR +df = pd.read_csv(basePath+"/data/"+logFileName) +abCoef = np.polyfit(df["Box Temperature"], df["Resistance"], 2) +zeroTC = findparabolaVertex(abCoef[0],abCoef[1],0) +zeroTC = round(zeroTC,3) +if abs(zeroTC) >= 500: + zeroTC = '/' +alpha = (abCoef[1]*1000000)/float(nomValue) +beta = (abCoef[0]*1000000)/float(nomValue) +if abs(alpha) >= 50000: + alpha = '/' +else: + alpha = round(alpha,3) +if abs(beta) >= 50000: + beta = '/' +else: + beta = round(beta,3) + +## Make plot and save +from matplotlib import pyplot as plt +plt.plot(df["Box Temperature"], df["Resistance"]) +plt.plot(df["Box Temperature"], ((abCoef[0]*pow(df["Box Temperature"],2))+abCoef[1]*df["Box Temperature"]+abCoef[2])) +plt.xlabel('Temperature DUT (PT100, °C)') +plt.ylabel('Resistance DUT (Ohms)') +plt.title ('TCR sweep '+ logFileName[:-4]) +plt.savefig(basePath+"/data/"+logFileName[:-4]+".jpg", bbox_inches='tight') + +## Write away values to result overview +if not os.path.exists(basePath+'/README.md'): + with open(basePath+'/README.md', 'a') as f: + f.write("| Manufacturer | Type | Nominal Value | Manufacturing Date | Alpha(ppm) | Beta(ppm) | Zero-Tempco | File | ID | User |\n") + f.write("|--------------|------|---------------|--------------------|------------|-----------|-------------|------|----|------|\n") + f.close() +with open(basePath+'/README.md', 'a') as f: + linkToImg = "/data/"+logFileName[:-4]+".jpg" + print("|"+manufacturer+"|"+restype+"|"+nomValue+"|"+resdate+"|"+str(alpha)+"|"+str(beta)+"|"+str(-zeroTC)+"|"+linkToImg+"|"+resid+"|"+username+"|\n") + f.write("|"+manufacturer+"|"+restype+"|"+nomValue+"|"+resdate+"|"+str(alpha)+"|"+str(beta)+"|"+str(-zeroTC)+"|"+linkToImg+"|"+resid+"|"+username+"|\n") + f.close() + repo = git.Repo(os.getcwd() + "/ResistorDatabase/") + repo.git.add(basePath) + repo.index.commit("Add resistor "+ logFileName) + repo.remotes[0].push() +