1 (2024-03-27 10:57:50 отредактировано klause)

Тема: Attiny4313&bme280

Попытался подключить модуль bme280(bmp280). Индикатор на MAx7219.Выводится через 3с температура,давление,влажность. Плата AttinyCore.

#include <Wire.h>
#include "TinyBME280.h"
#define DIN PD3 // нога1
#define CS  PD4 // нога12
#define CLK PD5 // нога13
int const sda = PB5;//pin 17 
int const scl = PB7;//pin 19  

void setup() {
  // Set up BME280
  Wire.begin();
  BME280setI2Caddress(0x76);
  BME280setup();
  DDRD |= (1 << DIN) | (1 << CS) | (1 << CLK);
  PORTD |= (1 << CS);
  PORTD &= ~(1 << CLK) | (1 << DIN);
  delay(1);

  WriteBit16(0x0f,0x00); // Тест выкл.
  WriteBit16(0x0C,0x01); // Вкл. индик.
  WriteBit16(0x0B,0x04); // кол-во разрядов
  WriteBit16(0x09,0xFF); // Дешифраторы вкл.
  WriteBit16(0x0A,0x0f); // яркость
}
void loop () {

int t = BME280temperature();
int p = BME280pressure()/10;
int h = BME280humidity();
delay(3000);
  WriteBit16(0x01,t/1000);
  WriteBit16(0x02,((t /100)% 10)|128);
  WriteBit16(0x03,(t/10)%10);
  WriteBit16(0x04,t%10);
  delay(3000);
  WriteBit16(0x01,p/1000);
  WriteBit16(0x02,(p /100)% 10);
  WriteBit16(0x03,((p/10)%10)|128);
  WriteBit16(0x04,p%10);
  delay(3000);
  WriteBit16(0x01,h/1000);
 WriteBit16(0x02,((h /100)% 10)|128);
  WriteBit16(0x03,(h/10)%10);
  WriteBit16(0x04,h%10);
  delay(3000);
  
}
void WriteBit16(byte reg, byte data)
{  
     PORTD &= ~(1 << CLK);PORTD &= ~(1 << CS);
     for(int i = 7; i >= 0; i--){
        if(((reg >> i) & 1) == 1){PORTD |= (1 << DIN);}else{PORTD &= ~(1 << DIN);}
        PORTD |=(1 << CLK);PORTD &= ~(1 << CLK);
        }
     for(int i = 7; i >= 0; i--){
        if(((data >> i) & 1) == 1){PORTD |= (1 << DIN);}else{PORTD &= ~(1 << DIN);}
        PORTD |=(1 << CLK);PORTD &= ~(1 << CLK);
        }
     PORTD |=(1 << CS);PORTD &= ~(1 << CLK);PORTD &= ~(1 << DIN);
  }  

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

2 (2025-01-10 07:03:15 отредактировано klause)

Re: Attiny4313&bme280

С дисплеем нокиа3410.

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <Wire.h>
#include "TinyBME280.h"
// Nokia LCD pin numbers
#define LCD_MOSI  PINB4 //DIN,SDA,data 
#define LCD_SCK   PINB3 //CLK,SCL,clock
#define LCD_CD    PINB2 //DC, D/C
#define LCD_RESET PINB1 //Res,reset
/*pin CS подключить на GND
pin Vout через конденсатор на GND */
/** Number of columns */
#define LCD_COL 96 //for Nokia 3310-84
/** Number of text rows */
#define LCD_ROW 10 //for Nokia 3310-6
int const sda = PB5;//pin 17 
int const scl = PB7;//pin 19
#define DHT PIND0
const unsigned long Alarm = 300000; //  time - 5 minutes
//unsigned long StartTime = 0;        // start time 
const int Dht = PIND1; // +dht11
byte _hum, _temp; 
extern const uint8_t SMALL_FONT[] PROGMEM;
const uint8_t SMALL_FONT[] PROGMEM = {
  0x00, 0x60, 0x60, 0x00, 0x00,//.
  0x7F, 0x02, 0x0C, 0x02, 0x7F// m 
  };
extern const uint8_t BIG_FONT[] PROGMEM;
const uint8_t BIG_FONT[] PROGMEM = {
   0x00,0xF0,0xFC,0xFE,0x06,0x02,0x06,0xFE,0xFC,0xF0,0x00,// 0
   0x00,0x07,0x1F,0x3F,0x30,0x20,0x30,0x3F,0x1F,0x07,0x00,
   0x00,0x00,0x08,0x0C,0xFC,0xFE,0xFE,0x00,0x00,0x00,0x00,// 1
   0x00,0x20,0x20,0x20,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x00,
   0x00,0x0C,0x0E,0x06,0x02,0x02,0x86,0xFE,0x7C,0x38,0x00,// 2
   0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x38,0x00,
   0x00,0x0C,0x0E,0x86,0x82,0x82,0xC6,0xFE,0x7C,0x38,0x00,// 3
   0x00,0x18,0x38,0x30,0x20,0x20,0x31,0x3F,0x1F,0x0E,0x00,
   0x00,0x00,0xC0,0x20,0x18,0x04,0xFE,0xFE,0xFE,0x00,0x00,// 4
   0x00,0x03,0x02,0x02,0x02,0x22,0x3F,0x3F,0x3F,0x22,0x02,
   0x00,0x00,0x7E,0x7E,0x46,0x46,0xC6,0xC6,0x86,0x00,0x00,// 5
   0x00,0x18,0x38,0x30,0x20,0x20,0x30,0x3F,0x1F,0x0F,0x00,
   0x00,0xC0,0xF0,0xF8,0xFC,0x4C,0xC6,0xC2,0x82,0x00,0x00,// 6
   0x00,0x0F,0x1F,0x3F,0x30,0x20,0x30,0x3F,0x1F,0x0F,0x00,
   0x00,0x06,0x06,0x06,0x06,0x06,0xC6,0xF6,0x3E,0x0E,0x00,// 7
   0x00,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,
   0x00,0x38,0x7C,0xFE,0xC6,0x82,0xC6,0xFE,0x7C,0x38,0x00,// 8
   0x00,0x0E,0x1F,0x3F,0x31,0x20,0x31,0x3F,0x1F,0x0E,0x00,
   0x00,0x78,0xFC,0xFE,0x86,0x02,0x86,0xFE,0xFC,0xF8,0x00,// 9
   0x00,0x00,0x00,0x21,0x21,0x31,0x1D,0x1F,0x0F,0x03,0x00,
   0xF0,0xF8,0x0C,0x06,0x02,0x02,0x02,0x02,0x0E,0x0C,0x00,// C
   0x03,0x07,0x0C,0x18,0x10,0x10,0x10,0x10,0x1C,0x0C,0x00,
   0x00,0x1C,0x22,0x22,0x22,0x1C,0x00,0x00,0x00,0x00,0x00,// degrees
   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 
   0x00,0x1C,0x22,0x22,0x22,0x1C,0x80,0x40,0x20,0x10,0x08,// %
   0x00,0x10,0x08,0x04,0x02,0x01,0x38,0x44,0x44,0x44,0x38, 
   0x88,0x48,0x29,0xDA,0x2C,0x32,0x32,0x4C,0x9A,0xA9,0x48,//Рress
   0x00,0x06,0x49,0x29,0x88,0x48,0x28,0x08,0x48,0x24,0x03,
   0x44,0x54,0x54,0xFE,0x01,0xFE,0x00,0xC6,0x29,0x29,0x46,//Тemp
   0x00,0x01,0x71,0x8F,0x80,0x8F,0x70,0x07,0x08,0x08,0x04,
   0x00,0x80,0x40,0x30,0x0E,0x07,0x38,0xE0,0xC0,0x80,0x00,//Нum 
   0x00,0x3E,0x41,0x80,0x80,0x80,0x80,0xC0,0xFF,0x7F,0x3E,     
}; 

void setup() {
 DDRD|=(1<<Dht);
 PORTD = PORTD | 1<<Dht;
  unitLCD(); 
  clearLCD(); 
  Wire.begin();
  BME280setI2Caddress(0x76);
  BME280setup();
 
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
}

void loop() {
  do{
int t = BME280temperature();
int p = BME280pressure()*100/13332;

dht_read(&_hum, &_temp);   
       lcdPrintBChar(6, 0, 15, 0, 0); 
         
       lcdPrintBChar(6, 34,_hum / 10%10, 0, 0); 
       lcdPrintBChar(6, 46,_hum %10, 0, 0);
       lcdPrintBChar(6, 58, 12, 0, 0);
       
       lcdPrintBChar(3, 1, 14, 0, 0);
       
       lcdPrintBChar(3, 22,t/1000%10, 0, 0);
       lcdPrintBChar(3, 34,t/100%10, 0, 0);
       lcdPrintChar (4, 44,0);       
       lcdPrintBChar(3, 51,t/10%10, 0, 0);
       lcdPrintBChar(3, 63, 11, 0, 0);
       lcdPrintBChar(3, 73, 10, 0, 0);
       
       lcdPrintBChar(0, 1, 13, 0, 0);
  
       lcdPrintBChar(0, 27,p /100%10, 0, 0); 
       lcdPrintBChar(0, 39,p/10%10, 0, 0);
       lcdPrintBChar(0, 51,p%10, 0, 0);
       lcdPrintChar (1, 65,1);
       lcdPrintChar (1, 72,1);
     
               delay(1000);
  }
  while( millis() < Alarm);
 
  PORTD = PORTD & ~(1<<Dht);
  PORTB=0; 
  sleep_enable();
  sleep_cpu();          
               
}

void sspiOutMSB(uint8_t sck, uint8_t mosi, uint16_t data, uint8_t bits) {
  uint16_t mask = (1 << (bits - 1));
  uint8_t output = (1 << mosi);
  uint8_t clock = (1 << sck);
  while(bits) {
    // Set data
    if(data&mask)
      PORTB |= output;
    else
      PORTB &= ~output;
    // Bring the clock high
    PORTB |= clock;
    // Move to the next bit
    mask = mask >> 1;
    bits--;
    // Bring the clock low again
    PORTB &= ~clock;
    }
  }
void lcdData(uint8_t data) {
  // Bring CD high
  PORTB |= (1 << LCD_CD);
  // Send the data
  sspiOutMSB(LCD_SCK, LCD_MOSI, data, 8);
  }

/** Send a command byte to the LCD
 *
 * @param cmd the command byte to send.
 */
void lcdCommand(uint8_t cmd) {
  // Bring CD low
  PORTB &= ~(1 << LCD_CD);
  // Send the data
  sspiOutMSB(LCD_SCK, LCD_MOSI, cmd, 8);
  }

/** Write a single character
 */

void lcdPrintChar(uint8_t row, uint8_t col, uint8_t ch) {

  // Set the starting address
  const uint8_t *chdata = SMALL_FONT + (ch * 5);

    lcdCommand(0x80 | col);
    lcdCommand(0x40 | (row % LCD_ROW));
    // And send the column data
   for(uint8_t pixels = 0; pixels < 5; pixels++, chdata++) {
    uint8_t data = pgm_read_byte_near(chdata);
    lcdData(data);
    // for double sized font put
   // lcdData(data);
    };
  // Add the padding byte
//if(col < LCD_COL)
 lcdData(0x00);
  }
  void clearLCD()
  { lcdCommand(0x80);
    lcdCommand(0x40);
    // Fill in the whole display with ZEROS
    for(uint16_t index = 0; index < (LCD_COL * LCD_ROW); index++)
     lcdData(0x00);}
  void unitLCD()
  {
    uint8_t val = (1 << LCD_SCK) | (1 << LCD_MOSI) | (1 << LCD_RESET) | (1 << LCD_CD);
   PORTB &= ~val;
   DDRB |= val;
   PORTB |= (1 << LCD_RESET);
   lcdCommand(0x21);  // LCD Extended Commands.
   lcdCommand(0xA1);  // Set LCD Vop (Contrast).
   lcdCommand(0x04);  // Set Temp coefficent.
   lcdCommand(0x14);  // LCD bias mode 1:48.
   lcdCommand(0x20);  // LCD Normal commands
   lcdCommand(0x0C);  // Normal display, horizontal addressing   
    }   
// общая функция опроса датчика
  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 3; // если контрольная сумма не сошлась вернем ошибку 3
  
  *hum=data[0];// пишем данные влажности 
  *temp=data[2];// пишем данные температуры 
  return 0;// вернем 0 - ошибок нет.
}
// функция передачи условия "старт" на линию и проверка ответов от датчика.
 byte  dht_start(){
  DDRD|=(1<<DHT);// притянули линию к земле - 0
  _delay_ms(20);// пауза 20 мс 
  DDRD&=~(1<<DHT);// отпустили линию - 1
  _delay_us(40);// ждем 40 мкс чтобы попасть в середину низкого сигнала
  if (PIND&(1<<DHT)) return 1; // если на линии 1 ошибка - "датчик не ответил"
  _delay_us(80); // ждем 80 мкс чтобы попасть в середину высокого сигнала
  if (!(PIND&(1<<DHT))) return 2; // если на линии 0 ошибка - "датчик не готов "
  while(PIND&(1<<DHT));// ждем пока датчик не притянет линию к земле.
  return 0;// ошибок нет
}
// получение байта от датчика
byte dht_byte(){
  byte i=8, byte=0;// переменная для цикла и под байт
  while(i--){
    while(!(PIND&(1<<DHT)));// ждем пока линия не поднимится в 1
    _delay_us(40);// отступаем 40 мкс
    if (PIND&(1<<DHT)) {// если на линии 1 = приняли 1
      byte|=(1<<i);// поднимаем итый бит в 1
      while(PIND&(1<<DHT));// ждем пока линия упадет в 0
    }
  }
  return byte;// возвращаем полученный байт
}
void lcdPrintBChar(uint8_t row, uint8_t col, uint8_t ch, bool big, bool invert) {

  // Set the starting address
  const uint8_t *chdata = BIG_FONT + (ch * 22);
 
  for(uint8_t rowused = row; rowused < row+2; rowused++) {
    lcdCommand(0x80 | col);
    lcdCommand(0x40 | (rowused % LCD_ROW));
    // And send the column data
   for(uint8_t pixels = 0; pixels < 11; pixels++, chdata++) {
    uint8_t data = pgm_read_byte_near(chdata);
    //double sized font
    lcdData(invert?~data:data);
    if (big) lcdData(invert?~data:data);
    };
  }
  // Add the padding byte
 if(col < LCD_COL)
   lcdData(invert?0xFF:0x00);
  }

3

Re: Attiny4313&bme280

Отличная работа, рекомендую опубликовать на сайте rck-radio.ru Ваши проекты, там намного больше посещаемость, больше вероятность получить отзывы о Ваших проектах.

4 (2024-03-29 08:10:51 отредактировано klause)

Re: Attiny4313&bme280

liman324 пишет:

Отличная работа, рекомендую опубликовать на сайте rck-radio.ru Ваши проекты, там намного больше посещаемость, больше вероятность получить отзывы о Ваших проектах.

Спасибо. Но это просто творческий порыв, для своего развития. Код ещё надо подкорректировать. В свойствах платы отключить millis()/micros(), чтобы код вместился.

5 (2024-10-22 10:43:02 отредактировано klause)

Re: Attiny4313&bme280

Attiny85,LCD1602,Dht11,bmp280
http://forum.rcl-radio.ru/uploads/images/2024/09/99e5ba8b2d9c7339aff097538b2e5590.jpg

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "TinyBME280.h"
int const sda = PB0;//SDA pin 5 PB0
int const scl = PB2;//SCL pin 7 PB2 
#define DHT PB4 // +подключить внешнюю подтяжку.
byte _hum, _temp;// переменные для влажности и температуры 
LiquidCrystal_I2C lcd(0x27, 16, 2);
byte c[] = {B00110,B01001,B01001,B00110,B00000,B00000,B00000,B00000};

void setup() {
  Wire.begin();
  BME280setI2Caddress(0x76);
  BME280setup();
  lcd.begin();
  lcd.backlight();
  lcd.print("Hello, world!");
  delay(1000);
  lcd.clear();
  lcd.createChar(0, c);
  
}
  
