Ведение журнала Picologger, чтобы преуспеть с помощью VBA

У меня есть регистратор данных picolog 1012, с которого мне нужно получить большое количество данных. Программное обеспечение по умолчанию действительно неприятно в использовании, и PicoTech предоставляет несколько простых примеров сценариев, позволяющих записывать данные в Excel. К сожалению, он регистрирует данные только с двух каналов, а у меня их девять.

Мне удалось настроить интервал регистрации и время, но я не могу заставить число каналов работать правильно.

' Excel Macro for the PicoLog 1000 series
' Pico Technology 2009

Declare Function pl1000OpenUnit Lib "pl1000.dll" (ByRef handle As Integer) As Long
Declare Function pl1000CloseUnit Lib "pl1000.dll" (ByVal handle As Integer) As Long
Declare Function pl1000GetUnitInfo Lib "pl1000.dll" (ByVal handle As Integer, ByVal S As String, ByVal lth As Integer, ByRef requiredSize As Integer, ByVal info As Integer) As Integer
Declare Function pl1000SetTrigger Lib "pl1000.dll" (ByVal handle As Integer, ByVal enabled As Integer, ByVal enable_auto As Integer, ByVal auto_ms As Integer, ByVal channel As Integer, ByVal dir As Integer, ByVal threshold As Integer, ByVal hysterisis As Integer, ByVal delay As Single) As Integer
Declare Function pl1000SetInterval Lib "pl1000.dll" (ByVal handle As Integer, ByRef us_for_block As Long, ByVal ideal_no_of_samples As Long, channels As Integer, ByVal No_of_channels As Integer) As Long
Declare Function pl1000GetValues Lib "pl1000.dll" (ByVal handle As Integer, ByRef values As Integer, ByRef no_of_values As Long, ByRef overflow As Integer, ByRef triggerIndex As Long) As Long
Declare Function pl1000Run Lib "pl1000.dll" (ByVal handle As Integer, ByVal no_of_values As Long, ByVal method As Integer) As Integer
Declare Function pl1000Ready Lib "pl1000.dll" (ByVal handle As Integer, ByRef ready As Integer) As Long
Declare Function pl1000MaxValue Lib "pl1000.dll" (ByVal handle As Integer, ByRef maxValue As Integer) As Long

Dim status As Long
Dim handle As Integer
Dim values(200) As Integer
Dim channels(22) As Integer
Dim nValues As Long
Dim ok As Integer
Dim ready As Integer
Dim requiredSize As Integer
Dim S As String * 255
Public port As Integer
Public product As Integer
Dim maxValue As Integer

Function adc_to_mv(value As Integer) As Integer
  adc_to_mv = value / maxValue * 2500
End Function

Sub GetPl1000()

' Open device
   status = pl1000OpenUnit(handle)
   opened = handle <> 0

If opened Then

  'Get the maximum ADC value for this variant
  status = pl1000MaxValue(handle, maxValue)

' Get the unit information
  Cells(9, "p").value = "Unit opened"
  SLegnth = pl1000GetUnitInfo(handle, S, 255, requiredSize, 3)
  Cells(10, "P").value = S
  SLegnth = pl1000GetUnitInfo(handle, S, 255, requiredSize, 4)
  Cells(11, "P").value = S
  SLegnth = pl1000GetUnitInfo(handle, S, 255, requiredSize, 1)
  Cells(12, "P").value = S

  ' No Trigger
  Call pl1000SetTrigger(handle, False, 0, 0, 0, 0, 0, 0, 0)

  ' Say that we want to take [W3] readings in [W4] s
  ' from channels 1 and 2

    'Set number of samples to read
    Dim samplenum As Integer
    samplenum = Worksheets("Sheet1").Range("W3").value 'Reads number of samples from W3

    nValues = samplenum
    channels(0) = 1
    channels(1) = 2
    channels(2) = 3
    channels(3) = 4
    channels(4) = 5
    channels(5) = 6
    channels(6) = 7
    channels(7) = 8
    channels(8) = 9


    'Set test length
    Dim sampleInterval As Long
    Dim microsecs_for_block As Long

    Dim testlength As Integer
    testlength = Worksheets("Sheet1").Range("$w$4").value
    microsecs_for_block = testlength * 1000000
    status = pl1000SetInterval(handle, microsecs_for_block, nValues, channels(0), 2)''<changing the 2 to a nine really made the data go odd>

    status = pl1000Run(handle, nValues, 0)

    ready = 0
    Do While ready = 0
        status = pl1000Ready(handle, ready)
    Loop

  ' Get a block of 100 readings...
  ' we can call this routine repeatedly
  ' to get more blocks with the same settings
  Dim triggerIndex As Long
  Dim overflow As Integer
  status = pl1000GetValues(handle, values(0), nValues, overflow, triggerIndex)

  ' Copy the data into the spreadsheet
  For i = 0 To nValues - 1
     Cells(i + 4, "A").value = adc_to_mv(values(2 * i))
     Cells(i + 4, "B").value = adc_to_mv(values(2 * i + 1)) '''<I am not sure what this command is doing so I have tried simply expanding it into other columns. The sheet does add data into cells C-E but it appears to be duplicate data from A and B>
     Cells(i + 4, "C").value = adc_to_mv(values(2 * i + 2))
     Cells(i + 4, "D").value = adc_to_mv(values(2 * i + 3))
     Cells(i + 4, "E").value = adc_to_mv(values(2 * i + 4))
  Next i

  ' Close the unit when finished to drop the driver
  Call pl1000CloseUnit(handle)

Else
   MsgBox "Unable to open device", vbCritical
End If

End Sub

Может ли кто-нибудь пролить какое-либо понимание?

Это то, что может решить любой, кто знает что-то о VBA, или вам тоже нужно знание пиколога? Очевидно, что если ничего другого, то для правильной проверки кода нужен пиколог.

1 ответ

Этот код функционален, но он может регистрировать только 12 каналов. Это не будет делать меньше или больше без изменений в коде. Это может сделать его очень медленным для больших наборов данных. Он построен на SDK Picotech

' Excel Macro for the PicoLog 1000 series
' Pico Technology 2009

Declare Function pl1000OpenUnit Lib "pl1000.dll" (ByRef handle As Integer) As Long
Declare Function pl1000CloseUnit Lib "pl1000.dll" (ByVal handle As Integer) As Long
Declare Function pl1000GetUnitInfo Lib "pl1000.dll" (ByVal handle As Integer, ByVal S As String, ByVal lth As Integer, ByRef requiredSize As Integer, ByVal info As Integer) As Integer
Declare Function pl1000SetTrigger Lib "pl1000.dll" (ByVal handle As Integer, ByVal enabled As Integer, ByVal enable_auto As Integer, ByVal auto_ms As Integer, ByVal channel As Integer, ByVal dir As Integer, ByVal threshold As Integer, ByVal hysterisis As Integer, ByVal delay As Single) As Integer
Declare Function pl1000SetInterval Lib "pl1000.dll" (ByVal handle As Integer, ByRef microsecs_for_block As Long, ByVal ideal_no_of_samples As Long, channels As Integer, ByVal No_of_channels As Integer) As Long
Declare Function pl1000GetValues Lib "pl1000.dll" (ByVal handle As Integer, ByRef values As Integer, ByRef no_of_values As Long, ByRef overflow As Integer, ByRef triggerIndex As Long) As Long
Declare Function pl1000Run Lib "pl1000.dll" (ByVal handle As Integer, ByVal no_of_values As Long, ByVal method As Integer) As Integer
Declare Function pl1000Ready Lib "pl1000.dll" (ByVal handle As Integer, ByRef ready As Integer) As Long
Declare Function pl1000MaxValue Lib "pl1000.dll" (ByVal handle As Integer, ByRef maxValue As Integer) As Long

Dim status As Long
Dim handle As Integer
Dim values() As Integer 'set number of datapoints outputted. Should equal samplenum * # ofchannels
Dim channels(12) As Integer
Dim nValues As Long
Dim ok As Integer
Dim ready As Integer
Dim requiredSize As Integer
Dim S As String * 255
Public port As Integer
Public product As Integer
Dim maxValue As Integer

Function adc_to_mv(value As Integer) As Integer
  adc_to_mv = value / maxValue * 2500
End Function

Sub GetPl1000()

Range("P9:P14").ClearContents 'remove device data from last run so that the device data is not displayed in case of error


'Open Device
    status = pl1000OpenUnit(handle)
    opened = handle <> 0

If opened Then

  'Get the maximum ADC value for this variant
  status = pl1000MaxValue(handle, maxValue)

  ' Get the unit information
  Cells(9, "P").value = "Unit opened"
  SLegnth = pl1000GetUnitInfo(handle, S, 255, requiredSize, 3)
  Cells(10, "P").value = S
  SLegnth = pl1000GetUnitInfo(handle, S, 255, requiredSize, 4)
  Cells(11, "P").value = S
  SLegnth = pl1000GetUnitInfo(handle, S, 255, requiredSize, 1)
  Cells(12, "P").value = S

  ' No Trigger
  Call pl1000SetTrigger(handle, False, 0, 0, 0, 0, 0, 0, 0)

  ' Say that we want to take W3 samples in W4 seconds
  ' from channels 1, 2, 3

    ' HM
    Dim numChannels As Integer
    'numChannels = Worksheets("Sheet1").Range("W5").value
    numChannels = 12

    Dim samplenum As Long
        samplenum = Worksheets("Sheet1").Range("W3").value 'Reads number of samples from W3
        nValues = samplenum * numChannels 'HM

    channels(0) = 1
    channels(1) = 2
    channels(2) = 3
    channels(3) = 4
    channels(4) = 5
    channels(5) = 6
    channels(6) = 7
    channels(7) = 8
    channels(8) = 9
    channels(9) = 10
    channels(10) = 11
    channels(11) = 12

    ReDim values(12 * Worksheets("Sheet1").Range("W3").value) 'allow a variable data array
    Dim sampleInterval As Long
    Dim microsecs_for_block As Long

    Dim testlength As Integer
    testlength = Worksheets("Sheet1").Range("W4").value
    microsecs_for_block = testlength * 1000000
    status = pl1000SetInterval(handle, microsecs_for_block, nValues, channels(0), 12)

    status = pl1000Run(handle, nValues, 0)


    ready = 0
    Do While ready = 0
        status = pl1000Ready(handle, ready)
    Loop
 Cells(14, "P").value = "RECORDING COMPLETE" 'indicate readiness
  ' Get a block of W3 readings...
  ' we can call this routine repeatedly
  ' to get more blocks with the same settings
  Dim triggerIndex As Long
  Dim overflow As Integer
  status = pl1000GetValues(handle, values(0), samplenum, overflow, triggerIndex)

  ' Copy the data into the spreadsheet
  For i = 0 To samplenum - 1
     Cells(i + 4, "A").value = adc_to_mv(values(numChannels * i + 0))
     Cells(i + 4, "B").value = adc_to_mv(values(numChannels * i + 1))
     Cells(i + 4, "C").value = adc_to_mv(values(numChannels * i + 2))
     Cells(i + 4, "D").value = adc_to_mv(values(numChannels * i + 3))
     Cells(i + 4, "E").value = adc_to_mv(values(numChannels * i + 4))
     Cells(i + 4, "F").value = adc_to_mv(values(numChannels * i + 5))
     Cells(i + 4, "G").value = adc_to_mv(values(numChannels * i + 6))
     Cells(i + 4, "H").value = adc_to_mv(values(numChannels * i + 7))
     Cells(i + 4, "I").value = adc_to_mv(values(numChannels * i + 8))
     Cells(i + 4, "J").value = adc_to_mv(values(numChannels * i + 9))
     Cells(i + 4, "K").value = adc_to_mv(values(numChannels * i + 10))
     Cells(i + 4, "L").value = adc_to_mv(values(numChannels * i + 11))
  Next i

  ' Close the unit when finished to drop the driver
  Call pl1000CloseUnit(handle)

Else
   MsgBox "Unable to open device", vbCritical
End If

End Sub
Другие вопросы по тегам