Можно было разделить по функциям но я боялся за размер скетча.
Кстати сейчас заметил, если я уменьшаю переменную long intervalRED = 600000; на 100000, всё работает.
Не могу понять почему?
Имхо надо искать косяки с переполнением.
Хорошую вам аналогию провели с смешались в кучу кони люди... Вы опять смешиваете сигнед и ансигнед. Если память мне не изменяет, в выражениях все приводится к сигнед, если есть хоть один сигнед.
Поэтому у вас и идёт переполнение имхо.
Кстати, в тини ядре акая точность сигнед Лонга?
Хотя опять же посмотрел, вроде и не должно быть переполнение. Вся проблема Атмелов, что никакой отладки нет, поэтому я и перешёл на стм8.
Кстати, вы экономите память, при этом очень расточительно ее используете на константы, которые могут быть прописаны в коде (interval red interval green), зачем вам две переменые lastMilis? Они разве различаются? Зачем два раза вызвать функцию, которая по сути должна вернуть одно и тоже? При инициализации портов вы можете вместо 4х строчек записать 2, так как настройка идёт одного порта, а не нескольких.
Активнее используйте макросы, это облегчает чтение кода не изменяя эффективность.
И я так понял светодиоды ут вас включены по разному? Проверьте, красный светодиод ут вас вообще управляется? Т.е в аппаратной части проблем нет?
Zahar, если я вам скажу, что компилятор умнее ,как правило, всех программистов, которые пишут программы. Вы мне поверите. Так вот чаще всего все эти действия которые вроде должны уменьшить код, код не уменьшают, а запутывают и увеличивают размер скетча. Так что не бойтесь добавлять лишние функции. Лишее и ненужное компилятор отбросит. Но компилятор еще не очень умный, что бы исправлять ну очень кривой код.
Иногда и элементарных вещей компилятор не видит, пока ему не подскажешь.
Скорее обратное. Человек который программирует не видит варианты. А когда компилятор показывает этот вариант, человек говорит, компилятор ты дурак, я имел здесь совершено другое. Та же аналогия: заказчик программист. Заказчик говорит делай то и это. А если то и это сделано, то "тупой программист" просто не понял заказчика. "Тупой программист" не знает "элеметарных вещей" :)
Ну мы примерно одно и тоже сказали: человек-программист не смог объяснить компилятору, что он от него хочет получить. Проблема скудности языка человека. Так и люди могут друг друга не понимать из-за костноязычности. Поэтому компилятору приходится дополнительно подсказывать, уточнять, что же хотел программист.
Я понимаю что между началом IF и следующим оператором присваивания
миллис может немножко изменится,
но не до такой-же степени точность вам нужна в ущерб размеру кода.
обсалютно одно и тоже. На размер скетча никак не влияет.
Вот именно, что на размер компилированного кода не влияет, но значительно упрощает чтение и понимание кода, его сопровождение и модификацию. Ты думаешь тут всем очень и интересно разбираться с магическими числами? Кстати, позволяет сильно сократить количество ошибок, особенно при модификации или переносе кода.
Ну и интересно, заработало у вас? Вы в комментах пишите 1 минута, но 600000 это 10 минут. Так работает ты выдержка, которая вначале не работала?
Подскажите у всех правильно работает функция delay();? У меня к примеру delay(1000); не равна секунде, а длиннее процентов на 20-30. В чём может быть проблема?
Attiny без внешнего кварц сильно не стабилен, в ДШ написано насколько, но 20....30 процентов что то не вериться - откуда цифры? Реальный скетч замера для проверки есть?
это совершенно нормально. Более того, так и должно быть. Пишите свой delay(), если есть желание.
millis - точнее, лучше прямо ovrf используйте, чтобы умножение к коду не приклеилось.
вот только что у себя посмотрел - по секундомеру - 10 мин, по тиньке - 428 сек ;) ;) ;).
Че то не верится в такую разницу - может частоты не те стоят? Уж не первый проект на attiny рисую - нет такой большой разницы - в будние дни после праздников проверю из любопытства
Я же написал, что дело не в генераторе, а в самой функции delay() в ядре тиньки. Если считать задержку через millis(), то там все нормально, в пределах 2-3%. Причем это НАПИСАНО в самой wiring.c, аглицким по белому в "todo". Есть желание - меняйте. У меня есть своя реализация.
========================
void delay(unsigned ms){
while(ms--){
_delay_ms(1); //Using the libc routine over and over is non-optimal but it works and is close enough
}//Note, I may have to reimplement this because the avr-libc delay is too slow *todo*
}
Подскажите у всех правильно работает функция delay();? У меня к примеру delay(1000); не равна секунде, а длиннее процентов на 20-30. В чём может быть проблема?
Вот этим регистром можно корректировать частоту МК.
К Attiny13 вобще можно кварц подцепить? В даташите по английски да еще так мутно написано, я ничего не понял. В даташите на Atmega328 все четко написано с какой частотой кварцы можно ставить и какой емкости конденсаторы к ним и еще схема нарисована куда все подсоединять.
500mA Высокая Эффективность 0.8-3.3 В до 3.3 В УГФ Step-up Dc-dc для ds18b20 dht22 STM32 FPGA CPLD Питания http://s.aliexpress.com/ZVFbUvu2?fromSns=Copy to Clipboard
(from AliExpress Android)
Радиомодуль самый дешёвый, качество отвратительное, но с антенной на несколько метров пробивает.
433 мГц РФ передатчик и приемник Ссылка Комплект для Arduino/arm/MCU WL хорошее качество http://s.aliexpress.com/i2YbInU7?fromSns=Copy to Clipboard
(from AliExpress Android)
С дуру взял ещё подороже супергетеродинный, думал сильно лучше, но ошибся, самое противное - у него было большое потребление, а пин выключения напрямую включён - пришлось на модуле отрывать ножку у чипа и припаивать на attiny85, что бы так же загонять радиомодуль в сон
Радиомодуль самый дешёвый, качество отвратительное, но с антенной на несколько метров пробивает.
433 мГц РФ передатчик и приемник Ссылка Комплект для Arduino/arm/MCU WL хорошее качество http://s.aliexpress.com/i2YbInU7?fromSns=Copy to Clipboard
(from AliExpress Android)
Andy, добрый день. Судя по Вашим словам, используете супергетеродин на 433 МГц, без применения библиотек типа WirtualWire и у Вас все работает? Ну Вы шаман, однако. Поделитесь, как подбирали длину антенны, ставили ли противовес и какую дальность передачи получили? Мой опыт - всего порядка 15 метров в городе в здании. При этом антенна - штырь в четверть волны.
я не шаман, а как и все начинающие ардуинщики - копипастер :) , тут пару страниц назад есть ссылка на источник, откуда скетч взят, я уже доработал для своих нужд.
никаких подборов длин антен, на передатчик - кусок провода метровой длины, на приемник - спиралька сантиметров 10, радиус действия метров 5 в помещении максимум - мне больше не нужно - просто повесить градусник на улице за окном.
Все понятно, просто звучали тут восторженные возгласы и цифры под километр, вот это меня и ввело в заблуждение. Тогда могу и посоветовать погуглить в сторону библиотеки WirtualWire. Обещают хорошую устойчивость к помехам. Сам не пробовал, т.к. пишу не на ардуино, а адаптировать библу было лень. Сделал т просто широтной-импульсный сигнал частотой 1кгц. На стороне приема rc-цепь и компаратор на транзисторе вроде. Мне надо было передавать 1 бит только. Работало, но иногда были сбои. Потом отказался вообще от вчрф, т.к. заказчик изменил ТЗ.
Все понятно, просто звучали тут восторженные возгласы и цифры под километр, вот это меня и ввело в заблуждение. Тогда могу и посоветовать погуглить в сторону библиотеки WirtualWire. Обещают хорошую устойчивость к помехам. Сам не пробовал, т.к. пишу не на ардуино, а адаптировать библу было лень. Сделал т просто широтной-импульсный сигнал частотой 1кгц. На стороне приема rc-цепь и компаратор на транзисторе вроде. Мне надо было передавать 1 бит только. Работало, но иногда были сбои. Потом отказался вообще от вчрф, т.к. заказчик изменил из.
что использовать всегда зависит от поставленной задачи.
VirtualWire на AtTiny запистить не смог - не стабильно работает - при уходе МК в спящий режим - потом уже не всегда передает данные.
Просто интересно, батарейка сильный мороз выдерживает?
Сам мечтаю сделать внешний термометр без проводов, но вижу его немного иначе. Батарейка, МК и передатчик в помещении, а датчик на улице, соединенный коротким проводком.
Zahar, почему вы все тащите в одну кучу. Или все же принцип разделяй и властвуй уже отменили
Что вы имеете в виду?
А что, с Новым годом поздравлять уже не принято? Ауууу. С Новым годом, ребята!
. Как вариант, высокоомный делитель в половину опорного и его смещать в плюс и минус. Прокатит?
А питание операционных усилителей двуполярное?
По идее должно работать, но на практике обычно на два разных входа ацп заводят.
/**/ //-красный светодиод------------------------------ //--зеленый светодиод-------------------------------- void setup() { //-красный светодиод------------------------------ //--зеленый светодиод-------------------------------- } void loop() { //-красный светодиод------------------------------ //--зеленый светодиод-------------------------------- } /**/А у вас Бородино
/**/ /*смешались в кучу кони люди*/ void setup() { /*смешались в кучу кони люди*/ } void loop() { /*смешались в кучу кони люди*/ } /**/Можно было разделить по функциям но я боялся за размер скетча.
Кстати сейчас заметил, если я уменьшаю переменную long intervalRED = 600000; на 100000, всё работает.
Не могу понять почему?
Можно было разделить по функциям но я боялся за размер скетча.
Кстати сейчас заметил, если я уменьшаю переменную long intervalRED = 600000; на 100000, всё работает.
Не могу понять почему?
Имхо надо искать косяки с переполнением.
Хорошую вам аналогию провели с смешались в кучу кони люди... Вы опять смешиваете сигнед и ансигнед. Если память мне не изменяет, в выражениях все приводится к сигнед, если есть хоть один сигнед.
Поэтому у вас и идёт переполнение имхо.
Кстати, в тини ядре акая точность сигнед Лонга?
Хотя опять же посмотрел, вроде и не должно быть переполнение. Вся проблема Атмелов, что никакой отладки нет, поэтому я и перешёл на стм8.
Кстати, вы экономите память, при этом очень расточительно ее используете на константы, которые могут быть прописаны в коде (interval red interval green), зачем вам две переменые lastMilis? Они разве различаются? Зачем два раза вызвать функцию, которая по сути должна вернуть одно и тоже? При инициализации портов вы можете вместо 4х строчек записать 2, так как настройка идёт одного порта, а не нескольких.
Активнее используйте макросы, это облегчает чтение кода не изменяя эффективность.
И я так понял светодиоды ут вас включены по разному? Проверьте, красный светодиод ут вас вообще управляется? Т.е в аппаратной части проблем нет?
Zahar, если я вам скажу, что компилятор умнее ,как правило, всех программистов, которые пишут программы. Вы мне поверите. Так вот чаще всего все эти действия которые вроде должны уменьшить код, код не уменьшают, а запутывают и увеличивают размер скетча. Так что не бойтесь добавлять лишние функции. Лишее и ненужное компилятор отбросит. Но компилятор еще не очень умный, что бы исправлять ну очень кривой код.
Иногда и элементарных вещей компилятор не видит, пока ему не подскажешь.
Прошу прощения, дубль пошел. Значит поздравим всех с наступившим новым годом!
Скорее обратное. Человек который программирует не видит варианты. А когда компилятор показывает этот вариант, человек говорит, компилятор ты дурак, я имел здесь совершено другое. Та же аналогия: заказчик программист. Заказчик говорит делай то и это. А если то и это сделано, то "тупой программист" просто не понял заказчика. "Тупой программист" не знает "элеметарных вещей" :)
Ну мы примерно одно и тоже сказали: человек-программист не смог объяснить компилятору, что он от него хочет получить. Проблема скудности языка человека. Так и люди могут друг друга не понимать из-за костноязычности. Поэтому компилятору приходится дополнительно подсказывать, уточнять, что же хотел программист.
Прислушался к вашим наставлениям.
Вот что получилось
unsigned int previousMillisGREEN = 0;// храним время последнего переключения светодиода unsigned long previousMillisRED = 0; unsigned int intervalGREEN = 1000; // интервал между включение/выключением светодиода (1 секунда) unsigned long intervalRED = 600000;// интервал между включение/выключением светодиода (10 секунд) void setup() { DDRB = 0b00010001; // PB0,PB4 - выходы PORTB = 0b00000001; //PB0 - ON PB4-ON } void loop() { red(); green(); } void red(){ unsigned long currentMillisRED = millis(); if(currentMillisRED - previousMillisRED > intervalRED) {//интервал для красного леда, если прошел то previousMillisRED = currentMillisRED; PORTB &= ~(1<<0);//Красный выкл } } void green(){ unsigned int currentMillisGREEN = millis(); if(currentMillisGREEN - previousMillisGREEN > intervalGREEN) {//интервал для зелёного леда, если прошел то previousMillisGREEN = currentMillisGREEN; // сохраняем время последнего переключения PORTB ^= 0b00010000; // Инвертирование на выходе PB4 } }Кстати если кому то интересно что это вообще такое, это USB паяльник, купил его на ибеи.
По закону подлости как только купил сразу проверил его, паяльник работал.
Только он мне понадобился, естественно он перестал работать.
Решил поменять всю внутреннею начинку.
Я только не совсем понял смысл использования переменной currentMillisRED,
а также currentMillisGREEN.
unsigned long currentMillisRED = millis(); if(currentMillisRED - previousMillisRED > intervalRED) { previousMillisRED = currentMillisRED;А если просто так:
if(millis() - previousMillisRED > intervalRED) { previousMillisRED = millis();Я понимаю что между началом IF и следующим оператором присваивания
миллис может немножко изменится,
но не до такой-же степени точность вам нужна в ущерб размеру кода.
Вот блин, столько всего написал и сбой прошел... Ладно, ещё чего нибудь другого напишу.
Вообще, лучше сделать Миллс статической глобальной (чтобы убрать лишние вызов функций). И обновлять ее в каждой итерации loop.
Далее, чтобы в каждом цикле не производить излишне арифметические операции, я бы сделал так:
Ulong nextRED = currentMillis+intervalRED // выполняется в setup
if (currentMillis > nextRED)
{nextRED += intervalRED;
PORTB ^= (1<<RED);}
Ах, да, забыл написать то что слетело из-за сбоя:
#define RED 0
#define GREEN 4
#define intervalRED 1000
#define intervalGREEN 600000
setup()
{
currentMillis = millis();
DDRB = (1<<RED)&(1<<GREEN)
...
}
Я только не совсем понял смысл использования переменной currentMillisRED,
а также currentMillisGREEN.
Да наверное ты прав, я брал это из примеров не особо задумываясь для чего нужна эта переменная.
DDRB = (1<<RED)&(1<<GREEN)
это DDRB = 0b00010001; // PB0,PB4 - выходы
обсалютно одно и тоже. На размер скетча никак не влияет.
DDRB = (1<<RED)&(1<<GREEN)
это DDRB = 0b00010001; // PB0,PB4 - выходы
обсалютно одно и тоже. На размер скетча никак не влияет.
Вот именно, что на размер компилированного кода не влияет, но значительно упрощает чтение и понимание кода, его сопровождение и модификацию. Ты думаешь тут всем очень и интересно разбираться с магическими числами? Кстати, позволяет сильно сократить количество ошибок, особенно при модификации или переносе кода.
Ну и интересно, заработало у вас? Вы в комментах пишите 1 минута, но 600000 это 10 минут. Так работает ты выдержка, которая вначале не работала?
DDRB = (1<<RED)&(1<<GREEN)
это DDRB = 0b00010001; // PB0,PB4 - выходы
обсалютно одно и тоже. На размер скетча никак не влияет.
Это абсолютно разные выражения. Команда (1<<RED)&(1<<GREEN) полностью обнулит регистр.
Да-да, правильно надо ИЛИ
(1<< RED)|(1<< GREEN)
Прошу прощения за невнимательность, большую часть внимания отвлекается на набор текста на телефоне.
Как убрать автоисправитель? В редакторе комментариев нет bb кодов.
Подскажите у всех правильно работает функция delay();? У меня к примеру delay(1000); не равна секунде, а длиннее процентов на 20-30. В чём может быть проблема?
Attiny без внешнего кварц сильно не стабилен, в ДШ написано насколько, но 20....30 процентов что то не вериться - откуда цифры? Реальный скетч замера для проверки есть?
Я не программист, только начал. Сделал цикл задержки на 10 минут
for (diod=1; diod <=600; diod++){
digitalWrite(4,HIGH);
delay(500);
digitalWrite(4,LOW);
delay(500); }
И заметил, что светодиод как то медленно мигает. Замерил по секундомеру, этот цикл выполняется за 13 с лишним минут. Это норма?
это совершенно нормально. Более того, так и должно быть. Пишите свой delay(), если есть желание.
millis - точнее, лучше прямо ovrf используйте, чтобы умножение к коду не приклеилось.
вот только что у себя посмотрел - по секундомеру - 10 мин, по тиньке - 428 сек ;) ;) ;).
это совершенно нормально. Более того, так и должно быть. Пишите свой delay(), если есть желание.
millis - точнее, лучше прямо ovrf используйте, чтобы умножение к коду не приклеилось.
вот только что у себя посмотрел - по секундомеру - 10 мин, по тиньке - 428 сек ;) ;) ;).
Че то не верится в такую разницу - может частоты не те стоят? Уж не первый проект на attiny рисую - нет такой большой разницы - в будние дни после праздников проверю из любопытства
Считайте фьюзы и посмотрите, какая тактовая частота выставлена. И сверьте её с тактовой частотой в boards.txt для этого микроконтроллера.
Блин! Коллеги!
Я же написал, что дело не в генераторе, а в самой функции delay() в ядре тиньки. Если считать задержку через millis(), то там все нормально, в пределах 2-3%. Причем это НАПИСАНО в самой wiring.c, аглицким по белому в "todo". Есть желание - меняйте. У меня есть своя реализация.
========================
void delay(unsigned ms){ while(ms--){ _delay_ms(1); //Using the libc routine over and over is non-optimal but it works and is close enough }//Note, I may have to reimplement this because the avr-libc delay is too slow *todo* }это совершенно нормально. Более того, так и должно быть. Пишите свой delay(), если есть желание.
millis - точнее, лучше прямо ovrf используйте, чтобы умножение к коду не приклеилось.
вот только что у себя посмотрел - по секундомеру - 10 мин, по тиньке - 428 сек ;) ;) ;).
Да, я так и подобрал у меня 10 минут равно 457 секунд. Я не разбираюсь, но чем выше я ставлю тактовую частоту в tiny, тем медленнее работает delay().
В общем всем спасибо! Тема закрыта.
Ну и интересно, заработало у вас? Вы в комментах пишите 1 минута, но 600000 это 10 минут. Так работает ты выдержка, которая вначале не работала?
1) Да все заработало.
2) В посте выше в коментах написано 10минут.
3) Скажите пожалуйста, почему я не получаю сообщения от сервера о том что есть "новые сообщения" ?
Подскажите у всех правильно работает функция delay();? У меня к примеру delay(1000); не равна секунде, а длиннее процентов на 20-30. В чём может быть проблема?
Вот этим регистром можно корректировать частоту МК.
OSCCAL=0x7F;
Значения варируюца от 0x00 до 0x7F
Ах, да, забыл написать то что слетело из-за сбоя:
#define RED 0
#define GREEN 4
#define intervalRED 1000
#define intervalGREEN 600000
setup()
{
currentMillis = millis();
DDRB = (1<<RED)&(1<<GREEN)
...
}
А почему я не могу исправить свое сообщение? Какие-то могу, какие-то нет.
Просьба к админу исправить ошибку в последней строке.
Ну и интересно, заработало у вас? Вы в комментах пишите 1 минута, но 600000 это 10 минут. Так работает ты выдержка, которая вначале не работала?
1) Да все заработало.
А смогли локализовать ошибку почему не работало?
Просто на первый взгляд не было не видно.
К Attiny13 вобще можно кварц подцепить? В даташите по английски да еще так мутно написано, я ничего не понял. В даташите на Atmega328 все четко написано с какой частотой кварцы можно ставить и какой емкости конденсаторы к ним и еще схема нарисована куда все подсоединять.
melectro, можно кварцевый генератор до 20МГц
А смогли локализовать ошибку почему не работало? Просто на первый взгляд не было не видно.
Нет.
Очевидно где то происходило переполнение, но где именно я так и не понял.
Наконец то пришли правильные стабилизаторы с микроамперными токами потребления в покое,
10 мкА без нагрузки, 16 мкА в спящем режиме всей схемы.
Уличный термометр, каждые ~17 минут отправляющий данные, скетч:
#include <avr/sleep.h> #include <avr/wdt.h> #include <avr/io.h> #include <util/delay.h> /* for _delay_us() */ #define periodusec 400 // mcs #define DS_BIT 4 // pin 3 #define RC_BIT 3 // pin 2 #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif // PB0 pin 5 #define PB0_OUT sbi(DDRB,PB0) #define PB0_LOW cbi(PORTB,PB0) // PB1 pin 6 - EN pin RFunit WL118 #define PB1_OUT sbi(DDRB,PB1) #define PB1_HIGH sbi(PORTB,PB1) #define PB1_LOW cbi(PORTB,PB1) // PB2 pin 7 #define PB2_OUT sbi(DDRB,PB2) #define PB2_LOW cbi(PORTB,PB2) // PB3 pin 2 #define PB3_OUT sbi(DDRB,PB3); #define PB3_LOW cbi(PORTB,PB3); // PB4 pin 3 #define PB4_OUT sbi(DDRB,PB4) #define PB4_IN cbi(DDRB,PB4) #define PB4_HIGH sbi(PORTB,PB4) #define PB4_LOW cbi(PORTB,PB4) #define TimerCountSec 1027 // ~17min delay start by sec word CurrentTime = 0; void ExecFunc() { // установка режима для ds DDRB |= _BV(DS_BIT); PORTB &= ~_BV(DS_BIT); DDRB &= ~_BV(DS_BIT); // get temp and send PB1_OUT; PB1_HIGH; // ON RF unit word TReading = GetTemp(); sendRC((unsigned long)(TReading + (word)11500)); // отправляем данные // OFF pins OneWireReset(); PB0_OUT; PB0_LOW; PB1_OUT; PB1_LOW; PB2_OUT; PB2_LOW; PB3_OUT; PB3_LOW; PB4_IN; PB4_LOW; } void CalcTimer() { ++CurrentTime; if (((CurrentTime + 1UL) * 8UL) >= TimerCountSec) { CurrentTime = 0; ExecFunc(); } } ISR (WDT_vect) { wdt_disable(); // disable watchdog } void setup () { // OFF pins PB0_OUT; PB0_LOW; PB1_OUT; PB1_LOW; PB2_OUT; PB2_LOW; PB3_OUT; PB3_LOW; PB4_IN; PB4_LOW; unsigned long delp = millis(); while ((millis() - delp) <= 1000); // pause for enable all device and get temp to clock // first run ExecFunc(); delp = millis(); while ((millis() - delp) <= 4000); // pause for enable all device and get temp to clock // second run ExecFunc(); // for exactly get temp } void loop () { CalcTimer(); cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF setup_watchdog(9); wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); sleep_bod_disable(); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); } // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec void setup_watchdog(int ii) { byte bb; int ww; if (ii > 9 ) ii = 9; bb = ii & 7; if (ii > 7) bb |= (1 << 5); bb |= (1 << WDCE); ww = bb; MCUSR &= ~(1 << WDRF); // start timed sequence WDTCR |= (1 << WDCE) | (1 << WDE); // set new watchdog timeout value WDTCR = bb; WDTCR |= _BV(WDIE); } void sendRC(unsigned long data) { // Отправка данных по радиоканалу RCswitch. Двоичный протокол DDRB |= _BV(RC_BIT); data |= 3L << 20; // ? unsigned short repeats = 1 << (((unsigned long)data >> 20) & 7); data = data & 0xfffff; unsigned long dataBase4 = 0; uint8_t i; for (i = 0; i < 20; i++) { dataBase4 <<= 1; dataBase4 |= (data % 2); data /= 2; } unsigned short int j; for (j = 0; j < repeats; j++) { data = dataBase4; uint8_t i; for (i = 0; i < 20; i++) { switch (data & 1) { case 0: PORTB |= _BV(RC_BIT); _delay_us(periodusec); PORTB &= ~_BV(RC_BIT); _delay_us(periodusec * 3); break; case 1: PORTB |= _BV(RC_BIT); _delay_us(periodusec * 3); PORTB &= ~_BV(RC_BIT); _delay_us(periodusec); break; } data >>= 1; } PORTB |= _BV(RC_BIT); _delay_us(periodusec); PORTB &= ~_BV(RC_BIT); _delay_us(periodusec * 31); } } // OneWire функции: void OneWireReset() { PORTB &= ~_BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_us(500); DDRB &= ~_BV(DS_BIT); _delay_us(500); } void OneWireOutByte(uint8_t d) { uint8_t n; for (n = 8; n != 0; n--) { if ((d & 0x01) == 1) { PORTB &= ~_BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_us(5); DDRB &= ~_BV(DS_BIT); _delay_us(60); } else { PORTB &= ~_BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_us(60); DDRB &= ~_BV(DS_BIT); } d = d >> 1; } } uint8_t OneWireInByte() { uint8_t d, n, b; for (n = 0; n < 8; n++) { PORTB &= ~_BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_us(5); DDRB &= ~_BV(DS_BIT); _delay_us(5); b = ((PINB & _BV(DS_BIT)) != 0); _delay_us(50); d = (d >> 1) | (b << 7); } return (d); } word GetTemp() { uint8_t DSdata[2]; OneWireReset(); OneWireOutByte(0xcc); OneWireOutByte(0x44); PORTB |= _BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_ms(1000); // если хотим ждать когда датчик посчитает температуру. DDRB &= ~_BV(DS_BIT); PORTB &= ~_BV(DS_BIT); OneWireReset(); OneWireOutByte(0xcc); OneWireOutByte(0xbe); DSdata[0] = OneWireInByte(); DSdata[1] = OneWireInByte(); word TReading = (word)(DSdata[1] << 8) + DSdata[0]; if ((word)(TReading & 0x8000) == (word)(0x8000)) { TReading = (~TReading) + (word)1; TReading = (((word)6 * TReading) + TReading / (word)4) / (word)10; } else { TReading = (((word)6 * TReading) + TReading / (word)4) / (word)10 + (word)2000; } return TReading; }500mA Высокая Эффективность 0.8-3.3 В до 3.3 В УГФ Step-up Dc-dc для ds18b20 dht22 STM32 FPGA CPLD Питания
http://s.aliexpress.com/ZVFbUvu2?fromSns=Copy to Clipboard
(from AliExpress Android)
Это вообще крутой пример. А что за радиомодуль? Я вот такие пробовал, только у другого продавца за 800 рублей
https://ru.aliexpress.com/item/2pcs-E45-TTL-100-20dBm-3km-SX1276-868MHz-...
Эти вообще на километр в городе передают и 4 в лесу. Если рядом можно мощность снижать со 100 до 1 мВт, чтобы помех не делать...
Радиомодуль самый дешёвый, качество отвратительное, но с антенной на несколько метров пробивает.
433 мГц РФ передатчик и приемник Ссылка Комплект для Arduino/arm/MCU WL хорошее качество
http://s.aliexpress.com/i2YbInU7?fromSns=Copy to Clipboard
(from AliExpress Android)
С дуру взял ещё подороже супергетеродинный, думал сильно лучше, но ошибся, самое противное - у него было большое потребление, а пин выключения напрямую включён - пришлось на модуле отрывать ножку у чипа и припаивать на attiny85, что бы так же загонять радиомодуль в сон
433 мГц РФ передатчик и приемник Ссылка Комплект для Arduino/arm/MCU WL хорошее качество
http://s.aliexpress.com/i2YbInU7?fromSns=Copy to Clipboard
(from AliExpress Android)
Andy, добрый день. Судя по Вашим словам, используете супергетеродин на 433 МГц, без применения библиотек типа WirtualWire и у Вас все работает? Ну Вы шаман, однако. Поделитесь, как подбирали длину антенны, ставили ли противовес и какую дальность передачи получили? Мой опыт - всего порядка 15 метров в городе в здании. При этом антенна - штырь в четверть волны.
Опять у меня дубли пошли(
я не шаман, а как и все начинающие ардуинщики - копипастер :) , тут пару страниц назад есть ссылка на источник, откуда скетч взят, я уже доработал для своих нужд.
никаких подборов длин антен, на передатчик - кусок провода метровой длины, на приемник - спиралька сантиметров 10, радиус действия метров 5 в помещении максимум - мне больше не нужно - просто повесить градусник на улице за окном.
...............- мне больше не нужно - просто повесить градусник на улице за окном.
...............- мне больше не нужно - просто повесить градусник на улице за окном.
конечно, что вас смущает?
Все понятно, просто звучали тут восторженные возгласы и цифры под километр, вот это меня и ввело в заблуждение. Тогда могу и посоветовать погуглить в сторону библиотеки WirtualWire. Обещают хорошую устойчивость к помехам. Сам не пробовал, т.к. пишу не на ардуино, а адаптировать библу было лень. Сделал т просто широтной-импульсный сигнал частотой 1кгц. На стороне приема rc-цепь и компаратор на транзисторе вроде. Мне надо было передавать 1 бит только. Работало, но иногда были сбои. Потом отказался вообще от вчрф, т.к. заказчик изменил ТЗ.
что использовать всегда зависит от поставленной задачи.
VirtualWire на AtTiny запистить не смог - не стабильно работает - при уходе МК в спящий режим - потом уже не всегда передает данные.
конечно, что вас смущает?
Сам мечтаю сделать внешний термометр без проводов, но вижу его немного иначе. Батарейка, МК и передатчик в помещении, а датчик на улице, соединенный коротким проводком.