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

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

Программаторы такие разные ...
Тоже работал с UsbASP сперва. Потом он в новой среде перестал работать, перешивать лень было.  Собрал себе такую штуку  на скорую руку 
Шьет меги в DIP28, Тиньки в DIP8, Тиньки в SOP8 через переходники (широкие и узкие)
Ну и ICSP разъемчик, если вдрук какю Ардуинку нужно перешить
+ еще выводы для макетирования. очень удобно тиньки в SOP8 отлаживать перед тем как на плату паять
Ну и нанку можно при необходимочти достать и заюзать

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

Baks пишет:

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

да и 70 р не такая уж и большая сумма)))

wdrakula а вы сами что используете? программатор или ардуинку для прошивки?

У меня тоже есть программаторы и китайские и самопальные, но для тинек давно уже тольк Ардуинку юзаю.

Вот даже видео записал как.

https://youtu.be/TS-b9FpGlYs

skela78
Offline
Зарегистрирован: 02.08.2015

Добрый Вечер.

собрал проект термостата для авто с двумя независимыми датчиками DS18B20 (работает на UNO) но не могу уменьшить для заливки в тини13. тыкните пальцем куда копать или помогите урезать. В дальнейшем датчик будет один на радиаторе, а пока два для контроля t двигателя и радиатора.

//I2C bus support
#include <Wire.h>
//I2C 
#include <LiquidCrystal_I2C.h>
//OneWire bus suport
#include <OneWire.h>
//DS18B20 temperature sensor support
#include <DallasTemperature.h>
//DS18B20 sensor pin
#define ONE_WIRE_BUS_1 9
#define ONE_WIRE_BUS_2 10

#define Relay1 12      // Реле 1
#define Relay2 13      // Реле 2

// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire_1(ONE_WIRE_BUS_1);
OneWire oneWire_2(ONE_WIRE_BUS_2);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors_1(&oneWire_1);
DallasTemperature sensors_2(&oneWire_2);

LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

byte ball[8] = { // создаем свой символ и присваиваем ему имя "ball"
0b00000,
0b01110,
0b10001,
0b10001,
0b10001,
0b10001,
0b01110,
0b00000
};
byte smile[8] = { // создаем свой символ и присваиваем ему имя "smile"
0b00000,
0b01110,
0b11111,
0b11111,
0b11111,
0b11111,
0b01110,
0b00000
};

void setup()
{
  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  
  lcd.init();
  lcd.backlight(); //Turns backlight on
  sensors_1.begin();
  sensors_2.begin();
}

void loop()
{  
  sensors_1.requestTemperatures();
  sensors_1.setResolution(12);   // установим разрешающую способность 12 бит (9-10-11-12)
  sensors_2.requestTemperatures();
  sensors_2.setResolution(12);   // установим разрешающую способность 12 бит (9-10-11-12)
  //Read first sensor
  float temp1 = sensors_1.getTempCByIndex(0);
  
  lcd.setCursor (0, 0 );
  lcd.print("T1: ");
  lcd.print(temp1);
  lcd.print("      ");

  //Read second sensor  
  float temp2 = sensors_2.getTempCByIndex(0);
  
  //Print second sensor result
  lcd.setCursor (0, 1 );
  lcd.print("T2: ");  
  lcd.print(temp2);
  lcd.print("      ");
  
  lcd.setCursor (12, 1 );
  lcd.print("P2-"); 

  lcd.setCursor (12, 0 );
  lcd.print("P1-");
  
  lcd.createChar(0, ball);
  lcd.createChar(1, smile);
  
  // 1 скорость венитляторов ВКЛ - 95С ;  ВЫКЛ - 85С 
  // 2 скорость вентиляторов ВКЛ - 102С ; ВЫКЛ - 92С 
  
  if (temp1 >= 95)  // если t больше или равна 45C 
  {
  digitalWrite(Relay1, HIGH);      //  реле1 вкл
  }
 
   if (temp1 <=85)   //если t меньше или равна 35С                   
  {                     
  digitalWrite(Relay1, LOW);     //  реле1 выкл
  }
  if (temp1 >=102)   // если t больше или равна 52C  
  {
  digitalWrite(Relay2, HIGH);      //  реле2 вкл
  }
    if (temp1 <=92)   //если t меньше или равна 42С 
  {                     
  digitalWrite(Relay2, LOW);     //  реле2 выкл
  }
  if (digitalRead(Relay1) == HIGH)   //  реле1 вкл
  {
  lcd.setCursor (15, 0 );            //  реле1 вкл
  lcd.write(1);
  }
  else
  {
  lcd.setCursor (15, 0 );            //  реле1 выкл
  lcd.write(0);
  }
   if (digitalRead(Relay2) == HIGH)  //  реле2 вкл
  {
  lcd.setCursor (15, 1 );            //  реле2 вкл
  lcd.write(1);
  }
  else
  {
  lcd.setCursor (15, 1 );            //  реле2 выкл
  lcd.write(0);
  }
  //Wait 0.1 sec
  delay(100);  
}

 

skela78
Offline
Зарегистрирован: 02.08.2015

урезал - убрав экран и что с ним связано и конечно ноги тиньки другие пока не изменял (надеюсь это не кричично при проверки скетча на ошибки). Что еще можно урезать?

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS_1 9
#define ONE_WIRE_BUS_2 10
#define Relay1 12      // Реле 1
#define Relay2 13      // Реле 2
OneWire oneWire_1(ONE_WIRE_BUS_1);
OneWire oneWire_2(ONE_WIRE_BUS_2);
DallasTemperature sensors_1(&oneWire_1);
DallasTemperature sensors_2(&oneWire_2);

void setup()
{
  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  sensors_1.begin();
  sensors_2.begin();
}

void loop()
{  
  sensors_1.requestTemperatures();
  sensors_1.setResolution(12);   // установим разрешающую способность 12 бит (9-10-11-12)
  sensors_2.requestTemperatures();
  sensors_2.setResolution(12);   // установим разрешающую способность 12 бит (9-10-11-12)
  //Read first sensor
  float temp1 = sensors_1.getTempCByIndex(0);
  float temp2 = sensors_2.getTempCByIndex(0);
  if (temp1 >= 95)  // если t больше или равна 95C 
  {
  digitalWrite(Relay1, HIGH);      //  реле1 вкл
  }
  if (temp1 <=85)   //если t меньше или равна 85С                   
  {                     
  digitalWrite(Relay1, LOW);     //  реле1 выкл
  }
  if (temp1 >=102)   // если t больше или равна 102C  
  {
  digitalWrite(Relay2, HIGH);      //  реле2 вкл
  }
    if (temp1 <=92)   //если t меньше или равна 92С 
  {                     
  digitalWrite(Relay2, LOW);     //  реле2 выкл
  }
  delay(100);  
}

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

поищите... несколько страниц назад был мой пример вообще без библиотек. так там еще и часы 3231 влезли и экран и даллас.

skela78
Offline
Зарегистрирован: 02.08.2015

Спасибо что отозвались. Обязательно посмотрю и почитаю

skela78
Offline
Зарегистрирован: 02.08.2015

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

skela78
Offline
Зарегистрирован: 02.08.2015

немного подправил но не влазиет в тини 13. прошу помощи впихнуть это в тиньку

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS_1 0
OneWire oneWire_1(ONE_WIRE_BUS_1);
DallasTemperature sensors_1(&oneWire_1);

void setup()
{
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  sensors_1.begin();
}

void loop()
{  
  sensors_1.requestTemperatures();
  sensors_1.setResolution(12);   // установим разрешающую способность 12 бит (9-10-11-12)
  //Read first sensor
  float temp1 = sensors_1.getTempCByIndex(0);
  if (temp1 >= 95)  // если t больше или равна 45C 
  {
  digitalWrite(4, HIGH);      //  реле1 вкл
  }
  if (temp1 <=85)   //если t меньше или равна 35С                   
  {                     
  digitalWrite(4, LOW);     //  реле1 выкл
  }
  if (temp1 >=102)   // если t больше или равна 52C  
  {
  digitalWrite(3, HIGH);      //  реле2 вкл
  }
    if (temp1 <=92)   //если t меньше или равна 42С 
  {                     
  digitalWrite(3, LOW);     //  реле2 выкл
  }
  delay(100);  
}

 

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

Выкинуть ардуиновские функции pinMode() и digitalWrite(), заменить их на прямое управление портами через регистры. Ну и библиотеки много места занимают.

skela78
Offline
Зарегистрирован: 02.08.2015

направте - покажите примерно как. дальше думаю въеду. а то что то сильно понять не могу что там и для чего в прямом управлении портами

 

skela78
Offline
Зарегистрирован: 02.08.2015

тип того и порт В от сокращенного РВ

PORTB=0x00;  //записать в весь порт В 0
DDRB=0x01;   //настроить порт В 0x01: по другому 000001 (1 означает выход, 0 вход)

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

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

тинька13 - это учебное пособие, для прикола, для поднятия скилла програмирования у спецов. Не для ардуиновского подхода с библиотеками - не поместится ничего.

skela78
Offline
Зарегистрирован: 02.08.2015

уже так и сделал. Все равно спасибо за объяснения. может когда нибудь дойдет и до этого очередь.

и где можно почитать про ето более подробно

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

skela78 пишет:

уже так и сделал. Все равно спасибо за объяснения. может когда нибудь дойдет и до этого очередь.

и где можно почитать про ето более подробно

 "ето" ?? У вас ведь больше 10 сообщений - значит уже можете редактировать. Впрочем, ваше дело.

---------------

Прочитать можно и нужно в даташите. В нем все действия с управляющими регистрами сопровождаются примерами на ассемблере и на С.

И да - даташит написан на аглицком. Без английского - только в дворники, это я уже много раз писал. Для первичного понимания можно найти на русском циклы статей по программированию АВР контроллеров, на схем.нет что-то было. Они легко ищутся в Яндексе или Гугле.

anarch
Offline
Зарегистрирован: 10.09.2017

Непонятки со спящим режимом. Тинька потребляет в режиме Power-down 130 мкА. 

Как снизить до 0,6 мкА? 

АЦП и компоратор выключенны. 

ADCSRA &= ~(1 << ADEN);
ACSR |= (1 << ACD);

MCUCR |=(1<<SM1);
MCUCR &=~(1<<SM0);
MCUCR |=(1<<SE);

pittyalex
Offline
Зарегистрирован: 09.11.2016

без полного кода сказать что не так, очень сложно. Если вся периферия выключена, внимание надо обратить на клок, и GPIO - правильная подтяжка (вверх/вниз) должна решить проблему.

anarch
Offline
Зарегистрирован: 10.09.2017
#include <avr/io.h>
#include <avr/sleep.h>
int main(void) {
  ACSR |= (1 << ACD);
  ADCSRA &= ~(1 << ADEN);
  
  //  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  //  sleep_enable();
  MCUCR |= (1 << SM1); // power-down mode
  MCUCR &= ~(1 << SM0); // power-down mode
  MCUCR |= (1 << SE);

  while (1) {

    //    sleep_cpu();
    asm("sleep");
  }

  return 0;
}

 

pittyalex
Offline
Зарегистрирован: 09.11.2016

Почитайте раздел 7.2 даташите. Там все написано. Скорее всего броунаут включен, а к нему ещё и референс.

anarch
Offline
Зарегистрирован: 10.09.2017

Спасибо вечером почитаю. Детектор отключен фьюзами.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

anarch, из любопытства залил в тини13а ваш скетч - всё ок, ток 0,4 µA.   Как и чем вы измеряете?

pittyalex
Offline
Зарегистрирован: 09.11.2016

А сама микросхема висит в воздухе? Напряжение питания какое? Может конденсатор по питанию даёт утечки?

Daget
Offline
Зарегистрирован: 31.05.2017

Здравствуйте.

Не получается отписаться от уведомлений о новых сообщениях.
Перехожу по ссылке из письма, появляеться сообщение "Уведомления о новых комментариях к этому материалу для вас отключены. Спасибо."
Но уведомления продолжают поступать.
Как написать админам?
anarch
Offline
Зарегистрирован: 10.09.2017

dimax пишет:

anarch, из любопытства залил в тини13а ваш скетч - всё ок, ток 0,4 µA.   Как и чем вы измеряете?

Мультиметр, сейчас прицепил головку на 100 uA. 

Микросхема висит в воздухе на макетке питание от 1.8 до 5 вольт.

Буду пробовать от батарейки запитать. Чудеса какие-то :(

Если честно не знаю куда уже копать. 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

anarch, (1) мультиметр должен быть с разрешением как минимум 0,1 µA   (3) никаких конденсаторов на МК не должно висеть, ничего кроме питания не должно быть подключено. (2) нельзя просто так включать последовательно мультиметр. для измерения микроампер есть определённые  способы. Самый простой - включить в разрыв цепи питания мультиметр, и паралельно  ему выключатель. Стартовать можно с разомкнутым выключателем в режиме миллиампер на мультиметре. Измерить ток неспящего. (в скетч потребуется паузу секунд на 5 вставить). Далее замкнуть выключатель, переключить на микроамперы. Разомкнуть выключатель, измерить микроамперы.

anarch
Offline
Зарегистрирован: 10.09.2017

Все встало на свои места. Спасибо!

А каким образом можно измерить ток с включенным сторожевым таймером?

pittyalex
Offline
Зарегистрирован: 09.11.2016

Так поделитесь секретом, что вы сделали, чтобы потом другие могли повторить ваш опыт. Внесите вклад в сообщество.

anarch
Offline
Зарегистрирован: 10.09.2017

Измерял не правильно! Померил как описал dimax и все получилось на микроамперметре стрелка не шевелиться. 

 

sim31
Offline
Зарегистрирован: 26.07.2017

Измерял мультиметром. Правда на микроконтроллере висит конденсатор в 10 uF, после снижения тока потребления показания некоторое время устанавливаются. И ток потребления 150 uA так как режим Sleep а не Powerdown, нужно быстрое пробуждение.

pittyalex
Offline
Зарегистрирован: 09.11.2016

Если период сторожевики больше секунды, то, наверное, таким же способом. Если меньше - с помощью шунта и осциллографа. Осциллограф должен быть с высокоомный входом. Резистор на два порядка меньше входного сопротивления осциллографа. Чувствительность должна быть достаточна, чтобы измерение попадало между первой и третьей третями диапазона. Если не выполняется, взять резистор побольше, но тогда нужно с помощью мультиметр откалибровать.
Ну и самый простой способ: если надо среднее значение, то просто измерить утечку фильтра по питанию, затем измерить потребление МК и вычесть одно из другого.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Делаю термометр на тини, хотел использовать динамическую индикацию. Проблема в том, что цикл начинается с небольшой задержкой, из-за этого наблюдается ощутимое мерцание. Как можно оптимизировать loop()?

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

Уверены, что дело именно в  loop(), а не в медленной digitalWrite() ? Скетч бы не помешал. А вообще, для быстродействия нужно забыть за Arduino IDE и писать в Atmel Studio. И работать с портами напрямую через регистры.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Jeka_M пишет:

Уверены, что дело именно в  loop(), а не в медленной digitalWrite() ? Скетч бы не помешал. А вообще, для быстродействия нужно забыть за Arduino IDE и писать в Atmel Studio. И работать с портами напрямую через регистры.

Вот скетч

#include <math.h>
#include <avr/io.h>
#include <util/delay.h>
#define latchPin 2
#define clockPin 1
#define dataPin 0
/* Определяем куда подключен датчик */
#define THERM_PORT PORTB
#define THERM_DDR DDRB
#define THERM_PIN PINB
#define THERM_DQ PB4
/* Макросы для "дергания ноги" и изменения режима ввода/вывода */
#define THERM_INPUT_MODE() THERM_DDR&=~(1<<THERM_DQ)
#define THERM_OUTPUT_MODE() THERM_DDR|=(1<<THERM_DQ)
#define THERM_LOW() THERM_PORT&=~(1<<THERM_DQ)
#define THERM_HIGH() THERM_PORT|=(1<<THERM_DQ)
// команды управления датчиком
#define THERM_CMD_CONVERTTEMP 0x44
#define THERM_CMD_RSCRATCHPAD 0xbe
#define THERM_CMD_WSCRATCHPAD 0x4e
#define THERM_CMD_CPYSCRATCHPAD 0x48
#define THERM_CMD_RECEEPROM 0xb8
#define THERM_CMD_RPWRSUPPLY 0xb4
#define THERM_CMD_SEARCHROM 0xf0
#define THERM_CMD_READROM 0x33
#define THERM_CMD_MATCHROM 0x55
#define THERM_CMD_SKIPROM 0xcc
#define THERM_CMD_ALARMSEARCH 0xec

byte dataArray[10] = {
  0b11111100, 0b01100000,
  0b11011010, 0b11110010,
  0b01100110, 0b10110110,
  0b10111110, 0b11100000,
  0b11111110, 0b11100110,
};
byte dataArray1[10] = {
  0b11111101, 0b01100001,
  0b11011011, 0b11110011,
  0b01100111, 0b10110111,
  0b10111111, 0b11100001,
  0b11111111, 0b11100111,
};

// сброс датчика
uint8_t therm_reset() {
  uint8_t i;
  // опускаем ногу вниз на 480uS
  THERM_LOW();
  THERM_OUTPUT_MODE();
  _delay_us(480);             // замените функцию задержки на свою
  // поднимаем линию на 60uS
  THERM_INPUT_MODE();
  _delay_us(60);
  // получаем значение на линии в период 480uS
  i = (THERM_PIN & (1 << THERM_DQ));
  _delay_us(420);
  // возвращаем значение (0=OK, 1=датчик не найден)
  return i;
}

// функция отправки бита
void therm_write_bit(uint8_t bit) {
  // опускаем на 1uS
  THERM_LOW();
  THERM_OUTPUT_MODE();
  _delay_us(1);
  // если хотим отправить 1, поднимаем линию (если нет, оставляем как есть)
  if (bit) THERM_INPUT_MODE();
  // ждем 60uS и поднимаем линию
  _delay_us(60);
  THERM_INPUT_MODE();
}

// чтение бита
uint8_t therm_read_bit(void) {
  uint8_t bit = 0;
  // опускаем на 1uS
  THERM_LOW();
  THERM_OUTPUT_MODE();
  _delay_us(1);
  // поднимаем на 14uS
  THERM_INPUT_MODE();
  _delay_us(14);
  // читаем состояние
  if (THERM_PIN & (1 << THERM_DQ)) bit = 1;
  // ждем 45 мкс и возвращаем значение
  _delay_us(45);
  return bit;
}

// читаем байт
uint8_t therm_read_byte(void) {
  uint8_t i = 8, n = 0;
  while (i--) {
    // сдвигаем в право на 1 и сохраняем следующее значение
    n >>= 1;
    n |= (therm_read_bit() << 7);
  }
  return n;
}

// отправляем байт
void therm_write_byte(uint8_t byte) {
  uint8_t i = 8;
  while (i--) {
    // отправляем бит и сдвигаем вправо на 1
    therm_write_bit(byte & 1);
    byte >>= 1;
  }
}

void setup() {
  DDRB = 0b00001111;
}

void loop() {
  uint8_t temperature[2];
  int8_t digit;

  therm_reset();
  therm_write_byte(THERM_CMD_SKIPROM);
  therm_write_byte(THERM_CMD_CONVERTTEMP);
  while (!therm_read_bit());
  therm_reset();
  therm_write_byte(THERM_CMD_SKIPROM);
  therm_write_byte(THERM_CMD_RSCRATCHPAD);

  temperature[0] = therm_read_byte();
  temperature[1] = therm_read_byte();
  therm_reset();

  digit = temperature[0] >> 4;
  digit |= (temperature[1] & 0x7) << 4;

  int8_t perv = digit / 10;
  int8_t posl = digit % 10;

  PORTB = 0b00001000;
  shiftOut(dataPin, clockPin, LSBFIRST, dataArray[perv]);
  PORTB = 0b00000100;
  _delay_ms(6);
  digitalWrite(2, 0);
  shiftOut(dataPin, clockPin, LSBFIRST, dataArray1[posl]);
  digitalWrite(2, 1);
  //_delay_ms(1);
}

Может я чего-то конечно не понимаю в динамической индикации и делаю что-то не так

sim31
Offline
Зарегистрирован: 26.07.2017

>>> для быстродействия нужно забыть за Arduino IDE

В Ардуине есть все те же команды для прямого управления портами.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

sim31 пишет:

>>> для быстродействия нужно забыть за Arduino IDE

В Ардуине есть все те же команды для прямого управления портами.

почему тогда такие тормоза. Просто все тайминги опроса ds18b20 с запасом где-то около 2мс

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

В строке 124 вы ждете готовности термометра. Время измерения у него 750 мс. Делайте выводы.... А то тормоза сразу! Читайте темп. раз в сек. И обнлвляйтесь.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

wdrakula пишет:
В строке 124 вы ждете готовности термометра. Время измерения у него 750 мс. Делайте выводы.... А то тормоза сразу! Читайте темп. раз в сек. И обнлвляйтесь.

Спасибо большое, заработало как надо!

sim31
Offline
Зарегистрирован: 26.07.2017

Apocalyps пишет:

такие тормоза. Просто все тайминги опроса ds18b20 с запасом где-то около 2мс

Вам нужны такие команды, прямая запись в порт, выполняется за 1-2 такта кварца

PORTB = PORTB | 0b00101100;
PORTB = PORTB & 0b11101111;

Вместо команды DigitalWrite()

Подробнее по ссылке и смотрите распиновку микроконтроллера
https://hubstub.ru/programming/64-kak-ustanovit-sbrosit-proverit-nuzhnyy-bit-ili-bitovyye-operatsii.html