Readings Vector Time Interval by David@ColeCanada.com created on 2023FJun29 updated on 2023JOct08 WaveForm Note: In real life, signal waveforms are usually monotonic. This means that sudden (instantaneous) rises and falls of a waveform do not occur on most oscilloscopes. This causes the "corners" of a square wave to appear to rise or fall at a slight angle off the vertical. The sharp corners of a square wave also appear somewhat rounded. This is usually caused by some capacitance in the probes or in the video amplifier. More expensive oscilloscopes suffer in this manner, especally at higher frequency waveforms. When multiple successive signal readings are sampled and recorded, these vertical transitions are seen to occur instantaneously. One reading can be very high, then the next reading can be very low. The transition occurs sometime between the two readings. When the sampling rate is increased, the sample interval is reduced and the transition appears to be a vertical transition. To a human, this seems very reasonable, except at the beginning and end of a waveform. Say the waveform is a square wave and we are sampling it 10 times per cycle. When viewed on an oscilloscope, a human "expects" that the waveform should begin at its lowest point, so we set the oscilloscope to trigger a new scan during a sharp downward vertical "trace." On many oscilloscopes, we also need to set the refresh cycle to a multiple of the period of a repeating waveform. Experienced people set the "trigger mechanism" and "trace width" almost automatically. However, when we are sampling a set of readings, we need to do the same thing, but we are working with an invisible trace because no oscilloscope is present. If our sample interval is 4 times the period of a squarewave, the first sample will probably NOT be at the exact beginning (the start of the lowest point) of the square). What we see in the readings is that the first and second readings are perhaps identical, but a full "square" is not captured. When a reading finally records the highest point in the square wave, usually less than a "half-wave" has elapsed. If the readings are timestamped, it is easy to "chop off" the partial initial trace by discarding one or more readings. Then the following readings should show the vertical transitions after the correct intervals. Of course, the chopping of the first few readings can be automated using appropriate code. More code can ensure that the first readings recorded are when the waveform begins at the lowest level, as a human expects to see the waveform. The next issue is to decide how many readings to record. If the period of the waveform is known, this can be easily calculated. (On a cheaper oscilloscope, this is usually done by trial and error.) But when a series of time-stamped readings is our only information, we must use another technique. An easy way to do this is to measure the time-interval between the timestamp of the beginning of waveform cycle #1 and the timestamp of the beginning of waveform cycle #10. Then subtract the two time-stamps which gives the time interval of 10 cycles. If our time measurement and the signal source are precise enough, the time-stamp for 20 cycles and 100 cycles can be predicted and compared to the time-stamps of these two points. Sometimes, we need to adjust the time-interval between readings in order to arrive at the precise period of the waveform. The most precise way to do this, is usually to adjust the time-interval between readings to exactly the period of the waveform. Then compare the time-stamps of each "start-of-waveform". A graph displaying the actual and the expected waveforms with a common horizontal timestamp x-axis greatly simplified this procedure. A graph that automatically displays a full-cycle "count" of the exact number of waveforms (or the number of readings) is very useful. However an easier method is to use a fast-fourier-transform (FFT) algorithm to quickly calculate the frequency (hence the period) of the waveform. Ideally, the time-interval bewteen readings should be 100 to 1000 times the period of the waveform to get good results using the FFT. The exact algorithm used by the FFT method is quite complex, but those with FFT experience prefer this method to making multiple measurements. It is not even necessary for the time-interval being meaured to be an exact fraction of the period of the waveform. A List called a Vector in Python A vector of readings is a list of numbers that are multiple successive samples. Usually this list of numbers contains samples taken at equal time intervals. The exact time interval is impossible to discern without additional information. This vector is often stored using a vector name. The extension of the vector name is suggested to be ".vix". This vector can be a separate file or can be embedded in a JSON file. There are at least four ways to identify the time interval: a) decode it from the vectorName (the name used to store the vector.) eg A vector named "PressureReadings_DT0o025.vix" will contain readings, each taken after an interval of 25msec b) read it from any file with the name ".txt" or "" that contains a single valid real number. This real number is the number of seconds (or fraction of a second) that is the time interval. An example of a record in such a linux file is '0.025\n' or '0.025' named "PressureReadings.txt" that is located in the same folder as the vector file. c) read it from a ".json" file. This file is a "time-stamp" JSON (Javascript Object Notation) file associated with and stored in a folder related to the the vector. The time-interval is the first valid real number that appears as a value in the JSON file. An example of such a file is a file named ".json containing "dt": "0.025"\n. A JSON file for linux contains at least one key/value pair such as '"dt": "0.025"\n' where "\n" is an end-of-line indicator. The name of this key is expected to be "dt" which means "delta-t" in seconds. f) Store the successive unequal time intervals in the imaginary portion of each reading and store each reading as a complex number eg (2.98+0.0256j). e) read it from a ".json" file. This file is a valid JSON file containing information about the vector of readings. The first name of this ".json" file must be exactly the same as the vector file. The key/value fields must be as listed below. Additional fields are permitted but are not essential. The only essential "key" field is a field which must be "dt" as in the valid JSON example below: { "vectorName": "PressureReadings_DT0o025.vix", "dt": "0.025", "vectorFMT": "RDasc", "unitsReadings": "lb/sq.in (PSI)", "unixTimeGMTstart": "1621625066", "vectorData": [ 12.3, 12.5, 12.7, 13.0, 14.4 ] "device:": "_SABRENT01", "path": "/home/pi/Desktop/d", "nameJSON": "/PressureReadings_DT0o025.json" } The subsequent keys should be as shown above. Procedure to capture the digital readings: The process used to capture the readings is: 1. Determina how many readings to record (eg set range=100) 2. start a timer (or record the value of a clock as a beginning time-stamp) 3. decide which vector format to use to record the readings. 4. for i in range(100): 5. wait for a time interval (usually a regular time interval such as 1 msec) 6. record the reading and read its time-stamp to calculate the inter-reading time-interval 7. optionally record the time-interval as an imaginary component of the vector value 8. store the reading (with any imaginary portion) 9. convert the readings to a vector 10. save the vector with a suffix in the name describing the time interval if all time-intervals are equal. 11. # eg "PressureReadings_DT0o025.vix" if the time-interval is 25 msec. This procedure can be used to record a series of readings taken at equal or different time-intervals. VIX Python Functions: The author (D@CC) has created a number of useful Python functions for storing vector readings as complex numbers They are: v makeVectorVIX() To create a VIX vector from a mathematical wave definition makeTimeStampTIX() To create a TIX timestamp & details in JSON format sampleVIX_imp() To create a VIX vector using Pico ADC readings graphN_VIX() to graph N VIX vectors in an RPi window. piR2_toVIX() To create a VIX vector from a PiR2 log analyzeFFT_VIX() To analyze a VIX vector using FFT periodOfVIX() To calculate the period of a VIX vector convertVIXtoEDT() To convert VIX vector to Equal DT (EDT) VIX v vectorMathLibrary_2023FJun30_py.py VIX Vector Math Library Sources: Articles by D@CC: 155 ix_all Library (no VIX or RUPasc functions) 164 RUPasc: A Format for ADC Reading Samples 165 strToComplex.py VRC 173 Pico: FF commands: FFQueue() FFRequest FFControl() DAC example 174 A Thonny Package of Functions 180 Pix voltmeter_pico 193 ixmRPC (eRPC lite) 195 ixmRPC Wio Remote Procedure Calls 204 IT: Python Coding Course (JSON example) 215 IX Raspberry Software Repository (JSON example) Stored in: Article 203 as of 2024BFeb28 /ReadingsVectorTimeInterval.txt