как передать ИК команды без участия ИК диода и ИК приемника(по кабелю)
- Войдите на сайт для отправки комментариев
Втр, 13/09/2016 - 23:06
Всем доброго времени суток, имеются команды ик пульта в HEX виде. Ардуина спокойно передаёт в приёмник, команды распознаются устройством, в моём случае магнитолой JVC. Проблема в реализации, ик диод примотан к ик приёмнику изолентой. Можно ли соеденить передатчик и приёмник (нонга out ик приемника) напрямую кабелем, и в каком виде передавать команды? Если такая проблемам уже решалась прошу ткнуть носом.
Что такое сигнал дистанционного управления. Как правило это несущая частота и наложенная на него закодированная последовательность импульсов. Значит надо детектировать сигнал и выделять несущую, потом подовать на обычный цифровой вход и обрабатывать. Или формировать закодированный сигнал без поднесущей и подовать минуя приемник с детектором.
А зачем? Если правильно подобрана частота модуляции (36КГц, 38КГц, 40КГц и т.д.), то ИК-приёмник должен улавливать сигнал от ИК-светодиода на гораздо бОльшем расстоянии, а не впритык. И даже переотраженный сигнал, если он направлен в сторону.
Если всё же хотите по кабелю, то вот Вам картинки. Чтобы Вы понимали, чем отличается сигнал излучаемый светодиодом от сигнала, который после "преобразования" приёмником передаётся непосредственно устройству. То есть, разницу сигнала на ножках ИК-светодиода и ножках ИК-приёмника.
Разобрать магнитолу, найти ик-приемник, отыскать, где у него выход, выпаять его из платы, в ту же дырку запаять провод от ноги ардуины, с которой сигнал до этого шел к ик-диоду. Единственное, стоит уточнить, с пятивольтовыми ли уровнями работал ик-приемник в магнитоле. Еще скорее всего придется убрать несущую (36-38кгц обычно) из сигнала формируемого ардуиной.
Еще скорее всего придется убрать несущую (36-38кгц обычно) из сигнала формируемого ардуиной.
И логические уровни инвертировать.
мда.. вот тока зачем вся эта затея .....
Мож он кнопками на руле хочет управлять ей.
Да, всё дело в кнопках
Нашел на просторах интернета такую схемку, прокатит?
Не совсем понятно, как вы хотите ее применить.
На магнитоле ещё есть провод, сине желтый, для выносных кнопок, вот к нему попробовать. На нем 3,3в
Блин, вы зачем-то валите все в одну кучу. Ик-приемник -- это одно, провода для выносных кнопок -- это другое. Совершенно точно, что там все по разному.
Ну очевидно, что эта схема предназначеня для подключения к тому контакту на плате, куда впаян ИК-приёмник (точнее, его ножка OUT). Потому что в схеме реализовано аппаратное "сглаживание" несущей и инвертирование сигнала. Что там за сине желтый провод с 3,3В без понятия.
Подскажи как за счет чего "реализовано "аппаратное" сглаживание несущей и инвертирование сигнала. " ? Я просто в сигналах не очень. И как мне подключится к ик приемнику, в таком случае
Я могу, конечно, путать, но на выходе приемника уже не должно быть несущей. Я к контату, куда (был) запаян выход приемника, предлагал сразу цеплять выход ардуины. Там больше никаких схем не нужно. Только проверить, чтобы по лог. уровням все совпадало.
обычно так и есть
а тут не так, т.к. на ИК-светодиод передатчика подается модулированный сигнал (обычное заполнение 36, 38 и т.п. кГц )
т.е. напрямую цеплять нельзя, только после детектирования и фильтрации
И как это проверить, если у меня в скетче коды кнопок прописаны. Скетч скину с утра
Я могу, конечно, путать, но на выходе приемника уже не должно быть несущей.
Да, не должно быть. В схеме конденсатор (RC-цепочка?) для этого же стоит? На входе схемы имеем сигнал модулированный несущей. После сглаживания (фильтрации) несущая убирается и остаётся чистый сигнал, который затем инвертируется транзистором.
Я к контату, куда (был) запаян выход приемника, предлагал сразу цеплять выход ардуины. Там больше никаких схем не нужно. Только проверить, чтобы по лог. уровням все совпадало.
Без аппаратной или программной доработки не получится. По лог. уровням точно совпадать не будет, т.к. на выходе ИК-приёмника лог. 0 - это высокий уровень, а лог. 1 - низкий уровень. Я не вкурсе, есть ли уже готовые библиотеки, которые будут работать в таком специфичном режиме.
Подскажи как за счет чего "реализовано "аппаратное" сглаживание несущей и инвертирование сигнала. " ?
За счет конденсатора и транзистора.
И как мне подключится к ик приемнику, в таком случае
Писал выше - контакт на плате, куда запаяна ножка OUT ИК-приёмника (да, надо ещё распиновку знать)
может таки стоит поискать мануал на магнитолу, если у нее уже штатно есть провод для кнопок?
там должна быть система типа аналоговой клавиатуры ардуины, т.е. просто набор резисторов подцепляется и коммутируется кнопками.
Необходимость в аппаратной доработке не видится мне обязательной. Ардуино-трансмиттер формирует модулированный сигнал, подключая или отключая пин к шим-каналу таймера. Если найти в коде, где это делается (а найти таки можно) и заменить действие на опускание/поднимание ноги (в том числе и с нужной инверсией) то на этом все модификации можно считать законченными.
А, ну так-то да. Только, боюсь, топикстартёр не осилит самостоятельно и попросит переделать ему библиотеку.
Да по любому нужна или какая-то минимальная квалификация или желание ее получить. Отпаять/запаять потребуется, чуть подправить код тоже. Захочет -- разберется. Не захочет, из раздела "Ищу исполнителя" тоже никого еще не выгоняли. :)
Я имел ввиду какие ножки транзистора куда цеплять к ИК приемнику. Так?
liseratum, похоже вы из вышесказанного не поняли ничего. В кратце : (1) выход ардуины подключается к входу для TSOP приёмника на магнитоле, никакие посредники в виде транзисторов не нужны. (2) нужно полностью менять код программы. Существующие IR библиотеки скорее всего не умеют посылать немодулированный сигнал. Если вы не в состоянии самостоятельно написать код для эмуляции нужной посылки - оставьте всё как есть )
Уметь-то они может и не умеют, но научить их не так и сложно. Я все-таки полез посмотреть, как там оно работает и мои предположения, похоже, подтверждаются. IR-посылка "набирается" из нужного количества вызовов "space" и "mark", где сами эти методы выглядят довольно просто:
01
//+=============================================================================
02
// Sends an IR mark for the specified number of microseconds.
03
// The mark output is modulated at the PWM frequency.
04
//
05
void
IRsend::mark (unsigned
int
time)
06
{
07
TIMER_ENABLE_PWM;
// Enable pin 3 PWM output
08
if
(time > 0) custom_delay_usec(time);
09
}
10
11
//+=============================================================================
12
// Leave pin off for time (given in microseconds)
13
// Sends an IR space for the specified number of microseconds.
14
// A space is no output, so the PWM output is disabled.
15
//
16
void
IRsend::space (unsigned
int
time)
17
{
18
TIMER_DISABLE_PWM;
// Disable pin 3 PWM output
19
if
(time > 0) IRsend::custom_delay_usec(time);
20
}
Каждый метод либо включает, либо выключает таймер с помощью макросов TIMER_xxx_PWM. Смотрим, из чего они состоят:
1
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
2
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
Так и есть, нога ардуины тупо подключается к каналу таймера или отключается от него. Тут уж и начинающий справится, переписав эти макры, да хоть бы так:
1
#define TIMER_ENABLE_PWM digitalWrite(IRPin, LOW)
2
#define TIMER_DISABLE_PWM digitalWrite(IRPin, HIGH)
Где HIGH, где LOW я сейчас не соображу, можно так попробовать, можно так.
Да я понял все. Но думал обойдется малой кровью. Сначала попробую с проводом по схеме, потом, с ногой out tsop, потом попробую библиотеку исправить и перезалить все. В любом случае если что либо из этого получится я буду безмерно рад счастлив и благодарен всем участникам.
Спасибо огромное!! У меня получилось!!! Изменил в библиотеке ВСЕ параметры (TIMER_*****_PWM ) следующим образом, и оно заработало по кабелю! Хотя я сомневался до последнего, и на последних изменениях заработало! На ножке ик приемника OUT замерено 0,12В. Поэтому и сомневался.
001
/*
002
* IRremote
003
* Version 0.1 July, 2009
004
* Copyright 2009 Ken Shirriff
005
* For details, see <a href="http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html" title="http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html" rel="nofollow">http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html</a>
006
*
007
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
008
*
009
* Interrupt code based on NECIRrcv by Joe Knapp
010
* <a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556" title="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556" rel="nofollow">http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556</a>
011
* Also influenced by <a href="http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/" title="http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/" rel="nofollow">http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/</a>
012
*
013
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
014
*/
015
016
#ifndef IRremoteint_h
017
#define IRremoteint_h
018
019
#if defined(ARDUINO) && ARDUINO >= 100
020
#include <Arduino.h>
021
#else
022
#include <WProgram.h>
023
#endif
024
025
// define which timer to use
026
//
027
// Uncomment the timer you wish to use on your board. If you
028
// are using another library which uses timer2, you have options
029
// to switch IRremote to use a different timer.
030
031
// Arduino Mega
032
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
033
//#define IR_USE_TIMER1 // tx = pin 11
034
#define IR_USE_TIMER2 // tx = pin 9
035
//#define IR_USE_TIMER3 // tx = pin 5
036
//#define IR_USE_TIMER4 // tx = pin 6
037
//#define IR_USE_TIMER5 // tx = pin 46
038
039
// Teensy 1.0
040
#elif defined(__AVR_AT90USB162__)
041
#define IR_USE_TIMER1 // tx = pin 17
042
043
// Teensy 2.0
044
#elif defined(__AVR_ATmega32U4__)
045
//#define IR_USE_TIMER1 // tx = pin 14
046
//#define IR_USE_TIMER3 // tx = pin 9
047
#define IR_USE_TIMER4_HS // tx = pin 10
048
049
// Teensy++ 1.0 & 2.0
050
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
051
//#define IR_USE_TIMER1 // tx = pin 25
052
#define IR_USE_TIMER2 // tx = pin 1
053
//#define IR_USE_TIMER3 // tx = pin 16
054
055
// Sanguino
056
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
057
//#define IR_USE_TIMER1 // tx = pin 13
058
#define IR_USE_TIMER2 // tx = pin 14
059
060
// Atmega8
061
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
062
#define IR_USE_TIMER1 // tx = pin 9
063
064
#elif defined( __AVR_ATtinyX4__ )
065
#define IR_USE_TIMER1 // tx = pin 6
066
067
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
068
#else
069
//#define IR_USE_TIMER1 // tx = pin 9
070
#define IR_USE_TIMER2 // tx = pin 3
071
#endif
072
073
074
075
#ifdef F_CPU
076
#define SYSCLOCK F_CPU // main Arduino clock
077
#else
078
#define SYSCLOCK 16000000 // main Arduino clock
079
#endif
080
081
#define ERR 0
082
#define DECODED 1
083
084
085
// defines for setting and clearing register bits
086
#ifndef cbi
087
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
088
#endif
089
#ifndef sbi
090
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
091
#endif
092
093
// Pulse parms are *50-100 for the Mark and *50+100 for the space
094
// First MARK is the one after the long gap
095
// pulse parameters in usec
096
#define NEC_HDR_MARK 9000
097
#define NEC_HDR_SPACE 4500
098
#define NEC_BIT_MARK 560
099
#define NEC_ONE_SPACE 1600
100
#define NEC_ZERO_SPACE 560
101
#define NEC_RPT_SPACE 2250
102
103
#define SONY_HDR_MARK 2400
104
#define SONY_HDR_SPACE 600
105
#define SONY_ONE_MARK 1200
106
#define SONY_ZERO_MARK 600
107
#define SONY_RPT_LENGTH 45000
108
#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
109
110
// SA 8650B
111
#define SANYO_HDR_MARK 3500 // seen range 3500
112
#define SANYO_HDR_SPACE 950 // seen 950
113
#define SANYO_ONE_MARK 2400 // seen 2400
114
#define SANYO_ZERO_MARK 700 // seen 700
115
#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
116
#define SANYO_RPT_LENGTH 45000
117
118
// Mitsubishi RM 75501
119
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
120
121
// #define MITSUBISHI_HDR_MARK 250 // seen range 3500
122
#define MITSUBISHI_HDR_SPACE 350 // 7*50+100
123
#define MITSUBISHI_ONE_MARK 1950 // 41*50-100
124
#define MITSUBISHI_ZERO_MARK 750 // 17*50-100
125
// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
126
// #define MITSUBISHI_RPT_LENGTH 45000
127
128
129
#define RC5_T1 889
130
#define RC5_RPT_LENGTH 46000
131
132
#define RC6_HDR_MARK 2666
133
#define RC6_HDR_SPACE 889
134
#define RC6_T1 444
135
#define RC6_RPT_LENGTH 46000
136
137
#define SHARP_BIT_MARK 245
138
#define SHARP_ONE_SPACE 1805
139
#define SHARP_ZERO_SPACE 795
140
#define SHARP_GAP 600000
141
#define SHARP_TOGGLE_MASK 0x3FF
142
#define SHARP_RPT_SPACE 3000
143
144
#define DISH_HDR_MARK 400
145
#define DISH_HDR_SPACE 6100
146
#define DISH_BIT_MARK 400
147
#define DISH_ONE_SPACE 1700
148
#define DISH_ZERO_SPACE 2800
149
#define DISH_RPT_SPACE 6200
150
#define DISH_TOP_BIT 0x8000
151
152
#define PANASONIC_HDR_MARK 3502
153
#define PANASONIC_HDR_SPACE 1750
154
#define PANASONIC_BIT_MARK 502
155
#define PANASONIC_ONE_SPACE 1244
156
#define PANASONIC_ZERO_SPACE 400
157
158
#define JVC_HDR_MARK 8000
159
#define JVC_HDR_SPACE 4000
160
#define JVC_BIT_MARK 600
161
#define JVC_ONE_SPACE 1600
162
#define JVC_ZERO_SPACE 550
163
#define JVC_RPT_LENGTH 60000
164
165
#define SHARP_BITS 15
166
#define DISH_BITS 16
167
168
#define TOLERANCE 25 // percent tolerance in measurements
169
#define LTOL (1.0 - TOLERANCE/100.)
170
#define UTOL (1.0 + TOLERANCE/100.)
171
172
#define _GAP 5000 // Minimum map between transmissions
173
#define GAP_TICKS (_GAP/USECPERTICK)
174
175
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
176
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
177
178
#ifndef DEBUG
179
int
MATCH(
int
measured,
int
desired) {
return
measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);}
180
int
MATCH_MARK(
int
measured_ticks,
int
desired_us) {
return
MATCH(measured_ticks, (desired_us + MARK_EXCESS));}
181
int
MATCH_SPACE(
int
measured_ticks,
int
desired_us) {
return
MATCH(measured_ticks, (desired_us - MARK_EXCESS));}
182
// Debugging versions are in IRremote.cpp
183
#endif
184
185
// receiver states
186
#define STATE_IDLE 2
187
#define STATE_MARK 3
188
#define STATE_SPACE 4
189
#define STATE_STOP 5
190
191
// information for the interrupt handler
192
typedef
struct
{
193
uint8_t recvpin;
// pin for IR data from detector
194
uint8_t rcvstate;
// state machine
195
uint8_t blinkflag;
// TRUE to enable blinking of pin 13 on IR processing
196
unsigned
int
timer;
// state timer, counts 50uS ticks.
197
unsigned
int
rawbuf[RAWBUF];
// raw data
198
uint8_t rawlen;
// counter of entries in rawbuf
199
}
200
irparams_t;
201
202
// Defined in IRremote.cpp
203
extern
volatile
irparams_t irparams;
204
205
// IR detector output is active low
206
#define MARK 0
207
#define SPACE 1
208
209
#define TOPBIT 0x80000000
210
211
#define NEC_BITS 32
212
#define SONY_BITS 12
213
#define SANYO_BITS 12
214
#define MITSUBISHI_BITS 16
215
#define MIN_RC5_SAMPLES 11
216
#define MIN_RC6_SAMPLES 1
217
#define PANASONIC_BITS 48
218
#define JVC_BITS 16
219
220
221
222
223
// defines for timer2 (8 bits)
224
#if defined(IR_USE_TIMER2)
225
#define TIMER_RESET
226
#define TIMER_ENABLE_PWM digitalWrite(3, LOW)
227
#define TIMER_DISABLE_PWM digitalWrite(3, HIGH)
228
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
229
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
230
#define TIMER_INTR_NAME TIMER2_COMPA_vect
231
#define TIMER_CONFIG_KHZ(val) ({ \
232
const
uint8_t pwmval = SYSCLOCK / 2000 / (val); \
233
TCCR2A = _BV(WGM20); \
234
TCCR2B = _BV(WGM22) | _BV(CS20); \
235
OCR2A = pwmval; \
236
OCR2B = pwmval / 3; \
237
})
238
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
239
#if (TIMER_COUNT_TOP < 256)
240
#define TIMER_CONFIG_NORMAL() ({ \
241
TCCR2A = _BV(WGM21); \
242
TCCR2B = _BV(CS20); \
243
OCR2A = TIMER_COUNT_TOP; \
244
TCNT2 = 0; \
245
})
246
#else
247
#define TIMER_CONFIG_NORMAL() ({ \
248
TCCR2A = _BV(WGM21); \
249
TCCR2B = _BV(CS21); \
250
OCR2A = TIMER_COUNT_TOP / 8; \
251
TCNT2 = 0; \
252
})
253
#endif
254
#if defined(CORE_OC2B_PIN)
255
#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */
256
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
257
#define TIMER_PWM_PIN 9 /* Arduino Mega */
258
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
259
#define TIMER_PWM_PIN 14 /* Sanguino */
260
#else
261
#define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
262
#endif
263
264
265
// defines for timer1 (16 bits)
266
#elif defined(IR_USE_TIMER1)
267
#define TIMER_RESET
268
#define TIMER_ENABLE_PWM digitalWrite(3, LOW)
269
#define TIMER_DISABLE_PWM digitalWrite(3, HIGH)
270
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
271
#define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A))
272
#define TIMER_DISABLE_INTR (TIMSK = 0)
273
#else
274
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
275
#define TIMER_DISABLE_INTR (TIMSK1 = 0)
276
#endif
277
278
#if defined(__AVR_ATtinyX4__)
279
#define TIMER_INTR_NAME TIM1_COMPA_vect
280
#else
281
#define TIMER_INTR_NAME TIMER1_COMPA_vect
282
#endif
283
284
#define TIMER_CONFIG_KHZ(val) ({ \
285
const
uint16_t pwmval = SYSCLOCK / 2000 / (val); \
286
TCCR1A = _BV(WGM11); \
287
TCCR1B = _BV(WGM13) | _BV(CS10); \
288
ICR1 = pwmval; \
289
OCR1A = pwmval / 3; \
290
})
291
#define TIMER_CONFIG_NORMAL() ({ \
292
TCCR1A = 0; \
293
TCCR1B = _BV(WGM12) | _BV(CS10); \
294
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
295
TCNT1 = 0; \
296
})
297
#if defined(CORE_OC1A_PIN)
298
#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */
299
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
300
#define TIMER_PWM_PIN 11 /* Arduino Mega */
301
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
302
#define TIMER_PWM_PIN 13 /* Sanguino */
303
#elif defined(__AVR_ATtinyX4__)
304
#define TIMER_PWM_PIN 6 /* ATTiny84 */
305
#else
306
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
307
#endif
308
309
310
// defines for timer3 (16 bits)
311
#elif defined(IR_USE_TIMER3)
312
#define TIMER_RESET
313
#define TIMER_ENABLE_PWM digitalWrite(3, LOW)
314
#define TIMER_DISABLE_PWM digitalWrite(3, HIGH)
315
#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
316
#define TIMER_DISABLE_INTR (TIMSK3 = 0)
317
#define TIMER_INTR_NAME TIMER3_COMPA_vect
318
#define TIMER_CONFIG_KHZ(val) ({ \
319
const
uint16_t pwmval = SYSCLOCK / 2000 / (val); \
320
TCCR3A = _BV(WGM31); \
321
TCCR3B = _BV(WGM33) | _BV(CS30); \
322
ICR3 = pwmval; \
323
OCR3A = pwmval / 3; \
324
})
325
#define TIMER_CONFIG_NORMAL() ({ \
326
TCCR3A = 0; \
327
TCCR3B = _BV(WGM32) | _BV(CS30); \
328
OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
329
TCNT3 = 0; \
330
})
331
#if defined(CORE_OC3A_PIN)
332
#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */
333
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
334
#define TIMER_PWM_PIN 5 /* Arduino Mega */
335
#else
336
#error "Please add OC3A pin number here\n"
337
#endif
338
339
340
// defines for timer4 (10 bits, high speed option)
341
#elif defined(IR_USE_TIMER4_HS)
342
#define TIMER_RESET
343
#define TIMER_ENABLE_PWM digitalWrite(3, LOW)
344
#define TIMER_DISABLE_PWM digitalWrite(3, HIGH)
345
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
346
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
347
#define TIMER_INTR_NAME TIMER4_OVF_vect
348
#define TIMER_CONFIG_KHZ(val) ({ \
349
const
uint16_t pwmval = SYSCLOCK / 2000 / (val); \
350
TCCR4A = (1<<PWM4A); \
351
TCCR4B = _BV(CS40); \
352
TCCR4C = 0; \
353
TCCR4D = (1<<WGM40); \
354
TCCR4E = 0; \
355
TC4H = pwmval >> 8; \
356
OCR4C = pwmval; \
357
TC4H = (pwmval / 3) >> 8; \
358
OCR4A = (pwmval / 3) & 255; \
359
})
360
#define TIMER_CONFIG_NORMAL() ({ \
361
TCCR4A = 0; \
362
TCCR4B = _BV(CS40); \
363
TCCR4C = 0; \
364
TCCR4D = 0; \
365
TCCR4E = 0; \
366
TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
367
OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
368
TC4H = 0; \
369
TCNT4 = 0; \
370
})
371
#if defined(CORE_OC4A_PIN)
372
#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */
373
#elif defined(__AVR_ATmega32U4__)
374
#define TIMER_PWM_PIN 13 /* Leonardo */
375
#else
376
#error "Please add OC4A pin number here\n"
377
#endif
378
379
380
// defines for timer4 (16 bits)
381
#elif defined(IR_USE_TIMER4)
382
#define TIMER_RESET
383
#define TIMER_ENABLE_PWM digitalWrite(3, LOW)
384
#define TIMER_DISABLE_PWM digitalWrite(3, HIGH)
385
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
386
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
387
#define TIMER_INTR_NAME TIMER4_COMPA_vect
388
#define TIMER_CONFIG_KHZ(val) ({ \
389
const
uint16_t pwmval = SYSCLOCK / 2000 / (val); \
390
TCCR4A = _BV(WGM41); \
391
TCCR4B = _BV(WGM43) | _BV(CS40); \
392
ICR4 = pwmval; \
393
OCR4A = pwmval / 3; \
394
})
395
#define TIMER_CONFIG_NORMAL() ({ \
396
TCCR4A = 0; \
397
TCCR4B = _BV(WGM42) | _BV(CS40); \
398
OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
399
TCNT4 = 0; \
400
})
401
#if defined(CORE_OC4A_PIN)
402
#define TIMER_PWM_PIN CORE_OC4A_PIN
403
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
404
#define TIMER_PWM_PIN 6 /* Arduino Mega */
405
#else
406
#error "Please add OC4A pin number here\n"
407
#endif
408
409
410
// defines for timer5 (16 bits)
411
#elif defined(IR_USE_TIMER5)
412
#define TIMER_RESET
413
#define TIMER_ENABLE_PWM digitalWrite(3, LOW)
414
#define TIMER_DISABLE_PWM digitalWrite(3, HIGH)
415
#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
416
#define TIMER_DISABLE_INTR (TIMSK5 = 0)
417
#define TIMER_INTR_NAME TIMER5_COMPA_vect
418
#define TIMER_CONFIG_KHZ(val) ({ \
419
const
uint16_t pwmval = SYSCLOCK / 2000 / (val); \
420
TCCR5A = _BV(WGM51); \
421
TCCR5B = _BV(WGM53) | _BV(CS50); \
422
ICR5 = pwmval; \
423
OCR5A = pwmval / 3; \
424
})
425
#define TIMER_CONFIG_NORMAL() ({ \
426
TCCR5A = 0; \
427
TCCR5B = _BV(WGM52) | _BV(CS50); \
428
OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
429
TCNT5 = 0; \
430
})
431
#if defined(CORE_OC5A_PIN)
432
#define TIMER_PWM_PIN CORE_OC5A_PIN
433
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
434
#define TIMER_PWM_PIN 46 /* Arduino Mega */
435
#else
436
#error "Please add OC5A pin number here\n"
437
#endif
438
439
440
#else // unknown timer
441
#error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
442
#endif
443
444
445
// defines for blinking the LED
446
#if defined(CORE_LED0_PIN)
447
#define BLINKLED CORE_LED0_PIN
448
#define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
449
#define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
450
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
451
#define BLINKLED 13
452
#define BLINKLED_ON() (PORTB |= B10000000)
453
#define BLINKLED_OFF() (PORTB &= B01111111)
454
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
455
#define BLINKLED 0
456
#define BLINKLED_ON() (PORTD |= B00000001)
457
#define BLINKLED_OFF() (PORTD &= B11111110)
458
#else
459
#define BLINKLED 13
460
#define BLINKLED_ON() (PORTB |= B00100000)
461
#define BLINKLED_OFF() (PORTB &= B11011111)
462
#endif
463
464
#endif