• No results found

Shakezilla Project

N/A
N/A
Protected

Academic year: 2021

Share "Shakezilla Project"

Copied!
31
0
0

Bezig met laden.... (Bekijk nu de volledige tekst)

Hele tekst

(1)

Shakezilla Project

AMEP Lab Project

Jeroen Glansdorp

October 2019 - February 2020

Size 6 EC

Studentnumber 11004452

Institute Van der Waals-Zeeman Institute Supervisor Dr. Corentin Coulais

Daily supervisor Mr. David Dykstra Msc. Examiner Dr. Rudolf Sprik

Version Final Draft

(2)

1

Introduction

This report describes the experimental setup of the Shakezilla experiment. Shakezilla, as it is called in the labs, is a vibration test system. Work has been underway to prepare the setup for experimentation since before the start of this lab project in October. The shaker itself was prepared by Daan Giessen of the technology center at Science Park. The bulk of the software necessary was written by Taco Walstra, formerly of the technology center.

The goal of this lab project initially was to quickly get the setup experiment-ready and perform a series of experiments. The aim of these experiments would have been to test the vibration damping properties of metamaterials such as the sample that can be seen in Figure 1. Getting the setup to this point has turned out to be significantly more challenging than originally estimated. Therefore, the focus of the lab project ultimately changed to getting the setup as close to what is needed for experiments as possible.

Figure 1: A metamaterial sample to test vibration damping proper-ties on the shaker.

The setup has so far been optimized for the purpose of performing the Shakezilla experiment. This is most specific in the software, which is optimized to do vibration experiments for vibrations with certain acceleration (g-values) and frequency parameters. The following chapters describe the hardware com-ponents, relevant software (Python scripts), and experimental protocol for the Shakezilla experiment. In the end, the experimental setup in lab D0.119 can be used for many experiments in the future. Most prominently with experi-ments where energy is put into a material through vibrations or compression and tension.

(3)

2

Hardware

The experimental setup consists of six pieces of important hardware: the shaker (Vibration Test System TV51140), the amplifier, the NI6211, the camera, the PCB sensor signal conditioner (Model 482C Series), and the computer. Each of these will briefly be described below.

The computer is the simplest part of the setup to describe. Any computer will be able to handle the necessary tasks. It is required to install some software to execute python scripts, like Spyder for example. Also it is necessary to have Pylon Viewer installed to support the use of a Basler camera. Finally, it might be required to have an SSD installed. This will depend on the amount of data that is sent as images.

The National Instruments NI USB-6211, or NI6211, is used for data acquisi-tion. All signals between the amplifier and PCB and the computer pass through the NI6211. The amplifier will receive a signal from the computer through the NI6211 to produce a certain vibration. In the other direction, the computer receives the accelerometer data through the NI6211 when it has gone through the PCB. The PCB Piezotronics device identifies a piezoelectric sensor element (Serial number LW256088) and it’s signal is converted to a low-impedance volt-age signal that can be transmitted to the NI6211.

The TIRAvib power amplifier will receive a signal coming from the computer through the NI6211 to produce a certain vibration in the shaker. This is gener-ally the case in the Shakezilla experiment. Alternatively, a function generator can be used to vary more quickly over a range of vibrations with different fre-quencies. The amplitude of the vibration is controlled by the input dial which can be seen in Figure 2. This seems rather arbitrary as there are no values on the input dial, but this is not a problem if the automated software is used. The amplifier has three different warning lights. The first gives an overload warning when there is too much weight put on the shaker. The second is an overtravel warning when the amplitude of the vibration exceeds the range of the shaker. And the third is a temperature warning which will light up when the tempera-ture in the shaker becomes too high. To prevent the temperatempera-ture from rising, a fan is connected to the shaker. This is important because the temperature warning will always be on when the fan is disconnected or switched off. This fan is very noisy, so the use of noise cancelling headphones is recommended.

(4)

Figure 2: The TIRAvib Power Amplifier is used to produce and change the vibration produced by the shaker.

The TIRAvib shaker has a metal plate on the top which can vibrate at a certain frequency and amplitude (Figure 3). The holes in the plate can be used to attach the sample to the plate. The shaker is connected to the fan, the amplifier and a tube with pressurized air. The pressurized air works as a counter balance to keep the plate at level position when a heavy object is placed on the plate. Also, the shaker is mounted on a 600 kilogram block of concrete to make sure it stays in place.

(5)

Figure 3: The TIRAvib shaker has a plate on top where the sample is screwed on. One accelerometer is attached to the plate and one to the top of the sample.

In addition, the camera that is used is a Basler acA640 (ID 106748) It is con-nected to the computer with a USB cable to send images or video. Additionally, the camera is connected to the NI6211 to allow the use of a software trigger. This can be set up using the Pylon Viewer software in combination with a part of the code written in python (see chapter three). To capture clear images at a high frame rate, it is further important to optimize the lighting around the setup and create a sharp contrast with a dark background.

Finally, a clear overview of how the pieces of hardware are connected can be seen in Figure 4.

(6)

Figure 4: A schematic overview of which pieces of hardware are con-nected and in which direction signals are being send.

3

Software

There are a large number of python scripts that are used in this experiment, of which the most relevant will be listed and described below. Not all python scripts related to this project will be described as some have become irrelevant in the process of setting up the experimental setup. Others are used only in the background (so far) and have not been studied by me. For any questions about these scripts Taco Walstra should be contacted.

The most relevant python scripts are: • global vars.py

• ni6211.py • regulate.py • shakezilla.py • Looping.py

All of these can be found in Appendix A.

The script global vars.py script is the shortest. The most important features there are the two sensitivity values for the two accelerometer channels. These are used to convert the voltage values of the accelerometers to a number of gs. The lines above are only used to debug the system with randomly generated data when there are significant problems with the hardware.

(7)

The second script, ni6211.py, handles most of the commands that are send to the NI6211 DAQ device. While performing the experiment nothing has to be adjusted here. However, when an issue with the hardware occurs this script will likely show some error. Therefore, it is included here in the report.

The third script, regulate.py, is used to regulate the vibration produced by the shaker to the chosen g-value. When an experiment starts, a random signal is sent through the amplifier to the shaker. The resulting vibration is measured with the accelerometers and fed back into the computer. This is then used to regulate closer towards the desired g-value. To achieve this, a PID controller has been implemented in the run() function. The necessary parameters are set in the init () function at the beginning of the script. Once these are tweaked to a workable value, this script will also work in the background during experi-mentation. Also in the run() function, a low pass Butterworth filter is used to eliminate high-frequency noise. To check if the regulation is working, the values of the accelerometer channel used for regulation (ch1) are saved in .csv files. The pandas library is used here. This can be turned on and off by a simple True/False statement. Finally, at the end of the script the determination is made how closely the system has to be regulated. This is done with a combi-nation of an absolute error and a counter to prevent endless regulation. After each regulation attempt, the resulting g-value is shown in console so it is easy to keep track of how close the regulation is getting.

The shakezilla.py scripts is one of the scripts that is used during experimen-tation. The first important function is the handle cmd() function. It describes what happens when commands are send and can be used to trace issues through different scripts. The createGUI() function is used to create an interface to plot the measured data between measurements for a quick check. The data from the two accelerometers is plotted as one blue line (ch0) and one red line (ch1). As mentioned before, ch1 (red line) is used for regulation. So also regulation can be quickly checked in the GUI. When an experiment is started, startMea-surement() is used to call on a number of other functions that plot the data in the GUI and save the data to a .csv file. The plotting of the data is done with plotData(), on draw(), and plotFFT(). Finally, the function saveData() is used to convert the data from voltage-values to g-values and then save these in separate columns in a .csv file. There is one column for time, one for the first accelerometer and one for the second accelerometer. These files are titled ”Ex-pdata#”, where the # signifies the number of the experimental run it belongs to. The last relevant script, Looping.py, is most worked with during experi-mentation. First of all, the class ContinuousPulseTrainGeneration() is used to execute a software trigger at certain intervals during measurements. Every time a software trigger is executed, the camera will take a picture. The only other function that is actively worked with is the do one run() function. A file ”OverviewExp.txt” is created to record the number of the experimental run, the system time of the start of the experiment, the set frequency and g-value.

(8)

This way, it is more convenient to keep track of the experiments done. Also, the pulse train settings can be adjusted here, such as the period, duty cycle, counter, and reset. These are explained in the relevant class. Finally, at the bottom of the script the g-values and frequencies to be measured are decided. One for-loop determines the range for each variable.

In this line below, the first value has to be changed to change the period of the software trigger (full scripts can be found in Appendix A):

p u l s e g e n e 1 = C o n t i n u o u s P u l s e T r a i n G e n e r a t i o n ( 0 . 5 , 0 . 5 , ” dev1 / c t r 0 ” , r e s e t=True ) To change the frequencies and g-values, the lines below should be edited. The

g range describes g-values and the f range describes the frequencies. Finally, t measure gives the measurement time per experiment, i.e. per combination of frequency and g-value.

f o r g in np . a r a n g e ( 2 . 0 , 3 . 0 , 1 . 0 ) : f o r f in np . a r a n g e ( 4 0 , 6 1 , 1 0 ) :

c o u n t = c o u n t + 1 t m e a s u r e = 1 . 0

The output is one text file with an overview of all experiments and a .csv file per experiment.

One additional note here: the diligent reader will probably notice that an extra results file is opened here as well. This is tied in to the way the data was originally saved by mr. Walstra as one large string. This was incorporated smoothly into the workings of the experiment and not easy to remove. Since it does not negatively affect experiments and in the interest of time, this has been left in the code for now.

4

Experimental Protocol

In this section the experimental protocol is described from the moment ev-erything (except the computer) is off until the experiment is completed. It is important to make sure that the two accelerometers are connected to the AI0 and AI1 input ports of the NI6211. In the GUI these signals are shown as ch0 (blue, LW256087) and ch1 (red, LW256088) respectively. Where ch1 is used to regulate, as mentioned before. In the output .csv file the resulting data is also shown in two columns, designated ch0 and ch1 respectively.

The very first step is to switch the amplifier and the fan on. Then the green button on the amplifier has to be pushed and the input dial turned half-way. If the fan is not turned on, the temperature warning will now go off. Additionally, the camera and lighting has to be turned on in order to receive clear images. The experimental setup is now ready to run.

(9)

On the computer the Pylon Viewer software has to be opened to select the camera. In Acquisition Control the software trigger can be selected as well as the folder where the images will be saved. Furthermore, the shakezilla.py and Looping.py scripts are opened in Spyder. Preferably in two separate instances to see the output next to one another. Next, the ranges for g-values and fre-quencies are set in Looping.py as well as the period for the PulseTrain and the measurement time for each run. The combination between for-loops will deter-mine the amount of experimental runs that will be performed.

To start the experiment the shakezilla.py script is run first. This will initial-ize the NI6211 and create the GUI. Once this is done, the Looping.py script is executed. During the experimental runs no actions have to be undertaken, but the data can quickly be checked in the GUI by eye. It is advised to stay in the room when experiments are running.

When the experiments are finished all hardware is turned off in reverse order. Finally, the data and overview files have to be moved to a separate folder. If this is not done, the files will be overwritten when a new series of experiments is started. Therefore, this is extremely important. It is possible to save the files in a separate folder automatically every time to avoid this all together. However, in the interest of time this has not been done so far.

5

Appendix A: Relevant Python Scripts

5.1

global vars.py

debug = F a l s e i f debug == F a l s e :

from PyDAQmx import ∗

from PyDAQmx. DAQmxCallBack import ∗ from PyDAQmx. DAQmxFunctions import ∗ from PyDAQmx. DAQmxConstants import ∗ CH0 SERIAL NR = ”LW256087” CH1 SERIAL NR = ”LW256088” CH0 SENSITIVY = 1 0 0 . 5 #mV/ g CH1 SENSITIVY = 1 0 0 . 0 #mV/ g

5.2

ni6211.py

’ ’ ’ n i d a q a c q u i s i t i o n f u n c t i o n s ’ ’ ’

(10)

import numpy a s np import c t y p e s import t i m e import o s from g l o b a l v a r s import ∗ c l a s s N I 6 2 1 1 ( object ) : def i n i t ( s e l f , c h a n n e l s i n , c h a n n e l s o u t , r e s e t = True ) : global debug print ( ” I n i t i a l i z i n g NI 6211 d e v i c e ” ) i f type ( c h a n n e l s i n ) == type ( ” ” ) : s e l f . c h a n n e l s i n = [ c h a n n e l s i n ] e l s e : s e l f . c h a n n e l s i n = c h a n n e l s i n s e l f . numberOfChannels = c h a n n e l s i n . l e n ( ) i f type ( c h a n n e l s o u t ) == type ( ” ” ) : s e l f . c h a n n e l s o u t = [ c h a n n e l s o u t ] e l s e : s e l f . c h a n n e l s o u t = c h a n n e l s o u t i f r e s e t and debug==F a l s e : DAQmxResetDevice ( c h a n n e l s o u t [ 0 ] . s p l i t ( ’ / ’ ) [ 0 ] ) s e l f . c o n f i g u r e ( ) def c o n f i g u r e ( s e l f ) : global debug i f debug : return s e l f . taskHandleOut = Task ( ” a n a l o g o u t ” ) s a m p l e s = 512 f r e q = 5 sampRate = s a m p l e s ∗ f r e q

s e l f . taskHandleOut . CreateAOVoltageChan ( ”Dev1/ ao0 ” , ” ” , −10.0 , 1 0 . 0 , DAQmx Val Volts , None )

s e l f . taskHandleOut . CfgSampClkTiming ( None , sampRate , DAQmx Val Rising , DAQmx Val ContSamps , s a m p l e s ) t a s k H a n d l e s i n = d i c t ( [ ( name , TaskHandle ( 0 ) ) f o r name in s e l f . c h a n n e l s i n ] )

f o r name in s e l f . c h a n n e l s i n :

DAQmxCreateTask ( ” ” , c t y p e s . b y r e f ( t a s k H a n d l e s i n [ name ] ) )

(11)

#t e r m i n a l C o n f i g v a l u e s :

# DAQMx Val Cfg Default : d e f a u l t c o n f i g a t run t i m e

# DAQmx Val RSE : s i n g l e ended mode ( T h i s i s w i t h r e s p e c t t o AIGND) # DAQmx Val NRSE : non r e f e r e n c e d s i n g l e −ended mode

# NRSE u s e s measures w i t h r e s p o e c t t o a s i n g l e −node a n a l o g i n p u t s e n s e (AISENSE) # DAQmx Val Diff : d i f f e r e n t i a l mode

# DAQmx Val PseudoDiff : p s e u d o d i f f e r e n t i a l mode

DAQmxCreateAIVoltageChan ( t a s k H a n d l e s i n [ name ] , name , ” ” , DAQmx Val RSE , −10.0 , 1 0 . 0 , DAQmx Val Volts , None )

s e l f . t a s k H a n d l e s i n = t a s k H a n d l e s i n def d a c w r i t e ( s e l f , waveform , f r e q , name = None ) :

i f name i s None : name = s e l f . c h a n n e l s o u t [ 0 ] d a t a = waveform w r i t t e n = i n t 3 2 ( ) s a m p l e s = 512 sampRate = s a m p l e s ∗ f r e q

s e l f . taskHandleOut . CfgSampClkTiming ( None , sampRate , DAQmx Val Rising , DAQmx Val ContSamps , s a m p l e s ) s t a t u s = s e l f . taskHandleOut . WriteAnalogF64 ( 5 1 2 , True , 1 0 . 0 , DAQmx Val GroupByChannel , data ,

c t y p e s . b y r e f ( w r i t t e n ) , None ) i f o s . name != ” nt ” : s e l f . taskHandleOut . S t a r t T a s k ( ) return s t a t u s def d a c s t o p ( s e l f ) : s e l f . taskHandleOut . StopTask ( ) def r e a d c h a n n e l ( s e l f , name ) : i f name i s None : name = s e l f . c h a n n e l s i n [ 0 ] t a s k H a n d l e = s e l f . t a s k H a n d l e s i n [ name ] DAQmxStartTask ( t a s k H a n d l e ) d a t a = np . z e r o s ( ( 1 , ) , dtype=np . f l o a t 6 4 ) r e a d = i n t 3 2 ( )

DAQmxReadAnalogF64 ( t a s k H a n d l e , 1 , 1 0 . 0 , DAQmx Val GroupByChannel , data , 1 , c t y p e s . b y r e f ( r e a d ) , None ) DAQmxStopTask ( t a s k H a n d l e ) return d a t a [ 0 ] def s e t D i g i t a l P o r t ( s e l f , v a l u e=True ) : p 1 0 o n = np . a r r a y ( [ 1 ] , dtype=np . u i n t 3 2 ) p 1 0 o f f = np . a r r a y ( [ 0 ] , dtype=np . u i n t 3 2 )

(12)

t i m e o u t =10.0 a u t o s t a r t =1

t a s k = Task ( ” d i g o u t ” ) i f o s . name == ” nt ” :

t a s k . CreateDOChan ( ”Dev1/ p o r t 1 / l i n e 0 ” , ” ” , DAQmx Val ChanForAllLines ) e l s e :

t a s k . CreateDOChan ( ”Dev1/ p o r t 1 /0 ” , ” ” , DAQmx Val ChanForAllLines ) t a s k . S t a r t T a s k ( )

i f v a l u e == True :

t a s k . W r i t e D i g i t a l U 3 2 ( 1 , a u t o s t a r t , t i m e o u t , DAQmx Val GroupByChannel , p 1 0 o n , None , None ) e l s e :

t a s k . W r i t e D i g i t a l U 3 2 ( 1 , a u t o s t a r t , t i m e o u t , DAQmx Val GroupByChannel , p 1 0 o f f , None , None ) t a s k . StopTask ( )

def r e g u l a t i o n S c a n ( s e l f , nsamples , s a m p l e r a t e , name=None ) : i f name i s None : name = s e l f . c h a n n e l s i n [ 0 ] t a s k H a n d l e = Task ( ” r e g u l a t i o n ” ) r e a d = i n t 3 2 ( ) t i m e o u t = ( n s a m p l e s / s a m p l e r a t e ) + 1 . 0 now = t i m e . t i m e ( ) # n s a m p l e s = n s a m p l e s ∗ 2 #t a k e 2 c h a n n e l s #d a t a = np . z e r o s ( ( nsamples , ) , d t y p e = np . f l o a t 6 4 )

d a t a = np . z e r o s ( ( nsamples , ) , dtype=np . f l o a t 6 4 ) #2 t i m e s removed

t a s k H a n d l e . CreateAIVoltageChan ( ” dev1 / a i 1 ” , ” ” , DAQmx Val RSE , −10.0 , 1 0 . 0 , DAQmx Val Volts , None )

t a s k H a n d l e . CfgSampClkTiming ( ” ” , f l o a t ( s a m p l e r a t e ) , DAQmx Val Rising , DAQmx Val FiniteSamps , n s a m p l e s )

t a s k H a n d l e . S t a r t T a s k ( )

p o i n t s r e a d = c t y p e s . b y r e f ( r e a d )

#DAQmxReadAnalogF64 ( t a s k h a n d l e , numSampsPerChannel , t i m e o u t , f i l l m o d e , d a t a a r r a y , #a r r a y s i z e i n S a m p s , ∗ samplePerChanread , ∗ r e s e r v e r d )

t a s k H a n d l e . ReadAnalogF64 ( nsamples , t i m e o u t , DAQmx Val GroupByChannel , data , len ( d a t a ) , p o i n t s r e a d , None )

now2 = t i m e . t i m e ( )

print ( ” s e c o n d s d e l t a : ” , now2−now ) t a s k H a n d l e . StopTask ( )

return d a t a

def s c a n C h a n n e l s ( s e l f , nsamples , s a m p l e r a t e , name=None ) : print ( ” s t a r t i n g s c a n o f ” , s e l f . c h a n n e l s i n )

(13)

i f name i s None : name = s e l f . c h a n n e l s i n [ 0 ] t a s k H a n d l e = Task ( ) r e a d = i n t 3 2 ( ) t i m e o u t = ( n s a m p l e s / s a m p l e r a t e ) + 1 . 0 now = t i m e . t i m e ( ) # n s a m p l e s = n s a m p l e s ∗ 2 #t a k e 2 c h a n n e l s #d a t a = np . z e r o s ( ( nsamples , ) , d t y p e = np . f l o a t 6 4 ) d a t a = np . z e r o s ( ( n s a m p l e s ∗ 2 , ) , dtype=np . f l o a t 6 4 ) #2 t i m e s n e c e s s a r y on w i n d o z z z z z e #DAQmxCreateAIVoltageChar ( t a s k H a n d l e , physicalChannelName , t e r m i n a l C o n f i g #t e r m i n a l C o n f i g v a l u e s :

# DAQMx Val Cfg Default : d e f a u l t c o n f i g a t run t i m e

# DAQmx Val RSE : s i n g l e ended mode ( T h i s i s w i t h r e s p e c t t o AIGND) # DAQmx Val NRSE : non r e f e r e n c e d s i n g l e −ended mode

# NRSE u s e s measures w i t h r e s p o e c t t o a s i n g l e −node a n a l o g i n p u t s e n s e (AISENSE) # DAQmx Val Diff : d i f f e r e n t i a l mode

# DAQmx Val PseudoDiff : p s e u d o d i f f e r e n t i a l mode

t a s k H a n d l e . CreateAIVoltageChan ( ” dev1 / a i 0 : 1 ” , ” ” , DAQmx Val RSE , −10.0 , 1 0 . 0 , DAQmx Val Volts , None )

t a s k H a n d l e . CfgSampClkTiming ( ” ” , f l o a t ( s a m p l e r a t e ) , DAQmx Val Rising , DAQmx Val FiniteSamps , n s a m p l e s )

t a s k H a n d l e . S t a r t T a s k ( )

p o i n t s r e a d = c t y p e s . b y r e f ( r e a d )

#DAQmxReadAnalogF64 ( t a s k h a n d l e , numSampsPerChannel , t i m e o u t , f i l l m o d e , d a t a a r r a y , #a r r a y s i z e i n S a m p s , ∗ samplePerChanread , ∗ r e s e r v e r d )

t a s k H a n d l e . ReadAnalogF64 ( nsamples , t i m e o u t , DAQmx Val GroupByChannel , data , len ( d a t a ) , p o i n t s r e a d , None ) now2 = t i m e . t i m e ( ) print ( ” s e c o n d s d e l t a : ” , now2−now ) t a s k H a n d l e . StopTask ( ) return d a t a

5.3

regulate.py

’ ’ ’ r e g u l a t e . py s i m p l e PID r e g u l a t i o n f o r c o n s t a n t g v a l u e . We o u t p u t a new a m p l i t u d e v a l u e t o t h e DAC0 o u t p u t ’ ’ ’

from PyQt5 . QtWidgets import ∗

(14)

import t i m e import numpy a s np import random from d e t e c t p e a k s import d e t e c t p e a k s from s c i p y . s i g n a l import b u t t e r , l f i l t e r , f r e q z from g l o b a l v a r s import ∗ import pandas a s pd c l a s s R e g u l a t e ( QThread ) : r e g u l a t i o n e v e n t = p y q t S i g n a l ( d i c t )

def i n i t ( s e l f , daq , f r e q , debug = True , s e t p o i n t = 0 . 0 ) : QThread . i n i t ( s e l f ) print ( ” s t a r t i n g r e g u l a t i n g p r o c e s s . . . ” ) s e l f . daq = daq #s e l f . ampl = ampl s e l f . f r e q = f r e q s e l f . debug = debug s e l f . e n a b l e R e g = F a l s e s e l f . s e t p o i n t = s e t p o i n t s e l f . Kp = 2 . 0 s e l f . Ki = 0 . 1 5 s e l f . Ci = 0 . 0 #i n t e g r a l term s e l f . Kd = 0 . 0 s e l f . o f f s e t = 0 . 0 #o f f s e t i s u s e d t o o u t p u t some f i x e d v a l u e s e l f . mutex = QMutex ( ) s e l f . e r r o r = 0 . 0 s e l f . s a m p l e s = 512 s e l f . ampl = s e l f . s e t p o i n t #### TBD u s e some c a l i b r a t i o n f o r c o r r e c t a m p l i t u d e s e l f . r a t e = s e l f . s a m p l e s ∗ 10 o u t p u t c h a n n e l = [ ”Dev1/ ao1 ” ] def c r e a t e s i n e ( s e l f , f r e q , ampl ) : t i m e i n t e r v a l = s e l f . s a m p l e s / f r e q t = np . l i n s p a c e ( 0 , t i m e i n t e r v a l , s e l f . s a m p l e s ) d a t a = ampl ∗ np . s i n ( 2 ∗ np . p i ∗ f r e q ∗ t ) . a s t y p e ( np . f l o a t 6 4 ) return d a t a def s e t d a c ( s e l f ) : global debug print ( ”#################################” ) d a t a = s e l f . c r e a t e s i n e ( s e l f . f r e q , s e l f . ampl ) i f debug == F a l s e : s e l f . daq . d a c s t o p ( ) s e l f . daq . d a c w r i t e ( data , s e l f . f r e q )

(15)

t i m e . s l e e p ( 1 ) def s e t s e t p o i n t ( s e l f , s e t p o i n t ) : s e l f . s e t p o i n t = s e t p o i n t s e l f . ampl = s e t p o i n t / 1 0 . 0 # t o b e c o r r e c t e d w i t h c u r v e def s e t f r e q u e n c y ( s e l f , f r e q ) : s e l f . f r e q = f r e q def checkRegEnabled ( s e l f ) : return s e l f . e n a b l e R e g def checkRegOutput ( s e l f ) : return s e l f . e r r o r #mmm t h i s s h o u l d b e i n d i c a t i o n t h a t r e g . h a s s e t t l e d w i t h i n a c e r t a i n l i m i t def s t a r t r e g ( s e l f ) : print ( ” e n a b l i n g r e g u l a t i o n ” ) s e l f . e n a b l e R e g = True s e l f . c o u n t = 0 s e l f . Ci = 0 . 0 #i n t e g r a l term o f t h e PI r e g . def s t o p r e g ( s e l f ) : s e l f . e n a b l e R e g = F a l s e def s t o p d a c o u t p u t ( s e l f ) : global debug i f debug == F a l s e : s e l f . daq . d a c s t o p ( ) def b u t t e r l o w p a s s ( s e l f , c u t o f f , f s , o r d e r = 5 ) : nyq = 0 . 5 ∗ f s n o r m a l c u t o f f = c u t o f f / nyq b , a = b u t t e r ( o r d e r , n o r m a l c u t o f f , btype = ’ low ’ , a n a l o g= F a l s e ) return b , a

#run method g e t s c a l l e d when we s t a r t t h e t h r e a d def run ( s e l f ) : global debug s e n s o r c h a n n e l = ”Dev1/ a i 0 ” # s t d d e v = 0 . 9 9 #dummy i n i t e r r o r = 1 0 0 0 . #dummy i n i t f r e q i n p = 10000 while True : i f s e l f . checkRegEnabled ( ) : # s t d d e v = 0 . 9 9 s e l f . c o u n t += 1

(16)

print ( ” r u n n i n g r e g u l a t i o n run no ” , s e l f . c o u n t ) i f debug==F a l s e : #s e n s o r v a l u e s = s e l f . daq . r e g u l a t i o n S c a n ( 5 1 2 , i n t ( s e l f . f r e q ∗ 1 0 0 ) ) s e n s o r v a l u e s = s e l f . daq . r e g u l a t i o n S c a n ( i n t ( 0 . 5 ∗ f r e q i n p ) , f r e q i n p ) e l s e : print ( ” debug s e n s o r v a l u e s ” )

s e n s o r v a l u e s = np . a r r a y ( [ random . random ( ) f o r i in range ( 1 0 0 ) ] ) print ( ” a c q u i r e d : ” , s e n s o r v a l u e s ) s e n s o r v a l u e s= s e n s o r v a l u e s ∗ 1 0 0 0 . 0 /CH1 SENSITIVY i n d s=range ( −301 , −1 ,10) print ( ” s e n s o r v a l u e s i n g : ” , s e n s o r v a l u e s [ i n d s ] ) s a m p l e r a t e = f r e q i n p#i n t ( s e l f . f r e q ∗ 1 0 0 ) b , a = s e l f . b u t t e r l o w p a s s ( s e l f . f r e q ∗ 8 , s a m p l e r a t e , o r d e r =4) y = l f i l t e r ( b , a , s e n s o r v a l u e s ) i n d = d e t e c t p e a k s ( y , mph = 0 . 3 ∗ np .max( y ) , mpd=20 , t h r e s h o l d =0 , show=F a l s e ) print ( ” i n d : ” , i n d ) p e a k d a t a s e t = [ s e n s o r v a l u e s [ i ] f o r i in i n d ] #i t l o o k s t h a t t h e f i r s t p e a k i s o f t e n n o t v e r y a c c u r a t e . We #t r y t o s k i p t h a t one i f we h a v e enough d a t a i f len ( i n d ) > 1 : p e a k d a t a s e t = p e a k d a t a s e t [ 1 : ] e l s e : #p e a k d a t a s e t = [ s e n s o r v a l u e s [ i ] f o r i i n i n d ] p e a k d a t a s e t = [ y [ i ] f o r i in i n d ] print ( p e a k d a t a s e t ) #@@@@@@@ c h e c k i f i n d and p e a k d a t a s e t a r e n o t empty ! ! i f len ( p e a k d a t a s e t ) != 0 : #s t d d e v = np . s t d ( p e a k d a t a s e t ) peaks mean = np . mean ( p e a k d a t a s e t ) e l s e : peaks mean = 10000 s a v e r e g v a l s = True i f s a v e r e g v a l s : c h 1 d i c = {} c h 1 d i c [ ’ ch1 ’ ] = 1 . ∗ s e n s o r v a l u e s ch1 DF = pd . DataFrame ( c h 1 d i c ) ch1 DF . t o c s v ( ’ R egDa ta ch1 ’+s t r ( s e l f . c o u n t )+ ’ . c s v ’ ) c h 1 f i l t d i c = {} c h 1 f i l t d i c [ ’ c h 1 f i l t ’ ] = 1 . ∗ y c h 1 f i l t d i c [ ’ ch1 ’ ] = 1 . ∗ s e n s o r v a l u e s

(17)

c h 1 f i l t D F = pd . DataFrame ( c h 1 f i l t d i c ) c h 1 f i l t D F . t o c s v ( ’ R e g D a t a c h 1 f i l t ’+s t r ( s e l f . c o u n t )+ ’ . c s v ’ ) c h 1 p e a k d i c = {} c h 1 p e a k d i c [ ’ c h 1 p e a k ’ ] = 1 . ∗ np . a r r a y ( p e a k d a t a s e t ) ch1 peak DF = pd . DataFrame ( c h 1 p e a k d i c ) ch1 peak DF . t o c s v ( ’ R e g D a t a c h 1 p e a k ’+s t r ( s e l f . c o u n t )+ ’ . c s v ’ ) # ============================================================================= # ch1 peak DF . t o c s v ( ’ T o g e t h e r D a t a c h 1 ’+ s t r ( s e l f . c o u n t ) + ’ . c s v ’ ) # c h 1 f i l t D F . t o c s v ( ’ T o g e t h e r D a t a c h 1 ’+ s t r ( s e l f . c o u n t ) + ’ . c s v ’ ) # =============================================================================

print ( ”mean : ” , peaks mean )

s i g n a l a r g = d i c t ( ) #r e p o r t t o c l i e n t s i g n a l a r g [ ” r e g s t a t u s ” ] = peaks mean s e l f . r e g u l a t i o n e v e n t . e m i t ( s i g n a l a r g )

i f peaks mean != 1 0 0 0 0 : #p r e v e n t ’ s t u p i d ’ ampl v a l u e s from wrong o r non e x i s t i n g p e a k s

e r r o r = s e l f . s e t p o i n t − peaks mean #TBD p e a k s mean i n g print ( ” s e t p o i n t e r r o r : ” , e r r o r ) i f np . abs ( e r r o r ) < 5 : #e r r o r = s e l f . s e t p o i n t − peaks mean s e l f . Cp = s e l f . Kp ∗ e r r o r #s e l f . Ci += s e l f . Ki ∗ s e l f . e r r o r #s e l f . ampl = s e l f . o f f s e t + s e l f . P v a l u e + s e l f . I v a l u e #u p d a t e t h i s i n r e g #t h i s i s a b i t t r i c k y . The a m p l i t u d e h a p p e n s t o b e i n t h e o r d e r o f t h e g #s e t p o i n t . a t l e a s t i t ’ s a s t a r t i n g p o i n t . Needs t o b e t w e a k e d . s e l f . ampl = s e l f . ampl + ( s e l f . Cp + s e l f . Ci ) / 1 0 . 0 print ( ” a m p l i t u d e t o be s e n d t o DAC: ” , s e l f . ampl ) i f s e l f . ampl <=0.0:

s e l f . ampl = 0 . 5 e l i f s e l f . ampl > 1 0 . 0 :

s e l f . ampl = 1 0 . 0 i f debug == F a l s e :

s e l f . s e t d a c ( ) #s e t t h e dac o u t p u t w i t h s e l f . f r e q and s e l f . ampl t i m e . s l e e p ( 1 )

i f s e l f . c o u n t >= 20 or np . abs ( e r r o r ) < 0 . 0 1 : print ( ” r e s u l a t i o n s e t t l e d ” )

(18)

s e l f . s t o p r e g ( )

s e l f . r e g u l a t i o n e v e n t . e m i t ( e v e n t a r g ) i f n a m e ==” m a i n ” :

print ( ” debug : ” , debug )

5.4

shakezilla.py

’ ’ ’ p y t h o n a p p l i c a t i o n f o r a c c e l e r a t i o n measurements u s i n g p c b s e n s o r s and N a t i o n a l I n s t r u m e n t s NI 6211 T h i s i s t h e ” s h a k e z i l l a ” v e r s i o n . e x p r i m e n t i n t e r f a c e u s i n g s e p a r a t e p y t h o n s c r i p t w i t h zermq i n t e r f a c e t o t h i s s e r v e r . u s b d a t a a c q u i s i t i o n s y s t e m . See README. md f o r d e t a i l s .

T h i s a p p l i c a t i o n can b e run i n d e b u g mode

I t can b e run on windows and l i n u x . T e s t t e d on windows 10 and l i n u x c e n t o s 7 2 0 1 9 . Taco W a l s t r a ( t . r . w a l s t r a @ u v a . n l ) F e b r u a r y −a u g u s t 2019 ’ ’ ’ import numpy a s np import pandas a s pd import c t y p e s import s y s import t i m e import t h r e a d i n g

from zmqhandler import ZmqCmdHandler , ZmqDataHandler , ZmqEventHandler from r e g u l a t e import R e g u l a t e

import m a t p l o t l i b . p y p l o t a s p l t from m a t p l o t l i b . f i g u r e import F i g u r e

from m a t p l o t l i b . b a c k e n d s . b a c k e n d q t 5 a g g import FigureCanvasQTAgg a s F i g u r e C a n v a s

from m a t p l o t l i b . b a c k e n d s . b a c k e n d q t 5 a g g import NavigationToolbar2QT a s N a v i g a t i o n T o o l b a r from PyQt5 . QtWidgets import ∗

from PyQt5 . QtCore import Qt , QThread from f i l t e r import F i l t e r

from g l o b a l v a r s import ∗ from n i 6 2 1 1 import N I 6 2 1 1

c l a s s Experiment ( QWidget ) :

(19)

QWidget . i n i t ( s e l f , p a r e n t ) i f debug == F a l s e : s e l f . daq = N I 6 2 1 1 ( c h a n n e l s i n , c h a n n e l s o u t ) e l s e : s e l f . daq = None print ( ” debug v e r s i o n a c t i v e . No N I 6 2 1 1 i n i t i a l i s a t i o n ” ) s e l f . t o t a l T i m e U n i t = True f i r s t l i n e = True s e l f . c r e a t e F i l e = F a l s e s e l f . d a t a = [ ] s e l f . t d a t a = [ ] s e l f . s a m p l e r a t e = 0 s e l f . e x p c m d i f = ZmqCmdHandler ( ) s e l f . e x p c m d i f . c m d s i g n a l . c o n n e c t ( s e l f . handle cmd ) s e l f . e x p c m d i f . s t a r t ( ) s e l f . e x p d a t a i f = ZmqDataHandler ( ) s e l f . e x p d a t a i f . s t a r t ( ) s e l f . e x p e v e n t i f = ZmqEventHandler ( ) s e l f . e x p e v e n t i f . s t a r t ( ) s e l f . f r e q u e n c y = 1 0 . 0 s e l f . s e t p o i n t = 2 . 0 s e l f . r e g t h r e a d= R e g u l a t e ( s e l f . daq , s e l f . f r e q u e n c y , debug , s e l f . s e t p o i n t ) s e l f . r e g t h r e a d . r e g u l a t i o n e v e n t . c o n n e c t ( s e l f . e x p e v e n t i f . p u b l i s h e v e n t ) s e l f . r e g t h r e a d . s t a r t ( ) print ( ” C r e a t i n g GUI” ) s e l f . c r e a t e G U I ( ) def handle cmd ( s e l f , cmd ) : print ( ” h a n d l i n g cmd : ” , cmd [ 0 ] ) i f cmd [ 0 ] == ” s t a r t a c q ” : print ( ” h a n d l i n g s t a r t acq ” ) s a m p l e r a t e = i n t ( cmd [ 1 ] ) s e l f . s a m p l e r a t e S p i n B o x . s e t V a l u e ( s a m p l e r a t e ) m e a s t i m e = s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . v a l u e ( ) #a l w a y s i n s e c o n d s n s a m p l e s = i n t ( m e a s t i m e ∗ s a m p l e r a t e ) s e l f . n s a m p l e s L i n e E d i t . s e t T e x t ( s t r ( n s a m p l e s ) ) s e l f . s t a r t M e a s u r e m e n t ( i n t ( cmd [ 2 ] ) ) e l i f cmd [ 0 ] == ” s e t t r i g g e r ” : s e l f . s e t T r i g g e r ( True ) e l i f cmd [ 0 ] == ” c l e a r t r i g g e r ” : s e l f . s e t T r i g g e r ( F a l s e ) e l i f cmd [ 0 ] == ” s e t s h a k e r ” : s e l f . s e t p o i n t = f l o a t ( cmd [ 1 ] ) s e l f . f r e q = f l o a t ( cmd [ 2 ] )

(20)

print ( ” s e t p o i n t : ” , s e l f . s e t p o i n t ) print ( ” f r e q : ” , s e l f . f r e q ) s e l f . r e g t h r e a d . s e t f r e q u e n c y ( s e l f . f r e q ) s e l f . r e g t h r e a d . s e t s e t p o i n t ( s e l f . s e t p o i n t ) s e l f . r e g t h r e a d . s e t d a c ( ) e l i f cmd [ 0 ] == ” s t a r t r e g ” : s e l f . r e g t h r e a d . s t a r t r e g ( ) e l i f cmd [ 0 ] == ” s t o p r e g ” : s e l f . r e g t h r e a d . s t o p r e g ( ) e l i f cmd [ 0 ] == ” s t o p d a c ” : s e l f . r e g t h r e a d . s t o p d a c o u t p u t ( ) #s t o p t h e dac o u t p u t t a s k e l i f cmd [ 0 ] == ” s e t m e a s u r e t i m e ” : s e l f . s e t T o t a l M e a s u r i n g T i m e ( cmd [ 1 ] ) e l i f cmd [ 0 ] == ” q u i t ” : s e l f . e x p c m d i f . t e r m i n a t e ( ) s e l f . e x p d a t a i f . t e r m i n a t e ( ) e l s e :

print ( ” R e c e i v e d unknown command” ) def s e t T r i g g e r ( s e l f , v a l u e=True ) : i f debug == F a l s e : i f v a l u e == True : s e l f . daq . s e t D i g i t a l P o r t ( True ) e l s e : s e l f . daq . s e t D i g i t a l P o r t ( F a l s e ) def c r e a t e G U I ( s e l f ) : s e l f . f i g = F i g u r e ( ( 4 5 . 0 , 6 4 . 0 ) , d p i = 1 0 0 ) s e l f . c a n v a s = F i g u r e C a n v a s ( s e l f . f i g ) s e l f . t o o l b a r = N a v i g a t i o n T o o l b a r ( s e l f . canvas , s e l f ) s e l f . c a n v a s . s e t P a r e n t ( s e l f ) s e l f . p l o t W i d g e t = QWidget ( s e l f ) s e l f . ax = s e l f . f i g . a d d s u b p l o t ( 2 1 1 , a u t o s c a l e o n = True , f a c e c o l o r = ’#FFFFCC ’ ) s e l f . ax . a u t o s c a l e v i e w ( True , True , True )

s e l f . ax . s e t x l a b e l ( ” t [ s ] ” ) s e l f . ax . s e t y l a b e l ( ” g [m/ s ˆ 2 ] ” ) s e l f . ax . g r i d ( )

s e l f . bx = s e l f . f i g . a d d s u b p l o t ( 2 1 2 , a u t o s c a l e o n = True , f a c e c o l o r = ’#FFFFCC ’ ) s e l f . bx . a u t o s c a l e v i e w ( True , True , True )

s e l f . bx . s e t x l a b e l ( ” f [ Hz ] ” ) s e l f . bx . s e t y l a b e l ( ” g [m/ s ˆ 2 ] ” )

(21)

s e l f . bx . g r i d ( ) s e l f . t d a t a = [ ] s e l f . ydata = [ ] s t a r t B u t t o n = QPushButton ( ” S t a r t ” ) s t a r t B u t t o n . s e t E n a b l e d ( F a l s e ) #s t a r t B u t t o n . c l i c k e d . c o n n e c t ( s e l f . s t a r t M e a s u r e m e n t ) daqGroupBox = QGroupBox ( ”DAQ s e t t i n g s ” )

f i l e n a m e L a b e l = QLabel ( ” Data f i l e n a m e ” ) s e l f . f i l e n a m e L i n e E d i t = QLineEdit ( ) s e l f . f i l e n a m e L i n e E d i t . s e t T e x t ( ” r e s u l t s 1 . c s v ” ) s e l f . f i l e n a m e L i n e E d i t . s e t E n a b l e d ( F a l s e ) s e l f . v o l t a g e D a t a C h e c k e d = QCheckBox ( ” V o l t a g e v a l u e s ” ) s e l f . v o l t a g e D a t a C h e c k e d . s e t C h e c k e d ( True ) n s a m p l e s L a b e l = QLabel ( ”Number o f s a m p l e s / c h a n n e l ” ) s e l f . n s a m p l e s L i n e E d i t = QLineEdit ( ) s e l f . n s a m p l e s L i n e E d i t . s e t T e x t ( s t r ( 1 0 0 0 ) ) s e l f . n s a m p l e s L i n e E d i t . setReadOnly ( True ) s a m p l e r a t e L a b e l = QLabel ( ” S a m p l e r a t e ” ) s e l f . s a m p l e r a t e S p i n B o x = QSpinBox ( ) s e l f . s a m p l e r a t e S p i n B o x . s e t R a n g e ( 0 , 2 5 0 0 0 0 ) s e l f . s a m p l e r a t e S p i n B o x . s e t V a l u e ( 1 0 0 0 ) measTimeLabel = QLabel ( ” T o t a l m e a s u r i n g t i m e ” ) s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x = QDoubleSpinBox ( ) s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . s e t V a l u e ( 1 . 0 ) s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . s e t R a n g e ( 0 . 0 , 2 0 0 0 0 . 0 ) s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . setReadOnly ( F a l s e ) s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . s e t A l i g n m e n t ( Qt . A l i g n R i g h t ) secminGroupBox = QGroupBox ( ” t i m e u n i t s ” ) s e l f . s e c R a d i o = QRadioButton ( ” s e c o n d s ” ) s e l f . s e c R a d i o . s e t C h e c k e d ( True ) s e l f . minRadio = QRadioButton ( ” m i n u t e s ” ) s ec m i nL a yo u t = QVBoxLayout ( ) s ec m i nL a yo u t . addWidget ( s e l f . s e c R a d i o ) s ec m i nL a yo u t . addWidget ( s e l f . minRadio ) secminGroupBox . s e t L a y o u t ( s ec m in L ay o ut ) s e l f . s e c R a d i o . t o g g l e d . c o n n e c t ( lambda : s e l f . s e c m i n B t n S t a t e ( s e l f . s e c R a d i o ) ) s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . valueChanged . c o n n e c t ( s e l f . updateTotalMeasuringTime ) s e l f . s a m p l e r a t e S p i n B o x . valueChanged . c o n n e c t ( s e l f . updateTotalMeasuringTime ) #FFT l i m i t s

(22)

s e l f . f r e q L i m i t L a b e l = QLabel ( ”FFT r a n g e ” ) s e l f . l o w e r F r e q L i m i t = QSpinBox ( ) s e l f . l o w e r F r e q L i m i t . s e t R a n g e ( 0 , 1 0 0 ) s e l f . l o w e r F r e q L i m i t . s e t V a l u e ( 0 ) s e l f . u p p e r F r e q L i m i t = QSpinBox ( ) s e l f . u p p e r F r e q L i m i t . s e t R a n g e ( 0 , 1 0 0 0 ) s e l f . u p p e r F r e q L i m i t . s e t V a l u e ( 1 0 ) s e l f . s e t F r e q L i m i t = QPushButton ( ” s e t FFT r a n g e ” ) s e l f . s e t F r e q L i m i t . c l i c k e d . c o n n e c t ( s e l f . setFFTRange ) s e l f . r e p l o t B t n = QPushButton ( ” R e p l o t ” ) #t o s o l v e M a t p l o t l i b bug s e l f . r e p l o t B t n . c l i c k e d . c o n n e c t ( s e l f . r e p l o t ) s e l f . f i l t e r B t n = QPushButton ( ” F i l t e r d a t a . . . ” ) s e l f . f i l t e r B t n . c l i c k e d . c o n n e c t ( s e l f . f i l t e r d a t a ) l a y o u t = QGridLayout ( ) l a y o u t . addWidget ( s e l f . t o o l b a r , 0 , 0 ) l a y o u t . addWidget ( s e l f . canvas , 1 , 0 ) c n t r l = QGridLayout ( ) c n t r l . addWidget ( f i l e n a m e L a b e l , 0 , 0 ) c n t r l . addWidget ( s e l f . f i l e n a m e L i n e E d i t , 0 , 1 ) c n t r l . addWidget ( s e l f . v o l t a g e D a t a C h e c k e d , 0 , 2 ) c n t r l . addWidget ( s t a r t B u t t o n , 1 , 1 ) c n t r l . addWidget ( n s a m p l e s L a b e l , 2 , 0 ) c n t r l . addWidget ( s e l f . n s a m p l e s L i n e E d i t , 2 , 1 ) c n t r l . addWidget ( s a m p l e r a t e L a b e l , 3 , 0 ) c n t r l . addWidget ( s e l f . s a m p l e r a t e S p i n B o x , 3 , 1 ) c n t r l . addWidget ( measTimeLabel , 4 , 0 ) c n t r l . addWidget ( s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x , 4 , 1 ) c n t r l . addWidget ( secminGroupBox , 4 , 2 ) c n t r l . addWidget ( s e l f . f r e q L i m i t L a b e l , 5 , 0 ) c n t r l . addWidget ( s e l f . l o w e r F r e q L i m i t , 5 , 1 ) c n t r l . addWidget ( s e l f . u p p e r F r e q L i m i t , 5 , 2 ) c n t r l . addWidget ( s e l f . s e t F r e q L i m i t , 6 , 1 ) c n t r l . addWidget ( s e l f . r e p l o t B t n , 7 , 1 ) c n t r l . addWidget ( s e l f . f i l t e r B t n , 7 , 2 ) daqGroupBox . s e t L a y o u t ( c n t r l ) l a y o u t . addWidget ( daqGroupBox , 1 , 1 )

(23)

s e l f . s e t L a y o u t ( l a y o u t ) s e l f . s e t W i n d o w T i t l e ( ” A c c e l e r o m e t e r ” ) s e l f . r e s i z e ( 1 0 0 0 , 6 2 0 ) def s e c m i n B t n S t a t e ( s e l f , b ) : i f b . t e x t ( ) == ” s e c o n d s ” : i f b . i s C h e c k e d ( ) == True : s e l f . t o t a l T i m e U n i t = True e l s e : s e l f . t o t a l T i m e U n i t = F a l s e s e l f . updateTotalMeasuringTime ( ) def setFFTRange ( s e l f ) : l o w e r L i m i t = s e l f . l o w e r F r e q L i m i t . v a l u e ( ) u p p e r L i m i t = s e l f . u p p e r F r e q L i m i t . v a l u e ( ) i f u p p e r L i m i t <= l o w e r L i m i t : warn = QErrorMessage ( s e l f )

warn . showMessage ( ” Cannot s e t FFT f r e q u e n c y r a n g e s ” ) e l s e : s e l f . bx . s e t x l i m ( l o w e r L i m i t , u p p e r L i m i t ) s e l f . on draw ( ) def s e t T o t a l M e a s u r i n g T i m e ( s e l f , v a l u e ) : s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . s e t V a l u e ( v a l u e ) s e l f . updateTotalMeasuringTime ( ) def updateTotalMeasuringTime ( s e l f ) : i f s e l f . t o t a l T i m e U n i t : m e a s t i m e = s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . v a l u e ( ) e l s e : m e a s t i m e = s e l f . t o t a l M e a s u r i n g T i m e S p i n B o x . v a l u e ( ) ∗ 60 print ( ” m i n u t e s ” ) #p r i n t ( ” meas t i m e : ” , m e a s t i m e ) s a m p l e r a t e = s e l f . s a m p l e r a t e S p i n B o x . v a l u e ( ) n s a m p l e s = i n t ( m e a s t i m e ∗ s a m p l e r a t e ) #p r i n t ( ” n s a m p l e s : ” , n s a m p l e s ) s e l f . n s a m p l e s L i n e E d i t . s e t T e x t ( s t r ( n s a m p l e s ) ) def s t a r t M e a s u r e m e n t ( s e l f , Expcount ) : print ( ” s t a r t i n g measurement ” ) #s e t d i g i t a l l i n e P1 0 t o True s e l f . n s a m p l e s = i n t ( s e l f . n s a m p l e s L i n e E d i t . t e x t ( ) ) s e l f . s a m p l e r a t e = s e l f . s a m p l e r a t e S p i n B o x . v a l u e ( ) print ( ” n s a m p l e s : %d , s a m p l e r a t e : %d”%( s e l f . nsamples , s e l f . s a m p l e r a t e ) )

(24)

i f debug == F a l s e : s e l f . d a t a = s e l f . daq . s c a n C h a n n e l s ( s e l f . nsamples , s e l f . s a m p l e r a t e ) e l s e : s e l f . d a t a = np . z e r o s ( ( s e l f . nsamples , ) , dtype = np . f l o a t 6 4 ) f 1 = 3 . 0 #f r e q f 2 = 2 6 . 0 t = 0 . 0 v a l u e s = np . random . r a n f ( s e l f . n s a m p l e s )#a d d i n g a b i t o f n o i s e f o r i in range ( s e l f . n s a m p l e s ) : #we s a m p l e 2 c h a n n e l s , s o we s p l i t t h e s a m p l e r a t e o v e r t h e s e c h a n n e l s #t h i s means t h a t f o r a c o r r e c t dummy d a t a we s h o u l d c o r r e c t f o r t h i s i n t i m e #s h o u l d g i v e p e a k s a t f 1 and f 2 i n FFT t = t + 2 . 0 / s e l f . s a m p l e r a t e s e l f . d a t a [ i ] = 0 . 5 ∗ np . s i n ( 2 ∗ np . p i ∗ f 1 ∗ t ) + 0 . 5 ∗ np . s i n ( 2 ∗ np . p i ∗ f 2 ∗ t ) + v a l u e s [ i ] / 2 . 0 print ( ” a c q u i r e d number o f s a m p l e s : ” , len ( s e l f . d a t a ) )

s e l f . e x p d a t a i f . p u b l i s h d a t a ( s e l f . d a t a )

t m e a s = f l o a t ( s e l f . n s a m p l e s ) / s e l f . s a m p l e r a t e s e l f . p l o t D a t a ( s e l f . data , t m e a s )

s e l f . plotFFT ( s e l f . data , s e l f . s a m p l e r a t e ) s e l f . on draw ( )

s e l f . saveData ( s e l f . data , t meas , Expcount ) def p l o t D a t a ( s e l f , data , t m e a s ) : l = i n t ( len ( d a t a ) / 2 ) ch0 = np . a r r a y ( d a t a [ 0 : l ] ) # c o n v e r t t o G u s i n g c a l i b r a t i o n c o n s t a n t ch0 = ch0 ∗ 1 0 0 0 . 0 / CH0 SENSITIVY ch1 = np . a r r a y ( d a t a [ l : ] ) ch1 = ch1 ∗ 1 0 0 0 . 0 / CH1 SENSITIVY t d a t a = np . a r a n g e ( 0 , t meas , 2∗ t m e a s / ( len ( d a t a ) ) ) s e l f . ax . c l a ( ) #c l e a r p l o t l i n e c h 0 = s e l f . ax . p l o t ( t d a t a , ch0 , ” bs ” , ms=1 , l a b e l=CH0 SERIAL NR ) l i n e c h 1 = s e l f . ax . p l o t ( t d a t a , ch1 , ” r s ” , ms=1 , l a b e l=CH1 SERIAL NR )

#s e l f . ax . l e g e n d ( ( CH0 SERIAL NR , CH1 SERIAL NR ) , l o c =’ u p p e r r i g h t ’ , f a n c y b o x=True , shadow=True ) s e l f . ax . l e g e n d ( l o c= ’ upper r i g h t ’ )

#s e l f . on draw ( ) def r e p l o t ( s e l f ) :

(25)

t m e a s = f l o a t ( s e l f . n s a m p l e s ) / s e l f . s a m p l e r a t e t d a t a = np . a r a n g e ( 0 , t meas , t m e a s / ( len ( s e l f . d a t a ) ) ) s e l f . p l o t D a t a ( s e l f . data , t m e a s ) s e l f . plotFFT ( s e l f . data , s e l f . s a m p l e r a t e ) s e l f . on draw ( ) def f i l t e r d a t a ( s e l f ) : i f len ( s e l f . d a t a ) == 0 : print ( ”No d a t a a v a i l a b l e y e t . ” ) e l s e : f i l t e r W i n = F i l t e r ( ) f i l t e r W i n . e x e c ( ) f i l t c h 0 , f i l t c h 1 = f i l t e r W i n . g e t F i l t e r e d R e s u l t ( 5 0 . 0 , s e l f . data , s e l f . s a m p l e r a t e ) s e l f . ax . c l a ( ) t m e a s = f l o a t ( s e l f . n s a m p l e s ) / s e l f . s a m p l e r a t e t d a t a = np . a r a n g e ( 0 , t meas , t m e a s / ( len ( f i l t c h 0 ) ) ) l i n e c h 0 = s e l f . ax . p l o t ( t d a t a , f i l t c h 0 , ” bs ” , ms=1 , l a b e l=CH0 SERIAL NR ) l i n e c h 1 = s e l f . ax . p l o t ( t d a t a , f i l t c h 1 , ” r s ” , ms=1 , l a b e l=CH1 SERIAL NR ) n0 = len ( f i l t c h 0 ) n1 = len ( f i l t c h 1 ) k = np . a r a n g e ( n0 ) T = n0 / s e l f . s a m p l e r a t e f r q = ( k/T) / 2 f r q = f r q [ range ( i n t ( n0 / 2 ) ) ] #t a k e o n l y one s i d e o f t h e f r e q u e n c y r a n g e Y0 = np . f f t . f f t ( f i l t c h 0 ) / n0 #do f f t and n o r m a l i z a t i o n Y0 = Y0 [ range ( i n t ( n0 / 2 ) ) ] Y1 = np . f f t . f f t ( f i l t c h 1 ) / n1 #do f f t and n o r m a l i z a t i o n Y1 = Y1 [ range ( i n t ( n1 / 2 ) ) ] #i n i t Y0 [ 0 ] = 0 . 0 Y1 [ 0 ] = 0 . 0 s e l f . bx . c l a ( ) s e l f . bx . p l o t ( f r q , abs ( Y0 ) , ’ bs ’ , f r q , abs ( Y1 ) , ’ r s ’ , ms =1) s e l f . on draw ( ) print ( ” r e t u r n i n g from f i l t e r . . . ” ) def on draw ( s e l f ) : s e l f . ax . s e t x l a b e l ( ” t [ s ] ” ) s e l f . ax . s e t y l a b e l ( ” g [m/ s ˆ 2 ] ” ) s e l f . ax . g r i d ( ) s e l f . bx . s e t x l a b e l ( ” f [ Hz ] ” ) s e l f . bx . s e t y l a b e l ( ” g [m/ s ˆ 2 ] ” )

(26)

s e l f . bx . g r i d ( )

s e l f . f i g . c a n v a s . draw ( )

def plotFFT ( s e l f , data , s a m p l e r a t e ) : l = i n t ( len ( d a t a ) / 2 ) ch0 = np . a r r a y ( d a t a [ 0 : l ] ) ch1 = np . a r r a y ( d a t a [ l : ] ) n0 = len ( ch0 ) n1 = len ( ch1 ) k = np . a r a n g e ( n0 ) T = n0 / s a m p l e r a t e f r q = ( k/T) / 2 f r q = f r q [ range ( i n t ( n0 / 2 ) ) ] #t a k e o n l y one s i d e o f t h e f r e q u e n c y r a n g e Y0 = np . f f t . f f t ( ch0 ) / n0 #do f f t and n o r m a l i z a t i o n Y0 = Y0 [ range ( i n t ( n0 / 2 ) ) ] Y1 = np . f f t . f f t ( ch1 ) / n1 #do f f t and n o r m a l i z a t i o n Y1 = Y1 [ range ( i n t ( n1 / 2 ) ) ] #i n i t Y0 [ 0 ] = 0 . 0 Y1 [ 0 ] = 0 . 0 s e l f . bx . c l a ( ) s e l f . bx . p l o t ( f r q , abs ( Y0 ) , ’ bs ’ , f r q , abs ( Y1 ) , ’ r s ’ , ms =1)

def saveData ( s e l f , data , meas t , Expcount ) : #add windows t i m e + name c s v t d a t a = np . a r a n g e ( 0 , meas t , 2∗ m e a s t / ( len ( d a t a ) ) ) f i l e n a m e = s e l f . f i l e n a m e L i n e E d i t . t e x t ( ) #f p = open ( f i l e n a m e , ”w” ) #f p . w r i t e l i n e s ( ” Time , G0 , G1”+”\n ” ) l = i n t ( len ( d a t a ) / 2 ) ch0 = np . a r r a y ( d a t a [ 0 : l ] ) ch1 = np . a r r a y ( d a t a [ l : ] ) i f s e l f . v o l t a g e D a t a C h e c k e d . i s C h e c k e d ( ) == F a l s e : print ( ” s t o r i n g g v a l u e s ” ) ch0 = ch0 ∗ 1 0 0 0 . 0 / CH0 SENSITIVY ch1 = ch1 ∗ 1 0 0 0 . 0 / CH1 SENSITIVY e l s e : ch0 = ch0 ∗ 1 0 0 0 . 0 / CH0 SENSITIVY ch1 = ch1 ∗ 1 0 0 0 . 0 / CH1 SENSITIVY print ( ” f e e s t j e ” ) s a v e v a l u e s = True i f s a v e v a l u e s :

(27)

E x p d a t a d i c = {}

E x p d a t a d i c [ ’ Time [ s ] ’ ] = 1 . ∗ t d a t a E x p d a t a d i c [ ’ Ch0 [ g ] ’ ] = 1 . ∗ ch0 E x p d a t a d i c [ ’ Ch1 [ g ] ’ ] = 1 . ∗ ch1

Expdata DF = pd . DataFrame ( E x p d a t a d i c )

Expdata DF . t o c s v ( ’ Expdata ’+s t r ( Expcount)+ ’ . c s v ’ )

# ============================================================================= # f o r i i n r a n g e ( l ) : # f p . w r i t e ( s t r ( t d a t a [ i ] ) + ” , ” ) # f p . w r i t e ( s t r ( ch0 [ i ] ) + ” , ” ) # f p . w r i t e ( s t r ( ch1 [ i ] ) ) # f p . w r i t e l i n e s ( ” \ n ” ) # f p . c l o s e ( ) # ============================================================================= print ( ” f e e s t j e 2 ” ) i f n a m e == ’ m a i n ’ : c h a n n e l s i n = [ ”Dev1/ a i 0 ” , ”Dev1/ a i 1 ” ] c h a n n e l s o u t = [ ”Dev1/ ao1 ” ] app = Q A p p l i c a t i o n ( s y s . a r g v ) exp = Experiment ( c h a n n e l s i n , c h a n n e l s o u t ) exp . show ( ) s y s . e x i t ( app . e x e c ( ) )

5.5

Looping.py

import t i m e import o s import zmq import z l i b import p i c k l e import t h r e a d i n g import numpy a s np from d a t e t i m e import d a t e t i m e a s dt from PyDAQmx. DAQmxFunctions import ∗ from PyDAQmx. DAQmxConstants import ∗ cmd port = 5555

d a t a p o r t = 5556 e v e n t p o r t = 5557

(28)

r e g s e t t l e d f l a g = F a l s e c o n t e x t = zmq . Context ( ) # S o c k e t t o t a l k t o s e r v e r print ( ” C o n n e c t i n g t o s e r v e r . . . ” ) c m d s o c k e t = c o n t e x t . s o c k e t ( zmq .REQ) c m d s o c k e t . c o n n e c t ( ” t c p : / / l o c a l h o s t :%d”%cmd port ) #s u b s c r i b e t o d a t a ( t o b e c h a n g e d a f t e r w a r d s w i t h e n a b l e / d i s a b l e and m u l t i t h r e a d e d ) d a t a s o c k e t = c o n t e x t . s o c k e t ( zmq . SUB) #d a t a s o c k e t . c o n n e c t ( ” t c p : / / 1 9 2 . 1 6 8 . 3 . 1 0 2 : % d”% d a t a p o r t ) d a t a s o c k e t . c o n n e c t ( ” t c p : / / l o c a l h o s t :%d”%d a t a p o r t ) d a t a s o c k e t . s e t s o c k o p t ( zmq . SUBSCRIBE , ’ ’ . e n c o d e ( ) )#g e t a l l d a t a , n o t a f i l t e r e d number e v e n t s o c k e t = c o n t e x t . s o c k e t ( zmq . SUB) e v e n t s o c k e t . c o n n e c t ( ” t c p : / / l o c a l h o s t :%d”%e v e n t p o r t ) e v e n t s o c k e t . s e t s o c k o p t ( zmq . SUBSCRIBE , ’ ’ . e n c o d e ( ) ) c l a s s C o n t i n u o u s P u l s e T r a i n G e n e r a t i o n ( ) : ””” C l a s s t o c r e a t e a c o n t i n u o u s p u l s e t r a i n on a c o u n t e r Usage : p u l s e = C o n t i n u o u s T r a i n G e n e r a t i o n ( p e r i o d [ s ] , d u t y c y c l e ( d e f a u l t = 0 . 5 ) , c o u n t e r ( d e f a u l t = ” d e v 1 / c t r 0 ” ) , r e s e t = True / F a l s e ) p u l s e . s t a r t ( ) p u l s e . s t o p ( ) p u l s e . c l e a r ( ) ””” def i n i t ( s e l f , p e r i o d = 1 . , d u t y c y c l e = 0 . 5 , c o u n t e r=”Dev1/ c t r 0 ” , r e s e t=F a l s e ) : i f r e s e t : DAQmxResetDevice ( c o u n t e r . s p l i t ( ’ / ’ ) [ 0 ] ) t a s k H a n d l e = TaskHandle ( 0 ) DAQmxCreateTask ( ” ” , b y r e f ( t a s k H a n d l e ) )

DAQmxCreateCOPulseChanFreq ( t a s k H a n d l e , c o u n t e r , ” ” , DAQmx Val Hz , DAQmx Val Low ,

0 . 0 , 1 / f l o a t ( p e r i o d ) , d u t y c y c l e ) DAQmxCfgImplicitTiming ( t a s k H a n d l e , DAQmx Val ContSamps , 1 0 0 0 )

s e l f . t a s k H a n d l e = t a s k H a n d l e def s t a r t ( s e l f ) : DAQmxStartTask ( s e l f . t a s k H a n d l e ) def s t o p ( s e l f ) : DAQmxStopTask ( s e l f . t a s k H a n d l e ) def c l e a r ( s e l f ) : DAQmxClearTask ( s e l f . t a s k H a n d l e ) def h a n d l e e v e n t ( name= ’ ’ ) : global r e g s e t t l e d f l a g

(29)

print ( ” r e a d y t o r e c e i v e e v e n t s . . . ” ) while 1 : try : z = e v e n t s o c k e t . r e c v ( f l a g s=zmq .NOBLOCK) p = z l i b . d e c o m p r e s s ( z ) e v e n t d a t a = p i c k l e . l o a d s ( p ) print ( ” r e c e i v e d EVENT: %s ” % e v e n t d a t a ) i f ” r e g s e t t l e d ” in e v e n t d a t a : r e g s e t t l e d f l a g = True e l i f ” r e g s t a t u s ” in e v e n t d a t a : print ( ” r e g s t a t u s : ” , e v e n t d a t a [ ” r e g s t a t u s ” ] ) e l s e : print ( ” r e c e i v e d e v e n t : ” , e v e n t d a t a ) except zmq . Again a s e : pass def h a n d l e s e n s o r d a t a ( name= ’ ’ ) : global f p print ( ” h a n d l i n g s e n s o r d a t a . . . ” ) while 1 : try : z = d a t a s o c k e t . r e c v ( f l a g s=zmq .NOBLOCK) p = z l i b . d e c o m p r e s s ( z ) d a t a = p i c k l e . l o a d s ( p ) s u b s e t d a t a = d a t a [ : 1 0 0 ] print ( ” r e c e i v e d d a t a : %s ” % s u b s e t d a t a ) f p . w r i t e ( s t r ( d a t a ) ) f p . w r i t e l i n e s ( ” \n” ) except zmq . Again a s e : pass #p r i n t ( ”No d a t a ” ) def s e n d z i p p e d c m d ( cmd obj ) : p = p i c k l e . dumps ( cmd obj ) z = z l i b . c o m p r e s s ( p ) return c m d s o c k e t . s e n d ( z ) def send cmd ( cmd ) : s e n d z i p p e d c m d ( cmd ) c m d r e p l y = c m d s o c k e t . r e c v ( ) return c m d r e p l y h a n d l e d a t a t h r e a d = t h r e a d i n g . Thread ( t a r g e t=h a n d l e s e n s o r d a t a ) h a n d l e d a t a t h r e a d . daemon = True h a n d l e e v e n t t h r e a d = t h r e a d i n g . Thread ( t a r g e t=h a n d l e e v e n t )

(30)

h a n d l e e v e n t t h r e a d . daemon = True h a n d l e e v e n t t h r e a d . s t a r t ( ) r e g s e t t l e d f l a g = F a l s e #p r e p a r e f o r w a i t l o o p print ( ”now s t a r t i n g t o r e c e i v e d a t a 3 s e c . . . . ” ) h a n d l e d a t a t h r e a d . s t a r t ( ) def d o o n e r u n ( count , g s e t p o i n t , f r e q , m e a s u r e t i m e , fp , f i l e ) : f p = open ( ” r e s u l t s %f=f r e q %.1 f=g . c s v ” % ( f r e q , g s e t p o i n t ) , ”w” ) f i l e = open ( ” OverviewExp . t x t ” , ” a ” ) p u l s e g e n e 1 = C o n t i n u o u s P u l s e T r a i n G e n e r a t i o n ( 0 . 5 , 0 . 5 , ” dev1 / c t r 0 ” , r e s e t=True ) cmd = [ ” s e t s h a k e r ” , g s e t p o i n t , f r e q ] #g s e t p o i n t , f r e q u e n c y c m d r e p l y = send cmd ( cmd ) cmd = [ ” s t a r t r e g ” ] c m d r e p l y = send cmd ( cmd ) while r e g s e t t l e d f l a g == F a l s e : t i m e . s l e e p ( 1 ) print ( ” w a i t i n g . . . . ” ) print ( ” r e g u l a t i o n s e t t l e d . C o n t i n u i n g w i t h e x p e r i m e n t ” ) cmd = [ ” s t o p r e g ” ] c m d r e p l y = send cmd ( cmd ) cmd = [ ” s e t m e a s u r e t i m e ” , m e a s u r e t i m e ] c m d r e p l y = send cmd ( cmd ) # ! ! ! ! w r i t e measurement t i m e i n f i r s t l i n e o f d a t a f i l e f p . w r i t e l i n e s ( ” m e a s u r e t i m e , %f ”% m e a s u r e t i m e ) f p . w r i t e l i n e s ( ” time , %s ”% s t r ( dt . now ( ) ) ) #w r i t e s y s t e m t i m e t o f i l e

f i l e . w r i t e ( ”Exp %f , syste m t i m e %s , f r e q %f , g %.1 f ” % ( count , s t r ( dt . now ( ) ) , f r e q , g s e t p o i n t )+ ’ \n ’ ) #f o r i i n r a n g e ( 1 0 ) : # ============================================================================= # cmd = [ ” s e t t r i g g e r ” ] #s e t P1 b i t 0 t o 1 # c m d r e p l y = send cmd ( cmd ) # cmd = [ ” c l e a r t r i g g e r ” ] #s e t P1 b i t 0 t o 0 # c m d r e p l y = send cmd ( cmd ) # ============================================================================= p u l s e g e n e 1 . s t a r t ( ) #a = i n p u t ( ” G e n e r a t i n g p u l s e t r a i n . P r e s s E n t e r t o i n t e r r u p t \n ” ) #t i m e . s l e e p ( 1 0 ) cmd = [ ” s t a r t a c q ” , 1 0 0 0 0 , c o u n t ] #a r g = s a m p l e r a t e .

(31)

c m d r e p l y = send cmd ( cmd ) print ( ” R e c e i v e d r e p l y [ %s ] ” % ( c m d r e p l y ) ) p u l s e g e n e 1 . s t o p ( ) p u l s e g e n e 1 . c l e a r ( ) t i m e . s l e e p ( i n t ( m e a s u r e t i m e ) +2) #w a i t u n t i l d a t a a r r i v e s cmd = [ ” c l e a r t r i g g e r ” ] #s e t P1 b i t 0 t o 0 c m d r e p l y = send cmd ( cmd ) print ( ”##### end run #####” )

# ============================================================================= # g = 2 . 0 # f = 50 # ============================================================================= c o u n t = 0 f i l e = open ( ” OverviewExp . t x t ” , ” a ” ) #o s . mkdir ( ” t e s t ” ) f o r g in np . a r a n g e ( 2 . 0 , 3 . 0 , 1 . 0 ) : f o r f in np . a r a n g e ( 4 0 , 6 1 , 1 0 ) : c o u n t = c o u n t + 1 t m e a s u r e = 1 . 0 f i l e = open ( ” OverviewExp . t x t ” , ” a ” ) f p = open ( ” r e s u l t s %f=f r e q %.1 f=g . c s v ” % ( f , g ) , ”w” ) d o o n e r u n ( count , g , f , t m e a s u r e , fp , f i l e ) f p . c l o s e ( ) f i l e . c l o s e ( ) #u n s u b s c r i b e w i l l s t o p t h e h a n d l i n g o f t h e d a t a w h i c h i s s e n t from #s h a k e z i l l a i n t h i s e x p e r i m e n t s c r i p t ( s e e d a t a t h r e a d a b o v e ) d a t a s o c k e t . s e t s o c k o p t ( zmq . UNSUBSCRIBE, ’ ’ . e n c o d e ( ) ) #n o t i m p o r t a n t cmd = [ ” s t o p d a c ” ] c m d r e p l y = send cmd ( cmd ) print ( ” R e c e i v e d r e p l y [ %s ] ” % ( c m d r e p l y ) ) e x i t ( 1 )

Referenties

GERELATEERDE DOCUMENTEN

In order to simulate the isolation of the real heat exchanger in its real- world operational case where the top header also had to convey fluid through the

While Leon became famous for his work on the Temple, and the 1646 Hebrew Mishnah edition came to be listed among the achievements of Menasseh and his son Joseph, Adam Boreel who

De keuze van Christie’s om het doek ondanks de discussie tussen de deskundigen en het bovengenoemde advies van het Rijksmuseum wel te veilen, roept de vraag op of het

Door het paarsgewijs linken van context variabelen met organisatie variabelen ziet de traditionele contingentie en configuratie theorie niet in hoe het functioneren van de

Sigma methodology takes the customer as a starting point for process improvements and therefore it is hard to think about Six Sigma projects that focus on functional

Analyticity spaces of self-adjoint operators subjected to perturbations with applications to Hankel invariant distribution

For a binaural hearing aid system with two microphones on each hearing aid, experimental results for several speech and noise configurations and for different rever- beration times

Exceptions are physical Quantities like the force vector F or the electrical field E .... Exceptions are physical Quantities like the force vector F or the electrical field