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

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

art-mistik пишет:

Дима, спасибо за ответ - Идея хорошая и по элементной базе 555 -проще и дешевле, но задача стоит в размере в один чип тини -13. Да и по времени нет строгости в 100%, прибилизительно 15 минут и теже два часа и пять секунд )))
Не думал, что такая сложность в этом написать ))))  Хотя для меня и книгу для чайников читал и уже собирал программу, но потом в итоге путаюсь, а тем более временные рамки - 2 часа ждать чтоб про тестить - не получается, то не отрабатывает, то что то сбрасывает ((( Спасибо

Я когда-то делал делей(1000) в цикле, ну и задавал там 300 сек - аля 5 мин. Вроде как работало всё...
Но на деле МК работал отнюдь не 5 мин а больше немного.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
#define led 0 
#define seconds 300 // 5 мин

void setup() {
  pinMode(led, OUTPUT);
}

void loop() {
  digitalWrite(led, HIGH);
  waitSeconds(seconds);
  digitalWrite(led, LOW);
  waitSeconds(seconds);
}

void waitSeconds(unsigned int waitSec) {
  while(waitSec > 0){
    delay(1000);
    waitSec--;
  }
}

 

art-mistik
Offline
Зарегистрирован: 05.12.2014

Спасибо за сообщение ))) Да я уже убедился, что делай может максимум 65000, а на деле это ужепочти 80 секунд )))) Это тоже не проблема в погрешности моего устройства, сам алгаритм не могу написаь - уже голова уплыла далеко, хотя из начально был на верном пути ))))

art-mistik
Offline
Зарегистрирован: 05.12.2014

HWman, это скетч для меня или подобие для моего решения ????

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

art-mistik пишет:

HWman, это скетч для меня или подобие для моего решения ????

Светодиод то светит 5 мин то не светит 5 мин, такой себе заторможеный блинк.

art-mistik
Offline
Зарегистрирован: 05.12.2014

МАН спасибо - уже пробовал ))) настроил два временных. Подскажите в какую сторону идти - пожал. У меня то задача такая. При включ питания, ждем 15 минут один раз, а потом цикл - два часа работает, пять сек отдыхаем и снова два часа и 5 сек отдых, спасибо

art-mistik
Offline
Зарегистрирован: 05.12.2014
#define led 2
#define seconds 300 // 5 мин
 #define seconds2 3 // 3 сек
void setup() {
  pinMode(led, OUTPUT);
}
 
void loop() {
  digitalWrite(led, HIGH);
  waitSeconds(seconds);
  digitalWrite(led, LOW);
  waitSeconds(seconds2);
}
 
void waitSeconds(unsigned int waitSec) {
  while(waitSec > 0){
    delay(1000);
    waitSec--;
  }
}

нижний блок не могу понять зачем, т.е. за что он отвечает

art-mistik
Offline
Зарегистрирован: 05.12.2014

Дорогой человек МАН.
Можете проверить мое домашнее задание )))))))))))) Спасибо ))))
 

#define led 2
#define seconds 6600 // к примеру 120 минут
#define seconds2 5 // к примеру 5 секунды
#define seconds3 800000 // к примеру 15 минут
unsigned long currentTime;
 
void setup()
{
  pinMode(led, OUTPUT);
  currentTime = millis();
} 
void loop() 
{
  currentTime = millis();
  if(currentTime >= seconds3)      // генераия 15 минут - один раз
 
    digitalWrite(led, HIGH);
  waitSeconds(seconds);      //цикл задержки ДВА ЧАСА (высокий сигнал)
  digitalWrite(led, LOW);
  waitSeconds(seconds2);      //цикл - ПЯТЬ СЕКУНД - отдыхаем (низкий сигнал)
}
 
void waitSeconds(unsigned int waitSec) {
  while(waitSec > 0){
    delay(1000);
    waitSec--;
  }
}
art-mistik
Offline
Зарегистрирован: 05.12.2014

Мужикик, мне тут немного подсказали, не могли бы проверить домашнее задание ??!!
Спасибо.

 

#define led 2
#define seconds 6600 // к примеру 120 мин
#define seconds2 5 // к примеру 5 секунды
#define seconds3 800000 // к примеру 15 минут
unsigned long currentTime;
void setup()
{
  pinMode(led, OUTPUT);
  currentTime = millis();
  }
 
void loop() 
{
  currentTime = millis();
  if(currentTime >= seconds3)      // генерация 15 минут - один раз
 
 
    digitalWrite(led, HIGH);
  waitSeconds(seconds);      //цикл задержки ДВА ЧАСА (высокий сигнал)
  digitalWrite(led, LOW);
  waitSeconds(seconds2);      //цикл - ПЯТЬ СЕКУНД - отдыхаем (низкий сигнал)
}
 
void waitSeconds(unsigned int waitSec) {
  while(waitSec > 0){
    delay(1000);
    waitSec--;
  }
}
 
HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
void waitSeconds(unsigned int waitSec) { // функция задержки в секундах
                                        // принимаем значение waitSec которое присвоили функции в коде
  while(waitSec > 0){ // если в переменной значение больше чем 0 то...
    delay(1000); // ждём 1000 милисек
    waitSec--; //декрементируем переменную на 1(отнимаем 1 от переменной) 
                       //и поднимаемся к задержке 1000 милисек
                      // и так пока переменная не обнулится
  } // потом выходим отсюда 
} 

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
#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.

 

Тестить будет весело чувствую.
ЗЫ ну мне прямо таки соавторство грозит для Вашего изобретения ;) 

art-mistik
Offline
Зарегистрирован: 05.12.2014

Дорогой друг МАН - если позволите вас так назвать - в честь благодарность ))))
С удовольствием обозначу вас соавтором - хоть как автором. Думаю вы единственный тот человек, который по жизни может протянуть руку и не важно на форуме или в реале ))))

Спасибо огромное, буду тестить, но пока тестирую про межутки буду джигу дрыгу танцевать )))))
Еще раз не земное спасибо ))))

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Я в таких случаях говорю - сделаешь что-то когда-то кому-то без пользы для себя.

art-mistik
Offline
Зарегистрирован: 05.12.2014

Ну почему же без пользы еще какая польза - я вам здоровья желаю )))))))

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

art-mistik пишет:

Ну почему же без пользы еще какая польза - я вам здоровья желаю )))))))

И тебе того же.

Юзал ядро на arduino-1.5.8 в целом остался доволен, стоит ли обновить? Нужно больше тестить...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Привет, нагуглил вот такой девайс:

http://www.youtube.com/watch?v=NJsCUbdwulE#t=57

Вот сцылка на хабр:

http://habrahabr.ru/post/111671/

Вот схема:

Сенсор выглядит вот так:

Суть работы, для тех кто не ходил по ссылке, касаемся к девайсу и он всячески мигает светодиодом, отпускаем тухнет.
Забыл вот этот исходник в ардуино иде, предварительно выбрав тиню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

"Это не я, оно само."

Вообщем подскажите что делать? Проект хорош сам по себе, хотеться поиграться... а вдруг что-то подобное получиться?

https://www.youtube.com/watch?v=OBspj1XJ0JY

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Мозги включил и сделал вот так:

 

//#define F_CPU 9600000UL  
#include<avr/io.h>
#include<util/delay.h>
#include<avr/wdt.h>
#include<avr/sleep.h>
#include<avr/interrupt.h>

//Состояния девайса

#define M_WAITING_SENSOR 0	//Ждем отклика от сенсора и спим
#define M_SENSOR_RECHECK 1	//После первого отклика перепроверяем
#define M_GLOW 2			//Разгораемся
#define M_GLOW_AND_CKECK 3	//Светим и проверяем сенсор
#define M_GLOW_AND_RECKECK 4 //Перепроверяем, если отпустили
#define M_FADE 5			//Гаснем

unsigned char DEV_MODE=0;
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);                                            
  }
}

Может кто потестить раньше меня? Пока нету возможности проверить в железе.

vvg10
vvg10 аватар
Offline
Зарегистрирован: 18.04.2013

Доброго дня! Может мне кто нибудь помочь? Задача такая : контроллер, кнопка, 4 светодиода. Нажимаем кнопку - загораются все. Нажимаем еще раз - 1 гаснет, еще - 2-й гаснет, еще - 3-й гаснет, еще - потухли все, еще - все зажглись. И т.д. по кругу.

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

а проблема то в чем? не знаешь как писать или что то конкретное?

vvg10
vvg10 аватар
Offline
Зарегистрирован: 18.04.2013

Честно говоря не знаю как написать...

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

хочешь научится или чтобы за тебя сделали?

vvg10
vvg10 аватар
Offline
Зарегистрирован: 18.04.2013

Конечно научиться. Уже делал проекты на ардуине. Здесь не соображу как выдавать сигнал на разных выходах при нажатии одной кнопки.

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

да сделай просто счетчик от 0 до 4. при достижении 0 он обнуляется. 

задай условия в зависимости от состояния счетчика зажигать нужные светодиоды

Kolchugin
Offline
Зарегистрирован: 15.12.2013

Посмотрите здесь на форуме есть раздел "Программирование" и сразу же первая тема "Работа с кнопками" и в первом сообщении как раз ваш пример, уже готовый лежит.

vvg10
vvg10 аватар
Offline
Зарегистрирован: 18.04.2013

Вот написал...

#include <util/delay.h>

int knopka=0;

void setup ()

{
  pinMode(4,INPUT);
  digitalWrite(4, HIGH);
  pinMode(0,OUTPUT);
  pinMode(1,OUTPUT);
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
    
}
void loop()
{
  if(digitalRead(4)==LOW)
  {
    knopka++;
    _delay_ms(500);
  }
   if(knopka==1)
    {
    digitalWrite(0,HIGH);
    digitalWrite(1,HIGH);
    digitalWrite(2,HIGH);
    digitalWrite(3,HIGH);
  }
  if(knopka==2)
    {
    digitalWrite(0,LOW);     
  }
  if(knopka==3)
   {
    digitalWrite(1,LOW);   
  }
  if(knopka==4)
   {
    digitalWrite(2,LOW);    
  }
  if(knopka==5)
    {
    digitalWrite(3,LOW);
    knopka=0;
  }  
    }
  
  

Все работает как хотелось. Возникла еще одна "хотелка" не соображу как реализовать. Нужно чтоб при удержании кнопки все гасло до последующего нажатия.

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

добавиь переменную unsigned long для времени. при нажатии записывай в нее текущее время через функцию millis

вообще в разделе работа с кнопками это все есть

vvg10
vvg10 аватар
Offline
Зарегистрирован: 18.04.2013

Сделал проще: 

if(knopka>=5)
    {
    digitalWrite(3,LOW);
      }
    if(digitalRead(4)==HIGH && (knopka>=5))
    {
    knopka=0;
  }

Посыл в раздел работа с кнопками очень действенный! Спасибо!

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Ну наконец-то написал. Как восстановить неправильно выставленные фьюзы в ATtiny:
http://habrahabr.ru/post/249967/
Пользуйтесь.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

jeka_tm пишет:

хочешь научится или чтобы за тебя сделали?

Вспомнил себя два с половиной года назад ;) когда увидел эту цитату.

инженерХО
Offline
Зарегистрирован: 19.02.2015

помогите, все делаю как описано выше, прошиваю ТИНКУ и он выдает такое 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

инженерХО пишет:

помогите...


Хз почему так, пишет что не видит, пишет типа дважды перепроверьте подключение к ардуине.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Обновил "ядро"(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, но я не тестировал, так что тоже теоретически. 
 

// this sketch turns the Arduino into a AVRISP
// using the following pins:
// 10: slave reset
// 11: MOSI
// 12: MISO
// 13: SCK
 
// Put an LED (with resistor) on the following pins:
// 9: Heartbeat - shows the programmer is running
// 8: Error - Lights up if something goes wrong (use red if that makes sense)
// 7: Programming - In communication with the slave
//
// October 2009 by David A. Mellis
// - Added support for the read signature command
//
// February 2009 by Randall Bohn
// - Added support for writing to EEPROM (what took so long?)
// Windows users should consider WinAVR's avrdude instead of the
// avrdude included with Arduino software.
//
// January 2008 by Randall Bohn
// - Thanks to Amplificar for helping me with the STK500 protocol
// - The AVRISP/STK500 (mk I) protocol is used in the arduino bootloader
// - The SPI functions herein were developed for the AVR910_ARD programmer
// - More information at code.google.com/p/mega-isp
#include <SPI.h>
#include "pins_arduino.h"  // defines SS,MOSI,MISO,SCK
#define RESET SS
 
#define LED_HB 9
#define LED_ERR 8
#define LED_PMODE 7
 
#define HWVER 2
#define SWMAJ 1
#define SWMIN 18
 
// STK Definitions
#define STK_OK 0x10
#define STK_FAILED 0x11
#define STK_UNKNOWN 0x12
#define STK_INSYNC 0x14
#define STK_NOSYNC 0x15
#define CRC_EOP 0x20 //ok it is a space...
 
void pulse(int pin, int times);
 
void setup() {
  Serial.begin(19200);
  pinMode(7, OUTPUT);
  pulse(7, 2);
  pinMode(8, OUTPUT);
  pulse(8, 2);
  pinMode(9, OUTPUT);
  pulse(9, 2);
  pinMode(SS, OUTPUT);
  pinMode(MISO, INPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(SCK, OUTPUT);
 
//  SPI.setClockDivider(SPI_CLOCK_DIV128);
 
}
 
int error=0;
int pmode=0;
// address for reading and writing, set by 'U' command
int here;
uint8_t buff[256]; // global block storage
 
#define beget16(addr) (*addr * 256 + *(addr+1) )
typedef struct param {
  uint8_t devicecode;
  uint8_t revision;
  uint8_t progtype;
  uint8_t parmode;
  uint8_t polling;
  uint8_t selftimed;
  uint8_t lockbytes;
  uint8_t fusebytes;
  int flashpoll;
  int eeprompoll;
  int pagesize;
  int eepromsize;
  int flashsize;
}
parameter;
 
parameter param;
 
// this provides a heartbeat on pin 9, so you can tell the software is running.
uint8_t hbval=128;
int8_t hbdelta=8;
void heartbeat() {
  if (hbval > 192) hbdelta = -hbdelta;
  if (hbval < 32) hbdelta = -hbdelta;
  hbval += hbdelta;
  analogWrite(LED_HB, hbval);
  delay(40);
}
 
 
void loop(void) {
  // is pmode active?
  if (pmode) digitalWrite(LED_PMODE, HIGH);
  else digitalWrite(LED_PMODE, LOW);
  // is there an error?
  if (error) digitalWrite(LED_ERR, HIGH);
  else digitalWrite(LED_ERR, LOW);
 
  // light the heartbeat LED
  heartbeat();
  if (Serial.available()) {
    avrisp();
  }
}
 
uint8_t getch() {
  while(!Serial.available());
  return Serial.read();
}
void readbytes(int n) {
  for (int x = 0; x < n; x++) {
    buff[x] = Serial.read();
  }
}
 
#define PTIME 30
void pulse(int pin, int times) {
  do {
    digitalWrite(pin, HIGH);
    delay(PTIME);
    digitalWrite(pin, LOW);
    delay(PTIME);
  }
  while (times--);
}
 
void spi_init() {
  /*uint8_t x;
  SPCR = 0x53;
  x=SPSR;
  x=SPDR;*/
}
 
void spi_wait() {
  do {
  }
  while (!(SPSR & (1 << SPIF)));
  delay(100);
}
//unsigned char msk[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
unsigned char msk[] = {0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
#define PCK() (bits[0] << 7 | bits[1] << 6 | bits[2] << 5 | bits[3] << 4 | bits[4] << 3 | bits[5] << 2 | bits[6] << 1 | bits[7])
uint8_t spi_send(uint8_t b) {
  uint8_t reply=0;
  char bits[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  /*SPDR=b;
  spi_wait();
  reply = SPDR;
  return reply;*/
//  digitalWrite(SS, LOW);
//  delayMicroseconds(20);
//cli();
  for(uint8_t _bit = 0;_bit < 8;_bit++){
   digitalWrite(MOSI, !!(b & msk[_bit]));
   delayMicroseconds(50);
   digitalWrite(SCK, HIGH);
   delayMicroseconds(50);
   bits[_bit] = digitalRead(MISO);
   delayMicroseconds(50);
   digitalWrite(SCK, LOW);
   delayMicroseconds(50);
//  delayMicroseconds(50);
  }
//  digitalWrite(SS, HIGH);
  delayMicroseconds(50);
  reply = PCK();
  return reply;
 
 
}
 
uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
  uint8_t n;
  spi_send(a);
  n=spi_send(b);
  //if (n != a) error = -1;
  n=spi_send(c);
  return spi_send(d);
}
 
void empty_reply() {
  if (CRC_EOP == getch()) {
    Serial.print((char)STK_INSYNC);
    Serial.print((char)STK_OK);
  }
  else {
    Serial.print((char)STK_NOSYNC);
  }
}
 
void breply(uint8_t b) {
  if (CRC_EOP == getch()) {
    Serial.print((char)STK_INSYNC);
    Serial.print((char)b);
    Serial.print((char)STK_OK);
  }
  else {
    Serial.print((char)STK_NOSYNC);
  }
}
 
void get_version(uint8_t c) {
  switch(c) {
  case 0x80:
    breply(HWVER);
    break;
  case 0x81:
    breply(SWMAJ);
    break;
  case 0x82:
    breply(SWMIN);
    break;
  case 0x93:
    breply('S'); // serial programmer
    break;
  default:
    breply(0);
  }
}
 
void set_parameters() {
  // call this after reading paramter packet into buff[]
  param.devicecode = buff[0];
  param.revision = buff[1];
  param.progtype = buff[2];
  param.parmode = buff[3];
  param.polling = buff[4];
  param.selftimed = buff[5];
  param.lockbytes = buff[6];
  param.fusebytes = buff[7];
  param.flashpoll = buff[8];
  // ignore buff[9] (= buff[8])
  //getch(); // discard second value
 
  // WARNING: not sure about the byte order of the following
  // following are 16 bits (big endian)
  param.eeprompoll = beget16(&buff[10]);
  param.pagesize = beget16(&buff[12]);
  param.eepromsize = beget16(&buff[14]);
 
  // 32 bits flashsize (big endian)
  param.flashsize = buff[16] * 0x01000000
    + buff[17] * 0x00010000
    + buff[18] * 0x00000100
    + buff[19];
 
}
 
void start_pmode() {
  spi_init();
  // following delays may not work on all targets...
  pinMode(RESET, OUTPUT);
  digitalWrite(RESET, HIGH);
  pinMode(SCK, OUTPUT);
  digitalWrite(SCK, LOW);
  delay(50);
  //delay(250);
  digitalWrite(RESET, LOW);
  delay(50);
//delay(250);
  pinMode(MISO, INPUT);
  pinMode(MOSI, OUTPUT);
  spi_transaction(0xAC, 0x53, 0x00, 0x00);
  pmode = 1;
}
 
void end_pmode() {
  pinMode(MISO, INPUT);
  pinMode(MOSI, INPUT);
  pinMode(SCK, INPUT);
  pinMode(RESET, INPUT);
  pmode = 0;
}
 
void universal() {
  int w;
  uint8_t ch;
 
  for (w = 0; w < 4; w++) {
    buff[w] = getch();
  }
  ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
  breply(ch);
}
 
void flash(uint8_t hilo, int addr, uint8_t data) {
  spi_transaction(0x40+8*hilo,
  addr>>8 & 0xFF,
  addr & 0xFF,
  data);
}
void commit(int addr) {
  spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
}
 
//#define _current_page(x) (here & 0xFFFFE0)
int current_page(int addr) {
  if (param.pagesize == 32) return here & 0xFFFFFFF0;
  if (param.pagesize == 64) return here & 0xFFFFFFE0;
  if (param.pagesize == 128) return here & 0xFFFFFFC0;
  if (param.pagesize == 256) return here & 0xFFFFFF80;
  return here;
}
uint8_t write_flash(int length) {
  if (param.pagesize < 1) return STK_FAILED;
  //if (param.pagesize != 64) return STK_FAILED;
  int page = current_page(here);
  int x = 0;
  while (x < length) {
    if (page != current_page(here)) {
      commit(page);
      page = current_page(here);
    }
    flash(LOW, here, buff[x++]);
    flash(HIGH, here, buff[x++]);
    here++;
  }
 
  commit(page);
 
  return STK_OK;
}
 
uint8_t write_eeprom(int length) {
  // here is a word address, so we use here*2
  // this writes byte-by-byte,
  // page writing may be faster (4 bytes at a time)
  for (int x = 0; x < length; x++) {
    spi_transaction(0xC0, 0x00, here*2+x, buff[x]);
    delay(45);
  }
  return STK_OK;
}
 
void program_page() {
  char result = (char) STK_FAILED;
  int length = 256 * getch() + getch();
  if (length > 256) {
      Serial.print((char) STK_FAILED);
      return;
  }
  char memtype = getch();
  for (int x = 0; x < length; x++) {
    buff[x] = getch();
  }
  if (CRC_EOP == getch()) {
    Serial.print((char) STK_INSYNC);
    if (memtype == 'F') result = (char)write_flash(length);
    if (memtype == 'E') result = (char)write_eeprom(length);
    Serial.print(result);
  }
  else {
    Serial.print((char) STK_NOSYNC);
  }
}
uint8_t flash_read(uint8_t hilo, int addr) {
  return spi_transaction(0x20 + hilo * 8,
    (addr >> 8) & 0xFF,
    addr & 0xFF,
    0);
}
 
char flash_read_page(int length) {
  for (int x = 0; x < length; x+=2) {
    uint8_t low = flash_read(LOW, here);
    Serial.print((char) low);
    uint8_t high = flash_read(HIGH, here);
    Serial.print((char) high);
    here++;
  }
  return STK_OK;
}
 
char eeprom_read_page(int length) {
  // here again we have a word address
  for (int x = 0; x < length; x++) {
    uint8_t ee = spi_transaction(0xA0, 0x00, here*2+x, 0xFF);
    Serial.print((char) ee);
  }
  return STK_OK;
}
 
void read_page() {
  char result = (char)STK_FAILED;
  int length = 256 * getch() + getch();
  char memtype = getch();
  if (CRC_EOP != getch()) {
    Serial.print((char) STK_NOSYNC);
    return;
  }
  Serial.print((char) STK_INSYNC);
  if (memtype == 'F') result = flash_read_page(length);
  if (memtype == 'E') result = eeprom_read_page(length);
  Serial.print(result);
  return;
}
 
void read_signature() {
  if (CRC_EOP != getch()) {
    Serial.print((char) STK_NOSYNC);
    return;
  }
  Serial.print((char) STK_INSYNC);
  uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
  Serial.print((char) high);
  uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
  Serial.print((char) middle);
  uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
  Serial.print((char) low);
  Serial.print((char) STK_OK);
}
//////////////////////////////////////////
//////////////////////////////////////////
 
 
////////////////////////////////////
////////////////////////////////////
int avrisp() {
  uint8_t data, low, high;
  uint8_t ch = getch();
  switch (ch) {
  case '0': // signon
    empty_reply();
    break;
  case '1':
    if (getch() == CRC_EOP) {
      Serial.print((char) STK_INSYNC);
      Serial.print("AVR ISP");
      Serial.print((char) STK_OK);
    }
    break;
  case 'A':
    get_version(getch());
    break;
  case 'B':
    readbytes(20);
    set_parameters();
    empty_reply();
    break;
  case 'E': // extended parameters - ignore for now
    readbytes(5);
    empty_reply();
    break;
 
  case 'P':
    start_pmode();
    empty_reply();
    break;
  case 'U':
    here = getch() + 256 * getch();
    empty_reply();
    break;
 
  case 0x60: //STK_PROG_FLASH
    low = getch();
    high = getch();
    empty_reply();
    break;
  case 0x61: //STK_PROG_DATA
    data = getch();
    empty_reply();
    break;
 
  case 0x64: //STK_PROG_PAGE
    program_page();
    break;
   
  case 0x74: //STK_READ_PAGE
    read_page();    
    break;
 
  case 'V':
    universal();
    break;
  case 'Q':
    error=0;
    end_pmode();
    empty_reply();
    break;
   
  case 0x75: //STK_READ_SIGN
    read_signature();
    break;
 
  // expecting a command, not CRC_EOP
  // this is how we can get back in sync
  case CRC_EOP:
    Serial.print((char) STK_NOSYNC);
    break;
   
  // anything else we will return STK_UNKNOWN
  default:
    if (CRC_EOP == getch())
      Serial.print((char)STK_UNKNOWN);
    else
      Serial.print((char)STK_NOSYNC);
  }
}

 

Взято отсюда:
http://forum.arduino.cc/index.php?topic=89781.msg2160449#msg2160449

iDimaX
Offline
Зарегистрирован: 03.04.2015

Не коректно работает Delay =\

При задержке 10сек получается 13 с хвостом.

Так же и при задержке 1 сек (1.3сек). Пробовал на разных частотах, одно и то же. Как вылечить? Мне нужно точно отмерять 10сек.

И как добавить устройство в новой версии Arduino IDE?

iDimaX
Offline
Зарегистрирован: 03.04.2015

iDimaX пишет:

>>помогите, все делаю как описано выше, прошиваю ТИНКУ и он выдает такое 

Мне помог резистор между 5V и RESET Arduino

NikitosZs
NikitosZs аватар
Offline
Зарегистрирован: 26.09.2013

iDimaX пишет:

Не коректно работает 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битные, то можно в выпадающей менюшке, где выбирались платы, выбрать Менеджер досок и скачать там. 

Косяк с частотой был и у меня, но я грешил на сбитую калибровку своих тинек. Оказывается, не так. 

burbuzin1
Offline
Зарегистрирован: 10.04.2015

Добрый день,

нужна помощь. Пытаюсь повторить 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 порт от ИК транзистора.

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Мои старые наработки: Сверх энергосберегающий маячок на 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();
  }
}

Код говно, работает через одно место, но работает! 
Может кто подскажет что не так? Нутром чую что это работает через одно место.

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Мне нужно чтобы микроконтроллер заводил вачдог на 1 / 2 / 4 / 8 сек, засыпал, причём очень крепко, даже АЦП чтобы не работал и потом по вачдогу от ресета просыпался, исполнял что нужно и когда нужно засыпал опять на некоторое время.

burbuzin1
Offline
Зарегистрирован: 10.04.2015

Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino. Кто-нибудь решал такую проблему? Как узнать какое значение кнопок ик-пульта получается в тини?

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

burbuzin1 пишет:

Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino.

Как и что там обрабатывается завистит от конкретной прошивки (программы). Прошивка (программа) для ATtiny и для ATmega может быть разной, т.к. в микроконтроллерах разные регистры и т.д. Либо ищете готовый код/библиотеки под конткретный микроконтроллер, либо берёте на него даташит, изучаете, и самостоятельно программируете.

burbuzin1
Offline
Зарегистрирован: 10.04.2015

Серьёзно? От программы зависит? Да еще и прошивки нужны?

Я в нескольких сообщениях до этого описал суть проблемы с кодом, мнением, и вопросами. Теперь я точно убедился, что код от пульта обрабатывается по разному.

Приведу два своих листинга, один для ардуино уно, второй для 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 

 

Kolchugin
Offline
Зарегистрирован: 15.12.2013

burbuzin1 пишет:

Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как Arduino. Кто-нибудь решал такую проблему? Как узнать какое значение кнопок ик-пульта получается в тини?

Попробую изложить свои мысли.  Дело скорее всего в несоответствии частоты. Т.е. ардуино работает на одной частоте. Вы считываете значение кнопки пульта. Потом это значение записываете в тиньку, а она работает на другой частоте, из-за это ваш ик-пакет искажается.

burbuzin1
Offline
Зарегистрирован: 10.04.2015

Тоже так думаю. Тини на 9.6мгц, Ардуино 16. Впринципе сталкивался с таким когда запускали дисплей 16*4.

У меня даже идей нет, как это можно тут обойти. Хотя появилась мысль сделать еще програмный UART в этом коде, который будет принимать число из переменной irCode, и как-то слать его дальше. Но это выглядит как велосипед, хотелось бы проще.

Вопрос конечно, почему у автора статьи всё работает http://habrahabr.ru/post/244349/

 

toc
Offline
Зарегистрирован: 09.02.2013

HWman пишет:

Мне нужно чтобы микроконтроллер заводил вачдог на 1 / 2 / 4 / 8 сек, засыпал, причём очень крепко, даже АЦП чтобы не работал и потом по вачдогу от ресета просыпался, исполнял что нужно и когда нужно засыпал опять на некоторое время.

кладезь знаний http://www.gammon.com.au/power

Kolchugin
Offline
Зарегистрирован: 15.12.2013

burbuzin1, попробуйте залить скетч выбрав тиньку 1,2 Мгц (default).

burbuzin1
Offline
Зарегистрирован: 10.04.2015

Пробовал, не помогает.

Появился прогресс. Плюнул на всё, решил пойти на пролом. Сделал код который делением и остатком от деления помог мне узнать чему равен irCode в тини.

Вкратце:

если q==5, мигаем 5 раз, если q==2, мигаем 2 раза итд.

while (irCode >=10){
irCode = irCode / 10} счетчиком определяем количество символов в irCode. получил 4 символа. ХХХХ
Далее убираем while и считаем без цикла.

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. Пока не получается понять в чем дело.

 

 

green4ik
Offline
Зарегистрирован: 23.04.2015

Добрый день! Можете помочь? Мне нужно на тиньке сделать так что бы поочереди загорались  3 светодиода. Но при этом что бы подстроечным резистором можно было бы регулировать их скорость (от 200мс до 2000мс). Просто что бы мограли, я осилил, а вот управление морганием никак не могу.

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

вместо delay используй:

int resistorValue = analogRead(POT_PIN);
int pauseLED = map(resistorValue, 0, 1023, 200, 2000);
delay(pauseLED);