ATtiny85 1001 применение.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Как-то незаслуженно обидели весьма достойный микроконтроллер. Из особенностей наличие умножителя частоты и возможность работы таймера до весьма высоких частот, 100 мегагерц уж точно, что позволяет сделать к примеру частотомер.
Надеюсь в этой теме появятся  скетчи ориентированные именно на этот микроконтроллер.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

А что, мне он нравится, на нем даччики первой линии оч. хорошо получаются. Всякие уровни, протечки, термостаты и т.д.  И жрёть немного. 

Жалко, подорожал в 3 раза. 

rkit
Offline
Зарегистрирован: 23.11.2016

ua6em пишет:

 100 мегагерц уж точно

64 максимум

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

ua6em пишет:

 100 мегагерц уж точно

64 максимум

встречал частотомер на 100 мегагерц

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

А что, мне он нравится, на нем даччики первой линии оч. хорошо получаются. Всякие уровни, протечки, термостаты и т.д.  И жрёть немного. 

Жалко, подорожал в 3 раза. 

 я только в начале пути, получил сегодня десяток, залил туда загрузчик от DigiSpark, напрямую с IDE не получилось.
Для заливки загрузчика понадобится bat файл с содержимым:
 

"%~dp0\hardware\tools\avr/bin/avrdude" -C"%~dp0\hardware\tools\avr/etc/avrdude.conf" -v -pattiny85 -cstk500v1 -PCOM2 -b19200 -Uflash:w:"%~dp0\ATtiny85.hex":i -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m -U efuse:w:0xfe:m
@pause

И прошивка в файле ATtiny85.hex:
 

:1019800017C0197A4005930B09021200010100806B
:101990003209040000000000000012011001FF00E5
:1019A0000008D016530703020000000104030904D5
:1019B00011241FBECFE5D2E0CDBFDEBF20E0A0E600
:1019C000B0E001C01D92AC38B207E1F7BFC1A82F4B
:1019D000B92F80E090E041E050EA609530E009C026
:1019E0002D9182279795879510F084279527305E53
:1019F000C8F36F5FA8F30895EADF8D939D93089570
:101A0000CF93CFB7CF93C395B39BE9F7B39B0BC0ED
:101A1000B39B09C0B39B07C0B39B05C0B39B03C076
:101A2000B39B01C0D9C00F92DF93C0916E00DD2738
:101A3000CA58DF4F012EB39B03C0DF910F90E6CF52
:101A40002F930F931F934F932FEF4F6F06B303FB0B
:101A500020F95F933F9350E03BE065C016B3012649
:101A6000502953FDC89556B3012703FB25F92F7361
:101A700006B3B1F05027102713FB26F906B2223027
:101A8000F0F000C016B3012703FB27F90126502907
:101A900006B22430E8F54F77206816B30000F6CF81
:101AA00050274F7D206206B2102F000000C006B301
:101AB00000265029102713FB26F906B2E2CF4F7BF0
:101AC00006B3206400C0DACF01265029187106B28F
:101AD00069F14E7F2160012F16B328C000265029DE
:101AE0004D7F06B22260102F29C0012650294B7F5E
:101AF00006B22460012F2DC016B301265029477F5E
:101B00002860000006B22EC04F7E06B3206130C0B0
:101B1000422706B3499300265029102706B24FEFFB
:101B200013FB20F9297F16B379F2187159F10126B8
:101B3000502906B2012703FB21F9237F06B371F276
:101B4000002650293150D0F006B2102713FB22F99D
:101B5000277E16B351F201265029012703FB06B256
:101B600023F92F7C49F2000006B3102713FB24F958
:101B70000026502906B22F7939F270CF10E21ABF31
:101B800000271DC03B503195C31BD04010E21ABF47
:101B90000881033C29F10B3419F120916C00198163
:101BA000110F1213EDCF093651F10D3211F0013E34
:101BB00039F7CAE01AB715FD02C0CA95D9F70093E4
:101BC00074003F915F914F911F910F912F91DF9181
:101BD0000F90CAB7C5FD17CFCF91CFBFCF91089552
:101BE00020917400222369F3109172001123F1F403
:101BF0003430F2F03093720020936D0019C00091E0
:101C0000720001309CF40AE530916F0034FD11C080
:101C100000936F00C1E6D0E010C0052710E000C0BF
:101C200021C0052710E0C89508BB14C03AE501C0E3
:101C300032ED032EC0E0D0E032E017B31861C39A52
:101C400008B317BB58E120E84FEF20FF052708BB7A
:101C5000279517951C3F28F700004552B0F720FF45
:101C60000527279508BB17951C3FB8F629913A958B
:101C700061F7077E10917300110F08BBC250D0406E
:101C800011F010936C0010E21ABF086017B3177EB2
:101C9000402F477E54E05A95F1F708BB17BB48BB6D
:101CA00090CF2FEFB0E8A0E04AE0B1BF000081EE96
:101CB0009CE0B399FECFB39BFECF0197B399FDCFC4
:101CC00097FF03C0BA1B819501C0BA0FA69539F4DE
:101CD000A0E428F4281710F031B7282FA1E04150D4
:101CE00021F731BF00000895F201309741F02AE753
:101CF000421629E1520629F481B790E002C08FEB29
:101D00009CEC21E00C0120935700E8951124CF01B1
:101D100002962C01089514BE88E181BD87E081BD43
:101D2000BB9A2FE28BE19FE0215080409040E1F789
:101D300000C00000BB988AE580936F008FEF80930E
:101D40006000AC9A8BB780628BBF0895EAE7F9E137
:101D5000E491EF3F11F0E1BF0000DDDF712C312C89
:101D6000412C512CCCE7D5E114E686B3887109F0FB
:101D700014E6115029F41092730010926C0091DF58
:101D80000AB605FE05C03CDE80E28ABF712C04C0A5
:101D9000219759F7C0E0D0E0A89522E032120CC09C
:101DA000E0E8F9E1E054F10983E080935700E89519
:101DB0003097C1F7412C512C832D803459F4F20116
:101DC0003297E03889E1F80750F485E080935700B6
:101DD000E89505C0843019F4CD2B11F4EAC0312CFC
:101DE00080917200835087FD99C090916D009D3263
:101DF00009F092C0883009F08FC083EC80936100B5
:101E00008AE580936F0080917700807690917800CA
:101E1000882379F1911108C082E899E190937100CB
:101E20008093700086E06DC0913069F441145104D4
:101E3000F1F080917B00807C482E50907C0081E105
:101E400087BFE89514C0933081F480917900909118
:101E50007A004ADF80917B0090917C0045DF842DE1
:101E60008F7329F490E4392E4CC09F73392E80E093
:101E700048C08091790010926A00911106C01092BA
:101E80006B002AE630E082E038C0953019F4809388
:101E9000730025C09630E9F490917A00913019F4DE
:101EA0008AE999E104C0923041F488E899E190937D
:101EB00071008093700082E124C09330C1F68111DB
:101EC000D6CF8CEA99E1909371008093700084E002
:101ED00018C0983079F0993031F4809375002AE673
:101EE00030E080E00AC081E09A3009F080E02AE624
:101EF00030E003C025E730E081E0309371002093AB
:101F0000700090917E00911105C090917D0098170E
:101F100008F4892F809360001092720080916F0006
:101F200084FF31C0809160008F3F69F1C82F8930F4
:101F300008F0C8E08C1B809360009091610088E8F5
:101F4000892780936100CC2391F080917000A2E6F4
:101F5000B0E0E82FF091710094919D9331969C2F01
:101F6000980F9E13F9CFF0937100E09370006C2FDF
:101F700082E690E041DDCC5FCC3019F08FEF8093AA
:101F80006000C0936F00C30101963C01803B944008
:101F900029F4EDE7F9E1E491EF3F59F40AB605FEC3
:101FA000E1CE8DE1B39B8DE18150E1F780E28ABF04
:0C1FB000D9CEB1DE1BBE15BAE1CCFFCFCC
:040000030000198060
:00000001FF

Файлы закинуть в каталог с программой IDE, запускать bat от администратора, в качестве программатора ARDUINO AS ISP.

Прошивает почему-то со второго раза, может что с программатором, конденсатор на резет не вешал.

Важно!!!
Установка драйверов возможна только с микроконтроллером в котором зашит только загрузчик, то-есть WINDOWS должна хотя бы раз найти ваше устройство и установить драйвера на выбранный порт USB.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Простой блинк без delay()
 

// BLINK для ATtiny85
// LED_BUILTIN на пине D1

uint32_t timer;
bool flag = true;
#define work_time 500
#define period 500


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN,flag);
}

void loop() {
  if (millis() - timer >= (flag ? work_time : period)) {
    timer = millis();
    flag = !flag;
    digitalWrite(LED_BUILTIN, flag);
  }
}
volatile bool leds = true;
uint16_t divs = 3; // программный делитель
volatile uint16_t clocks;
uint16_t tiks = 0;
#define work_time 5
#define period 15

ISR (TIMER1_COMPA_vect) {
  clocks++;
  if (clocks == divs) {
    clocks = 0;
    tiks++;
    if(tiks >= (leds ? work_time : period)){
      tiks = 0;
      leds = !leds;
       digitalWrite(PB1,leds);
    }
  }
}

void setup() {
  DDRB = (1 << PB1);
  OCR1A = 83;
  OCR1C = 165;
  TCCR1 = (1 << PWM1A) | (15 << CS10); // |(1<<COM1A0)2)|(1<<CS11);
  TIMSK = 1 << OCIE1A;
  digitalWrite(PB1,leds);
}

void loop() {
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

Нахрен загрузчик. Скетч - экспорт бинарного файла и программатор это наше всё. Как оказалось бонусом генериться lst файл с отличным листингом.

Green
Offline
Зарегистрирован: 01.10.2015

Не будем о наших и ваших. Люди хотят как проще.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Green пишет:

Не будем о наших и ваших. Люди хотят как проще.


При этом для простоты приходится делать ряд важных шагов и при этом не ошибаться )))

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

nik182
Offline
Зарегистрирован: 04.05.2015

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

nik182 пишет:

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

Громова? Если он  - видел как Натаха из Липецка его ваяла, на ютубе, сейчас она металлом увлечена )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Тренажёр для изучения телеграфной азбуки, передаёт в средневолновом диапазоне.
Как пример использования умножителя PLL.
Статья на Хабре.
 

Схема:

 

Код программы:
 

/* AM Morse-Code Transmitter - see http://www.technoblogy.com/show?3QEF

   David Johnson-Davies - www.technoblogy.com - 16th December 2021
   ATtiny85 @ 8 MHz (internal oscillator; BOD disabled)
   
   CC BY 4.0
   Licensed under a Creative Commons Attribution 4.0 International license: 
   http://creativecommons.org/licenses/by/4.0/

   HABR
   https://habr.com/ru/company/ruvds/blog/598955/
*/

// Constants

const int Speaker = 0;                    // PB0
const int Antenna = 1;                    // PB1
const int Lamp = 2;                       // PB2
const int Keyer = 3;                      // PB3
const int Auto = 4;                       // PB4
const int Dot = 6;                        // Dot duration in 32ths of a second

const char Message[] PROGMEM = "The quick brown fox jumps over the lazy dog.  ";

uint8_t Chars[48] = {
//A           B           C           D           E           F
  0b01100000, 0b10001000, 0b10101000, 0b10010000, 0b01000000, 0b00101000,
//G           H           I           J           K           L
  0b11010000, 0b00001000, 0b00100000, 0b01111000, 0b10110000, 0b01001000,
//M           N           O           P           Q           R
  0b11100000, 0b10100000, 0b11110000, 0b01101000, 0b11011000, 0b01010000,
//S           T           U           V           W           X
  0b00010000, 0b11000000, 0b00110000, 0b00011000, 0b01110000, 0b10011000,
//Y           Z           0           1           2           3
  0b10111000, 0b11001000, 0b11111100, 0b01111100, 0b00111100, 0b00011100,
//4           5           6           7           8           9
  0b00001100, 0b00000100, 0b10000100, 0b11000100, 0b11100100, 0b11110100,
//+           ,           -           .           /           ?
  0b01010110, 0b11001110, 0b10000110, 0b01010110, 0b10010100, 0b00110010,
//&           '           (           )           !           "            
  0b10101110, 0b01000100, 0b10110100, 0b10110110, 0b10101110, 0b01001010,
};

// Timer **********************************************

volatile unsigned int GlobalTicks = 0;

// Watchdog interrupt counts ticks (1/32 sec)
ISR (WDT_vect) {
  WDTCR = WDTCR | 1<<WDIE;
  GlobalTicks++;
}

// Read ticks without interrupts
unsigned int Ticks () {
  cli(); unsigned int t = GlobalTicks; sei();
  return t;
}

// Wait for n dot durations
void Wait (int n) {
  unsigned int start = Ticks();
  while (Ticks() - start < Dot * n);
}

// Generate morse **********************************************

// Interrupt modulates carrier at 644Hz
ISR (TIMER0_COMPA_vect) {
  TCCR1 = TCCR1 ^ 1<<CS10;
}

void Beep (bool on) {
  if (on) {
    digitalWrite(Lamp, HIGH);             // LED on
    TCCR0B = 0<<WGM02 | 3<<CS00;          // Clock / 64
  } else {
    digitalWrite(Lamp, LOW);              // LED off
    TCCR0B = 0<<WGM02 | 0<<CS00;          // Clock off
    TCCR1 =  TCCR1 | 1<<CS10;             // Leave carrier on
  }
}

void DotDash (bool dash) {
  Beep(true);
  if (dash) Wait(3); else Wait(1);
  Beep(false);
  Wait(1);
}

void Letter (char letter) {
  uint8_t index;
  letter = letter | 0x20;                 // Convert letters to lower case
  if (letter == ' ') { Wait(4); return; }
  else if (letter >= 'a' && letter <= 'z') index = letter - 'a';
  else if (letter >= '0' && letter <= '9') index = letter - '0' + 26;
  else if (letter >= '+' && letter <= '/') index = letter - '+' + 36;
  else if (letter = '?') index = 41;
  else if (letter >= '&' && letter <= ')') index = letter - '&' + 42;
  else if (letter >= '!' && letter <= '"') index = letter - '!' + 46;
  else return;
  uint8_t code = Chars[index];
  while (code != 0x80) {
    DotDash(code & 0x80);
    code = code<<1;
  }
  Wait(2);
}

// Setup **********************************************

void setup() {
  pinMode(Antenna, OUTPUT);               // Antenna
  pinMode(Speaker, OUTPUT);               // Optional piezo
  pinMode(Lamp, OUTPUT);                  // Optional LED
  pinMode(Keyer, INPUT_PULLUP);           // Morse keyer
  pinMode(Auto, INPUT_PULLUP);            // Transmit message

  // Set up Timer/Counter1 to generate 585kHz
  PLLCSR = 1<<LSM | 1<<PCKE | 1<<PLLE;
  TCCR1 =  1<<CTC1 | 1<<COM1A0 | 1<<CS10; // CTC mode /1
  OCR1C = 28;
  
  // Set up Timer/Counter0 to 644Hz
  TCCR0A = 1<<COM0A0 | 2<<WGM00;          // CTC mode
  TCCR0B = 0<<WGM02 | 3<<CS00;            // Clock / 64
  OCR0A = 96;                             // Divide by 97
  TIMSK = 1<<OCIE0A;                      // Interrupt enabled
  
  // Set up Watchdog timer for 32Hz interrupt for ticks timer.
  WDTCR = 1<<WDIE | 1<<WDP0;              // 32Hz interrupt
}

void loop() {
  // Manual mode
  if (digitalRead(Keyer) == 0) Beep(true);
  else Beep(false);
  // Auto mode
  if (digitalRead(Auto) == 0) {
    int p = 0; char c;
    do {
      char c = pgm_read_byte(&Message[p++]);
      if (c == 0 || digitalRead(Keyer) == 0) break;
      Letter(c);
    } while (true);
  } 
}

Макетная плата:

Компиляция программы:
Для компиляции используйте ATTiny Core от Spence Konde6.
Во вкладке ATtinyCore выберите опцию ATtiny25/45/85 (No bootloader), ведущую в меню Board.
Убедитесь, что опции выставлены как указано ниже (прочие игнорируйте):

Chip: «ATtiny85»
Clock: «8 MHz (internal)»

Выберите Burn Bootloader для установки фьюз-битов в соответствии с этим вариантом частоты.
Затем загрузите программу, используя ISP (внутрисхемное программирование).

В переводе статьи есть ошибки в расчёте частоты излучения, должно быть:

The carrier frequency is:

f = 32000000 / (2 × (28 + 1)) = 552kHz

 

b707
Offline
Зарегистрирован: 26.05.2017

тини85 это та же атмега8/88, только с меньшим числом ног. Особенностей минимум. Скетчи в Ардуино ИДЕ. Че там осваивать? :)

Я вот все мечтаю начать колхозить мелкие девайсы на стм8, коих у меня целый пакетик :)... но все времени не хватает...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

тини85 это та же атмега8/88, только с меньшим числом ног. Особенностей минимум. Скетчи в Ардуино ИДЕ. Че там осваивать? :)

Я вот все мечтаю начать колхозить мелкие девайсы на стм8, коих у меня целый пакетик :)... но все времени не хватает...

в атмеге 8 есть PLL?

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

в атмеге 8 есть PLL?

не знаю

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

ua6em пишет:

в атмеге 8 есть PLL?

не знаю

цимес ATtiny  в наличии умножителя и высокоскоростного таймера )))
 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Реле оттайки (ТИМ-1) на ATtiny85:
 

// Настройка фьюзов для ATtiny85

// Fuse High Byte
// D7 - RSTDISBL = 1  (External Reset enabled, if disabled SPI low voltage programming is impossible)
// D6 - DWEN = 1      (debugWire disabled, if enabled SPI low voltage programming is impossible)
// D5 - SPIEN = 0  (Serial Programming enabled, if disabled low and high voltage programming is impossible)
// D4 - WDTON = 1  (Watchdog Timer is not locked to be reset source, it can be set-up by software)
// D3 - EESAVE = 1 (EEPROM is not preserved through Chip Erase)
// D2 - BODLEVEL2 = 1 (не программируется)
// D1 - BODLEVEL1 = 1 (не программируется)
// D0 - BODLEVEL0 = 1 (не программируется)

// Fuse Low Byte
// D7 - CKDIV8 = 0 (CLKPR = 3 upon start: divide clock by 8)
// D6 - CKOUT = 1 (не программируется)
// D5 - SUT1 = 1  (не программируется)
// D4 - SUT0 = 0  ()
// D3 - CKSEL3 = 1 (MHz)
// D2 - CKSEL2 = 0 (MHz)
// D1 - CKSEL1 = 1 (не программируется)
// D0 - CKSEL0 = 0 (MHz)




#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/eeprom.h>      // не забываем подключить
#include <EEPROM.h>

#define  freezer  0x00       //; freeser mode
#define  heater   0x01       //; heater mode
#define  _1min    12         //; 1 min const
#define  _1hour   60*_1min   //; 1 hour const
#define  _2min    2*_1min    //; 2 min const
#define  _8min    8*_1min    //; 8 min const
#define  _8hour   8*_1hour   //; 8 hour const
#define ac_tick   15/0.02    //; количество 20-ти миллисекундных тиков за 15 секунд
#define xp_tick   8*60*60/15 //; количество 15 секундных тиков в 8-часах работы
#define po_tick   10*60/15   //; количество 15 секундных тиков за 10 минут
#define ao_tick   40*60/15   //; количество 15 секундных тиков за 40 минут


volatile int schetchik = 0; // считает в 15 секундных интервалах
volatile int ac_schetchik = 0;
bool ac_flag = 0;
bool btn_flag = 0;
volatile byte work_mode = 0; // 0 - рабочий режим, 1 - активная оттайка, 2 - пассивная оттайка

// Прерывания
// INT0 обрабатывает нажатие кнопки (настраивать INPUT_PULLUP)
// PCINT2 (настраивать INPUT)

ISR(INT0_vect) {
  // наш код обработки нажатия кнопки принудительного оттаивания
  if (!btn_flag) // еще не было нажатия кнопки
  {
    btn_flag = 1;
    digitalWrite(0, HIGH); // включим реле оттайки
    schetchik = 0;         // сбросим счетчик в ноль
    work_mode = 1;
    EEPROM.write(2, work_mode);
  }
}

// Обработчик прерывания PCINT0
ISR(PCINT0_vect)
{
  ac_schetchik++;
  if (ac_schetchik >= ac_tick) {
    ac_flag = 1; // увеличить счетчик в EEPROM
    ac_schetchik = 0;
  }
}

//Функции (с) Кэп
void EEPROM_write(int uiAddress, char ucData)
{
  while (EECR & (1 << EEPE)); /*Ждать завершения предыдущей записи*/
  EEAR = uiAddress; /*Проинициализировать регистры*/
  EEDR = ucData;
  EECR |= (1 << EEMPE); /*Установить флаг EEMWE*/
  EECR |= (1 << EEPE); /*Начать запись в EEPROM*/
}

char EEPROM_read(int uiAddress)
{
  while (EECR & (1 << EEPE)); /*Ждать завершения предыдущей записи*/
  EEAR = uiAddress; /* Проинициализировать регистр адреса*/
  EECR |= (1 << EERE); /*Выполнить чтение*/
  return EEDR;
}

void EEPROMWriteInt(int p_address, int p_value) // принимает 2 параметра, адресс и число 0...65534
{ // забирает 2 ячейки, так что использовать ячейки 0, 2, 4, 6...
  byte lowByte = ((p_value >> 0) & 0xFF);
  byte highByte = ((p_value >> 8) & 0xFF);
  EEPROM_write(p_address, lowByte);
  EEPROM_write(p_address + 1, highByte);
}

int EEPROMReadInt(int p_address) //Считывает число в диапазоне 0...65534
{ // использует 2 ячейки, так что считывает ячейки 0, 2, 4, 6...
  byte lowByte = EEPROM_read(p_address);
  byte highByte = EEPROM_read(p_address + 1);
  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

void setup() {
  DDRB = 0b00000001;    // pinMode(0, OUTPUT);
  PORTB &= ~(1 << PB0); // digitalWrite(0, LOW);
  pinMode(1, INPUT);    // D1 PB1 (ATTINY13A - Attiny13)
  PORTB |= (1 << PB1);  // D1 - INPUT_PULLUP
  pinMode(2, INPUT);    // D2 PB2 (ATTINY13A - Attiny13)

  // Настройка прерываний
  // Инициализация INT0 и PCINT0
  cli(); // Запрещаем прерывания на время изменения WDE и WDP
  MCUCR = _BV(ISC01) | _BV(ISC00);  // FALLING
  // RISING - 11, LOW - 00,HIGH - 01,  FALLING - 10

  GIMSK |= (1 << PCIE) | _BV(INT0); // Разрешаем внешние прерывания PCINT0, INT0
  PCMSK |= (1 << PB2)/* | (1<<PB1)*/; // Разрешаем по маске прерывания на ноге (PCINT2)
  sei();                            // Разрешаем прерывания глобально: SREG |= (1<<SREG_I)

  // восстанавливаем значение счетчика и режим работы
  work_mode = EEPROM.read(2);
  schetchik = EEPROMReadInt(0);
}

void loop() {
  work_mode = EEPROM.read(2);
  // Раз в 15 секунд пишем счетчик в EEPROM
  if (ac_flag) {
    schetchik++;
    EEPROMWriteInt(0, schetchik);
    ac_flag = 0;
  }
  if (work_mode == 0) {
    if (schetchik >= xp_tick /*8 часов */)
    {
      // включить режим активной оттайки
      digitalWrite(0, HIGH);
      work_mode = 1;
      EEPROM.write(2, work_mode);
      schetchik = 0;      // запущен таймер активной оттайки
    }
  }
  if (work_mode == 1) {
    if (schetchik >= ao_tick /*8 часов */)
    {
      work_mode = 2;
      EEPROM.write(2, work_mode);
      schetchik = 0;      // запущен таймер пассивной оттайки
    }
  }
  if (work_mode == 1) {
    if (schetchik >= po_tick /*8 часов */)
    {
      btn_flag = 0;
      work_mode = 0;
      EEPROM.write(2, work_mode);
      schetchik = 0;      // запущен таймер пассивной оттайки
      digitalWrite(0, LOW); // переключиться в режим охлаждения
    }
  }
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Можно ли настроить на вывод отрицательных температур?
 

#include <TM1637Display.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Module connection pins (Digital Pins)
#define CLK 4
#define DIO 3
#define ONE_WIRE_BUS 2

const uint8_t SEG_ERR[] = {
  SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E
  SEG_E | SEG_G,                         // r
  SEG_E | SEG_G,                         // r
  0,                                     // space
};

TM1637Display display(CLK, DIO);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  display.setBrightness(0x02);
  sensors.begin();
  if (sensors.getDS18Count() == 0)
    display.setSegments(SEG_ERR);
  else
    sensors.setResolution(12);
}

void loop() {
  if (sensors.getDS18Count() != 0) {
    sensors.requestTemperatures();
    double temp = sensors.getTempCByIndex(0);
    display.showNumberDecEx(temp * 100, 0b01000000, false);
  }
  delay(1000);
}

Logik
Offline
Зарегистрирован: 05.08.2014

Готов поспорить, до 1001 применений не доберётся.

Upper
Offline
Зарегистрирован: 23.06.2020

Похоже здесь был бы уместен заголовок "ATtiny85 1001 применение по ua6em"

Upper
Offline
Зарегистрирован: 23.06.2020

ua6em пишет:

Можно ли настроить на вывод отрицательных температур?

По поводу отрицательных температур не понял.
Они вроде и так выводятся, если места хватает. Т.е. если не меньше -9.99
Если надо холоднее, то умножать не на 100 а на 10 и сдвинуть точку.
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Upper пишет:

ua6em пишет:

Можно ли настроить на вывод отрицательных температур?

По поводу отрицательных температур не понял.
Они вроде и так выводятся, если места хватает. Т.е. если не меньше -9.99
Если надо холоднее, то умножать не на 100 а на 10 и сдвинуть точку.

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

Green
Offline
Зарегистрирован: 01.10.2015

ua6em пишет:

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


Ужас. Я на 3-х разрядный минус вывожу: -10  -9.9  0  0.5  36.6
Офигенные проблемы. 

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

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

это потому что в коде не используется PLL и высокоскоростной таймер :)

Green
Offline
Зарегистрирован: 01.10.2015

b707 пишет:

это потому что в коде не используется PLL и высокоскоростной таймер :)


Как будто без PLL нельзя получить частоты СВ диапазона.)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Green пишет:

b707 пишет:

это потому что в коде не используется PLL и высокоскоростной таймер :)


Как будто без PLL нельзя получить частоты СВ диапазона.)

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Блинк на первом таймере:
 

// ATMEL                                ATtiny 25/45/85
//                                           +-\/-+
//             !RESET PCINT5 5/A0 (D 5) PB5 1|    |8  Vcc
//  XTAL1 CLKI !OC1B  PCINT3 3/A3 (D 3) PB3 2|    |7  PB2 (D 2) 2/A1 PCINT2 USCK SCK T0   INT0 SCL  
//  XTAL2 CLKO  OC1B  PCINT4 4/A2 {D 4) PB4 3|    |6  PB1 (D 1) pwm1 PCINT1 MISO DO  OC0B AIN1
//                                      GND 4|    |5  PB0 (D 0) pwm0 PCINT0 MOSI DI  OC0A AIN0 SDA AREF
//                                           +----+



enum Prescalers {
  //T1CK
  PRESCALER_1 = 1,
  PRESCALER_2 = 2,
  PRESCALER_4 = 3,
  PRESCALER_8 = 4,
  PRESCALER_16 = 5,
  PRESCALER_32 = 6,
  PRESCALER_64 = 7,
  PRESCALER_128 = 8,
  PRESCALER_256 = 9,
  PRESCALER_512 = 10,
  PRESCALER_1024 = 11,
  PRESCALER_2048 = 12,
  PRESCALER_4096 = 13,
  PRESCALER_8192 = 14,
  PRESCALER_16384 = 15
};

void setup() {
  uint8_t prescaler = PRESCALER_16384;
  uint8_t topValue = 254;

  PLLCSR = 1<<LSM | 1<<PCKE | 1<<PLLE; // тактирование от PLL CLKx2 (4)

  DDRB |= (1 << DDB1) | (1 << DDB4);
  TCCR1 = prescaler | (1 << CTC1/*обнулить счетчик*/) | (1 << COM1A0/*переключить выходную линию*/);
  GTCCR = 1 << COM1B0/*переключить выходную линию*/;
  OCR1C = topValue;

}

void loop() {}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Генератор импульсов: (библиотека здесь)
 

// ATMEL                                ATtiny 25/45/85
//                                           +-\/-+
//             !RESET PCINT5 5/A0 (D 5) PB5 1|    |8  Vcc
//  XTAL1 CLKI !OC1B  PCINT3 3/A3 (D 3) PB3 2|    |7  PB2 (D 2) 2/A1 PCINT2 USCK SCK T0   INT0 SCL  
//  XTAL2 CLKO  OC1B  PCINT4 4/A2 {D 4) PB4 3|    |6  PB1 (D 1) pwm1 PCINT1 MISO DO  OC0B AIN1
//                                      GND 4|    |5  PB0 (D 0) pwm0 PCINT0 MOSI DI  OC0A AIN0 SDA AREF
//                                           +----+

// BLINK для ATtiny85
#include "Blink.h"

uint8_t led01_pin = 0;
uint8_t led02_pin = 1; //(LED_BUILTIN)
uint8_t led03_pin = 2;

uint16_t work_01_time = 2000;  // включено (время включенного состояния мс) LED1
uint16_t pause_01 = 10000;     // выключено (время выключенного состояния мс) LED1
uint16_t impuls_01 = 270;      // число импульсов LED1
bool inverse_01 = true;

uint16_t work_02_time = 250;   // включено (время включенного состояния мс) LED2
uint16_t pause_02 = 300;       // выключено(время выключенного состояния мс) LED2
uint16_t impuls_02 = 27;       // число импульсов LED2
bool inverse_02 = false;

uint16_t work_03_time = 10;    // включено (время включенного состояния мс) LED3
uint16_t pause_03 = 10;        // выключено(время выключенного состояния мс) LED3
uint16_t impuls_03 = 5000;     // число импульсов LED3
bool inverse_03 = false;

Blink leds_01(led01_pin, work_01_time, pause_01, impuls_01, inverse_01);
Blink leds_02(led02_pin, work_02_time, pause_02, impuls_02);
Blink leds_03(led03_pin);

void setup() {
  leds_01.start();
  leds_02.start();
  leds_03.start();
}

void loop()
{
  leds_01.myrun();
  leds_02.myrun();
  leds_03.myrun();
}

 

b707
Offline
Зарегистрирован: 26.05.2017

если значения в enum идут последовательно, необязательно присваивать каждое:

enum Prescalers {
  //T1CK
  PRESCALER_1 = 1,
  PRESCALER_2,
  PRESCALER_4,
  PRESCALER_8,
  PRESCALER_16,
  PRESCALER_32,
  PRESCALER_64,
 .....
};

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Еще бы калькулятор от Евгения Петровича к ATtiny адаптировать не помешало бы...

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

Еще бы калькулятор от Евгения Петровича к ATtiny адаптировать не помешало бы...

и что мешает?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

У меня такая в пылесосе трудится.
На практике использовал данный МК один раз.
Заказ был на эмулятор датчика температуры, делал i2c slave устройство, вроде претензий от заказчика не было.

ЗЫ:ещё вспомнил для "ненастоящего" немца (или австрийца) управление семафором на макете железной дороги.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Столкнулся с непонятками! Есть простой блинк на ватчдог таймере, на значении 4096 - встряёт в состоянии HIGH, ядро и платка - DigiSpark

Код вот:
 

enum Wdt {
  //WDP(3-0)регистра WDTCR
  PRESCALER_16ms = 0,
  PRESCALER_32ms = 1,
  PRESCALER_64ms = 2,
  PRESCALER_128ms = 3,
  PRESCALER_256ms = 4,
  PRESCALER_512ms = 5,
  PRESCALER_1024ms = 6,
  PRESCALER_2048ms = 7,
  PRESCALER_4096ms = 8,
  PRESCALER_8192ms = 9
};


bool flash;

// Watchdog interrupt
ISR (WDT_vect) {
  WDTCR = WDTCR | 1 << WDIE;// |PRESCALER_4096ms;
  flash = !flash;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  WDTCR = 1 << WDIE | PRESCALER_4096ms;
}

void loop() {
  digitalWrite(LED_BUILTIN, flash);
}

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ua6em пишет:

Столкнулся с непонятками! Есть простой блинк на ватчдог таймере, на значении 4096 - встряёт в состоянии HIGH, ядро и платка - DigiSpark

Код вот:
 

enum Wdt {
  //WDP(3-0)регистра WDTCR
  PRESCALER_16ms = 0,
  PRESCALER_32ms = 1,
  PRESCALER_64ms = 2,
  PRESCALER_128ms = 3,
  PRESCALER_256ms = 4,
  PRESCALER_512ms = 5,
  PRESCALER_1024ms = 6,
  PRESCALER_2048ms = 7,
  PRESCALER_4096ms = 8,
  PRESCALER_8192ms = 9
};


bool flash;

// Watchdog interrupt
ISR (WDT_vect) {
  WDTCR = WDTCR | 1 << WDIE;// |PRESCALER_4096ms;
  flash = !flash;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  WDTCR = 1 << WDIE | PRESCALER_4096ms;
}

void loop() {
  digitalWrite(LED_BUILTIN, flash);
}

 

Оно вообще зачем ?
Тебе кто то запретил подключать "util/delay.h" ?
Почему тогда он тебе разрешил использовать digitalWrite() ?

Если то теме, то в строке 26 должно быть как минимум(с даташитом сверяться лениво):
WDTCR = (1 << WDIE) | (1<<PRESCALER_4096ms);

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Сам же и отвечу, лоханулся со значением, WDP3 он в регистре 5-й бит )))
 

enum Wdt {
  //WDP(3-0)регистра WDTCR
  PRESCALER_16ms = 0,
  PRESCALER_32ms = 1,
  PRESCALER_64ms = 2,
  PRESCALER_128ms = 3,
  PRESCALER_256ms = 4,
  PRESCALER_512ms = 5,
  PRESCALER_1024ms = 6,
  PRESCALER_2048ms = 7,
  PRESCALER_4096ms = 32,
  PRESCALER_8192ms = 33
};


bool flash;
uint8_t regs;

// Watchdog interrupt
ISR (WDT_vect) {
  WDTCR = WDTCR | 1 << WDIE;
  flash = !flash;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  regs = PRESCALER_4096ms;
  WDTCR =  regs | 1 << WDIE;
}

void loop() {
  digitalWrite(LED_BUILTIN, flash);
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

BLINK на 1 таймере, используется встроенный LED DigiSpark.
Расчет таймеров:
 

		FREQ-255								PWM
CK/	16500000	CS13	CS12	CS11	CS10		64453,125	64202,33463	256
1	16500000	0	0	0	1	1	64453,125	64202,33463	256
2	8250000	0	0	1	0	2	32226,5625	32101,16732	256
4	4125000	0	0	1	1	3	16113,28125	16050,58366	256
8	2062500	0	1	0	0	4	8056,640625	8025,291829	256
16	1031250	0	1	0	1	5	4028,320313	4012,645914	256
32	515625	0	1	1	0	6	2014,160156	2006,322957	256
64	257812,5	0	1	1	1	7	1007,080078	1003,161479	256
128	128906,25	1	0	0	0	8	503,5400391	501,5807393	256
256	64453,125	1	0	0	1	9	251,7700195	250,7903696	256
512	32226,5625	1	0	1	0	10	125,8850098	125,3951848	256
1024 16113,28125	1	0	1	1	11	62,94250488	62,69759241	256
2048 8056,640625	1	1	0	0	12	31,47125244	31,34879621	256
4096 4028,320313	1	1	0	1	13	15,73562622	15,6743981	256
8192 2014,160156	1	1	1	0	14	7,86781311	7,837199052	256
16384 1007,080078	1	1	1	1	15	3,933906555	3,918599526	256

 

Код программы:

enum Prescalers_1 {
  //T1CK
  PRESCALER_1 = 1,
  PRESCALER_2 = 2,
  PRESCALER_4 = 3,
  PRESCALER_8 = 4,
  PRESCALER_16 = 5,
  PRESCALER_32 = 6,
  PRESCALER_64 = 7,
  PRESCALER_128 = 8,
  PRESCALER_256 = 9,
  PRESCALER_512 = 10,
  PRESCALER_1024 = 11,
  PRESCALER_2048 = 12,
  PRESCALER_4096 = 13,
  PRESCALER_8192 = 14,
  PRESCALER_16384 = 15
};
void setup() {
  
  uint8_t prescaler1 = PRESCALER_16384;
  DDRB = (1 << PB1);
  OCR1A = 127;
  OCR1C = 255;
  TCCR1 = prescaler1 |(1 << PWM1A) | (1 << COM1A0);// | (1 << CS13) | (1 << CS12) | (1 << CS11)| (1 << CS10);

}

void loop() {

}

 

b707
Offline
Зарегистрирован: 26.05.2017

мое сообщение #28 игнорируете?

Green
Offline
Зарегистрирован: 01.10.2015

Ну сказали же, нафига енуму присвоение! Как то по калечному всё.)
Долго я писал.)))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

мое сообщение #28 игнорируете?

а #34 как?

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

а #34 как?

enum Wdt {
  //WDP(3-0)регистра WDTCR
  PRESCALER_16ms ,
  PRESCALER_32ms,
  PRESCALER_64ms ,
  PRESCALER_128ms,
  PRESCALER_256ms,
  PRESCALER_512ms ,
  PRESCALER_1024ms,
  PRESCALER_2048ms ,
  PRESCALER_4096ms = 32,
  PRESCALER_8192ms = 33
};

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

Green
Offline
Зарегистрирован: 01.10.2015

"Горбатого могила исправит".( Так на ассемблере писать нужно!) А Wdt - это зачем?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Green пишет:

 Так на ассемблере писать нужно! А Wdt - это зачем?

так оттуда и тянется, 500 байт программы 16 килобайт листинг )))
Это я таймеры изучаю...

PS вообще-то подглядел у ЕвгенийП, а он плохому не научит )))

Logik
Offline
Зарегистрирован: 05.08.2014

Задействованный wdt - значить код глючит, зависает а автор кода потерял надежду найти и исправить ошибки )))

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Ну не соглашусь, всякие форс мажоры типа Эл магнитных помех никто не исключал, так что wdt пригодится всегда

Green
Offline
Зарегистрирован: 01.10.2015

Logik пишет:

Задействованный wdt ...


Не, не, не. Я об имени перечисления, которое нигде не используется.)

Upper
Offline
Зарегистрирован: 23.06.2020

ua6em пишет:

PS вообще-то подглядел у ЕвгенийП, а он плохому не научит )))

Может он в тот момент не знал, что за ним подглядывают.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

Задействованный wdt - значить код глючит, зависает а автор кода потерял надежду найти и исправить ошибки )))

мне тут автор радиолюбительских спутников книжку подписал и я её даже прочитал, так там аж три типа WDT используется, поэтому AO-7 до сих пор еще живой )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Green пишет:

Logik пишет:

Задействованный wdt ...


Не, не, не. Я об имени перечисления, которое нигде не используется.)

мой косяк )))

Green
Offline
Зарегистрирован: 01.10.2015

ua6em пишет:

мне тут автор радиолюбительских спутников книжку подписал и я её даже прочитал, так там аж три типа WDT используется, поэтому AO-7 до сих пор еще живой )))


В 2002-м воскрес, как я понял? И что работает кто то с ним? Как это выглядит?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Green пишет:

ua6em пишет:

мне тут автор радиолюбительских спутников книжку подписал и я её даже прочитал, так там аж три типа WDT используется, поэтому AO-7 до сих пор еще живой )))


В 2002-м воскрес, как я понял? И что работает кто то с ним? Как это выглядит?

отлично работает, у него зона покрытия более 1000км, высоко висит, да и наклон орбиты очень приличный, в высокие широты хорошо заходит... в 11-44 войдёт в зону радиосвязи в 11-57 покинет, там CW, если действовать оперативно пяток связей можно провести )))