Shop OBEX P1 Docs P2 Docs Learn Events
Sound Impact Sensors TDOA code - help! — Parallax Forums

Sound Impact Sensors TDOA code - help!

r.daneelr.daneel Posts: 96
edited 2014-02-24 15:14 in Propeller 1
I thought I was writing some very simple code, but I can't make it work and I can't see why...

I have three (genuine Parallax) Sound Impact Sensors arranged on a breadboard. The sensors are about 3 inches apart. 5V and GND are connected to each sensor, and sensor signal pins are connected to Prop pins 26, 27 and 28. What I am trying to do is record the time (system counter) at which each sensor hears a noise (so pin high), and then the delay between each sensor (the sensors are arranged so that the farthest sensor is 6 inches further away from the sound source (my hands clapping) than the closest). I thought this would be reasonably simple...

I've reproduced my code below. I have pared down the code to as simple as I can. I am using a separate cog for each sensor. I know I could do this with one cog, and that's how I started, but I used a cog per sensor to make the code as simple as possible in a so far futile effort to see where I am going wrong. I still can't see it, and staring at it longer just isn't helping.

First, the Spin code:
CON
   
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
  

VAR

  long sound[3]
  long silence[3]
  long status[3]
  

OBJ

  dbg : "FullDuplexSerial"  

  sis[3] : "listen"

  
DAT

  pin long 24, 25, 26

    
PUB Main | s, cog, ready


  cog := dbg.Start(31,30,0,250_000)
  waitcnt(clkfreq + cnt) 

  dbg.str(string("Ready", 13))

  ' start listening on all three sound impact sensors
  
  repeat s from 0 to 2
    cog := sis[s].Start(pin[s], @sound[s], @silence[s], @status[s])
    if (cog < 0)
      return

  waitcnt(clkfreq*3+cnt)     ' wait for all 3 cogs to start

  ' by now, all 3 sound impact sensors should be waiting on sound
  
  repeat

    ' wait until all 3 sensors have signaled sample is ready
    repeat while ((ready := status[0] + status[1] + status[2]) <> 3)

    ' to get here, all 3 sensors have signaled sample is ready
    dbg.tx(13)

    repeat s from 0 to 2
      dbg.str(string("sensor["))
      dbg.dec(s)
      dbg.str(string("], status = "))
      dbg.dec(status[s])
      dbg.str(string(", cnt[sound] = "))
      dbg.hex(sound[s], 8)
      dbg.str(string(", cnt[silence] = "))
      dbg.hex(silence[s], 8)
      dbg.str(string(", duration = "))
      dbg.dec(||(silence[s] - sound[s]))

      if (s > 0)
        dbg.str(string(", delay = "))
        dbg.dec(||(sound[s] - sound[0]))    ' delay from sound at sensor 0

      dbg.tx(13)

    waitcnt(clkfreq+cnt)

    ' all sensors should be waiting to be signaled to sample again
    ' signal sample again
    status[0] := status[1] := status[2] := 0
  



And the PASM code:
CON
   
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000


VAR

long _pin, _sound, _silence, _status    
  

PUB Start(sensorPin, soundPtr, silencePtr, statusPtr) | cog 

  _pin     := sensorPin  
  _sound   := soundPtr
  _silence := silencePtr
  _status  := statusPtr

  cog := cognew(@listen, @_pin)
  
  return cog
      

DAT

                        org

listen                  mov     arg, par                ' arg pointer
                        
                        rdlong  scr, arg                ' sensor signal pin
                        shl     mask, scr               ' mask
                        andn    dira, mask              ' make pin an input

                        add     arg, #4                 ' next arg
                        rdlong  sound, arg              ' pointer to sound counter

                        add     arg, #4                 ' next arg
                        rdlong  silence, arg            ' pointer to silence counter

                        add     arg, #4                 ' next arg
                        rdlong  status, arg             ' pointer to status
                         
                        mov     scr, #0                 ' sample not ready
                        wrlong  scr, status             ' set sample status to not ready

:waitForSound           test    mask, ina    wz         ' wait for pin to go high - sound
              if_z      jmp     #$-1                    ' keep listening
                       
                        mov     t1, cnt                 ' record clock
                        
                        test    mask, ina    wz         ' wait for pin to go low - silence
              if_nz     jmp     #$-1                    ' keep listening

                        mov     t2, cnt                 ' record clock

                        wrlong  t1, sound               ' clock when sound heard
                        wrlong  t2, silence             ' clock when silence heard (if one can hear silence...)

                        mov     scr, #1                 ' sample ready
                        wrlong  scr, status             ' set sample status to ready 
                        
                        rdlong  scr, status             ' get sample status
                        tjnz    scr, #$-1               ' wait for signal to sample again (status = 0)

                        jmp     #:waitForSound          ' sample again

                        
mask                    long    1                       ' sensor pin mask

arg                     res     1                       ' arg pointer
sound                   res     1                       ' pointer to sound counter
silence                 res     1                       ' pointer to silence counter
status                  res     1                       ' pointer to sample status
scr                     res     1                       ' scratch register
t1                      res     1                       ' time sound heard
t2                      res     1                       ' time silence heard




I'm using the TEST and JMP pairs to test for pin high/low (rather than waitpeq/pne) so that I can implement a timeout - if I ever get it working.

The output I get from this is:

Ready

