<!-- Double contactless acoustic stopwatch from standard of phyphox.
     Project: to create double stopwatch using arduino Nano 33 sense board BLE.
     mIv Dec 2020, also more comments -->
<phyphox version="1.7" locale="en"> 
    <title>Double Acoustic Stopwatch and Sound Speed</title>
    <category>own experiment</category>
    <description>
        Get the time between two acoustic events measured by smartphone and arduino Nano 33 sense board BLE and determines the sound speed.

        This experiment allows to measure by two distante sensors the time between two loud acoustic signals produced sequentially near to each sensor location. These can be clicks, beeps, claps etc. as long as they are louder than the environment. You might want to adjust the threshold, giving the level at which the stop watch is triggered (ranging from 0 to 1 for smartphone).

        After launching the experiment (run), the clock will start on the first noise exceeding the threshold and will be stopped on the second noise. To repeat the experiment, clear the data and start again. Make sure that the first noise is short as a long sound might be immediately detected as a stop. New: Two more claps clear the data and let you restart the smartphone clock again.

	Then the sound speed is calculated by the difference of the time intervals measured by sensors: distance*2 / abs(time1 - time2).
    </description>
    <icon>T2S</icon>
    <color>red</color>
  <data-containers>
    <container>threshold</container> <!-- sound threshold to START/STOP -->
    <container>mindelay</container> <!-- max sound duration -->
    <container size="16384">recording</container> <!-- 16384 ??? -->
    <container>rate</container>
    <container>i</container>
    <container>i2</container>
    <container>t</container>
    <container>limit</container>
    <container>max</container>
    <container>last</container>
    <container size="0">tlist</container>
    <container size="0">dtlist</container>
    <container size="0">tindex</container>
    <container size="1">tcount</container>
    <container size="1">tcount-1</container>

    <container>t0</container> <!-- size = 1 by default -->
    <container>t1</container>
    <container>t0effective</container>
    <container>t1effective</container>
    <container>tmax</container>
    <container>dt01</container>

    <container>count</container>
    <container init="0">index</container>
    <!-- BLE channels -->
	    <container size="0" static="false" init="">CH1</container>
	    <container size="0" static="false" init="">CH2</container>
	    <container size="0" static="false" init="">CH3</container>
	    <container size="0" static="false" init="">CH4</container>
	    <container size="0" static="false" init="">CH5</container>
	    <container size="0" static="false" init="">CH0</container>
    <container size="1" static="false">phone</container>
    <container size="1" static="false">distance</container> <!-- distance between sensors -->
    <container size="1" static="false">speed</container> <!-- sound speed estimation -->

    <container size="1" static="false">arduino_threshold</container> <!-- to send to arduino -->
  </data-containers>

    <input> 
        <audio>  <!-- Continuous sound recording -->
            <output>recording</output>
            <output component="rate">rate</output>
        </audio>

        <bluetooth name="phyphox" mode="notification" rate="1" subscribeOnStart="false" id="Sense">
            <output char="cddf1002-30f7-4671-8b43-5e40ba53514a" conversion="float32LittleEndian" offset="0">CH1</output>
            <output char="cddf1002-30f7-4671-8b43-5e40ba53514a" conversion="float32LittleEndian" offset="4">CH2</output>
            <output char="cddf1002-30f7-4671-8b43-5e40ba53514a" conversion="float32LittleEndian" offset="8">CH3</output>
            <output char="cddf1002-30f7-4671-8b43-5e40ba53514a" conversion="float32LittleEndian" offset="12">CH4</output>
            <output char="cddf1002-30f7-4671-8b43-5e40ba53514a" conversion="float32LittleEndian" offset="16">CH5</output>
            <output char="cddf1002-30f7-4671-8b43-5e40ba53514a" extra="time">CH0</output>
        </bluetooth>
    </input>

    <output>
        <bluetooth name="phyphox" id="Sense">
            <input char="cddf1003-30f7-4671-8b43-5e40ba53514a" conversion="float32LittleEndian">arduino_threshold</input>
        </bluetooth>
    </output>

  <views>
    <view label="Phone">
      <edit label="Threshold" unit="a.u." default="0.1" signed="false" min="0" max="1">
        <output>threshold</output>
      </edit>
      <edit label="Minimum Delay" unit="s" default="0.1" signed="false">
        <output>mindelay</output>
      </edit>
      <value label="Time" size="2" precision="4" unit="s">
        <input>dt01</input>
      </value>

      <button label="Reset">
        <input type="empty"/>
        <output>tlist</output>
        <input type="value">0</input>
        <output>index</output>
      </button>

      <separator height="1"/>
      <info label="Change the threshold to be above the environmental noise level, but below the trigger noise (you can try the audio scope experiment to check these). Also set the minimum delay to avoid triggers shorter than that time (for example due to echo or reverberation)."/>
      <separator height="1"/>
      <info color="red" label="Unfortunately, this won't work on slow phones. Please compare to a regular clock first, to make sure, that the experiment is working as expected."/>
    </view>

    <view label="Arduino">
      <value label="Phone Time" size="2" precision="4" unit="s">
        <input>phone</input>
      </value>
      <value label="Arduino Time" size="2" precision="4" unit="s">
        <input>CH1</input>
      </value>
      <separator height="1"/>
      <edit label="Distance" unit="m" default="1.0" signed="false">
        <output>distance</output>
      </edit>
      <edit label="Arduino threshold" unit="" default="444.4" signed="false">
        <output>arduino_threshold</output>
      </edit>
      <separator height="1"/>
      <value label="Sound speed" size="2" precision="0" unit="m/s" color="red">
        <input>speed</input>
      </value>
      <separator height="1"/>
      <info label="In order to have a more reliable value of the sound speed the experiment should be repeated twice: first starting with sensor 1 and second with sensor 2, and then calculating the average. It allows to compensate some difference between these sensors."/>
    </view>
  </views>

  <analysis>

    <count> <!-- length of the sound recording -->
      <input clear="false">recording</input>
      <output>count</output>
    </count>
    <max>   <!-- position and value of sound peak, recording is cleared -->
      <input as="y">recording</input>
      <output as="position">i</output>
      <output as="max">max</output>
    </max>
    <add>   <!-- index + i = absolute peak position, i is cleared -->
      <input>i</input>
      <input clear="false">index</input>
      <output>i2</output>
    </add>

    <divide> <!-- absolute time, i2 is cleared -->
      <input>i2</input>
      <input clear="false">rate</input>
      <output>t</output>
    </divide>
    <if greater="true"> <!-- if not high enough t to zero -->
      <input clear="false">max</input>
      <input clear="false">threshold</input>
      <input clear="false">t</input>
      <input type="value">0</input>
      <output>t</output>
    </if>

    <const>  <!-- last=0 -->
      <output>last</output>
    </const>
    <append>
      <input clear="false">tlist</input>
      <output clear="false">last</output>
    </append>

    <add> <!-- limit = mindelay for absolute time t -->
      <input clear="false">last</input>
      <input clear="false">mindelay</input>
      <output>limit</output>
    </add>
    <if less="true" equal="true">
      <input clear="false">limit</input>
      <input clear="false">t</input>
      <input clear="false">t</input>
      <input type="value">0</input>
      <output>t</output>
    </if>
    <if greater="true"> <!-- if t greater 0, t saved to tlist -->
      <input clear="false">t</input>
      <input type="value">0</input>
      <input clear="false">t</input>
      <output clear="false">tlist</output>
    </if>

    <differentiate> <!-- calculate time intervals in tlist -->
      <input clear="false">tlist</input>
      <output>dtlist</output>
    </differentiate>
    <append>
      <input type="value">0</input>
      <output clear="false">dtlist</output>
    </append>

    <count> <!-- number of measurements in tlist -->
      <input clear="false">tlist</input>
      <output>tcount</output>
    </count>
    <subtract>
      <input clear="false">tcount</input>
      <input type="value">1</input>
      <output>tcount-1</output>
    </subtract>

    <add> <!-- upgrade index for next run, count is cleared -->
      <input clear="false">index</input>
      <input>count</input>
      <output>index</output>
    </add>
    <divide> <!-- tmax ? -->
      <input clear="false">index</input>
      <input clear="false">rate</input>
      <output>tmax</output>
    </divide>

    <!-- At the end conserve the measured time interval (may be cleaned by sound restart) -->
    <if greater="true">
      <input as="a" clear="false">tcount</input>
      <input as="b" type="value">1</input>
      <input as="true" clear="false">dt01</input>
      <output>phone</output>
    </if>
    <!-- Restart by two more claps -->
    <if greater="true">
      <input as="a" clear="false">tcount</input>
      <input as="b" type="value">3</input>
      <input as="true" type="empty"/>
      <output>tlist</output>
    </if>
    <if greater="true">
      <input as="a" clear="false">tcount</input>
      <input as="b" type="value">3</input>
      <input as="true" type="value">0</input>
      <output>index</output>
    </if>

    <formula formula="[3]*2/abs([1]-[2])">
      <input clear="false">phone</input>
      <input clear="false">CH1</input>
      <input clear="false">distance</input>
      <output>speed</output>
    </formula>

    <const>  <!-- ? if followed by subrange -->
      <output>t0</output>
    </const>
    <const>
      <output>t1</output>
    </const>

    <subrange> <!-- 1st element of tlist -->
      <input as="from" type="value">0</input>
      <input as="length" type="value">1</input>
      <input as="in" clear="false">tlist</input>
      <output clear="false">t0</output>
    </subrange>
    <subrange>  <!-- 2nd element of tlist -->
      <input as="from" type="value">1</input>
      <input as="length" type="value">1</input>
      <input as="in" clear="false">tlist</input>
      <output clear="false">t1</output>
    </subrange>
    <if less="true" equal="true">
      <input clear="false">t1</input>
      <input type="value">0</input>
      <input clear="false">tmax</input>
      <input clear="false">t1</input>
      <output>t1effective</output>
    </if>
    <if less="true" equal="true">
      <input clear="false">t0</input>
      <input type="value">0</input>
      <input clear="false">tmax</input>
      <input clear="false">t0</input>
      <output>t0effective</output>
    </if>
    <subtract>
      <input>t1effective</input>
      <input>t0effective</input>
      <output>dt01</output>
    </subtract>

  </analysis>

  <!-- ALL peak times: for some potential usage -->
  <export>
    <set name="ALL times">
      <data name="times (s)">tlist</data>
    </set>
  </export>

</phyphox>