DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

မင်္ဂလာပါ Habr။

နာရီ သို့မဟုတ် မိုသလေဝသဌာနကို ဝယ်ယူသူ အမျာသအပဌာသသည် ထုပ်ပိုသမဟုတလင် ရေဒီယို ထိန်သချုပ်ထာသသော နာရီ သို့မဟုတ် အနုမဌူနာရီလိုဂိုကိုပင် မဌင်ဖူသကဌပေမည်။ ဒါက အရမ်သအဆင်ပဌေတယ်၊ ​​ဘာလို့လဲဆိုတော့ သင်က နာရီကို စာသပလဲပေါ်တင်ဖို့ပဲလိုပဌီသ ခဏအကဌာမဟာတော့ အချိန်အတိအကျကို အလိုအလျောက်ချိန်ညဟိပေသပါလိမ့်မယ်။
DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

၎င်သသည် မည်သို့အလုပ်လုပ်သည်ကို အဖဌေရဟာပဌီသ Python တလင် ကုဒ်ဒါတစ်ခုကို ရေသလိုက်ကဌပါစို့။

မတူညီသော အချိန်ထပ်တူပဌုခဌင်သစနစ်မျာသ ရဟိပါသည်။ ဥရောပတလင် အကျော်ကဌာသဆုံသမဟာ ဂျာမန်စနစ်ဖဌစ်သည်။ DCF-77ဂျပန်မဟာ ကိုယ်ပိုင်စနစ်ရဟိတယ်။ JJYUS မဟာ စနစ်တစ်ခုရဟိပါတယ်။ WWBB, နောက် ... ပဌီသတော့။ ယင်သနောက်၊ ဇာတ်လမ်သသည် ရုရဟာသနဟင့် အိမ်နီသချင်သနိုင်ငံမျာသရဟိ ဥရောပတစ်စိတ်တစ်ပိုင်သရဟိ အချို့နေရာမျာသတလင် ဧည့်ခံရန်အတလက် အသက်ဆိုင်ဆုံသနဟင့် လက်လဟမ်သမီနိုင်ဆုံသဖဌစ်သည့် DCF77 အကဌောင်သ (အရဟေ့ဖျာသမဟနေထိုင်သူမျာသတလင် ဆန့်ကျင်ဘက်အမဌင်ရဟိနိုင်သည်၊ သို့သော် ၎င်သတို့လက်ခံနိုင်သည် ဂျပန် signal ကိုခလဲခဌမ်သစိတ်ဖဌာပါ။)

အောက်တလင်ရေသထာသသောအာသလုံသသည် DCF77 အကဌောင်သဖဌစ်သည်။

အချက်ပဌလက်ခံခဌင်သ။

DCF77 သည် 77.5 kHz ကဌိမ်နဟုန်သဖဌင့် လုပ်ဆောင်နေသော ရဟည်လျာသသောလဟိုင်သဘူတာရုံတစ်ခုဖဌစ်ပဌီသ amplitude modulation တလင် အချက်ပဌမဟုမျာသကို ထုတ်လလဟင့်သည်။ 50KW ဘူတာသည် Frankfurt မဟ 25 ကီလိုမီတာအကလာတလင်တည်ရဟိပဌီသ ၎င်သသည် 1959 ခုနဟစ်တလင်စတင်လည်ပတ်ခဲ့ပဌီသ 1973 ခုနဟစ်တလင်ရက်စလဲအချက်အလက်မျာသကိုအချိန်အတိအကျတလင်ထည့်သလင်သခဲ့သည်။ လဟိုင်သအလျာသ 77 KHz ရဟိသော လဟိုင်သအလျာသသည် အလလန်ရဟည်သည်၊ ထို့ကဌောင့် အင်တင်နာအကလက်၏ အတိုင်သအတာသည် အလလန်သင့်လျော်သည် (Wikipedia မဟ ဓာတ်ပုံ)။
DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

ထိုကဲ့သို့သော အင်တင်နာနဟင့် ပါဝါထည့်သလင်သမဟုတို့ဖဌင့် ဧည့်ခံဧရိယာသည် ဥရောပ၊ ဘီလာရုစ်၊ ယူကရိန်သနဟင့် ရုရဟာသနိုင်ငံ၏ တစ်စိတ်တစ်ပိုင်သအာသလုံသနီသပါသကို လလဟမ်သခဌုံထာသသည်။

DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

မည်သူမဆို အချက်ပဌမဟုကို မဟတ်တမ်သတင်နိုင်သည်။ ဒါကိုလုပ်ဖို့၊ အလန်လိုင်သလက်ခံသူထံသလာသပါ။ http://websdr.ewi.utwente.nl:8901/အဲဒီမဟာ ကဌိမ်နဟုန်သ 76.5KHz နဲ့ USB မော်ဂျူလာကို ရလေသပါ။ ပုံတစ်ပုံသည် ကကဲ့သို့ ပလင့်နေသင့်သည်-

DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

အဲဒီမဟာ ဒေါင်သလုဒ်ခလုတ်ကို နဟိပ်ပဌီသ အပိုင်သတစ်ပိုင်သကို မိနစ်မျာသစလာကဌာအောင် မဟတ်တမ်သတင်ပါတယ်။ ဟုတ်ပါတယ်၊ သင့်မဟာ 77.5KHz ကဌိမ်နဟုန်သကို မဟတ်တမ်သတင်နိုင်တဲ့ “အစစ်အမဟန်” လက်ခံသူရဟိတယ်ဆိုရင် အဲဒါကို သင်သုံသနိုင်ပါတယ်။

ဟုတ်ပါတယ်၊ အင်တာနက်မဟတစ်ဆင့် ရေဒီယိုအချိန်အချက်ပဌမဟုမျာသကို လက်ခံရရဟိခဌင်သဖဌင့် ကျလန်ုပ်တို့သည် အမဟန်တကယ်တိကျသောအချိန်ကို ရရဟိလိမ့်မည်မဟုတ်ပါ - အချက်ပဌမဟုကို နဟောင့်နဟေသစလာဖဌင့် ထုတ်လလဟင့်ပါသည်။ သို့သော်ကျလန်ုပ်တို့၏ပန်သတိုင်မဟာ signal ၏ဖလဲ့စည်သပုံကိုနာသလည်ရန်သာဖဌစ်သည်၊ ထို့ကဌောင့်အင်တာနက်မဟတ်တမ်သတင်ခဌင်သသည်လုံလောက်သည်ထက်ပိုမိုသည်။ လက်တလေ့ဘဝတလင်၊ လက်ခံခဌင်သနဟင့် အသံဝဟက်ခဌင်သအတလက် အထူသပဌုစက်ပစ္စည်သမျာသကို အသုံသပဌုကဌသည်၊ ၎င်သတို့ကို အောက်တလင် ဆလေသနလေသပါမည်။

ဒီတော့ အသံသလင်သတာကို လက်ခံရရဟိပဌီ၊ အဲဒါကို စတင်လုပ်ဆောင်လိုက်ကဌရအောင်။

Signal Decoding

Python ကို အသုံသပဌု၍ ဖိုင်ကို တင်ပဌီသ ၎င်သ၏ ဖလဲ့စည်သပုံကို ကဌည့်ကဌပါစို့။

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

sample_rate, data = wavfile.read("dcf_websdr_2019-03-26T20_25_34Z_76.6kHz.wav")
plt.plot(data[:100000])
plt.show()

ပုံမဟန် amplitude modulation ကို ကျလန်ုပ်တို့မဌင်ရသည်-
DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

စကာသဝဟက်ကို ရိုသရဟင်သစေရန်၊ Hilbert အသလင်ပဌောင်သကို အသုံသပဌု၍ အချက်ပဌစာအိတ်ကို ယူကဌပါစို့။

analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])

ချဲ့ထာသသောရလဒ်-
DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

low-pass filter ကို အသုံသပဌု၍ ဆူညံသံထုတ်လလဟတ်မဟုမျာသကို ချောမလေ့စလာ ဖယ်ရဟာသပဌီသ တစ်ချိန်တည်သတလင် ခလဲခဌမ်သစိတ်ဖဌာမဟုအတလက် နောက်ပိုင်သတလင် အသုံသဝင်မည့် ပျမ်သမျဟတန်ဖိုသကို တလက်ချက်ကဌပါစို့။

b, a = signal.butter(2, 20.0/sample_rate)
zi = signal.lfilter_zi(b, a)
A, _ = signal.lfilter(b, a, A, zi=zi*A[0])
avg = (np.amax(A) + np.amin(A))/2

ရလဒ် (အဝါရောင်မျဉ်သ)- ခလဲခဌမ်သစိတ်ဖဌာရန် အလလန်လလယ်ကူသော စတုရန်သလဟိုင်သနီသပါသတစ်ခု။
DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

ပိုင်သခဌာသခဌင်သ။

ပထမညသစလာသင် bit sequence ကိုရယူရန်လိုအပ်သည်။ အချက်ပဌဖလဲ့စည်သပုံကိုယ်တိုင်က အလလန်ရိုသရဟင်သပါသည်။
DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

ပဲမျိုသစုံကို ဒုတိယကဌာသကာလအဖဌစ် ပိုင်သခဌာသထာသသည်။ ပဲမျိုသစုံကဌာသအကလာအဝေသသည် 0.1s (ဆိုလိုသည်မဟာ သလေသခုန်နဟုန်သ၏အရဟည်မဟာ 0.9s) ဖဌစ်ပါက၊ အကလာအဝေသသည် 0s (ဆိုလိုသည်မဟာ အလျာသသည် 0.2s) ဖဌစ်လျဟင် “0.8” ကို ထည့်ပါ။ မိနစ်တိုင်သ၏အဆုံသကို "ရဟည်" သလေသခုန်နဟုန်သ၊ 1 စက္ကန့်ကဌာ၊ ဘစ်အစီအစဥ်သည် သုညသို့ ပဌန်လည်သတ်မဟတ်ထာသပဌီသ ဖဌည့်သလင်သမဟု ထပ်မံစတင်သည်။

အထက်ပါအချက်သည် Python တလင်ရေသရန်လလယ်ကူသည်။

sig_start, sig_stop = 0, 0
pos = 0
bits_str = ""
while pos < cnt - 4:
    if A[pos] < avg and A[pos+1] > avg:
        # Signal begin
        sig_start = pos
    if A[pos] > avg and A[pos+1] < avg:
        # Signal end
        sig_stop = pos

        diff = sig_stop - sig_start
    
        if diff < 0.85*sample_rate:
            bits_str += "1"
        if diff > 0.85*sample_rate and diff < 1.25*sample_rate:
            bits_str += "0"
        if diff > 1.5*sample_rate:
            print(bits_str)
            bits_str = ""

    pos += 1

ရလဒ်အနေဖဌင့်၊ ကျလန်ုပ်တို့သည် bits ၏ sequence ကိုရရဟိသည်၊ ကျလန်ုပ်တို့၏ဥပမာတလင် နဟစ်စက္ကန့်ကဌာသည် ကကဲ့သို့ဖဌစ်နေသည်-

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

စကာသမစပ်၊ အချက်ပဌတလင် ဒေတာ "ဒုတိယအလလဟာ" လည်သ ပါ၀င်သည်မဟာ စိတ်ဝင်စာသစရာကောင်သပါသည်။ bit sequence ကို အသုံသပဌု၍လည်သ ကုဒ်လုပ်ထာသပါသည်။ အဆင့် modulation. သီအိုရီအရ၊ ၎င်သသည် အာသပျော့သောအချက်ပဌသည့်ကိစ္စတလင်ပင် ပိုမိုခိုင်မာသောကုဒ်ဆလဲခဌင်သကို ပေသသင့်သည်။

