Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

Which data logger for Nortek Vectrino profiler (ADV) and the Nortek Signature1000 (ADCP) on salty environment? Or should I stick with fanless industrial PC?


Venexiano May 4, 2018 02:36 AM

Dear all,
I recently purchased the Nortek Vectrino profiler (ADV) and the Nortek Signature1000 (ADCP). I will deploy them on back barrier basins, mainly salt marshes. The Vectrino profiler does not have internal storage, so I will need to connect it to a data logger. Initially I was thinking of a toughbook/industrial PC but they use too much power, about 60-90W, and I have hard time to power them with a sigle 12V deep cycle 100Ah battery. With the data logger I would need only a few Watts for it and the 2 instruments. The Signature 1000 has an internal memory, so no need to connect it to the data logger, but it would be good If I buy a logger that is compatible with the ADCP too, in case one day I wanna upgrade and get the data collected by the data logger and transmitted via a modem. Which data logger would you suggest? How hard will it  be to program them? This is my first time ever I will use a data logger, but I have good Fortran and Matlab programming skills. However, my student will probably do it.Thank you very much
Best,
Alberto  


JDavis May 17, 2018 08:09 PM

I connected a CR1000 to a Nortek AWAC before. I haven't worked with those particular models you are looking at. If these other models have RS232 output, and a well documented data format, it should be possible.

I have included the program code for reading the AWAC below:

 

'CR1000 Series Datalogger
'Program to collect receive and process velocity and wave data from a Nortek AWAC
'date: March 16, 2012
'program author: Jacob

'Constants
Const VelocityCells = 23  'Number of velocity cells configured in the AWAC. Must be exact.
Const NortekPort = Com2  'Comport where Nortek is connected
Const MaxWaves = 300 'Maximum number of waves within the wave burst
Const MaxWaveSamples = 1200  'Number of samples/wave burst configured in AWAC

'Declare Public Variables
Public PTemp, batt_volt

'Internally used variables
'Dim BufferString As String * 40000 'buffer to hold raw data stream
'Public BufferLength As Long 'length of useable data in BufferString
'Dim StructureString As String * (120 + 9 * VelocityCells) 'Will hold the structure currently processing
'Public StructureLength As Long  'Number of useable bytes in StructureString
'Public BytesAvailable As Long 'Number of bytes available in buffer which may be added to buffer string
'Public NewStructure As Boolean 'Indicates if there is an unprocessed structure in StructureString
'Public ValidStructure As Boolean 'Indicates if structure in StructureString passed checksum test
'Public StructureID As Long  'ID number of the current structure being processed
Public StructureChecksum As Long, CalculatedChecksum As Long 'Used for checksum test

'Velocity Structure Variables
Const VelocityLength =  Ceiling( (120 + 9 * VelocityCells )/2 ) * 2
Dim VelocityStructure As String * (VelocityLength + 4)
Public NBytesvelocity As Long
Public ValidVelocity As Boolean, NewVelocity As Boolean

Public AWACbatt
Public AWACerr As Long
Public Heading, Pitch, Roll
Public Pressure
Public AWACstatus As Long
Public AWACtemperature
Public SoundSpeed

Units AWACbatt = V
Units Heading = Degrees
Units Pressure = dBar
Units AWACtemperature = C

Public VelB1(VelocityCells) As Long,  VelB2(VelocityCells) As Long,  VelB3(VelocityCells) As Long
Public AmpB1(VelocityCells), AmpB2(VelocityCells), AmpB3(VelocityCells)

'Wave Data Header Structure Variables
Dim WaveHeaderStructure As String * 64
Public NewWaveHeader As Boolean, ValidWaveHeader As Boolean
Public NBytesWaveHeader As Long
Public NRecordsWave As Long
Public Blanking As Long
Public MinPress As Long, hMaxPress As Long
Public CellSize As Long
Public Noise(4) As Long
Public ProcMagn(4) As Long

'Stage Data Structure Variables
Const StageLength =  Ceiling( (32 + VelocityCells )/2 ) * 2
Dim StageStructure As String * (StageLength + 4)
Public NBytesStage As Long
Public NewStageStructure As Boolean, ValidStageStructure As Boolean
Public Amplitude(3) As Long
Public AST(2) As Long
Public ASTQuality As Long
Public Velocity(3) As Long
Public StageAmp(VelocityCells) As Long

'Wave Data Variables
Public NewWaveBurst As Boolean  'True when wave samples come in until processing done
Public WaveBurstDone As Boolean 'Indicates the final wave sample has been read from the buffer
Public WaveSampleCount As Long 'Number of Wave Data Structures processed
Public WaveCount As Long 'Number of waves within wave samples

Dim WaveDataStructure As String * 28
Public NewWaveDataStructure As Boolean
Dim tempWaveData As Long
Public ValidWaveData As Boolean
Dim NBytesWaveData As Long
Dim PreviousDistance As Long 'Temp value used in handling zero reading waves
Dim Distance1 As Long   'units is mm
Dim Distance2 As Long
Dim Distance(MaxWaveSamples) As Long 'Corrected for zeros distance to surface, units in mm
Public DepthAvg As Float 'Average of distances, units in m
Public MaxWaveHeight As Float
Public SigWaveHeight As Float
Public AvgWaveHeight As Float

Dim WaveHeight(MaxWaves) As Long 'units is mm
Public SortedHeight(MaxWaves) As Long


Dim DestChange(2), DestPeak As Long, IsPeak As Boolean, PrevPeak As Long
Dim Trough As Long, Peak As Long, ThirdCount As Long

Dim tempLong(6) As Long
Dim i As Long
Dim si As Long, ti As Long

'Define Data Tables
DataTable (Test,1,1000)
  DataInterval (0,60,Sec,10)
  Minimum (1,batt_volt,FP2,0,False)
  Sample (1,PTemp,FP2)
EndTable

DataTable (WaveStats,True,8000)
  Sample (1,MaxWaveHeight,FP2)
  Sample (1,SigWaveHeight,FP2)
  Sample (1,AvgWaveHeight,FP2)
  Sample (1,DepthAvg,FP2)
  Sample (1,WaveCount,FP2)
EndTable

Function SignedInt16(tempDec As Long) 'Converts two byte long to 16bit signed
  If tempDec>32767 Then
    tempDec=tempDec-65536
  EndIf
  SignedInt16=tempDec
EndFunction


Sub ValidateVelocity
  Dim li As Long
  Dim tempInt As Long

  MoveBytes (VelocityStructure,2,VelocityStructure,0,VelocityLength)
  MoveBytes (VelocityStructure,0,&ha520,2,2) 'replace first two bytes removed by SerialInRecord

  tempInt = 0
  For li = 1 To (VelocityLength - 2)
    tempInt = tempInt + ASCII(VelocityStructure(1,1,li))
  Next
  tempInt = &hb721 XOR tempInt 'TODO fix checksum calculation

  CalculatedChecksum = tempInt AND 65535
  StructureChecksum = ASCII(VelocityStructure(1,1,VelocityLength-1)) + 256 * ASCII(VelocityStructure(1,1,VelocityLength))

  'TODO reenable checksum validation
  '  If CalculatedChecksum = StructureChecksum Then 'Validates with checksum
  ValidVelocity = true
  NewVelocity = true
  '  Else
  '    ValidVelocity= false
  'newvelocity = false
  '  EndIf 'Validates with checksum

EndSub

Sub ValidateWaveHeader

  MoveBytes (WaveHeaderStructure,2,WaveHeaderStructure,0,60)
  MoveBytes (WaveHeaderStructure,0,&ha531,2,2) 'replace first two bytes removed by SerialInRecord

  'TODO
  ValidWaveHeader = true

EndSub

Sub ValidateStage
  MoveBytes (StageStructure,2,StageStructure,0,StageLength)
  MoveBytes (StageStructure,0,&ha542,2,2) 'replace first two bytes removed by SerialInRecord


  'TODO
  ValidStageStructure = true
EndSub

Sub ValidateWaveData
  MoveBytes (WaveDataStructure,2,WaveDataStructure,0,24)
  MoveBytes (WaveDataStructure,0,&ha530,2,2) 'replace first two bytes removed by SerialInRecord

  'TODO
  ValidWaveData = true
EndSub

'Main Program
BeginProg
  DestChange(2) = 1

  SerialOpen (NortekPort,9600,3,0,40000)

  Scan (10,Sec,0,0)
    PanelTemp (PTemp,250)
    Battery (batt_volt)
    'Other measurements here

    CallTable Test
  NextScan

  SlowSequence

  Do
    Delay (1,50,mSec)
    'Data Processing

    'Reads Velocity Structure from buffer
    SerialInRecord (NortekPort,VelocityStructure,&ha520,VelocityLength-2,0,NBytesvelocity,110)
    If NBytesvelocity Then NewVelocity = true

    SerialInRecord (NortekPort,WaveHeaderStructure,&ha531,58,0,NBytesWaveHeader,110)
    If NBytesWaveHeader    Then NewWaveHeader = true

    SerialInRecord (NortekPort,StageStructure,&ha542,StageLength-2,0,NBytesStage,110)
    If NBytesStage Then NewStageStructure = true


    'Process Velocity Data
    If NewVelocity Then
      ValidateVelocity()
    EndIf


    If ValidVelocity  AND NewVelocity Then 'Velocity Structure
      NewVelocity = false
      AWACerr = ASCII(VelocityStructure(1,1,11)) + 256 * ASCII(VelocityStructure(1,1,12))
      AWACbatt = (ASCII(VelocityStructure(1,1,15)) + 256 * ASCII(VelocityStructure(1,1,16))) * 0.1
      SoundSpeed  = (ASCII(VelocityStructure(1,1,17)) + 256 * ASCII(VelocityStructure(1,1,18))) * 0.1
      tempLong(1) = (ASCII(VelocityStructure(1,1,19)) + 256 * ASCII(VelocityStructure(1,1,20)))
      Heading = SignedInt16(tempLong(1)) * 0.1
      tempLong(1) = (ASCII(VelocityStructure(1,1,21)) + 256 * ASCII(VelocityStructure(1,1,22)))
      Pitch = SignedInt16(tempLong(1)) * 0.1
      tempLong(1) = (ASCII(VelocityStructure(1,1,23)) + 256 * ASCII(VelocityStructure(1,1,24)))
      Roll = SignedInt16(tempLong(1)) * 0.1
      Pressure  = (ASCII(VelocityStructure(1,1,27)) + 256 * ASCII(VelocityStructure(1,1,28)) + 65536 * ASCII(VelocityStructure(1,1,25)) ) * 0.001
      AWACstatus = ASCII(VelocityStructure(1,1,26))
      tempLong(1)  = (ASCII(VelocityStructure(1,1,29)) + 256 * ASCII(VelocityStructure(1,1,30)))
      AWACtemperature = SignedInt16(tempLong(1)) * 0.01

      tempLong(1) = 0 'initialize
      tempLong(2) = 119 + 2 * VelocityCells 'B2 velocities start
      tempLong(3) = 119 + 4 * VelocityCells 'B3 velocities start
      tempLong(4) = 119 + 6 * VelocityCells 'B1 amp start
      tempLong(5) = 119 + 7 * VelocityCells 'B2 amp start
      tempLong(6) = 119 + 8 * VelocityCells 'B3 amp start
      For si  = 0 To (VelocityCells -1) 'Process cells
        MoveBytes (tempLong(1),3,VelocityStructure,118 + si * 2 ,1)
        MoveBytes (tempLong(1),2,VelocityStructure,119 + si * 2 ,1)
        VelB1(si+1) = SignedInt16(tempLong(1))

        MoveBytes (tempLong(1),3,VelocityStructure,tempLong(2) - 1 + si * 2 ,1)
        MoveBytes (tempLong(1),2,VelocityStructure,tempLong(2)  + si * 2 ,1)
        VelB2(si+1) = SignedInt16(tempLong(1))

        MoveBytes (tempLong(1),3,VelocityStructure,tempLong(3) - 1 + si * 2 ,1)
        MoveBytes (tempLong(1),2,VelocityStructure,tempLong(3)  + si * 2 ,1)
        VelB3(si+1) = SignedInt16(tempLong(1))

        AmpB1(si+1) = ASCII(VelocityStructure(1,1,tempLong(4) + si  ))
        AmpB2(si+1) = ASCII(VelocityStructure(1,1,tempLong(5) + si  ))
        AmpB3(si+1) = ASCII(VelocityStructure(1,1,tempLong(6) + si  ))
      Next  'Process cells
    EndIf 'ValidVelocity


    If NewWaveHeader Then
      ValidateWaveHeader()
    EndIf 'NewWaveHeader

    If NewWaveHeader AND ValidWaveHeader Then
      NRecordsWave = ASCII(WaveHeaderStructure(1,1,11)) + 256 * ASCII(WaveHeaderStructure(1,1,12))
      Blanking = ASCII(WaveHeaderStructure(1,1,13)) + 256 * ASCII(WaveHeaderStructure(1,1,14))
      MinPress = ASCII(WaveHeaderStructure(1,1,25)) + 256 * ASCII(WaveHeaderStructure(1,1,26))
      hMaxPress = ASCII(WaveHeaderStructure(1,1,27)) + 256 * ASCII(WaveHeaderStructure(1,1,28))
      CellSize = ASCII(WaveHeaderStructure(1,1,31)) + 256 * ASCII(WaveHeaderStructure(1,1,32))
      For si =  0 To 3
        Noise(si+1) =   ASCII(WaveHeaderStructure(1,1,33+si))

        ProcMagn(si + 1) = ASCII(WaveHeaderStructure(1,1,37 + si*2)) + 256 * ASCII(WaveHeaderStructure(1,1,38 + si*2))
      Next si

      NewWaveHeader = false

      NewWaveBurst = true
      WaveBurstDone = false
      WaveSampleCount = 0
      WaveCount = 0
    EndIf  'Process Wave Header


    If NewStageStructure Then
      ValidateStage()
    EndIf

    'Process Stage Structure
    If NewStageStructure AND ValidStageStructure Then

      For si =  0 To 2
        Amplitude(si+1) = ASCII(StageStructure(1,1,7 + si))
        tempLong(1) = ASCII(StageStructure(1,1,23 + si*2)) + 256 * ASCII(StageStructure(1,1,24 + si*2))
        Velocity(si + 1) = SignedInt16(tempLong(1))
      Next si
      AST(1) = ASCII(StageStructure(1,1,13)) + 256 * ASCII(StageStructure(1,1,14))
      AST(2) = ASCII(StageStructure(1,1,19)) + 256 * ASCII(StageStructure(1,1,20))

      For si = 0 To VelocityCells - 1
        'amplitude cells
        StageAmp(si + 1) = ASCII(StageStructure(1,1,33+si))
      Next si

      NewStageStructure = false
    EndIf  'Process Stage Structure

  Loop  'End Slowsequence 1 loop

  SlowSequence
  'Wave Statistics Processing Slow Scan
  Do
    Delay (1,50,mSec) 'This delay allows the logger to time slice better and sleep
    'Shorter delay allows faster processing, but will increase power consumption

    If NewWaveBurst Then
      '     SerialInRecord (NortekPort,WaveDataStructure,&ha530,22,0,NBytesWaveData,111)
      tempWaveData = 0
      If SerialInChk(NortekPort) > 23 Then
        SerialInBlock (NortekPort,tempWaveData,1)
        If tempWaveData = &ha5000000 Then 'Correct first byte
          SerialInBlock (NortekPort,tempWaveData,1)
          If tempWaveData = &h30000000 Then 'Correct second byte
            SerialInBlock (NortekPort,WaveDataStructure,22)
            NewWaveDataStructure = true
          EndIf 'Correct second byte
        EndIf 'Correct first byte
      EndIf 'Enough bytes in buffer
    EndIf

    'Process Wave Data Structure
    If NewWaveDataStructure Then
      If WaveSampleCount < MaxWaveSamples Then
        WaveSampleCount = WaveSampleCount + 1
        '     ValidateWaveData()
        '    If ValidWaveData Then
        Distance1 = ASCII(WaveDataStructure(1,1,5)) + 256 * ASCII(WaveDataStructure(1,1,6))
        Distance2 = ASCII(WaveDataStructure(1,1,15)) + 256 * ASCII(WaveDataStructure(1,1,16))
        If Distance1 = 0 Then
          If Distance2 <> 0 Then 'Use distance2 if distance1 = 0
            Distance(WaveSampleCount) = Distance2
            PreviousDistance = Distance(WaveSampleCount)
          Else
            Distance(WaveSampleCount) = PreviousDistance 'Use previous distance if both distance1 and distance2 are 0
          EndIf
        Else
          Distance(WaveSampleCount) = Distance1
          PreviousDistance = Distance(WaveSampleCount)
        EndIf
        If WaveSampleCount = 1 Then PrevPeak = Distance 'starting value
        If Distance(WaveSampleCount) <> 0 Then  'Valid distance reading
          'PeakValley replacement code
          If DestChange(2) = 1 Then 'Going up
            If Distance(WaveSampleCount) > DestChange(1) Then
              DestChange(1) = Distance(WaveSampleCount)
            Else
              DestPeak = DestChange(1)
              DestChange(1) = Distance(WaveSampleCount)
              DestChange(2) = 0
            EndIf
          Else  'Going down
            If Distance(WaveSampleCount) < DestChange(1) Then
              DestChange(1) = Distance(WaveSampleCount)
            Else
              DestPeak = DestChange(1)
              DestChange(1) = Distance(WaveSampleCount)
              DestChange(2) = 1
            EndIf
          EndIf

          If PrevPeak < DestPeak Then
            'Peak
            IsPeak = true
            If Trough <> 0 Then 'Will not trigger if a trough hasn't yet been recorded
              WaveCount = WaveCount + 1
              Peak = DestPeak
              WaveHeight(WaveCount) = Peak - Trough
            EndIf
            PrevPeak = DestPeak
          ElseIf PrevPeak > DestPeak
            'Trough
            IsPeak = false
            Trough = DestPeak
            PrevPeak = DestPeak
          EndIf 'Peak or Trough
        EndIf 'Valid distance reading

        '   EndIf 'Valid wave data
      EndIf 'within sample count
      NewWaveDataStructure = false
      If WaveSampleCount = MaxWaveSamples Then WaveBurstDone = true
    EndIf 'Process Wave Data Structure

    If NewWaveBurst AND WaveBurstDone Then 'Start wave statistics processing
      NewWaveBurst = false
      'Gets data back in synch if off
      SerialFlush(NortekPort)

      'Calculate average depth in meters
      ' AvgSpa (DepthAvg,MaxWaveSamples,Distance())
      tempWaveData = 0
      For ti = 1 To MaxWaveSamples
        tempWaveData = tempWaveData + Distance(ti)
      Next ti
      DepthAvg = (tempWaveData/MaxWaveSamples)/1000 'Convert to m

      'Maximum wave height calculation
      tempWaveData = 0
      For ti = 1 To WaveCount
        If WaveHeight(ti) > tempWaveData Then tempWaveData = WaveHeight(ti)
      Next ti
      MaxWaveHeight = tempWaveData/1000 'Divide by 1000 to get meters

      'Average wave height calculation
      tempWaveData = 0
      For ti = 1 To WaveCount
        tempWaveData = tempWaveData + WaveHeight(ti)
      Next ti
      AvgWaveHeight =  (tempWaveData/WaveCount)/1000 'Divide by 1000 to get meters

      'Significant Wave Height Calculation, most intense calculation
      ThirdCount = INT(WaveCount/3)
      SortSpa (SortedHeight(),MaxWaves,WaveHeight())
      tempWaveData = 0
      For ti =  (MaxWaves - ThirdCount + 1) To MaxWaves
        tempWaveData = tempWaveData + SortedHeight(ti)
      Next ti
      SigWaveHeight =  (tempWaveData / ThirdCount)/1000  'Divide by 1000 to get meters

      Move (WaveHeight(),MaxWaves,0,1) 'Erase waves

      Trough = 0
      DestChange(1) = 0 'Reset variables used for trough/peak recognition
      DestChange(2) = 1
      CallTable (WaveStats)
    EndIf  'End Wave Statistics Processing

  Loop 'End of Wave processing slow scan

EndProg

 

Log in or register to post/reply in the forum.