Программа для ИК пульта

AlexSH
Offline
Зарегистрирован: 28.02.2018

Здравствуйте. Передо мной встала не очень стандартная задача - нужно сделать ИК пульт для фотоаппарата на ардуино. Сложность для меня в том, чтобы выставить частоту заполнения (несущую частоту) в 38.4 КГц. Представляю, что это можно сделать с помощью ШИМ, но не понимаю как именно. Так вот, программа должна включать ИК светодиод, моргающий с такой частотой на определенные промежутки времени. Вопрос: как это реализовать?  Может быть делать такой проект на ардуино нецелесообразно, но других вариантов для меня сейчас нет, так что сильно не ругайтесь. 

SLKH
Offline
Зарегистрирован: 17.08.2015

AlexSH пишет:

Здравствуйте. Передо мной встала не очень стандартная задача - нужно сделать ИК пульт для фотоаппарата на ардуино. Сложность для меня в том, чтобы выставить частоту заполнения (несущую частоту) в 38.4 КГц. Представляю, что это можно сделать с помощью ШИМ, но не понимаю как именно. Так вот, программа должна включать ИК светодиод, моргающий с такой частотой на определенные промежутки времени. Вопрос: как это реализовать?  

Например, так: tone(pin, 38400, duration).

Пробовал набрать в гугле "ик-пульт на ардуино" или что-то близкое? и получить тысячи готовых решений твоей сверхоригинальной нестандартной задачи?

vvadim
Offline
Зарегистрирован: 23.05.2012

вы бы более подробно и внятно описали свою задачу в разделе "Ищу исполнителя".
там хоть за денежку кто то, может быть, возмётся.

не забудьте указать контактные данные.

в этом разделе для вас будет только флуд или стёб.

AlexSH
Offline
Зарегистрирован: 28.02.2018

Замечу, я не прошу написать программу, это я сделаю самостоятельно. Я лишь прошу подсказать, как можно выставить такую частоту 38.4КГц.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

AlexSH пишет:
Я лишь прошу подсказать, как можно выставить такую частоту 38.4КГц.

Вот здесь есть обязснения, примеры и скетч калькулятора частоты - http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-blink-i-bez-delay-i-bez-millis

AlexSH
Offline
Зарегистрирован: 28.02.2018

Ну если я пишу на форум, значит пробовал и не нашел. Там одни ИК модули с пультами и программы с библиотекой IRremote. Я попробовал с tone но не могу выключить светодиод, то есть он моргает постоянно с частотой 38400Гц. Пробовал noTone на другой пин - не помогает.

Вот код на спуск затвора. Что тут не так?

void setup() {
pinMode(13, OUTPUT);
}
void loop() {
tone(13, 38400, 2);
noTone(7);
delay(27.8);
tone(13, 38400, 0.4);
noTone(7);
delay(1.6);
tone(13, 38400,0.4);
noTone(7);
delay(3.6);
tone(13, 38400,0.4);
noTone(7);
delay(1000);
}

 

b707
Offline
Зарегистрирован: 26.05.2017

 чего вам пришла идея подавть noTone() на другой пин?? - чтобы выключить, надо подавать на тот же.

Кроме того, что это за дробные делеи у вас в скетче? Делеи могут быть только целыми, как и длительность сигнала Tone(третий параметр в скобках)

vk007
Offline
Зарегистрирован: 16.06.2015

Кроме использования нецелых чисел и разных пинов, разве tone() приостанавливает выполнение программы??? У вас сразу после tone() следует noTone().

AlexSH
Offline
Зарегистрирован: 28.02.2018

Значит я не так понял описание команда tone.  Написано, что noTone прекращает подачу сигнала на пин. А почему дилеи дробные, показано на картинке. Не знаю, как по другому сделать.bd6b6d98e7da4b49af0fc7f0ef368c48.jpg

b707
Offline
Зарегистрирован: 26.05.2017

AlexSH пишет:

 А почему дилеи дробные, показано на картинке. Не знаю, как по другому сделать.

Tone не умеет работать с дробными длительностями, так что эта функция для ваших целей не подойдет. Вам придется писать генератор 38.4 КГц самому - посмотрите ссылку, которую выше давал ЕвгенийП

AlexSH
Offline
Зарегистрирован: 28.02.2018

Я и по этой схеме пробовал. Та же проблема. Горит постоянно. Частоту я настроить смог, но видимо дробные дилеи всё портят.

enum Prescalers {
  PRESCALER_1 = 1, PRESCALER_8 = 2, PRESCALER_64 = 3, PRESCALER_256 = 4, PRESCALER_1024 = 5
};

void setup() {
  uint8_t prescaler = PRESCALER_1;
  uint16_t topValue = 207;
  pinMode(9, OUTPUT);
  TCCR1A = 0x40;      // Инвертирование пина 9 по сравнению
  TCCR1B = 0x08 | prescaler;  // Установить СТС режим и делитель частоты
  OCR1A = topValue;   // установить TOP равным topValue
}

void loop() 
{
  digitalWrite(9,HIGH);
  delay(2);
  digitalWrite(9,LOW);
  delay(27.8);
  digitalWrite(9,HIGH);
  delay(0.4);
  digitalWrite(9,LOW);
  delay(1.6);
    digitalWrite(9,HIGH);
  delay(0.4);
  digitalWrite(9,LOW);
  delay(3.6);
  digitalWrite(9,HIGH);
    delay(0.4);
 digitalWrite(9,LOW);
     delay(1000);
    }

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

delay() не могут быть дробными, только целые числа в миллисекундах. Если нужно разрешение меньше миллисекунды, для этого есть delayMicroseconds() в микроосекундах.

vk007
Offline
Зарегистрирован: 16.06.2015

delay() не подойдет, но подойдет delayMicroseconds() и вызывать tone() без указания длительности, а глушить его noTone(), опять же используя для указания задержки delayMicroseconds(). Для длинных пауз (длиннее 16 мс) попробовать воспользоваться комбинацией из delay() и delayMicroseconds().

b707
Offline
Зарегистрирован: 26.05.2017

похоже, что вы не поняли статьи Евгения по ссылке. Зачем вы в loop() включаете и выключаете пин 9? - Пин 9 у вас управляется таймером, сконфигурированным в setup и меняет значения с частотой 38 КГц. А вы в него digitalWrite тычете...

Чтобы прекратить генерацию сигнала таймером, нужно переключить его режим.

Отключить генерацию - TCCR1A = 0x00;

включить обратно - снова TCCR1A = 0x40;

Для того, чтобы задавать задержки, некратные миллисекундам - есть функция delaymicroseconds()

 

SLKH
Offline
Зарегистрирован: 17.08.2015

b707 пишет:

AlexSH пишет:

 А почему дилеи дробные, показано на картинке. Не знаю, как по другому сделать.

Tone не умеет работать с дробными длительностями, так что эта функция для ваших целей не подойдет. Вам придется писать генератор 38.4 КГц самому - посмотрите ссылку, которую выше давал ЕвгенийП

непонятно, зачем писать генератор? чем готовая функция tone() не устраивает?

и ещё: если ТС с tone() не справляется, этично ли предлагать ему "TCCR1A &= ~0xC0" ?

 

 

AlexSH
Offline
Зарегистрирован: 28.02.2018

Спасибо всем, кто помог! Проблема решена, камера реагирует. На всякий случай выкладываю код, может кому-нибудь понадобится. Подходит для всех аппаратов марки Nikon, имеющих ИК порты. Код только на спуск затвора (с фокусировкой).

void setup() {
  pinMode(9, OUTPUT);
}
void loop() {
tone(9, 38400);
delayMicroseconds(2000);
noTone(9);
delayMicroseconds(800);
delay(27);
tone(9, 38400);
delayMicroseconds(400);
noTone(9);
delayMicroseconds(1600);
tone(9, 38400);
delayMicroseconds(400);
noTone(9);
delayMicroseconds(3600);
tone(9, 38400);
delayMicroseconds(400);
noTone(9);
delay(27);
}