Advertisement
Guest User

Knock detection

a guest
Jun 23rd, 2018
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.86 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import serial
  4. import time
  5. import numpy.linalg
  6. import math
  7.  
  8.  
  9. class Microphone(object):  # Microphone class
  10.  
  11.     def __init__(self, x, y, limit):
  12.         self.X = x
  13.         self.Y = y
  14.         self.low_limit = limit
  15.         self.counter = 0
  16.  
  17.  
  18. def handle_adc_msg(msg, mics):
  19.     words = msg.split(' ')
  20.     mics[(ord(msg[1]) - ord('0'))].counter = int(words[1])
  21.     mics[(ord(msg[1]) - ord('0'))].raw = msg
  22.  
  23.  
  24. def reset_mics(mics):
  25.     for m in range(0,len(mics)):
  26.         mics[m].counter = -1
  27.  
  28.  
  29. def do_hard_math_2d(mics, W):
  30.  
  31.     N = [None] * len(mics)
  32.     for i in range(0, len(mics)):
  33.         N[i] = float(mics[i].counter - mics[0].counter)
  34.  
  35.     print N
  36.     print "C:     " + str('%.2f' % C) + "\nN:     " + str([ round(e, 2) for e in N ]) + "\n------------------------------"
  37.  
  38.     Tao = [None] * (len(N)-1)
  39.     for i in range(0, len(Tao)):
  40.         Tao[i] = N[i+1]-N[0]
  41.     print "Tao:   " + str([ round(e, 2) for e in Tao ])
  42.  
  43.     D = [None] * len(Tao)
  44.     for i in range(0, len(D)):
  45.         D[i] = Tao[i] * C
  46.     print "D:     " + str([round(e, 2) for e in D])
  47.  
  48.     W = [None] * len(D)
  49.     for i in range(0, len(W)):
  50.         W[i] = ( math.pow(D[i],2) -math.pow(mics[i+1].X,2) +math.pow(mics[0].X,2) -math.pow(mics[i+1].Y,2) +math.pow(mics[0].Y,2) ) / 2
  51.     print "W:     " + str([round(e, 2) for e in W])
  52.  
  53.     A = numpy.zeros((len(mics)-1,3))
  54.     for i in range(0, len(mics)-1):
  55.         A[i][0] = mics[0].X - mics[i+1].X
  56.         A[i][1] = mics[0].Y - mics[i+1].Y
  57.         A[i][2] = D[i]
  58.     print("A:       \n" + '\n'.join([''.join(['{:10}'.format(round(item, 2)) for item in row])  for row in A]))
  59.  
  60.     A_plus = numpy.linalg.pinv(A)
  61.     print("A+:      \n" + '\n'.join([''.join(['{:10}'.format(round(item, 2)) for item in row]) for row in A_plus]))
  62.  
  63.     X = A_plus.dot(numpy.array(W).transpose())
  64.     print "\nX:     " + str([round(e, 2) for e in X])
  65.  
  66.     #ERROR =  math.pow(X[2], 2) - ( math.pow(knock.X, 2) + math.pow(knock.Y, 2)  )
  67.     #print("ERROR: " + str(round(ERROR)))
  68.  
  69.  
  70. def knock_calibration_2d(port, microphones, W):
  71.  
  72.     print " ------------------------- Knock calibration ----------------------------- "
  73.     i = 0
  74.     while True:
  75.         if port.in_waiting > 0:
  76.             msg = str(port.readline()).strip()
  77.             if msg.startswith("ACK:"):  # received an ACK message
  78.                 continue
  79.             elif msg.startswith("A"):  # received an ADC value
  80.                 words = msg.split(' ')
  81.                 microphones[(ord(msg[1]) - ord('0'))] = int(words[1])
  82.                 i = i + 1
  83.             if i == len(microphones):
  84.                 break
  85.  
  86.     print "Raw calibration counter values: " + str([e for e in microphones])
  87.  
  88.     L = W / math.sqrt(2)  # W=47
  89.     T = 0.0
  90.  
  91.     for j in range(1, len(microphones)):
  92.         T = T + (microphones[j].counter - microphones[0].counter)
  93.     T = T / (len(microphones) - 1)
  94.     C = L / T
  95.     print "Normalized calibration counter values: " + str([e for e in microphones])
  96.     print "L=" + str(L) + " T=" + str(T) + " C=" + str(C)
  97.  
  98.  
  99.     return 1
  100.  
  101.  
  102. def main():
  103.     #   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   INIT    ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~
  104.  
  105.     BAUD_RATE = 115200
  106.     PORT_NUMBER = 'COM5'
  107.     WAIT_ALL_MICS_TIME = 0.5  # sec
  108.     W = 47
  109.  
  110.     port = serial.Serial(PORT_NUMBER, BAUD_RATE)
  111.     msg = ""
  112.     first_read_time = time.time()
  113.     is_first_mics = True
  114.     msg_count = 0
  115.     adc_read_success = False
  116.  
  117.     microphones = [
  118.                     Microphone(  0,    0,   50),
  119.                     Microphone(  W/2,  W/2, 50),
  120.                     Microphone(  W/2, -W/2, 50),
  121.                     Microphone( -W/2, -W/2, 50),
  122.                     Microphone( -W/2,  W/2, 50)
  123.                    ]
  124.  
  125.     C = knock_calibration_2d(port, microphones, W)
  126.  
  127.  
  128.     while True: # main loop
  129.  
  130.         if port.in_waiting > 0:
  131.             msg = str(port.readline()).strip()
  132.  
  133.             if msg.startswith("ACK:"):  # received an ACK message
  134.                  continue
  135.             elif msg.startswith("A"):  # received an ADC calue
  136.  
  137. #   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~
  138.  
  139.                 if not is_first_mics:
  140.                     if time.time() - first_read_time < WAIT_ALL_MICS_TIME:  # we are in time to collect more mics value
  141.  
  142.                         if msg_count < len(microphones):
  143.                             print "new value has added to the microphones " + msg
  144.                             msg_count = msg_count + 1
  145.                             handle_adc_msg(msg, microphones)
  146.  
  147.                         if msg_count == len(microphones):
  148.                             do_hard_math_2d(microphones, W)
  149.                             is_first_mics = True
  150.                             continue
  151.  
  152.                     else:
  153.                         print "Runned out of time. New round started "
  154.                         is_first_mics = True
  155.  
  156.                 if is_first_mics:
  157.                     print "Read first mics val in the round: " + msg
  158.                     first_read_time = time.time()
  159.                     reset_mics(microphones)
  160.                     msg_count = 0
  161.                     is_first_mics = False  # here we read the first mics val so the others are not first val anymore
  162.                     msg_count = msg_count + 1
  163.                     handle_adc_msg(msg, microphones)
  164.                     continue
  165.  
  166. #   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~   ~
  167.  
  168.             elif msg.startswith("S"):  # received an ADC SUM value
  169.                 continue
  170.             else: # received an unknown message
  171.                 continue
  172.  
  173.             if adc_read_success:
  174.                 adc_read_success = False
  175.                 reset_mics(microphones)
  176.  
  177.  
  178. if __name__ == '__main__':
  179.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement