Jak sobie poradzić z tematem odbiornik / sensor IR w standardzie NEC VS1838B?
Powszechnie wiadomo, że Bascom AVR ma wsparcie dla odbioru i nadawania IR w standardzie RC5, oraz nadawania w standardzie RC6 i Sony, dzięki wbudowanym poleceniom. Do dyspozycji mamy: RC5SEND, RC6SEND, RC5SENDEXT, SONYSEND, GETRC5. Polecenia do wysyłania danych korzystają z Timera1, a odbierające/dekodujące dane z Timera0 (istnieje możliwość zmiany), i o tym trzeba zawsze pamiętać.
Czujnik 1838T pracuje na częstotliwości nośnej 37,9kHz zasilany w przedziale 2,4 do 5,5V (graniczne 7,5V). Cechuje go niskie zużycie energii 0,85mA, szeroki kąt 35° i odbiór z dalekiej odległości do 11m. Wyjście jest zgodne ze standardem TTL, i poziomami CMOS, – aktywny stan niski. Temperatura pracy -30 – +80℃
VS1838T zawiera szybką fotodiodę PIN, o wysokiej czułości i niskim zużyciu energii, wysoki zysk przedwzmacniacza IC, a także obudowę z suchej żywicy epoksydowej, odporną na zarysowania, oraz zewnętrzną osłonę anty-scratch, produkt ma certyfikat SGS.
Cechy, które odróżniają pozostałe typy:
VS1838 pracuje na częstotliwości nośnej 38,0kHz, i może być zasilany w przedziale 2,2 do 6,0V. Pobór prądu 0,4mA. Kąt pracy 45° i odbiór z odległości typowo 20m. Temperatura pracy -20 – +85℃.
VS1938B pracuje na częstotliwości nośnej 38,0kHz, i może być zasilany w przedziale 2,7 do 5,5V. Pobór prądu 0,4mA. Kąt pracy 45° i odbiór z odległości typowo 20m. Temperatura pracy -20 – +85℃. To ten zakuty w blachę 😉
Specyfikacja standardu:
- 8 bitów adresu i 8 bitów polecenia
- Adres i polecenia przekazywane są dwa razy dla niezawodności
- Modulacja długości impulsów
- Częstotliwość nośnej 38kHz
- Czas trwania bitu 1.125ms lub 2.25ms
Protokół NEC umożliwia kontrolę ponad 256 różnych urządzeń z 256 różnymi poleceniami dla każdego z nich.
Wracając do powyższego rysunku, nadawanie jest rozpoczynane przez impuls AGC trwający 9ms, który był używany do ustawienia wzmocnienia we wcześniejszych odbiornikach podczerwieni. Przez kolejne 4,5ms trwa przerwa, a później zaczyna być odbierany adres i numer rozkazu.
Nadawane słowa mogą mieć różną zawartość w zależności od tego czy przycisk jest przytrzymywany czy krótko naciśnięty. Każda pierwsza wiadomość zawiera 32 bity z czego (w kolejności odbierania) pierwszy bajt zawiera adres, drugi identyczny adres w postaci zanegowanej, trzeci bajt zawiera numer kodu/rozkazu, a czwarty ten sam kod w postaci zanegowanej. Przy trzymanym przycisku, każda kolejna wiadomość zawiera tylko impuls wstępny i jeden pojedynczy impulsu stopu, wskazujący klucz powtórzeń. Jest to kontynuowane tak długo, jak długo klawisz jest przytrzymywany.
Powtórzone dane w formie zanegowanej, można użyć do weryfikacji poprawności odebranych bitów.Całkowity czas transmisji jest stały! Przy budowie swojego nadajnika w razie potrzeby powtórzone zanegowane dane można ignorować, lub wykorzystać do rozszerzenia długości adresu i rozkazu do 16 bitów …
Jak widać na obrazku, protokół NEC wykorzystuje kodowanie długości impulsów bitów. Każdy impuls o czasie trwania 560μs jest serią nośnej 38kHz (ok. 21 cykli). Logiczna „1” trwa 2.25ms transmisji, gdy logiczne „0” jest tylko połową tego czasu, jako 1.125ms.
Jak już wiemy, gdy określony przycisk nie jest krótko naciśnięty, tylko przytrzymany, adres i rozkaz nie są już nadawane. W takim przypadku nadawany jest rozkaz powtórzenia. Trwa to dopóki dopóty klawisz jest wciśnięty. Ten rozkaz to po prostu 9ms impuls AGC a następnie przerwa 2.25ms i seria nośnej trwająca 560μs powtarzane co 110ms, do czasu puszczenia przycisku w nadajniku. Zobrazowano to na rysunkach poniżej.
Protokół NEC stał się tak popularny, że szybko wszystkie możliwe adresy zostały wykorzystane i zarezerwowane dla poszczególnych urządzeń. Poświęcając redundancję adresu, rozszerzono zakres z 256 możliwych do około 65000 różnych adresów. Zrezygnowano z zanegowanego powtórzenia adresu. W ten sposób zakres został wydłużony z 8 bitów do 16 bitów bez zmiany innych właściwości protokołu.
Rozszerzając zakres adresu w ten sposób całkowity czas komunikatu nie jest już stały. Jest teraz zależny od ogólnej liczby 1 i 0 w komunikacie.
Jeżeli chcemy zachować stały całkowity czas wiadomości, ważne aby upewnić się czy liczba jedynek w polu adresu wynosi 8 (to automatycznie oznacza, że liczba 0 również wynosi 8). Zabieg ten spowoduje zmniejszenie maksymalnej liczby różnych adresów do około 13000.
Przy dekodowaniu nieznanego adresu należy dokładnie zbadać, czy nie zastosowano protokołu rozszerzonego przez porównanie odebranego adresu z adresem zanegowanym. Sprawdzenie chyba najprościej wykonać przez dodanie tych wartości, w przypadku zgodności wynik powinien wynieść 255.
Dla zestawienia podstawowej różnicy między nadajnikiem a odbiornikiem zamieszczę dodatkowy rysunek.
Mamy już podstawowe informacje o standardzie NEC więc możemy zabrać się za odbieranie i dekodowanie danych „złapanych” przez sensor VS1838 😉
A więc do dzieła.
Postępując według starej prawdy: chcesz coś zrobić to sprawdź czy już ktoś tego nie zrobił, umiesz to zrobić lepiej więc zrób od nowa … wpadłem w czeluści internetu, długo nie mogłem znaleźć czegoś co by mi odpowiadało.
Po długotrwałych poszukiwaniach wyłowiłem sobie działający kod Bascom AVR. Odpowiada mnie dlatego, że nie zawierał wstawek asemblerowych w związku z czym będzie działał na różnych µC i jest przejrzysty. Nie ma tam żadnej czarnej magii ;-p Oto on
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 |
'zrodlo http://iloapp.royalsystems.dk/blog/blog?Home&category=0 '* Author : Rubashka Vasiliy , Ukraine , 2007 $regfile = "m32def.dat" $crystal = 8000000 $hwstack = 36 $swstack = 36 $framesize = 40 Config Lcdpin = Pin , Rs = Portc.7 , E = Portc.6 , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 Config Lcd = 24 * 2 Cursor Off Cls Locate 1 , 4 Lcd "NEC DECODER" Locate 2 , 4 Lcd "BASCOM-AVR" Wait 1 Config Timer0 = Timer , Prescale = 256 '8000000/256=31250 Hz Config Int1 = Falling 'Interruption on Falling Stop Timer0 Enable Timer0 Enable Int1 Enable Interrupts On Timer0 Tikers 'work on timer On Int1 Infrared 'work on interruption Dim Got As Bit Dim Tik As Word 'counter of teaks of timer Dim Byt As Byte 'counter accepted bit Dim Repeat_flag As Bit 'flag of repetition Dim Start_flag As Bit 'flag of start condition Dim Address_1 As Byte 'direct byte of address Dim Command_1 As Byte 'direct byte of command Dim Address_0 As Byte 'indirect byte of address Dim Command_0 As Byte 'indirect byte of command Dim Summa As Word Dim Address_nec As Byte , Command_nec As Byte Cursor Off 'Switch Off cursor '################################################################################################################ Do 'Main cycle If Got = 1 Then Cls Locate 1 , 1 Lcd "ADDRESS " ; Address_nec Locate 2 , 1 Lcd "COMMAND " ; Command_nec 'Lcd ADDRESS and COMMAND Reset Got End If Waitms 10 'Delay 10 en Loop End 'End of main cycle '################################################################################################################ Tikers: 'work on timer Timer0 = 253 '31250/(256-253)=10416,66 Hz (96 een) Incr Tik If Tik >= 1200 Then 'if 1200 teaks, have thrown all in source condition Tik = 0 Repeat_flag = 0 Start_flag = 0 Address_1 = 255 Command_1 = 255 Address_0 = 0 Command_0 = 0 Address_nec = 255 Command_nec = 255 Stop Timer0 End If Return '################################################################################################################ Infrared: 'work on interruption Start Timer0 If Tik >= 139 And Tik < 150 Then 'if has happenned from 139 before 150 teaks - "START" Address_nec = 1 Repeat_flag = 0 Start_flag = 1 Address_1 = 255 Command_1 = 255 Address_0 = 0 Command_0 = 0 End If If Tik >= 116 And Tik < 139 Then 'if has happenned from 116 before 138 teaks - "REPETITION" Address_nec = 0 Repeat_flag = 1 Start_flag = 0 End If If Tik >= 22 And Tik < 116 And Start_flag = 1 Then 'if has happenned from 22 before 115 teaks - have taken "1" Incr Byt If Byt < 9 Then Shift Address_1 , Left Address_1 = Address_1 + 1 End If If Byt >= 9 And Byt < 17 Then Shift Address_0 , Left Address_0 = Address_0 + 1 End If If Byt >= 17 And Byt < 25 Then Shift Command_1 , Left Command_1 = Command_1 + 1 End If If Byt >= 25 Then Shift Command_0 , Left Command_0 = Command_0 + 1 End If End If If Tik >= 10 And Tik < 22 And Start_flag = 1 Then 'if has happenned from 10 before 21 teaks - have taken "0" Incr Byt If Byt < 9 Then Shift Address_1 , Left End If If Byt >= 9 And Byt < 17 Then Shift Address_0 , Left End If If Byt >= 17 And Byt < 25 Then Shift Command_1 , Left End If If Byt >= 25 Then Shift Command_0 , Left End If End If Tik = 0 If Byt = 32 Then Address_nec = Address_1 Command_nec = Command_1 Set Got Address_1 = 255 Command_1 = 255 Byt = 0 Repeat_flag = 0 Start_flag = 0 Stop Timer0 End If Return |
i drugi,
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 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 |
'Volume range:-96DB - +31.5 DB '----------------------------------------------------------------------------------------- ' name : pga2310_m8515_6in_encoder.bas ' copyright : (c) danzup ' purpose : PGA Preamp controller ' micro : AtMega8515 ' version : 1.enc ' this version with 6 input, RC5 remote control & PGA2310 volume , ' mute ,backlight LED control , with Encoder : A-->PD2 ,B-->PD1 ,C -->GND ' modified time delay for volume set , stop at +3dB for PGA2310 ' 'Modified by FarmTech 20.09.2010 NEC 'volume show + 31.5db To -95.5db step 1db 'http://www.diyaudio.com/forums/analog-line-level/149597-yet-another-volume-controlers-source-selections-3.html#post1987096 '----------------------------------------------------------------------------------------- '$sim $regfile = "M8515.dat" $crystal = 8000000 $hwstack = 38 $swstack = 38 $framesize = 38 Ddra = &B11111111 Ddrb = &B11111111 Ddrc = &B11111000 Ddrd = &B11110000 Ddre = &B100 Portc.0 = 1 Portc.1 = 1 Portc.2 = 1 Porta = &B00001110 Portd.2 = 1 Set Portc.5 Reset Porta.4 Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portd.4 , Rs = Portc.6 , Wr = Portd.5 Config Lcd = 16 * 2 Cursor Off Cls Config Spi = Soft , Din = Porte.0 , Dout = Porta.6 , Ss = Porta.7 , Clock = Porta.5 Declare Sub Spio ' Declare Sub Shif ' Declare Sub Vol Declare Sub Poweron ' Declare Sub Poweroff ' Declare Sub Af_sel ' Declare Sub Pwr_onof ' Declare Sub Mute ' Declare Sub Balance_r ' Declare Sub Balance_l ' Declare Sub Menu ' Declare Sub Bklght ' Declare Sub Lcd_vol_show Dim W As Word Dim G As Byte Dim Inp_sel As Byte Dim Pwr As Bit Dim Mut As Bit Dim L As Byte Dim R As Byte L = 70 R = 70 Dim Vol_u As Byte , Vol_d As Byte ' , Lcd_vol_l As Byte , Lcd_vol_r As Byte Dim Shift_l As Byte , Shift_r As Byte , Power_1 As Byte Dim My_address As Byte , Mut_a As Byte , Tmp As Byte Dim Sel_fun As Byte Dim Gain As Single Dim Gain1 As Single Dim Got As Bit Dim Tik As Word 'counter of teaks of timer Dim Byt As Byte 'counter accepted bit Dim Repeat_flag As Bit 'flag of repetition Dim Start_flag As Bit 'flag of start condition Dim Address_1 As Byte 'direct byte of address Dim Command_1 As Byte 'direct byte of command Dim Address_0 As Byte 'indirect byte of address Dim Command_0 As Byte 'indirect byte of command Dim Address_nec As Byte , Command_nec As Byte Dim Old_nec_a As Byte , Old_nec_c As Byte Dim Menu_text(3) As String * 8 Dim A As Bit , Tmp_mut As Byte , O As Byte Enable Interrupts O = 0 Spiinit Spiout O , 1 Spiout O , 1 Pwr = 0 '0 =stand-by ; 1 = power on Mut = 1 ' 0 =mute , 1 = normal Inp_sel = &B00000010 'default selected first input Tmp = Porta And &B11110001 ' will set the input selected default Porta = Tmp Or Inp_sel Config Timer0 = Timer , Prescale = 256 '8000000/256=31250 Hz Config Int1 = Falling 'Interruption on Falling Stop Timer0 Enable Timer0 Enable Int1 On Timer0 Tikers 'work on timer On Int1 Infrared 'work on interruption Menu_text(1) = "CD " Menu_text(2) = "TUNER " Menu_text(3) = "DVD " My_address = 0 Power_1 = 0 Shift_r = 16 Shift_l = 80 Vol_u = 160 Vol_d = 176 Mut_a = 144 Portd.2 = 0 Encb Alias Pinc.0 Set Encb On Int0 Int_0 'we enable the INT0 interrupt Enable Int0 'we configure the INT0 interrupt to trigger when a falling edge is detected Config Int0 = Falling Config Timer1 = Timer , Prescale = 1024 Enable Timer1 Start Timer1 Enable Interrupts '-------------------------------------------------------------------------- If Pwr = 0 Then Call Poweroff End If '-------------------------------------------------------------------------- Do If Pwr = 1 Then W = Timer1 If W => 55000 Then Set Portc.5 Stop Timer1 G = 0 Home Upper Call Af_sel Call Lcd_vol_show End If 'will set the Port D bit 7 to 0V backlight off If Got = 1 Or Repeat_flag = 1 Then If Repeat_flag = 1 Then Address_nec = Old_nec_a Command_nec = Old_nec_c End If Reset Got Reset Repeat_flag If Address_nec = My_address Then Select Case Command_nec Case Shift_l : A = 1 Call Shif 'remote command code for CH up Case Shift_r : A = 0 Call Shif 'remote command code for CH down Case Vol_u : A = 1 Call Vol 'remote command code for Vol + Case Vol_d : A = 0 Call Vol 'remote command code for Vol - Case Mut_a : Call Mute 'remote command code for Mute Case Power_1 : Call Pwr_onof 'remote command code for On/Off End Select End If End If If Pinc.2 = 0 Then Sel_fun = 0 Do Incr Sel_fun Waitms 10 Loop Until Pinc.2 = 1 Or Sel_fun > 155 If Sel_fun < 100 Then Call Menu If Sel_fun > 99 And Sel_fun < 150 Then Call Mute If Sel_fun > 149 Then Call Pwr_onof End If End If If Pwr = 0 Then If Got = 1 Then 'read if we have remote ir command If Address_nec = My_address Then Select Case Command_nec Case Power_1 : Call Pwr_onof 'remote command code for On/Off End Select Reset Got End If End If If Pinc.2 = 0 Then Call Pwr_onof End If Loop End '-------------------Int_0------------------------ Int_0: Disable Int0 If Encb = 1 Then If G = 0 Then A = 1 Call Vol End If If G = 1 Then A = 1 Call Shif End If Else If G = 0 Then A = 0 Call Vol End If If G = 1 Then A = 0 Call Shif End If End If End_me: Gifr = 64 'asta e cea mai mare smecherie ! Enable Int0 Return '------- Bklght------------------ Sub Bklght: Reset Portc.5 'backlight on W = 0 Timer1 = W Start Timer1 'reset timer 1 End Sub '-----------Pwr_onof----------------- Sub Pwr_onof: Pwr = Not Pwr If Pwr = 1 Then Call Poweron Else Call Poweroff End If End Sub '------Poweron------------------------ Sub Poweron: Set Porta.4 'unmute PGA2310 Reset Portc.5 'power relay on Display On 'turn display on Cls Lcd " POWER ON " Waitms 500 Cls Tmp = Porta And &B11110001 Porta = Tmp Or Inp_sel Call Af_sel O = 1 For Tmp_mut = 0 To L Spiinit Spiout Tmp_mut , 1 Spiout Tmp_mut , 1 Waitms 10 Call Lcd_vol_show Next O = 0 Waitms 100 Enable Int0 Enable Interrupts W = 0 Timer1 = W Start Timer1 End Sub '-------Poweroff---------------------- Sub Poweroff: O = 1 For Tmp_mut = L To 0 Step -1 Spiinit Spiout Tmp_mut , 1 Spiout Tmp_mut , 1 Waitms 10 Call Lcd_vol_show Next O = 0 Set Porta.4 'mute PGA2310 Reset Portc.5 'power relay off Cls Lcd " POWER OFF" 'turn display off Tmp = Porta And &B11110001 Porta = Tmp Or &B0000000 ' mute Waitms 1000 Set Portc.5 Display Off Disable Int0 Enable Interrupts End Sub '---------shift input Left---------- Sub Shif() Call Bklght If A = 1 Then If Inp_sel >= 2 And Inp_sel < 8 Then Shift Inp_sel , Left , 1 End If Else If Inp_sel > 2 And Inp_sel < 9 Then Shift Inp_sel , Right , 1 End If End If Call Af_sel If Mut = 1 Then Tmp = Porta And &B11110001 Porta = Tmp Or Inp_sel Else Home Lowerline Lcd " MUTE " End If Waitms 500 End Sub Sub Vol() Call Bklght O = 0 If Mut = 0 Then Call Mute If A = 1 Then If L = 254 Then L = 252 End If If R = 254 Then R = 252 End If L = L + 2 R = R + 2 Else If L = 0 Then L = 2 End If If R = 0 Then R = 2 End If L = L - 2 R = R - 2 End If Call Lcd_vol_show Call Spio Waitms 5 End Sub Sub Lcd_vol_show() If O = 1 Then Gain = Tmp_mut / 2 Else Gain = L / 2 End If Gain1 = -96 + Gain Home Lowerline If O = 0 Then If L > 192 Then Lcd "Volume +" ; Gain1 ; " dB " Else Lcd "Volume " ; Gain1 ; " dB " End If End If If O = 1 Then If Tmp_mut > 192 Then Lcd "Volume +" ; Gain1 ; " dB " Else Lcd "Volume " ; Gain1 ; " dB " End If End If End Sub '------Af_sel--------------------------- Sub Af_sel: Home Upper If Inp_sel = 2 Then Lcd Menu_text(1) End If If Inp_sel = 4 Then Lcd Menu_text(2) End If If Inp_sel = 8 Then Lcd Menu_text(3) End If End Sub '------- Mute ---------- Sub Mute: Call Bklght Mut = Not Mut O = 1 If Mut = 1 Then Set Porta.4 Tmp = Porta And &B11110001 Porta = Tmp Or Inp_sel For Tmp_mut = 0 To L Spiinit Spiout Tmp_mut , 1 Spiout Tmp_mut , 1 Waitms 10 Call Lcd_vol_show Next Wait 1 Else For Tmp_mut = L To 0 Step -1 Spiinit Spiout Tmp_mut , 1 Spiout Tmp_mut , 1 Waitms 10 Call Lcd_vol_show Next Tmp = Porta And &B11110001 Porta = Tmp Or &B0000000 Reset Porta.4 Home Lowerline Lcd " MUTE " Wait 1 End If O = 0 End Sub '-----Send data to PGA2310------ Sub Spio: Spiinit Spiout L , 1 Spiout R , 1 End Sub '-----------Menu----------------- Sub Menu: G = G + 1 Call Bklght 'backlight on If G > 1 Then G = 0 End If If G = 0 Then Cls Home Upper Lcd " Adjust Volume " Call Lcd_vol_show Waitms 200 End If If G = 1 Then Cls Home Upper Call Af_sel Home Lowerline Lcd " Select Input " Waitms 200 End If End Sub '( '--------------Balance left----------------- Sub Balance_r: If L = 254 Then L = 252 End If If L = 0 Then L = 2 End If If R = 0 Then R = 2 End If If R = 254 Then R = 252 End If If L < R Then L = L + 2 Else R = R - 2 End If Call Spio Lcd_vol_l = L / 2 Lcd_vol_r = R / 2 End Sub '------------Balance right---------- Sub Balance_l If R = 0 Then R = 2 End If If R = 254 Then R = 252 End If If L = 0 Then L = 2 End If If L = 254 Then L = 252 End If If R < L Then R = R + 2 Else L = L - 2 End If Call Spio Lcd_vol_l = L / 2 Lcd_vol_r = R / 2 End Sub ') Tikers: 'work on timer Timer0 = 253 '31250/(256-253)=10416,66 Hz (96 een) Incr Tik If Tik >= 1200 Then 'if 1200 teaks, have thrown all in source condition Tik = 0 Repeat_flag = 0 Start_flag = 0 Address_1 = 255 Command_1 = 255 Address_0 = 0 Command_0 = 0 Address_nec = 255 Command_nec = 255 Stop Timer0 End If Return '################################################################################################################ Infrared: 'work on interruption Start Timer0 If Tik >= 139 And Tik < 150 Then 'if has happenned from 139 before 150 teaks - "START" Address_nec = 1 Repeat_flag = 0 Start_flag = 1 Address_1 = 255 Command_1 = 255 Address_0 = 0 Command_0 = 0 End If If Tik >= 116 And Tik < 139 Then 'if has happenned from 116 before 138 teaks - "REPETITION" Address_nec = 0 Repeat_flag = 1 Start_flag = 0 Address_nec = Old_nec_a Command_nec = Old_nec_c End If If Tik >= 22 And Tik < 116 And Start_flag = 1 Then 'if has happenned from 22 before 115 teaks - have taken "1" Incr Byt If Byt < 9 Then Shift Address_1 , Left Address_1 = Address_1 + 1 End If If Byt >= 9 And Byt < 17 Then Shift Address_0 , Left Address_0 = Address_0 + 1 End If If Byt >= 17 And Byt < 25 Then Shift Command_1 , Left Command_1 = Command_1 + 1 End If If Byt >= 25 Then Shift Command_0 , Left Command_0 = Command_0 + 1 End If End If If Tik >= 10 And Tik < 22 And Start_flag = 1 Then 'if has happenned from 10 before 21 teaks - have taken "0" Incr Byt If Byt < 9 Then Shift Address_1 , Left End If If Byt >= 9 And Byt < 17 Then Shift Address_0 , Left End If If Byt >= 17 And Byt < 25 Then Shift Command_1 , Left End If If Byt >= 25 Then Shift Command_0 , Left End If End If Tik = 0 If Byt = 32 Then Address_nec = Address_1 Command_nec = Command_1 Old_nec_a = Address_nec Old_nec_c = Command_nec Set Got Address_1 = 255 Command_1 = 255 Byt = 0 Repeat_flag = 0 Start_flag = 0 Stop Timer0 End If Return |
który był pierwszy/źródłowy nie wiem, ale drugi jest bardziej rozwinięty. Więc moim zdaniem dał podwaliny temu pierwszemu, oczywiście nie twierdzę, że ktoś przygarnął sobie czyjąś pracę …
Na tej podstawie po małej optymalizacji opracowałem swój odbiornik IR według specyfikacji NEC, i zaszczepiam go do projektu sterownika dwóch źródeł światła led sterowanych przez PWM na ATtiny44. Prace trwają … (AD2013-12-07). Po ich zakończeniu przedstawię moją wersję kodu odbiornika i trochę go omówię co tam się dzieje.
A.D. 2014-09-27 Miałem dopisać co i jak bo naobiecywałem …. i co?
Nota katalogowa
VT1838Tpdf.pdf (4020 pobrań )
Nota katalogowa
VS1838.pdf (3812 pobrań )
Nota katalogowa
VS1838B.pdf (3757 pobrań )
Rysunki z przebiegami, oraz duża dawka wiedzy o protokole NEC zaczerpnięta z tej witryny, z działu baza wiedzy.
Witam
Istnieje możliwość zoptymalizowania kodu odbiornika abym mógł go wgrać na ATMEGA8 lub mniejszego?
Mam tylko jeden pin wyjściowy (włącz wyłącz) bez obsługi wyświetlacza.
Spróbuj wyłuskać to co potrzebne, skompiluj i będziesz mile zaskoczony ;-D
Jeszcze może głupie pytanie, ale pod jaki pin podpinamy czujnik IR w drugiej wersji programu ??
Wiesz co odpowiem w dwóch częściach. Najpierw nie na temat … który Cię interesuje.
Jest takie przysłowie: „nie ma głupich pytań, są tylko głupie odpowiedzi”
Co może oznaczać, że nawet złe, lub źle zadane pytanie, o ile uzyskamy dobrą odpowiedź czyni nas mądrzejszymi. Tylko głupie odpowiedzi są złe, z głupich pytań można coś wynieść.
Teraz do rzeczy 😀
Z kodu wynika, że obsługa jest inicjowana przez zewnętrzne przerwanie Int1.
Config Timer0 = Timer , Prescale = 256 '8000000/256=31250 Hz
Config Int1 = Falling 'Interruption on Falling
Stop Timer0
Enable Timer0
Enable Int1
On Timer0 Tikers 'work on timer
On Int1 Infrared
Więc musisz tam doprowadzić odpowiedni sygnał sterujący. Inaczej mówiąc odszukaj w swoim µC pin o takiej nazwie, i tam doprowadź wygnał ze swojego sensora.
Niestety brak reakcji przy Int1
Posprawdzałem piny wszystkie i jedyna reakcja była przy resecie:D
Co trzeba zmienić w kodzie aby pilot działał z kwarcem 11.0592MHz?
Chodzi mi o pierwszy kod, ten mniej rozbudowany 😉
Witam.
Musisz dostroić system przerwań tak by działał zgodnie z komentarzami w kodzie.
Config Timer0 = Timer , Prescale = 256 '8000000/256=31250 Hz
Chodzi o to by uzyskać częstotliwość generowanego przerwania = 31250Hz. W razie rozbieżności konieczne może okazać się „dostrojenie” wartości tik w liniach:
If Tik >= 139 And Tik < 150 Then 'if has happenned from 139 before 150 teaks - "START"
oraz
If Tik >= 116 And Tik < 139 Then 'if has happenned from 116 before 138 teaks - "REPETITION"
kolejnej:
If Tik >= 22 And Tik < 116 And Start_flag = 1 Then 'if has happenned from 22 before 115 teaks - have taken "1"
i tej:
If Tik >= 10 And Tik < 22 And Start_flag = 1 Then 'if has happenned from 10 before 21 teaks - have taken "0"
Dlatego najlepiej będzie pochylić się i dobrze wybrać czas generowanego przerwania, by był jak najbardziej zbliżony do 8,192ms.
Zwróć też uwagę na fakt iż w obsłudze przerwania autor obcina czas:
Timer0 = 253 '31250/(256-253)=10416,66 Hz (96 een)
W razie komplikacji z konfiguracją systemu przerwań, tu też należy nanieść stosowną zmianę.
Jeśli masz problem z obliczeniem wartości dla konfiguracji timerów polecę Twojej uwadze to narzędzie: AVR Timer oblicza co trzeba i generuje kod dla Bascom AVR.
Ślicznie dziękuję za tak obszerną odpowiedź co należy zrobić, ale jestem zbyt cienki w uszach aby to zrobić. Myślałem, że będzie to prostsze 🙁
W takim razie może jeszcze prościej 😉
Kliknij w witrynkę, jest w obcym języku ale to nie szkodzi.
W okienku podpisanym Quarzfrequenz: wpisz 11.0592, kolejnie tam gdzie jest podpis Wunschzeit/Frequenz: wpisz 8.192. Zaznacz Timer0.
Zaobserwuj jak się zmienia przykład kodu w poniżej ramce, wraz z obfitymi komentarzami. Nowe obliczenia zawierają nieznaczny odchył, od założeń.
Te nastawy dotyczą wstępnej konfiguracji timera.
Po poprawieniu swojego kodu o prezentowane wartości, zrób próby, jak wszystko będzie działało to nie trzeba nic więcej zmieniać, w przeciwnym wypadku pomyślimy.
Zrobiłem coś takiego, ale pilot ani drgnie.
$regfile = "m32def.dat"
$crystal = 11059200
(...)
Const Timer0_preload = 168
Config Timer0 = Timer , Prescale = 1024 '8000000/256=31250 Hz
Config Int1 = Falling 'Interruption on Falling
Stop Timer0
Timer0 = Timer0_preload
Enable Timer0
Enable Int1
Enable Interrupts
On Timer0 Tikers 'work on timer
On Int1 Infrared 'work on interruption
Dim Got As Bit
Dim Tik As Word 'counter of teaks of timer
Dim Byt As Byte 'counter accepted bit
Dim Repeat_flag As Bit 'flag of repetition
Dim Start_flag As Bit 'flag of start condition
Dim Address_1 As Byte 'direct byte of address
Dim Command_1 As Byte 'direct byte of command
Dim Address_0 As Byte 'indirect byte of address
Dim Command_0 As Byte 'indirect byte of command
Dim Summa As Word
Dim Address_nec As Byte , Command_nec As Byte
Cursor Off 'Switch Off cursor
To teraz w linii:
Timer0 = 253 '31250/(256-253)=10416,66 Hz (96 een)
popraw na
Timer0 = 253 na 255
Heehh ten komentarz ’31250/(256-253)=10416,66 Hz już jest nie na miejscu … zresztą tak jak i poprzedni. Po modyfikacji kody wprowadza w błąd.
Sęk w tym, że „prawdziwa nastawa” timera do dekodowania, ukryta jest w obsłudze jego przerwania.
Do licznika ładowana jest wartość określająca czas przepełnienia, i wywołania przerwania. Teraz z uwagi na wyśrubowanie timmingu (żwawszy inny rezonator) wyszło trochu ekstremalnie i do licznika ładowana jest jego maksymalna wartość, czyli przerwanie występuje za każdym razem po zwiększeniu licznika ;-D
Spowodowane jest to mniejszą pojemnością licznika 8-bitowego (który użyłeś), w porównaniu do 16-to bitowego. W razie gdybyś chciał można wszystko przełożyć na inny timer – o większej pojemności.
Czasy są teraz mniej precyzyjne od poprzednich. Przetestuj dokładnie wszystko by później nie było wpadki.