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

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

xorkrus пишет:

dimax пишет:
Joiner, можно попробовать использовать счётный регистр таймера как генератор чисел от 0 до 255,  uint8_t n=TCNT0; этот вариант точно займёт минимум памяти)

А можно как-то также по-лёгкому сделать random(1,3)? Т.е. выбирать число от 1 до 3х (надо заполнить массив на 100 мест в случайном порядке этими тремя циферами)

Я, кстати, думал об этом :) Даже в чьем-то скетче видел такую реализацию. Скорее всего так и попробую. Наверняка места меньше займет чем рандом.

А почему от 1 до 3х?

xorkrus
Offline
Зарегистрирован: 22.09.2013

Joiner пишет:
А почему от 1 до 3х?

Действительно - почему? Можно же и так... Спасибо :)

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Если надо получить рандомные числа не больше какого-либо значения, надо найти остаток от деления рандомчисла на max. число - 1.

Пример:

// Получаем рандомные числа из промежутка [0;Х)
// В переменной random хранится случайное значение, любым способом полученное.

random = random % (x - 1);

Метод рабочий, у меня на нём блекджек и джекпот под виндус консольные написаны)

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

еще вариант: берём 3 переменных А=123 B=23 C=1; это начальные значения.
Получение случайки:
А=B;
B=C<<1; 7бит в регистре надо перенести в 0 бит, т.е прокрутить полностью.
C=A+B;
собственно и всё [​IMG]
Зависимость всё-таки есть, но числа получаются равномерно  (начинают повторятся) только после где-то 20000 цикла. Думаю, этого вполне достаточно. Причём А=123 B=23 C=1 как оказалось самый лучший вариант.

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

Tomasina пишет:

еще вариант: берём 3 переменных А=123 B=23 C=1; это начальные значения.
Получение случайки:
А=B;
B=C<<1; 7бит в регистре надо перенести в 0 бит, т.е прокрутить полностью.
C=A+B;
собственно и всё [​IMG]
Зависимость всё-таки есть, но числа получаются равномерно  (начинают повторятся) только после где-то 20000 цикла. Думаю, этого вполне достаточно. Причём А=123 B=23 C=1 как оказалось самый лучший вариант.

Не совсем понял...Написал такой скетч

byte A=123;
byte B=23;
byte C=1;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
A=B;
B=C<<1; //7бит в регистре надо перенести в 0 бит, т.е прокрутить полностью.
C=A+B;
Serial.println(C);
delay(1000);
}

Запустил. Сначала все хорошо, значений 15-20...А потом начинает выдавать одни нули

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

Yarik.Yar пишет:

Если надо получить рандомные числа не больше какого-либо значения, надо найти остаток от деления рандомчисла на max. число - 1.

Пример:

// Получаем рандомные числа из промежутка [0;Х)
// В переменной random хранится случайное значение, любым способом полученное.

random = random % (x - 1);

Метод рабочий, у меня на нём блекджек и джекпот под виндус консольные написаны)

Попробовал, работает. Но рандом на тиньке жрет 75% памяти :(

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

Сваял скетчик для иммитации пламени в игрушечном камине. Работает именно так, как мне хотелось, плавненько, есть простор для настроек. Беда в том, что работает он на UNO. В тиньку13 запихнуть мне его не удалось, даже при отсутствии иммитации искорок третьим светиком (было в планах сделать третий светик, который бы давал очень короткие вспышки с рандомным периодом). При компиляции на тиньку получается 1294 byte (126%) из 1024 byte.  :(((

Вот этот скетч

//мк ATtiny13
//F_CPU = 9600000/8=1200000
#include <avr/io.h>

byte led[]= {9,11};
int brightness[] = {200, 100};//Здесь хранится яркость светиков
int fadeAmount[] = {5, 25};//Здесь хранится скорость изменения яркости
int brightnessMin[] = {30, 50};//Здесь минимальная яркость, чтобы светик не гас полностью(можно поиграться)
int brightnessMax[] = {255, 200};//Здесь максимальная яркость, убавить, если слишком ярко(можно поиграться)
int fadeAmountMin[]= {1, 5};//Минимальная скорость изменения яркости(можно поиграться)
int fadeAmountMax[] = {25, 35};//Максимальная скорость изменения(можно поиграться)

void setup() {
  for (byte i=0; i<=1; i++)
  {
    pinMode(led[i], OUTPUT);
  }
}

void loop() 
{ 
  for (byte i=0; i <=1; i++)//Перебираем светики по очереди
  { 
    analogWrite(led[i], brightness[i]);
    brightness[i]=brightness[i]+fadeAmount[i];//Изменяем яркость одного из светиков
      if (brightness[i] < brightnessMin[i] || brightness[i] >brightnessMax[i])//Если привысили значение
        {
          brightness[i]=brightness[i]-fadeAmount[i];//то исправляем
          raNdom(i);//Обращаемся за случайным значением
          if (brightness[i]>(brightnessMax[i]+brightnessMin[i])/2)//Проверяем значение
                                             //ближе к максимому или к минимуму
            {
              fadeAmount[i]=0-fadeAmount[i];//Меняем знак
            }         
        }
    delay(20);//Задержка, не знаю оптимальная ли....потом подберем 
  } 
}
//=================================================================
int raNdom(byte i)//Функция для получения случайного значения
                  //Не понимаю как, но работает
{
do
{ 
  fadeAmount[i] = random() % (fadeAmountMax[i] - 1);//Эта строка от Yarika с форума Arduino
} 
while (fadeAmount[i]<fadeAmountMin[i]);//Проверяем не меньше ли минимума
return fadeAmount[i];//Возвращаем значение функции
}

Может кто-то сможет подсказать, как его затолкать в тиньку?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner. вы будто специально всё делали что б он максимальным был. Убирайте все ардуиновские команды _ВСЕ_ что б никаких setup() loop() delay() analogWrite() pinMode() Убрать все массивы 5-11 строки, не вижу в них надобности. Если что-то сильно хочется определить в шапке, можно использовать #define   Скелет программы должен быть такой, как я писал в #685

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

dimax пишет:

Joiner. вы будто специально всё делали что б он максимальным был. Убирайте все ардуиновские команды _ВСЕ_ что б никаких setup() loop() delay() analogWrite() pinMode() Убрать все массивы 5-11 строки, не вижу в них надобности. Если что-то сильно хочется определить в шапке, можно использовать #define   Скелет программы должен быть такой, как я писал в #685

Пробовал все, что писали выше. Кое-что работает, кое-что не работает. А то что работает, работает как-то не так (может я что-то не так делаю). Вместо того, что мне надо, простое беспорядочное моргание светодиодов. Очень похоже на то, как раньше в одной из тем моргали тремя светодиодами с разным периодом. А мне резкое моргание не нужно. Мне хочется плавного изменения яркости светиков, нужно впечатление спокойного пламени в игрушечном камине.

Девочка ждет, а я все ни как не могу справиться с довольно простой задачей. Начинаю разочаровываться в тиньке. Стоит на каких-то рублей пятьдесят дешевле атмеги328......а такой гемморой для неспециалиста!!!! Единственное достоинство - малый размер и низкое энергопотребление.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, так нужно отлаживать, доводить до результата. Вполне логично, что сразу не заработает так как нужно.  Я вообще не вижу смысла в тини13, это прошлый век.   Если речь не идёт об коммерческом проекте в партии несколько тысяч штук, то какой смысл их сейчас покупать.  Для домашних поделок те же tiny85 в дижиспарке за 100 руб  гораздо удобнее.

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

dimax пишет:

Joiner, так нужно отлаживать, доводить до результата. Вполне логично, что сразу не заработает так как нужно.  Я вообще не вижу смысла в тини13, это прошлый век.   Если речь не идёт об коммерческом проекте в партии несколько тысяч штук, то какой смысл их сейчас покупать.  Для домашних поделок те же tiny85 в дижиспарке за 100 руб  гораздо удобнее.

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

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

Поддерживаю обеих! dimax и Joiner

Тинни13 самого разочаровала!))

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

Joiner бери мегу8!,  лично она у нас на 0,3сентов дороже тини13, можно даже бутлодер ардуиновский зилить и полная совместимость ардуино!

 

 

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

bodriy2014 пишет:

.........Joiner бери мегу8!,  лично она у нас на 0,3сентов дороже тини13, можно даже бутлодер ардуиновский зилить и полная совместимость ардуино!

Пришли из китая 2шт тиньки 2613. Обошлись за 65 руб за штуку. Попробую поиграться с ними :)

Почитал статью http://bigbarrel.ru/%d1%80%d1%83%d0%b1%d1%80%d0%b8%d0%ba%d0%b0-%d1%81%d0%ba%d0%be%d0%bb%d1%8c%d0%ba%d0%be-%d0%b2%d0%b5%d1%81%d0%b8%d1%82-%d0%b2-%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0%d1%85/

Вот цитаты из нее:

  • Наименее компактный код получился для Attiny13.
  • Нет возможности использовать на контроллере Attiny13 все приведенные процедуры, т.к. общий размер будет превышать размер доступной памяти.

Вывод: Мой выбор Аттини13 не совсем удачный :), хотя генератор для пугателя собак получился вполне даже хорошо, компактней, более функциональный, и без какой-либо обвязки, в отличие от генератора на NE555.

sav13
sav13 аватар
Offline
Зарегистрирован: 17.06.2013

bodriy2014 пишет:

Поддерживаю обеих! dimax и Joiner

Тинни13 самого разочаровала!))

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

Joiner бери мегу8!,  лично она у нас на 0,3сентов дороже тини13, можно даже бутлодер ардуиновский зилить и полная совместимость ардуино!

Где взять мегу по цене тини13?

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

sav13 пишет:

Где взять мегу по цене тини13?

Поискать у себя в стране или на али.

напимер у меня в стране такие цены.

Мега ДИП http://aukro.ua/atmega8-16pu-avr-atmega-mikrokontroller-i5784415178.html

Мега СМД http://aukro.ua/mikrokontroller-atmega8a-au-atmega8a-atmel-tqfp-32-i5780862115.html

для сравнения тин13

ДИП http://aukro.ua/attiny13a-pu-dip8-mikrokontroller-avr-i5783482268.html

СМД  http://aukro.ua/attiny13a-su-soic8-mikrokontroller-avr-i5783482261.html

Разница копеечная.

 

sav13
sav13 аватар
Offline
Зарегистрирован: 17.06.2013

bodriy2014 пишет:

Поискать у себя в стране или на али.

напимер у меня в стране такие цены.

Мега ДИП http://aukro.ua/atmega8-16pu-avr-atmega-mikrokontroller-i5784415178.html

Мега СМД http://aukro.ua/mikrokontroller-atmega8a-au-atmega8a-atmel-tqfp-32-i5780862115.html

для сравнения тин13

ДИП http://aukro.ua/attiny13a-pu-dip8-mikrokontroller-avr-i5783482268.html

СМД  http://aukro.ua/attiny13a-su-soic8-mikrokontroller-avr-i5783482261.html

Разница копеечная.

Разница копеечная. Только точень дорого. 22UAH это почти доллар

Я брал тиньки по $0.48 в DIP и там же можно взять по $3.3 в SOP

А меги 8 на али в DIP около $1 стоят. Чуть доплатить и уже 168/328 мегу можно взять причем в виде Arduino Pro Mini

veshamot
Offline
Зарегистрирован: 07.08.2013

Народ. помогите новичку. Программирую 85. с инфрокрасником не хочет работать. на уно все хорошо.вот скетч:

#include <IRremote.h>
 
 
 
int RECV_PIN = 0;
int green = 2;
int yellow = 1;
 
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;
bool LampState = false;
 
void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Запуск приемника
 
    pinMode(yellow, OUTPUT);
    digitalWrite(yellow,LOW);
    pinMode(green, OUTPUT);
    digitalWrite(green,LOW);
 
}
 
void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
   
     if (results.value == 16753245 )
   {
 LampState = !LampState;
 if (LampState)
 {
 digitalWrite(green,HIGH);
 }
 else
 {
 digitalWrite(green,LOW);
 }
 }
     if (results.value == 16769565 )
    {
 LampState = !LampState;
 if (LampState)
 {
 digitalWrite(yellow,HIGH);
 }
 else
 {
 digitalWrite(yellow,LOW);
 }
 }
    irrecv.resume(); // Получаем следующее значение
  }
}
deadromeo
Offline
Зарегистрирован: 26.11.2015

Всем доброго времени суток, как не прискорбно, но помогите новичку...

Дано - Arduino mega2560, Attiny13a-pu. Не могу прошить тиньку. Если подробнее, что делалось:

1. Отредактировал скетч ArduinoISP, конкретно секцию

#define PIN_MOSI	11
#define PIN_MISO	12
#define PIN_SCK	13

Заменил на



#define PIN_MOSI	51
#define PIN_MISO	50
#define PIN_SCK		52

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

Ошибка при записи загрузчика: пропущен параметр конфигурации 'bootloader.tool'

Среда ArduinoIDE 1.6.6, версия ядра для тини - 22, в поиск ходил, у гугла спрашивал, честно не могу понять в чем беда, буду рад любой помощи

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

deadromeo, а зачем вам записывать загрузчик, которого нет? Я прошиваю просто кнопкой "вгрузить".

deadromeo
Offline
Зарегистрирован: 26.11.2015

Да и так делал, выбивает ошибку, сейчас текста не могу дать, вечером отпишусь, сейчас хотел бы знать правильно ли скетч отредактировал или еще в каком месте надо подправить под мегу 2560. Может кто уже через мегу прошивал тиньку, может схема другая?

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

Для меги эти пины

// slave reset:    53
// MOSI:             51
// MISO:             50
// SCK:               52

Сначала не мегу заливаете пример ардуино ISP.

Затем открываете свой скетч для тини выбираете свою тини и выбираете программатор Arduino as ISP.

И нажимаете загрузить.

 

Клапауций 777
Offline
Зарегистрирован: 21.11.2015

deadromeo пишет:

Среда ArduinoIDE 1.6.6, версия ядра для тини - 22, в поиск ходил, у гугла спрашивал, честно не могу понять в чем беда, буду рад любой помощи

с версией arduino-1.6.5-r5 arduino-tiny-0150-0020 работает

пример боард текст для 2313

###########################################################################

attiny2313at8.name=ATtiny2313 - 8MHz

attiny2313at8.upload.tool=arduino:arduinoisp

attiny2313at8.upload.maximum_size=2048
attiny2313at8.upload.maximum_data_size=0

attiny2313at8.build.mcu=attiny2313
attiny2313at8.build.f_cpu=8000000L
attiny2313at8.build.core=tiny

###########################################################################

 

deadromeo
Offline
Зарегистрирован: 26.11.2015

Это магия какая то, вчера все перепробывал, и то что последние парни советовали, не шилась тинька, а сейчас ничего нигде не меняя прошилось. Спасибо всем за советы, вопрос снимается

deadromeo
Offline
Зарегистрирован: 26.11.2015

Хммм, снова я к вам за помощью, собираю термометр на attiny13a ( датчик DHT22) с выводом на 2 семисегментника (через пару сдвиговых регистров), вывод любых чисел впринципе работает отлично, НО пытаясь по стандарту подключить датчик (с помощью библиотеки DHT.h) при компиляции постоянно выбивает ошибку. Сам скетч (там еще присутствует мусор от найденного примера)

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> 
#include <avr/pgmspace.h>
#include <DHT.h>
#define DHTPIN 3 
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

//------------------0-----1-----2-----3-----4-----5                      
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D,
//------------------6-----7-----8-----9----пусто
                   0x7D, 0x07, 0x7F, 0x6F, 0x00};
 
// Функция вывода данных через регистр
void write_display(unsigned char *data, unsigned char nbytes)
{
unsigned char mask,i;
 
for(i = 0; i < nbytes; i++)
{
mask = 0x80;
 
for(char k = 0; k < 8; k++)
{
// сравниваем каждый бит с единицей
if(data[i] & mask)
{
PORTB |= (1 << PB0); // DATA 1
PORTB |= (1 << PB2); // CLK 1
PORTB &= ~(1 << PB2); // CLK 0
}
else
{
PORTB &= ~(1 << PB0); // DATA 0
PORTB |= (1 << PB2); // CLK 1
PORTB &= ~(1 << PB2); // CLK 0
}
mask = mask >> 1; // сдвигаем биты
}
}
// защелкиваем регистр
PORTB |= (1 << PB1); 
PORTB &= ~(1 << PB1);
}
 void setup() {
    dht.begin();
DDRB = 0b00000111;
PORTB = 0b00000000;
}

void loop(void)
{
unsigned char display[2];
int16_t t = dht.readTemperature();
display[0] =  SEGMENTE[ t % 10];
display[1] =  SEGMENTE[( t / 10) % 10];
write_display(display,2);
_delay_ms(500);
}

И расширенный текст ошибки

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp: In constructor 'DHT::DHT(uint8_t, uint8_t, uint8_t)':

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp:15:35: error: 'digitalPinToBitMask' was not declared in this scope

     _bit = digitalPinToBitMask(pin);

                                   ^

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp:16:33: error: 'digitalPinToPort' was not declared in this scope

     _port = digitalPinToPort(pin);

                                 ^

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp: In member function 'void DHT::begin()':

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp:26:17: error: 'INPUT_PULLUP' was not declared in this scope

   pinMode(_pin, INPUT_PULLUP);

                 ^

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp: In member function 'boolean DHT::read(bool)':

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp:159:19: error: 'INPUT_PULLUP' was not declared in this scope

     pinMode(_pin, INPUT_PULLUP);

                   ^

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp: In member function 'uint32_t DHT::expectPulse(bool)':

C:\Users\111\Documents\Arduino\libraries\DHT\DHT.cpp:243:37: error: 'portInputRegister' was not declared in this scope

     while ((*portInputRegister(_port) & _bit) == portState) {

                                     ^

Используем библиотеку DHT версии 1.2.3 из папки: C:\Users\111\Documents\Arduino\libraries\DHT 
exit status 1
Ошибка компиляции.

Датчик подключен к пину PB3, чувствую что гдето туплю, но не могу понять где

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

deadromeo, даже если вы переделаете библу на прямое управление портами, то возрадоваться результатом всё равно не сможете, управление dht не уместится в килобайт флеша, (если конечно не переписать всё на ассемблере).

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

После последнего вопроса во мне пробудился спортивный интерес, и я сделал это! Скетч для тиньки13  с датчиком dht22,  занимает всего 248 байт! :)) Float не использовал, и запятой один знак не отделяется. Выводит например вместо 28,3 - просто 283 .  Можно отделить последнюю цифру командой %.   В скетче ни одной ардуиновской команды не осталось, но компилится и заливается в среде arduino ide как обычно.

// tiny13 + AM2302, вход для датчика PB1
#include <avr/delay.h>
uint16_t Humidity;
uint16_t Temperature;
int main(void) {
TCCR0A=0; //Normal mode
TCCR0B=1<<CS01; // divider 9600000/8=1200000
TIMSK0=0;

while(1){ 
dht_read();
// какая-нибудь программа вывода данных: Humidity, Temperature
_delay_ms(2000); //не опрашивать DHT чаще чем раз в 2 сек
}
}

void dht_read(){
uint8_t error;
uint16_t data;
PORTB&=~(1<<PB1);  DDRB|=1<<DDB1;
_delay_us(800);
DDRB&=~(1<<DDB1);  PORTB|=1<<PB1;

for ( int8_t i = -3 ; i < 2 * 40; i++ ) {
    uint8_t age;
    TCNT0=0;
    do { age=TCNT0; if ( age > 108 ) {error = 1; return; } }
     while( (PINB&(1<<1))>>1 == (i & 1)? 1 : 0  ) ;
    if ( i >= 0 && (i & 1) ) {  data <<= 1; if ( age > 36 ) {data |= 1; } }

    switch ( i ) {
      case 31:
        Humidity = data;
        break;
      case 63:
        Temperature = data;
        data = 0;
        break;
    }
  }

  // Verify checksum
  if ( (byte)(((byte)Humidity) + (Humidity >> 8) + ((byte)Temperature) + (Temperature >> 8)) != data ) {
    error = 2;
    return;
  }

if ( Temperature & 0x8000 ) {
    Temperature = -(int16_t)(Temperature & 0x7FFF);   }
    error = 0;
}

 

deadromeo
Offline
Зарегистрирован: 26.11.2015

Спасибо большущее, сегодня буду пробовать дружить со своей констукцией семисегментников. Пока до дома далеко, глупый вопрос, если допустим мне нужно получить только температуру в переменную, использовать вывод типа: int t = dht_read(Temperature); или как то иначе?

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

Просто берите значение нужной переменой

Temperature-это переменная в которой уже находится значение температуры.

но она без зяптой.

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

deadromeo, тут функция dht_read ничего не возвращает. Переменные с данными -глобальные, определены в 3 и 4 строке.  Тактовая должна быть только 9,6Мгц, с другой работать не будет. Я ещё не знаю, как отрицательную температуру будет показывать. Строки 48-49 взяты из оригинальной библы, тут хитро отрицательная   температура преобразуется в положительную. Т.е. по идее должно показывать правильно, но без знака минус.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Спасибо большое за код.

Переработал его под свою либу, получилось так:

// tiny13 + AM2302, вход для датчика PB1
#include "arhat.h"

#define pinDHT pin52 // для Мега2560 сохранен PB1

uint16_t Humidity;
uint16_t Temperature;
uint8_t  error;

void setup()
{
    timerControl(0,A) = 0;                              // Normal mode
    timerControl(0,B) = prescalerMode(8);               // divider 9600000/8=1200000
    TIMSK0=0;
}

void loop()
{
    // не опрашивать DHT чаще чем раз в 2 сек
    everyOVF(1952, {
        dht_read();
        // .. какая-нибудь программа вывода данных: Humidity, Temperature
    });
    // .. тут что-нибудь, чего можно делать когда не опрашиваем датчик
}

void dht_read()
{
    uint16_t data;

    pinOut(pinDHT, 0); pinModeOut(pinDHT);
    delayMicro16(800*4);
    pinModeIn(pinDHT); pinOut(pinDHT, HIGH);

    for ( int8_t i = -3 ; i < 2 * 40; i++ ) {
        uint8_t age;

        timerCount(0) = 0;
        do {
            uint8_t age=timeCount(0);
            if ( age > 108 ){ error = 1; return; }
        }while( pinRead(pinDHT) == (i & 1)? 1 : 0  ) ;

        if ( i >= 0 && (i & 1) ){
            data <<= 1;
            if ( age > 36 ){ data |= 1; }
        }
        switch ( i ) {
            case 31: Humidity = data;              break;
            case 63: Temperature = data; data = 0; break;
        }
    }

    // Verify checksum
    if ( (byte)(((byte)Humidity) + (Humidity >> 8) + ((byte)Temperature) + (Temperature >> 8)) != data ) {
        error = 2;
        return;
    }
    if ( Temperature & 0x8000 ) {
        Temperature = -(int16_t)(Temperature & 0x7FFF);
    }
    error = 0;
}

