ATtiny13A 101 применение

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

ranzer пишет:

Вот, программно, это как? Без Arduino, напрямую?

Конечно без ардуино, что вы хотите чтоб три светодиода плавно загорались и тухли?

Одновременно или поочереди вы же ничего не пишите.

ranzer
Offline
Зарегистрирован: 19.04.2017

bodriy2014 пишет:

Конечно без ардуино, что вы хотите чтоб три светодиода плавно загорались и тухли?

Одновременно или поочереди вы же ничего не пишите.

Как же не пишу? Вот, сразу же сказал

ranzer пишет:

fade поочередно на три разных светодиода?

Просто именно из инсрукций по сборке подобных схем на три светодиода я и наткнулся на Attiny13, но там в лучших традициях "профессионалов" вообще ничего не было сказано ни о том чем их прошивать, ни о том, как и что за что отвечает и даже где искть инфу, мол - разбирайся сам. Ну вот, теперь пытаюсь разобраться... Только на контроллер уже потратился

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

ranzer пишет:

....

Просто именно из инсрукций по сборке подобных схем на три светодиода я и наткнулся на Attiny13, но там в лучших традициях "профессионалов" вообще ничего не было сказано ни о том чем их прошивать, ни о том, как и что за что отвечает и даже где искть инфу, мол - разбирайся сам. Ну вот, теперь пытаюсь разобраться... Только на контроллер уже потратился

Что за схема дайте ссылку или сюда вставьте,

если есть готовое почему не применяете.

 

ranzer
Offline
Зарегистрирован: 19.04.2017

bodriy2014 пишет:

Что за схема дайте ссылку или сюда вставьте,

если есть готовое почему не применяете.

Потому, что все полезное, что я из нее вынес, это то, что это в теории возможно. Даже программа написанная там, как позже выяснилось с обсуждений (не привязанных, поэтому нашел я их существенно позже), написана с ошибками, да и контроллер там не 13, а 15, но по нему информации еще меньше, а достать и подключить сложнее. Тогда как разница, как я понял из прочитанных в дальнейшем статей, не очень существенная для моих целей, так что сказал это просто к тому, почему взял за основу.

Но если поможет, то вот: http://www.radiokot.ru/circuit/light/run/10/

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

ranzer пишет:

.....

Потому, что все полезное, что я из нее вынес, это то, что это в теории возможно. Даже программа написанная там, как позже выяснилось с обсуждений (не привязанных, поэтому нашел я их существенно позже), написана с ошибками, да и контроллер там не 13, а 15, но по нему информации еще меньше, а достать и подключить сложнее. Тогда как разница, как я понял из прочитанных в дальнейшем статей, не очень существенная для моих целей, так что сказал это просто к тому, почему взял за основу.

Но если поможет, то вот: http://www.radiokot.ru/circuit/light/run/10/

Загляните в эту веточку позже выложу код.

ranzer
Offline
Зарегистрирован: 19.04.2017

bodriy2014 пишет:

Загляните в эту веточку позже выложу код.

Хорошо, благодарю!

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

ranzer

Вот простейший fade на три светодиода, я там все прокомментировал, дальше сами под себя подстраивайте.

Вот видео на нем схема и осциллограмма.

Частота тини13 любая.

#define spee_d 3 //скорость изменения яркости

int n = 0, c = 0;
bool f = 0;
void setup() {
  DDRB |= (1 << 0) | (1 << 1) | (1 << 2); //пины на выход
}

void loop() {
  while (1) {//быстрее крутится чем луп
    PORTB |= (1 << 0);//зажигаем
    PORTB |= (1 << 1);//зажигаем
    PORTB |= (1 << 2);//зажигаем
    c = 0 + n;
    while (c > 0) {//пауза
      asm("nop");//пропуск одноко такта МК
      c--;
    }
    PORTB &= ~(1 << 0);//тушим
    PORTB &= ~(1 << 1);//тушим
    PORTB &= ~(1 << 2);//тушим
    c = 1000 - n;
    while (c > 0) {//пауза
      asm("nop");//пропуск одноко такта МК
      c--;
    }
    if (f == 0) {
      n = n + spee_d;
    }
    if (f == 1) {
      n = n - spee_d;
    }
    if (n >= 1000 || n <= 0) {
      f = !f;
    }
  }
}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

bodriy2014, кстати в этой теме был полезный скетчик , пост #672  это эмулятор свечки с кол-м светодиодов от 1 до 6,  интересен метод управления софт-шимом, который применил автор.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

dimax пишет:

bodriy2014, кстати в этой теме был полезный скетчик , пост #672  это эмулятор свечки с кол-м светодиодов от 1 до 6,  интересен метод управления софт-шимом, который применил автор.

Для свечей или эмуляции пламени самое-то, гибко.

Спасибо, нужно сохранить.

Но если тини  что-то еще должна делать кроме моргания, лучше программно ИМХО.

taxi242
Offline
Зарегистрирован: 28.03.2017

Приветствую Всех.

Ответ к посту

http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=21#comment-272828

#define Min_C 100 // значение  при котором отключаем вентилятор
#define Max_C 180 // значение  при котором  вентилятор на максимум

byte dvig_1, dvig_2;
void setup() {
  DDRB |= (1 << 0) | (1 << 1);//пины на выход
  TCCR0A = 0b10100011; //режим fast pwm
  TCCR0B = 0b00000001; //выбираем скорость ШИМ делителем
}

void loop() {
  //первый двигатиель
  dvig_1 = analogRead_C(3) / 4; // РВ3 в ATtiny13
  if (dvig_1 <= Min_C) {
    OCR0A = 0;
  } else if (dvig_1 >= Max_C) {
    OCR0A = 255;
  } else {
    OCR0A = dvig_1;
  }
  //второй двигатиель
  dvig_2 = analogRead_C(2) / 4; // РВ4 в ATtiny13
  if (dvig_2 <= Min_C) {
    OCR0B = 0;
  }  else if (dvig_2 >= Max_C) {
    OCR0B = 255;
  } else {
    OCR0B = dvig_2;
  }
}

unsigned int analogRead_C(byte channel) {//функция измерения АЦП
  ADMUX = channel; // ADC pin
  ADCSRA |= 1 << ADEN;
  ADCSRA |= 1 << ADSC;
  while (!(ADCSRA & (1 << ADIF)));
  ADCSRA |= 1 << ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  return (high << 8) | low;
}

Плата разведена и готова на 95% есть еще такой вопрос - как в этот код добавить условие: при запуске (подаче питания на схему) вентиляторы должны расскручиваться до максимума, или до 75% и через сек 3-5 уже входить в штатный режим термоконтроля, при чем лучше раскручивать вентиляторы разных каналов поочередно, дабы уменьшить издаваемый шум.

Проведя тесты понял, что можно попасть на такой неприятный момент, когда вентилятору немного не хватает напруги для уверенного старта, в этот момент можно услышать от вентилятора от писка гула до вибрации.

Понятно, что это задание детское, но у меня уйдет на это месяц-два с моей основной деятельность.

С меня как схема, так и фото и видео готового устройства.

Спасибо.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

taxi242

Это элементарно задается в Сетап.

void setup() {
  DDRB |= (1 << 0) | (1 << 1);//пины на выход
  TCCR0A = 0b10100011; //режим fast pwm
  TCCR0B = 0b00000001; //выбираем скорость ШИМ делителем
  OCR0A = 200;
  OCR0B = 200;
  delay(3000);
}

 

taxi242
Offline
Зарегистрирован: 28.03.2017

аааа, а я думал в основную программу гдето уже вставлять. А если нужно не резко установить, а плавно (можно и ступенчато)?

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

taxi242 пишет:

аааа, а я думал в основную программу гдето уже вставлять. А если нужно не резко установить, а плавно (можно и ступенчато)?

Сетап выполняется один раз во время загрузки.

Можно в цикле подымать, если не умеете можно просто ступенями, все в ваших руках!)

//через цикл
void setup() {
  DDRB |= (1 << 0) | (1 << 1);//пины на выход
  TCCR0A = 0b10100011; //режим fast pwm
  TCCR0B = 0b00000001; //выбираем скорость ШИМ делителем
  for(int i=100;i<255;i++){
	  OCR0A = i;
	  OCR0B = i;
	  delay(100);
  }
}
//просто ступенями
void setup() {
  DDRB |= (1 << 0) | (1 << 1);//пины на выход
  TCCR0A = 0b10100011; //режим fast pwm
  TCCR0B = 0b00000001; //выбираем скорость ШИМ делителем
  OCR0A = 100;
  OCR0B = 100;
  delay(1000);
  OCR0A = 150;
  OCR0B = 150;
  delay(1000);
  OCR0A = 200;
  OCR0B = 200;
  delay(1000);
}

 

renoshnik
Offline
Зарегистрирован: 11.04.2013

Добрый день !

Нужен совет, подсказка...

В проекте arduino следит за датчиками (используются около 10 датчиков механические и аналоговые) хочу каждый датчик подключить на свой Attiny13 .

