1

Тема: attiny13

Основная статья - http://rcl-radio.ru/?p=98729

ЧАСЫ DS1307 + TM1637

http://forum.rcl-radio.ru/uploads/images/2021/04/c0a2d40655bbe6f337b25c737e2cae61.jpg

http://forum.rcl-radio.ru/uploads/images/2021/04/2dd754d39eb1fdb5401086fc5a2151eb.jpg


#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 0 // PB0
#define DIO 1 // PB1


void setup() {
  //set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
}
 

void loop() {
  byte min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  byte hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
  
   print_time(hour *100 + min,0,7);
   delay(500);
   print_time(hour *100 + min,2,7);
   delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0 = t / 1000;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      if(pd_t==2){data1 = data1+0b10000000;}
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

bool i2c_read_bit() {
    bool i2c_bit = 1;        
    DDRB &= ~(1 << SDA);            
    delayMicroseconds(10); 
    DDRB &= ~(1 << SCL);                
    if((PINB >> SDA) & 1) i2c_bit=0;                            
    delayMicroseconds(10);  
    DDRB |= (1 << SCL);              
    return i2c_bit;  
}
 
byte i2c_write_byte(byte data){
    for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}    
    return i2c_read_bit(); 
}
 
byte i2c_read_byte(byte a){
    byte i, data=0;                
    for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}        
    i2c_write_bit(a);return data;  
}
 
void i2c_write_bit(byte b){
    delayMicroseconds(5);
    if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
    delayMicroseconds(5);
    DDRB &= ~(1 << SCL);       
    delayMicroseconds(10);
    DDRB |= (1 << SCL);
}
 
void i2c_start(){
     delayMicroseconds(10);  
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL); 
     delayMicroseconds(10); 
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     delayMicroseconds(10); 
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);   
     delayMicroseconds(10);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);            
     delayMicroseconds(10);
     DDRB &= ~(1 << SCL);               
     delayMicroseconds(10); 
     DDRB &= ~(1 << SDA);             
}
 
byte ds_read(byte reg){
     byte data = 0;
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte(0b11010001); 
     data = i2c_read_byte(0);
     i2c_stop();
     return data;
  }
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
 
void set_time(byte hours ,byte minute, byte second){
    ds_write(0x00,(second/10<<4)+second%10);
    ds_write(0x01,(minute/10<<4)+minute%10);
    ds_write(0x02,(hours/10<<4)+hours%10);

  }

Скетч использует 938 байт (91%) памяти устройства. Всего доступно 1024 байт.
Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 64 байт для локальных переменных. Максимум: 64 байт.

2

Re: attiny13

ВОЛЬТМЕТР 5В

http://forum.rcl-radio.ru/uploads/images/2021/04/31a51c78e7f034e8a3c27c4b4c7cd16c.jpg


#define CLK 0 // PB0
#define DIO 1 // PB1
unsigned int u;

void setup() {
   ADMUX |= (1<<MUX1);// ADC2 (PB4) input
   ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (1<<ADIF);
   ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);// Division Factor 128
}
 

void loop() {
  while((ADCSRA & (1 << ADIF)) == 0);
   u = (ADCL|ADCH << 8);
   print_time(u*51/102,2,7);// 51=VCC 5.1V | 102 = 1023
   delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0 = 10;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

Скетч использует 592 байт (57%) памяти устройства. Всего доступно 1024 байт.
Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 64 байт для локальных переменных. Максимум: 64 байт.

ТОЖЕ САМОЕ

#define CLK 0 // PB0
#define DIO 1 // PB1
unsigned int u;

void setup() {
  
}
 

void loop() {
   u = analogRead(A2);
   print_time(u*51/102,2,7);// 51=VCC 5.1V | 102 = 1023
   delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0 = 10;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

Скетч использует 588 байт (57%) памяти устройства. Всего доступно 1024 байт.
Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 64 байт для локальных переменных. Максимум: 64 байт.

3

Re: attiny13

ИЗМЕРЕНИЕ НАПРЯЖЕНИЕ (ВНУТРЕННИЙ ОПОРНЫЙ ИСТОЧНИК 1.1 В)

#define CLK 0 // PB0
#define DIO 1 // PB1
unsigned int u;

void setup() {
   ADMUX |= (1<<MUX1) | (1<<REFS0);// Internal Voltage Reference ADC2 (PB4) input
   ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (1<<ADIF);
   ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);// Division Factor 128
}
 

void loop() {
  while((ADCSRA & (1 << ADIF)) == 0);
   u = (ADCL|ADCH << 8);
   print_time(u*11/102,2,7);// 11=VCC 1.1V | 102 = 1023
   delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0 = 10;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

4

Re: attiny13

ЦИФРОВОЙ ТЕРМОМЕТР DS18B20 + TM1637

http://forum.rcl-radio.ru/uploads/images/2021/04/96a82077df82db68dfdca4efef794b0d.jpg

#define CLK 0 // PB0
#define DIO 1 // PB1
#define OUT 4 // PB4


void setup() {

}
 

void loop() {
  if(read_temp()<0){print_time(abs(read_temp()),1,7,1);}
  else{print_time(read_temp(),1,7,0);}
  delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br,bool mn){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0;
        if(mn==1){data0 = 11;}
        else{data0 = 10;}
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

/////////////////////

// reset
uint8_t therm_reset(){
    uint8_t i;
    PORTB &= ~(1 << OUT);
    DDRB |= (1 << OUT);
    delayMicroseconds(480);  
    DDRB &= ~(1 << OUT);
    delayMicroseconds(60);
    i=((PINB >> OUT) & 1);
    delayMicroseconds(420);
    return i;
}
// write bit
void therm_write_bit(uint8_t bit){
    PORTB &= ~(1 << OUT);
    DDRB |= (1 << OUT);
    delayMicroseconds(1);
    if(bit) DDRB &= ~(1 << OUT);
    delayMicroseconds(60);
    DDRB &= ~(1 << OUT);
}
// read bit
uint8_t therm_read_bit(void){
    uint8_t bit=0;
    PORTB &= ~(1 << OUT);
    DDRB |= (1 << OUT);
    delayMicroseconds(1);
    DDRB &= ~(1 << OUT);
    delayMicroseconds(14);
    if(PINB & (1 << OUT)) bit=1;
    delayMicroseconds(45);
    return bit;
}
 
// read byte
uint8_t therm_read_byte(void){
    uint8_t i=8, n=0;
    while(i--){n>>=1;n|=(therm_read_bit()<<7);}
    return n;
}
 
// write byte
void therm_write_byte(uint8_t byte){
    uint8_t i=8;
    while(i--){therm_write_bit(byte&1);byte >>= 1;
    }
}
// read temp
int read_temp(){
    uint8_t temperature[2];
    float temper;
    therm_reset();
    therm_write_byte(0xCC);
    therm_write_byte(0x44);
    while(!therm_read_bit());
    therm_reset();
    therm_write_byte(0xCC);
    therm_write_byte(0xBE);
    temperature[0]=therm_read_byte();
    temperature[1]=therm_read_byte();
    therm_reset();
    temper = (temperature[1] << 8 | temperature[0])*10/16;
    return (int)temper;
}

Скетч использует 828 байт (80%) памяти устройства. Всего доступно 1024 байт.
Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 64 байт для локальных переменных. Максимум: 64 байт.

5

Re: attiny13

Добрый день !
liman324,не могли бы Вы выложить схему, по которой собирали ЧАСЫ DS1307 + TM1637.

6

Re: attiny13

http://forum.rcl-radio.ru/uploads/images/2022/10/a4d54af24d871704843881912b6294ba.png

7 (2022-10-29 08:34:35 отредактировано korsar)

Re: attiny13

liman324, в скетче соответствие портов противоположное.

#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 0 // PB0
#define DIO 1 // PB1


void setup() {
  //set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
}

Где ошибка?

P.S. В данном проекте не предусмотрена настройка времен  с кнопок.
Возможно ли это реализовать ?

8

Re: attiny13

Я поправил схему.

P.S. В данном проекте не предусмотрена настройка времен  с кнопок.
Возможно ли это реализовать ?

Свободен PB2 это аналоговый вход ADC1, можно повесить делитель напряжения и подключить две кнопки - часы и минуты.

http://forum.rcl-radio.ru/uploads/images/2022/10/60b5d6496dd2eed1478105c1d5c830a5.png

9

Re: attiny13

Ok!
Если честно, в написании скетчей я профан!
Не подскажите, какие нужны изменения в программе, чтоб заработали кнопки?

10

Re: attiny13

Не получается запихнуть код кнопок, места не хватает.

11 (2023-02-28 16:35:13 отредактировано klause)

Re: attiny13

korsar пишет:

Ok!
Если честно, в написании скетчей я профан!
Не подскажите, какие нужны изменения в программе, чтоб заработали кнопки?

На мой взгляд можно подключить одну кнопку. Лучше поменять  DS1307 на ds3231.
я попробывал так сделать. вот кусочек кода.
#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 0 // PB0
#define DIO 1 // PB1
#define BUT 2 // PB2
void setup() {
// set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
  PORTB |= (1 << BUT);

}


void loop() {
  byte min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  byte hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
 
   print_time(hour *100 + min,0,7);
   delay(500);
   print_time(hour *100 + min,2,7);
   delay(500);
   
if(((PINB >> BUT) & 1) == 0){
   set_time(12,0,0);
}

}

Настроить часы в 12.00 или в то время, которое самому удобное,изменив значение.
Скорректировать секунды тоже можно в это же время, если часы "убежали".

12 (2023-11-08 16:42:27 отредактировано klause)

Re: attiny13

Интересно, хватить ли места для кнопок? Немного уменьшил скетч.

#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 1 // PB0
#define DIO 0 // PB1
#define BUT 2 // PB2
byte min;
byte hour;
byte tochka;// разделительная точка часов и минут

void setup() {
  //set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
   
}
 

void loop() {
  min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
   tochka=0x80;
   print_time();
   delay(500);
   tochka=0x00;
   print_time();
   delay(500);
       
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(){
        tm_start();tm_dec(0b10001000 + 7);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
     int  data0 = (hour / 10) % 10;
     int  data1 = hour % 10;
     int  data2 = (min / 10) % 10;
     int  data3 = min % 10;
     if(data0 == 0)data0=10;//гашение нуля.
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
     
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1+tochka);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

bool i2c_read_bit() {
    bool i2c_bit = 1;        
    DDRB &= ~(1 << SDA);            
    delayMicroseconds(10); 
    DDRB &= ~(1 << SCL);                
    if((PINB >> SDA) & 1) i2c_bit=0;                            
    delayMicroseconds(10);  
    DDRB |= (1 << SCL);              
    return i2c_bit;  
}
 
byte i2c_write_byte(byte data){
    for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}    
    return i2c_read_bit(); 
}
 
byte i2c_read_byte(byte a){
    byte i, data=0;                
    for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}        
    i2c_write_bit(a);return data;  
}
 
void i2c_write_bit(byte b){
    delayMicroseconds(5);
    if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
    delayMicroseconds(5);
    DDRB &= ~(1 << SCL);       
    delayMicroseconds(10);
    DDRB |= (1 << SCL);
}
 
void i2c_start(){
     delayMicroseconds(10);  
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL); 
     delayMicroseconds(10); 
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     delayMicroseconds(10); 
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);   
     delayMicroseconds(10);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);            
     delayMicroseconds(10);
     DDRB &= ~(1 << SCL);               
     delayMicroseconds(10); 
     DDRB &= ~(1 << SDA);             
}
 
byte ds_read(byte reg){
     byte data = 0;
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte(0b11010001); 
     data = i2c_read_byte(0);
     i2c_stop();
     return data;
  }
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
 
void set_time(byte hours ,byte minute, byte second){
    ds_write(0x00,(second/10<<4)+second%10);
    ds_write(0x01,(minute/10<<4)+minute%10);
    ds_write(0x02,(hours/10<<4)+hours%10);

  }

У меня скетч занимает 82%. Внимание. MicroCore v.2.2.1. В версии 2.3.0 скетч не вмещается!!!.

13

Re: attiny13

Кнопку надо переделать
Примерно так
http://forum.rcl-radio.ru/uploads/images/2023/10/19c59b935ba22fc15796b706fad2d2a5.png

Сопротивления надо высчитывать

Коррекция часов условие > значение ADC больше 300 но меньше 600
Коррекция минут условие > значение ADC больше 600
При условии, что 5 В на входе равно 1023

В железе не тестировал

#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 1 // PB0
#define DIO 0 // PB1

byte min;
byte hour;
byte tochka;// разделительная точка часов и минут
int u;

void setup() {
  //set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
    ADCSRA = 0b10000100; 
}
 

void loop() {
  ADMUX = 0b00000001; // input A1 (PB2)
  do{ADCSRA |= (1 << ADSC);}
   while ((ADCSRA & (1 << ADIF)) == 0);
    u = (ADCL|ADCH << 8);

  if(u>300 || u < 600){set_time(hour++,min,0);}
  if(u>600){set_time(hour,min++,0);}  
  
  min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
 
   tochka=0x80;
   print_time();
   delay(500);
   tochka=0x00;
   print_time();
   delay(500);
       
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(){
        tm_start();tm_dec(0b10001000 + 7);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
     int  data0 = (hour / 10) % 10;
     int  data1 = hour % 10;
     int  data2 = (min / 10) % 10;
     int  data3 = min % 10;
     if(data0 == 0)data0=10;//гашение нуля.
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
     
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1+tochka);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

bool i2c_read_bit() {
    bool i2c_bit = 1;        
    DDRB &= ~(1 << SDA);            
    delayMicroseconds(10); 
    DDRB &= ~(1 << SCL);                
    if((PINB >> SDA) & 1) i2c_bit=0;                            
    delayMicroseconds(10);  
    DDRB |= (1 << SCL);              
    return i2c_bit;  
}
 
byte i2c_write_byte(byte data){
    for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}    
    return i2c_read_bit(); 
}
 
byte i2c_read_byte(byte a){
    byte i, data=0;                
    for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}        
    i2c_write_bit(a);return data;  
}
 
void i2c_write_bit(byte b){
    delayMicroseconds(5);
    if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
    delayMicroseconds(5);
    DDRB &= ~(1 << SCL);       
    delayMicroseconds(10);
    DDRB |= (1 << SCL);
}
 
void i2c_start(){
     delayMicroseconds(10);  
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL); 
     delayMicroseconds(10); 
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     delayMicroseconds(10); 
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);   
     delayMicroseconds(10);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);            
     delayMicroseconds(10);
     DDRB &= ~(1 << SCL);               
     delayMicroseconds(10); 
     DDRB &= ~(1 << SDA);             
}
 
byte ds_read(byte reg){
     byte data = 0;
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte(0b11010001); 
     data = i2c_read_byte(0);
     i2c_stop();
     return data;
  }
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
 
void set_time(byte hours ,byte minute, byte second){
    ds_write(0x00,(second/10<<4)+second%10);
    ds_write(0x01,(minute/10<<4)+minute%10);
    ds_write(0x02,(hours/10<<4)+hours%10);
  }

14 (2023-10-24 20:34:32 отредактировано Karl2233)

Re: attiny13

Коррекция часов условие > значение ADC больше 300 но меньше 600
Коррекция минут условие > значение ADC больше 600
При условии, что 5 В на входе равно 1023

>600 = 4,7к...5,6к
300...<600 = 8,2к

15 (2023-11-27 15:03:10 отредактировано klause)

Re: attiny13

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

  #define SDA 3 // PB3
 #define SCL 4 // PB4
  #define TM1637_DIO_HIGH() (PORTB |= _BV(TM1637_DIO_PIN))
  #define TM1637_DIO_LOW() (PORTB &= ~_BV(TM1637_DIO_PIN))
  #define TM1637_DIO_OUTPUT() (DDRB |= _BV(TM1637_DIO_PIN))
  #define TM1637_DIO_INPUT() (DDRB &= ~_BV(TM1637_DIO_PIN))
  #define TM1637_DIO_READ() (((PINB & _BV(TM1637_DIO_PIN)) > 0) ? 1 : 0)
  #define TM1637_CLK_HIGH() (PORTB |= _BV(TM1637_CLK_PIN))
  #define TM1637_CLK_LOW() (PORTB &= ~_BV(TM1637_CLK_PIN))  
  #define TM1637_DIO_PIN  PB0
  #define TM1637_CLK_PIN  PB1 
  byte _config = 0x08 | 7;
  byte _segments = 0xff;
 byte min;
 byte hour;
// byte second;
 int u;
  PROGMEM const byte _digit2segments[] =
  {
  0x3F, // 0
  0x06, // 1
  0x5B, // 2
  0x4F, // 3
  0x66, // 4
  0x6D, // 5
  0x7D, // 6
  0x07, // 7
  0x7F, // 8
  0x6F // 9
  };
  
  void setup() { 
 
} 
  void loop() {
 u = analogRead(A1);
 
 if (u>690&&u<700){ //подгон минут
    min++;
    if(min>=60)min=0;
    ds_write(0x01,(min/10<<4)+min%10);
     }
           
  if(u>605&&u<615){ // подгон часов
    hour++;
    if(hour>23)hour=0;
    ds_write(0x02,(hour/10<<4)+hour%10);    
    }
    
  //  if(u>565&&u<575){ // обнуление секунд
   //  second=0;
  // ds_write(0x00,(second/10<<4)+second%10); }
       
  min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
  TM1637_init(1/*включить*/, 7/*яркость*/);
  TM1637_display_digit(3, min %10);
  TM1637_display_digit(2, min /10);
  TM1637_display_digit(1, hour %10);
  if(hour<10)TM1637_display_segments(0,0);// гашение нуля
  else TM1637_display_digit(0, hour/10);
  TM1637_display_colon(1);
    //delay(200);
  TM1637_display_colon(0);
    //delay(200);
  
  }

  bool i2c_read_bit() {
    bool i2c_bit = 1;        
    DDRB &= ~(1 << SDA);            
    delayMicroseconds(10); 
    DDRB &= ~(1 << SCL);                
    if((PINB >> SDA) & 1) i2c_bit=0;                            
    delayMicroseconds(10);  
    DDRB |= (1 << SCL);              
    return i2c_bit;  
}
 
byte i2c_write_byte(byte data){
    for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}    
    return i2c_read_bit(); 
}
 
byte i2c_read_byte(byte a){
    byte i, data=0;                
    for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}        
    i2c_write_bit(a);return data;  
}
 
void i2c_write_bit(byte b){
    delayMicroseconds(5);
    if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
    delayMicroseconds(5);
    DDRB &= ~(1 << SCL);       
    delayMicroseconds(10);
    DDRB |= (1 << SCL);
}
 
void i2c_start(){
     delayMicroseconds(10);  
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL); 
     delayMicroseconds(10); 
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     delayMicroseconds(10); 
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);   
     delayMicroseconds(10);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);            
     delayMicroseconds(10);
     DDRB &= ~(1 << SCL);               
     delayMicroseconds(10); 
     DDRB &= ~(1 << SDA);             
}
 
byte ds_read(byte reg){
     byte data = 0;
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte(0b11010001); 
     data = i2c_read_byte(0);
     i2c_stop();
     return data;
  }
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
/* 
void set_time(byte hours ,byte minute, byte second){
    ds_write(0x00,(second/10<<4)+second%10);
    ds_write(0x01,(minute/10<<4)+minute%10);
    ds_write(0x02,(hours/10<<4)+hours%10);
 }
 */
// библиотека tm1637
 void delay1sec(void)
   {    
  asm volatile (
    "    ldi  r18, 6"  "\n"
    "    ldi  r19, 19"  "\n"
    "    ldi  r20, 174" "\n"
    "1:  dec  r20"  "\n"
    "    brne 1b" "\n"
    "    dec  r19"  "\n"
    "    brne 1b" "\n"
    "    dec  r18"  "\n"
    "    brne 1b" "\n"
    "    rjmp 1f" "\n"
    "1:"  "\n"
       );
}
  // Инициализация дисплея
  void TM1637_init(byte enable, byte brightness)
  { 
  DDRB |= (_BV(TM1637_DIO_PIN)|_BV(TM1637_CLK_PIN));
  PORTB &= ~(_BV(TM1637_DIO_PIN)|_BV(TM1637_CLK_PIN));
  TM1637_send_config(enable, brightness);
  }
  // включение дисплея
  void TM1637_enable(byte value) {
    TM1637_send_config(value, _config & 7);
  }
  // яркость от 0 до 7
  void TM1637_set_brightness(byte value){
  TM1637_send_config(_config & 0x08, value & 7);
  }
  // По сегментамБ например,'H', segments=0b01110110
  void TM1637_display_segments(byte position,byte segments){  
  TM1637_send_command(0x40 | 0x04);
  TM1637_start();
  TM1637_write_byte(0xC0 | (position & 3));
  TM1637_write_byte(segments);
  TM1637_stop();
  }
  // По цифрам от 0 до 9
  void TM1637_display_digit(byte position, byte digit){
  uint8_t segments = (digit < 10 ? pgm_read_byte_near((byte *)&_digit2segments + digit) : 0x00);
   if (position == 0x01) {
  segments = segments | (_segments & 0x80);
  _segments = segments;
  }
   TM1637_display_segments(position, segments);
  }
  // Разделительные точки  1 - on, 0 - off
  void TM1637_display_colon(byte value){
  if (value) {
  _segments |= 0x80;
  } else {
  _segments &= ~0x80;
  }
  TM1637_display_segments(0x01, _segments);
  }
 
  void TM1637_send_config(byte enable,byte brightness)
  { 
  _config = (enable ? 0x08 : 0x00) |
  (brightness > 7 ? 7 : brightness); 
  TM1637_send_command(0x80 | _config);
  }
  
  void TM1637_send_command(byte value){
  TM1637_start();
  TM1637_write_byte(value);
  TM1637_stop();
  }
  
  void TM1637_start() { 
  TM1637_DIO_HIGH();
  TM1637_CLK_HIGH();
   // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_DIO_LOW();
  }
  
  void TM1637_stop() { 
  TM1637_CLK_LOW();
     // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_DIO_LOW();
     // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_CLK_HIGH();
    // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm" "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_DIO_HIGH();
  }
  
  byte TM1637_write_byte(byte value) {
  byte i, ack;  
  for (i = 0; i < 8; ++i, value >>= 1) {
  TM1637_CLK_LOW();
     // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  if (value & 0x01) {
  TM1637_DIO_HIGH();
  } else {
  TM1637_DIO_LOW();
  } 
  TM1637_CLK_HIGH(); 
     // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  }
  
  TM1637_CLK_LOW();
  TM1637_DIO_INPUT();
  TM1637_DIO_HIGH(); 
   // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  ack = TM1637_DIO_READ();
  if (ack) {
  TM1637_DIO_OUTPUT();
  TM1637_DIO_LOW();
  }
    // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm" "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_CLK_HIGH();
    // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm" "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_CLK_LOW();
   // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_DIO_OUTPUT();
  return ack;
  } 

http://forum.rcl-radio.ru/uploads/images/2023/11/a16b53c03b3a21c8db62d47d822c9bee.bmp
Очень медленно корректируется время. Лучше взять кнопки с фиксацией в этом варианте.
2 вариант.
http://forum.rcl-radio.ru/uploads/images/2023/11/5f922c17974d89ac6143fd964aaf52db.bmp
3 вариант. В железе не опробовано. Pin reset установлен как пин входа-выхода.
http://forum.rcl-radio.ru/uploads/images/2023/11/079b812c402ccfaf7dff6ef8e37f06f8.bmp
Файлы + исходник Attiny13 TM1637 от польского товарища.
sketchclock.rar sketchclock2.rar sketchclock3.rar attinytm1637librarymaster.rar

16 (2023-11-13 15:53:10 отредактировано klause)

Re: attiny13

термометр dht11&tm1637. Код опроса датчика был взят из и-нета.

#define CLK 1 // PB0
#define DIO 0 // PB1
#define DHT PB4 // +подключить внешнюю подтяжку.
byte _hum, _temp;// переменные для влажности и температуры
void setup() {  

}

void loop() {
dht_read(&_hum, &_temp);// опроса датчика
 delay(3000);
  print_time(_hum,0,7,0);
  delay(3000);
  print_time(_temp,0,7,1);
 
}

// общая функция опроса датчика
  byte dht_read(byte *hum, byte* temp) {
  byte data[5];// массив под данные датчика
  byte error=dht_start();// стартуем и получаем код ошибки в переменную

  if (error) return error; // если есть ошибки выходим с кодом ошибки
  
  // получаем 5 байт от датчика
  for (byte i=0; i<5; i++)
  {
    data[i]=dht_byte();
  }
  
  if (data[0]+data[1]+data[2]+data[3]!=data[4]) return 1; // если контрольная сумма не сошлась вернем ошибку 
  
  *hum=data[0];// пишем данные влажности 
  *temp=data[2];// пишем данные температуры 
  return 0;// вернем 0 - ошибок нет.
}
// функция передачи условия "старт" на линию и проверка ответов от датчика.
 byte  dht_start(){
  DDRB|=(1<<DHT);// притянули линию к земле - 0
  _delay_ms(20);// пауза 20 мс 
  DDRB&=~(1<<DHT);// отпустили линию - 1
  _delay_us(40);// ждем 40 мкс чтобы попасть в середину низкого сигнала
  if (PINB&(1<<DHT)) return 1; // если на линии 1 ошибка - "датчик не ответил"
  _delay_us(80); // ждем 80 мкс чтобы попасть в середину высокого сигнала
  if (!(PINB&(1<<DHT))) return 1; // если на линии 0 ошибка - "датчик не готов "
  while(PINB&(1<<DHT));// ждем пока датчик не притянет линию к земле.
  return 0;// ошибок нет
}
// получение байта от датчика
byte dht_byte(){
  byte i=8, byte=0;// переменная для цикла и под байт
  while(i--){
    while(!(PINB&(1<<DHT)));// ждем пока линия не поднимится в 1
    _delay_us(40);// отступаем 40 мкс
    if (PINB&(1<<DHT)) {// если на линии 1 = приняли 1
      byte|=(1<<i);// поднимаем итый бит в 1
      while(PINB&(1<<DHT));// ждем пока линия упадет в 0
    }
  }
  return byte;// возвращаем полученный байт
}
void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br, bool mn){
        tm_start();tm_dec(0b10001000 + br); tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
     int data0;
        if(mn == 1){data0 = 11;}else{data0 = 12;}
        int data1 = 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01111000;break;     // t
        case 12: data = 0b01110110;break;     // H
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

Интересно,что скетч в версии 2.3.0. занимает 97%. В версии 2.2.1 занимает 73%.
Похожий проект. Частота чипа 1.2Мгц.attiny13dht12mhz.rar

17

Re: attiny13

Термометр dht11 + max7219.

#define MAX7219_DIN PB2 // нога1
#define MAX7219_CS  PB1 // нога12
#define MAX7219_CLK PB0 // нога13
#include <SimpleDHT.h>
int pinDHT11 = PB4; // датчик
SimpleDHT11 dh11;
byte DisplayNumtoSeg[] = {126,48, 109, 121, 51, 91, 95, 112, 127, 123};
void setup() {
digitalWrite(MAX7219_CS, HIGH);
 pinMode(MAX7219_DIN, OUTPUT);
 pinMode(MAX7219_CS, OUTPUT);
 pinMode(MAX7219_CLK, OUTPUT);
  output(0x0f, 0x00); //тест выкл
  output(0x0c, 0x01); // спящий режим
  output(0x0b, 0x04); // количествов знакомест
  output(0x0a, 0x0f); //яркость
  output(0x09, 0x00); // включен режим декодирования
  
}

void loop() {
 byte temperature = 0;
  byte humidity = 0;
 if (dh11.read(pinDHT11, &temperature, &humidity, NULL)) {   
    return; }  
  byte data0 = DisplayNumtoSeg[temperature / 10 % 10];
  byte data1= DisplayNumtoSeg[temperature % 10];
  byte data2 = DisplayNumtoSeg[humidity / 10 % 10];
  byte data3 = DisplayNumtoSeg[humidity % 10];
  output(0x01,data0);
  output(0x02,data1);
  output(0x03,0b01100011);
  output(0x04,0b01001110);
  delay(3000);
  output(0x01,data2);
  output(0x02,data3); 
  output(0x03,0b00110111);
  output(0x04,0b00011100);
  delay(3000);
}

 void output(byte address, byte data)
{
 digitalWrite(MAX7219_CS, LOW);
 shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, address);
 shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, data);
 digitalWrite(MAX7219_CS, HIGH);
}
 

simpledht101.rar
Программа декодирования MAX7219
decode7219.rar

18 (2023-12-04 17:40:13 отредактировано klause)

Re: attiny13

Попробывал подсоединить dht22. MAX7219 индикатор самодельный.

#define MAX7219_DIN PB0 // нога1
#define MAX7219_CS  PB1 // нога12
#define MAX7219_CLK PB2 // нога13
#define DHT22_PIN PB4
byte c=0,temperature_hi, temperature_lo, humidity_hi, humidity_lo, dig1,dig2,dig3,dig4,dig5,dig6,temporary, check_sum;
int temperature_result, humidity_result;
byte DisplayNumtoSeg[] = {126,48, 109, 121, 51, 91, 95, 112, 127, 123};
void setup() {
 digitalWrite(MAX7219_CS, HIGH);
 pinMode(MAX7219_DIN, OUTPUT);
 pinMode(MAX7219_CS, OUTPUT);
 pinMode(MAX7219_CLK, OUTPUT);
  output(0x0f, 0x00); //тест выкл
  output(0x0c, 0x01); // спящий режим
  output(0x0b, 0x07); // количествов знакомест
  output(0x0a, 0x0f); //яркость
  output(0x09, 0x00); // включен режим декодирования
  for(byte i=0;i<9;i++){  
  output(i, 0); } 
  for(byte i=0;i<9;i++){  
  output(i, 1);
   delay(500);}
   delay(2000); 
   
}

void loop() {
request();    /* стартовый импульс */
response();
humidity_lo=receive_data(); /* целое число влажности */
humidity_hi=receive_data();  /* дробное число влажности */
temperature_lo=receive_data(); /* целое число температуры */
temperature_hi=receive_data();  /* дробное число температуры */
check_sum=receive_data(); /* контрольная сумма */
humidity_result = (humidity_lo * 256 + humidity_hi );
if(temperature_lo > 127){ //
 temperature_result = (temperature_lo-128)* 256+ temperature_hi;
output(0x01,1);
if((temperature_result / 100)>0){ // если ниже -10 гр
dig1 = DisplayNumtoSeg [temperature_result / 100];  
temporary = temperature_result % 100;   
dig2 = DisplayNumtoSeg[temporary / 10]|128;
dig3 = DisplayNumtoSeg[temporary % 10];
output(0x02,dig1);
output(0x03,dig2);
output(0x04,dig3);}
else{
temporary = temperature_result % 100; // между 0 и -10гр.         
dig2 = DisplayNumtoSeg[temporary / 10]|128;
dig3 = DisplayNumtoSeg[temporary % 10];
output(0x02,dig2);
output(0x03,dig3);
output(0x04,99);}  
dig1 = DisplayNumtoSeg [temperature_result / 100];
temporary = temperature_result % 100;           
dig2 = DisplayNumtoSeg[temporary / 10]|128;
dig3 = DisplayNumtoSeg[temporary % 10];
output(0x02,dig2);
output(0x03,dig3);
output(0x04,99);}  
else{
temperature_result = (temperature_lo * 256 + temperature_hi ); // выше 0          
  if (temperature_result / 100==0)dig1=0;
 else{dig1 = DisplayNumtoSeg [temperature_result / 100];};         
 temporary = temperature_result % 100; 
 dig2 = DisplayNumtoSeg[temporary / 10]|128;
 dig3 = DisplayNumtoSeg[temporary % 10];  
  output(0x01,dig1);
  output(0x02,dig2);
  output(0x03,dig3);
  output(0x04,99);}   
      
dig4 =DisplayNumtoSeg [humidity_result / 100];
temporary = humidity_result % 100; 
dig5 =DisplayNumtoSeg[ temporary / 10]|128;
dig6 =DisplayNumtoSeg[ temporary % 10];  
  output(0x05,dig4);
  output(0x06,dig5);
  output(0x07,dig6);
  output(0x08,55);
  delay(2000);  
}

void output(byte address, byte data)
{
 digitalWrite(MAX7219_CS, LOW);
 shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, address);
 shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, data);
 digitalWrite(MAX7219_CS, HIGH);
}
void request()  {
  
  DDRB |= (1<<DHT22_PIN);
  PORTB &= ~(1<<DHT22_PIN);    /* set to low pin */
  delay(20);            /* wait for 20ms */
  PORTB |= (1<<DHT22_PIN); /* set to high pin */

}

void response() {
  
  DDRB &= ~(1<<DHT22_PIN);
  while(PINB & (1<<DHT22_PIN));
  while((PINB & (1<<DHT22_PIN))==0);
  while(PINB & (1<<DHT22_PIN));
}

uint8_t receive_data() {  
  int q;
  for (q=0; q<8; q++) {
    while((PINB & (1<<DHT22_PIN)) == 0);  /* check received bit 0 or 1 */
    delayMicroseconds(30);
    if(PINB & (1<<DHT22_PIN))/* if high pulse is greater than 30ms */
    c = (c<<1)|(0x01);  /* then its logic HIGH */
    else      /* otherwise its logic LOW */
    c = (c<<1);
    while(PINB & (1<<DHT22_PIN));
  }
  return c;
}
//int get_checksum() {  
//  return humidity_lo + humidity_hi + temperature_lo +  temperature_hi;}

http://forum.rcl-radio.ru/uploads/images/2023/12/3c335ef57b54f2c94a10dbe762f2bbc0.jpg http://forum.rcl-radio.ru/uploads/images/2023/12/ae3bd9c7bea732294b66d9abf376dd91.jpg http://forum.rcl-radio.ru/uploads/images/2023/12/2e52f74463e42b1ea2ca26edab0b131f.jpg http://forum.rcl-radio.ru/uploads/images/2023/12/6e6b225ddcd3a93d5c52f739b5fd20b6.jpg http://forum.rcl-radio.ru/uploads/images/2023/12/d5caef0c53166063931e9f78dc426f1d.jpg

19 (2023-12-02 14:44:45 отредактировано Karl2233)

Re: attiny13

http://forum.rcl-radio.ru/uploads/images/2023/12/da9511c40712b26a467393ec6e3027a8.jpg
Вопрос по устройству на. Attiny13.
Нужен вот такой функционал:
1. Вкл-выкл с кнопки и с пульта(с возможностью прописать кнопку пульта).
2. Режим MUTE с пульта(с возможностью прописать код кнопки).
3. Переключение двух входов с одной кнопки пульта (с возможностью прописать код кнопки).

Схему накидал.

Уважаемый liman324, есть возможность помочь с таким?

20

Re: attiny13

Вот код для ардуино:

bool data[96],st,st1,raz;
uint32_t cod;
byte i1,i2,s;
 
void setup() {
  Serial.begin(9600);
  DDRB &= ~(1 << 0);
   cli(); 
  TCCR1A = 0;   
  TCCR1B = 0;   
  OCR1A = 9000; // 562.5 mks
  TCCR1B |= (1 << WGM12); 
  TCCR1B |= (1 << CS10);  
  TIMSK1 |= (1 << OCIE1A);  
   sei(); 
}
 
void loop() {
if(raz==1){  Serial.println(IR(),HEX);}
delay(200);
}
 
uint32_t IR(){
 delay(150);
 cod=0;i2=0;
 for(int a=0;a<96;a++){
   if(data[a] + data[a+2] == 2){cod += ((uint32_t)0 << 31-i2);i2++;a=a+1;}
   if(data[a] + data[a+2] == 1){cod += ((uint32_t)1 << 31-i2);i2++;a=a+3;}}
 raz=0;
 TCCR1B |= (1 << CS10);OCR1A = 3200;//5000 Hz
 if(cod==1||cod>0x7FFFFFFF){cod=0xFFFFFFFF;}
 return cod;}
 
ISR(TIMER1_COMPA_vect){
     if(((PINB >> 0) & 1)==0&&st==0&&raz==0){st=1;OCR1A = 9000;}
     if(st==1){s++;}
     if(s>20&&((PINB >> 0) & 1)==0){st1=1;}   
     if(st1==1){data[i1]=((PINB >> 0) & 1);i1++;} 
     if(i1>96){i1=0;s=0;st=0;raz=1;st1=0;TCCR1B &= ~(1 << CS10); }
     }

Вывод кода в монитор порта

http://forum.rcl-radio.ru/uploads/images/2023/12/8ad3161ef9c53bc9b8a047be85944266.png

21

Re: attiny13

Но все это не будет работать на attny13, не хватит места, нужно как то уменьшить код, например считывать пакет кода не расшифровывая его.

22 (2023-12-02 16:59:31 отредактировано Karl2233)

Re: attiny13

liman324 пишет:

Но все это не будет работать на attny13, не хватит места, нужно как то уменьшить код, например считывать пакет кода не расшифровывая его.

Ардуину жалко на это.
Правильно ли я понимаю: если считать код кнопок и потом вписать в скетч, тогда возможно этот функционал в Ат13 впихнуть?
Или убрать переключение входов?

23

Re: attiny13

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

http://forum.rcl-radio.ru/uploads/images/2023/12/d303cdee5e7fd4a28b141c833fdee985.png


Считывает только 2 последних байта кода кнопок ,без обработки, они как раз на пульте всегда разные.

Загрузите, посмотрите в мониторе порта коды кнопок Вашего пульта, если все работает, то можно адаптировать под attiny13

bool st,st1,raz,dat;
uint32_t cod;
unsigned long data;
byte i1,i2,s,n;
 
void setup() {
  Serial.begin(9600);
  DDRB &= ~(1 << 0);
   cli(); 
  TCCR1A = 0;   
  TCCR1B = 0;   
  OCR1A = 9000; // 562.5 mks
  TCCR1B |= (1 << WGM12); 
  TCCR1B |= (1 << CS10);  
  TIMSK1 |= (1 << OCIE1A);  
   sei(); 
}
 
void loop() {
if(raz==1){Serial.println(IR(),HEX);}
// тут пишем условие, если IR()=0x7755, то сделать что то.
delay(200);
}
 
uint32_t IR(){
 delay(150);
 cod=0;i2=0;
 raz=0;
 TCCR1B |= (1 << CS10);OCR1A = 3200;//5000 Hz
 cod=data & 0xFFFF;data=0;
 return cod;}
 
ISR(TIMER1_COMPA_vect){
     if(((PINB >> 0) & 1)==0&&st==0&&raz==0){st=1;OCR1A = 9000;}
     if(st==1){s++;}
     if(s>20&&((PINB >> 0) & 1)==0){st1=1;}   
     if(st1==1){ dat = ((PINB >> 0) & 1);  if(i1>64){data+=(dat<<n);n++;}i1++;} 
     if(i1>96){i1=0;n=0;s=0;st=0;raz=1;st1=0;TCCR1B &= ~(1 << CS10);}
     }

24

Re: attiny13

Предварительно без настройки таймера attiny13

Скетч использует 170 байт (16%) памяти устройства. Всего доступно 1024 байт.
Глобальные переменные используют 10 байт (15%) динамической памяти, оставляя 54 байт для локальных переменных. Максимум: 64 байт.

bool st,st1,raz,dat;
uint32_t cod;
unsigned long data;
byte i1,i2,s,n;
 
void setup() {
  
  DDRB &= ~(1 << 0);
   cli(); 
  TCCR0A = 0;   
  TCCR0B = 0;   
  OCR0A = 9000; // 562.5 mks
  TCCR0B |= (1 << WGM02); 
  TCCR0B |= (1 << CS00);  
  TIMSK0 |= (1 << OCIE0A);  
   sei(); 
}
 
void loop() {
if(raz==1){IR();}
// тут пишем условие, если IR()=0x7755, то сделать что то.
delay(200);
}
 
uint32_t IR(){
 delay(150);
 cod=0;i2=0;
 raz=0;
 TCCR0B |= (1 << CS00);OCR0A = 3200;//5000 Hz
 cod=data & 0xFFFF;data=0;
 return cod;}
 
ISR(TIMER1_COMPA_vect){
     if(((PINB >> 0) & 1)==0&&st==0&&raz==0){st=1;OCR0A = 9000;}
     if(st==1){s++;}
     if(s>20&&((PINB >> 0) & 1)==0){st1=1;}   
     if(st1==1){ dat = ((PINB >> 0) & 1);  if(i1>64){data+=(dat<<n);n++;}i1++;} 
     if(i1>96){i1=0;n=0;s=0;st=0;raz=1;st1=0;TCCR0B &= ~(1 << CS00);}
     }

25

Re: attiny13

Правильно ли я понял: надо скетч из сообщения 23 загрузить в Ардуино? И надо проверить что в монитр порта попадает при использовании пульта?
Верно?
А на какой пин цеплять IR датчик?