Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

ہیلو حبر۔ ممکنہ طور پر ہر وہ شخص جس نے کبھی ہوائی جہاز میں اپنے رشتہ داروں یا دوستوں سے ملاقات کی ہو یا اسے دیکھا ہو مفت Flightradar24 سروس استعمال کی ہو۔ یہ حقیقی وقت میں ہوائی جہاز کی پوزیشن کو ٹریک کرنے کا ایک بہت آسان طریقہ ہے۔

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

В پہلا حصہ اس طرح کے ایک آن لائن سروس کے آپریٹنگ اصول بیان کیا گیا تھا. اب ہم آگے بڑھیں گے اور پتہ لگائیں گے کہ ہوائی جہاز سے وصول کرنے والے اسٹیشن تک کون سا ڈیٹا بھیجا اور وصول کیا جا رہا ہے اور ازگر کا استعمال کرتے ہوئے اسے خود ڈی کوڈ کر رہے ہیں۔

کہانی

ظاہر ہے، ہوائی جہاز کا ڈیٹا صارفین کو ان کے اسمارٹ فونز پر دیکھنے کے لیے منتقل نہیں کیا جاتا ہے۔ اس نظام کو ADS-B (خودکار انحصار نگرانی—براڈکاسٹ) کہا جاتا ہے، اور اس کا استعمال ہوائی جہاز کے بارے میں معلومات کو کنٹرول سینٹر تک خود بخود منتقل کرنے کے لیے استعمال کیا جاتا ہے - اس کا شناخت کنندہ، نقاط، سمت، رفتار، اونچائی اور دیگر ڈیٹا منتقل کیا جاتا ہے۔ اس سے پہلے، اس طرح کے نظام کی آمد سے پہلے، ڈسپیچر صرف ریڈار پر ایک نقطہ دیکھ سکتا تھا. یہ اب کافی نہیں تھا جب بہت زیادہ طیارے تھے۔

تکنیکی طور پر، ADS-B ایک ہوائی جہاز پر ایک ٹرانسمیٹر پر مشتمل ہوتا ہے جو وقتاً فوقتاً 1090 میگاہرٹز کی کافی زیادہ فریکوئنسی پر معلومات کے پیکٹ بھیجتا ہے (اس کے دیگر طریقے بھی ہیں، لیکن ہمیں ان میں اتنی دلچسپی نہیں ہے، کیونکہ نقاط صرف یہاں منتقل ہوتے ہیں)۔ بلاشبہ، ٹرانسمیٹر کے علاوہ ہوائی اڈے پر کہیں نہ کہیں ایک ریسیور بھی ہوتا ہے، لیکن ہمارے لیے بطور صارف، ہمارا اپنا ریسیور دلچسپ ہے۔

ویسے، موازنہ کے لیے، اس طرح کا پہلا سسٹم، Airnav Radarbox، جو عام صارفین کے لیے ڈیزائن کیا گیا تھا، 2007 میں سامنے آیا، اور اس کی لاگت تقریباً 900 ڈالر ہے؛ نیٹ ورک سروسز کی رکنیت پر سالانہ مزید $250 لاگت آتی ہے۔

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

ان پہلے روسی مالکان کے جائزے فورم پر پڑھے جا سکتے ہیں۔ ریڈیو سکینر. اب چونکہ RTL-SDR ریسیورز بڑے پیمانے پر دستیاب ہو چکے ہیں، اسی طرح کی ڈیوائس کو $30 میں اسمبل کیا جا سکتا ہے۔ پہلا حصہ. آئیے خود پروٹوکول کی طرف چلتے ہیں - آئیے دیکھتے ہیں کہ یہ کیسے کام کرتا ہے۔

سگنل وصول کرنا

سب سے پہلے، سگنل کو ریکارڈ کرنے کی ضرورت ہے. پورے سگنل کا دورانیہ صرف 120 مائیکرو سیکنڈز ہے، اس لیے اس کے اجزاء کو آرام سے جدا کرنے کے لیے، کم از کم 5 میگاہرٹز کے نمونے لینے کی فریکوئنسی کے ساتھ ایک SDR ریسیور ضروری ہے۔

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

ریکارڈنگ کے بعد، ہمیں 5000000 نمونے فی سیکنڈ کے نمونے لینے کی شرح کے ساتھ ایک WAV فائل موصول ہوتی ہے؛ اس طرح کی ریکارڈنگ کے 30 سیکنڈ کا "وزن" تقریباً 500MB ہے۔ میڈیا پلیئر کے ساتھ اسے سننا، یقیناً بیکار ہے - فائل میں آواز نہیں ہوتی، بلکہ براہ راست ڈیجیٹائزڈ ریڈیو سگنل ہوتا ہے - بالکل اسی طرح سافٹ ویئر ڈیفائنڈ ریڈیو کام کرتا ہے۔

ہم Python کا استعمال کرتے ہوئے فائل کو کھولیں گے اور اس پر کارروائی کریں گے۔ جو لوگ خود تجربہ کرنا چاہتے ہیں وہ ایک مثال کی ریکارڈنگ ڈاؤن لوڈ کر سکتے ہیں۔ ссылке по.

آئیے فائل ڈاؤن لوڈ کریں اور دیکھیں کہ اندر کیا ہے۔

from scipy.io import wavfile
import matplotlib.pyplot as plt
import numpy as np

fs, data = wavfile.read("adsb_20190311_191728Z_1090000kHz_RF.wav")
data = data.astype(float)
I, Q = data[:, 0], data[:, 1]
A = np.sqrt(I*I + Q*Q)

plt.plot(A)
plt.show()

نتیجہ: ہم پس منظر کے شور کے خلاف واضح "دالیں" دیکھتے ہیں۔

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

ہر "پلس" ایک سگنل ہے، جس کی ساخت واضح طور پر نظر آتی ہے اگر آپ گراف پر ریزولوشن بڑھاتے ہیں۔

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

جیسا کہ آپ دیکھ سکتے ہیں، تصویر اوپر دی گئی تفصیل کے ساتھ بالکل مطابقت رکھتی ہے۔ آپ ڈیٹا پر کارروائی شروع کر سکتے ہیں۔

ضابطہ کشائی

سب سے پہلے، آپ کو تھوڑا سا سلسلہ حاصل کرنے کی ضرورت ہے. مانچسٹر انکوڈنگ کا استعمال کرتے ہوئے سگنل خود کو انکوڈ کیا جاتا ہے:

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

نبلوں میں سطح کے فرق سے حقیقی "0" اور "1" حاصل کرنا آسان ہے۔

    bits_str = ""
    for p in range(8):
        pos = start_data + bit_len*p
        p1, p2 = A[pos: pos + bit_len/2], A[pos + bit_len/2: pos + bit_len]
        avg1, avg2 = np.average(p1), np.average(p2)
        if avg1 < avg2:
            bits_str += "0"
        elif avg1 > avg2:
            bits_str += "1"

سگنل کی ساخت خود مندرجہ ذیل ہے:

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

آئیے مزید تفصیل سے کھیتوں کو دیکھتے ہیں۔

DF (ڈاؤن لنک فارمیٹ، 5 بٹس) - پیغام کی قسم کا تعین کرتا ہے۔ کئی قسمیں ہیں:

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول
(ٹیبل کا ذریعہ)

ہمیں صرف قسم DF17 میں دلچسپی ہے، کیونکہ... یہ ہوائی جہاز کے نقاط پر مشتمل ہے.

آایسییو (24 بٹس) - ہوائی جہاز کا بین الاقوامی منفرد کوڈ۔ آپ ہوائی جہاز کو اس کے کوڈ سے چیک کر سکتے ہیں۔ آن لائن (بدقسمتی سے، مصنف نے ڈیٹا بیس کو اپ ڈیٹ کرنا بند کر دیا ہے، لیکن یہ اب بھی متعلقہ ہے)۔ مثال کے طور پر، کوڈ 3c5ee2 کے لیے ہمارے پاس درج ذیل معلومات ہیں:

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

ترمیم کریں: میں مضمون پر تبصرے ICAO کوڈ کی تفصیل مزید تفصیل سے دی گئی ہے؛ میری تجویز ہے کہ دلچسپی رکھنے والے اسے پڑھیں۔

اعداد و شمار (56 یا 112 بٹس) - اصل ڈیٹا جسے ہم ڈی کوڈ کریں گے۔ ڈیٹا کے پہلے 5 بٹس فیلڈ ہیں۔ قسم کا کوڈ۔, ذخیرہ کیے جانے والے ڈیٹا کی ذیلی قسم پر مشتمل ہے (DF کے ساتھ الجھن میں نہ پڑے)۔ ان میں سے چند اقسام ہیں:

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول
(ٹیبل کا ذریعہ)

آئیے پیکجوں کی چند مثالیں دیکھتے ہیں۔

ہوائی جہاز کی شناخت

بائنری شکل میں مثال:

00100 011 000101 010111 000111 110111 110001 111000

ڈیٹا فیلڈز:

+------+------+------+------+------+------+------+------+------+------+
| TC,5 | EC,3 | C1,6 | C2,6 | C3,6 | C4,6 | C5,6 | C6,6 | C7,6 | C8,6 |
+------+------+------+------+------+------+------+------+------+------+

TC = 00100b = 4، ہر کریکٹر C1-C8 لائن میں موجود انڈیکس کے مطابق کوڈز پر مشتمل ہے:
#ABCDEFGHIJKLMNOPQRSTUVWXYZ####_################0123456789#####

سٹرنگ کو ڈی کوڈ کرنے سے، ہوائی جہاز کا کوڈ حاصل کرنا آسان ہے: EWG7184

symbols = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######"
code_str = ""
for p in range(8):
     c = int(bits_str[8 + 6*p:8 + 6*(p + 1)], 2)
     code_str += symbols[c]
print("Aircraft Identification:", code_str.replace('#', ''))

ہوا سے چلنے والی پوزیشن

اگر نام سادہ ہے، تو نقاط زیادہ پیچیدہ ہیں۔ وہ 2، برابر اور طاق فریموں کی شکل میں منتقل ہوتے ہیں۔ فیلڈ کوڈ TC = 01011b = 11۔

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول

جفت اور طاق پیکٹس کی مثال:

01011 000 000101110110 00 10111000111001000 10000110101111001
01011 000 000110010000 01 10010011110000110 10000011110001000

نقاط کا حساب خود ایک مشکل فارمولے کے مطابق ہوتا ہے:

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول
(ذرائع)

میں GIS ماہر نہیں ہوں، اس لیے مجھے نہیں معلوم کہ یہ کہاں سے آیا ہے۔ کون جانتا ہے، کمنٹس میں لکھیں۔

اونچائی کو آسان سمجھا جاتا ہے - مخصوص بٹ پر منحصر ہے، اسے 25 یا 100 فٹ کے کثیر کے طور پر دکھایا جا سکتا ہے۔

ہوا سے چلنے والی رفتار

TC=19 کے ساتھ پیکیج۔ یہاں دلچسپ بات یہ ہے کہ رفتار یا تو درست ہو سکتی ہے، زمین کی نسبت (گراؤنڈ سپیڈ)، یا ہوائی ہوائی، ہوائی جہاز کے سینسر (ایئر اسپیڈ) سے ناپی جاتی ہے۔ بہت سے مختلف شعبوں کو بھی منتقل کیا جاتا ہے:

Flightradar24 - یہ کیسے کام کرتا ہے؟ حصہ 2، ADS-B پروٹوکول
(ذرائع)

حاصل يہ ہوا

جیسا کہ آپ دیکھ سکتے ہیں، ADS-B ٹیکنالوجی ایک دلچسپ سمبیوسس بن گئی ہے، جب ایک معیار نہ صرف پیشہ ور افراد کے لیے، بلکہ عام صارفین کے لیے بھی مفید ہے۔ لیکن یقیناً، اس میں ایک کلیدی کردار ڈیجیٹل SDR ریسیورز کی سستی ٹیکنالوجی نے ادا کیا، جو کہ ڈیوائس کو لفظی طور پر ایک گیگاہرٹز سے زیادہ فریکوئنسی کے ساتھ سگنل وصول کرنے کی اجازت دیتا ہے "پینی کے لیے۔"

