1 (2024-03-27 16: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 (2024-10-22 16:37:48 отредактировано 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  PINB2 //DIN,SDA,data 
#define LCD_SCK   PINB4 //CLK,SCL,clock
#define LCD_CD    PINB1 //DC, D/C
#define LCD_RESET PINB0 //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 
extern const uint8_t SMALL_FONT[] PROGMEM;
const uint8_t SMALL_FONT[] PROGMEM = {
  0x7C, 0x82, 0x82, 0x82, 0x7C, // 30 0
  0x00, 0x84, 0xFE, 0x80, 0x00, // 31 1
  0x84, 0xC2, 0xA2, 0x92, 0x8C, // 32 2
  0x42, 0x82, 0x8A, 0x96, 0x62, // 33 3
  0x30, 0x28, 0x24, 0xFE, 0x20, // 34 4
  0x4E, 0x8A, 0x8A, 0x8A, 0x72, // 35 5
  0x7C, 0x92, 0x92, 0x92, 0x64, // 36 6
  0x02, 0xE2, 0x12, 0x0A, 0x06, // 37 7
  0x6C, 0x92, 0x92, 0x92, 0x6C, // 38 8
  0x4C, 0x92, 0x92, 0x92, 0x7C, // 39 9
  0x00, 0x60, 0x60, 0x00, 0x00,  // .
  0x01, 0x01, 0x7F, 0x01, 0x01,// т
  0x7F, 0x49, 0x49, 0x49, 0x41,//e
  0xFF, 0x02, 0x0C, 0x02, 0xFF,//м
  0x7F, 0x01, 0x01, 0x01, 0x7F,//п
  0x7F, 0x09, 0x09, 0x09, 0x06,//p
  0x07, 0x48, 0x48, 0x48, 0x3F,//у
  0x7C, 0x12, 0x11, 0x12, 0x7C,//a
  0x00, 0x0C, 0x12, 0x12, 0x0C,//gradus
  0x3E, 0x41, 0x41, 0x41, 0x22,//c
  0x7F, 0x49, 0x49, 0x49, 0x36,//в
  0x40, 0x3E, 0x01, 0x01, 0x7F,//л
  0x77, 0x08, 0x7F, 0x08, 0x77,//ж
  0x7F, 0x08, 0x08, 0x08, 0x7F,//H
  0x00, 0x7F, 0x48, 0x48, 0x30,//Ь
  0x46, 0x26, 0x10, 0xC8, 0xC4,//%
  0x60, 0x3F, 0x21, 0x3F, 0x60,//д
  0x7F, 0x10, 0x08, 0x04, 0x7F,//и
  0xF8, 0x20, 0x50, 0x88, 0x00,//к
  0x3E, 0x41, 0x41, 0x41, 0x3E,//о
  0xFE, 0x02, 0x02, 0x02, 0xFE,//п
  0x40, 0xA8, 0xA8, 0xA8, 0xF0,//a
  0x7C, 0x82, 0x82, 0x82, 0x44,//c
  };


void setup() {
   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
   // clear nokia LCD
    lcdCommand(0x80);
    lcdCommand(0x40);
    // Fill in the whole display with ZEROS
    for(uint16_t index = 0; index < (LCD_COL * LCD_ROW); index++)
     lcdData(0x00);
  Wire.begin();
  BME280setI2Caddress(0x76);
  BME280setup();  
}

void loop() {
int t = BME280temperature();
int p = BME280pressure()/100;
int h = BME280humidity();
             
               lcdPrintChar(0, 22,26);//д
               lcdPrintChar(0, 29,17);//а
               lcdPrintChar(0, 36,20);//в
               lcdPrintChar(0, 43,21);//л
               lcdPrintChar(0, 50,12);//е
               lcdPrintChar(0, 57,23);//н
               lcdPrintChar(0, 64,27);//и
               lcdPrintChar(0, 71,12);//е


               lcdPrintChar(1,26,p/ 1000);
               lcdPrintChar(1,33,(p/100) % 10);       
               lcdPrintChar(1,40,(p/ 10) % 10);
               lcdPrintChar(1,47,p % 10);
               lcdPrintChar(1, 54,28);//к
               lcdPrintChar(1, 61,30);//п
               lcdPrintChar(1, 68,31);//а
               
               lcdPrintChar(3, 8, 11);//т
               lcdPrintChar(3, 15,12);//е
               lcdPrintChar(3, 22,13);//м
               lcdPrintChar(3, 29,14);//п
               lcdPrintChar(3, 36,12);//е
               lcdPrintChar(3, 43,15);//р
               lcdPrintChar(3, 50,17);//а
               lcdPrintChar(3, 57,11);//т
               lcdPrintChar(3, 64,16);//у
               lcdPrintChar(3, 71,15);//р
               lcdPrintChar(3, 78,17);//а
                       
               lcdPrintChar(4,26,t/ 1000);
               lcdPrintChar(4,33,(t/ 100) % 10);
               lcdPrintChar(4,40,10);
               lcdPrintChar(4,45,(t/ 10) % 10);
              // lcdPrintChar(4,54, t % 10);
               lcdPrintChar(4,52, 18);
               lcdPrintChar(4,59, 32);
               
               lcdPrintChar(6, 15,20);//в
               lcdPrintChar(6, 22,21);//л
               lcdPrintChar(6, 29,17);//а
               lcdPrintChar(6, 36,22);//ж
               lcdPrintChar(6, 43,23);//н
               lcdPrintChar(6, 50,29);//0
               lcdPrintChar(6, 57,19);//с
               lcdPrintChar(6, 64,11);//т
               lcdPrintChar(6, 71,24);//ь
  
               lcdPrintChar(7,26,h/1000 % 10);
               lcdPrintChar(7,33,(h/100) % 10);
               lcdPrintChar(7,40,10);
               lcdPrintChar(7,45,(h/10) % 10);
              // lcdPrintChar(7,54,h % 10);
               lcdPrintChar(7,52,25);//%
              
               
}

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);
  }

http://forum.rcl-radio.ru/uploads/images/2024/03/2418bf1c7e29b9a559a65a578da92f5e.jpg

"Поигрался" с картинкой
http://forum.rcl-radio.ru/uploads/images/2024/10/61fbf000839dca52368a049cdc6116e7.jpg
спящий режим через 5 минут

#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,  // . 
  0x3E, 0x41, 0x49, 0x49, 0x7A,//g
  };
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, 
   0x00,0x00, 0x80, 0xC0, 0x60, 0x60,0x60, 0x60, 0xE0, 0xE0, 0x00,// Г
   0x00,0x00, 0x03, 0x07, 0xCC, 0xCC,0xCC, 0xCC, 0xFF, 0x7F, 0x00,  
   0x00,0x00, 0xF8, 0xFC, 0x0C, 0x0C,0x0C, 0x0C, 0xF8, 0xF0, 0x00,//P
   0x00,0x00, 0x7F, 0x7F, 0x03, 0x03,0x03, 0x03, 0x01, 0x00, 0x00,
   0x00,0x00,0x00,0x00,0x40,0x60,0x60,0x60,0xE0,0xC0,0x00,//А
   0x00,0x00,0x00,0x3C,0x7E,0x66,0x66,0x66,0x3F,0x7F,0x40,
   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;

dht_read(&_hum, &_temp);   
       lcdPrintBChar(6, 0, 18, 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, 17, 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, 16, 0, 0);
      
       if(p/1000>0){
       lcdPrintBChar(0,22,p / 1000, 0, 0) ;
       lcdPrintBChar(0, 34,p /100%10, 0, 0); 
       lcdPrintBChar(0, 46,p/10%10, 0, 0);
       lcdPrintBChar(0, 58,p%10, 0, 0);}
       else {
       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, 63,1);
     //  lcdPrintBChar(0, 60, 13, 0, 0);
       lcdPrintBChar(0, 70, 14, 0, 0);
       lcdPrintBChar(0, 80, 15, 0, 0);
     
               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 14:10:51 отредактировано klause)

Re: Attiny4313&bme280

liman324 пишет:

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

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

5 (2024-10-22 16: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, то получится интересная штука для дома.