sensor[0], status = 1, cnt[sound] = 502E7996, cnt[silence] = 506AFE22, duration = 3966092
sensor[1], status = 1, cnt[sound] = 502EC528, cnt[silence] = 506D6BBC, duration = 4105876, delay = 19346
sensor[2], status = 1, cnt[sound] = 502FFFC2, cnt[silence] = 50711FC6, duration = 4268036, delay = 99884

sensor[0], status = 1, cnt[sound] = 5EA27C7A, cnt[silence] = 5EDF08D6, duration = 3968092
sensor[1], status = 1, cnt[sound] = 5EA2DDC4, cnt[silence] = 5EE18690, duration = 4106444, delay = 24906
sensor[2], status = 1, cnt[sound] = 5EA3AD26, cnt[silence] = 5EE4CA6A, duration = 4267332, delay = 77996

sensor[0], status = 1, cnt[sound] = 66A47A4A, cnt[silence] = 66E0FC7E, duration = 3965492
sensor[1], status = 1, cnt[sound] = 66A4C66C, cnt[silence] = 66E36A08, duration = 4105116, delay = 19490
sensor[2], status = 1, cnt[sound] = 66A6845E, cnt[silence] = 66E79982, duration = 4265252, delay = 133652

sensor[0], status = 1, cnt[sound] = 6D96E29A, cnt[silence] = 6DD35F16, duration = 3964028
sensor[1], status = 1, cnt[sound] = 720340C4, cnt[silence] = 7241ED68, duration = 4107428, delay = 74210858
sensor[2], status = 1, cnt[sound] = 72050E96, cnt[silence] = 72462282, duration = 4264940, delay = 74329084

sensor[0], status = 1, cnt[sound] = 801E31EA, cnt[silence] = 805AB986, duration = 3966876
sensor[1], status = 1, cnt[sound] = 801E79DC, cnt[silence] = 805D21D8, duration = 4106236, delay = 18418
sensor[2], status = 1, cnt[sound] = 802034F6, cnt[silence] = 80615122, duration = 4267052, delay = 131852

sensor[0], status = 1, cnt[sound] = 87DD565A, cnt[silence] = 8819D326, duration = 3964108
sensor[1], status = 1, cnt[sound] = 8A64D244, cnt[silence] = 8AA37518, duration = 4104916, delay = 42433514
sensor[2], status = 1, cnt[sound] = 8F17ECEE, cnt[silence] = 8F59078A, duration = 4266652, delay = 121280148

sensor[0], status = 1, cnt[sound] = 953294B2, cnt[silence] = 956F1A76, duration = 3966404
sensor[1], status = 1, cnt[sound] = 9532DFA4, cnt[silence] = 95718818, duration = 4106356, delay = 19186
sensor[2], status = 1, cnt[sound] = 9533C936, cnt[silence] = 9574E68A, duration = 4267348, delay = 78980

sensor[0], status = 1, cnt[sound] = 9A5A9D8A, cnt[silence] = 9A711A0E, duration = 1473668
sensor[1], status = 1, cnt[sound] = 9A5A9BEC, cnt[silence] = 9A737D08, duration = 1630492, delay = 414
sensor[2], status = 1, cnt[sound] = 9A5A9A0E, cnt[silence] = 9A763572, duration = 1809252, delay = 892

sensor[0], status = 1, cnt[sound] = A537752A, cnt[silence] = A573FB4E, duration = 3966500
sensor[1], status = 1, cnt[sound] = A537BFBC, cnt[silence] = A57668B0, duration = 4106484, delay = 19090
sensor[2], status = 1, cnt[sound] = A5398B4E, cnt[silence] = A57AA312, duration = 4265924, delay = 136740

sensor[0], status = 1, cnt[sound] = AD74DC62, cnt[silence] = ADB15D86, duration = 3965220
sensor[1], status = 1, cnt[sound] = AD76DEB4, cnt[silence] = ADB58238, duration = 4105092, delay = 131666
sensor[2], status = 1, cnt[sound] = B18C50B6, cnt[silence] = B1CD6792, duration = 4265692, delay = 68645972

Where each group of three lines is the result of a handclap. The output follows a handclap immediately - so I don't understand some of the delays being close to (or more than) a second, or some of them being extremely small. I also don't understand how the sound seems to be heard at the middle sensor first in at least one case. The durations seem to be consistent (except for one instance), but the delays are all over the place - which makes no sense because the sensors are stationary, and my hands are (within a few millimetres) the same distance from the sensors for each of the handclaps.

I thought what I was doing was pretty straight forward, but I just cannot see my mistake.

Any ideas anyone?

Comments

  • r.daneelr.daneel Posts: 96
    edited 2014-02-24 15:14
    Ok, I think I know what's happening. Occasionally the sound (in this case a handclap) isn't loud enough to trigger all three sound sensors - or, more correctly I think, the waveform is such that the first peak triggers one of the sound sensors, but not one or both of the others. Then another peak comes along some time later and triggers the remaining sound sensors. It could be part of the same wave (if the first part of the handclap was a bit muffled), or it could be a second handclap a second or two later. Since my code hasn't implemented the timeouts yet (to keep it clean and simple - doh!), I'm waiting until all three sound sensors detect a sound. Small variances in their sensitivity (I tried to match them) and the fact that they are separated (by 2 inches...) seems to be enough to cause some sounds to trigger one sensor but noth the other(s).

    Now I just have to code the fix and see if I'm right. Later - work beckons.
Sign In or Register to comment.