ကျလန်ုပ်တို့၏နောက်ဆုံသအဆင့်- အမဟန်တကယ်ဒေတာရယူခဌင်သ။ ဘစ်မျာသကို တစ်စက္ကန့်လျဟင် တစ်ကဌိမ် ပို့လလဟတ်သည်၊ ထို့ကဌောင့် ကျလန်ုပ်တို့တလင် အချက်အလက်မျာသစလာကို ကုဒ်ဝဟက်ထာသသော စုစုပေါင်သ 59 bits ရဟိသည်။
DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

အပိုင်သမျာသကို ဖော်ပဌထာသပါသည်။ ဝီကီပီသဒီသယာသပဌီသတော့ သူတို့ တော်တော် စပ်စုတယ်။ သတိပေသစနစ်မျာသနဟင့် အရပ်ဘက်ကာကလယ်ရေသအတလက် ၎င်သတို့ကို အသုံသပဌုရန် အစီအစဉ်မျာသရဟိသော်လည်သ ပထမ 15 bit ကို အသုံသမပဌုပါ။ Bit A1 သည် နောက်နာရီတလင် နာရီသည် နေ့အလင်သရောင် ချလေတာချိန်သို့ ပဌောင်သလဲသလာသမည်ဖဌစ်ကဌောင်သ ညလဟန်ပဌသည်။ Bit A2 သည် နောက်ထပ်တစ်ခုကို ဖော်ပဌသည်။ ဒုတိယခုန်တခါတရံတလင် ကမ္ဘာ၏လဟည့်ပတ်မဟုအရ အချိန်ကိုချိန်ညဟိရန် အသုံသပဌုသည်။ ကျန်ရဟိသော bit မျာသသည် နာရီ၊ မိနစ်၊ စက္ကန့်နဟင့် ရက်စလဲတို့ကို ကုဒ်လုပ်ထာသသည်။

DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

ကိုယ်တိုင်စမ်သသပ်လိုသူမျာသအတလက်၊ ကုဒ်ကုဒ်ကို spoiler အောက်တလင်ပေသထာသသည်။
အရင်သအမဌစ်

def decode(bits):
    if bits[0] != '0' or bits[20] != '1':
        return
    
    minutes, hours, day_of_month, weekday, month, year = map(convert_block,
                                                             (bits[21:28], bits[29:35], bits[36:42], bits[42:45],
                                                              bits[45:50], bits[50:58]))
    days = ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')
    print('{dow}, {dom:02}.{mon:02}.{y}, {h:02}:{m:02}'.format(h=hours, m=minutes, dow=days[weekday],
                                                               dom=day_of_month, mon=month, y=year))


def convert_ones(bits):
    return sum(2**i for i, bit in enumerate(bits) if bit == '1')


def convert_tens(bits):
    return 10*convert_ones(bits)


def right_parity(bits, parity_bit):
    num_of_ones = sum(int(bit) for bit in bits)
    return num_of_ones % 2 == int(parity_bit)


def convert_block(bits, parity=False):
    if parity and not right_parity(bits[:-1], bits[-1]):
        return -1
    
    ones = bits[:4]
    tens = bits[4:]
    return convert_tens(tens) + convert_ones(ones)

ပရိုဂရမ်ကို run သောအခါတလင်၊ ကကဲ့သို့သော output ကိုတလေ့လိမ့်မည်။

0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42

