Sabtu, 10 Oktober 2015

TUNING KONTROLER PID LINE FOLLOWER

TUNING KONTROLER PID LINE FOLLOWER
Tunning kontrol PID ini bertujuan untuk menentukan paramater aksi kontrol Proportional, Integratif, Derivatif pada robot line follower. Proses ini dapat dilakukan dengan cara trial and error . Keunggulan cara ini kita gak perlu mengidentifikasi plant, membuat model matematis plant, menentukan parameter plant dengan grafis ataupun analitis…cukup dengan cara coba-coba memberikan konstanta P-I-D pada formula PID hingga di peroleh hasil yang di inginkan, dengan mengacu pada karakteristik masing-masing kontrol P-I-D.
Nach kalo kita menggunakan kendali PID artinya kita nantinya bertujuan mengolah suatu sinyal kesalahan atau error, nilai error tersebut diolah dengan formula PID untuk dijadikan suatu sinyal kendali atau sinyal kontrol yang akan diteruskan ke aktuator. Gampangnya perhatikan saja blok diagram umpan balik loop tertutup pada perancangan kedali PID pada robot line follower berikut ini:
Dari blok diagram diatas dapat q jelasin sebagai berikut
  1. SP = Set point, secara simple maksudnya ialah suatu prameter nilai acuan atau nilai yang kita inginkan.
  2. PV = Present Value, kalo yang ini maksudnya ialah nilai bobot pembacaan sensor saat itu atau variabel terukur yang di umpan balikan oleh sensor (sinyal feedback dari sensor).
  3. Error = nilai kesalahan, nach kalo yang ini pengertiannya ialah Deviasi atau simpangan antar variabel terukur atau bobot sensor (PV) dengan nilai acuan (SP)
Setelah memahami alur pengendalian PID nach berikut ilustrasi pemberian bobot sensor (nilai kesalahan pembacaan sensor) pada robot line follower:
Dari blok iliustrasi tersebut dapat q jelasin sebagai berikut:
Proses pemberian bobot sensor dapat dilakukan dengan proses pemetaan (mapping) pembacaan sensor terhadap garis, berikut salah satu sample proses mapping sensor:
11111110 (PV=-7)
11111000 (PV=-6)
11111100 (PV=-6)
11111101 (PV=-5)
11110001 (PV=-4)
11111001 (PV=-4)
11111011 (PV=-3)
11100011 (PV=-2)
11110011 (PV=-2)
11110111 (PV=-1)
11100111 (PV=0)
11101111 (PV=1)
11000111 (PV=2)
11001111 (PV=2)
11011111 (PV=3)
10001111 (PV=4)
10011111 (PV=4)
10111111 (PV=5)
00011111 (PV=6)
00111111 (PV=6)
01111111 (PV=7)
11111111 (PV=8 / -8)
Kondisi ideal robot terjadi saat kondisi robot pada PV= 0 (misal kondisi nilai sensor = 11100111, nilai 0 merepresentasikan sensor mengenai garis). Atau SP = 0 ialah kondisi ideal dari robot line follower. Jika PV tidak sama dengan 0 berarti robot tidak berada pada kondisi ideal dan artinya ada sinyal kesalahan (error). Pada kondisi error inilah formula PID akan menentukan hasil sinyal kendalinya. Nach berikut ini penjelasan tentang penerapan PID pada robot line follower:
Proporsional kontrol
Kondisi ideal pada robot adalah bergerak maju lurus mengikuti garis, dengan kata lain PV = 0 (nilai sensor = 11100111). Dari sini dapat diasumsikan bahwa Set Point (SP) / kondisi ideal adalah saat SP = 0. Nilai sensor yang dibaca oleh sensor disebut Process Variable (PV) / nilai aktual pembacaan. Menyimpangnya posisi robot dari garis disebut sebagai error (e), yang didapat dari e = SP – PV. Dengan mengetahui besar error, mikrokontroler dapat memberikan nilai PWM motor kiri dan kanan yang sesuai agar dapat menuju ke posisi ideal (SP = 0). Besarnaya nilai PWM ini dapat diperoleh dengan menggunakan kontrol Proporsional (P), dimana P = e  Kp (Kp adalah konstanta proporsional yang nilainya di set sendiri dari hasil tuning).
Saat Sensor = 11111111 nilai PV dapat ditentukan dengan cara membandingkan kondisi PV sebelumnya, jika PV lebih besar dari 0, maka nilai PV dapat diasumsikan 30 dan jika PV kurang dari 0, maka nilai PV dapat diasumsikan -30 atau dengan cara menyimpan nilai error yang lalu.
Dalam pemrograman robot line follower ini kodenya  ditulis secara sederhana seperti berikut:
If Sensor = &B11111111 Then
If Pv < 0 Then : Pv = -30
End If
If Pv > 0 Then : Pv = 30
End If
End If
Perhitungan Kontroler Proporsional
Sp_sensor = 0                             ‘setpoint sensor
Error = Sp_sensor – Pv           ‘nilai error
P = Kp * Error                              ‘proporsional kontrol
Aplikasi kontrol proporsional pada PWM ialah sebagai berikut:
Pwm = Sp_kecepatan + P       ‘motor kiri
Pwm = Sp_kecepatan – P       ‘motor kanan
Derivatif kontrol
Jika pergerakan robot masih terlihat bergelombang, bisa ditambahkan kontrol Derivatif (D). Kontrol D digunakan untuk mengukur seberapa cepat robot bergerak dari kiri ke kanan atau dari kanan ke kiri. Semakin cepat bergerak dari satu sisi ke sisi lainnya, maka semakin besar nilai D. Konstanta D (Kd) digunakan untuk menambah atau mengurangi imbas dari derivatif. Dengan mendapatkan nilai Kd yang tepat pergerakan sisi ke sisi yang bergelombang akibat dari kontrol proporsional bisa diminimalisasi. Nilai D didapat dari D = Kd/Ts * rate, dimana Ts ialah time sampling atau waktu cuplik dan rate = e(n) – e(n-1). Dalam program nilai error (SP – PV) saat itu menjadi nilai last_error, sehingga rate didapat dari error – last_error. Untuk menambahkan kontrol D, program dimodifikasi menjadi:
Perhitungan Kontroler Proporsional + Derivatif
Sp_sensor = 0                             ‘setpoint sensor
Error = Sp_sensor – Pv           ‘nilai error
P = Kp * Error                              ‘proporsional kontrol
D1 = Kd * 10                                 ‘derivatif kontrol
D2 = D1 / Ts
D3 = Error – Last_error           ‘rate
D = D2 * D3
Last_error = Error                   ‘error lampau
Pd = P + D                                     ‘proporsional-derivatif kontrol
Aplikasi kontrol proporsional dan drivatif pada PWM ialah sebagai berikut:
Pwm = Sp_kecepatan + Pd     ‘motor kiri
Pwm = Sp_kecepatan – Pd     ‘motor kanan
Integratif kontrol
Jika dengan P + D sudah membuat pergerakan robot cukup smooth, maka penambahan Integratif menjadi opsional. Jika ingin mencoba-coba bisa ditambahakan Integratif (I). I digunakan untuk mengakumulasi error dan mengetahui durasi error. Dengan menjumlahkan error disetiap pembacaan PV akan memberikan akumulasi offset yang harus diperbaiki sebelumnya. Saat robot bergerak menjauhi garis, maka nilai error akan bertambah. Semakin lama tidak mendapatkan SP, maka semakin besar nilai I. Degan mendapatkan nilai Ki yang tepat, imbas dari Integratif bisa dikurangi. Nilai akumulasi error didapat dari: error + last_error. Untuk menambahkan kontrol I, maka program di modifikasi menjadi:
Perhitungan Kontroler Proporsional + Integratif + Derivatif
Sp_sensor = 0                             ‘setpoint sensor
Error = Sp_sensor – Pv           ‘nilai error
P = Kp * Error                              ‘proporsional kontrol
D1 = Kd * 10                                  ‘derivatif kontrol
D2 = D1 / Ts
D3 = Error – Last_error           ‘rate
D = D2 * D3
I1 = Ki / 10                                    ’integratif kontrol
I2 = Error + Last_error           ‘akumulasi error
I3 = I1 * I2
I = I3 * Ts
Last_error = Error                   ‘error lampau
Pd = P + D                                     ‘proporsional-derivatif kontrol
Pid = Pd+I                                    ‘proporsional-integratif-derivatif
Aplikasi kontrol proporsional, integratif dan drivatif pada PWM ialah sebagai berikut:
Pwm = Sp_kecepatan + Pid    ‘motor kiri
Pwm = Sp_kecepatan – Pid    ‘motor kanan
Parameter Nilai Konstanta Kontroler P I D
Nilai konstanta perhitungan PID di tuning secara trial and error, proses ini dilakukan dengan metode mencoba-coba (eksperimental) nilai proporsional, derivatif dan integratif pada formula PID hingga ditemukan hasil sistem yag stabil, adapun cara yang dilakukan untuk mentuning PID pada robot line follower ialah sebagai berikut:
  1. Langkah awal gunakan kontrol proporsional terlebih dahulu, abaikan konstanta integratif dan derivatifnya dengan memberikan nilai nol pada integratif dan derivatif.
  2. Tambahkan terus konstanta proporsional maksimum hingga keadaan stabil namun robot masih berosilasi.
  3. Untuk meredam osilasi, tambahkan konstanta derivatif dengan membagi dua nilai proporsional, amati keadaan sistem robot hingga stabil dan lebih responsif.
  4. Jika sistem robot telah stabil, kontrol integratif dapat menjadi opsional, dalam artian jika ingin mencoba-coba tambahkan kontrol integratif tersebut, namun pemberian nilai integratif yang tidak tepat dapat membuat sistem robot menjadi tidak stabil.
  5. Nilai set point kecepatan dan nilai batas bawah/atas memberikan patokan kecepatan robot.
  6. Nilai time sampling (waktu cuplik) juga mempengaruhi perhitungan PID, tentunnya saat penggunaan kontrol integratif dan derivatif.
  7. Periksa kembali perfoma sistem hingga mendapatkan hasil yang memuaskan.
Acuan penentuan parameter Kp, Ki dan Kd  dapat diadopsi dari watak dari kontroler itu masing seperti yang dijelaskan pada tabel berikut ini:

Dan berikut ini sample coding PID line followerku dengan pemrograman BASCOM AVR :
$regfile = “m8535.dat”
$crystal = 12000000
$eeprom
‘—————————inisialisasi pwm————————————
Config Timer1 = Pwm , Pwm = 10 , Prescale = 64 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down       ‘pwm dengan settingan fast pwm 10 bit
‘—————————inisialisasi adc————————————
Config Adc = Single , Prescaler = Auto
‘—————————inisialisasi lcd————————————
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.2 , Rs = Portc.0
Config Lcd = 16 * 2 : Cursor Off
‘——————————————————————————-
‘PENDEFINISIAN PIN MIKRO
‘——————————————————————————-
Config Portd = Output
‘alias logika motor
M1a Alias Portd.0
M1b Alias Portd.1
M2a Alias Portd.2
M2b Alias Portd.3
Config Portb = Input
Portb = 255
‘alias tombol
Sw_ok Alias Pinb.3
Sw_cancel Alias Pinb.2
Sw_down Alias Pinb.1
Sw_up Alias Pinb.0
Config Portc.3 = Output
‘——————————————————————————-
‘DEKLARASI VARIABEL
‘——————————————————————————-
Dim B1 As Bit , B2 As Bit , B3 As Bit , B4 As Bit , B5 As Bit , B6 As Bit , B7 As Bit , B8 As Bit,
Dim S1 As Byte , S2 As Byte , S3 As Byte , S4 As Byte , S5 As Byte , S6 As Byte , S7 As Byte , S8 As Byte
Dim Adc1 As Integer , Adc2 As Integer , Adc3 As Integer , Adc4 As Integer , Adc5 As Integer , Adc6 As Integer , Adc7 As Integer , Adc8 As Integer,
Dim S12 As Byte , S123 As Byte , S1234 As Byte , S12345 As Byte , S123456 As Byte , S1234567 As Byte , S12345678 As Byte
Dim C As Byte
Dim B As Byte
Dim Sensor As Byte
Dim Konversi_sensor As Byte
Dim Data1 As Byte
Dim Menu As Byte
‘——————————-declarasi variabel——————————
‘variabel eeprom
Dim Kp_eprom As Eram Integer
Dim Ki_eprom As Eram Integer
Dim Kd_eprom As Eram Integer
Dim Ts_eprom As Eram Integer
Dim Sp_kecepatan_eprom As Eram Integer
Dim Up_eprom As Eram Integer
Dim Lp_eprom As Eram Integer
Dim Nos_eprom As Eram Integer
Dim Hold_eprom As Eram Integer
Dim Kp As Integer
Dim Ki As Integer
Dim Kd As Integer
Dim Ts As Integer
Dim Sp_sensor As Integer
Dim Sp_kecepatan As Integer
Dim Up As Integer
Dim Lp As Integer
Dim Nos As Integer
Dim Hold As Integer
Dim Error As Integer
Dim Last_error As Integer
Dim Pv As Integer
Dim P As Integer
Dim Pd As Integer
Dim Pid As Integer
Dim Pwm As Integer
Dim I1 As Integer
Dim I2 As Integer
Dim I3 As Integer
Dim I As Integer
Dim D1 As Integer
Dim D2 As Integer
Dim D3 As Integer
Dim D As Integer
Dim N1 As Integer
Dim N2 As Integer
‘——————————————————————————-
‘DEKLARASI SUBRUTIN
‘——————————————————————————-
Declare Sub Baca_sensor()
Declare Sub Kiri_maju()
Declare Sub Kanan_maju()
Declare Sub Kiri_mundur()
Declare Sub Kanan_mundur()
Declare Sub Bantingkanan()
Declare Sub Bantingkiri()
Portc.3 = 0                                                 ‘lcd on
Cls : Home
Lcd “ADC LINEfollower”
Waitms 500
Lowerline
Lcd “Fahmizal_dte2006″
Waitms 1500
Portc.3 = 1                                                 ‘lcd off
Menu_utama:
Cls
Home : Lcd “‘menu’<<<<^>>>>>”
Lowerline
Lcd “Please choice…”
Do
If Sw_up = 0 Then : Waitms 250 : Menu = 1
End If
If Sw_down = 0 Then : Waitms 250 : Menu = 2
End If
If Menu = 1 Then : Locate 2 , 1 : Lcd “Setting ROBOT…”
If Sw_ok = 0 Then : Waitms 250 : Gosub Setting_pid : End If
End If
If Menu = 2 Then : Locate 2 , 1 : Lcd “Go……..Ready?”
If Sw_ok = 0 Then : Waitms 250 : Gosub Go : End If
End If
Loop
‘——————————-menu Konstanta PID——————————
Setting_pid:
Cls
Menu_kp:
Do
Kp = Kp_eprom
If Sw_up = 0 Then : Incr Kp : Waitms 10
End If
If Sw_down = 0 Then : Decr Kp : Waitms 10
End If
If Sw_ok = 0 Then : Waitms 250 : Gosub Menu_ki
End If
If Sw_cancel = 0 Then : Waitms 250 : Gosub Menu_utama
End If
If Kp > 50 Then : Kp = 0 : Waitms 10
End If
If Kp < 0 Then : Kp = 50 : Waitms 10
End If
Home : Lcd “Tuning PID ^–^ ” : Locate 2 , 1 : Lcd “KP:” : Locate 2 , 4 : Lcd “           ” : Locate 2 , 4 : Lcd Kp : Waitms 100
Kp_eprom = Kp
Loop
‘———————————————
Menu_ki:
Do
Ki = Ki_eprom
If Sw_up = 0 Then : Incr Ki : Waitms 10
End If
If Sw_down = 0 Then : Decr Ki : Waitms 10
End If
If Sw_ok = 0 Then : Waitms 250 : Gosub Menu_kd
End If
If Sw_cancel = 0 Then : Waitms 250 : Gosub Menu_kp
End If
If Ki > 20 Then : Ki = 0 : Waitms 10
End If
If Ki < 0 Then : Ki = 20 : Waitms 10
End If
Home : Lcd “Tuning PID ^–^ ” : Locate 2 , 1 : Lcd “KI:” : Locate 2 , 4 : Lcd “           ” : Locate 2 , 4 : Lcd Ki : Waitms 100
Ki_eprom = Ki
Loop
‘———————————————
Menu_kd:
Do
Kd = Kd_eprom
If Sw_up = 0 Then : Kd = Kd + 5 : Waitms 10
End If
If Sw_down = 0 Then : Kd = Kd – 5 : Waitms 10
End If
If Sw_ok = 0 Then : Waitms 250 : Gosub Menu_ts
End If
If Sw_cancel = 0 Then : Waitms 250 : Gosub Menu_ki
End If
If Kd > 150 Then : Kd = 0 : Waitms 10
End If
If Kd < 0 Then : Kd = 150 : Waitms 10
End If
Home : Lcd “Tuning PID ^–^ ” : Locate 2 , 1 : Lcd “KD:” : Locate 2 , 4 : Lcd “           ” : Locate 2 , 4 : Lcd Kd : Waitms 100
Kd_eprom = Kd
Loop
‘———————————————
Menu_ts:
Do
Ts = Ts_eprom
If Sw_up = 0 Then : Ts = Ts + 5 : Waitms 10
End If
If Sw_down = 0 Then : Ts = Ts – 5 : Waitms 10
End If
If Sw_ok = 0 Then : Waitms 250 : Gosub Menu_sp_kecepatan
End If
If Sw_cancel = 0 Then : Waitms 250 : Gosub Menu_kd
End If
If Ts > 20 Then : Ts = 0 : Waitms 10
End If
If Ts < 0 Then : Ts = 20 : Waitms 10
End If
Home : Lcd “TimeSampling(ms)” : Locate 2 , 1 : Lcd “TS:” : Locate 2 , 4 : Lcd “           ” : Locate 2 , 4 : Lcd Ts : Waitms 100
Ts_eprom = Ts
Loop
‘———————————————
Menu_sp_kecepatan:
Do
Sp_kecepatan = Sp_kecepatan_eprom
If Sw_up = 0 Then : Sp_kecepatan = Sp_kecepatan + 50 : Waitms 10
End If
If Sw_down = 0 Then : Sp_kecepatan = Sp_kecepatan – 50 : Waitms 10
End If
If Sw_ok = 0 Then : Waitms 250 : Gosub Menu_up
End If
If Sw_cancel = 0 Then : Waitms 250 : Gosub Menu_ts
End If
If Sp_kecepatan > 600 Then : Sp_kecepatan = 400 : Waitms 5
End If
If Sp_kecepatan < 400 Then : Sp_kecepatan = 600 : Waitms 5
End If
Home : Lcd “Set Point  ^–^ ” : Locate 2 , 1 : Lcd “kecepatan:” : Locate 2 , 11 : Lcd “        ” : Locate 2 , 11 : Lcd Sp_kecepatan : Waitms 100
Sp_kecepatan_eprom = Sp_kecepatan
Loop
‘———————————————
Menu_up:
Do
Up = Up_eprom
If Sw_up = 0 Then : Up = Up + 50 : Waitms 10
End If
If Sw_down = 0 Then : Up = Up – 50 : Waitms 10
End If
If Sw_ok = 0 Then : Waitms 250 : Gosub Menu_nos
End If
If Sw_cancel = 0 Then : Waitms 250 : Gosub Menu_sp_kecepatan
End If
If Up > 1000 Then : Up = 700 : Waitms 10
End If
If Up < 700 Then : Up = 1000 : Waitms 10
End If
Home : Lcd “TOP speed ROBOT ” : Locate 2 , 1 : Lcd “top:” : Locate 2 , 5 : Lcd “           ” : Locate 2 , 5 : Lcd Up : Waitms 100
Up_eprom = Up
Loop
‘———————————————
Menu_nos:
Do
Nos = Nos_eprom
If Sw_up = 0 Then : Nos = Nos + 100 : Waitms 10
End If
If Sw_down = 0 Then : Nos = Nos -100 : Waitms 10
End If
If Sw_ok = 0 Then : Waitms 250 : Gosub Menu_hold:
End If
If Sw_cancel = 0 Then : Waitms 250 : Gosub Menu_up
End If
If Nos > 500 Then : Nos = 100 : Waitms 10
End If
If Nos < 100 Then : Nos = 500 : Waitms 10
End If
Home : Lcd “POWER ^–^ ROBOT” : Locate 2 , 1 : Lcd “start:” : Locate 2 , 7 : Lcd “           ” : Locate 2 , 7 : Lcd Nos : Waitms 100
Nos_eprom = Nos
Loop
‘——————————————————————————-
Menu_hold:
Do
Hold = Hold_eprom
If Sw_up = 0 Then : Hold = Hold + 5 : Waitms 10
End If
If Sw_down = 0 Then : Hold = Hold – 5 : Waitms 10
End If
If Sw_ok = 0 Then : Waitms 250 : Gosub Rampung_setting:
End If
If Sw_cancel = 0 Then : Waitms 250 : Gosub Menu_nos
End If
If Hold > 75 Then : Hold = 25 : Waitms 10
End If
If Hold < 25 Then : Hold = 75 : Waitms 10
End If
Home : Lcd “TressHold^SENSOR” : Locate 2 , 1 : Lcd “hold:” : Locate 2 , 6 : Lcd “           ” : Locate 2 , 6 : Lcd Hold : Waitms 100
Hold_eprom = Hold
Loop
‘——————————————————————————-
‘——————————-tampilansaveepprom——————————
Rampung_setting:
Cls
Locate 1 , 1 : Lcd “Write’_to_EEPROM”
Locate 2 , 1 : Lcd “=” : Waitms 200
Locate 2 , 2 : Lcd “=” : Waitms 180
Locate 2 , 3 : Lcd “=” : Waitms 155
Locate 2 , 4 : Lcd “=” : Waitms 125
Locate 2 , 5 : Lcd “=” : Waitms 90
Locate 2 , 6 : Lcd “=” : Waitms 70
Locate 2 , 7 : Lcd “=” : Waitms 50
Locate 2 , 8 : Lcd “=” : Waitms 35
Locate 2 , 9 : Lcd “=” : Waitms 20
Locate 2 , 10 : Lcd “=” : Waitms 15
Locate 2 , 11 : Lcd “=” : Waitms 13
Locate 2 , 12 : Lcd “=” : Waitms 11
Locate 2 , 13 : Lcd “=” : Waitms 9
Locate 2 , 14 : Lcd “=” : Waitms 7
Locate 2 , 15 : Lcd “=” : Waitms 5
Locate 2 , 16 : Lcd “=” : Waitms 300
Locate 2 , 1 : Lcd “writesucsesfully” : Waitms 500 : Gosub Go:
‘——————————————————————————-
Go:
Kp = Kp_eprom
Ki = Ki_eprom
Kd = Kd_eprom
Ts = Ts_eprom
Sp_kecepatan = Sp_kecepatan_eprom
Up = Up_eprom
Nos = Nos_eprom
Hold = Hold_eprom
Portc.3 = 0                                                 ‘lcd      on
Cls
Locate 2 , 5 : Lcd “Ready..!!”
Locate 1 , 8 : Lcd “-” : Waitms 150
Locate 1 , 8 : Lcd “3″ : Waitms 150
Locate 1 , 8 : Lcd “2″ : Waitms 150
Locate 1 , 8 : Lcd “1″ : Waitms 150
Locate 1 , 8 : Lcd “-” : Waitms 150
Cls : Locate 2 , 7 : Lcd “GO…” : Waitms 200 : Cls
Do
Portc.3 = 1                                                ‘lcd      off
Call Baca_sensor()
Sensor = Konversi_sensor
If Sensor = &B00000001 Then : Pv = 20 : End If
If Sensor = &B00000010 Then : Pv = 11 : End If
If Sensor = &B00000100 Then : Pv = 5 : End If
If Sensor = &B00001000 Then : Pv = 0 : End If
If Sensor = &B00010000 Then : Pv = 0 : End If
If Sensor = &B00100000 Then : Pv = -5 : End If
If Sensor = &B01000000 Then : Pv = -11 : End If
If Sensor = &B10000000 Then : Pv = -20 : End If
If Sensor = &B00000011 Then : Pv = 16 : End If
If Sensor = &B00000110 Then : Pv = 8 : End If
If Sensor = &B00001100 Then : Pv = 2 : End If
If Sensor = &B00011000 Then : Pv = 0 : End If
If Sensor = &B00110000 Then : Pv = -2 : End If
If Sensor = &B01100000 Then : Pv = -8 : End If
If Sensor = &B11000000 Then : Pv = -16 : End If
If Sensor = &B00000111 Then : Pv = 12 : End If
If Sensor = &B00001110 Then : Pv = 6 : End If
If Sensor = &B00011100 Then : Pv = 3 : End If
If Sensor = &B00111000 Then : Pv = -3 : End If
If Sensor = &B01110000 Then : Pv = -6 : End If
If Sensor = &B11100000 Then : Pv = -12 : End If
If Sensor = &B00001111 Then : Pv = 8 : End If
If Sensor = &B00011110 Then : Pv = 2 : End If
If Sensor = &B00111100 Then : Pv = 0 : End If
If Sensor = &B01111000 Then : Pv = -2 : End If
If Sensor = &B11110000 Then : Pv = -8 : End If
If Sensor = &B00000000 Then
Portc.3 = 0                                                ‘lcd      on
If Pv < -10 Then : Pv = -30 : Nos = Up / 2
End If
If Pv > 10 Then : Pv = 30 : Nos = Up / 2
End If
End If
If Pv < 0 Then
N1 = Up / 2
N2 = Nos / 3
Nos = N1 + N2
End If
If Pv > 0 Then
N1 = Up / 2
N2 = Nos / 3
Nos = N1 + N2
End If
‘setpoint sensor
Sp_sensor = 0
‘nilai error
Error = Sp_sensor – Pv
‘proportional control
P = Kp * Error
‘integrativ control
I1 = Error + Last_error
I2 = I1 / 2
I = Ki * I2
‘derivative control
D1 = Kd * 10
D2 = Error – Last_error
D = D1 * D2
‘error lampau
Last_error = Error
‘proportional-derivative control
Pd = P + D
‘proportional-integrativ-derivative control
Pid = Pd + I
‘===== Hitung Kondisi Pertama=============’sebelah kiri
Pwm = Sp_kecepatan + Pid
If Pwm > 0 Then : Call Kiri_maju() : Locate 2 , 7 : Lcd “F” : End If
If Pwm > Up Then : Pwm = Up : End If
If Pwm < 0 Then : Call Kiri_mundur() : Pwm = 0 – Pwm : Locate 2 , 7 : Lcd “R” : End If
If Pv = 0 Then : Pwm = Nos : If Nos < Up Then : Nos = Nos + 25 : End If : End If
Pwm1a = Pwm
‘=====Hitung Kondisi Kedua===============’sebelah kanan
Pwm = Sp_kecepatan – Pid
If Pwm > 0 Then : Call Kanan_maju() : Locate 2 , 16 : Lcd “F” : End If
If Pwm > Up Then : Pwm = Up : End If
If Pwm < 0 Then : Call Kanan_mundur() : Pwm = 0 – Pwm : Locate 2 , 16 : Lcd “R” : End If
If Pv = 0 Then : Pwm = Nos : If Nos < Up Then : Nos = Nos + 25 : End If : End If
Pwm1b = Pwm
Locate 2 , 1 : Lcd “L:” : Locate 2 , 3 : Lcd “    ” : Locate 2 , 3 : Lcd Pwm1a : Locate 2 , 10 : Lcd “R:” : Locate 2 , 12 : Lcd “    ” : Locate 2 , 12 : Lcd Pwm1b
Locate 1 , 11 : Lcd “PV:” : Locate 1 , 14 : Lcd “   ” : Locate 1 , 14 : Lcd Pv
‘selang waktu cuplik
Waitms Ts                                                   ‘time sampling
Loop
End
Sub Baca_sensor()
Start Adc
Adc1 = Getadc(0) : Adc1 = Adc1 / 5
Adc2 = Getadc(1) : Adc2 = Adc2 / 5
Adc3 = Getadc(2) : Adc3 = Adc3 / 5
Adc4 = Getadc(3) : Adc4 = Adc4 / 5
Adc5 = Getadc(4) : Adc5 = Adc5 / 5
Adc6 = Getadc(5) : Adc6 = Adc6 / 5
Adc7 = Getadc(6) : Adc7 = Adc7 / 5
Adc8 = Getadc(7) : Adc8 = Adc8 / 5
If Adc1 < Hold Then : S1 = &B00000000 : B1 = 0 : End If : If Adc1 > Hold Then : S1 = &B00000001 : B1 = 1 : End If
If Adc2 < Hold Then : S2 = &B00000000 : B2 = 0 : End If : If Adc2 > Hold Then : S2 = &B00000010 : B2 = 1 : End If
If Adc3 < Hold Then : S3 = &B00000000 : B3 = 0 : End If : If Adc3 > Hold Then : S3 = &B00000100 : B3 = 1 : End If
If Adc4 < Hold Then : S4 = &B00000000 : B4 = 0 : End If : If Adc4 > Hold Then : S4 = &B00001000 : B4 = 1 : End If
If Adc5 < Hold Then : S5 = &B00000000 : B5 = 0 : End If : If Adc5 > Hold Then : S5 = &B00010000 : B5 = 1 : End If
If Adc6 < Hold Then : S6 = &B00000000 : B6 = 0 : End If : If Adc6 > Hold Then : S6 = &B00100000 : B6 = 1 : End If
If Adc7 < Hold Then : S7 = &B00000000 : B7 = 0 : End If : If Adc7 > Hold Then : S7 = &B01000000 : B7 = 1 : End If
If Adc8 < 120 Then : S8 = &B00000000 : B8 = 0 : End If : If Adc8 > 120 Then : S8 = &B10000000 : B8 = 1 : End If
S12 = S1 Or S2 : S123 = S12 Or S3 : S1234 = S123 Or S4 : S12345 = S1234 Or S5 : S123456 = S12345 Or S6 : S1234567 = S123456 Or S7 : S12345678 = S1234567 Or S8
Konversi_sensor = S12345678 And &B11111111
Locate 1 , 1 : Lcd “s”
Locate 1 , 2 : Lcd B1
Locate 1 , 3 : Lcd B2
Locate 1 , 4 : Lcd B3
Locate 1 , 5 : Lcd B4
Locate 1 , 6 : Lcd B5
Locate 1 , 7 : Lcd B6
Locate 1 , 8 : Lcd B7
Locate 1 , 9 : Lcd B8
End Sub
Sub Kiri_maju()
Reset M2a
Set M2b
End Sub
Sub Kanan_maju()
Reset M1a
Set M1b
End Sub
Sub Kiri_mundur()
Set M2a
Reset M2b
End Sub
Sub Kanan_mundur()
Set M1a
Reset M1b
End Sub
===============================================================
Dan berikut ini sample coding PID line followerku dengan pemrograman CODEVISION AVR :
#include<mega8535.h>
#include <delay.h>
#define sensor PINB
//===pwm motor alias
#define motor_ki OCR1A  //sip
#define motor_ka OCR1B
#define m1a PORTD.0
#define m1b PORTD.1
#define m2a PORTD.2
#define m2b PORTD.3
void maju ()
{
m1a=1;m1b=0;
m2a=0;m2b=1;
}
void rem_kanan ()
{
m1a=0;m1b=1;
m2a=0;m2b=1;
}
void rem_kiri ()
{
m1a=1;m1b=0;
m2a=1;m2b=0;
}
//===Tombol Yang Digunakan======
#define sw_ok     PINC.3
#define sw_cancel PINC.2
#define sw_down   PINC.1
#define sw_up     PINC.0
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd.h>
#include <stdio.h>
//====Variabel di eeprom=====
eeprom int Kp = 0;
eeprom int Ki = 0;
eeprom int Kd = 0;
eeprom int Ts= 0;
eeprom int Upper= 0;
eeprom int Lower= 0;
eeprom int Set_point=0;
//====Nilai-nilai eror=======
eeprom int e0=  0;
eeprom int e1 = 0;
eeprom int e2 = 0;
eeprom int e3 = 0;
eeprom int e4 = 0;
eeprom int e5 = 0;
eeprom int e6 = 0;
eeprom int e7 = 0;
int error,error1,nil_pid,pwm,kode;
char lcd_buff[33];
void seting_awal ()
{
set:
Kp=Kp;
if(sw_up==0){Kp++;delay_ms(10);}
if(sw_down==0){Kp=Kp-1;delay_ms(10);}
if(Kp>100){Kp=0;delay_ms(10);}
if(Kp<0){Kp=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“***************”);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”Nilai Kp:%i”,Kp);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0)
{
delay_ms(150);goto set1;
}
else goto set;
//====================================
set1:
Ki=Ki;
if(sw_up==0) {Ki++;delay_ms(10);}
if(sw_down==0) {Ki=Ki-1;delay_ms(10);}
if(Ki>100){Ki=0;delay_ms(10);}
if(Ki<0) {Ki=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“***************”);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”Nilai Ki:%i.%i”,Ki/10,Ki%10);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set2;}
if(sw_cancel==0){delay_ms(150);goto set;}
else
goto set1;
//======================================
set2:
Kd=Kd;
if(sw_up==0) {Kd++;delay_ms(10);}
if(sw_down==0) {Kd=Kd-1;delay_ms(10);}
if(Kd>100){Kd=0;delay_ms(10);}
if(Kd<0) {Kd=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“***************”);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”Nilai Kd:%i”,Kd);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set3;}
if(sw_cancel==0){delay_ms(150);goto set1;}
else
goto set2;
//========================================
set3:
Ts=Ts;
if(sw_up==0) {Ts++;delay_ms(10);}
if(sw_down==0) {Ts=Ts-1;delay_ms(10);}
if(Ts>100){Ts=0;delay_ms(10);}
if(Ts<0) {Ts=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Time Sampling”);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”Delay:%ims”,Ts);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set4;}
if(sw_cancel==0){delay_ms(150);goto set2;}
else
goto set3;
//=============================================
set4:
Ts=Ts;
if(sw_up==0) {Set_point++;delay_ms(10);}
if(sw_down==0) {Set_point=Set_point-1;delay_ms(10);}
if(Set_point>255){Set_point=0;delay_ms(10);}
if(Set_point<0) {Set_point=255;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Set Point”);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”Kec:%i”,Set_point);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set5;}
if(sw_cancel==0){delay_ms(150);goto set3;}
else
goto set4;
//=================================================
set5:
Upper=Upper;
if(sw_up==0) {Upper++;delay_ms(10);}
if(sw_down==0) {Upper=Upper-1;delay_ms(10);}
if(Upper>255){Upper=0;delay_ms(10);}
if(Upper<0) {Upper=255;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Limit Speed”);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”Upper:%i”,Upper);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set6;}
if(sw_cancel==0){delay_ms(150);goto set4;}
else
goto set5;
//====================================================
set6:
Lower=Lower;
if(sw_up==0) {Lower++;delay_ms(10);}
if(sw_down==0) {Lower=Lower-1;delay_ms(10);}
if(Lower>255){Lower=0;delay_ms(10);}
if(Lower<0) {Lower=255;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Limit Speed”);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”Lower:%i”,Lower);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set7;}
if(sw_cancel==0){delay_ms(150);goto set5;}
else
goto set6;
//========Menampilkan Eror-Eror===============
set7:
e0=e0;
if(sw_up==0) {e0++;delay_ms(10);}
if(sw_down==0) {e0=e0-1;delay_ms(10);}
if(e0>100){e0=0;delay_ms(10);}
if(e0<0) {e0=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Error 0″);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”e0:%i”,e0);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set8;}
if(sw_cancel==0){delay_ms(150);goto set6;}
else
goto set7;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set8:
e1=e1;
if(sw_up==0) {e1++;delay_ms(10);}
if(sw_down==0) {e1=e1-1;delay_ms(10);}
if(e1>100){e1=0;delay_ms(10);}
if(e1<0) {e1=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Error 1″);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”e1:%i”,e1);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set9;}
if(sw_cancel==0){delay_ms(150);goto set7;}
else
goto set8;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set9:
e2=e2;
if(sw_up==0) {e2++;delay_ms(10);}
if(sw_down==0) {e2=e2-1;delay_ms(10);}
if(e2>100){e2=0;delay_ms(10);}
if(e2<0) {e2=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Error 2″);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”e2:%i”,e2);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set10;}
if(sw_cancel==0){delay_ms(150);goto set8;}
else
goto set9;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set10:
e3=e3;
if(sw_up==0) {e3++;delay_ms(10);}
if(sw_down==0) {e3=e3-1;delay_ms(10);}
if(e3>100){e3=0;delay_ms(10);}
if(e3<0) {e3=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Error 3″);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”e3:%i”,e3);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set11;}
if(sw_cancel==0){delay_ms(150);goto set9;}
else
goto set10;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set11:
e4=e4;
if(sw_up==0) {e4++;delay_ms(10);}
if(sw_down==0) {e4=e4-1;delay_ms(10);}
if(e4>100){e4=0;delay_ms(10);}
if(e4<0) {e4=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Error 4″);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”e4:%i”,e4);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set12;}
if(sw_cancel==0){delay_ms(150);goto set10;}
else
goto set11;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set12:
e5=e5;
if(sw_up==0) {e5++;delay_ms(10);}
if(sw_down==0) {e5=e5-1;delay_ms(10);}
if(e5>100){e5=0;delay_ms(10);}
if(e5<0) {e5=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Error 5″);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”e5:%i”,e5);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set13;}
if(sw_cancel==0){delay_ms(150);goto set11;}
else
goto set12;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set13:
e6=e6;
if(sw_up==0) {e6++;delay_ms(10);}
if(sw_down==0) {e6=e6-1;delay_ms(10);}
if(e6>100){e6=0;delay_ms(10);}
if(e6<0) {e6=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Error 6″);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”e6:%i”,e6);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto set14;}
if(sw_cancel==0){delay_ms(150);goto set12;}
else
goto set13;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set14:
e7=e7;
if(sw_up==0) {e7++;delay_ms(10);}
if(sw_down==0) {e7=e7-1;delay_ms(10);}
if(e7>100){e7=0;delay_ms(10);}
if(e7<0) {e7=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Error 7″);
lcd_gotoxy(0,1);
sprintf(lcd_buff,”e7:%i”,e7);
lcd_puts(lcd_buff);
delay_ms(100);
if(sw_ok==0) {delay_ms(150);goto Magelang;}
if(sw_cancel==0){delay_ms(150);goto set13;}
else
goto set14;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Magelang:
lcd_clear();
lcd_gotoxy(1,0);
lcd_putsf(” Save To EEPROM”);
delay_ms(200);
Kp=Kp;Ki=Ki;Kd=Kd;Ts=Ts;Set_point=Set_point;Lower=Lower;Upper=Upper;
e0=e0;e1=e1;e2=e2;e3=e3;e4=e4;e5=e5;e6=e6;e7=e7;
}
void tampilan_awal()
{
lcd_gotoxy(0,0);
lcd_putsf(” C_Tools__!     “);
delay_ms(1000);
lcd_gotoxy(6,1);
lcd_putsf(“Present         “);
delay_ms(1000);
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(“Fahmizal_DTE_UGM”);
delay_ms(500);
lcd_gotoxy(0,1);
lcd_putsf(” Line Follower  “);
delay_ms(1000);
lcd_clear();
}
//=====Perlihatkan Sensor=========
//#define sensor    PINA
#define s0   PINB.0
#define s1   PINB.1
#define s2   PINB.2
#define s3   PINB.3
#define s4   PINB.4
#define s5   PINB.5
#define s6   PINB.6
#define s7   PINB.7
void show_sensor()
{
lcd_gotoxy(2,1);
if (s7) lcd_putchar(’1′);
else    lcd_putchar(’0′);
if (s6) lcd_putchar(’1′);
else    lcd_putchar(’0′);
if (s5) lcd_putchar(’1′);
else    lcd_putchar(’0′);
if (s4) lcd_putchar(’1′);
else    lcd_putchar(’0′);
if (s3) lcd_putchar(’1′);
else    lcd_putchar(’0′);
if (s2) lcd_putchar(’1′);
else    lcd_putchar(’0′);
if (s1) lcd_putchar(’1′);
else    lcd_putchar(’0′);
if (s0) lcd_putchar(’1′);
else    lcd_putchar(’0′);
}
//=====Tutup Perlihatkan Sensor====
void PID ()
{
//***hitam=mati/0 &  putih=nyala/1
//=====sensor mengarah ke Kiri
if (sensor==0b11101110) {error=e0;}
else if (sensor==0b11001110) {error=-e1;}
else if (sensor==0b11011110) {error=-e2;}
else if (sensor==0b10011110) {error=-e3;}
else if (sensor==0b10111110) {error=-e4;}
else if (sensor==0b00111110) {error=-e5;}
else if (sensor==0b01111110) {error=-e6;kode=12;}
//=====sensor mengarah ke Kanan
else if (sensor==0b11101110) {error=e0;}
else if (sensor==0b11100110) {error=e1;}
else if (sensor==0b11110110) {error=e2;}
else if (sensor==0b11110010) {error=e3;}
else if (sensor==0b11111010) {error=e4;}
else if (sensor==0b11111000) {error=e5;}
else if (sensor==0b11111100) {error=e6;kode=24;}
else if (sensor==0b11111110)//di putih semua
{
if (kode==12)
{
error=-e7;
rem_kiri();
delay_ms(20);
}
else if (kode==24)
{
error=e7;
rem_kanan();
delay_ms(20);
}
}
maju();
nil_pid=((Kp*error)+((Ki/10)*(error+error1)*Ts)+((Kd/Ts)*(error-error1)));
error1=error;
//===== Hitung Kondisi Pertama=============
pwm=Set_point-(nil_pid);
if(pwm>Upper){pwm=Upper;}
if(pwm<Lower){pwm=Lower;}
motor_ka=pwm;
//=====Hitung Kondisi Kedua===============
pwm=Set_point+(nil_pid);
if(pwm>Upper){pwm=Upper;}
if(pwm<Lower){pwm=Lower;}
motor_ki=pwm;
//kode=0;
delay_ms(Ts);
}
void show_detail()
{
lcd_gotoxy(0,0);
sprintf(lcd_buff,”e:%i”,error);
lcd_puts(lcd_buff);
lcd_gotoxy(5,0);
sprintf(lcd_buff,”Ki%i”,motor_ki);
lcd_puts(lcd_buff);
lcd_gotoxy(11,0);
sprintf(lcd_buff,”Ka%i”,motor_ka);
lcd_puts(lcd_buff);
}
void inisialisasi_port()
{
//===Seting untuk sensor============
DDRB=0b00000000;
PORTB=0b11111111;
//===Seting untuk fungsi Tombol======
DDRC=0×00;
PORTC=0xff;
//===Seting motor====================
DDRD=0xff;
PORTD=0×00;
//——-inisialisasi PWM—–//
TCCR1A=0xA3;
TCCR1B=0x0B;
TCNT1=0×0000;//PWM 16 bit//
OCR1A=0x3FF;
OCR1B=0x3FF;
TIFR=0;
}
void main(void)
{
inisialisasi_port();
lcd_init(16);
lcd_clear();
tampilan_awal();
seting_awal();
while(1)
{
lcd_clear();
PID();
show_sensor();
kode=0;
show_detail();
delay_ms(Ts);
}
}
sumber /http://hariniseptyaningasri.blogspot.co.id/2013/05/tuning-kontroler-pid-line-follower.html