Только чтобы получить требуемую частоту, наверное таймер надо выставлять в другой режим и использовать не нулевой (ибо занят временем) а например 2. Буду пробовать, есть такой датчик. :)

P.S. Да можно заменить все обратно на вызовы Wiring .. и будет "тоже самое". :)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Вроде работает, пасибки. Компиляется - точно, посмотреть данные с выводом куда-то не успел. Заодно нашел ошибку у себя в delayMicro16() - неверно указан тип аргумента в асм. вставке.

Итого, на Мега этот скетч 648 байт. Вместе с таймером. Без него 552 байт. За вычетом таблицы векторов, "собственно" код  282 байта. Пасибки.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Скетчик написал, он для отладочного вывода информации из тини13 на любую другую ардуину по одному проводу. Выводит 16-бит переменную за один вызов функции. Очень компактная альтернатива программному UARTу, который занимает порядка 500 байт в памяти, два вывода и таймер.  Этот же интерфейс занимает 146 байт, один вывод и не занимает таймер. Но нужна ардуина для приёма ) Никаких наворотов, всё максимально упрощено ради малого размера. Вот код, в качестве примера инкременируется переменная tim каждую секунду.


//скетч для отправки данных из тини13 на ардуино по одному проводу
#define pin_out 3 // номер порта для связи (B0..B5)   
#include <avr/delay.h>
int main(void) {
DDRB|=1<<pin_out; // как выход
PORTB&=~(1<<pin_out); // ноль -не готов передавать по умолчанию
while(1){
static uint16_t tim; 
dataout(tim);
tim++;
_delay_ms(1000);
}
}

void dataout(uint16_t data){
DDRB&=~(1<<pin_out);//стать входом
PORTB|=(1<<pin_out); //с подтяжкой
_delay_us(5); // на устаканивание
while (PINB&1<<pin_out); // цикл пока 1, ждать пока приёмник положит ногу в ноль
while (PINB&(1<<pin_out)? 0 : 1  ); // цик пока 0, ждать когда приёмник отпустит ногу
DDRB|=1<<pin_out;//стать выходом, с лог1 на выходе
_delay_us(50);//дать время приёмной части приготовится к приёму данных
for(int i=0; i<=15; i++) { // будем давать "0" на 30us -передаём единицу, 70us - передаём ноль. пауза 50us
PORTB&=~(1<<pin_out); // передний фронт импульса
data&1 ? _delay_us(25) : _delay_us(75); //первым отправлять старший байт
PORTB|=(1<<pin_out); // конец импульса
data>>=1; //продвинуть все биты вправо
_delay_us(50);//пауза между битами
} //end for
PORTB&=~(1<<pin_out); //конец передачи, опустили линию в ноль.
} //end void

Приёмный код для обычной ардуины. Написан уже традиционными командами))


uint16_t data;
#include <avr/delay.h>
#define inpin 8 // вход для связи с тинькой
void setup() {
Serial.begin(9600);
}

void loop() {

if (digitalRead(inpin)==HIGH) {
   data=0;
   pinMode(inpin,OUTPUT); //опустить линию, сообщитьчто готовы к приёму данных
   _delay_us(50); 
    pinMode(inpin, INPUT);// освободить линию передатчику 
      for(int i=0; i<=15; i++) { // будем получать "0" 25us -передавали единицу, 75us - передавали ноль. пауза 50us
       uint8_t tim=0; //переменная счёта времени длины импульса
        tim=pulseIn(inpin, LOW,200) ;
       if (tim > 100||tim==0){ data=0; return;}
       if (tim < 40) { data|=(1<<i);} 
       
       }
Serial.println(data);
}      
}

Если принимающую сторону отключить, то передающая встанет в ожидании сигнала от принимающей. У принимающей стороны при нарушении связи loop не остановится, просто вылетит из функции по таймауту. Желательно соединять порт тини и ардуины не напрямую, а через резистор 100..500 ом на всякий случай.

Если есть мысли как ещё больше ужать -высказывайте))

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Спасибки. Мне больше понравился вариант, реализованный для Arduino UNO в библиотеке cyberlib для UART. Очень компактный код и работает стандартно.

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Привет всем.
В этом сообщении : http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=1...
Был пример высокоскоростного ШИМа.
Пару вопросов по нему:
1. Каковы минимальная и максимальная частота ШИМа для атмеги 328?
2. Будет ли нормально работать библиотека, если в процессе исполнения кода будет динамически меняться частота и скважность?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

А в чем там "проблемы"? При частоте проца 16Мгц и прескалере 1:1 для 8-битного таймера получим частоту ШИМ = 16/256 = 1/16Мгц = 62.5 кгц .. если гонять ШИМ меньшей разрядности можно получить и выше.

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Arhat109-2 пишет:
А в чем там "проблемы"? При частоте проца 16Мгц и прескалере 1:1 для 8-битного таймера получим частоту ШИМ = 16/256 = 1/16Мгц = 62.5 кгц .. если гонять ШИМ меньшей разрядности можно получить и выше.
В этом случае работа с ШИмом происходит через библиотеку и частота ШИМа прописывается любая (если я правильно понял). Поэтому и был вопрос про мин-макс частоту и её динамическое изменение.

Извиняюсь, вопрос про мин-макс частоту решён, читать комменты в скетчах примеров надо :) frequency range from 1Hz - 2MHz on 16 bit timers and 31Hz - 2 MHz on 8 bit timers а вот вопрос по динамическое изменение частоты в коде остаётся.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Не пользуюсь библиотеками, поэтому не подскажу что там да как. С точки зрения управления таймерами - пофиг. А вот по предельным частотам ШИМ - в ваших комментах, извините написана откровенная лажа. При 16Мгц тактовой, частоту ШИМ в 2 мегагерца вы получите только на 3-х разрядном ШИМ. 16/2 = 8 или 3 бита. Полноценный ШИМ на 8 разрядов можно получить не быстрее 62.5кгц. Это "теоретически" согласно даташиту и независимо от разрядности счетчика. :)

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Arhat109-2 пишет:

Не пользуюсь библиотеками, поэтому не подскажу что там да как. :)

Далее можно было не продолжать.
Давайте не будем засорять ветку и подождём ответов от людей,
которые работали с этой библиотекой.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Извиняюсь, за "засор ветки", но таки замечу, что ветка про Attiny13 .. и в силу физ. ограничений работать ту с "бибилиотеками" - имхо расточительно. Вряд ли Вы дождетесь ответа. :)

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

zilibob4ik пишет:
Привет всем. В этом сообщении : http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=12#comment-144091 Был пример высокоскоростного ШИМа. Пару вопросов по нему: 1. Каковы минимальная и максимальная частота ШИМа для атмеги 328? 2. Будет ли нормально работать библиотека, если в процессе исполнения кода будет динамически меняться частота и скважность?

А залить в ардуино или мегу и проверить слабо.

Я динамически менял только скважность, частоту устанавливал во время старта.

Но это не для этой ветки!

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

bodriy2014 пишет:

лить в ардуино или мегу и проверить слабо.

Я динамически менял только скважность, частоту устанавливал во время старта.

Но это не для этой ветки!

Извиняюсь.

Проверю, отпишусь.

Просто нет приборов, которые смогут более 200 кгц замерить.

Надеялся, что кто нибудь, да работал с это библиотекой в таком режиме

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

Arhat109-2 пишет:

Спасибки. Мне больше понравился вариант, реализованный для Arduino UNO в библиотеке cyberlib для UART. Очень компактный код и работает стандартно.

Чувак ты ветки попутал!

dimax написал толковую вещь для вывода инфы с тини13 в внешний мир через уно.

А ты о библиотеке которая в тини даже не влезет.

 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

?!? Что конкретно из cyberlib "не влезет"? Там прямая работа с регистрами проца. Вы её видели? :)

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Несколькими сообщениями выше, Arhat109-2 сказал что библиотеками не пользуется...

Как будто  в библиотеках, работа напрямую с портами контроллера исключена.

Если что, в некоторых библиотеках и ассемблерные вставки встречаются.... как-то так...

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

Arhat109-2 пишет:

?!? Что конкретно из cyberlib "не влезет"? Там прямая работа с регистрами проца. Вы её видели? :)

Да просто откройте пустой скетч или любой работающий скетч для тини13 и добавьте строчку

#include <CyberLib.h>  в начало.

Попробуйте скомпилировать.

П.С.

С "регистрами проца"-но какого? меги328 конечно, на худой конец восьмой.-но не тини13.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Arhat109-2 пишет:

?!? Что конкретно из cyberlib "не влезет"? Там прямая работа с регистрами проца. Вы её видели? :)

Я кстати тоже не понял, к чему вы ту фразу сказали. Мой скетч был для вывода из тини. Вы сказали, "Мне больше понравился вариант, реализованный для Arduino UNO в библиотеке cyberlib для UART.". Но это разные вещи, там  просто интерфейс к аппаратному UART, его никаким образом не прикрутить к тини13.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Да, звиняюсь. Не знал что у тинек нет аппаратного UART "в принципе" .. казалось что это нечто такое, что есть у всех AVR хотя бы в 1 экземпляре .. ошибся. Просто для своей либы часто смотрю код, сделанный для тинек и "как его переработать" под свою мегу2560. Отсюда и интерес к этой теме.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

zilibob4ik пишет:

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

Если у вас есть лишняя ардуина, то у вас есть частотометр до 8 МГц :) Тыц

Я кстати так не понял, что вы хотели узнать то? Библу ту библой и не назовёшь, она всего лишь три бита в регистре TCCRxB подменяет. В принципе Arhat вам правильно всё написал. Частоты можно разные получить в качестве просто генератора, но если нужен именно шим, то там много ограничений.

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

dimax пишет:

zilibob4ik пишет:

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

Если у вас есть лишняя ардуина, то у вас есть частотометр до 8 МГц :) Тыц

Я кстати так не понял, что вы хотели узнать то? Библу ту библой и не назовёшь, она всего лишь три бита в регистре TCCRxB подменяет. В принципе Arhat вам правильно всё написал. Частоты можно разные получить в качестве просто генератора, но если нужен именно шим, то там много ограничений.

Dimax, спасибо за ссылку.

Проверил, частота ШИМ без проблем меняется динамически в процессе исполнения основного кода.

Частота меняется с шагом 1 герц, проверял на цифровом осциллографе.

А по ШИМу какие ограничения?

На любой выставленной частоте ШИМ тоже менялся без проблем.

Была задача:

К выходу микроконтроллера подключен мосфет, к мосфету импульсный трансформатор.

На выход трансформатора диод и сглаживающий кондёр, далее через делитель на ацп.

Логика: прибавляет частоту +1, прогоняет шим от 1 до 128,

записываем максимальное значение с ацп и так далее на заданном диапазоне частот.

В результате получаем оптимальную частоту и скважность работы трансформатора.

В планах повесить шунт на питание мосфета и замерять потребление,

т.к максимальный выход на трансформаторе необходимо получить при минимальном потреблении.

Скажу больше- на конкретном экземпляре трансформатора было достигнуто потребление не более 10 ма

( бп показывал 0, но у него погрешность 10 ма.)

Если трансформатор не в режиме, потребление порой достигало 1 А.

 

В общем, получился DC-DC с очень высоким кпд, на вскидку намного больше 90%, увы, но не более 100 :)

xorkrus
Offline
Зарегистрирован: 22.09.2013
//                 +-\/-+
// ADC0 (D 5) PB5 1|    |8 Vcc
// ADC3 (D 3) PB3 2|    |7 PB2 (D 2) ADC1
// ADC2 (D 4) PB4 3|    |6 PB1 (D 1) PWM1
//            GND 4|    |5 PB0 (D 0) PWM0
// PB2/PB0 - LED 0 GREEN/ LED 2 RED INV
int data[10];
void setup(){
  pinMode(PB0, OUTPUT);
  digitalWrite(PB0,LOW);
  pinMode(PB2, OUTPUT);
  digitalWrite(PB2,HIGH);
  TCCR0A= (1<<COM0A1)|(1<<WGM01)|(1<<WGM00);
  TCCR0B=1<<CS00;
  for (int i=0; i < 10; i++){
    OCR0A=TCNT0;
    uint8_t n=TCNT0;
    if (n <= 128) {
      data[i] = 0;
    } else if (n >= 129) {
      data[i] = 1;
    }
  }
}

void loop(){
  for (int i=0; i < 10; i++){
    if (data[i] == 0) {
      digitalWrite(PB0,HIGH);
      delay(1000);
      digitalWrite(PB0,LOW);
      delay(1000);
    } else if (data[i] == 1) {
      digitalWrite(PB2,LOW);
      delay(1000);
      digitalWrite(PB2,HIGH);
      delay(1000);
    } else {
      digitalWrite(PB0,HIGH);
      digitalWrite(PB2,LOW);
      delay(1000);
      digitalWrite(PB0,LOW);
      digitalWrite(PB2,HIGH);
      delay(1000);
    }
  }
}

Подскажите пожалуйста в чем косяк. Задача заполнить массив data[10] чиселками 0,1 в случайном порядке, а затем поморгать двумя лампочками в соответствии с 0 и 1. Не моргает никак :(

upd.: мой косяк, да. напутал со всеми этими < > ==. вроде исправил. если не считать, что массив заполняется нулями.