void loop() {

dht_read(&_hum, &_temp);// опроса датчика
int t = BME280temperature();
int p = BME280pressure()/10;
int h = p/1.333224;

 lcd.home();
 lcd.print("P=");
 lcd.print(p/1000);
 lcd.print(p / 100 % 10);
 lcd.print(p/ 10 % 10);
 lcd.print("kPa ");
 lcd.print(h/1000);
 lcd.print(h / 100 % 10);
 lcd.print(h/ 10 % 10);
 lcd.print("mmHg"); 
 lcd.setCursor(0, 1);
 lcd.print("T="); 
 lcd.print(t / 1000);
 lcd.print(t/ 100 % 10 );
 lcd.print("."); 
 lcd.print(t/ 10 % 10);
 lcd.write(0);
 lcd.print("C"); 
 lcd.print(" Hum=");
 lcd.print(_hum/ 10 % 10 );
 lcd.print(_hum % 10);
 lcd.print("%");
 delay(1000);
  
}
// общая функция опроса датчика
  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 3; // если контрольная сумма не сошлась вернем ошибку 3
  
  *hum=data[0];// пишем данные влажности 
  *temp=data[2];// пишем данные температуры 
  return 0;// вернем 0 - ошибок нет.
}
// функция передачи условия "старт" на линию и проверка ответов от датчика.
 byte  dht_start(){
  DDRB|=(1<<DHT);// притянули линию к земле - 0
  delay(20);// пауза 20 мс 
  DDRB&=~(1<<DHT);// отпустили линию - 1
  delayMicroseconds(40);// ждем 40 мкс чтобы попасть в середину низкого сигнала
  if (PINB&(1<<DHT)) return 1; // если на линии 1 ошибка - "датчик не ответил"
  delayMicroseconds(80); // ждем 80 мкс чтобы попасть в середину высокого сигнала
  if (!(PINB&(1<<DHT))) return 2; // если на линии 0 ошибка - "датчик не готов "
  while(PINB&(1<<DHT));// ждем пока датчик не притянет линию к земле.
  return 0;// ошибок нет
}
// получение байта от датчика
byte dht_byte(){
  byte i=8, byte=0;// переменная для цикла и под байт
  while(i--){
    while(!(PINB&(1<<DHT)));// ждем пока линия не поднимится в 1
    delayMicroseconds(40);// отступаем 40 мкс
    if (PINB&(1<<DHT)) {// если на линии 1 = приняли 1
      byte|=(1<<i);// поднимаем итый бит в 1
      while(PINB&(1<<DHT));// ждем пока линия упадет в 0
    }
  }
  return byte;// возвращаем полученный байт
}
 

BMP180, DHT11.
http://forum.rcl-radio.ru/uploads/images/2024/10/7989d5912c85746f677e8690d7f72b93.jpg
http://forum.rcl-radio.ru/uploads/images/2024/10/61c769bf2790ea9209e4925d9963d0ed.jpg

#include <TinyWireM.h>
#include <tinyBMP085.h>
tinyBMP085 bmp;
#define DIN PB1
#define CS  PB3
#define CLK PB4
//SDA pin 5 PB0
//SCL pin 7 PB2 
byte _hum, _temp; 
#define DHT PB5
unsigned long StartTime;
byte DisplayNumtoSeg[] = {126,48, 109, 121, 51, 91, 95, 112, 127, 123};
void setup() {
  bmp.begin(); 
  delay(2);
  DDRB |= (1 << DIN) | (1 << CS) | (1 << CLK);
  max7219(0x0F, 0, 0);// тест выкл.
  max7219(0x0C, 1, 1);// вкл. индик.
  max7219(0x0A, 0x0f, 0x0f);// яркость
  max7219(0x09, 0, 0);// дешифраторы выкл.
  max7219(0x0B, 7, 7);// кол-во разрядов  
}
  
void loop() {
    int pres = bmp.readPressure()/100; //kилопаскалях 
    pres=pres-2;// коррекция 
    int  p = pres/0.133322;// мм ртутного столба
 
   // int temp = bmp.readTemperature10C();
  dht_read(&_hum, &_temp); 
  max7219(1, 103, DisplayNumtoSeg [_temp / 10%10]);
  max7219(2, 5, DisplayNumtoSeg [_temp %10]);
  max7219(3, DisplayNumtoSeg [p / 1000], 99);
  max7219(4, DisplayNumtoSeg [p / 100%10], 78);
  max7219(5 ,DisplayNumtoSeg [p / 10%10] , DisplayNumtoSeg [_hum/ 10%10]);
  max7219(6, 0 , DisplayNumtoSeg [_hum %10]);
  max7219(7, 0, 99);  
  max7219(8, 0, 29);
  if(millis()-StartTime > 10000){
   StartTime= millis();
  if(pres>=1000)max7219(1, DisplayNumtoSeg [pres / 1000], DisplayNumtoSeg [_temp / 10%10]); 
  else max7219(1,0, DisplayNumtoSeg [_temp / 10%10]);
  max7219(2, DisplayNumtoSeg [pres / 100%10], DisplayNumtoSeg [_temp %10]);
  max7219(3, DisplayNumtoSeg [pres / 10%10], 99);
  max7219(4, DisplayNumtoSeg [pres %10], 78);
  max7219(5 ,0 , DisplayNumtoSeg [_hum/ 10%10]);
  max7219(6, 103, DisplayNumtoSeg [_hum %10]);
  max7219(7, 0, 99);  
  max7219(8, 0, 29);
  }
  delay(1000);
}
void WriteBit16(byte reg, byte data){  
     for(char i = 7; i >= 0; i--){
        PORTB &= ~(1 << CLK);
        if(((reg >> i) & 1) == 1){PORTB |= (1 << DIN);}else{PORTB &= ~(1 << DIN);}
        PORTB |=(1 << CLK);}
     for(char i = 7; i >= 0; i--){
        PORTB &= ~(1 << CLK);
        if(((data >> i) & 1) == 1){PORTB |= (1 << DIN);}else{PORTB &= ~(1 << DIN);}
        PORTB |=(1 << CLK);}
        PORTB &= ~(1 << CLK);PORTB |= (1 << DIN);
  }
  void max7219(byte reg_n, byte h1, byte h2){
  PORTB &=~(1 << CS);
  WriteBit16(reg_n,h1);
  WriteBit16(reg_n,h2);
  PORTB |=(1 << CS);} 
  // общая функция опроса датчика
  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 3; // если контрольная сумма не сошлась вернем ошибку 3
  
  *hum=data[0];// пишем данные влажности 
  *temp=data[2];// пишем данные температуры 
  return 0;// вернем 0 - ошибок нет.
}
// функция передачи условия "старт" на линию и проверка ответов от датчика.
 byte  dht_start(){
  DDRB|=(1<<DHT);// притянули линию к земле - 0
  delay(20);// пауза 20 мс 
  DDRB&=~(1<<DHT);// отпустили линию - 1
  delayMicroseconds(40);// ждем 40 мкс чтобы попасть в середину низкого сигнала
  if (PINB&(1<<DHT)) return 1; // если на линии 1 ошибка - "датчик не ответил"
  delayMicroseconds(80); // ждем 80 мкс чтобы попасть в середину высокого сигнала
  if (!(PINB&(1<<DHT))) return 2; // если на линии 0 ошибка - "датчик не готов "
  while(PINB&(1<<DHT));// ждем пока датчик не притянет линию к земле.
  return 0;// ошибок нет
}
// получение байта от датчика
byte dht_byte(){
  byte i=8, byte=0;// переменная для цикла и под байт
  while(i--){
    while(!(PINB&(1<<DHT)));// ждем пока линия не поднимится в 1
    delayMicroseconds(40);// отступаем 40 мкс
    if (PINB&(1<<DHT)) {// если на линии 1 = приняли 1
      byte|=(1<<i);// поднимаем итый бит в 1
      while(PINB&(1<<DHT));// ждем пока линия упадет в 0
    }
  }
  return byte;// возвращаем полученный байт
}

6

Re: Attiny4313&bme280

Отличная разработка.
Если добавить измерение СО2 на MQ135, то получится интересная штука для дома.

7

Re: Attiny4313&bme280

Attiny85 + BME280+ds18b20+max7219

#include <Wire.h>
#include "TinyBME280.h"
#define DIN PB1
#define CS  PB4
#define CLK PB3
//SDA pin 5 PB0
//SCL pin 7 PB2  
const int OneWirePin = 5;
byte DisplayNumtoSeg[] = {126,48, 109, 121, 51, 91, 95, 112, 127, 123};
int t,p,h;
#define t1 DisplayNumtoSeg [t / 1000]
#define t2 DisplayNumtoSeg [t / 100%10]
#define p1 DisplayNumtoSeg [p / 100%10]
#define p2 DisplayNumtoSeg [p / 10%10]
#define p3 DisplayNumtoSeg [p %10]
uint8_t DataBytes[2];
 
byte d1,d2,d3,d4;  
void setup() {
  Wire.begin();
  BME280setI2Caddress(0x76);
  BME280setup();
  DDRB |= (1 << DIN) | (1 << CS) | (1 << CLK);
  max7219(0x0F, 0, 0);// тест выкл.
  max7219(0x0C, 1, 1);// вкл. индик.
  max7219(0x0A, 0x0f, 0x0f);// яркость
  max7219(0x09, 0, 0);// дешифраторы выкл.
  max7219(0x0B, 7, 7);// кол-во разрядов 
  TCCR1 = 0<<CTC1 | 0<<PWM1A | 5<<CS10;  // CTC mode, 500kHz clock
  GTCCR = 0<<PWM1B;
  max7219(1, 0,0 );
  max7219(2, 55, 0);
  max7219(3, 79, 0);
  max7219(4, 14, 0);
  max7219(5, 14, 0);
  max7219(6, 126, 0);    
  max7219(7, 0, 0);  
  max7219(8, 0, 0);
  delay(1000);
}
  
void loop() {
 
 t = BME280temperature();
 p = BME280pressure()*100/13332;  
 h = BME280humidity();
 Temperature ();  
  if(t / 1000!=0) max7219(1,t1,103 );
  else  max7219(1,0,103 );
  max7219(2, t2, p1);
  max7219(3, 99, p2);
  max7219(4, d1, p3);
  max7219(5, d2, DisplayNumtoSeg [h /1000]);
  max7219(6, d3, DisplayNumtoSeg [h /100%10]);    
  max7219(7, d4, 99);  
  max7219(8, 0, 29);
  delay(3000);
      
}
void WriteBit16(byte reg, byte data){  
     for(char i = 7; i >= 0; i--){
        PORTB &= ~(1 << CLK);
        if(((reg >> i) & 1) == 1){PORTB |= (1 << DIN);}else{PORTB &= ~(1 << DIN);}
        PORTB |=(1 << CLK);}
     for(char i = 7; i >= 0; i--){
        PORTB &= ~(1 << CLK);
        if(((data >> i) & 1) == 1){PORTB |= (1 << DIN);}else{PORTB &= ~(1 << DIN);}
        PORTB |=(1 << CLK);}
        PORTB &= ~(1 << CLK);PORTB |= (1 << DIN);
  }
  void max7219(byte reg_n, byte h1, byte h2){
  PORTB &=~(1 << CS);
  WriteBit16(reg_n,h1);
  WriteBit16(reg_n,h2);
  PORTB |=(1 << CS);} 
 /////////////
inline void PinLow () {
  DDRB = DDRB | 1<<OneWirePin;
}

inline void PinRelease () {
  DDRB = DDRB & ~(1<<OneWirePin);
}

// Returns 0 or 1
inline uint8_t PinRead () {
  return PINB>>OneWirePin & 1;
}

void DelayMicros (int micro) {
  TCNT1 = 0; TIFR = 1<<OCF1A;
  OCR1A = (micro>>1) - 1;
  while ((TIFR & 1<<OCF1A) == 0);
}

void LowRelease (int low, int high) {
  PinLow();
  DelayMicros(low);
  PinRelease();
  DelayMicros(high);
}

uint8_t OneWireReset () {
  uint8_t data = 1;
  LowRelease(480, 70);
  data = PinRead();
  DelayMicros(410);
  return data;                         // 0 = device present
}

void OneWireWrite (uint8_t data) {
  int del;
  for (int i = 0; i<8; i++) {
    if ((data & 1) == 1) del = 6; else del = 60;
    LowRelease(del, 70 - del);
    data = data >> 1;
  }
}

uint8_t OneWireRead () {
  uint8_t data = 0;
  for (int i = 0; i<8; i++) {
    LowRelease(6, 9);
    data = data | PinRead()<<i;
    DelayMicros(55);
  }
  return data;
}

void Temperature () {
  int temp;
   cli(); // No interrupts
  if(OneWireReset()!=0){
  sei();  
  d1=78;
  d2=d3=d4=128;
  }
  else{
  OneWireWrite(0xCC);
    OneWireWrite(0x44);
    while (OneWireRead() != 0xFF);
    OneWireReset();
    OneWireWrite(0xCC);
    OneWireWrite(0xBE);
    DataBytes[0]=OneWireRead();
    DataBytes[1]=OneWireRead();
    OneWireReset();
    sei();
 temp =(DataBytes[1]<<8 | DataBytes[0])/16;
if (temp>=100)d1=DisplayNumtoSeg[temp/100];  
if (temp<0) d1=1;
else d1=0;
if(abs(temp)/10 % 10==0){
   d2=DisplayNumtoSeg[abs(temp) % 10];
   d3=99;
   d4=78;
   }
else {
 d2= DisplayNumtoSeg[abs(temp)/10%10];
 d3= DisplayNumtoSeg[abs(temp) % 10];
 d4 = 99;} 
  }
}