Не могу придумать как организовать обмен данными датчиков с ardino по двум проводам (типа I2С) . 

Для аналоговых датчиков достаточно передавть один байт.

Joiner
Offline
Зарегистрирован: 04.09.2014

renoshnik пишет:

Добрый день !

Нужен совет, подсказка...

В проекте arduino следит за датчиками (используются около 10 датчиков механические и аналоговые) хочу каждый датчик подключить на свой Attiny13 .

Не могу придумать как организовать обмен данными датчиков с ardino по двум проводам (типа I2С) . 

Для аналоговых датчиков достаточно передавть один байт.

Мне кажется не надо огород городить из Attiny13. Есть микросхемка (забыл как называется, умные люди подскажут), которая может переключать по очереди все ваши аналоговые датчики на один вход Ардуинки. Мне кажется, что это гораздо лучше, чем куча тинек.

renoshnik
Offline
Зарегистрирован: 11.04.2013

Joiner пишет:

renoshnik пишет:

Добрый день !

Нужен совет, подсказка...

В проекте arduino следит за датчиками (используются около 10 датчиков механические и аналоговые) хочу каждый датчик подключить на свой Attiny13 .

Не могу придумать как организовать обмен данными датчиков с ardino по двум проводам (типа I2С) . 

Для аналоговых датчиков достаточно передавть один байт.

Мне кажется не надо огород городить из Attiny13. Есть микросхемка (забыл как называется, умные люди подскажут), которая может переключать по очереди все ваши аналоговые датчики на один вход Ардуинки. Мне кажется, что это гораздо лучше, чем куча тинек.

 

Расширитель входов это НЕ решение. Смысл в том, что тинька обрабатывает данные аналоговых датчиков и механических (типа энкодеров) и отправляет уже готовый результат.

Цель, разгрузить arduino для основной работы.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

OneWire или RS-485 тут идеально подходят.

renoshnik
Offline
Зарегистрирован: 11.04.2013

Tomasina пишет:

OneWire или RS-485 тут идеально подходят.

в теории ...  а есть где глянуть практический пример такой реализации для Attiny13 ?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
renoshnik
Offline
Зарегистрирован: 11.04.2013

Tomasina, спасибо, буду изучать...

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

renoshnik пишет:

Добрый день !

Нужен совет, подсказка...

В проекте arduino следит за датчиками (используются около 10 датчиков механические и аналоговые) хочу каждый датчик подключить на свой Attiny13 .

Не могу придумать как организовать обмен данными датчиков с ardino по двум проводам (типа I2С) . 

Для аналоговых датчиков достаточно передавть один байт.

Сделать можно, но дешевле перейти на Mega2560

Еще и пины свободные останутся.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

если датчики сильно разнесены, это не выход.

Joiner
Offline
Зарегистрирован: 04.09.2014

bodriy2014 пишет:

Сделать можно, но дешевле перейти на Mega2560

Еще и пины свободные останутся.

Золотые слова! И не понадобится куча всякого обвеса.

Joiner
Offline
Зарегистрирован: 04.09.2014

Tomasina пишет:

если датчики сильно разнесены, это не выход.

Если датчики сильно разнесены, то можно применить Raspberry Pi, а датчики соединить с ней по интернету :)

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

ага, вместо 27-рублевых и надежных RS-485 использовать Wi-Fi минимум на порядок дороже? И сколько точек держит сеть Wi-Fi? В подвале ловит?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

renoshnik, вы почему то умолчали о предполагаемой длины проводов. А ведь это самый важный фактор в выборе метода организации подключания датчиков.

renoshnik
Offline
Зарегистрирован: 11.04.2013

dimax пишет:

renoshnik, вы почему то умолчали о предполагаемой длины проводов. А ведь это самый важный фактор в выборе метода организации подключания датчиков.

Длина проводов не большая (до одного метра).

Это планируется станок, датчики (некоторые) оптопары в энкодерах, есть датчики Холла на валах двигателей, плюс тактовые кнопки.

Обробатывать все датчики в одной arduino не вариант т.к. важна точность, нельзя пропустить сигнал например с энкодера или оборот вала. Поэтому и хочу загрузить тиньки обработкой датчиков, а основной контроллер будет получать уже готовое значение.

Например энкодеры применяются инкремментальные, а тинькой хочу сделать, как псевдо абсолютный...

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

renoshnik пишет:

Длина проводов не большая (до одного метра).

Тогда очевидно I2C, и тиньку все-таки не 13 а 85. на цену это никак не влияет, а I2C почти аппаратный и памяти побольше. При том же 8-ми ногом корпусе.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

renoshnik, мне кажется вы преувеличиваете загрузку для мк. Энкодеры для МК как улитка для скакуна.  На метре провода нет смысла заморачиваться с отдельными контролерами, главное грамотно организовать обработку сигналов. Тем более что собрать данные со всех конроллеров , успеть их обрадотать и адекватно отреагировать при надобности -тоже задача не такая простая и уж точно не быстрая. В меге 328 на каждой ноге прерывание, так что всё  "в руках" обработчика энкодеров и прочих датчиков.

renoshnik
Offline
Зарегистрирован: 11.04.2013

wdrakula пишет:

renoshnik пишет:

Длина проводов не большая (до одного метра).

Тогда очевидно I2C, и тиньку все-таки не 13 а 85. на цену это никак не влияет, а I2C почти аппаратный и памяти побольше. При том же 8-ми ногом корпусе.

 

Таки да....  просто пока прийдут 85 хотел нае...ть систему ...

renoshnik
Offline
Зарегистрирован: 11.04.2013

dimax пишет:

renoshnik, мне кажется вы преувеличиваете загрузку для мк. Энкодеры для МК как улитка для скакуна.  На метре провода нет смысла заморачиваться с отдельными контролерами, главное грамотно организовать обработку сигналов. Тем более что собрать данные со всех конроллеров , успеть их обрадотать и адекватно отреагировать при надобности -тоже задача не такая простая и уж точно не быстрая. В меге 328 на каждой ноге прерывание, так что всё  "в руках" обработчика энкодеров и прочих датчиков.

 

Не совсем понял... это как ...

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

renoshnik, групповые прерывания PCINT на каждой ноге, образуют три общих прерывания. Внутри прерываний можно анализировать какая нога сработала. Есть перываний нужно не более 6, но можно взять два обычных, + прерывания компаратора + по одной ноге из каждого прерывания PCINT. Если что гугл расскажет подробнее..

renoshnik
Offline
Зарегистрирован: 11.04.2013

dimax пишет:

renoshnik, групповые прерывания PCINT на каждой ноге, образуют три общих прерывания. Внутри прерываний можно анализировать какая нога сработала. Есть перываний нужно не более 6, но можно взять два обычных, + прерывания компаратора + по одной ноге из каждого прерывания PCINT. Если что гугл расскажет подробнее..

Вы об этом... Немного торможу....

небольшая поправка

"Внутри прерываний можно анализировать какая нога сработала." = нужно ...

Только не думаю, что один контроллер справится со всеми задачами...

Например у меня считается число оборотов которое должен сделать вал, таких валов два. Скорость вращения около 3500 об/мин. В этоже время контролируется скорость вращения вала. Все это скорость и количество оборотов обображается на экране.

Плюс к этому датчики перемещения (энкодеры) восемь штук...

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

renoshnik, я и написал ниже, что если нужно всего  6 прерываний -то прерывание PCINT монопольно занимается одним пином, и внутри уже не нужно анализировать.

renoshnik
Offline
Зарегистрирован: 11.04.2013

dimax пишет:

renoshnik, я и написал ниже, что если нужно всего  6 прерываний -то прерывание PCINT монопольно занимается одним пином, и внутри уже не нужно анализировать.

я подредактировал свой пост выше (до вашего ответа)...

думаю, что такое решение не подойдет...

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

renoshnik, решать вам. Я думаю что подойдёт, вы склонны сгущать краски. PS:  3500 в минуту -это 60 Герц, если датчик один. Т.е. раз в вечность для МК.  Можно всё повесить на pcint и внутри всё неспешно разбирать, времени вагон - у вас одни улитки и черепахи :) 

renoshnik
Offline
Зарегистрирован: 11.04.2013

dimax пишет:

renoshnik, решать вам. Я думаю что подойдёт, вы склонны сгущать краски. PS:  3500 в минуту -это 60 Герц, если датчик один. Т.е. раз в вечность для МК.  Можно всё повесить на pcint и внутри всё неспешно разбирать, времени вагон - у вас одни улитки и черепахи :) 

Это возрастное...  :-)

Лучше перебдеть чем недобдеть ....

Спасибо, обнадежили, попробую загрузить всеми задачами контроллер, а там будет видно...

pittyalex
Offline
Зарегистрирован: 09.11.2016

renoshnik пишет:

wdrakula пишет:

renoshnik пишет:

Длина проводов не большая (до одного метра).

Тогда очевидно I2C, и тиньку все-таки не 13 а 85. на цену это никак не влияет, а I2C почти аппаратный и памяти побольше. При том же 8-ми ногом корпусе.

 

Таки да....  просто пока прийдут 85 хотел нае...ть систему ...


Это конечно злостный оффтоп, но вложу свои 5 копеек:
Если уж уходить от 13 на 85 (а это почти в 2 раза дороже), то уж лучше взять stm8s103. Из преимуществ: больше ног, куча периферии, в том числе до 7 устройств захвата (для энкодеров), полностью аппаратные I2c, spi uart. Мощная система прерываний И, барабаны, отладка полноценная по 1 проводу, а дебаггер стоит не дороже 2 баксов.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

забыли упомянуть про цену на билет (высокий порог входа).

Что толку от кучи аппаратных возможностей, если нет знаний как ими воспользоваться? А такого большого сообщества как у Arduino нету, форумы есть, но чайника там ожидаемо пошлют.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

Tomasina прав. так и есть. как только в ардуино иде можно будет программировать stm8 как сделали stm32c8t6 тогда конечно можно будет предлагать

pittyalex
Offline
Зарегистрирован: 09.11.2016

Чайника не пошлют. Ламера пошлют. А порог входа не такой уж и высокий. Примеры есть, отладчик есть, даташите есть. Бери и разбирайся. Поняв, как работает периферия один раз, на других камнях уже значительно проще разобраться. Сами чипы сейчас на Али нашел по 35 центов. Дороже тиньки13 но значительно дешевле 85, хотя мне ее. Есть аппаратное умножение и деление, два индексных 16битных регистра для которых поддерживается арифметика, т.е. фактически есть 16 битная арифметика. Я сейчас и ардуина 328 пользуюсь и stm8. Стм мне нравится больше за возможность полноценной отладки.

pittyalex
Offline
Зарегистрирован: 09.11.2016

Да, забыл сказать, наш соотечественник неспешно ведет разработку библиотек, аналогичных wiring. Уже очень похоже на ардуино, только среду разработки нужно использовать. IAR, но она бесплатная есть.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Привет.

Выкладываю скетч газового сигнализатор на тини13

/*Контроль уровня газа и сигнализация в случае опасности.
Алгоритм работы:
---Прогрев датчика и замер нормальной концентрации газа.
---Пауза
---Прогрев датчика и замер концентрации газа.
---В случае превышения концентрации  пищим тревогу.
---И так в цикле.*/
//               AtTity13
//                 ----
// ADC0 (D5) res 1|    |8 Vcc
// ADC3 (D3) PB3 2|    |7 PB2 (D2) ADC1
// ADC2 (D4) PB4 3|    |6 PB1 (D1) PWM1
//           GND 4|    |5 PB0 (D0) PWM0
//                 ----
// * PB0-LED
// * PB1-BUZZER
// * PB3-MQ7
// * PB4-key MQ7
#include <avr/delay.h> //уже есть в ИДЕ подключать не нужно

#define porog 100      //порог для тревоги
int dCO = 0;           //переменная уровня СО
int norm_dCO = 0;      //переменная нормального уровня СО
byte flag_trevoga = 0; //флаг тревоги

void setup() {
  DDRB |= (1 << 0);     // устанавливаем вывод PB0 как выход
  DDRB |= (1 << 1);     // устанавливаем вывод PB1 как выход
  DDRB |= (1 << 4);     // устанавливаем вывод PB1 как выход
  DDRB |= (0 << 3);     // устанавливаем вывод PB3 как вход
  PORTB &= ~(1 << 0); // устанавливаем низкий уровень на выводе PB0
  PORTB &= ~(1 << 1); // устанавливаем низкий уровень на выводе PB1
  PORTB &= ~(1 << 4); // устанавливаем низкий уровень на выводе PB4
  progrev ();
  //при сиарте меряем уровень СО десять раз находим среднее и принимаем его нормальным
  PORTB |= (1 << 0);  // включаем LED
  for (int i = 0; i <= 10; i++) {
    dCO = analogRead(PB3);
    norm_dCO = norm_dCO + dCO;
    _delay_ms(10);
  }
  norm_dCO = norm_dCO / 10;
  PORTB &= ~(1 << 4); //выключаем питание датчика
  PORTB &= ~(1 << 0); // выключаем LED
  //##################
}

void loop() {
  progrev ();
  PORTB |= (1 << 0);  // включаем LED
  _delay_ms(1000);
  dCO = analogRead(PB3);
  PORTB &= ~(1 << 4); //выключаем питание датчика
  PORTB &= ~(1 << 0); // выключаем LED
  if (dCO > norm_dCO + porog) { //Если превышен уровень СО
    flag_trevoga = 1;
  }
  if (dCO < norm_dCO + porog) { //Если не превышен уровень СО
    flag_trevoga = 0;
  }
  for (byte i = 0; i < 30; i++) { // пауза 30сек
    _delay_ms(1000);
    if (flag_trevoga == 1) {
      trevoga ();
    }
  }
}

void progrev () { // Греем датчик 30сек
  PORTB |= (1 << 4);  //включаем питание датчика
  for (byte i = 0; i < 30; i++) {
    _delay_ms(1000);
    if (flag_trevoga == 1) {
      trevoga ();
    }
  }
}

void trevoga () { //пищим
  for (int i = 0; i < 1000; i++) {
    PORTB |= (1 << 1);  //включаем Buzzer
    _delay_us(100);
    PORTB &= ~(1 << 1);  //выключаем Buzzer
    _delay_us(100);
  }
}

Второй скетч тот же сигнализатор но вместо пищалки включает вытяжку.

/*Контроль уровня газа и сигнализация в случае опасности.
Алгоритм работы:
---Прогрев датчика и замер нормальной концентрации газа.
---Пауза
---Прогрев датчика и замер концентрации газа.
---В случае превышения концентрации  включаем вентилятор вытяжки.
---И так в цикле.*/
//               AtTity13
//                 ----
// ADC0 (D5) res 1|    |8 Vcc
// ADC3 (D3) PB3 2|    |7 PB2 (D2) ADC1
// ADC2 (D4) PB4 3|    |6 PB1 (D1) PWM1
//           GND 4|    |5 PB0 (D0) PWM0
//                 ----
// * PB0-LED
// * PB1-BUZZER
// * PB3-MQ7
// * PB4-вентилятор вытяжки.
#include <avr/delay.h> //уже есть в ИДЕ подключать не нужно

#define porog 100      //порог для тревоги
int dCO = 0;           //переменная уровня СО
int norm_dCO = 0;      //переменная нормального уровня СО
byte flag_trevoga = 0; //флаг тревоги

void setup() {
  DDRB |= (1 << 0);     // устанавливаем вывод PB0 как выход
  DDRB |= (1 << 1);     // устанавливаем вывод PB1 как выход
  DDRB |= (1 << 4);     // устанавливаем вывод PB1 как выход
  DDRB |= (0 << 3);     // устанавливаем вывод PB3 как вход
  PORTB &= ~(1 << 0); // устанавливаем низкий уровень на выводе PB0
  PORTB &= ~(1 << 1); // устанавливаем низкий уровень на выводе PB1
  PORTB &= ~(1 << 4); // устанавливаем низкий уровень на выводе PB4
  progrev ();
  //при сиарте меряем уровень СО десять раз находим среднее и принимаем его нормальным
  PORTB |= (1 << 0);  // включаем LED
  for (int i = 0; i <= 10; i++) {
    dCO = analogRead(PB3);
    norm_dCO = norm_dCO + dCO;
    _delay_ms(10);
  }
  norm_dCO = norm_dCO / 10;
  PORTB &= ~(1 << 4); //выключаем питание датчика
  PORTB &= ~(1 << 0); // выключаем LED
  //##################
}

void loop() {
  progrev ();
  PORTB |= (1 << 0);  // включаем LED
  _delay_ms(1000);
  dCO = analogRead(PB3);
  PORTB &= ~(1 << 4); //выключаем питание датчика
  PORTB &= ~(1 << 0); // выключаем LED
  if (dCO > norm_dCO + porog) { //Если превышен уровень СО
    flag_trevoga = 1;
  }
  if (dCO < norm_dCO + porog) { //Если не превышен уровень СО
    flag_trevoga = 0;
    PORTB &= ~(1 << 1);  //выключаем вентилятор вытяжки.
  }
  for (byte i = 0; i < 30; i++) { // пауза 30сек
    _delay_ms(1000);
    if (flag_trevoga == 1) {
      trevoga ();
    }
  }
}

void progrev () { // Греем датчик 30сек
  PORTB |= (1 << 4);  //включаем питание датчика
  for (byte i = 0; i < 30; i++) {
    _delay_ms(1000);
    if (flag_trevoga == 1) {
      trevoga ();
    }
  }
}

void trevoga () { //пищим
  PORTB |= (1 << 1);  //включаем вентилятор вытяжки.
}

Вот видео по прибору.

renoshnik
Offline
Зарегистрирован: 11.04.2013

dimax пишет:

renoshnik, мне кажется вы преувеличиваете загрузку для мк. Энкодеры для МК как улитка для скакуна.  На метре провода нет смысла заморачиваться с отдельными контролерами, главное грамотно организовать обработку сигналов. Тем более что собрать данные со всех конроллеров , успеть их обрадотать и адекватно отреагировать при надобности -тоже задача не такая простая и уж точно не быстрая. В меге 328 на каждой ноге прерывание, так что всё  "в руках" обработчика энкодеров и прочих датчиков.

 

.... моя паранойя (перестраховщика) всетаки победила ...  :-))

а может это был уже спортивный интерес...

 

https://www.youtube.com/watch?v=ejbCYs-WJaY

 

Joiner
Offline
Зарегистрирован: 04.09.2014

renoshnik пишет:

.... моя паранойя (перестраховщика) всетаки победила ...  :-))

а может это был уже спортивный интерес...

Интересненько! Добавил в закладки.

Rhonstin
Offline
Зарегистрирован: 16.05.2017

Всем привет! Решил реализовать термометр на DHT-11 и отображать это через регистры 595 на 2 семисегментника, все хорошо, вот только не хватает 100 байт, чем бы еще оптимизировать? 

//Оптимизация digitalRead(Write)

byte datamask = (1 << 0);
byte latchmask = (1 << 1);
byte clockmask = (1 << 2);

#define Data_OUTPUT   DDRB |= datamask
#define Latch_OUTPUT  DDRB |= latchmask
#define Clock_OUTPUT  DDRB |= clockmask
#define Data_HIGH   PORTB |= datamask
#define Latch_HIGH  PORTB |= latchmask
#define Clock_HIGH  PORTB |= clockmask
#define Clock_LOW   PORTB &= ~clockmask
#define Latch_LOW   PORTB &= ~latchmask
#define Data_LOW    PORTB &= ~datamask

byte pin13mask = (1 << 4);
#define D13_SET_OUTPUT      DDRB  |=  pin13mask // Устанавливаем пин D13 в режим OUTPUT
#define D13_SET_INPUT       DDRB  &= ~pin13mask // Устанавливаем пин D13 в режим INPUT
#define D13_WRITE_HIGH      PORTB |=  pin13mask // Устанавливаем бит отвечающий за пин D13 в HIGH, остальные пины не трогаем
#define D13_WRITE_LOW       PORTB &= ~pin13mask // Устанавливаем бит отвечающий за пин D13 в LOW, остальные пины не трогаем

// Числа на семисегментные идикаторы
unsigned char numbersOne[10] = {0b11110111, 0b00010001, 0b01101011, 0b00111011, 0b00011101, 0b00111110, 0b01111110, 0b00010111, 0b11111111, 0b00111111};
unsigned char numbersTwo[10] = {0b00111111, 0b00001001, 0b01011110, 0b01011011, 0b01101001, 0b01110011, 0b01110111, 0b00111001, 0b11111111, 0b01111011};

void shiftout(unsigned char _byte) {
  //цикл по битам
  for (unsigned char i = 0; i < 8; i++) {
    if (_byte & (1 << i)) Data_HIGH;
    else Data_LOW;
    Clock_HIGH;
    Clock_LOW;
  }
}

#define DHT_OK                0
#define DHT_ERROR_CHECKSUM   -1 // Ошибка контрольной суммы
#define DHT_ERROR_TIMEOUT    -2 // Ошибка таймаут

byte pinData = 12;

// Объявляем переменные для хранения данных
byte humidity;     // Влажность
byte temperature;  // Температура


byte getTempDate(byte pin) {

  byte data[40];

  D13_SET_OUTPUT; // Включаем режим управления линией данных
  // Подаем сигнал датчику о том, что хотим получить данные
  D13_WRITE_LOW; // Притягиваем к нулю линию данных
  delay(18); // Ждем 18 мс

  D13_WRITE_HIGH; // Отпускаем к единице
  delayMicroseconds(40); // Ждем 40 мкс
  D13_SET_INPUT; // Переключаемся в режим приема и начинаем слушать

  unsigned int timeoutInt = 10000; // Создаем переменную, отслеживающую таймаут
  
  // Датчик должен притянуть линию данных к 0 и...
  while (digitalRead(pin) == LOW)
    if (timeoutInt-- == 0) return DHT_ERROR_TIMEOUT; // Если прошло 10000 итераций, а датчик не отреагировал, то ошибка!
  
  // ... потом отпустить её
  timeoutInt = 10000;
  while (digitalRead(pin) == HIGH)
    if (timeoutInt-- == 0) return DHT_ERROR_TIMEOUT;

  // Если дошли до этого места, значит все нормально - начинаем принимать данные
  // Нам нужно принять 40 бит
  for (byte i = 0; i < 40; i++)
  {
    timeoutInt = 10000;
    // Датчик притянул линию данных к нулю, ждем, когда отпустит
    while (digitalRead(pin) == LOW)
      if (timeoutInt-- == 0) return DHT_ERROR_TIMEOUT;

    // Засекаем, когда датчик отпустит линию данных к единице
    unsigned long t = micros();
    timeoutInt = 10000;
    // Ждем когда датчик снова притянет линию данных к нулю
    while (digitalRead(pin) == HIGH)
      if (timeoutInt-- == 0) return DHT_ERROR_TIMEOUT;

    // По интервалу определяем, какой бит был передан
    // Если больше 40 (нам нужно 70 мкс) - значит 1, если меньше 40 (27 мкс) - значит 0
    if ((micros() - t) > 40) data[i] = 1;
    else data[i] = 0; // Инициализация нулевого значения
  }

  // Собираем байты из битов
  byte bytes[5] = {0, 0, 0, 0, 0}; // Инициализируем байты для хранения полученных данных
  byte byteindex = 0; // Индекс байта
  int posindex = 7; // Индекс бита в байте. Данные приходят в порядке: первым приходит старший бит
  for (byte i = 0; i < 40; i++) {
    if (data[i] == 1)  bytes[byteindex] |= (1 << posindex); // Задаем бит при помощи побитового ИЛИ
    posindex--;
    if (posindex < 0) {
      posindex = 7;
      byteindex++; // Переходим к следующему байту
    }
  }

  byte sum = bytes[0] + bytes[2];
  // Проверяем контрольную сумму
  if (bytes[4] != sum) return DHT_ERROR_CHECKSUM; // Контрольная сумма не совпадает - возвращаем ошибку

  // Все проверки прошли нормально
  // Присваиваем полученные данные переменным температуры и влажности
  humidity    = bytes[0];
  temperature = bytes[2];

  // Возвращаем положительный ответ
  return DHT_OK;
}

int main()
{  
  Data_OUTPUT;
  Latch_OUTPUT;
  Clock_OUTPUT;
  while (1) {
      byte result = getTempDate(pinData);
  delay(3000);
    byte NO = temperature / 10;
    byte NW = temperature % 10;
    Latch_HIGH;
    shiftout(numbersTwo[1]);
    shiftout(numbersOne[1]);
    Latch_LOW;
  }
}

 

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Rhonstin пишет:

Всем привет! Решил реализовать термометр на DHT-11 и отображать это через регистры 595 на 2 семисегментника, все хорошо, вот только не хватает 100 байт, чем бы еще оптимизировать?....

Привет.

#include <util/delay.h>

  _delay_ms(18); // Ждем 18 мс
  _delay_us(40); // Ждем 40 мкс

_delay_ms(3000);

Это 28 экономии

И  digitalRead(pin) везде замените на сишные строки.

в первых постах этой темы все есть.

 

 

Rhonstin
Offline
Зарегистрирован: 16.05.2017

/*И  digitalRead(pin) везде замените на сишные строки.*/

Если не сложно, можно пример как с while работать и digitalRead в си, потому что вот как раз это у меня и не получилось

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Rhonstin пишет:

/*И  digitalRead(pin) везде замените на сишные строки.*/

Если не сложно, можно пример как с while работать и digitalRead в си, потому что вот как раз это у меня и не получилось

//               AtTity13
//                 ----
// ADC0 (D5) PB5 1|    |8 Vcc
// ADC3 (D3) PB3 2|    |7 PB2 (D2) ADC1
// ADC2 (D4) PB4 3|    |6 PB1 (D1) PWM1
//           GND 4|    |5 PB0 (D0) PWM0
//                 ----


//Можно ждать
while (digitalRead(PB2) == LOW)
while (!(PINB & (1<<PINB2)))
//---	
while (digitalRead(PB2) == HIGH)
while (PINB & (1<<PINB2))

//можно и по условию
if(digitalRead(PB2) == LOW)   
if(!(PINB & (1<<PINB2)))
//---	
if (digitalRead(PB2) == HIGH)
if (PINB & (1<<PINB2))

 

Rhonstin
Offline
Зарегистрирован: 16.05.2017

Отлично, поместилось, спасибо огромное)