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
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