/* 自定義代碼塊樣式 */

2020年6月19日 星期五

使用 VB 透過 SCPI 控制儀器設備

因要讀取電表的資料,所以接觸了SCPI這個語言,這次又要讀取示波器的波形資料,所以乾脆整理了一下使用的命令,方便於日後查詢

SCPI (Standard Command for Programmable Instrumentation)可程式化儀器標準語言,是透過ASCII語法來與儀器做溝通

簡單的命令範例如下

  1. MEASure:VOLTage:DC?;:MEASure:CURRent:AC?

當然首先要先安裝電腦端的驅動程式,因為電表是使用Keysight的,所以就上Keysight網站找驅動程式了,下載網址


網站中有三套軟體,IO Libraries Suite是最主要的驅動,會安裝VisaComLib這個Library,主要是透過這個Library跟儀器做溝通的,所以至少要安裝這套軟體

在VB6中,要使用VisaComLib時,需要先引用它,所以要到 [專案] --> [設定引用項目] 中,選取 [VISA-COM 5.12 Type Library] 後才能開始寫應用程式

在VB6中宣告如下


  1. '--- General define ---
  2. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'declare to use "sleep"
  3. Dim ioMgr As VisaComLib.ResourceManager
  4. Dim instrument As VisaComLib.FormattedIO488
  5.  
  6. '--- function define ---
  7. Dim ioMgr As VisaComLib.ResourceManagerDim instrument As VisaComLib.FormattedIO488
  8. Dim sndBuffer As String
  9. Dim rcvBuffer As String
  10. Set ioMgr = New VisaComLib.ResourceManager
  11. Set instrument = New VisaComLib.FormattedIO488
  12. Set instrument.IO = ioMgr.Open("USB0::10893::4865::MY59022278::0::INSTR")
  13. instrument.SetBufferSize IO_IN_AND_OUT_BUFS, 64


*IDN?是所有儀器通用的命令,透過這個指令來查詢儀器的 ID。儀器通常會回傳製造商名稱、儀器型號,以及製造商提供的韌體版本英數字元

  1. instrument.WriteString "*IDN?"
  2. Debug.Print instrument.ReadString

讀取電壓與電流的程式如下

  1. '--------------------------
  2. ' Volt
  3. '--------------------------
  4. status = commSend(instrument, "SENSe:VOLTage:DC:NULL:VALue:AUTO 1")
  5. status = commSend(instrument, "CONFigure:VOLTage:DC 10,0.001") ' mV resolution
  6. status = commSend(instrument, "SAMPle:COUNt 1")
  7. status = commSend(instrument, "*WAI")
  8. rcvBuffer = commQuery(instrument, "READ?")
  9.  
  10. '--------------------------
  11. ' Current
  12. '--------------------------
  13. status = commSend(instrument, "SENSe:CURRent:DC:NULL:VALue:AUTO 1")
  14. status = commSend(instrument, "CONFigure:CURRent:DC 1E-6")
  15. status = commSend(instrument, "CURRent:DC:RES 1E-6") ' uA resolution
  16. status = commSend(instrument, "SAMPle:COUNt 1")
  17. status = commSend(instrument, "*WAI")
  18. rcvBuffer = commQuery(instrument, "READ?")

電表是使用USB連接,後來要控制R&S示波器,就想改用TCP/IP的方式試試,也是OK的喔,下面列出幾個範例,讀取波形電壓平均值、上升時間及波形的各點電壓資料

  1. '==================================
  2. ' R&S RTM3004 波形平均值
  3. '==================================
  4. instrument.WriteString "TRIGger:A:EDGE:SLOpe NEGative"
  5. instrument.WriteString "MEASurement1:SOURce CH2"
  6. instrument.WriteString "MEASurement1:MAIN MEAN"
  7. instrument.WriteString "MEASurement1:RESult? MEAN"
  8. '==================================
  9. 'Measure rise time
  10. '==================================
  11. instrument.WriteString "TRIGger:A:EDGE:SLOpe NEGative"
  12. instrument.WriteString "MEASurement1:SOURce CH2"
  13. instrument.WriteString "REFLevel:RELative:MODE TEN" ' 10% - 90%
  14. instrument.WriteString "MEASurement1:MAIN RTIMe"
  15. instrument.WriteString "MEASurement1:RESult?"
  16. '==================================
  17. ' Wave RAW data
  18. '==================================
  19. instrument.WriteString "TRIGger:A:MODE NORMal" ' Normal trigger
  20. instrument.WriteString "TRIGger:A:EDGE:SLOpe NEGative" ' Negative edge
  21.  
  22. instrument.WriteString "FORM ASC" ' output format ASCii
  23. instrument.WriteString "FORM:BORD LSBF"
  24. instrument.WriteString "CHAN1:DATA:POIN DEF"
  25.  
  26. instrument.WriteString "SINGle" ' Single trigger
  27.  
  28. instrument.WriteString "CHANnel1:DATA:HEAD?"
  29. Debug.Print instrument.ReadString
  30.  
  31. instrument.WriteString "CHANnel1:DATA?"
  32. Debug.Print instrument.ReadString