معیار میں ہی، یقینا، اور بھی بہت کچھ ہے۔ دلچسپی رکھنے والے صفحہ پر پی ڈی ایف دیکھ سکتے ہیں۔ آایسییو یا پہلے ہی اوپر ذکر کردہ پر جائیں ویب سائٹ.

اس بات کا امکان نہیں ہے کہ مذکورہ بالا سبھی بہت سے لوگوں کے لیے کارآمد ہوں گے، لیکن کم از کم اس کے کام کرنے کا عمومی خیال، مجھے امید ہے، باقی رہے گا۔

ویسے، Python میں ایک ریڈی میڈ ڈیکوڈر پہلے سے موجود ہے، آپ اس کا مطالعہ کر سکتے ہیں۔ یہاں. اور SDR ریسیورز کے مالکان ایک ریڈی میڈ ADS-B ڈیکوڈر کو جمع اور لانچ کر سکتے ہیں۔ صفحہ سے، اس میں مزید تفصیل سے بات کی گئی۔ پہلا حصہ.

مضمون میں بیان کردہ تجزیہ کار کا ماخذ کوڈ کٹ کے نیچے دیا گیا ہے۔ یہ ایک آزمائشی مثال ہے جو پروڈکشن کا بہانہ نہیں کرتی، لیکن اس میں کچھ چیزیں کام کرتی ہیں، اور اسے اوپر درج فائل کو پارس کرنے کے لیے استعمال کیا جا سکتا ہے۔
ماخذ کوڈ (ازگر)

