From 66206eea01aaf98de40cff4334075f94a05e0419 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Thu, 27 Feb 2020 20:21:05 +0100 Subject: [PATCH] add --- .../Makefile | 54 ++++++++ .../README.md | 17 +++ .../SensorSerial.ino | 64 +++++++++ .../hardware | 1 + .../libraries/GFX | 1 + .../libraries/SPI | 1 + .../libraries/SSD1306 | 1 + .../libraries/TinyBME280/README.md | 42 ++++++ .../libraries/TinyBME280/TinyBME280.cpp | 130 ++++++++++++++++++ .../libraries/TinyBME280/TinyBME280.h | 37 +++++ .../libraries/TinyWireM | 1 + .../libraries/Wire | 1 + 12 files changed, 350 insertions(+) create mode 100644 841-tinycore-micronucleus-bme280-test/Makefile create mode 100644 841-tinycore-micronucleus-bme280-test/README.md create mode 100644 841-tinycore-micronucleus-bme280-test/SensorSerial.ino create mode 120000 841-tinycore-micronucleus-bme280-test/hardware create mode 120000 841-tinycore-micronucleus-bme280-test/libraries/GFX create mode 120000 841-tinycore-micronucleus-bme280-test/libraries/SPI create mode 120000 841-tinycore-micronucleus-bme280-test/libraries/SSD1306 create mode 100644 841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/README.md create mode 100644 841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/TinyBME280.cpp create mode 100644 841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/TinyBME280.h create mode 120000 841-tinycore-micronucleus-bme280-test/libraries/TinyWireM create mode 120000 841-tinycore-micronucleus-bme280-test/libraries/Wire diff --git a/841-tinycore-micronucleus-bme280-test/Makefile b/841-tinycore-micronucleus-bme280-test/Makefile new file mode 100644 index 0000000..72f1627 --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/Makefile @@ -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) diff --git a/841-tinycore-micronucleus-bme280-test/README.md b/841-tinycore-micronucleus-bme280-test/README.md new file mode 100644 index 0000000..fe21e57 --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/README.md @@ -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) +``` diff --git a/841-tinycore-micronucleus-bme280-test/SensorSerial.ino b/841-tinycore-micronucleus-bme280-test/SensorSerial.ino new file mode 100644 index 0000000..0e96bde --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/SensorSerial.ino @@ -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 +#include + +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); +} + diff --git a/841-tinycore-micronucleus-bme280-test/hardware b/841-tinycore-micronucleus-bme280-test/hardware new file mode 120000 index 0000000..d34e522 --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/hardware @@ -0,0 +1 @@ +/usr/local/arduino/hardware \ No newline at end of file diff --git a/841-tinycore-micronucleus-bme280-test/libraries/GFX b/841-tinycore-micronucleus-bme280-test/libraries/GFX new file mode 120000 index 0000000..4ade844 --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/libraries/GFX @@ -0,0 +1 @@ +/usr/local/esp32/arduino-core/libraries/GFX \ No newline at end of file diff --git a/841-tinycore-micronucleus-bme280-test/libraries/SPI b/841-tinycore-micronucleus-bme280-test/libraries/SPI new file mode 120000 index 0000000..56e807e --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/libraries/SPI @@ -0,0 +1 @@ +/usr/local/arduino/hardware/ATTinyCore/avr/libraries/SPI \ No newline at end of file diff --git a/841-tinycore-micronucleus-bme280-test/libraries/SSD1306 b/841-tinycore-micronucleus-bme280-test/libraries/SSD1306 new file mode 120000 index 0000000..c2d18df --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/libraries/SSD1306 @@ -0,0 +1 @@ +/usr/local/esp32/arduino-core/libraries/SSD1306 \ No newline at end of file diff --git a/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/README.md b/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/README.md new file mode 100644 index 0000000..272776a --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/README.md @@ -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. diff --git a/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/TinyBME280.cpp b/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/TinyBME280.cpp new file mode 100644 index 0000000..ed1f205 --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/TinyBME280.cpp @@ -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; +} \ No newline at end of file diff --git a/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/TinyBME280.h b/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/TinyBME280.h new file mode 100644 index 0000000..2af36ce --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/libraries/TinyBME280/TinyBME280.h @@ -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 +#include +#include + +#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 \ No newline at end of file diff --git a/841-tinycore-micronucleus-bme280-test/libraries/TinyWireM b/841-tinycore-micronucleus-bme280-test/libraries/TinyWireM new file mode 120000 index 0000000..a6a4ed0 --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/libraries/TinyWireM @@ -0,0 +1 @@ +/usr/local/esp32/arduino-core/libraries/TinyWireM \ No newline at end of file diff --git a/841-tinycore-micronucleus-bme280-test/libraries/Wire b/841-tinycore-micronucleus-bme280-test/libraries/Wire new file mode 120000 index 0000000..0211f71 --- /dev/null +++ b/841-tinycore-micronucleus-bme280-test/libraries/Wire @@ -0,0 +1 @@ +/usr/local/arduino/hardware/ATTinyCore/avr/libraries/Wire \ No newline at end of file