下面是UART、USB與TCP/IP的宣告方式

  1. '=========
  2. 'UART
  3. '=========
  4. Set instrument.IO = ioMgr.Open("ASRL6::INSTR") ' COM6
  5.  
  6. Dim serInfc As VisaComLib.ISerial
  7. Set serInfc = instrument.IO
  8. serInfc.BaudRate = 9600 ' 9600bps baud rate
  9. serInfc.FlowControl = ASRL_FLOW_NONE
  10. serInfc.Timeout = 10000
  11. instrument.IO.SendEndEnabled = True
  12. instrument.IO.TerminationCharacter = 10 ' could be 10 (line feed) or 13 (carriage return)
  13. instrument.IO.TerminationCharacterEnabled = True
  14. instrument.IO.Timeout = 10000
  15.  
  16. '=========
  17. 'USB
  18. '=========
  19. Set instrument.IO = ioMgr.Open("USB0::0x0AAD::0x01D6::104068::INSTR")
  20. instrument.SetBufferSize IO_IN_AND_OUT_BUFS, 64
  21. Set serInfc = instrument.IO
  22.  
  23. '=========
  24. 'TCP/IP
  25. '=========
  26.  
  27. Set instrument.IO = ioMgr.Open("tcpip0::192.168.0.13::instr") ' ip addr 192.168.0.13
  28. instrument.SetBufferSize IO_IN_AND_OUT_BUFS, 64
  29. Set serInfc = instrument.IO

下面是用Arduino與ADS1015做的4通道電表,解析度至小數第二位,使用VBA透過UART讀取電表至Excel表格中

Arduin 用的SCPI Library 有蠻多個 (Vrekrerscpiparser) (Open Instrument Control),下面範例是使用OIC的Library完成的




2020年6月4日 星期四

智能插座改造


最近看到一個智能插座,因為沒有App的支援,所以老闆就便宜賣,價格超便宜,就買了幾個回來準備拆開研究看看,拆開後如下



底部插座跟Relay部分可以延用,上面有一片小板,是藍芽控制板,既然沒有App支援,就乾脆改裝WiFi版的智能插座吧

從抽屜中拿出ESP8266模組,研究一下藍芽小板的走線後,便把藍芽模組拆掉


因為頂部空間有限,要焊接ESP8266上去似乎不太夠,便用漆包線延長,固定在側邊

最後再裝回原來的樣子,WiFi版的智能插座硬體部分就完成了



ESP8266的韌體一樣使用Arduino做開發,使用 IotWebConf 及 arduino-mqtt 的Library,
並以 IotWebConf07MqttRelay 範例進行修改

韌體/硬體完成後,就可以用手機進行設定了,如下是連線後跳出的畫面,按下configure page就可以進行設定



Thing name 可以修改成自己想要的名稱,之後設定 MQTT 時會需要這個名稱
AP password 就是登入這個裝置的WiFi密碼
WiFi SSID 要讓裝置連線的 AP SSID名稱
WiFi password 要讓裝置連線的 AP SSID 密碼  
MQTT server 讓裝置可登入的MQTT sever,因我自己是在 NAS 上增加MQTT的服務,所以這邊是填家中的NAS IP address

接著是新增加的功能,本來的範例除了可以遠端控制外,我還想讓裝置有定時的功能,所以多增加五組的開關機時間

--------------------------------------------------------------------------------

都設定完成後,準備進行測試

安裝 Chrome MQTT延伸擴充功能進行測試,如下為 MQTTLens 套件



一樣將MQTT server設定好,訂閱的路徑設定好,應該就可以對裝置進行操作了

如下圖

Subscribe : /devices/testThing/status 
Publish : /devices/testThing/action

其中的 testThing 就是前面透過手機所設定的 Thing name 名稱

在 Message 填入ON或OFF即可進行測試



--------------------------------------------------------------------------------

以上都在電腦端測試完成後,手機App呢? 

參考另一篇文章,App的設定

https://mattlinotes.blogspot.com/2020/10/app.html

下一步,準備把溫度與濕度 sensor 也一併整合進這個智能插座中,掌握當下的房間狀況,決定要不要遠端啟動受控裝置了


定義Arduino Flash Partition

在Arduino 的工程目錄中,增加一個 partitions.csv 文字檔案,內容範例如下 # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, o...