Televizyonu Kumanda Edelim
IoT çalışmaları yapan geliştiriciler için faydalı olacak bu yazıda, CEYD-A ile televizyonu sesli olarak kumanda edeceğiz. Çalışmada gereksinimler şunlar:
Arduino Uno | |
HC 05 Bluetooth Modülü | |
1K Ohm ve 2.2K Ohm Dirençler | |
Breadboard | |
Jumper Kablolar (Erkek-erkek ve dişi-erkek) | |
IR Alıcı Verici Kumanda Seti | |
CEYD-A uygulaması |
Alıcı Devre Şeması (Opsiyonel)
Eğer kumandanıza ait tuş kombinasyon kodlarını öğrenmek istiyorsanız aşağıdaki gibi bir devre kurup kumanda sinyal kodlarını öğrenebilirsiniz.
KY-022 IR alıcı sensörü ile mevcut televizyon kumandanızın tuşlarını belirlememiz gerekiyor. Bunun için aşağıdaki Arduino kodunu IDE üzerinde çalıştıralım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
#include <IRremote.h> // Sktech from: //https://gist.github.com/probonopd/5793692#file-sendandreceive-ino // http://www.pjrc.com/teensy/td_libs_IRremote.html // If one keypress results in multiple codes being output, then // change in IRremoteInt.h: // #define _GAP 50000 // Provided by Robojax.com on August 04, 2018 // Watch Video instruction for this code:https://youtu.be/xA66hXYRx9I int RECV_PIN = 12; IRrecv irrecv(RECV_PIN); decode_results results; // Compare two tick values, returning 0 if newval is shorter, // 1 if newval is equal, and 2 if newval is longer // Use a tolerance of 20% int compare(unsigned int oldval, unsigned int newval) { if (newval < oldval * .8) { return 0; } else if (oldval < newval * .8) { return 2; } else { return 1; } } // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param #define FNV_PRIME_32 16777619 #define FNV_BASIS_32 2166136261 /* Converts the raw code values into a 32-bit hash code. * Hopefully this code is unique for each button. */ unsigned long decodeHash(decode_results *results) { unsigned long hash = FNV_BASIS_32; for (int i = 1; i+2 < results->rawlen; i++) { int value = compare(results->rawbuf[i], results->rawbuf[i+2]); // Add value into the hash hash = (hash * FNV_PRIME_32) ^ value; } return hash; } void setup() { Serial.begin(9600); Serial.println("Robojax IR Capture"); irrecv.enableIRIn(); // Start the receiver } int c = 1; void dump(decode_results *results) { int count = results->rawlen; Serial.println(c); c++; Serial.println("Hash: "); unsigned long hash = decodeHash(results); Serial.println(hash, HEX); Serial.println("For IR Scope/IrScrutinizer: "); for (int i = 1; i < count; i++) { if ((i % 2) == 1) { Serial.print("+"); Serial.print(results->rawbuf[i]*USECPERTICK, DEC); } else { Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); } Serial.print(" "); } Serial.println("-127976"); Serial.println("For Arduino sketch: "); Serial.print("unsigned int raw["); Serial.print(count, DEC); Serial.print("] = {"); for (int i = 1; i < count; i++) { if ((i % 2) == 1) { Serial.print(results->rawbuf[i]*USECPERTICK, DEC); } else { Serial.print((int)results->rawbuf[i]*USECPERTICK, DEC); } Serial.print(","); } Serial.print("};"); Serial.println(""); Serial.print("irsend.sendRaw(raw,"); Serial.print(count, DEC); Serial.print(",38);"); Serial.println(""); Serial.println(""); } #include <avr/interrupt.h> #include <stdio.h> #include <avr/pgmspace.h> #include <stdint.h> #include <avr/io.h> #define IR_PORT PORTB // #define IR_PIN PINB // #define IR_DDR DDRB // #define IR_BV _BV(1) #define IR_OCR OCR1A #define IR_TCCRnA TCCR1A #define IR_TCCRnB TCCR1B #define IR_TCNTn TCNT1 #define IR_TIFRn TIFR1 #define IR_TIMSKn TIMSK1 #define IR_TOIEn TOIE1 #define IR_ICRn ICR1 #define IR_OCRn OCR1A #define IR_COMn0 COM1A0 #define IR_COMn1 COM1A1 #define PRONTO_IR_SOURCE 0 // Pronto code byte 0 #define PRONTO_FREQ_CODE 1 // Pronto code byte 1 #define PRONTO_SEQUENCE1_LENGTH 2 // Pronto code byte 2 #define PRONTO_SEQUENCE2_LENGTH 3 // Pronto code byte 3 #define PRONTO_CODE_START 4 // Pronto code byte 4 static const uint16_t *ir_code = NULL; static uint16_t ir_cycle_count = 0; static uint32_t ir_total_cycle_count = 0; static uint8_t ir_seq_index = 0; static uint8_t ir_led_state = 0; void ir_on() { IR_TCCRnA |= (1<<IR_COMn1) + (1<<IR_COMn0); ir_led_state = 1; } void ir_off() { IR_TCCRnA &= ((~(1<<IR_COMn1)) & (~(1<<IR_COMn0)) ); ir_led_state = 0; } void ir_toggle() { if (ir_led_state) ir_off(); else ir_on(); } void ir_start(uint16_t *code) { ir_code = code; // IR_PORT &= ~IR_BV; // Turn output off (atmega328 only) digitalWrite(9,LOW); // Turn output off // IR_DDR |= IR_BV; // Set it as output (atmega328 only) pinMode(9,OUTPUT); // Set it as output IR_TCCRnA = 0x00; // Reset the pwm IR_TCCRnB = 0x00; //printf_P(PSTR("FREQ CODE: %hd"), code[PRONTO_FREQ_CODE]); uint16_t top = ( (F_CPU/1000000.0) * code[PRONTO_FREQ_CODE] * 0.241246 ) - 1; //printf_P(PSTR("top: %hu"), top); IR_ICRn = top; IR_OCRn = top >> 1; IR_TCCRnA = (1<<WGM11); IR_TCCRnB = (1<<WGM13) | (1<<WGM12); IR_TCNTn = 0x0000; IR_TIFRn = 0x00; IR_TIMSKn = 1 << IR_TOIEn; ir_seq_index = PRONTO_CODE_START; ir_cycle_count = 0; ir_on(); IR_TCCRnB |= (1<<CS10); } #define TOTAL_CYCLES 80000 // Turns off after this number of // cycles. About 2 seconds // FIXME: Turn off after having sent ISR(TIMER1_OVF_vect) { uint16_t sequenceIndexEnd; uint16_t repeatSequenceIndexStart; ir_total_cycle_count++; ir_cycle_count++; if (ir_cycle_count== ir_code[ir_seq_index]) { ir_toggle(); ir_cycle_count = 0; ir_seq_index++; sequenceIndexEnd = PRONTO_CODE_START + (ir_code[PRONTO_SEQUENCE1_LENGTH]<<1) + (ir_code[PRONTO_SEQUENCE2_LENGTH]<<1); repeatSequenceIndexStart = PRONTO_CODE_START + (ir_code[PRONTO_SEQUENCE1_LENGTH]<<1); if (ir_seq_index >= sequenceIndexEnd ) { ir_seq_index = repeatSequenceIndexStart; if(ir_total_cycle_count>TOTAL_CYCLES) { ir_off(); TCCR1B &= ~(1<<CS10); } } } } void ir_stop() { IR_TCCRnA = 0x00; // Reset the pwm IR_TCCRnB = 0x00; } const uint16_t inputLength = 512; void loop() { if (irrecv.decode(&results)) { dump(&results); irrecv.resume(); // Receive the next value } if ( Serial.available() > 0 ) { static char input[inputLength]; static uint16_t i; char c = Serial.read(); if ( c != '\n' && c != '\r' && i < inputLength-1) input[i++] = c; else { input[i] = ' '; i = 0; uint16_t array[80]; uint16_t j = 0; if ( !strncmp(input, "SEND", 4) ) { char* p = input+4; while ( (p = strchr(p, ' ')) != NULL ) array[j++] = strtol(p, &p, 16); ir_start(array); Serial.print("SENT "); for ( uint8_t i = 0; i < j; i++ ) { Serial.print ("0x"); Serial.print (array[i], HEX); Serial.print(" "); } Serial.println(); } } } } |
Kodu çalıştırdıktan sonra, kumandamızda tuşları denediğimizde Serial console üzerinde 2 satırlık kodlar oluşacaktır. O kodları kopyalayıp verici devremizde kullanacağız.
Verici Devre Şeması
Verici Arduino IDE Kodu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
#include <SoftwareSerial.h> #include <dht.h> #include <IRremote.h> IRsend irsend; SoftwareSerial BTSerial(10, 11); // RX, TX char data; void setup() { analogReference(INTERNAL); Serial.begin(9600); BTSerial.begin(9600);//38400 } void loop() { if (BTSerial.available()) { data = BTSerial.read(); Serial.write(data); if(data=='a')//PHILIPS KUMANDA SES KIS { unsigned int raw[38] = {2600,900,400,850,450,450,450,400,1300,1300,450,450,450,400,450,400,450,450,400,450,450,400,450,450,450,400,450,400,450,450,900,850,400,450,450,400,900,}; irsend.sendRaw(raw,38,38); delay(500); } if(data=='b')//PHILIPS KUMANDA SES AÇ { unsigned int raw[40] = {2650,850,450,850,450,400,450,400,1350,1250,500,400,450,400,500,400,400,450,450,400,500,400,450,400,450,400,450,450,450,400,900,850,450,400,500,400,450,400,450,}; irsend.sendRaw(raw,40,38); delay(500); } if(data=='c')//PHILIPS KUMANDA AÇ KAPA { unsigned int raw[40] = {2600,900,450,850,450,400,450,400,1350,1300,400,450,450,400,450,450,450,400,450,400,500,400,450,400,450,400,500,400,450,400,500,400,900,400,450,850,450,400,450,}; irsend.sendRaw(raw,40,38); delay(500); Serial.println("Güç tuşu"); } if(data=='d')//PHILIPS KUMANDA NETFLIX { unsigned int raw[38] = {2600,850,500,850,450,400,450,400,1300,1300,450,450,450,400,450,450,450,400,450,400,500,400,450,400,450,400,900,400,500,400,450,850,850,450,450,850,450,}; irsend.sendRaw(raw,38,38); delay(500); } if(data=='e')//PHILIPS KUMANDA AŞAĞI { unsigned int raw1[38] = {2650,850,450,850,400,450,450,400,500,800,900,400,500,400,450,400,450,400,500,400,450,400,500,400,450,400,450,400,900,850,900,400,500,800,450,450,850,}; irsend.sendRaw(raw1,38,38); } if(data=='f')//PHILIPS KUMANDA OK { unsigned int raw[40] = {2650,850,450,850,450,400,500,400,450,850,850,450,450,400,500,400,450,400,450,400,450,450,400,450,450,400,500,400,900,850,900,400,450,400,450,850,450,450,400,}; irsend.sendRaw(raw,40,38); delay(500); unsigned int raw1[38] = {2650,800,500,850,400,450,450,400,1300,1300,450,450,450,400,450,450,450,400,450,400,450,450,450,400,450,400,900,850,900,400,500,400,450,850,450,400,450,}; irsend.sendRaw(raw1,38,38); } if(data=='g')//PHILIPS KUMANDA SAĞ { unsigned int raw[38] = {2600,900,400,900,400,450,400,450,400,950,800,500,350,500,400,450,400,500,400,450,400,500,350,500,400,500,400,400,850,900,850,500,350,900,850,450,450,}; irsend.sendRaw(raw,38,38); delay(500); } if(data=='h')//PHILIPS KUMANDA ALTYAZI { unsigned int raw[38] = {2600,850,450,850,450,450,450,400,450,850,900,400,450,400,450,450,450,450,400,450,400,450,450,400,500,400,400,450,850,900,450,400,900,850,850,450,450,}; irsend.sendRaw(raw,38,38); delay(500); } if(data=='i')//PHILIPS KUMANDA İPTAL { unsigned int raw1[38] = {2650,850,450,850,400,450,450,400,1350,1250,450,450,450,400,500,400,400,450,450,400,500,400,450,400,450,400,500,400,450,400,500,400,850,850,900,850,450,}; irsend.sendRaw(raw1,38,38); } } if (Serial.available()) { BTSerial.write(Serial.read()); } } |
Örnek kod üzerinde Philips Android TV kumandasının kodları kullanılmıştır. Alıcı devresinden alacağınız kodlar ile kendi kumanda kodlarınızı deneyebilirsiniz.
CEYD-A Kullanımı
Bağlantı kurabilmek için önce sesli olarak Bluetooth ile Bağlan demeyi unutmayınız.
İSTEĞE BAĞLI: Eğer doğal dil cümleleri kullanmak istiyorsanız size özel kurgular oluşturabilirsiniz.
Kurguları kodla.ceyd-a.com adresinden girebilirsiniz. Giriş yaparken CEYD-A uygulamasındaki geliştirici kullanıcı bilgileriniz ile site üzerindeki giriş bilgileri aynı olmalıdır.
Tek bir kurgu, SORU, ŞABLON ve CEVAP üçlüsünden oluşmaktadır. Dilediğiniz kadar kurgu ekleyebilirsiniz. Kurguları site üzerinde güncelledikten sonra, CEYD-A uygulamasını açıp güncelle deyiniz. Kurgular cihazına yansıyacaktır.
Kurgularınızı https://kodla.ceyd-a.com sitesinden girebilir, deneyebilir ve yayınlayabilirsiniz.
Yukarıdaki örnek kodda ‘b’ verisi Philips Kumanda Ses aç olarak düzenlenmiştir. Bluetooth b gönder dediğinizde televizyonun sesi açılacaktır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
KURGU KOMUT KODU SORU: ok,5|okey,5| SABLON: {HER}televizyon|kumanda{HER}$ CEVAP: {!RET cmdsendbluetooth f!}ok KURGU KOMUT KODU SORU: geri,2| SABLON: {HER}televizyon|kumanda{HER}$ CEVAP: {!RET cmdsendbluetooth i!}ok KURGU KOMUT KODU SORU: ileri,5|sonraki,10.2| SABLON: {HER}televizyon|kumanda{HER}$ CEVAP: {!RET cmdsendbluetooth g!}ok KURGU KOMUT KODU SORU: netflix aç%,6| SABLON: {HER}televizyon{HER}$ CEVAP: {!RET cmdsendbluetooth d!}Açtım KURGU KOMUT KODU SORU: sesi kıs%,21|sesini kıs%,21| SABLON: {HER}televizyon{HER}$ CEVAP: {!RET cmdsendbluetooth a!}Kıstım KURGU KOMUT KODU SORU: altyazı%,6| SABLON: {HER}değiştir{HER}$ CEVAP: {!RET cmdsendbluetooth h!} {!RET cmdmessagebox Altyazı tuşuna bastım!} {!RET cmdsendbluetooth e!} {!RET cmdmessagebox Bir aşağı indim!} {!RET cmdsendbluetooth f!} {!RET cmdmessagebox Bunu seçtim!} {!RET cmdsendbluetooth i!} |