Panduan Pembuatan SMS Gateway di Linux Ubuntu

Hardware Requirement

Spesifikasi Minimum : Processor : Intel P4 1.8GHZ
RAM : 256MB
Hardisk : 80GB
Modem atau handphone kompabilitynya bisa di cek di sini

Software Requirement

Kebutuhan Paket Software :
  1. Linux Ubuntu
  2. Apache 2.x.x
  3. PHP 5.x.x (with mysql, session, hash, json extension)
  4. PHP-CLI
  5. MySQL 5.x.x
  6. Gammu
  7. Kalkun

Instalasi

Install LAMP

  1. Install package ;
    $ sudo tasksel install lamp-server
  2. Dalam proses instalasi akan di tanyakan untuk membuat passsword user dan password mysql
    user : root
    passwd : root
  3. Install PHP-CLI [penting]
    $ sudo apt-get install php5-cli
  4. Install PHPMYADMIN [optional]
    $ sudo apt-get install phpmyadmin
  5. Dalam proses instalasi akan di tanyakan passsword user dan password mysql
    user : root
    pass : root

Install GAMMU

  1. Update dan install aplikasi gammu dan gammu-smsd dengan perintah berikut ;
    $ sudo apt-get update
    $ sudo apt-get install gammu gammu-smsd
  2. Untuk melihat konfigurasi port device, gunakan perintah berikut :
    $ dmesg | grep tty
    [12321.308078] usb 5-3: GSM modem (1-port) converter now attached to ttyUSB0
    [12321.308275] usb 5-3: GSM modem (1-port) converter now attached to ttyUSB1
  3. Konfigurasi Gammu terlebih dahulu ;
    $ sudo gammu-config
  4. Maka akan keluar form berikut ;
  5. Isi dengan variabel seperti dibawah dan pilih Save ;
    port = /dev/ttyUSB0 # disesuaikan
    connection = at115200 # disesuaikan
    synchronizetime = yes
    logfile = /var/log/gammulog
    logformat = textall
    use_locking = # isi yes jika ingin resource modem di kunci
  6. Perintah diatas akan menyimpan file config dengan nama .gammurc di home user : ~/.gammurc
  7. Konfigurasi berkas /etc/gammu-smsdrc
    [gammu]
    port = /dev/ttyUSB0 # change this
    connection = at115200 # change this
    
    [smsd]
    PIN = ''
    service = sql
    driver = native_mysql
    DeliveryReport = sms
    logfile = /var/log/smsdlog
    debuglevel = 1 # change to 255 if you want to debug
    
    User = root # change this
    password = root # change this
    pc = localhost
    database = kalkun
    runonreceive = /var/www/kalkun/scripts/daemon.sh
  8. WARNING!! untuk menggunakan perintah gammu, matikan dulu service gammu-smsd. Pastikan dengan cara ;
    $ sudo /etc/init.d/gammu-smsd stop
  9. Kemudian baru bisa cek identify modem dengan perintah ;
    $ sudo gammu --identify
    Device               : /dev/ttyUSB0
    Manufacturer         : huawei
    Model                : E220 (E220)
    Firmware             : 11.117.10.02.00
    IMEI                 : 351827014879XXX
    SIM IMSI             : 510012541759XXX
  10. Untuk testing pengiriman SMS menggunakan perintah berikut ;
    $ sudo gammu --sendsms text 0857257XXXXX
    Enter the message text and press Ctrl+D:
    test server
    If you want break, press Ctrl+C...
    Sending SMS 1/1....waiting for network answer..OK, message reference=3
  11. Untuk cek pulsa (ex.simpati) ;
    $ sudo gammu --getussd *888#
    Press Ctrl+C to break...
    USSD received
    Status : No action needed
    Service reply : “Sisa Pulsa Anda Rp.4950. Penggunaan pulsa di periode ini Rp.11150. Aktif s.d. 14/05/2011. Cari t4 menarik dsekitarmu dgn TelkomselLacak. Hub *123*55#”
  12. Setelah itu, jalankan service gammu-smsd untuk aplikasi kalkun ;
    $ sudo /etc/init.d/gammu-smsd start

Install Kalkun

Kalkun merupakan open source berbasis web SMS (Short Message Service) manajemen, itu menggunakan gammu-smsd (bagian dari keluarga gammu) sebagai mesin SMS gateway untuk menyampaikan dan mengambil pesan dari telepon / modem.

Fitur-fitur

  • Memiliki lebih dari satu pengguna (Multi User);
  • Threated SMS.
  • Memiliki lebih dari satu telepon / modem? Beberapa modem yang tepat bagi Anda.
  • Kirim SMS berulang kali (SMS Bomber);
  • Ingin membuat SMS berbasis masyarakat? Anggota SMS akan membantu Anda.
  • Forward SMS ke Email;
  • SMS Iklan untuk pesan Anda.
  • Lelah mengetik SMS yang sama lagi dan lagi? Template SMS adalah yang Anda butuhkan.
  • Ingin membuat program Anda sendiri tetapi tidak ingin menyentuh kode Kalkun? Script eksternal adalah solusinya.
  • Mari kita menendang spammer dengan Spam Filter.
  • Jawaban SMS secara otomatis dengan Autoreply Sederhana.
  • Kirim SMS dari aplikasi lain menggunakan API.

Tahapan Installasi

  1. Download aplikasi Kalkun di sini http://sourceforge.net/projects/kalkun/files
    $ wget -c http://nchc.dl.sourceforge.net/project/kalkun/kalkun/X.X/kalkun_X.X.zip
  2. Buat folder web Kalkun dan ekstrak file ;
    $ sudo mkdir /var/www/kalkun
    $ sudo mv kalkun_X.X.zip /var/www/kalkun
    $ cd /var/www/kalkun/
    $ sudo unzip kalkun_X.X.zip
  3. Buat database kalkun
    $ mysql -u root -p
    mysql> CREATE DATABASE kalkun;
    mysql> quit
  4. Edit config Kalkun database di /var/www/kalkun/application/config/database.php
    $db['default']['hostname'] = "localhost";
    $db['default']['username'] = "root"; // change this
    $db['default']['password'] = "root"; // change this
    $db['default']['database'] = "kalkun"; // change this
    $db['default']['dbdriver'] = "mysql";
  5. Ekstrak example database struktur Gammu agar bisa di import, caranya ;
    $ sudo gunzip /usr/share/doc/gammu/examples/sql/mysql.sql.gz
  6. Import konfig database struktur Gammu;
    $ mysql kalkun -u root -p < /usr/share/doc/gammu/examples/sql/mysql.sql
  7. Konfigurasi path daemon di /var/www/kalkun/scripts/daemon.sh, menjadi dibawah ini ;
    #!/bin/sh
    
    # Configure this (use absolute path)
    PHP=/usr/bin/php # php cli path
    DAEMON=/var/www/kalkun/scripts/daemon.php # daemon.php path
    
    # Execute
    $PHP $DAEMON
    ~            
  8. Jangan lupa juga cek path konfigurasi /var/www/kalkun/scripts/daemon.php dibagian;
    $url = "http://localhost/kalkun";
  9. Buka web browser mengarah ke http://localhost/kalkun/ dan selanjutnya akan terjadi proses instalasi.
  10. Pada akhir instalasi ada pesan gagal untuk menghapus folder install, hapus secara manual ;
    $ sudo rm -rf /var/www/kalkun/install
  11. Akses http://localhost/kalkun/ kembali dengan user dan pass default user=kalkun pass=kalkun.

Troubleshooting

Startup Daemon

Untuk menjalankan daemon setiap kali komputer restart, ketik perintah berikut ;
$ sudo update-rc.d gammu-smsd defaults 

Log Membengkak

Agar log tidak membengkak, berikut tahapan untuk mengatasi hal tersebut, sebaiknya anda menggunakan hak akses superuser atau root :
  1. Sesuaikan tempat penyimpanan berkas log, misal di /etc/smsdlog
  2. Membuat berkas smsdlog di /etc/logrotate.d/
    $ sudo vim /etc/logrotate.d/smsdlog 
  3. Membuat berkas smsdlog di /etc/logrotate.d/ :
    /var/log/smsdlog {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    create 640 root root
    endscript
    } 
  4. Selanjutnya membuat penjadwalan menggunakan perintah crontab :
    $ sudo su 
    # crontab -e 
  5. Isi dengan baris dibawah ini, agar daemon gammu-smsd di-restart setiap jam 06.50
    50 6 * * * /etc/init.d/gammu-smsd restart 

Error database struktur

Jika dilihat kembali pesan error-nya : Database structures version: 11, SMSD current version: 12, maka sebaiknya lakukan perintah dibawah ini pada database server yang digunakan dalam hal ini adalah MySQL.
$ mysql -u root -p
mysql> UPDATE `kalkun`.`gammu` SET `Version` = '12' WHERE `gammu`.`Version` =11;
mysql> quit

Connect/Disconnect di Kalkun

Connect/Disconnect di Kalkun hanya perkiraan dari waktu terakhir gammu-smsd mengupdate aktifitas dengan waktu sekarang. Defaultnya adalah 10 menit, bisa diganti di file /var/www/kalkun/application/config/kalkun_settings.php,
$config['modem_tolerant'] = ’10′;
Beberapa mungkin yang bisa di konfigurasi;
$config['sms_bomber'] = FALSE;
$config['enable_emoticons'] = FALSE;
$config['sms_advertise'] = FALSE;
$config['sms_advertise_message'] = "This is ads message";

Modem Tidak terdeteksi

Ketika melakukan perintah dmesg dan tidak menemukan modem terknoneksi, berikut langkah solusinya (ex. Modem Huawei e1550) ;
  1. Install package usb-modeswitch
    $ sudo apt-get install usb-modeswitch
  2. Buat rule baru untuk udev:
    $ sudo vim /etc/udev/rules.d/15-huawei-155x.rules
  3. Ketik dengan isian berikut :
    SUBSYSTEM=="usb",
    ATTRS{idProduct}=="1446",
    ATTRS{idVendor}=="12d1",
    RUN+="/lib/udev/modem-modeswitch --vendor 0x$attr{idVendor} --product 0x$attr{idProduct} --type option-zerocd"
  4. Simpan dan cabut modem dan colokkan kembali. Untuk keterangan idProduct dan idVendor dapat di temukan dari perintah berikut ;
    $ sudo lsusb -v | less
    Bus 005 Device 004: ID 12d1:1446 Huawei Technologies Co., Ltd. E220 HSDPA Modem / E270 HSDPA/HSUPA Modem
    Device Descriptor:
      bLength                18
      bDescriptorType         1
      bcdUSB               2.00
      bDeviceClass            0 (Defined at Interface level)
      bDeviceSubClass         0 
      bDeviceProtocol         0 
      bMaxPacketSize0        64
      idVendor               0x12d1 Huawei Technologies Co., Ltd.
      idProduct              0x1446 E220 HSDPA Modem / E270 HSDPA/HSUPA Modem
      bcdDevice            0.00
      iManufacturer           2 HUAWEI Technology
      iProduct                1 HUAWEI Mobile
      iSerial                 0 
      bNumConfigurations      1

Memindahkan Port USB Modem, Service menjadi tidak berjalan

Kasus ini terjadi jika Anda memindah modem ke port USB yang lain. Maka service tidak akan berjalan, karena config masih mendeteksi lokasi port USB sebelumnya.
  1. Cek perubahan port menggunakan perintah wvdial :
    $ sudo wvdialconf
    $ cat /etc/wvdial.conf 
    [Dialer Defaults]
    Init1 = ATZ
    Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
    Modem Type = Analog Modem
    ; Phone = <Target Phone Number>
    ISDN = 0
    ; Password = <Your Password>
    New PPPD = yes
    ; Username = <Your Login Name>
    Modem = /dev/ttyUSB1
    Baud = 9600 
  2. Tampak pada konfigurasi wvdial posisi modem pada ttyUSB1, kemudian ubah konfigurasi dan sesuaikan port USBnya pada file /root/.gammurc dan /etc/gammu-smsdlog.

Debugging Web Kalkun

Untuk mengidentifikasi error pada web Kalkun, aktifkan log debugging pada config Kalkun seperti cara berikut ;
$sudo vim kalkun/application/config/config.php
Ubah baris log_treshold menjadi seprti berikut
$config['log_threshold'] = 4;
Akses menggunakan browser dengan alamat berikut ;
http://localhost/index.php/daemon/message_routine

Startup Daemon Bermasalah Ketika Restart Server

Kendala ini ketika server sms restart secara tidak sengaja karena masalah kelistrikan service gammu-smsd tidak bisa melakukan auto startup daemon padahal sudah kita set secara automatis. Hal ini bisa diakali dengan menambahkan script start service gammu pada file rc.local. Langkah-langkahnya sebagai berikut :
Hapus Auto Daemon gammu dengan perintah dibawah ini
$ sudo update-rc.d -f gammu-smsd remove
Kemudian edit file /etc/rc.local, kemudian tambahkan baris menjadi seperti dibawah ini
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
sleep 10
/etc/init.d/gammu-smsd start
exit 0

Sumber Referensi