This commit is contained in:
Thomas von Dein
2020-02-27 20:21:05 +01:00
parent fa98e283a3
commit 66206eea01
12 changed files with 350 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile
# attiny841:
# BOARD_TAG = attinyx41
# BOARD_SUB = 841
# attiny861:
# BOARD_TAG = attinyx61
# BOARD_SUB = 861
# attiny85:
# BOARD_TAG = attinyx5
# BOARD_SUB = 85
# attiny84:
# BOARD_TAG = attinyx4
# BOARD_SUB = 84
ARDUINO_VERSION = 10810
PROJECT_DIR = $(shell pwd)
BOARD_TAG = attinyx41
BOARD_SUB = 841
ARDUINO_DIR = /usr/local/arduino
ARDMK_DIR = /usr/local/arduino/Arduino-Makefile
MONITOR_PORT = /dev/ttyACM0
ISP_PORT = /dev/ttyACM0
AVRDUDE = /usr/local/bin/avrdude
#ARDUINO_LIB_PATH = $(ARDUINO_DIR)/hardware/ATTinyCore/avr/libraries
ARDUINO_LIBS = TinyBME280 Wire
ARDUINO_SKETCHBOOK = .
# mk stuff
ALTERNATE_CORE = ATTinyCore
F_CPU = 8000000L
MONITOR_BAUDRATE = 115200
AVRDUDE_ARD_PROGRAMMER = stk500v2
AVRDUDE_ARD_BAUDRATE = 9600
AVR_TOOLS_DIR = /usr/local/avr
AVRDUDE_CONF = /usr/local/etc/avrdude.conf
# Micronucleus
MNINST = sudo micronucleus
# compiler stuff
CFLAGS_STD = -std=gnu11
CXXFLAGS_STD = -std=gnu++11
CXXFLAGS + = -pedantic -Wall -Wextra
CURRENT_DIR = $(shell pwd)
# keep this!
include $(ARDMK_DIR)/Arduino.mk
# install using micronucleus
install: $(TARGET_HEX) verify_size
@echo "########### Press RESET on the Nanite! ##############"
$(MNINST) $(TARGET_HEX)

View File

@@ -0,0 +1,17 @@
# Usable Pins
```
PIN_A0 (10)
PIN_A1 ( 9)
PIN_A2 ( 8)
PIN_A3 ( 7)
PIN_A4 ( 6)
PIN_A5 ( 5)
PIN_A6 ( 4)
PIN_A7 ( 3)
PIN_B0 ( 0)
PIN_B1 ( 1)
PIN_B2 ( 2)
PIN_B3 (11) /* RESET */
LED_BUILTIN (2)
```

View File

@@ -0,0 +1,64 @@
/* -*-c++-*-
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
/*
Nanite841 Pinout from above:
button
PA5 PA6 SDA
SCL PA4 PA7
PA3 PB2
RX0 PA2 PB2
TX0 PA1 PB1
PA0 PB0
GND VCC
usb
*/
#include <Wire.h>
#include <TinyBME280.h>
int const sda = PA6;
int const scl = PA4;
#define LED LED_BUILTIN
void blinken(int howlong) {
digitalWrite(LED, HIGH);
delay(howlong);
digitalWrite(LED, LOW);
delay(howlong);
}
void print_measurements() {
Serial.print(" Temperature: ");
Serial.print(BME280temperature()/10);
Serial.println(" Grad C");
Serial.print(" Pressure: ");
Serial.print(BME280pressure()/100);
Serial.println(" hPa");
Serial.print(" Humidity: ");
Serial.print(BME280humidity()/100);
Serial.println(" %");
Serial.println();
}
void setup() {
pinMode(LED, OUTPUT);
Serial.begin(115200);
Serial.print("init");
Wire.begin();
BME280setI2Caddress(0x76);
BME280setup();
}
void loop() {
print_measurements();
delay(1000);
}

View File

@@ -0,0 +1 @@
/usr/local/arduino/hardware

View File

@@ -0,0 +1 @@
/usr/local/esp32/arduino-core/libraries/GFX

View File

@@ -0,0 +1 @@
/usr/local/arduino/hardware/ATTinyCore/avr/libraries/SPI

View File

@@ -0,0 +1 @@
/usr/local/esp32/arduino-core/libraries/SSD1306

View File

@@ -0,0 +1,42 @@
Tiny BME280
===========
The Bosch BME280 is the perfect sensor for a home weather station as it provides temperature, pressure, and humidity in a single device. This is an interface to allow you to use the sensor from an ATtiny processor such as the ATtiny85.
For information about using this library see [ATtiny85 Weather Station](http://www.plasticki.com/show?2F5D).
#### Introduction
The Bosch BME280 is a relatively low cost sensor which measures three environmental variables in a single device: temperature, pressure, and humidity. It's available on a breakout board from Adafruit, Sparkfun, or Chinese suppliers such as AliExpress and Banggood. Some boards, such as Adafruit's, support either 5V or 3.3V operation, so check carefully before buying if this is important to you.
The downside with this sensor is that you have to do quite a bit of calculation to get the final readings; it's not just a case of reading the values from the device via I2C or SPI, as with some other sensors. Both Adafruit and Sparkfun provide a library to interface to the sensor, but unfortunately these don't seem to work on ATtiny processors, such as the ATtiny85, so I set about writing my own Tiny BME280 library. I've only supported the I2C interface as it is the most useful one on ATtiny devices with a limited number of pins.
As with the other libraries my library uses the calculations from the BME280 datasheet, and I checked that it gives identical readings to the Sparkfun one. The only difference was with the pressure reading; Bosch gives two versions of the calculation, one using 64-bit integers and one using 32-bit integers. Sparkfun use the 64-bit version and I used the 32-bit version, but this resulted in a difference of under 1 part in 10000. I haven't provided altitude or dew point calculations.
This library is also compatible with the Bosch BMP280, a similar sensor that provides just temperature and pressure. If you use this sensor you'll get zero humidity readings.
#### Routines
The library provides the following routines:
**BME280setI2Caddress(address)** - specifies the I2C address. This should be called before **BME280setup()**. You don't need to call this if you are using the default I2C address, 0x77.
**BME280setup()** - sets up the BME280 into its normal measurement mode, with no upsampling, and reads the fixed calibrations from the sensor. You should call this in setup().
**BME280temperature()** - gives the temperature as a signed 32-bit integer in °C with a resolution of 0.01°C. So an output value of “5123” equals 51.23°C.
**BME280pressure()** - gives the pressure in Pa as an unsigned 32-bit integer, so an output value of “96386” equals 96386 Pa, or 963.86 hPa.
**BME280humidity()** - gives the humidity in %RH with a resolution of 0.01%RH, so an output value of “4653” represents 46.53 %RH.
#### Altitude
To add altitude use this routine:
// Altitude in metres
float BME280altitude (float referencePressure) {
return ((float)-45846.2)*(pow(((float)BME280pressure()/(float)referencePressure), 0.190263) - (float)1);
}
where **referencePressure** is the pressure in Pa at zero altitude; for example, 101325.0.

View File

@@ -0,0 +1,130 @@
/* TinyBME280 Library v2
David Johnson-Davies - www.technoblogy.com - 22nd June 2019
CC BY 4.0
Licensed under a Creative Commons Attribution 4.0 International license:
http://creativecommons.org/licenses/by/4.0/
*/
#include "TinyBME280.h"
int16_t T[4], P[10], H[7];
int32_t BME280t_fine;
int BME280address = 118;
int16_t read16 () {
uint8_t lo, hi;
lo = Wire.read(); hi = Wire.read();
return hi<<8 | lo;
}
int32_t read32 () {
uint8_t msb, lsb, xlsb;
msb = Wire.read(); lsb = Wire.read(); xlsb = Wire.read();
return (uint32_t)msb<<12 | (uint32_t)lsb<<4 | (xlsb>>4 & 0x0F);
}
// Can be called before BME280setup
void BME280setI2Caddress (uint8_t address) {
BME280address = address;
}
// Must be called once at start
void BME280setup () {
delay(2);
// Set the mode to Normal, no upsampling
Wire.beginTransmission(BME280address);
Wire.write(0xF2); // ctrl_hum
Wire.write(0b00000001);
Wire.write(0xF4); // ctrl_meas
Wire.write(0b00100111);
// Read the chip calibrations.
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280address, 26);
for (int i=1; i<=3; i++) T[i] = read16(); // Temperature
for (int i=1; i<=9; i++) P[i] = read16(); // Pressure
Wire.read(); // Skip 0xA0
H[1] = (uint8_t)Wire.read(); // Humidity
//
Wire.beginTransmission(BME280address);
Wire.write(0xE1);
Wire.endTransmission();
Wire.requestFrom(BME280address, 7);
H[2] = read16();
H[3] = (uint8_t)Wire.read();
uint8_t e4 = Wire.read(); uint8_t e5 = Wire.read();
H[4] = ((int16_t)((e4 << 4) + (e5 & 0x0F)));
H[5] = ((int16_t)((Wire.read() << 4) + ((e5 >> 4) & 0x0F)));
H[6] = ((int8_t)Wire.read()); // 0xE7
// Read the temperature to set BME280t_fine
BME280temperature();
}
// Returns temperature in DegC, resolution is 0.01 DegC
// Output value of “5123” equals 51.23 DegC
int32_t BME280temperature () {
Wire.beginTransmission(BME280address);
Wire.write(0xFA);
Wire.endTransmission();
Wire.requestFrom(BME280address, 3);
int32_t adc = read32();
// Compensate
int32_t var1, var2, t;
var1 = ((((adc>>3) - ((int32_t)((uint16_t)T[1])<<1))) * ((int32_t)T[2])) >> 11;
var2 = ((((adc>>4) - ((int32_t)((uint16_t)T[1]))) * ((adc>>4) - ((int32_t)((uint16_t)T[1])))) >> 12);
var2 = (var2 * ((int32_t)T[3])) >> 14;
BME280t_fine = var1 + var2;
return (BME280t_fine*5+128)>>8;
}
// Returns pressure in Pa as unsigned 32 bit integer
// Output value of “96386” equals 96386 Pa = 963.86 hPa
uint32_t BME280pressure () {
Wire.beginTransmission(BME280address);
Wire.write(0xF7);
Wire.endTransmission();
Wire.requestFrom(BME280address, 3);
int32_t adc = read32();
// Compensate
int32_t var1, var2;
uint32_t p;
var1 = (((int32_t)BME280t_fine)>>1) - (int32_t)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((int32_t)P[6]);
var2 = var2 + ((var1*((int32_t)P[5]))<<1);
var2 = (var2>>2) + (((int32_t)P[4])<<16);
var1 = (((P[3] * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)P[2]) * var1)>>1))>>18;
var1 = ((((32768+var1))*((int32_t)((uint16_t)P[1])))>>15);
if (var1 == 0) return 0;
p = (((uint32_t)(((int32_t)1048576) - adc) - (var2>>12)))*3125;
if (p < 0x80000000) p = (p << 1) / ((uint32_t)var1);
else p = (p / (uint32_t)var1) * 2;
var1 = (((int32_t)P[9]) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;
var2 = (((int32_t)(p>>2)) * ((int32_t)P[8]))>>13;
p = (uint32_t)((int32_t)p + ((var1 + var2 + P[7]) >> 4));
return p;
}
// Humidity in %RH, resolution is 0.01%RH
// Output value of “4653” represents 46.53 %RH
uint32_t BME280humidity () {
Wire.beginTransmission(BME280address);
Wire.write(0xFD);
Wire.endTransmission();
Wire.requestFrom(BME280address, 2);
uint8_t hi = Wire.read(); uint8_t lo = Wire.read();
int32_t adc = (uint16_t)(hi<<8 | lo);
// Compensate
int32_t var1;
var1 = (BME280t_fine - ((int32_t)76800));
var1 = (((((adc << 14) - (((int32_t)H[4]) << 20) - (((int32_t)H[5]) * var1)) +
((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)H[6])) >> 10) * (((var1 *
((int32_t)H[3])) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
((int32_t)H[2]) + 8192) >> 14));
var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)H[1])) >> 4));
var1 = (var1 < 0 ? 0 : var1);
var1 = (var1 > 419430400 ? 419430400 : var1);
return (uint32_t)((var1>>12)*25)>>8;
}

View File

@@ -0,0 +1,37 @@
/* TinyBME280 Library v2
David Johnson-Davies - www.technoblogy.com - 22nd June 2019
CC BY 4.0
Licensed under a Creative Commons Attribution 4.0 International license:
http://creativecommons.org/licenses/by/4.0/
*/
#include <stdint.h>
#include <Arduino.h>
#include <Wire.h>
#ifndef TINYBME280
#define TINYBME280
/* Function declarations */
// Can be called before BME280setup
void BME280setI2Caddress(uint8_t address);
// Sets Normal mode, no upsampling, and reads the chip calibrations
void BME280setup();
// Temperature in DegC, resolution is 0.01 DegC
// Output value of “5123” equals 51.23 DegC
int32_t BME280temperature();
// Pressure in Pa as unsigned 32 bit integer
// Output value of “96386” equals 96386 Pa = 963.86 hPa
uint32_t BME280pressure();
// Humidity in %RH, resolution is 0.01%RH
// Output value of “4653” represents 46.53 %RH
uint32_t BME280humidity();
#endif

View File

@@ -0,0 +1 @@
/usr/local/esp32/arduino-core/libraries/TinyWireM

View File

@@ -0,0 +1 @@
/usr/local/arduino/hardware/ATTinyCore/avr/libraries/Wire