Симметричный мультивибратор на ардуино ?
- Войдите на сайт для отправки комментариев
Помогите в написании скетча для функции симметричного мультивибратора. Вот схемма она даволи проста и давно всем извессна: http://www.dessy.ru/include/images/ware/RKT-L01_1.GIF Нужно для одного проекта на ардуино.
Все не так просто как я думал.
В общем нужно что бы мультивибратор работал с частатой 36 кГц (периуд 27 мкСек) и пины D4 и D5 управляли транзисторами n-p-n к колектарам которых подключены 2 света-диода.
В общем все проблемма в том что здесь ну ни как нельзя использовать команды digitalWrite & digitalRead т.к. они медленно работают и это добовляет не нужный мне момент - оба света-диода могут быть выключены. т.е. работает так led1 включен, таймер, led1 & led 2 выключены, затем проходит время 10 мкСек на команду digitalWrite дважды затем led2 включен и led 1 выкл. затем сново эта пауза вызванная командой digitalWrite и все повторяется.
А нужно как в классической схемме в любой момент времени светит только 1 из света-диодов, а затем переключаются.
Наверное стоит почитать :
Управление портами через регистры Atmega
Да спасибо, но это сложно как то, вообще прям затрагивает все порты ввода вывода, когда к ним таким способом обращатся. Но у меня др. выбора нет, буду разбиратся. И еще такой вопрос это правило обсалютно одинаково и для atmega 328, а не только для 168 как в примере?
это правило обсалютно одинаково и для atmega 328, а не только для 168 как в примере?
Не абсолютно, но в данном случае - 328=168.
не нравится прямое обращение к портам - ставьте внешний инвертор. Делов то - резистор+транзистор.
вообще прям затрагивает все порты ввода вывода, когда к ним таким способом обращатся.
Если правильно обращаться, то не затрагивает:
А вот это уже полутше, спасибо.
Только не забывайте, что разные пины висят на разных портах (B, C, D). Соответственно - DDRB/DDRC/DDRD и PORTB/PORTC/PORTD
Да, это я понял, тут вообще путаница может быть, пины свои на чипе , на ардуине свои , программно др. порты, просто голова кругом. :)
Да, номера разные, нужно смотреть распиновку. Набираете в гугле arduino uno pinout (вместо uno подставляете название своей ардуины) и переключаетесь на картинки. Например - https://www.google.com/search?q=arduino+uno+pinout
Кажись получил что хотел, запоралелил сигналы через резисторы на 2,2 киОма и нагрузочный резистор на 4,7 кОма к gnd подключил, к нагрузочному резисотру осциллограф в итооге ровная линия, значет порты переключаются без провалов. Да еще обнаружил какой то бракованный транзистор 1 из 2-х bc547 у одного тэстер показывает 640 коэффициент, а у др. зашкал, у бракованного падение база - эмиттер 1,1 вольта, у рабочего 0,6 вольт. И этот транзистор искажает форму сигнала.
Что или кто мешает подключить транзисторы так, чтобы от ардуины шёл один провод и когда на нём HIGH - один транзистор открыт, а другой- закрыт, а когда LOW, наоборот? Это можно сделать с двумя транзисторами, с одним, а если речь только о светодиодах, то и вовсе без транзисторов. Не знаете как? Нужна схема?
И гловной боли меньше (всего один провод) и переключать можно didgitalWrite - полне хватит скорости.
Да, делал так, но тоже не так работало, скорей всего из - за этого бракованного транзистора. Нужно найти будет 2 нормальных и папробую.
Какая нагрузка-то? Если только светодиоды (ну, типа до 20мА), то транзисторы и вовсе не нужны. А если больше, покажите схему по которой делали. Что там у Вас не получилось - интересно.
В общем нет времени рисовать, попытаюсь объяснить на словах. Есть 1 ИК фото-приемник на 36 кГц и 2 ик - света-диода, которые направленны на этот фото- приемник. Эти ИК света-диоды переключает мультивибратор с несущей частатой 36кГц , если сигнал приходит с двух сразу ИК света-диодов, то логично же что ИК фото-приемник должен реагировать на их как буд то бы на его светят 1 им ИК света-диодом который питается не от импульсов,а от постоянки и таким образом ИК- фото-приемник не миняет свое состояние на выходе в LOW (нормальное состояние HIGH). Но если появляется припятствие на пути одного ИК света-диода, то на ИК - фотоприемник уже приходит импульсное ИК излучение и он начинает свой выход подтягивать в состояние LOW. Далее у меня запущенно внешнее преривание (FALLING) на том входе к которому подключен ИК - фотоприемник. В обработчике преривания определяется какой из этих 2-х света-диодов был включен в это время и тем самым определяется какой из 2-х лучей был пересечен. В общем так работают промышленные счетчики посетителей - внешне они именно так построенны (с одной стороны прохода 1 - ик фота-приемник, а с др. 2 ИК света-диода), вот и догадывайтесь как он работает, а я и догадался. ;)
В общем аказалось что этот ИК фото-приемник реагирует и на постоянное свечение света-диода ИК. Так что так не получится.
Ваше изложение алгоритма не выглядит слишком простым. Проще одним излучателем передавать код, допустим "А", затем делать паузу в доли секунды и в течении её передавать другим излучателем "Б". Как именно кодировать - дело десятое. Тогда с приемника при открытых обоих будет ити "АБАБАБ" и только один код при одном закрытом. Передача, прием и формирование 36КГц из прерывания таймера, 27мксек - не много, но должно хватать.
А через uart вобще просто выходит! ИК излучатели через транзисторные ключи к Tx, но кроме этого в базу каждого еще и строб, для возможности включать только один из них и модулировать на 36кГц. Ну а Rx к приемнику. Вобще примитивщина. Я утратил интерес к вопросу.
Вот и я думаю как кадировать сигнал? Хмм странныйй ик ФП. Может нужно что бы пачки сигнала с несущей частатой 36 кГц шли и частота этих пачек отличалась для 1 ик света-диода и для 2 - ого, а потом нужно как то считать импульсы на выходе ик фотприемника. Я в растерянности. А может подключить библиатеку IR Remote и слать разные коды для 1 Ик светадиода и для др. др. коды, но что то мне подсказывает что ничего не выйдет.
Не выйдет с библиатекой ir remote , тут только к 3 пину может быть подключен ик диод.
Ладно оставлю так https://www.youtube.com/watch?v=vbfXED8Dfuk&t=8s вроде работает, но иногдапропускает и не считает людей. Большинство схемм в интернете по этому же принципу работают. Думаю папробовать с аналоговыми датчиками Sharp, которые на отражение работают, но они дорогие 6 баксов за шт, а нужно 2.
А вообще, зачем вам такой "странный ИК фотоприемник" (TSOP)? Возьмите обычную пару ИК свето- фото- диодов скажем на 940нм .. не подходит? Тоже намучался с ними в свое время - выбросил.
Если нужен именно "мультивибратор", то наверное лучше воспользоваться 2 ногами какого-таймера, поставив их в "противофазу". И период подобрать можно "какой хочешь" (почти) и мега не занята дурным делом..
не.. TSOP к засветкам менее чувствителен. А обычный слепнуть будет. И ловить шопопало.
TSOP совсем для конкретных целей нужен. И чтобы он измерял и вычитал засветки - ему ТАКАЯ подача явно не в тему .. там по даташиту несколько иное управление ваще-то.
Именно.
Какая там подача?! TSOP просто фильтр полосовой имеет, на частоту модуляции ИК. Засветка не модулирована потому и меньше влияет. Ну пока не засветит его до насыщения. Все в общем что нужно знать о TSOP.
Все верно. Но как оказалось есть 2 типа ИК фотоприемников. У некаторых есть даже ограничение на частату передачи данных. А у некоторых нет такого аграничения и вот как раз последний даже реагирует на постоянное (не импульсное) ИК излучение, хотя это ж тупо как то - выходит что полосового фильтра в нем нет.
Ну так и я об чем .. засветка не модулирована, а вот полезный сигнал просто обязан быть модулирован, в этом и есть его разница между ними. Только, тут ТС просит мультивибратор и хочет ОБОИМИ лампами светить в TSOP, что уже не совсем "модуляция" на его частоте, согласны? Вот за это и написал .. нафига такой гемморой.
Да, тупо. может подделка. Мне такое не попадало.
Ну так и я об чем .. засветка не модулирована, а вот полезный сигнал просто обязан быть модулирован, в этом и есть его разница между ними.
угу.
Только, тут ТС просит мультивибратор и хочет ОБОИМИ лампами светить в TSOP, что уже не совсем "модуляция" на его частоте, согласны? Вот за это и написал .. нафига такой гемморой.
Так и я пишу - геморой. И то что собрался автор делать скорей всего на побочных эффектах держится, светят оба излучателя по очереди, а яркость немного разная и направленость разная. Вот приемник и видит модуляцию на своей частоте )))
Так я паапробовал даже взять 1 света-диод и подключить напрямую к источнику питания, в итоге этот ИК ФП увидел этот сигнал. А вот др. ИК ФП просто в момент облучения этим ИК света-диодом на выходе сделал пару импульсов (хотя откуда там импульсы то, ИК излучение было постоянное, должен был быть всего один импульс ) и все состояние вернулось в HIGH.
Ток какой в излучателе? Расстояние? Ну и про TSOP поподробней, который на немодулированом постоянно выдавал 0, наверно левый какой. Может он не TSOP вобще? Есть просто другие фотоприемники, которые в таком же корпусе но без модуляции. И ему соответственно формировать 36КГц безсмыслено.
Так может ТС приведет полноценное описание проблемы с выкладкой фоток, кода и т.д. что там за TSOP, в каком приборе или он чего сам ваяет.. Чего так-то гадать на кофейной гуще? (* да и гуща уже не та пошла..*)
А то может разговор за китайские датчики линии/препятствий на базе TSOP .. так им место в помойке, давно уже выяснено.
Так может ТС приведет полноценное описание проблемы с выкладкой фоток
Не. Фантастика. Как всегда гадаем на кофейной гуще, хрустальном шаре и картах таро ;)
Вот код
#include <TimerOne.h> const int out_ir1 = 4;// выход для управления ИК света-диодом 1 const int out_ir2 = 5;// выход для управления ИК света-диодом 2 #define FQ_IR_RECEIVER 36 //несущая частота (в кГц) с которой работает ИК фото-приемник const int out_led1 = 6;// обычный света-диод для индикации сработки пересечения ИК луча 1 const int out_led2 = 7;// обычный света-диод для индикации сработки пересечения ИК луча 2 const int out_relay = 8;// выход для подключения реле volatile boolean IR_sensor1; //переменная для хранения состояния пересечения ИК луча 1 (если 1 - значет был пересечен, 0 - нормальное состояние) volatile boolean IR_sensor2; //переменная для хранения состояния пересечения ИК луча 2 (если 1 - значет был пересечен, 0 - нормальное состояние) long period_ir_led_switch;// переуд (в микросек) с которым будут переключатся ИК света-диоды будет получен из частоты long start_ir_led_switch; #define DELAY_START 1 //задержка на включение ИК фотоприемника (в сек), дабы исключить ложный счет в момент включения long delay_start_IR_Sensor; boolean IR_on = 0; volatile byte state = 0; int counts = 0; boolean switch_ir_led = 0; void blinkLED(){ //if(PIND == if(switch_ir_led == 0){ PORTD = B00100000 ; //noTone(out_ir2); // tone(out_ir1, 36000); //delayMicroseconds(500); // noTone(out_ir1); //delayMicroseconds(500); switch_ir_led = 1; }else{ PORTD = B00010000 ; //noTone(out_ir1); //tone(out_ir2, 36000); switch_ir_led = 0; } /* digitalWrite(out_ir1, !digitalRead(out_ir1)); digitalWrite(out_ir2, !digitalRead(out_ir2)); */ } void setup() { // pinMode(out_ir1, OUTPUT); //pinMode(out_ir2, OUTPUT); DDRD = DDRD | B11110000;//задает порты 4,5,6,7 как выходы // pinMode(out_led1, OUTPUT); //pinMode(out_led2, OUTPUT); pinMode(out_relay, OUTPUT); //digitalWrite(out_ir1, HIGH); //digitalWrite(out_ir2, LOW); Serial.begin(115200); //period_ir_led_switch = (1/FQ_IR_RECEIVER)*1000 ;// значение периуда в микросекундах (1 с = 1000 милисек = 1 000 000 миксек) period_ir_led_switch = 13;//периуд переключения ик света-диодов в миксек Timer1.initialize(period_ir_led_switch); Timer1.attachInterrupt(blinkLED); //tone(out_ir1, FQ_IR_RECEIVER * 1000); Serial.print(F("Set. period = ")); Serial.println(period_ir_led_switch); start_ir_led_switch = micros(); delay_start_IR_Sensor = millis(); } void sensor (){ if(digitalRead(out_ir1) == LOW && digitalRead(out_ir2) == HIGH)IR_sensor2 = 1; if(digitalRead(out_ir1) == HIGH && digitalRead(out_ir2) == LOW)IR_sensor1 = 1; //========алгоритм определяющий направление движения===================== if(state == 3 && IR_sensor1 == 1){ state = 4; // чел вышел IR_sensor1 = 0; } if(state == 0 && IR_sensor2 == 1){ state = 3; IR_sensor2 = 0; } if(state == 1 && IR_sensor2 == 1){ state = 2;// чел зашел IR_sensor2 = 0; } if(state == 0 && IR_sensor1 == 1){ state = 1; IR_sensor1 = 0; } } void loop() { /* if(micros() > start_ir_led_switch + period_ir_led_switch){ digitalWrite(out_ir1, !digitalRead(out_ir1)); delayMicroseconds(1); digitalWrite(out_ir2, !digitalRead(out_ir2)); start_ir_led_switch = micros(); //Serial.println(F("Generator work")); } */ if((millis() > (delay_start_IR_Sensor + DELAY_START * 1000)) && IR_on == 0){ attachInterrupt(0, sensor, FALLING); IR_on = 1;//ИК фото-приемник включен и преривание для его тоже Serial.println(F("IR recever enabled")); } /* if(IR_sensor1 == 1 && IR_sensor2 == 0){ Serial.println(F("vhod")); } if(IR_sensor1 == 0 && IR_sensor2 == 1){ Serial.println(F("Exit")); } */ /* //========алгоритм определяющий направление движения===================== if(state == 0 && IR_sensor1 == 1){ state = 1; IR_sensor1 = 0; //attachInterrupt(0, sensor, RISING); } if(state == 1 && IR_sensor2 == 1){ state = 2;// чел зашел IR_sensor2 = 0; //attachInterrupt(0, sensor, RISING); } if(state == 0 && IR_sensor2 == 1){ state = 3; IR_sensor2 = 0; //attachInterrupt(0, sensor, RISING); } if(state == 3 && IR_sensor1 == 1){ state = 4; // чел вышел IR_sensor1 = 0; // attachInterrupt(0, sensor, RISING); } //========================================================================= */ //======= счетчик людей в помещении ================================ if(counts < 0)counts = 0; // обнуляем отрицательные значения if(state == 2){ counts = counts + 1; state = 0; Serial.print(F("Counts = ")); Serial.println(counts); } if(state == 4){ counts = counts - 1; state = 0; Serial.print(F("Counts = ")); Serial.println(counts); } //=================================================================== /* if(counts > 0){ digitalWrite(out_relay, HIGH); }else{ digitalWrite(out_relay, LOW); } */ delay(1); }Схема https://yadi.sk/d/XEj04n1q3HruC3
Тока через излучатели мало, по докам там сотни мА. Ну и по приемнику понятно что ничего по прежнему непонятно.
Ик фотоприемника 3 разных:
1. simens 614 sfh 506-36
2. hl 536AA3P (этот уникальный, способен удерживать уровень low при непреривном облучении несущей частатой).
3. tk 69 105 tsop 1736
На hl 536AA3P и даташит не находится, алах его знает, что оно там такое. А на прямой солнечній свет если сунуть, тоже LOW?
Вернувшись к вопросу
Вот и я думаю как кадировать сигнал? Хмм странныйй ик ФП. Может нужно что бы пачки сигнала с несущей частатой 36 кГц шли и частота этих пачек отличалась для 1 ик света-диода и для 2 - ого, а потом нужно как то считать импульсы на выходе ик фотприемника. Я в растерянности.
Можна 2-я путями. Лучше через uart.
схема дето так.
логика работы следующая. В покое PinA и PinB HIGH. Для передачи по LED1 на PinB выводим частоту 36кГц, в Serial отправляем например "B". Затем возвращаем PinB в HIGH. Выводим частоту 36кГц на PinA в Serial отправляем например "А". После отправки возвращаем PinА в HIGH. Принимаем из Serial. Если приняли "BА" - открыты оба излучателя, если только один - будет один соответствующий символ.
Диоды на схеме - лучше шотке. Марку транзисторов забыл удалить, левые попали, там по сути любые pnp только чтоб ток в ИК обеспечивали.
В общем удалось пока разделить 3 состояния:
1. если преград нету то на выкоде ик фп прямоугольные импульсы с частатой 460 Гц,
2. если пересечен один из лучей частота импульсов около 100 гц
3. если оба луча пересечены то на выходе уровень HIGH
Но как это использовать?
А сделал следующее с помощью timer1 сначало излучает 1 сета-диод несущую частоту 36 кГц, затем чере 14 мкСек * 77 пауза равная 14 мкСек * 77 , затем излучает 2-ой света-диод несущую частоту излучает длинною 14 мкСек * 77, затем сново пауза 14 мкСек * 77 и все повторяется.
Но как измерять частоту на выходе ИК ФП?
Вот вот, рождается истина, закодировал оба луча, отслеживатся будет по цифравому шим сигналу (длительность состояние уровня LOW: кароткая - логический 0, длинная - единица).
теперь таким образом получаем раздельные состояния:
1. если пересечено 2 луча, ни как не реагирует уровень HIGH на выходе ИК ФП.
2. если поступает последовательность логических 0, 1, 0, 1, 0, 1 значет приходят оба луча
3. если поступает последовательность 0, 0, 0, 0, 0 , то пересечен 1 - ый лучь
4. если поступает последовательность 1,1, 1, 1 , то пересечен 2-ой лучь
осталось все это как то связать в обработчик внешних прериваний, что бы в нем запускался таймер на millis() и считал длительность LOW, но может ли millis() работать с внешним прериванием?
Надо папробовать, интересно, даже, долетит ли по ИК сообщение с сериал порта. :)
Скорей всего модулятор должен выглядеть вот так: https://yadi.sk/d/D23IRP_t3HsLea Круто, проверил, (пока только на 1 канале) моя схема модулятора работает, передает данные по ИК. Максимальная скорость 2400 бод, оптимальная 1200 бод. :) Я даже не верил в это, но оно работает.
Почему не работает Эхо сигнал через софт сериал?
#include <SoftwareSerial.h> SoftwareSerial mySerial(6, 7); // RX, TX char inByte = 0; void setup() { Serial.begin(115200); delay(100); mySerial.begin(1200); } void loop() { mySerial.print(F("Echo test soft serial")); mySerial.listen(); while(mySerial.available() > 0){ inByte = mySerial.read(); Serial.write(inByte); Serial.println(); } delay(100); }Вот замкнул друг с другом потры rx и tx софтсериал и то что прилетает в софт сериал, пытаюсь отправить в аппаратный сериал, в итоге нечего нет. С аппаратным портом такое проходит нормально.
Не удивлен. Софт сириал дурной на всю голову, я его проклял в теме про gsm модем А6. Там в прерывании оно блокирующее ((( Соответственно либо передаем, либо принимаем. А одновременно - фиг. Вот он сам себя и не принимает.
Дааа я так и предпологал и старался это Г... не трогать и метровой палкой. Построил на аппаратном пока, работает как задуманно, я удивлен таким нестандартным использованием сериал порта с моим модулятором ИК. :)
Сейчас папробую тоже самое провернуть с библиотекой IRremote но думаю тут будет тоже Г как и с софтсериал портом. :)
Цепляйте на аппарвтный сириал. Я потом так и поцепил модем к нане. Оно конечно не совсем по стандарту на uart но если не работают одновременно два Tx на один Rx то нормально. С модема Tx через диод подключил. И шется и с модема принимает нормально.
Вот схемма: https://yadi.sk/d/8eYcmR873HuvSx
Скетчь
//#include <SoftwareSerial.h> //SoftwareSerial mySerial(10, 11);// RX, TX //ИК Фото-приемник подключен к Rx аппаратного serial port // модулятор ИК-света-диодов подключен к Tx аппаратного serial port (оба канала А и В запоралелены через резисторы на 2 кОм). const int IR_LED1 = 4; //ИК света-диод const int IR_LED2 = 5; //ИК света-диод const int Led1 = 6;//света-диод отображающий сработку луча А const int Led2 = 7;//света-диод отображающий сработку луча В const int Led3 = 8;//света диод определяющий направление последнего движения const int Led4 = 9;//света диод определяющий направление последнего движения int counts = 0; char data1; char data2; bool luch_A = 0;//флаг хронящий пересечение луча, если 0 - лучь пересечен, 1 - не пересечен bool luch_B = 0;//флаг хронящий пересечение луча, если 0 - лучь пересечен, 1 - не пересечен byte state = 0;// состоянии для определения направления движения void setup() { Serial.begin(2400); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } pinMode(IR_LED1, OUTPUT); pinMode(IR_LED2, OUTPUT); pinMode(Led1, OUTPUT); pinMode(Led2, OUTPUT); pinMode(Led3, OUTPUT); pinMode(Led4, OUTPUT); //mySerial.begin(9600); delay(100); } void loop() { //Опрашиваем лучь А tone(IR_LED1, 36000);// старт генератора несущей частоты Serial.print('A');//отправляем данные if(Serial.available() > 1){//если данные получены data1 = Serial.read();// читаем их в буфер data } if(data1 == 'A'){// если данные из буфера получили те что отправляли luch_A = 1;// значет лучь А не пересечен }else{//иначе luch_A = 0;//лучь А пересечен } //data = 0; //опрашиваем луч В noTone(IR_LED1);//останавливаем генератор несущей частоты //delayMicroseconds(100); tone(IR_LED2, 36000);// старт генератора несущей частоты Serial.print('M');//отправляем данные if(Serial.available() > 1){//если данные получены data2 = Serial.read();// читаем их в буфер data } if(data2 == 'M'){// если данные из буфера получили те что отправляли luch_B = 1;// значет лучь А не пересечен }else{//иначе luch_B = 0;//лучь А пересечен } // data = 0; noTone(IR_LED2);//останавливаем генератор несущей частоты if(state == 0 && luch_A == 1 && luch_B == 0){ state = 1; //mySerial.print(F("State = ")); // mySerial.println(state); } if(state == 1 && luch_A == 1 && luch_B == 1){ state = 2; // чел зашел } if(state == 2 && luch_A == 0 && luch_B == 0){ state = 5; } if(state == 0 && luch_B == 1 && luch_A == 0)state = 3; if(state == 3 && luch_B == 1 && luch_A == 1){ state = 4; //чел вышел } if(state == 4 && luch_A == 0 && luch_B == 0){ state = 6; } //mySerial.print(F("State = ")); //mySerial.println(state); if(state == 5){ counts = counts + 1; state = 0; //mySerial.print(F("Counts = ")); //mySerial.println(counts); digitalWrite(Led3, HIGH); digitalWrite(Led4, LOW); } if(state == 6){ counts = counts - 1; state = 0; // mySerial.print(F("Counts = ")); //mySerial.println(counts); digitalWrite(Led3, LOW); digitalWrite(Led4, HIGH); } if(luch_A == 1){ digitalWrite(Led1, HIGH); }else{ digitalWrite(Led1, LOW); } if(luch_B == 1){ digitalWrite(Led2, HIGH); }else{ digitalWrite(Led2, LOW); } }К сожалению нет подходящего дисплея что бы выводить колличество, папробовал выводить в софт сериал порт, но начинает глючить, путает иногда направление движения и вместо того что бы убавить на 1 колличество, наоборот прибовляет, пока зделал еще 2 доп. света-диода, которые отображают последнее направление движения и походил туда - сюда, вроди переключаются (направление).
Проверьте у себя (колличество), может есть дисплейчик с i2c.