from __future__ import print_function
from scipy.io import wavfile
from scipy import signal
import matplotlib.pyplot as plt
import numpy as np
import math
import sys
def parse_message(data, start, bit_len):
max_len = bit_len*128
A = data[start:start + max_len]
A = signal.resample(A, 10*max_len)
bits = np.zeros(10*max_len)
bit_len *= 10
start_data = bit_len*8
# Parse first 8 bits
bits_str = ""
for p in range(8):
pos = start_data + bit_len*p
p1, p2 = A[pos: pos + bit_len/2], A[pos + bit_len/2: pos + bit_len]
avg1, avg2 = np.average(p1), np.average(p2)
if avg1 < avg2:
bits_str += "0"
elif avg1 > avg2:
bits_str += "1"
df = int(bits_str[0:5], 2)
# Aircraft address (db - https://junzis.com/adb/?q=3b1c5c )
bits_str = ""
for p in range(8, 32):
pos = start_data + bit_len * p
p1, p2 = A[pos: pos + bit_len / 2], A[pos + bit_len / 2: pos + bit_len]
avg1, avg2 = np.average(p1), np.average(p2)
if avg1 < avg2:
bits_str += "0"
elif avg1 > avg2:
bits_str += "1"
# print "Aircraft address:", bits_str, hex(int(bits_str, 2))
address = hex(int(bits_str, 2))
# Filter specific aircraft (optional)
# if address != "0x3c5ee2":
#    return
if df == 16 or df == 17 or df == 18 or df == 19 or df == 20 or df == 21:
# print "Pos:", start, "DF:", msg_type
# Data (56bit)
bits_str = ""
for p in range(32, 88):
pos = start_data + bit_len*p
p1, p2 = A[pos: pos + bit_len/2], A[pos + bit_len/2: pos + bit_len]
avg1, avg2 = np.average(p1), np.average(p2)
if avg1 < avg2:
bits_str += "0"
# bits[pos + bit_len / 2] = 50
elif avg1 > avg2:
bits_str += "1"
# http://www.lll.lu/~edward/edward/adsb/DecodingADSBposition.html
# print "Data:"
# print bits_str[:8], bits_str[8:20],  bits_str[20:22], bits_str[22:22+17], bits_str[39:39+17]
# Type Code:
tc, ec = int(bits_str[:5], 2), int(bits_str[5:8], 2)
# print("DF:", df, "TC:", tc)
# 1 - 4  Aircraft identification
# 5 - 8  Surface position
# 9 - 18  Airborne position (w/ Baro Altitude)
# 19  Airborne velocities
if tc >= 1 and tc <= 4: # and (df == 17 or df == 18):
print("Aircraft address:", address)
print("Data:")
print(bits_str[:8], bits_str[8:14],  bits_str[14:20], bits_str[20:26], bits_str[26:32], bits_str[32:38], bits_str[38:44])
symbols = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######"
code_str = ""
for p in range(8):
c = int(bits_str[8 + 6*p:8 + 6*(p + 1)], 2)
code_str += symbols[c]
print("Aircraft Identification:", code_str.replace('#', ''))
print()
if tc == 11:
print("Aircraft address:", address)
print("Data: (11)")
print(bits_str[:8], bits_str[8:20],  bits_str[20:22], bits_str[22:22+17], bits_str[39:39+17])
# Bit 22 contains the F flag which indicates which CPR format is used (odd or even)
# First frame has F flag = 0 so is even and the second frame has F flag = 1 so odd
# f = bits_str[21:22]
# print("F:", int(f, 2))
# Altitude
alt1b = bits_str[8:20]
if alt1b[-5] == '1':
bits = alt1b[:-5] + alt1b[-4:]
n = int(bits, 2)
alt_ft = n*25 - 1000
print("Alt (ft)", alt_ft)
# lat_dec = int(bits_str[22:22+17], 2)
# lon_dec = int(bits_str[39:39+17], 2)
# print("Lat/Lon:", lat_dec, lon_dec)
# http://airmetar.main.jp/radio/ADS-B%20Decoding%20Guide.pdf
print()
if tc == 19:
print("Aircraft address:", address)
print("Data:")
# print(bits_str)
print(bits_str[:5], bits_str[5:8], bits_str[8:10], bits_str[10:13], bits_str[13] ,bits_str[14:24], bits_str[24], bits_str[25:35], bits_str[35:36], bits_str[36:65])
subtype = int(bits_str[5:8], 2)
# https://mode-s.org/decode/adsb/airborne-velocity.html
spd, hdg, rocd = -1, -1, -1
if subtype == 1 or subtype == 2:
print("Velocity Subtype 1: Ground speed")
v_ew_sign = int(bits_str[13], 2)
v_ew = int(bits_str[14:24], 2) - 1       # east-west velocity
v_ns_sign = int(bits_str[24], 2)
v_ns = int(bits_str[25:35], 2) - 1       # north-south velocity
v_we = -1*v_ew if v_ew_sign else v_ew
v_sn = -1*v_ns if v_ns_sign else v_ns
spd = math.sqrt(v_sn*v_sn + v_we*v_we)  # unit in kts
hdg = math.atan2(v_we, v_sn)
hdg = math.degrees(hdg)                 # convert to degrees
hdg = hdg if hdg >= 0 else hdg + 360    # no negative val
if subtype == 3:
print("Subtype Subtype 3: Airspeed")
hdg = int(bits_str[14:24], 2)/1024.0*360.0
spd = int(bits_str[25:35], 2)
vr_sign = int(bits_str[36], 2)
vr = int(bits_str[36:45], 2)
rocd = -1*vr if vr_sign else vr         # rate of climb/descend
print("Speed (kts):", spd, "Rate:", rocd, "Heading:", hdg)
print()
# print()
def calc_coordinates():
def _cprN(lat, is_odd):
nl = _cprNL(lat) - is_odd
return nl if nl > 1 else 1
def _cprNL(lat):
try:
nz = 15
a = 1 - math.cos(math.pi / (2 * nz))
b = math.cos(math.pi / 180.0 * abs(lat)) ** 2
nl = 2 * math.pi / (math.acos(1 - a/b))
return int(math.floor(nl))
except:
# happens when latitude is +/-90 degree
return 1
def floor_(x):
return int(math.floor(x))
lat1b, lon1b, alt1b = "10111000111010011", "10000110111111000", "000101111001"
lat2b, lon2b, alt2b = "10010011101011100", "10000011000011011", "000101110111"
lat1, lon1, alt1 = int(lat1b, 2), int(lon1b, 2), int(alt1b, 2)
lat2, lon2, alt2 = int(lat2b, 2), int(lon2b, 2), int(alt2b, 2)
# 131072 is 2^17, since CPR lat and lon are 17 bits each
cprlat_even, cprlon_even = lat1/131072.0, lon1/131072.0
cprlat_odd, cprlon_odd = lat2/131072.0, lon2/131072.0
print(cprlat_even, cprlon_even)
j = floor_(59*cprlat_even - 60*cprlat_odd)
print(j)
air_d_lat_even = 360.0 / 60
air_d_lat_odd = 360.0 / 59
# Lat
lat_even = float(air_d_lat_even * (j % 60 + cprlat_even))
lat_odd = float(air_d_lat_odd * (j % 59 + cprlat_odd))
if lat_even >= 270:
lat_even = lat_even - 360
if lat_odd >= 270:
lat_odd = lat_odd - 360
# Lon
ni = _cprN(lat_even, 0)
m = floor_(cprlon_even * (_cprNL(lat_even)-1) - cprlon_odd * _cprNL(lat_even) + 0.5)
lon = (360.0 / ni) * (m % ni + cprlon_even)
print("Lat", lat_even, "Lon", lon)
# Altitude
# Q-bit (bit 48) indicates whether the altitude is encoded in multiples of 25 or 100 ft (0: 100 ft, 1: 25 ft)
# The value can represent altitudes from -1000 to +50175 ft.
if alt1b[-5] == '1':
bits = alt1b[:-5] + alt1b[-4:]
n = int(bits, 2)
alt_ft = n*25 - 1000
print("Alt (ft)", alt_ft)
fs, data = wavfile.read("adsb_20190311_191728Z_1090000kHz_RF.wav")
T = 1/fs
print("Sample rate %f MS/s" % (fs / 1e6))
print("Cnt samples %d" % len(data))
print("Duration: %f s" % (T * len(data)))
data = data.astype(float)
cnt = data.shape[0]
# Processing only part on file (faster):
# cnt = 10000000
# data = data[:cnt]
print("Processing I/Q...")
I, Q = data[:, 0], data[:, 1]
A = np.sqrt(I*I + Q*Q)
bits = np.zeros(cnt)
# To see scope without any processing, uncomment
# plt.plot(A)
# plt.show()
# sys.exit(0)
print("Extracting signals...")
pos = 0
avg = 200
msg_start = 0
# Find beginning of each signal
while pos < cnt - 16*1024:
# P1 - message start
while pos < cnt - 16*1024:
if A[pos] < avg and A[pos+1] > avg and pos - msg_start > 1000:
msg_start = pos
bits[pos] = 100
pos += 4
break
pos += 1
start1, start2, start3, start4 = msg_start, 0, 0, 0
# P2
while pos < cnt - 16*1024:
if A[pos] < avg and A[pos+1] > avg:
start2 = pos
bits[pos] = 90
pos += 1
break
pos += 1
# P3
while pos < cnt - 16*1024:
if A[pos] < avg and A[pos+1] > avg:
start3 = pos
bits[pos] = 80
pos += 1
break
pos += 1
# P4
while pos < cnt - 16*1024:
if A[pos] < avg and A[pos+1] > avg:
start4 = pos
bits[pos] = 70
pos += 1
break
pos += 1
sig_diff = start4 - start1
if 20 < sig_diff < 25:
bits[msg_start] = 500
bit_len = int((start4 - start1) / 4.5)
# print(pos, start1, start4, ' - ', bit_len)
# start = start1 + 8*bit_len
parse_message(A, msg_start, bit_len)
pos += 450
# For debugging: check signal start
# plt.plot(A)
# plt.plot(bits)
# plt.show()

مجھے امید ہے کہ کسی کو دلچسپی تھی، آپ کی توجہ کا شکریہ۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں