Дима, спасибо за ответ - Идея хорошая и по элементной базе 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 мин а больше немного.
#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--; } }Спасибо за сообщение ))) Да я уже убедился, что делай может максимум 65000, а на деле это ужепочти 80 секунд )))) Это тоже не проблема в погрешности моего устройства, сам алгаритм не могу написаь - уже голова уплыла далеко, хотя из начально был на верном пути ))))
HWman, это скетч для меня или подобие для моего решения ????
HWman, это скетч для меня или подобие для моего решения ????
Светодиод то светит 5 мин то не светит 5 мин, такой себе заторможеный блинк.
МАН спасибо - уже пробовал ))) настроил два временных. Подскажите в какую сторону идти - пожал. У меня то задача такая. При включ питания, ждем 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.Тестить будет весело чувствую.
ЗЫ ну мне прямо таки соавторство грозит для Вашего изобретения ;)
Дорогой друг МАН - если позволите вас так назвать - в честь благодарность ))))
С удовольствием обозначу вас соавтором - хоть как автором. Думаю вы единственный тот человек, который по жизни может протянуть руку и не важно на форуме или в реале ))))
Спасибо огромное, буду тестить, но пока тестирую про межутки буду джигу дрыгу танцевать )))))
Еще раз не земное спасибо ))))
Я в таких случаях говорю - сделаешь что-то когда-то кому-то без пользы для себя.
Ну почему же без пользы еще какая польза - я вам здоровья желаю )))))))
Ну почему же без пользы еще какая польза - я вам здоровья желаю )))))))
И тебе того же.
Юзал ядро на 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-ю в списке:
//#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); } }А оно мне грит мол:
"Это не я, оно само."
Вообщем подскажите что делать? Проект хорош сам по себе, хотеться поиграться... а вдруг что-то подобное получиться?
https://www.youtube.com/watch?v=OBspj1XJ0JY
Мозги включил и сделал вот так:
//#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); } }Может кто потестить раньше меня? Пока нету возможности проверить в железе.
Доброго дня! Может мне кто нибудь помочь? Задача такая : контроллер, кнопка, 4 светодиода. Нажимаем кнопку - загораются все. Нажимаем еще раз - 1 гаснет, еще - 2-й гаснет, еще - 3-й гаснет, еще - потухли все, еще - все зажглись. И т.д. по кругу.
а проблема то в чем? не знаешь как писать или что то конкретное?
Честно говоря не знаю как написать...
хочешь научится или чтобы за тебя сделали?
Конечно научиться. Уже делал проекты на ардуине. Здесь не соображу как выдавать сигнал на разных выходах при нажатии одной кнопки.
да сделай просто счетчик от 0 до 4. при достижении 0 он обнуляется.
задай условия в зависимости от состояния счетчика зажигать нужные светодиоды
Посмотрите здесь на форуме есть раздел "Программирование" и сразу же первая тема "Работа с кнопками" и в первом сообщении как раз ваш пример, уже готовый лежит.
Вот написал...
#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; } }Все работает как хотелось. Возникла еще одна "хотелка" не соображу как реализовать. Нужно чтоб при удержании кнопки все гасло до последующего нажатия.
добавиь переменную unsigned long для времени. при нажатии записывай в нее текущее время через функцию millis
вообще в разделе работа с кнопками это все есть
Сделал проще:
if(knopka>=5) { digitalWrite(3,LOW); } if(digitalRead(4)==HIGH && (knopka>=5)) { knopka=0; }Посыл в раздел работа с кнопками очень действенный! Спасибо!
Ну наконец-то написал. Как восстановить неправильно выставленные фьюзы в 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, но я не тестировал, так что тоже теоретически.
// 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
Не коректно работает 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.
#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(); } }Код для тини:
Столкнулся с тем, что тини обрабатывает ИК код от пульта не так, как 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 используй: