万用表内阻
01 万用表内阻
一、背景介绍
今天看到一个有趣的短片, 博主小哥把玩两个金属圆板, 非常清晰的展示了电容的工作原理。 但其中一个实验, 涉及到使用万用表测量金属板电压, 对于有经验的人来说, 对于他的实验结果会感到非常奇怪。
二、万用表内阻
首先,从视频中来看这两个圆盘之间的电容大约为0.18nF 充电之后,两个圆盘相互离开, 可以看到电压在升高。 这实际上没有考虑到测量电压万用表的内阻。 通常情况下,万用表的内阻为10M欧姆, 对于0.1nF电容, 应该在10ms就释放完了。 可以这个短片中却显示电压在升高! 这太奇怪了。
※ 总 结 ※
本文记录了一个短频中使用万用表测量两个平行铁片电压的实验。 显然这个实验没有考虑到万用表的内阻。 实在不清楚影片中万用表内阻该是多少了。
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# SPS.PY -- by Dr. ZhuoQing 2022-10-03
# Seperate speak signal into segment.
# Usage: sps wavefile silencevalue(int) silencetime(float)
# sps azure # Open AZURE link
# a # Open AZURE Link
# h # Head time
# s # Voice speed
# =,> # Head
# x # Using XUNJIE
# z # Using AZure
#
# Before using sps, copy all voice string into clipboard.
#
# Note:
#============================================================
from headm import *
from scipy.io import wavfile
import pyautogui
import webbrowser
import shutil
import soundfile as sf
#------------------------------------------------------------
wavefile = r'D:\Temp\1.wav'
#------------------------------------------------------------
try:
if not os.path.exists(r'd:\temp'):
os.makedirs(r'd:\temp')
if not os.path.exists(r'd:\temp\VOICE'):
os.makedirs(r'd:\temp\VOICE')
except OSError:
printf("Error :Creating directory of data.")
#------------------------------------------------------------
silencevalue = 100 # Silence max value
SILENCETIME = 0.58
silencetime = SILENCETIME #
starttime = 2.0 # Begin time
mp3flag = 0
#------------------------------------------------------------
XUNJIE_TITLE = '迅捷文字转语音'
XUNJIE_PROGRAM = r'C:\Users\SCW4000\AppData\Roaming\HuDun\XunJieVoice\audioconverter.exe'
XUNJIE_RECT = tspgetwindowrect(XUNJIE_TITLE)
XUNJIE_FLAG = sum(XUNJIE_RECT)
#------------------------------------------------------------
azure_url = "https://azure.microsoft.com/zh-cn/products/cognitive-services/text-to-speech/#overview"
azure_title = "文本转语音"
AUDACITY_TITLE = 'Audacity'
AUDACITY_PROGRAM = r'"C:\Program Files (x86)\Audacity\audacity.exe"'
#------------------------------------------------------------
def AudacityOpen():
rect = tspgetwindowrect(AUDACITY_TITLE)
if sum(rect) == 0:
printf(AUDACITY_PROGRAM)
# os.system(AUDACITY_PROGRAM)
os.startfile(AUDACITY_PROGRAM)
#------------------------------------------------------------
spsstr = tspstring2text('-|-').split('\r\n')
replacestring = []
for s in spsstr:
ss = s.split('|')
if len(ss) == 2:
replacestring.append(ss)
#------------------------------------------------------------
audacityflag = 0
audacityfile = r'd:\temp\Audacity1.wav'
def AudacityOpenFile(fname):
tspsendwindowkey(AUDACITY_TITLE, "tv", alt=1, noreturn=1)
time.sleep(.1)
tspsendwindowkey(AUDACITY_TITLE, "tv", alt=1, noreturn=1)
time.sleep(.1)
tspsendwindowkey(AUDACITY_TITLE, "i", control=1, shift=1, noreturn=1)
time.sleep(.5)
clipboard.copy(fname)
time.sleep(.25)
OPENDIALOG_TITLE = '选择一个或多个'
tspsendwindowkey(OPENDIALOG_TITLE, "n", alt=1,noreturn=1)
tspsendwindowkey(OPENDIALOG_TITLE, "v", control=1, noreturn=1)
tspsendwindowkey(OPENDIALOG_TITLE, "o", alt=1, noreturn=1)
time.sleep(.5)
tspsendwindowkey("警告", "\r", noreturn=1)
#------------------------------------------------------------
def AudacitySave(fname):
tspsendwindowkey(AUDACITY_TITLE, "fe", alt=1, noreturn=1)
time.sleep(1)
rect = tspgetwindowrect("导出音频")
if sum(rect) == 0:
printf("ERROR: Can not open the save dialog.\a")
exit()
clipboard.copy(fname)
tspsendwindowkey("导出音频", "t", alt=1,noreturn=1)
tspsendwindowkey("导出音频", "cw", noreturn=1)
tspsendwindowkey("导出音频", "n", alt=1, noreturn=1)
tspsendwindowkey("导出音频", "v", control=1, noreturn=1)
tspsendwindowkey("导出音频", "s", alt=1, noreturn=1)
time.sleep(1)
rect = tspgetwindowrect("警告")
if sum(rect) != 0:
time.sleep(.5)
tspsendwindowkey("警告", "y", alt=1, noreturn=1)
time.sleep(.5)
rect = tspgetwindowrect("编辑元信息")
if sum(rect) == 0:
printf("ERROR: Can not open the edit dialog.\a")
tspsendwindowkey("编辑元信息", "\r", noreturn=1)
time.sleep(1.5)
# tspsendwindowkey(AUDACITY_TITLE, "tv", alt=1, noreturn=1)
#------------------------------------------------------------
def StringVoice(s):
global replacestring
rps = (('8050', '8 0 5 0'), ('8550', '8 5 5 0'), ('9013', '9 0 1 3'),
('mV', '毫伏'), ('mAH', '毫安时'), ('mH', '毫亨'), ('uF', '微法'),
('nF', '纳法'), ('pF','皮法'), ('VA', "伏安"), ('M欧姆', '兆欧姆'),
('k欧姆','千欧姆'), ('M法拉', "兆法拉"), ('I2C', 'I方C'),
('mA', '毫安'), ('本文', '在这里'), ('MHz', '兆赫兹'), ('kHz', '千赫兹'),
(':', ','), ('TB','淘宝'), ('NXP', '恩智浦'), ('Infineon','英飞凌'))
for ss in rps:
s = s.replace(ss[0], ss[1])
for ss in replacestring:
s = s.replace(ss[0], ss[1])
#--------------------------------------------------------
VAW = (('V','伏'), ('A', '安'), ('W','瓦'), ('M', '兆'), ('ms', '毫秒'))
for vaw in VAW:
if s.find("型号") >= 0: continue
ss = s.split(vaw[0])
for id,sss in enumerate(ss):
flag = 0
for ii in range(len(sss)):
if ord(sss[-(ii+1)]) > 0x80:
if ii == 0: flag = 1
break
if not sss[-(ii+1):].replace('.','').replace('+','').replace('-','').isdigit():
flag = 1
break
if flag == 0:
ss[id] = sss + vaw[1]
elif id < len(ss) - 1:
ss[id] = sss + vaw[0]
s = ''.join(ss)
#--------------------------------------------------------
WAV = (('+', '正'), ('-', '负'), ('TSSOP', 'T S S O P'),('SOP', 'S O P '),
('SOT', 'S O T '), ('SSOP', 'S S O P '))
for wav in WAV:
ss = s.split(wav[0])
for id,sss in enumerate(ss):
if id < len(ss) - 1:
if ord(sss.replace(' ','')[-1]) < 0x80:
ss[id] = sss + wav[0]
else:
if ss[id+1][:1].isdigit():
ss[id] = sss + wav[1]
else: ss[id] = sss + wav[0]
s = ''.join(ss)
return s
#------------------------------------------------------------
MAX_LENGTH = 600
voicesegmentnumber = 0
voiceflag = ''
def VoiceSegment1000(strall, s):
global voicesegmentnumber, voiceflag
section = -1
if len(s) > 0:
if s.isdigit():
section = int(s)
else: section = 0
#--------------------------------------------------------
tempdim = []
headstr = ''
for s in strall:
if s[:2] == '>>' or s[:2] == '<<':
continue
if s.find('~') >= 0:
ss = s.split('~')
s = ss[-1]
if len(ss) >= 3:
headstr = ss[1]
else:
if headstr in '!@#$%^&*()':
headstr = ''
if len(voiceflag) > 0:
if voiceflag == '0' or voiceflag == ')':
if len(headstr) == 0 or headstr == '0':
tempdim.append(s)
elif voiceflag == '1' or voiceflag == '!':
if headstr == '1' or headstr == '!' or headstr == '!':
tempdim.append(s)
elif voiceflag == '2' or voiceflag == '@':
if headstr == '2' or headstr == '@':
tempdim.append(s)
elif voiceflag == '3' or voiceflag == '#':
if headstr == '3' or headstr == '#':
tempdim.append(s)
elif voiceflag == '4' or voiceflag == '$':
if headstr == '4' or headstr == '¥' or headstr == '$':
tempdim.append(s)
elif voiceflag == '5' or voiceflag == '%':
if headstr == '5' or headstr == '%':
tempdim.append(s)
elif voiceflag == '6' or voiceflag == '^':
if headstr == '6' or headstr == '^':
tempdim.append(s)
elif voiceflag == '7' or voiceflag == '&':
if headstr == '7' or headstr == '&':
tempdim.append(s)
elif voiceflag == '8' or voiceflag == '*':
if headstr == '8' or headstr == '*':
tempdim.append(s)
elif voiceflag == '9' or voiceflag == '(':
if headstr == '9s' or headstr == '(':
tempdim.append(s)
else:
tempdim.append(s)
strall = tempdim
#--------------------------------------------------------
sseg = []
stemp = []
count = 0
for s in strall:
if s[0] == '{':
ids = s.find('}')
if ids > 0:
s = s[ids+1:]
if count + len(s) > MAX_LENGTH:
if len(stemp) > 0:
sseg.append(stemp)
stemp = [s]
count = len(s)
else:
stemp.append(s)
count += len(s)
if len(stemp) > 0: sseg.append(stemp)
for id,sg in enumerate(sseg):
tspshowinfor("Seg%d/%d:%d; "%(id+1, len(sg), sum([len(l) for l in sg])))
# printf('\a')
#--------------------------------------------------------
if section < 0:
voicesegmentnumber = len(sseg)
totallen = sum([len(l) for l in strall])
printf("Total Segment:%d/%d"%(len(strall), totallen))
return strall
voicesegmentnumber = len(sseg)
if section < len(sseg):
return sseg[section]
else: return []
#------------------------------------------------------------
printf(sys.argv)
savewavefile = wavefile
procflag = 0
XUNJIE_PROCFLAG = 3
for s in sys.argv[1:]:
if s[:1] == 'A' or s[:1] == 'a':
rect = tspgetwindowrect(azure_title)
flag = 0
if sum(rect) == 0:
webbrowser.open_new_tab(azure_url)
flag = 1
tspcopyhelptext()
strall = [s.strip('\r') for s in clipboard.paste().split('\n') if len(s) > 2]
strall = VoiceSegment1000(strall, s[1:])
for id,s in enumerate(strall):
printff(id, s)
clipboard.copy(StringVoice('\n'.join(strall)))
if flag == 0:
tspsendwindowkey(azure_title, "av", control=1,noreturn=1)
exit()
if s[:1] == '|' or s[:1] == 'B' or s[:1] == 'b':
rect = tspgetwindowrect(AUDACITY_TITLE)
if os.path.isfile(savewavefile):
os.remove(savewavefile)
if sum(rect) != 0:
AudacitySave(savewavefile)
audacityflag = 1
tspcopyhelptext()
strall = [s.strip('\r') for s in clipboard.paste().split('\n') if len(s) > 2]
strall = VoiceSegment1000(strall, s[1:])
clipboard.copy('\n'.join(strall))
procflag = 1
continue
if s[:1] == 'C' or s[:1] == 'c':
tspcopyhelptext()
strall = [s.strip('\r') for s in clipboard.paste().split('\n') if len(s) > 2]
strall = VoiceSegment1000(strall, s[1:])
clipboard.copy('\n'.join(strall))
procflag = 1
printf('\n'.join(strall))
exit()
continue
if s[:1] == 'h' or s[:1] == 'H':
starttime = float(s[1:])
continue
if s[:1] == 's' or s[:1] == 'S':
if s[1:].replace('.','').isdigit():
silencetime = silencetime / float(s[1:])
continue
if s[:1] == '=' or s[:1] == '>':
voiceflag = s[1:]
if len(voiceflag) == 0: voiceflag = '0'
continue
if s[:1] == 'x' or s[:1] == 'X':
if XUNJIE_FLAG == 0:
os.startfile(XUNJIE_PROGRAM)
for i in range(20):
time.sleep(.5)
tspbeep(1200, 50)
XUNJIE_RECT = tspgetwindowrect(XUNJIE_TITLE)
XUNJIE_FLAG = sum(XUNJIE_RECT)
if XUNJIE_FLAG > 0:
time.sleep(2)
tspbeep(1200, 50)
break
if s[:1] == 'X':
XUNJIE_PROCFLAG = 1
else: XUNJIE_PROCFLAG = 2
continue
if s[:1] == 'z' or s[:1] == 'Z':
XUNJIE_FLAG = 0
continue
fname = os.path.join(r'd:\temp', '%s.WAV'%s)
if os.path.isfile(fname):
wavefile = fname
continue
fname = os.path.join(r'd:\temp', '%s.MP3'%s)
if os.path.isfile(fname):
wavefile = fname
mp3flag = 1
continue
if s.isdigit():
silencevalue = int(s)
if silencevalue > 500:
silencevalue = 500
continue
if s.replace('.', '').isdigit():
silencetime = float(s)
continue
#------------------------------------------------------------
if XUNJIE_FLAG != 0:
tspsendwindowkey(AUDACITY_TITLE, "tv", alt=1, noreturn=1)
time.sleep(.1)
tspcopyhelptext()
pastestr = clipboard.paste()
strall = [s.strip('\r') for s in pastestr.split('\n') if len(s) > 2]
vss = VoiceSegment1000(strall, '')
printf("PROCFLAG:%d"%XUNJIE_PROCFLAG)
# if XUNJIE_PROCFLAG != 3:
# clipboard.copy(StringVoice('[3s] ' + '[2s]\n'.join(vss) + '[2s]'))
# else:
# clipboard.copy(StringVoice('\n'.join(vss)))
clipboard.copy(StringVoice('[3s] ' + '[2s]\n'.join(vss) + '[2s]'))
rect = XUNJIE_RECT
time.sleep(.1)
tspsendwindowkey(XUNJIE_TITLE, "a", control=1,noreturn=1)
pyautogui.click((rect[0]*2+rect[2]*3)//5, (rect[1]*3+rect[3]*2)//5)
tspsendwindowkey(XUNJIE_TITLE, "av", control=1,noreturn=1)
#--------------------------------------------------------
filedim = os.listdir(r'd:\temp')
printf('\a')
if XUNJIE_PROCFLAG != 1:
for f in filedim:
if f.split('.')[-1].upper() != 'WAV': continue
fname = os.path.join(r'd:\temp', f)
os.remove(fname)
time.sleep(.5)
if XUNJIE_PROCFLAG != 3:
pyautogui.click(rect[2] - 100, rect[3] - 50)
else:
pyautogui.click(rect[2] - 100, rect[3] - 100)
printf('\a')
exit()
#--------------------------------------------------------
for i in range(1000):
xy = tspgetcursor()['tsxy']
time.sleep(0.1)
if xy[3] != 0 or xy[2] != 0:
printf('\a')
exit()
if (i%5) == 0:
tspbeep(1200, 20)
filedim = os.listdir(r'd:\temp')
flag = 0
for f in filedim:
if f.split('.')[-1].upper() == 'WAV':
flag = 1
wavefile = os.path.join(r'd:\temp', f)
break
if flag > 0: break
tspbeep(1500, 50)
tspbeep(1000, 200)
time.sleep(1)
#--------------------------------------------------------
rect = tspgetwindowrect(AUDACITY_TITLE)
if sum(rect) != 0:
savewavefile = r'd:\temp\1.wav'
if os.path.isfile(audacityfile):
os.remove(audacityfile)
if os.path.isfile(savewavefile):
os.remove(savewavefile)
shutil.copyfile(wavefile, audacityfile)
time.sleep(.5)
AudacityOpenFile(audacityfile)
time.sleep(.1)
AudacitySave(savewavefile)
audacityflag = 1
if os.path.isfile(wavefile):
os.remove(wavefile)
wavefile = savewavefile
#--------------------------------------------------------
starttime = 1.0
strall = VoiceSegment1000(strall, '')
clipboard.copy('\n'.join(strall))
time.sleep(.1)
#------------------------------------------------------------
if procflag == 0 and XUNJIE_FLAG == 0:
AudacityOpen()
rect = tspgetwindowrect(azure_title)
if sum(rect) == 0:
webbrowser.open_new_tab(azure_url)
for i in range(5):
time.sleep(.5)
tspbeep(1200, 50)
rect = tspgetwindowrect(azure_title)
printf(rect)
tspcopyhelptext()
pastestr = clipboard.paste()
strall = [s.strip('\r') for s in pastestr.split('\n') if len(s) > 2]
vss = VoiceSegment1000(strall, '')
tspsendwindowkey(AUDACITY_TITLE, "tv", alt=1)
printf("Press left buttom to record.\a")
#--------------------------------------------------------
segment = 0
while True:
key = 0
while True:
xy = tspgetcursor()['tsxy']
time.sleep(0.1)
# printf(xy)
if xy[3] != 0:
key = 2
time.sleep(0.2)
printf('\a')
tspsendwindowkey(AUDACITY_TITLE, "c")
exit()
if xy[2] != 0:
if xy[-4] != 0:
speed = SILENCETIME / silencetime + 0.05
silencetime = SILENCETIME / speed
printf('Speed:%f\a'%speed)
elif xy[-3] != 0:
speed = SILENCETIME / silencetime - 0.05
silencetime = SILENCETIME / speed
printf('Speed:%f\a'%speed)
else:
key = '\r'
break
#----------------------------------------------------
if key == '\r':
if segment == 0:
tspsendwindowkey(AUDACITY_TITLE, "r")
if segment >= voicesegmentnumber:
tspsendwindowkey(AUDACITY_TITLE, "c")
break
vss = VoiceSegment1000(strall, str(segment))
clipboard.copy(StringVoice('\n'.join(vss)))
time.sleep(.1)
pyautogui.click((rect[0]*3+rect[2]*2)//5, (rect[1]*2+rect[3]*3)//5)
tspsendwindowkey(azure_title, "av", control=1,noreturn=1)
segment += 1
elif key == 'ESC':
printf('\a')
break
tspsendwindowkey(AUDACITY_TITLE, "c", noreturn=1)
printf('\a')
if os.path.isfile(savewavefile):
os.remove(savewavefile)
AudacitySave(savewavefile)
audacityflag = 1
strall = VoiceSegment1000(strall, '')
clipboard.copy('\n'.join(strall))
time.sleep(.1)
#------------------------------------------------------------
strall = [s.strip('\r') for s in clipboard.paste().split('\n') if len(s) > 2]
printff(wavefile, silencevalue, silencetime)
#------------------------------------------------------------
time.sleep(1.5)
channel_num = 1
if mp3flag == 0:
if XUNJIE_FLAG == 0:
sig, sample_rate = sf.read(wavefile)
sig = (sig * 0x7fff).astype(int16)
else:
sample_rate, sig = wavfile.read(wavefile)
startnum = int(starttime * sample_rate)
if len(shape(sig)) == 2:
sig = sig[startnum:, :]
sigdata = array(sig[:,1])
channel_num = 2
else:
sig = sig[startnum:]
sigdata = array(sig)
else:
# sample_rate = 44100
# sound = AudioSegment.from_file(file=wavefile)
# left = sound.split_to_mono()[0]
# sig = frombuffer(left._data, int16)
# sigdata = array(sig)
printf("Can not open MP3 file.\a")
exit()
printff(sample_rate, shape(sig))
#------------------------------------------------------------
sigdata[(sigdata > -silencevalue) & (sigdata < silencevalue)] = 0
sigdata[(sigdata <= -silencevalue) | (sigdata >= silencevalue)] = 1
sigone = where(sigdata == 1)[0]
sigdelta = array([x2-x1 for x1,x2 in zip(sigone[0:-1], sigone[1:])])
deltamin = int(sample_rate*silencetime)
#sigmax = where(sigdelta > deltamin)[0]
num = len(strall)-1
sigmax = sorted([x[0] for x in sorted(zip(range(len(sigdelta)),sigdelta), key=lambda x:x[1], reverse=True)[:num]])
sigsegment =[sigone[0]]
for sm in sigmax:
sigsegment.append(sigone[sm+1])
sigsegment.append(sigone[-1])
#------------------------------------------------------------
printff('Voice Segment:%d'%len(sigsegment), 'Voice String:%d'%len(strall))
printf('\a')
if len(sigsegment) - len(strall) != 1:
printf("Voice String Number error !\a")
exit()
#------------------------------------------------------------
for i in range(len(sigsegment) - 1):
startid = sigsegment[i]
endid = sigsegment[i+1] - sample_rate//2
if i+1 >= len(sigsegment) - 1:
endid = sigsegment[i+1] + sample_rate//2
wavefilename = '%04d.wav'%i
if i < len(strall):
sa = strall[i].replace(',', '').replace(',','').replace('.','').replace('。', '').replace(';','')
sa = sa.replace(';','').replace('、', '').replace('*', '').replace('!', '').replace('?', '')
wavefilename = '%s.wav'%(sa)
outfile = os.path.join(r'd:\temp\VOICE', wavefilename)
if channel_num == 2:
wavfile.write(outfile, sample_rate, sig[startid:endid, :])
else: wavfile.write(outfile, sample_rate, sig[startid:endid])
printf(outfile)
#------------------------------------------------------------
if audacityflag > 0:
tspsendwindowkey(AUDACITY_TITLE, "tv", alt=1, noreturn=1)
if os.path.isfile(savewavefile):
os.remove(savewavefile)
if os.path.isfile(wavefile):
os.remove(wavefile)
if os.path.isfile(audacityfile):
os.remove(audacityfile)
tspbeep(1800, 100)
#------------------------------------------------------------
# END OF FILE : SPS.PY
#============================================================