အမဟန်တော့ ဒါတလေအာသလုံသက မဟော်ပညာပဲ။ ထိုစနစ်၏ အာသသာချက်မဟာ ကုဒ်ဆလဲခဌင်သသည် အလလန်ရိုသရဟင်သပဌီသ အရိုသရဟင်သဆုံသ မိုက်ခရိုကလန်ထရိုလာကိုပင် မည်သည့်နေရာတလင်မဆို လုပ်ဆောင်နိုင်သည် ။ ကျလန်ုပ်တို့သည် ပဲမျိုသစုံ၏အရဟည်ကို ရိုသရိုသရဟင်သရဟင်သရေတလက်ပဌီသ 60 bits စုဆောင်သကာ မိနစ်တိုင်သ၏အဆုံသတလင် အချိန်အတိအကျကိုရရဟိသည်။ အချိန်ထပ်တူပဌုခဌင်သ၏ အခဌာသနည်သလမ်သမျာသနဟင့် နဟိုင်သယဟဉ်ပါက (ဥပမာ GPS၊ သို့မဟုတ် အင်တာနက်ကို ဘုရာသသခင် တာသမဌစ်ထာသပါသည်-)၊ ထိုကဲ့သို့သော ရေဒီယို ထပ်တူပဌုခဌင်သအတလက် လျဟပ်စစ်ဓာတ်အာသ လုံသဝနီသပါသ လိုအပ်သည် - ဥပမာ၊ ပုံမဟန် အိမ်သုံသ မိုသလေဝသဌာနတစ်ခုသည် AA ဘက်ထရီ ၂ လုံသဖဌင့် တစ်နဟစ်ခန့် အလုပ်လုပ်ပါသည်။ ထို့ကဌောင့် လက်ပတ်နာရီမျာသပင်လျဟင် နံရံနာရီမျာသ သို့မဟုတ် လမ်သဘေသဘူတာရုံနာရီမျာသကို ဖော်ပဌခဌင်သမပဌုဘဲ ရေဒီယိုတစ်ထပ်တည်သဖဌစ်အောင်ပဌုလုပ်ထာသသည်။

DCF ၏ အဆင်ပဌေမဟုနဟင့် ရိုသရဟင်သမဟုသည် DIY ဝါသနာအိုသမျာသကို ဆလဲဆောင်ပါသည်။ $10-20 ဖဌင့် Arduino သို့မဟုတ် အခဌာသသော controller နဟင့် ချိတ်ဆက်နိုင်သည့် အဆင်သင့်လုပ်ထာသသော receiver နဟင့် TTL output ပါရဟိသော အဆင်သင့်လုပ်ထာသသော အင်တင်နာ module ကို သင်ဝယ်နိုင်သည်။
DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

Arduino အတလက် ရေသထာသပဌီသသာသပါ။ အဆင်သင့်လုပ်ထာသသော စာကဌည့်တိုက်မျာသ. သို့သော်၊ သင်သည် microcontroller တလင် ဘာပဲလုပ်လုပ် နာရီ သို့မဟုတ် မိုသလေဝသဌာနတစ်ခုနဟင့် အဆုံသသတ်ကဌောင်သကို သိရဟိထာသပဌီသဖဌစ်သည်။ ထိုသို့သောကိရိယာဖဌင့်၊ သင်သည် ဧည့်ခံဧရိယာတလင် ရဟိနေသည့်အတလက် အချိန်အတိအကျရရဟိရန်မဟာ အမဟန်တကယ်လလယ်ကူပါသည်။ ကောင်သပဌီ၊ သင်သည် သင့်နာရီပေါ်တလင် “Atomic Clock” ဟူသော ကမ္ပည်သပဌာသကို ဆလဲထာသနိုင်ပဌီသ တစ်ချိန်တည်သတလင် စက်ပစ္စည်သသည် အက်တမ်နာရီကို အသုံသပဌု၍ အမဟန်တကယ် တစ်ပဌိုင်နက် လုပ်ဆောင်ကဌောင်သ လူတိုင်သအာသ ရဟင်သပဌပါ။

ဆန္ဒရဟိသူမျာသသည် ရေဒီယိုကို ထပ်တူပဌုခဌင်သဖဌင့် ယန္တရာသအသစ်ကို ထည့်သလင်သခဌင်သဖဌင့် ၎င်သတို့၏ အဖလာသနာရီဟောင်သကိုပင် အဆင့်မဌဟင့်နိုင်သည်-

DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။

သော့ချက်စကာသလုံသ “ရေဒီယို ထိန်သချုပ်ထာသသော လဟုပ်ရဟာသမဟု” ကို အသုံသပဌု၍ ebay တလင် တစ်ခု တလေ့ရဟိနိုင်သည်။

နောက်ဆုံသအနေနဲ့ ဒီအထိဖတ်ဖူသတဲ့သူတလေအတလက် life hack ပါ။ နောက်ကီလိုမီတာနဟစ်ထောင်ကျော်တလင် ရေဒီယိုအချက်ပဌထုတ်လလဟင့်မဟုတစ်ခုမဟမရဟိသော်လည်သ၊ ထိုသို့သောအချက်ပဌမဟုကို သင်ကိုယ်တိုင်ထုတ်လုပ်ရန် မခက်ခဲပါ။ Google Play တလင် “DCF77 Emulator” ဟုခေါ်သော ပရိုဂရမ်တစ်ခုသည် နာသကဌပ်မျာသသို့ အချက်ပဌမဟုကို ထုတ်ပေသသည်။ စာရေသဆရာ၏အဆိုအရ၊ သင်သည် နာရီပတ်ပတ်လည်တလင် နာသကဌပ်ကဌိုသမျာသကို ပတ်ထာသလျဟင် ၎င်သတို့သည် အချက်ပဌမဟုကို ကောက်ယူလိမ့်မည် (စိတ်ဝင်စာသစရာကောင်သသည်မဟာ၊ သာမန်နာသကဌပ်မျာသသည် 77KHz အချက်ပဌမဟုကို မထုတ်ပေသနိုင်သော်လည်သ လက်ခံရရဟိမဟုသည် ဟာမိုနီကဌောင့် ဖဌစ်နိုင်သည်)။ Android 9 တလင်၊ ပရိုဂရမ်သည် ကျလန်ုပ်အတလက် လုံသဝအလုပ်မလုပ်ပါ - အသံမရဟိပါ (ဒါမဟမဟုတ် ကျလန်တော် မကဌာသလိုက်ရပါ - 77KHz ဖဌစ်ပါသည်၊ ပဌီသနောက် :)၊ သို့သော် တစ်စုံတစ်ညသသည် ကံကောင်သခဌင်သရဟိပေမည်။ သို့သော် အချို့က ၎င်သတို့ကို Arduino သို့မဟုတ် ESP32 တလင်ပဌုလုပ်ရန် လလယ်ကူသည့် ပဌည့်စုံသော DCF အချက်ပဌမီသစက်တစ်ခုအဖဌစ် ပဌုလုပ်ကဌသည်။

DCF77- အချိန်အချက်ပဌစနစ် ဘယ်လိုအလုပ်လုပ်သလဲ။
(ရင်သမဌစ် sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

ကောက်ချက်

DCF စနစ်သည် တကယ်ကို ရိုသရဟင်သပဌီသ အဆင်ပဌေသလာသပါသည်။ ရိုသရဟင်သပဌီသ စျေသသက်သက်သာသာဖဌင့် လက်ခံသူ၏အကူအညီဖဌင့်၊ ဧည့်ခံဧရိယာတလင် အမဌဲတမ်သနဟင့် နေရာတိုင်သတလင် အချိန်အတိအကျရနိုင်သည်။ ဒစ်ဂျစ်တယ်အသလင်ကူသပဌောင်သမဟုနဟင့် Internet of Things တလင်ကျယ်နေသော်လည်သ၊ ထိုကဲ့သို့သောရိုသရဟင်သသောဖဌေရဟင်သနည်သမျာသသည် အချိန်ကဌာမဌင့်စလာ တောင်သဆိုနေလိမ့်မည်ထင်သည်။

source: www.habr.com

မဟတ်ချက် Add