Дима, спасибо за ответ - Идея хорошая и по элементной базе 555 -проще и дешевле, но задача стоит в размере в один чип тини -13. Да и по времени нет строгости в 100%, прибилизительно 15 минут и теже два часа и пять секунд )))
Не думал, что такая сложность в этом написать )))) Хотя для меня и книгу для чайников читал и уже собирал программу, но потом в итоге путаюсь, а тем более временные рамки - 2 часа ждать чтоб про тестить - не получается, то не отрабатывает, то что то сбрасывает ((( Спасибо
Я когда-то делал делей(1000) в цикле, ну и задавал там 300 сек - аля 5 мин. Вроде как работало всё...
Но на деле МК работал отнюдь не 5 мин а больше немного.
Спасибо за сообщение ))) Да я уже убедился, что делай может максимум 65000, а на деле это ужепочти 80 секунд )))) Это тоже не проблема в погрешности моего устройства, сам алгаритм не могу написаь - уже голова уплыла далеко, хотя из начально был на верном пути ))))
МАН спасибо - уже пробовал ))) настроил два временных. Подскажите в какую сторону идти - пожал. У меня то задача такая. При включ питания, ждем 15 минут один раз, а потом цикл - два часа работает, пять сек отдыхаем и снова два часа и 5 сек отдых, спасибо
void waitSeconds(unsigned int waitSec) { // функция задержки в секундах
// принимаем значение waitSec которое присвоили функции в коде
while(waitSec > 0){ // если в переменной значение больше чем 0 то...
delay(1000); // ждём 1000 милисек
waitSec--; //декрементируем переменную на 1(отнимаем 1 от переменной)
//и поднимаемся к задержке 1000 милисек
// и так пока переменная не обнулится
} // потом выходим отсюда
}
#define led 2
#define seconds 6600 // к примеру 120 мин
#define seconds2 5 // к примеру 5 секунды
#define waitMillis 800000 // к примеру 15 минут
unsigned long previousMillis = 0;
void setup()
{
pinMode(led, OUTPUT);
}
void loop()
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= waitMillis) {
previousMillis = currentMillis;
digitalWrite(led, HIGH);
waitSeconds(seconds); //цикл задержки ДВА ЧАСА (высокий сигнал)
digitalWrite(led, LOW);
waitSeconds(seconds2); //цикл - ПЯТЬ СЕКУНД - отдыхаем (низкий сигнал)
}
}
void waitSeconds(unsigned int waitSec) { // функция задержки в секундах
// принимаем значение waitSec которое присвоили функции в коде
while(waitSec > 0){ // если в переменной значение больше чем 0 то...
delay(1000); // ждём 1000 милисек
waitSec--; // декрементируем переменную на 1(отнимаем 1 от переменной)
// и поднимаемся к задержке 1000 милисек
// и так пока переменная не обнулится
} // потом выходим отсюда
}
// Sketch uses 580 bytes (56%) of program storage space. Maximum is 1 024 bytes.
// Global variables use 8 bytes of dynamic memory.
Тестить будет весело чувствую.
ЗЫ ну мне прямо таки соавторство грозит для Вашего изобретения ;)
Дорогой друг МАН - если позволите вас так назвать - в честь благодарность ))))
С удовольствием обозначу вас соавтором - хоть как автором. Думаю вы единственный тот человек, который по жизни может протянуть руку и не важно на форуме или в реале ))))
Спасибо огромное, буду тестить, но пока тестирую про межутки буду джигу дрыгу танцевать )))))
Еще раз не земное спасибо ))))
Суть работы, для тех кто не ходил по ссылке, касаемся к девайсу и он всячески мигает светодиодом, отпускаем тухнет.
Забыл вот этот исходник в ардуино иде, предварительно выбрав тиню13-ю в списке:
//#define F_CPU 9600000UL
#include<avr/io.h>
#include<util/delay.h>
#include<avr/wdt.h>
#include<avr/sleep.h>
#include<avr/interrupt.h>
//Состояния девайса
enum DEV_MODE{
M_WAITING_SENSOR, //Ждем отклика от сенсора и спим
M_SENSOR_RECHECK, //После первого отклика перепроверяем
M_GLOW, //Разгораемся
M_GLOW_AND_CHECK, //Светим и проверяем сенсор
M_GLOW_AND_RECKECK, //Перепроверяем, если отпустили
M_FADE}; //Гаснем
unsigned char SensorHi=0; //Переменная, которая будет хранить значение для активного сенсора
unsigned short Delay=0; //Внутренняя переменная для организации долгих задержек
unsigned short PWMs=0; //Скважность ШИМа
unsigned char Mode=0; //Режим работы
void SetTimer(char Mod) //Функция для быстрой переинициализации таймера с режима сенсора на ШИМ
{
if(Mod) //1, проверка сенсора
{
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
}
else //0, ШИМ
{
TCCR0A=0x83;
TCCR0B=0x00;
TCNT0=0x00;
}
}
void Recalibrate() //Калибровка сенсора
{
cli(); //На всякий случай отключаем интеррапты, мало ли что)
SetTimer(1);
DDRB&= 0b11110111;
PORTB|=0b00010000;
TCCR0B=0x01;
while(!(PINB&0b00001000));
TCCR0B=0x00;
DDRB|= 0b00001000;
PORTB&= 0b11101111;
SensorHi=TCNT0+3; //При такой частоте +3 оказалось вполне достаточно, даже слегка много
sei(); //Включаем интеррапты обратно
}
unsigned char CheckSensor()
{
cli();
SetTimer(1);
DDRB&= 0b11110111;
PORTB|=0b00010000;
TCCR0B=0x01;
while(!(PINB&0b00001000));
TCCR0B=0x00;
DDRB|= 0b00001000;
PORTB&= 0b11101111;
unsigned char Time=TCNT0;
sei();
if(Time>SensorHi)
return 0xFF;
return 0x00;
}
ISR(SIG_WATCHDOG_TIMEOUT) //Пустой обработчик прерывания сторожевого таймера
{
__asm__ __volatile__("nop"); //Нужен просто чтобы разбудить систему
}
int main(void)
{
ACSR = 0b1000000; //Настройка режима энергосбережения
DDRB = 0b00011001;
SetTimer(1); //Переключили таймер в режим проверки сенсора
Mode= M_WAITING_SENSOR;
sei();
PORTB=0b00000001; //Зажигаем диод и ждем 4 секунды
for(char i=0;i<40;i++) //Чтобы было понятно, когда именно калибруемся
{
_delay_ms(20);
_delay_ms(20);
_delay_ms(20);
_delay_ms(20);
_delay_ms(20);
}
PORTB=0b00000000; //Гасим диод
Recalibrate(); //Калибруемся
_delay_ms(20);
while(1)
{
switch(Mode)
{
case M_WAITING_SENSOR:
if(CheckSensor())
{
Mode= M_SENSOR_RECHECK;
PWMs=0x00;
}
else
{
//Здесь инициализируется вотчдог таймер и режим энергосбережения
//В процессе отладки пользовался ассемблером, и не стал менять обратно
//То же самое можно написать и с использованием библиотечных функций
sei();
__asm__ __volatile__("in r16, 0x21");
__asm__ __volatile__("ori r16, 0b00011000");
__asm__ __volatile__("out 0x21 ,r16");
__asm__ __volatile__("ldi r16, 0b01000111");
__asm__ __volatile__("out 0x21 ,r16");
__asm__ __volatile__("ldi r16 ,0b00110000");
__asm__ __volatile__("out 0x35 ,r16");
__asm__ __volatile__("sleep");
//сюда мы вернемся уже через 1 секунду, из прерывания
}
break;
case M_SENSOR_RECHECK:
cli();
Delay++;
if(Delay>0x0010)
{
if(!CheckSensor())
{
Mode= M_WAITING_SENSOR;
Delay=0x0000;
}
else
{
Delay=0x0000;
Mode= M_GLOW;
SetTimer(0);
PWMs=0x00;
OCR0A=PWMs;
TCCR0B|=0x01;
}
}
break;
case M_GLOW:
Delay++;
if((PWMs<0xFF)&&(Delay%2==0)) //разгораемся *медленно*, поэтому Delay%2
PWMs++;
if(Delay>0x0200) //Полностью разгорелись
{
SetTimer(1);
PORTB =0b00000001; //Вместо ШИМа напрямую подаем лог. 1
Mode= M_GLOW_AND_CKECK;
Delay=0x0000;
}
break;
case M_GLOW_AND_CKECK:
if(!CheckSensor())
{
Mode=M_GLOW_AND_RECKECK;
PWMs=0xFF;
}
break;
case M_GLOW_AND_RECKECK:
Delay++;
if(Delay>0x0500) //Долгая пауза, чтобы не погаснуть сразу же как отпустят
{ //а посветить еще секунд 20
if(CheckSensor())
{
Mode= M_GLOW_AND_CKECK;
Delay=0x0000;
}
else
{
Delay=0x0000;
Mode=M_FADE;
PWMs=0xFF;
OCR0A=PWMs;
SetTimer(0);
TCCR0B=0x01;
}
}
break;
case M_FADE:
Delay++;
if(Delay%5==0) //Раз в пять Delay перепроверяем сенсор
{
TCCR0B=0x00;
PORTB = 0b00000000;
if(CheckSensor())
{
Mode=0x02; //Если что - начинаем снова разгораться
Delay=0x0000;
}
SetTimer(0);
TCCR0B=0x01;
}
if((PWMs>0)&&(Delay%2==0)) //Медленно гаснем
PWMs--;
if(Delay>0x0200) //Совсем погасли
{
SetTimer(1);
PORTB=0b00000000;
Mode= M_WAITING_SENSOR;
Delay=0x0000;
}
break;
}
OCR0A=PWMs;
_delay_ms(20);
}
}
А оно мне грит мол:
sketch_dec30a.ino: In function 'int main()':
sketch_dec30a:155: error: 'M_GLOW_AND_CKECK' was not declared in this scope
sketch_dec30a:160: error: 'M_GLOW_AND_CKECK' was not declared in this scope
"Это не я, оно само."
Вообщем подскажите что делать? Проект хорош сам по себе, хотеться поиграться... а вдруг что-то подобное получиться?
Доброго дня! Может мне кто нибудь помочь? Задача такая : контроллер, кнопка, 4 светодиода. Нажимаем кнопку - загораются все. Нажимаем еще раз - 1 гаснет, еще - 2-й гаснет, еще - 3-й гаснет, еще - потухли все, еще - все зажглись. И т.д. по кругу.
Посмотрите здесь на форуме есть раздел "Программирование" и сразу же первая тема "Работа с кнопками" и в первом сообщении как раз ваш пример, уже готовый лежит.
Обновил "ядро"(core13_20), пока что нужно протестировать, нужна ваша помощь.
Добавил поддержку как старых версий Arduino IDE так и новых, теоретически.
Поддерживаемые функции:
Так же и при задержке 1 сек (1.3сек). Пробовал на разных частотах, одно и то же. Как вылечить? Мне нужно точно отмерять 10сек.
И как добавить устройство в новой версии Arduino IDE?
Пропишите в начале скетча : #define F_CPU16000000/1.3; //Для 16МГц кварца. 8000000 для 8МГц и так далее.
Добавить нестардартные профили в IDE можно перейдя в Arduino\dist\default_package.zip\ . А там дальше уже разберётесь) Если вы про новые, которые 32битные, то можно в выпадающей менюшке, где выбирались платы, выбрать Менеджер досок и скачать там.
Косяк с частотой был и у меня, но я грешил на сбитую калибровку своих тинек. Оказывается, не так.
нужна помощь. Пытаюсь повторить http://habrahabr.ru/post/244349/ Реле с дистанционным ИК управлением на Attiny13A. Собрал все по схеме из статьи, подключение такое же, но не получается отловить код ИК приемника на тиньке. Решил отложить этот код и попробовал испольовать TinyPCRemote
По пунктам, что было проделано:
1. Полностью использую код из статьи, только подставляя значения кнопок распознаных от пульта.
Светодиоды горят, на нажатие кнопки на пульте никак не реагируют.
Интересная особенность: при использовании библиотеки TinyPCRemote для определения кода кнопки пульта, на нужной кнопке я получаю код - 4095737855. Потом испольовал код и статьи, раскоментировав строки для дебага и залив код в Arduino Uno, я получил значение кода, той же кнопки - 488.
#define IRpin_PIN PINB
#define IRpin 2
#define rLedPin 3
#define gLedPin 4
#define relayPin 1
#define MAXPULSE 5000
#define NUMPULSES 32
#define RESOLUTION 2
#define timeN1 1800000
#define timeN2 3600000
#define timerInterval 500
bool relayState = false;
unsigned long timer = 0;
unsigned long shift = timeN1;//30 min timer by default
unsigned long previousMillis = 0;
bool timerN = false;
byte i = 0;
void setup() {
//default states
DDRB |= (1<<relayPin);
DDRB |= (1<<rLedPin);
DDRB |= (1<<gLedPin);
PORTB &= ~(1<<relayPin);//relay off
PORTB &= ~(1<<rLedPin);//red led off
PORTB |= (1<<gLedPin);//green led on
/*
//for debug
Serial.begin(9600);
Serial.println("Start | "+String(millis()));
//*/
/*
//for debug without ir receiver
pinMode(5, INPUT);
pinMode(6, INPUT);
//*/
}
void shutDown(){
relayState = true;
PORTB |= (1<<relayPin);
PORTB &= ~(1<<gLedPin);
PORTB |= (1<<rLedPin);
//Serial.println("turining off |"+String(millis()));
}
void startUp(){
relayState = false;
PORTB &= ~(1<<relayPin);
PORTB |= (1<<gLedPin);
PORTB &= ~(1<<rLedPin);
//Serial.println("turining on |"+String(millis()));
}
void loop() {
unsigned long irCode = listenForIR(); // Wait for an IR Code
//Serial.println("ir code: "+String(irCode));
if(irCode == 4095737855){//green button
//Serial.println("Pressed green btn |"+String(millis()));
if(timer == 0){//on off mode
if(relayState == true){
startUp();
}else{
shutDown();
}
}else{//cancel timer mode
timer = 0;
PORTB &= ~(1<<rLedPin);//turn off red led
//Serial.println("timer canceled |"+String(millis()));
}
}//end green btn
if(488 == irCode){//red btn
//Serial.println("pressed red btn |"+String(millis()));
if(timer == 0){
if(relayState == 0){
timer = millis();
//Serial.println("timer started |"+String(millis()));
}/*else{
Serial.println("already shutdown |"+String(millis()));
}
//*/
}else{//changing time mode
timerN = !timerN;
if(timerN){
//Serial.println("change 30sec |"+String(millis()));
shift = timeN1;//30 min
}else{
//Serial.println("change 60sec |"+String(millis()));
shift = timeN2;//60 min
}
}
}//end red btn
} // loop end
void checkTimer(){
unsigned long time = millis();
if(time - previousMillis >= timerInterval || previousMillis > time ) {
previousMillis =time;
timer1();
}
}
unsigned long listenForIR() {// IR receive code
byte currentpulse = 0; // index for pulses we're storing
unsigned long irCode = 0; // Wait for an IR Code
irCode = irCode << 1;
while (true) {
unsigned int pulse = 0;// temporary storage timing
//bool true (HIGH)
while (IRpin_PIN & _BV(IRpin)) { // got a high pulse (99% standby time have HIGH)
if(++i > 150){//check timer every 150 iterations (high frequency break ir code timing)
i = 0;
checkTimer();
}
pulse++;
delayMicroseconds(RESOLUTION);
if (((pulse >= MAXPULSE) && (currentpulse != 0)) || currentpulse == NUMPULSES ) {
return irCode;
}
}
//make irCode
irCode = irCode << 1;
if ((pulse * RESOLUTION) > 0 && (pulse * RESOLUTION) < 500) {
irCode |= 0;
}else {
irCode |= 1;
}
currentpulse++;
pulse = 0;
//bool false (LOW)
while (!(IRpin_PIN & _BV(IRpin))) {//wait before new pulse
//checkTimer();
pulse++;
delayMicroseconds(RESOLUTION);
if (pulse >= MAXPULSE || currentpulse == NUMPULSES ) {
//Serial.println(irCode);
return irCode;
}
}
}//end while(1)
}//end listenForIR
//executing every timerInverval
void timer1() {
if(timer != 0){
if(timerN == true){//timeN1 or timeN2
PORTB |= (1<<rLedPin);
}else{//blinking 30min
PORTB ^= (1<<rLedPin);//invert
}
//Serial.println(String((timer+shift - millis())/1000));
}
if(timer != 0 &&(timer+shift < millis() || timer > millis())){
timer = 0;
shutDown();
}
}
2. Испольую для Arduino UNO код из библиотеки TinyPCRemote подставляя свои значения портов.
Всё работает, в порт сыпятся коды кнопок, срабатывает обработка нужной кнопки. Вроде как всё работает.
// IR sensor connected to Arduino D13
#define IRpin_PIN PINB
#define IRpin 5
#define MAXPULSE 5000 // max IR pulse length, default 5 milliseconds
#define NUMPULSES 100 // max IR pulse pairs to sample
#define RESOLUTION 2 // time between IR measurements
uint16_t pulses[NUMPULSES][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
void setup() {
Serial.begin(9600);
Serial.println("TinyPCRemote_CodeReader Ready!");
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);
}
void loop() {
unsigned int highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
while (IRpin_PIN & _BV(IRpin)) { // got a high pulse
highpulse++;
delayMicroseconds(RESOLUTION);
if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
currentpulse=0;
printpulses();
return;
}
}
pulses[currentpulse][0] = highpulse;
while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse
lowpulse++;
delayMicroseconds(RESOLUTION);
if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
currentpulse=0;
printpulses();
return;
}
}
pulses[currentpulse][1] = lowpulse;
currentpulse++;
}
void printpulses() {
unsigned long irCode=0;
for (int i = 0; i < 32; i++) {
irCode=irCode<<1;
if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) {
irCode|=0;
} else {
irCode|=1;
}
}
if (irCode == 4095737855){
digitalWrite(9, LOW);
}
Serial.print("Code for this button: ");
Serial.println(irCode);
}
3. В предыдущий код вставляю значения выводов своей attiny 13a pu 1217. Испольую команды Arduino для наглядности. Размер скетча в двоичном коде: 598 байт.
И ничего не работает, даже светодиоды не загораются.
Подскажите пожалуйста, в чем проблема? Почему даже не выставляются значения для выводов?
Если следом записать блинк с этими же выводами (3,4), то все работает
#define IRpin_PIN PINB
#define IRpin 2
#define MAXPULSE 5000 // max IR pulse length, default 5 milliseconds
#define NUMPULSES 100 // max IR pulse pairs to sample
#define RESOLUTION 2 // time between IR measurements
uint16_t pulses[NUMPULSES][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
void setup() {
// Serial.begin(9600);
// Serial.println("TinyPCRemote_CodeReader Ready!");
pinMode(3, OUTPUT);
digitalWrite(3, HIGH);
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
}
void loop() {
unsigned int highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
while (IRpin_PIN & _BV(IRpin)) { // got a high pulse
highpulse++;
delayMicroseconds(RESOLUTION);
if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
currentpulse=0;
printpulses();
return;
}
}
pulses[currentpulse][0] = highpulse;
while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse
lowpulse++;
delayMicroseconds(RESOLUTION);
if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
currentpulse=0;
printpulses();
return;
}
}
pulses[currentpulse][1] = lowpulse;
currentpulse++;
}
void printpulses() {
unsigned long irCode=0;
for (int i = 0; i < 32; i++) {
irCode=irCode<<1;
if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) {
irCode|=0;
} else {
irCode|=1;
}
}
if (irCode == 4095737855){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
// Serial.print("Code for this button: ");
//Serial.println(irCode);
}
p.s. все собрано так, что проблемы в контактах или подключении нет. Тини стоит на макетке, к 1,5,6,7 выводу припаяны провода для подключения Arduino при програмировании. На 7 выводе так же ИК транзистор, т.е. при надобности я перепрошиваю Arduino, и ничего не меняя в подключении смотрю что приходит на 13 порт от ИК транзистора.
Мои старые наработки: Сверх энергосберегающий маячок на ATtiny13, который мигает светодиодом на ножке PB0 раз в 8 секунд и засыпает, причём когда спит то, практически ничего не потребляет.
#define F_CPU 1200000UL // Частота МК в герцах
#include <avr/io.h>
#include <avr/wdt.h> // здесь организована работа с ватчдогом
#include <avr/sleep.h> // здесь описаны режимы сна
#include <avr/power.h>
#include <avr/interrupt.h> // работа с прерываниями
#include <util/delay.h>
#define led 0 // PB0
int main( void ) // по аналогии как void setup()
{
wdt_reset(); // сначало нужно сбросить вачдог
// иначе может быть ребут
pinMode(led, OUTPUT);
while(1){ // вечный цикл, аналог void loop()
digitalWrite(led, HIGH);
_delay_ms(500);
digitalWrite(led, LOW);
//_delay_ms(500);
sleepFewSeconds(); // сон на 8 сек.
}
return 0;
}
void sleepFewSeconds() {
wdt_reset(); // сбрасываем ватчдог
PORTB = 0x00; // подаём лог. 0 на все порты
DDRB = 0x00;
ADCSRA &= ~(1 << ADEN); // отключаем АЦП
// иначе будет лишний ток потребления в режиме сна
MCUSR &= ~(1<<WDRF);
/* Start the WDT Config change sequence. */
WDTCR |= (1<<WDCE) | (1<<WDE);
/* Configure the prescaler and the WDT for interrupt mode only*/
// Раскомментируй тот интервал, какой нужно
WDTCR = (1<<WDP0) | (1<<WDP3) | (1<<WDTIE); // 8sec
//WDTCR = (1<<WDP2) | (1<<WDP1) | (1<<WDTIE); // 2sec
//WDTCR = (1<<WDP2) | (1<<WDP0) | (1<<WDTIE); // 0.5sec
WDTCR |= (1<<WDTIE);
sei(); // Enable global interrupts
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
while(1) {
sleep_enable(); // разрешаем сон
sleep_cpu(); // спать!
sleep_disable();
}
}
Код говно, работает через одно место, но работает!
Может кто подскажет что не так? Нутром чую что это работает через одно место.
Мне нужно чтобы микроконтроллер заводил вачдог на 1 / 2 / 4 / 8 сек, засыпал, причём очень крепко, даже АЦП чтобы не работал и потом по вачдогу от ресета просыпался, исполнял что нужно и когда нужно засыпал опять на некоторое время.
Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino. Кто-нибудь решал такую проблему? Как узнать какое значение кнопок ик-пульта получается в тини?
Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino.
Как и что там обрабатывается завистит от конкретной прошивки (программы). Прошивка (программа) для ATtiny и для ATmega может быть разной, т.к. в микроконтроллерах разные регистры и т.д. Либо ищете готовый код/библиотеки под конткретный микроконтроллер, либо берёте на него даташит, изучаете, и самостоятельно программируете.
Серьёзно? От программы зависит? Да еще и прошивки нужны?
Я в нескольких сообщениях до этого описал суть проблемы с кодом, мнением, и вопросами. Теперь я точно убедился, что код от пульта обрабатывается по разному.
Приведу два своих листинга, один для ардуино уно, второй для Attiny13, может кто-то сможет подсказать.
#define IRpin_PIN PINB
#define IRpin 3
#define rLedPin 0
#define gLedPin 1
#define relayPin 2
#define MAXPULSE 5000
#define NUMPULSES 32
#define RESOLUTION 2
#define timeN1 1800000
#define timeN2 3600000
#define timerInterval 500
bool relayState = false;
int timer = 0;
int shift = timeN1;//30 min timer by default
int previousMillis = 0;
bool timerN = false;
byte i = 0;
void setup() {
//default states
DDRB |= (1<<relayPin);
DDRB |= (1<<rLedPin);
DDRB |= (1<<gLedPin);
PORTB &= ~(1<<relayPin);//relay off
PORTB |= (1<<rLedPin);//red led off
PORTB |= (1<<gLedPin);//green led on
Serial.begin(9600);
Serial.println("Start | "+String(millis()));
}
void shutDown(){
relayState = true;
PORTB |= (1<<relayPin);
PORTB &= ~(1<<gLedPin);
PORTB |= (1<<rLedPin);
Serial.println("turining off |"+String(millis()));
}
void startUp(){
relayState = false;
PORTB &= ~(1<<relayPin);
PORTB |= (1<<gLedPin);
PORTB &= ~(1<<rLedPin);
Serial.println("turining on |"+String(millis()));
}
void loop() {
int irCode = listenForIR(); // Wait for an IR Code
Serial.println("ir code: "+String(irCode));
if(irCode == 488){//green button
Serial.println("Pressed green btn |"+String(millis()));
PORTB &= ~(1<<rLedPin);//red led off
PORTB &= ~(1<<gLedPin);//green led off
}
if(900 == irCode){//red btn
Serial.println("pressed red btn |"+String(millis()));
if(timer == 0){
if(relayState == 0){
timer = millis();
Serial.println("timer started |"+String(millis()));
}else{
Serial.println("already shutdown |"+String(millis()));
}
}else{//changing time mode
timerN = !timerN;
if(timerN){
Serial.println("change 20sec |"+String(millis()));
shift = timeN1;//30 min
}else{
Serial.println("change 10sec |"+String(millis()));
shift = timeN2;//30 min
}
}
}//end red btn
} // loop end
void checkTimer(){
int time = millis();
if(time - previousMillis >= timerInterval || previousMillis > time ) {
previousMillis =time;
timer1();
}
}
int listenForIR() {// IR receive code
byte currentpulse = 0; // index for pulses we're storing
int irCode = 0; // Wait for an IR Code
irCode = irCode << 1;
while (true) {
unsigned int pulse = 0;// temporary storage timing
//bool true (HIGH)
while (IRpin_PIN & _BV(IRpin)) { // got a high pulse (99% standby time have HIGH)
if(++i > 150){//check timer every 150 iterations (high frequency break ir code timing)
i = 0;
checkTimer();
}
pulse++;
delayMicroseconds(RESOLUTION);
if (((pulse >= MAXPULSE) && (currentpulse != 0)) || currentpulse == NUMPULSES ) {
return irCode;
}
}
//make irCode
irCode = irCode << 1;
if ((pulse * RESOLUTION) > 0 && (pulse * RESOLUTION) < 500) {
irCode |= 0;
}else {
irCode |= 1;
}
currentpulse++;
pulse = 0;
//bool false (LOW)
while (!(IRpin_PIN & _BV(IRpin))) {//wait before new pulse
//checkTimer();
pulse++;
delayMicroseconds(RESOLUTION);
if (pulse >= MAXPULSE || currentpulse == NUMPULSES ) {
Serial.println(irCode);
//return irCode = 488;
}
}
}//end while(1)
}//end listenForIR
//executing every timerInverval
void timer1() {
if(timer != 0){
if(timerN == true){//timeN1 or timeN2
PORTB |= (1<<rLedPin);
}else{//blinking 30min
PORTB ^= (1<<rLedPin);//invert
}
Serial.println(String((timer+shift - millis())/1000));
}
if(timer != 0 &&(timer+shift < millis() || timer > millis())){
timer = 0;
shutDown();
}
}
Код для тини:
//original algorithm & code https://github.com/nathanchantrell/TinyPCRemote/blob/master/TinyPCRemote...
//original head:
////----------------------------------------------------------------------------------------------------------------------
//// TinyPCRemote_CodeReader
//// By Nathan Chantrell http://nathan.chantrell.net
//// Reads codes from the remote control and outputs to serial monitor
//// Enter the resulting codes in TinyPCRemote_ATtiny85.ino
////
//// Licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence:
//// http://creativecommons.org/licenses/by-sa/3.0/
////----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
//modified and optimized for attiny13 by fishlabsoman 7.11.2014
//----------------------------------------------------------------------------------------------------------------------
#define IRpin_PIN PINB
#define IRpin 0 // ИК подключен к PB0
#define rLedPin 4 //BP4
#define gLedPin 3 //PB3
#define relayPin 1
#define MAXPULSE 5000
#define NUMPULSES 32
#define RESOLUTION 2
byte i = 0;
void setup() {
//default states
DDRB |= (1<<relayPin);
DDRB |= (1<<rLedPin);
DDRB |= (1<<gLedPin);
PORTB &= ~(1<<relayPin);//relay off
PORTB |= (1<<rLedPin);//red led on
PORTB |= (1<<gLedPin);//green led on
/*
//for debug
Serial.begin(9600);
Serial.println("Start | "+String(millis()));
//*/
}
void loop() {
int irCode = listenForIR(); // Wait for an IR Code
//Serial.println("ir code: "+String(irCode));
// irCode = 488;
// если присвоить irCode своё значение и указать его в условии.
//То срабатывание будет происходить при нажатии любой кнопки пульта
//Это моя проверка правильности подключения ИК транзистора к тини
//488 код который кнопки который выдал мне Ардуино
if(irCode ==488){//green button
//Serial.println("Pressed green btn |"+String(millis()));
PORTB &= ~(1<<rLedPin);//red led off
PORTB &= ~(1<<gLedPin);//green led off
}//end green btn
} // loop end
int listenForIR() {// IR receive code
byte currentpulse = 0; // index for pulses we're storing
int irCode = 0; // Wait for an IR Code
irCode = irCode << 1;
while (true) {
unsigned int pulse = 0;// temporary storage timing
//bool true (HIGH)
while (IRpin_PIN & _BV(IRpin)) { // got a high pulse (99% standby time have HIGH)
if(++i > 150){//check timer every 150 iterations (high frequency break ir code timing)
i = 0;
//checkTimer();
}
pulse++;
delayMicroseconds(RESOLUTION);
if (((pulse >= MAXPULSE) && (currentpulse != 0)) || currentpulse == NUMPULSES ) {
return irCode;
}
}
//make irCode
irCode = irCode << 1;
if ((pulse * RESOLUTION) > 0 && (pulse * RESOLUTION) < 500) {
irCode |= 0;
}else {
irCode |= 1;
}
currentpulse++;
pulse = 0;
//bool false (LOW)
while (!(IRpin_PIN & _BV(IRpin))) {//wait before new pulse
//checkTimer();
pulse++;
delayMicroseconds(RESOLUTION);
if (pulse >= MAXPULSE || currentpulse == NUMPULSES ) {
//Serial.println(irCode);
return irCode;
}
}
}//end while(1)
}//end listenForIR
Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino. Кто-нибудь решал такую проблему? Как узнать какое значение кнопок ик-пульта получается в тини?
Попробую изложить свои мысли. Дело скорее всего в несоответствии частоты. Т.е. ардуино работает на одной частоте. Вы считываете значение кнопки пульта. Потом это значение записываете в тиньку, а она работает на другой частоте, из-за это ваш ик-пакет искажается.
Тоже так думаю. Тини на 9.6мгц, Ардуино 16. Впринципе сталкивался с таким когда запускали дисплей 16*4.
У меня даже идей нет, как это можно тут обойти. Хотя появилась мысль сделать еще програмный UART в этом коде, который будет принимать число из переменной irCode, и как-то слать его дальше. Но это выглядит как велосипед, хотелось бы проще.
Мне нужно чтобы микроконтроллер заводил вачдог на 1 / 2 / 4 / 8 сек, засыпал, причём очень крепко, даже АЦП чтобы не работал и потом по вачдогу от ресета просыпался, исполнял что нужно и когда нужно засыпал опять на некоторое время.
Код мега тупой и идиотский, и вообще велосипед с костылями, но ничего лучше я не придумал. К тому же, именно этим способом я убедился, что в тини код определяется иначе чем в ардуино.
Проверял это значение кнопки на тини85 с 1, 8, 16мгц конфигурацией - работает. Проверял на тини13А с 1.2, 4.8, 9.6мгц - работает. Т.е. дело не в частоте работы, а в чем-то другом. Есть идеи в чем?
Ещё утром обнаружил, что при irCode=2052, срабатывает еще 4 кнопки на пульте. Это очень плохо :(. Пробовал менять подтяжку ИК, и делал проверки полученного irCode. Пока не получается понять в чем дело.
Добрый день! Можете помочь? Мне нужно на тиньке сделать так что бы поочереди загорались 3 светодиода. Но при этом что бы подстроечным резистором можно было бы регулировать их скорость (от 200мс до 2000мс). Просто что бы мограли, я осилил, а вот управление морганием никак не могу.
Дима, спасибо за ответ - Идея хорошая и по элементной базе 555 -проще и дешевле, но задача стоит в размере в один чип тини -13. Да и по времени нет строгости в 100%, прибилизительно 15 минут и теже два часа и пять секунд )))
Не думал, что такая сложность в этом написать )))) Хотя для меня и книгу для чайников читал и уже собирал программу, но потом в итоге путаюсь, а тем более временные рамки - 2 часа ждать чтоб про тестить - не получается, то не отрабатывает, то что то сбрасывает ((( Спасибо
Я когда-то делал делей(1000) в цикле, ну и задавал там 300 сек - аля 5 мин. Вроде как работало всё...
Но на деле МК работал отнюдь не 5 мин а больше немного.
Спасибо за сообщение ))) Да я уже убедился, что делай может максимум 65000, а на деле это ужепочти 80 секунд )))) Это тоже не проблема в погрешности моего устройства, сам алгаритм не могу написаь - уже голова уплыла далеко, хотя из начально был на верном пути ))))
HWman, это скетч для меня или подобие для моего решения ????
HWman, это скетч для меня или подобие для моего решения ????
Светодиод то светит 5 мин то не светит 5 мин, такой себе заторможеный блинк.
МАН спасибо - уже пробовал ))) настроил два временных. Подскажите в какую сторону идти - пожал. У меня то задача такая. При включ питания, ждем 15 минут один раз, а потом цикл - два часа работает, пять сек отдыхаем и снова два часа и 5 сек отдых, спасибо
нижний блок не могу понять зачем, т.е. за что он отвечает
Дорогой человек МАН.
Можете проверить мое домашнее задание )))))))))))) Спасибо ))))
Мужикик, мне тут немного подсказали, не могли бы проверить домашнее задание ??!!
Спасибо.
Тестить будет весело чувствую.
ЗЫ ну мне прямо таки соавторство грозит для Вашего изобретения ;)
Дорогой друг МАН - если позволите вас так назвать - в честь благодарность ))))
С удовольствием обозначу вас соавтором - хоть как автором. Думаю вы единственный тот человек, который по жизни может протянуть руку и не важно на форуме или в реале ))))
Спасибо огромное, буду тестить, но пока тестирую про межутки буду джигу дрыгу танцевать )))))
Еще раз не земное спасибо ))))
Я в таких случаях говорю - сделаешь что-то когда-то кому-то без пользы для себя.
Ну почему же без пользы еще какая польза - я вам здоровья желаю )))))))
Ну почему же без пользы еще какая польза - я вам здоровья желаю )))))))
И тебе того же.
Юзал ядро на arduino-1.5.8 в целом остался доволен, стоит ли обновить? Нужно больше тестить...
http://arduino.ru/forum/programmirovanie/proshivka-hex-failov-pri-pomosh... загляните сюда.
Привет, нагуглил вот такой девайс:
http://www.youtube.com/watch?v=NJsCUbdwulE#t=57
Вот сцылка на хабр:
http://habrahabr.ru/post/111671/
Вот схема:
Сенсор выглядит вот так:
Суть работы, для тех кто не ходил по ссылке, касаемся к девайсу и он всячески мигает светодиодом, отпускаем тухнет.
Забыл вот этот исходник в ардуино иде, предварительно выбрав тиню13-ю в списке:
А оно мне грит мол:
"Это не я, оно само."
Вообщем подскажите что делать? Проект хорош сам по себе, хотеться поиграться... а вдруг что-то подобное получиться?
https://www.youtube.com/watch?v=OBspj1XJ0JY
Мозги включил и сделал вот так:
Может кто потестить раньше меня? Пока нету возможности проверить в железе.
Доброго дня! Может мне кто нибудь помочь? Задача такая : контроллер, кнопка, 4 светодиода. Нажимаем кнопку - загораются все. Нажимаем еще раз - 1 гаснет, еще - 2-й гаснет, еще - 3-й гаснет, еще - потухли все, еще - все зажглись. И т.д. по кругу.
а проблема то в чем? не знаешь как писать или что то конкретное?
Честно говоря не знаю как написать...
хочешь научится или чтобы за тебя сделали?
Конечно научиться. Уже делал проекты на ардуине. Здесь не соображу как выдавать сигнал на разных выходах при нажатии одной кнопки.
да сделай просто счетчик от 0 до 4. при достижении 0 он обнуляется.
задай условия в зависимости от состояния счетчика зажигать нужные светодиоды
Посмотрите здесь на форуме есть раздел "Программирование" и сразу же первая тема "Работа с кнопками" и в первом сообщении как раз ваш пример, уже готовый лежит.
Вот написал...
Все работает как хотелось. Возникла еще одна "хотелка" не соображу как реализовать. Нужно чтоб при удержании кнопки все гасло до последующего нажатия.
добавиь переменную unsigned long для времени. при нажатии записывай в нее текущее время через функцию millis
вообще в разделе работа с кнопками это все есть
Сделал проще:
Посыл в раздел работа с кнопками очень действенный! Спасибо!
Ну наконец-то написал. Как восстановить неправильно выставленные фьюзы в ATtiny:
http://habrahabr.ru/post/249967/
Пользуйтесь.
хочешь научится или чтобы за тебя сделали?
Вспомнил себя два с половиной года назад ;) когда увидел эту цитату.
помогите, все делаю как описано выше, прошиваю ТИНКУ и он выдает такое
помогите...
Хз почему так, пишет что не видит, пишет типа дважды перепроверьте подключение к ардуине.
Программный UART на ATtiny13
Обновил "ядро"(core13_20), пока что нужно протестировать, нужна ваша помощь.
Добавил поддержку как старых версий Arduino IDE так и новых, теоретически.
Поддерживаемые функции:
"* = Partial support
map()
random()
randomSeed()
millis()
micros()
delay()
delayMicroseconds() *
analogRead()
analogWrite()
pinMode()
digitalRead()
digitalWrite()
pulseIn() (Untested)
shiftIn() (Untested)
shiftOut() (Untested)"
Установка та же:
Скачать ядро можно тут:
https://vk.com/doc256435878_378485100
!Для работы с частотами ниже 1 мГц используем скетч Arduino slow ISP, но я не тестировал, так что тоже теоретически.
Взято отсюда:
http://forum.arduino.cc/index.php?topic=89781.msg2160449#msg2160449
Не коректно работает Delay =\
При задержке 10сек получается 13 с хвостом.
Так же и при задержке 1 сек (1.3сек). Пробовал на разных частотах, одно и то же. Как вылечить? Мне нужно точно отмерять 10сек.
И как добавить устройство в новой версии Arduino IDE?
>>помогите, все делаю как описано выше, прошиваю ТИНКУ и он выдает такое
Мне помог резистор между 5V и RESET Arduino
Не коректно работает Delay =\
При задержке 10сек получается 13 с хвостом.
Так же и при задержке 1 сек (1.3сек). Пробовал на разных частотах, одно и то же. Как вылечить? Мне нужно точно отмерять 10сек.
И как добавить устройство в новой версии Arduino IDE?
Пропишите в начале скетча : #define F_CPU 16000000/1.3; //Для 16МГц кварца. 8000000 для 8МГц и так далее.
Добавить нестардартные профили в IDE можно перейдя в Arduino\dist\default_package.zip\ . А там дальше уже разберётесь) Если вы про новые, которые 32битные, то можно в выпадающей менюшке, где выбирались платы, выбрать Менеджер досок и скачать там.
Косяк с частотой был и у меня, но я грешил на сбитую калибровку своих тинек. Оказывается, не так.
Добрый день,
нужна помощь. Пытаюсь повторить http://habrahabr.ru/post/244349/ Реле с дистанционным ИК управлением на Attiny13A. Собрал все по схеме из статьи, подключение такое же, но не получается отловить код ИК приемника на тиньке. Решил отложить этот код и попробовал испольовать TinyPCRemote
По пунктам, что было проделано:
1. Полностью использую код из статьи, только подставляя значения кнопок распознаных от пульта.
Светодиоды горят, на нажатие кнопки на пульте никак не реагируют.
Интересная особенность: при использовании библиотеки TinyPCRemote для определения кода кнопки пульта, на нужной кнопке я получаю код - 4095737855. Потом испольовал код и статьи, раскоментировав строки для дебага и залив код в Arduino Uno, я получил значение кода, той же кнопки - 488.
2. Испольую для Arduino UNO код из библиотеки TinyPCRemote подставляя свои значения портов.
Всё работает, в порт сыпятся коды кнопок, срабатывает обработка нужной кнопки. Вроде как всё работает.
3. В предыдущий код вставляю значения выводов своей attiny 13a pu 1217. Испольую команды Arduino для наглядности. Размер скетча в двоичном коде: 598 байт.
И ничего не работает, даже светодиоды не загораются.
Подскажите пожалуйста, в чем проблема? Почему даже не выставляются значения для выводов?
Если следом записать блинк с этими же выводами (3,4), то все работает
p.s. все собрано так, что проблемы в контактах или подключении нет. Тини стоит на макетке, к 1,5,6,7 выводу припаяны провода для подключения Arduino при програмировании. На 7 выводе так же ИК транзистор, т.е. при надобности я перепрошиваю Arduino, и ничего не меняя в подключении смотрю что приходит на 13 порт от ИК транзистора.
Мои старые наработки: Сверх энергосберегающий маячок на ATtiny13, который мигает светодиодом на ножке PB0 раз в 8 секунд и засыпает, причём когда спит то, практически ничего не потребляет.
Код говно, работает через одно место, но работает!
Может кто подскажет что не так? Нутром чую что это работает через одно место.
Мне нужно чтобы микроконтроллер заводил вачдог на 1 / 2 / 4 / 8 сек, засыпал, причём очень крепко, даже АЦП чтобы не работал и потом по вачдогу от ресета просыпался, исполнял что нужно и когда нужно засыпал опять на некоторое время.
Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino. Кто-нибудь решал такую проблему? Как узнать какое значение кнопок ик-пульта получается в тини?
Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino.
Как и что там обрабатывается завистит от конкретной прошивки (программы). Прошивка (программа) для ATtiny и для ATmega может быть разной, т.к. в микроконтроллерах разные регистры и т.д. Либо ищете готовый код/библиотеки под конткретный микроконтроллер, либо берёте на него даташит, изучаете, и самостоятельно программируете.
Серьёзно? От программы зависит? Да еще и прошивки нужны?
Я в нескольких сообщениях до этого описал суть проблемы с кодом, мнением, и вопросами. Теперь я точно убедился, что код от пульта обрабатывается по разному.
Приведу два своих листинга, один для ардуино уно, второй для Attiny13, может кто-то сможет подсказать.
Код для тини:
Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino. Кто-нибудь решал такую проблему? Как узнать какое значение кнопок ик-пульта получается в тини?
Попробую изложить свои мысли. Дело скорее всего в несоответствии частоты. Т.е. ардуино работает на одной частоте. Вы считываете значение кнопки пульта. Потом это значение записываете в тиньку, а она работает на другой частоте, из-за это ваш ик-пакет искажается.
Тоже так думаю. Тини на 9.6мгц, Ардуино 16. Впринципе сталкивался с таким когда запускали дисплей 16*4.
У меня даже идей нет, как это можно тут обойти. Хотя появилась мысль сделать еще програмный UART в этом коде, который будет принимать число из переменной irCode, и как-то слать его дальше. Но это выглядит как велосипед, хотелось бы проще.
Вопрос конечно, почему у автора статьи всё работает http://habrahabr.ru/post/244349/
Мне нужно чтобы микроконтроллер заводил вачдог на 1 / 2 / 4 / 8 сек, засыпал, причём очень крепко, даже АЦП чтобы не работал и потом по вачдогу от ресета просыпался, исполнял что нужно и когда нужно засыпал опять на некоторое время.
кладезь знаний http://www.gammon.com.au/power
burbuzin1, попробуйте залить скетч выбрав тиньку 1,2 Мгц (default).
Пробовал, не помогает.
Появился прогресс. Плюнул на всё, решил пойти на пролом. Сделал код который делением и остатком от деления помог мне узнать чему равен irCode в тини.
Вкратце:
если q==5, мигаем 5 раз, если q==2, мигаем 2 раза итд.
q = irCode / 1000 - получаем первый символ. 2. 2ХХХ
q = (irCode-2000)/100 - получаем второй символ. 10.20ХХ
q = (irCode-2000)/10 - получаем третий символ. 5. 205Х
q = (irCode-2050)%10 - получаем четвертый символ. 2. 2052
Код мега тупой и идиотский, и вообще велосипед с костылями, но ничего лучше я не придумал. К тому же, именно этим способом я убедился, что в тини код определяется иначе чем в ардуино.
Проверял это значение кнопки на тини85 с 1, 8, 16мгц конфигурацией - работает. Проверял на тини13А с 1.2, 4.8, 9.6мгц - работает. Т.е. дело не в частоте работы, а в чем-то другом. Есть идеи в чем?
Ещё утром обнаружил, что при irCode=2052, срабатывает еще 4 кнопки на пульте. Это очень плохо :(. Пробовал менять подтяжку ИК, и делал проверки полученного irCode. Пока не получается понять в чем дело.
Добрый день! Можете помочь? Мне нужно на тиньке сделать так что бы поочереди загорались 3 светодиода. Но при этом что бы подстроечным резистором можно было бы регулировать их скорость (от 200мс до 2000мс). Просто что бы мограли, я осилил, а вот управление морганием никак не могу.
вместо delay используй: