mirror of
https://github.com/sascha-hemi/HGD4_reversed.git
synced 2026-03-21 02:03:56 +01:00
Add files via upload
This commit is contained in:
37
HGD4_reversed/include/README
Normal file
37
HGD4_reversed/include/README
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the convention is to give header files names that end with `.h'.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
46
HGD4_reversed/lib/README
Normal file
46
HGD4_reversed/lib/README
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into the executable file.
|
||||
|
||||
The source code of each library should be placed in a separate directory
|
||||
("lib/your_library_name/[Code]").
|
||||
|
||||
For example, see the structure of the following example libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
Example contents of `src/main.c` using Foo and Bar:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries by scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
20
HGD4_reversed/platformio.ini
Normal file
20
HGD4_reversed/platformio.ini
Normal file
@@ -0,0 +1,20 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:nrf52840_dk]
|
||||
platform = nordicnrf52
|
||||
board = nrf52840_dk
|
||||
framework = arduino
|
||||
board_build.variants_dir = variants
|
||||
board_build.variant = hgd6
|
||||
lib_deps =
|
||||
adafruit/Adafruit Unified Sensor@^1.1.15
|
||||
adafruit/Adafruit LIS3DH@^1.3.0
|
||||
sparkfun/SparkFun Ambient Light Sensor Arduino Library@^1.0.4
|
||||
368
HGD4_reversed/src/ens210.cpp
Normal file
368
HGD4_reversed/src/ens210.cpp
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
ens210.cpp - Library for the ENS210 relative humidity and temperature sensor with I2C interface from ams
|
||||
2018 Oct 23 v2 Maarten Pennings Improved begin()
|
||||
2017 Aug 2 v1 Maarten Pennings Created
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include "ens210.h"
|
||||
|
||||
|
||||
// begin() prints errors to help diagnose startup problems.
|
||||
// Change these macro's to empty to suppress those prints.
|
||||
#define PRINTLN Serial.println
|
||||
#define PRINT Serial.print
|
||||
#define PRINTF Serial.printf
|
||||
|
||||
|
||||
// Chip constants
|
||||
#define ENS210_PARTID 0x0210 // The expected part id of the ENS210
|
||||
#define ENS210_BOOTING_MS 2 // Booting time in ms (also after reset, or going to high power)
|
||||
|
||||
// Addresses of the ENS210 registers
|
||||
#define ENS210_REG_PART_ID 0x00
|
||||
#define ENS210_REG_UID 0x04
|
||||
#define ENS210_REG_SYS_CTRL 0x10
|
||||
#define ENS210_REG_SYS_STAT 0x11
|
||||
#define ENS210_REG_SENS_RUN 0x21
|
||||
#define ENS210_REG_SENS_START 0x22
|
||||
#define ENS210_REG_SENS_STOP 0x23
|
||||
#define ENS210_REG_SENS_STAT 0x24
|
||||
#define ENS210_REG_T_VAL 0x30
|
||||
#define ENS210_REG_H_VAL 0x33
|
||||
|
||||
// Division macro (used in conversion functions), implementing integer division with rounding.
|
||||
// It supports both positive and negative dividends (n), but ONLY positive divisors (d).
|
||||
#define IDIV(n,d) ((n)>0 ? ((n)+(d)/2)/(d) : ((n)-(d)/2)/(d))
|
||||
|
||||
|
||||
// 7654 3210
|
||||
// Polynomial 0b 1000 1001 ~ x^7+x^3+x^0
|
||||
// 0x 8 9
|
||||
#define CRC7WIDTH 7 // A 7 bits CRC has polynomial of 7th order, which has 8 terms
|
||||
#define CRC7POLY 0x89 // The 8 coefficients of the polynomial
|
||||
#define CRC7IVEC 0x7F // Initial vector has all 7 bits high
|
||||
// Payload data
|
||||
#define DATA7WIDTH 17
|
||||
#define DATA7MASK ((1UL<<DATA7WIDTH)-1) // 0b 0 1111 1111 1111 1111
|
||||
#define DATA7MSB (1UL<<(DATA7WIDTH-1)) // 0b 1 0000 0000 0000 0000
|
||||
// Compute the CRC-7 of 'val' (should only have 17 bits)
|
||||
// https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Computation
|
||||
static uint32_t crc7( uint32_t val ) {
|
||||
// Setup polynomial
|
||||
uint32_t pol= CRC7POLY;
|
||||
// Align polynomial with data
|
||||
pol = pol << (DATA7WIDTH-CRC7WIDTH-1);
|
||||
// Loop variable (indicates which bit to test, start with highest)
|
||||
uint32_t bit = DATA7MSB;
|
||||
// Make room for CRC value
|
||||
val = val << CRC7WIDTH;
|
||||
bit = bit << CRC7WIDTH;
|
||||
pol = pol << CRC7WIDTH;
|
||||
// Insert initial vector
|
||||
val |= CRC7IVEC;
|
||||
// Apply division until all bits done
|
||||
while( bit & (DATA7MASK<<CRC7WIDTH) ) {
|
||||
if( bit & val ) val ^= pol;
|
||||
bit >>= 1;
|
||||
pol >>= 1;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
// Resets ENS210 and checks its PART_ID. Returns false on I2C problems or wrong PART_ID.
|
||||
// Stores solder correction.
|
||||
bool ENS210::begin(void) {
|
||||
bool ok;
|
||||
uint16_t partid;
|
||||
// Record solder correction
|
||||
_soldercorrection= 0;
|
||||
// Reset
|
||||
ok= reset();
|
||||
if( !ok ) ok= reset(); // Retry
|
||||
if( !ok ) { PRINTLN("ens210: begin: reset failed (ENS210 connected? Wire.begin called?)"); return false; }
|
||||
// Get partid
|
||||
ok= getversion(&partid,NULL);
|
||||
if( !ok ) { PRINTLN("ens210: begin: getversion failed"); return false; }
|
||||
// Check partid
|
||||
if( partid!=ENS210_PARTID ) { PRINT("ens210: begin: PARTID mismatch: "); PRINTLN(partid,HEX); return false; }
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Performs one single shot temperature and relative humidity measurement.
|
||||
void ENS210::measure(int * t_data, int * t_status, int * h_data, int * h_status ) {
|
||||
bool ok;
|
||||
uint32_t t_val;
|
||||
uint32_t h_val;
|
||||
// Set default status for early bail out
|
||||
*t_status= ENS210_STATUS_I2CERROR;
|
||||
*h_status= ENS210_STATUS_I2CERROR;
|
||||
// Start a single shot measurement
|
||||
ok= startsingle(); if(!ok) return; // Both statuses have value ENS210_STATUS_I2CERROR
|
||||
// Wait for measurement to complete
|
||||
delay(ENS210_THCONV_SINGLE_MS);
|
||||
// Get the measurement data
|
||||
ok= read(&t_val,&h_val); if(!ok) return; // Both statuses have value ENS210_STATUS_I2CERROR
|
||||
// Extract the data and update the statuses
|
||||
extract(t_val, t_data, t_status);
|
||||
extract(h_val, h_data, h_status);
|
||||
}
|
||||
|
||||
|
||||
// Sends a reset to the ENS210. Returns false on I2C problems.
|
||||
bool ENS210::reset(void) {
|
||||
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
|
||||
Wire.write(ENS210_REG_SYS_CTRL); // Register address (SYS_CTRL)
|
||||
Wire.write(0x80); // SYS_CTRL: reset
|
||||
int result= Wire.endTransmission(); // STOP
|
||||
//PRINTF("ens210: debug: reset %d\n",result);
|
||||
delay(ENS210_BOOTING_MS); // Wait to boot after reset
|
||||
return result==0;
|
||||
}
|
||||
|
||||
|
||||
// Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems.
|
||||
bool ENS210::lowpower(bool enable) {
|
||||
uint8_t power = enable ? 0x01: 0x00;
|
||||
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
|
||||
Wire.write(ENS210_REG_SYS_CTRL); // Register address (SYS_CTRL)
|
||||
Wire.write(power); // SYS_CTRL: power
|
||||
int result= Wire.endTransmission(); // STOP
|
||||
//PRINTF("ens210: debug: lowpower(%d) %d\n",power,result); // 0:success, 1:data-too-long, 2:NACK-on-addr, 3:NACK-on-data, 4:other
|
||||
delay(ENS210_BOOTING_MS); // Wait boot-time after power switch
|
||||
return result==0;
|
||||
}
|
||||
|
||||
|
||||
// Reads PART_ID and UID of ENS210. Returns false on I2C problems.
|
||||
bool ENS210::getversion(uint16_t*partid,uint64_t*uid) {
|
||||
bool ok;
|
||||
uint8_t i2cbuf[2];
|
||||
int result;
|
||||
|
||||
// Must disable low power to read PART_ID or UID
|
||||
ok= lowpower(false); if(!ok) goto errorexit;
|
||||
|
||||
// Read the PART_ID
|
||||
if( partid!=0 ) {
|
||||
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
|
||||
Wire.write((byte)ENS210_REG_PART_ID); // Register address (PART_ID); using auto increment
|
||||
result= Wire.endTransmission(false); // Repeated START
|
||||
Wire.requestFrom(_slaveaddress,2); // From ENS210, read 2 bytes, STOP
|
||||
//PRINTF("ens210: debug: getversion/part_id %d\n",result);
|
||||
if( result!=0 ) goto errorexit;
|
||||
// Retrieve and pack bytes into partid
|
||||
for( int i=0; i<2; i++ ) i2cbuf[i]= Wire.read();
|
||||
*partid= i2cbuf[1]*256U + i2cbuf[0]*1U;
|
||||
}
|
||||
|
||||
// Read the UID
|
||||
if( uid!=0 ) {
|
||||
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
|
||||
Wire.write(ENS210_REG_UID); // Register address (UID); using auto increment
|
||||
result= Wire.endTransmission(false); // Repeated START
|
||||
Wire.requestFrom(_slaveaddress,8); // From ENS210, read 8 bytes, STOP
|
||||
//PRINTF("ens210: debug: getversion/uid %d\n",result);
|
||||
if( result!=0 ) goto errorexit;
|
||||
// Retrieve and pack bytes into uid (ignore the endianness)
|
||||
for( int i=0; i<8; i++) ((uint8_t*)uid)[i]=Wire.read();
|
||||
}
|
||||
|
||||
// Go back to default power mode (low power enabled)
|
||||
ok= lowpower(true); if(!ok) goto errorexit;
|
||||
|
||||
// { uint32_t hi= *uid >>32, lo= *uid & 0xFFFFFFFF; PRINTF("ens210: debug: PART_ID=%04x UID=%08x %08x\n",*partid,hi,lo); }
|
||||
// Success
|
||||
return true;
|
||||
|
||||
errorexit:
|
||||
// Try to go back to default mode (low power enabled)
|
||||
ok= lowpower(true);
|
||||
// Hopefully enabling low power was successful; but there was an error before that anyhow
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Configures ENS210 to perform a single measurement. Returns false on I2C problems.
|
||||
bool ENS210::startsingle(void) {
|
||||
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
|
||||
Wire.write(ENS210_REG_SENS_RUN); // Register address (SENS_RUN); using auto increment
|
||||
Wire.write((byte)0x00); // SENS_RUN : T_RUN=0/single , H_RUN=0/single
|
||||
Wire.write(0x03); // SENS_START: T_START=1/start, H_START=1/start
|
||||
int result= Wire.endTransmission(); // STOP
|
||||
//PRINTF("ens210: debug: startsingle %d\n",result);
|
||||
return result==0;
|
||||
}
|
||||
|
||||
|
||||
// Configures ENS210 to switch to continuous measurement. Returns false on I2C problems.
|
||||
bool ENS210::startcont(void) {
|
||||
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
|
||||
Wire.write(ENS210_REG_SENS_RUN); // Register address (SENS_RUN); using auto increment
|
||||
Wire.write(0x03); // SENS_RUN : T_RUN=1/cont , H_RUN=1/cont
|
||||
Wire.write(0x03); // SENS_START: T_START=1/start, H_START=1/start
|
||||
int result= Wire.endTransmission(); // STOP
|
||||
//PRINTF("ens210: debug: startcont %d\n",result);
|
||||
return result==0;
|
||||
}
|
||||
|
||||
|
||||
// Configures ENS210 to stop continuous measurement. Returns false on I2C problems.
|
||||
bool ENS210::stopcont(void) {
|
||||
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
|
||||
Wire.write(ENS210_REG_SENS_STOP); // Register address (SENS_STOP)
|
||||
Wire.write(0x03); // SENS_START: T_STOP=1/start, H_STOP=1/start
|
||||
int result= Wire.endTransmission(); // STOP
|
||||
//PRINTF("ens210: debug: stopcont %d\n",result);
|
||||
return result==0;
|
||||
}
|
||||
|
||||
|
||||
// Reads measurement data from the ENS210. Returns false on I2C problems.
|
||||
bool ENS210::read(uint32_t *t_val, uint32_t *h_val) {
|
||||
uint8_t i2cbuf[6];
|
||||
// Read T_VAL and H_VAL
|
||||
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
|
||||
Wire.write(ENS210_REG_T_VAL); // Register address (T_VAL); using auto increment (up to H_VAL)
|
||||
int result= Wire.endTransmission(false); // Repeated START
|
||||
Wire.requestFrom(_slaveaddress,6); // From ENS210, read 6 bytes, STOP
|
||||
//PRINTF("ens210: debug: read %d\n",result);
|
||||
if( result!=0 ) return false;
|
||||
// Retrieve and pack bytes into t_val and h_val
|
||||
for( int i=0; i<6; i++ ) i2cbuf[i]= Wire.read();
|
||||
*t_val= (i2cbuf[2]*65536UL) + (i2cbuf[1]*256UL) + (i2cbuf[0]*1UL);
|
||||
*h_val= (i2cbuf[5]*65536UL) + (i2cbuf[4]*256UL) + (i2cbuf[3]*1UL);
|
||||
// Range checking
|
||||
//PRINTF("ens210: debug: read T=%06x H=%06x\n",*t_val,*h_val);
|
||||
//if( *t_val<(273-100)*64 || *t_val>(273+150)*64 ) return false; // Accept only readouts -100<=T_in_C<=+150 (arbitrary limits)
|
||||
//if( *h_val>100*512 ) return false; // Accept only readouts 0<=H<=100
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Reads measurement data from the ENS210 and extracts data and status.
|
||||
void ENS210::read(int*t_data,int*t_status,int*h_data,int*h_status) {
|
||||
uint32_t t_val;
|
||||
uint32_t h_val;
|
||||
// Get the measurement data
|
||||
bool ok=read(&t_val,&h_val);
|
||||
if( !ok ) {
|
||||
// Signal I2C error
|
||||
*t_status= ENS210_STATUS_I2CERROR;
|
||||
*h_status= ENS210_STATUS_I2CERROR;
|
||||
} else {
|
||||
// Extract the data and update the statuses
|
||||
extract(t_val, t_data, t_status);
|
||||
extract(h_val, h_data, h_status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Extracts measurement `data` and `status` from a `val` obtained from `read`.
|
||||
// Upon entry, 'val' is the 24 bits read from T_VAL or H_VAL.
|
||||
// Upon exit, 'data' is the T_DATA or H_DATA, and 'status' one of ENS210_STATUS_XXX.
|
||||
void ENS210::extract(uint32_t val, int * data, int * status) {
|
||||
// Destruct 'val'
|
||||
* data = (val>>0 ) & 0xffff;
|
||||
int valid = (val>>16) & 0x1;
|
||||
uint32_t crc = (val>>17) & 0x7f;
|
||||
uint32_t payload = (val>>0 ) & 0x1ffff;
|
||||
int crc_ok= crc7(payload)==crc;
|
||||
// Check CRC and valid bit
|
||||
if( !crc_ok ) *status= ENS210_STATUS_CRCERROR;
|
||||
else if( !valid ) *status= ENS210_STATUS_INVALID;
|
||||
else *status= ENS210_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Converts a status (ENS210_STATUS_XXX) to a human readable string.
|
||||
const char * ENS210::status_str( int status ) {
|
||||
switch( status ) {
|
||||
case ENS210_STATUS_I2CERROR : return "i2c-error";
|
||||
case ENS210_STATUS_CRCERROR : return "crc-error";
|
||||
case ENS210_STATUS_INVALID : return "data-invalid";
|
||||
case ENS210_STATUS_OK : return "ok";
|
||||
default : return "unknown-status";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Convert raw `t_data` temperature to Kelvin (also applies the solder correction).
|
||||
// The output value is in Kelvin multiplied by parameter `multiplier`.
|
||||
int32_t ENS210::toKelvin(int t_data, int multiplier) {
|
||||
assert( (1<=multiplier) && (multiplier<=1024) );
|
||||
// Force 32 bits
|
||||
int32_t t= t_data & 0xFFFF;
|
||||
// Compensate for soldering effect
|
||||
t-= _soldercorrection;
|
||||
// Return m*K. This equals m*(t/64) = (m*t)/64
|
||||
// Note m is the multiplier, K is temperature in Kelvin, t is raw t_data value.
|
||||
// Uses K=t/64.
|
||||
return IDIV(multiplier*t,64);
|
||||
}
|
||||
|
||||
|
||||
// Convert raw `t_data` temperature to Celsius (also applies the solder correction).
|
||||
// The output value is in Celsius multiplied by parameter `multiplier`.
|
||||
int32_t ENS210::toCelsius(int t_data, int multiplier) {
|
||||
assert( (1<=multiplier) && (multiplier<=1024) );
|
||||
// Force 32 bits
|
||||
int32_t t= t_data & 0xFFFF;
|
||||
// Compensate for soldering effect
|
||||
t-= _soldercorrection;
|
||||
// Return m*C. This equals m*(K-273.15) = m*K - 27315*m/100 = m*t/64 - 27315*m/100
|
||||
// Note m is the multiplier, C is temperature in Celsius, K is temperature in Kelvin, t is raw t_data value.
|
||||
// Uses C=K-273.15 and K=t/64.
|
||||
return IDIV(multiplier*t,64) - IDIV(27315L*multiplier,100);
|
||||
}
|
||||
|
||||
|
||||
// Convert raw `t_data` temperature to Fahrenheit (also applies the solder correction).
|
||||
// The output value is in Fahrenheit multiplied by parameter `multiplier`.
|
||||
int32_t ENS210::toFahrenheit(int t_data, int multiplier) {
|
||||
assert( (1<=multiplier) && (multiplier<=1024) );
|
||||
// Force 32 bits
|
||||
int32_t t= t_data & 0xFFFF;
|
||||
// Compensate for soldering effect
|
||||
t-= _soldercorrection;
|
||||
// Return m*F. This equals m*(1.8*(K-273.15)+32) = m*(1.8*K-273.15*1.8+32) = 1.8*m*K-459.67*m = 9*m*K/5 - 45967*m/100 = 9*m*t/320 - 45967*m/100
|
||||
// Note m is the multiplier, F is temperature in Fahrenheit, K is temperature in Kelvin, t is raw t_data value.
|
||||
// Uses F=1.8*(K-273.15)+32 and K=t/64.
|
||||
return IDIV(9*multiplier*t,320) - IDIV(45967L*multiplier,100);
|
||||
// The first multiplication stays below 32 bits (t:16, multiplier:11, 9:4)
|
||||
// The second multiplication stays below 32 bits (multiplier:10, 45967:16)
|
||||
}
|
||||
|
||||
|
||||
// Convert raw `h_data` relative humidity to %RH.
|
||||
// The output value is in %RH multiplied by parameter `multiplier`.
|
||||
int32_t ENS210::toPercentageH(int h_data, int multiplier) {
|
||||
assert( (1<=multiplier) && (multiplier<=1024) );
|
||||
// Force 32 bits
|
||||
int32_t h= h_data & 0xFFFF;
|
||||
// Return m*H. This equals m*(h/512) = (m*h)/512
|
||||
// Note m is the multiplier, H is the relative humidity in %RH, h is raw h_data value.
|
||||
// Uses H=h/512.
|
||||
return IDIV(multiplier*h, 512);
|
||||
}
|
||||
|
||||
|
||||
// Sets the solder correction (default is 50mK) - only used by the `toXxx` functions.
|
||||
void ENS210::correction_set(int correction) {
|
||||
assert( -1*64<correction && correction<+1*64 ); // A correction of more than 1 Kelvin does not make sense (but the 1K is arbitrary)
|
||||
_soldercorrection = correction;
|
||||
}
|
||||
|
||||
|
||||
// Gets the solder correction
|
||||
int ENS210::correction_get(void) {
|
||||
return _soldercorrection;
|
||||
}
|
||||
|
||||
69
HGD4_reversed/src/ens210.h
Normal file
69
HGD4_reversed/src/ens210.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
ens210.h - Library for the ENS210 relative humidity and temperature sensor with I2C interface from ams
|
||||
Created by Maarten Pennings 2017 Aug 1
|
||||
*/
|
||||
#ifndef __ENS210_H_
|
||||
#define __ENS210_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// Measurement status as output by `measure()` and `extract()`.
|
||||
// Note that the ENS210 provides a "value" (`t_val` or `h_val` each 24 bit).
|
||||
// A "value" consists of a payload (17 bit) and a CRC (7 bit) over that payload.
|
||||
// The payload consists of a valid flag (1 bit) and the actual measurement "data" (`t_data` or `h_data`, 16 bit)
|
||||
#define ENS210_STATUS_I2CERROR 4 // There was an I2C communication error, `read`ing the value.
|
||||
#define ENS210_STATUS_CRCERROR 3 // The value was read, but the CRC over the payload (valid and data) does not match.
|
||||
#define ENS210_STATUS_INVALID 2 // The value was read, the CRC matches, but the data is invalid (e.g. the measurement was not yet finished).
|
||||
#define ENS210_STATUS_OK 1 // The value was read, the CRC matches, and data is valid.
|
||||
|
||||
// Chip constants
|
||||
#define ENS210_THCONV_SINGLE_MS 130 // Conversion time in ms for single shot T/H measurement
|
||||
#define ENS210_THCONV_CONT_MS 238 // Conversion time in ms for continuous T/H measurement
|
||||
|
||||
class ENS210 {
|
||||
public: // Main API functions
|
||||
// Resets ENS210 and checks its PART_ID. Returns false on I2C problems or wrong PART_ID.
|
||||
bool begin(void);
|
||||
// Performs one single shot temperature and relative humidity measurement.
|
||||
// Sets `t_data` (temperature in 1/64K), and `t_status` (from ENS210STATUS_XXX).
|
||||
// Sets `h_data` (relative humidity in 1/512 %RH), and `h_status` (from ENS210STATUS_XXX).
|
||||
// Use the conversion functions below to convert `t_data` to K, C, F; or `h_data` to %RH.
|
||||
// Note that this function contains a delay of 130ms to wait for the measurement to complete.
|
||||
// If you don't want that, use startsingle() ... wait ENS210_THCONVERSION_MS ... read().
|
||||
void measure(int * t_data, int * t_status, int * h_data, int * h_status );
|
||||
|
||||
public: // Conversion functions - the temperature conversions also subtract the solder correction (see correction_set() method).
|
||||
int32_t toKelvin (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Kelvin
|
||||
int32_t toCelsius (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Celsius
|
||||
int32_t toFahrenheit (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Fahrenheit
|
||||
int32_t toPercentageH(int h_data, int multiplier); // Converts h_data (from `measure`) to 1/multiplier %RH
|
||||
|
||||
// Optionally set a solder `correction` (units: 1/64K, default from `begin` is 0).
|
||||
// See "Effect of Soldering on Temperature Readout" in "Design-Guidelines" from
|
||||
// https://download.ams.com/ENVIRONMENTAL-SENSORS/ENS210/Documentation
|
||||
void correction_set(int correction=50*64/1000); // Sets the solder correction (default is 50mK) - only used by the `toXxx()` functions.
|
||||
int correction_get(void); // Gets the solder correction.
|
||||
|
||||
public: // Helper functions (communicating with ENS210)
|
||||
bool reset(void); // Sends a reset to the ENS210. Returns false on I2C problems.
|
||||
bool lowpower(bool enable); // Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems.
|
||||
bool getversion(uint16_t*partid,uint64_t*uid); // Reads PART_ID and UID of ENS210. Returns false on I2C problems.
|
||||
bool startsingle(void); // Configures ENS210 to perform one single shot measurement. Returns false on I2C problems.
|
||||
bool startcont(void); // Configures ENS210 to switch to continuous measurement. Returns false on I2C problems.
|
||||
bool stopcont(void); // Configures ENS210 to stop continuous measurement. Returns false on I2C problems.
|
||||
bool read(uint32_t*t_val,uint32_t*h_val); // Reads measurement data from the ENS210. Returns false on I2C problems.
|
||||
void read(int*t_data,int*t_status,int*h_data,int*h_status); // Reads measurement data from the ENS210 and extracts data and status.
|
||||
|
||||
public: // Helper functions (data conversion)
|
||||
static void extract(uint32_t val,int*data,int*status); // Extracts measurement `data` and `status` from a `val` obtained from `read()`.
|
||||
static const char * status_str( int status ); // Converts a status (ENS210_STATUS_XXX) to a human readable string.
|
||||
|
||||
protected: // Data members
|
||||
int _slaveaddress= 0x43; // Slave address of ENS210
|
||||
int _soldercorrection; // Correction due to soldering (in 1/64K); subtracted from `t_data` by conversion functions.
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
166
HGD4_reversed/src/main.cpp
Normal file
166
HGD4_reversed/src/main.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include "ens210.h" // ENS210 library
|
||||
#include "SparkFun_VEML6030_Ambient_Light_Sensor.h"
|
||||
#include <SPI.h>
|
||||
#include <Adafruit_LIS3DH.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
|
||||
#define LIS3DH_CS 6
|
||||
|
||||
#define AL_ADDR 0x29
|
||||
|
||||
SparkFun_Ambient_Light light(AL_ADDR);
|
||||
|
||||
ENS210 ens210;
|
||||
|
||||
Adafruit_LIS3DH lis = Adafruit_LIS3DH(LIS3DH_CS);
|
||||
|
||||
void testallpins();
|
||||
void test1pin(int i,int d);
|
||||
void busscan();
|
||||
void measuretemp();
|
||||
void lightsense();
|
||||
|
||||
void in1_handler() {
|
||||
digitalWrite(10,HIGH);
|
||||
delay(1);
|
||||
digitalWrite(10,LOW);
|
||||
delay(1);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
//latch on the main power
|
||||
pinMode(2, OUTPUT);
|
||||
digitalWrite(2, HIGH);
|
||||
//setup watchdog feeding
|
||||
pinMode(10, OUTPUT);
|
||||
pinMode(9, INPUT);
|
||||
attachInterrupt(digitalPinToInterrupt(9), in1_handler, RISING);
|
||||
//setup Serial
|
||||
Serial.begin(115200);
|
||||
//setup I2C bus
|
||||
Wire.begin();
|
||||
//set i2c pins
|
||||
pinMode(15, OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.println("loop");
|
||||
busscan();
|
||||
measuretemp();
|
||||
lightsense();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void test1pin(int i,int d){
|
||||
Serial.println("Testing Pin with number");
|
||||
Serial.println(i);
|
||||
pinMode(i, OUTPUT);
|
||||
for (size_t j = 0; j < 100; j++)
|
||||
{
|
||||
delay(d);
|
||||
digitalWrite(i, HIGH);
|
||||
delay(d);
|
||||
digitalWrite(i, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void lightsense(){
|
||||
|
||||
// Possible values: .125, .25, 1, 2
|
||||
// Both .125 and .25 should be used in most cases except darker rooms.
|
||||
// A gain of 2 should only be used if the sensor will be covered by a dark
|
||||
// glass.
|
||||
float gain = .125;
|
||||
|
||||
// Possible integration times in milliseconds: 800, 400, 200, 100, 50, 25
|
||||
// Higher times give higher resolutions and should be used in darker light.
|
||||
int time = 100;
|
||||
long luxVal = 0;
|
||||
if(light.begin())
|
||||
Serial.println("Ready to sense some light!");
|
||||
else
|
||||
Serial.println("Could not communicate with the sensor!");
|
||||
|
||||
// Again the gain and integration times determine the resolution of the lux
|
||||
// value, and give different ranges of possible light readings. Check out
|
||||
// hoookup guide for more info.
|
||||
light.setGain(gain);
|
||||
light.setIntegTime(time);
|
||||
|
||||
Serial.println("Reading settings...");
|
||||
Serial.print("Gain: ");
|
||||
float gainVal = light.readGain();
|
||||
Serial.print(gainVal, 3);
|
||||
Serial.print(" Integration Time: ");
|
||||
int timeVal = light.readIntegTime();
|
||||
Serial.println(timeVal);
|
||||
luxVal = light.readLight();
|
||||
Serial.print("Ambient Light Reading: ");
|
||||
Serial.print(luxVal);
|
||||
Serial.println(" Lux");
|
||||
}
|
||||
|
||||
void measuretemp(){
|
||||
ens210.begin();
|
||||
int t_data, t_status, h_data, h_status;
|
||||
ens210.measure(&t_data, &t_status, &h_data, &h_status );
|
||||
|
||||
Serial.print( ens210.toCelsius(t_data,10)/10.0, 1 ); Serial.print(" C, ");
|
||||
Serial.print( ens210.toPercentageH(h_data,1) ); Serial.print(" %RH");
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
|
||||
void busscan(){
|
||||
byte error, address;
|
||||
int nDevices;
|
||||
|
||||
Serial.println("Scanning...");
|
||||
|
||||
nDevices = 0;
|
||||
for(address = 1; address < 127; address++ )
|
||||
{
|
||||
// The i2c_scanner uses the return value of
|
||||
// the Write.endTransmisstion to see if
|
||||
// a device did acknowledge to the address.
|
||||
Wire.beginTransmission(address);
|
||||
error = Wire.endTransmission();
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
Serial.print("I2C device found at address 0x");
|
||||
if (address<16)
|
||||
Serial.print("0");
|
||||
Serial.print(address,HEX);
|
||||
Serial.println(" !");
|
||||
|
||||
nDevices++;
|
||||
}
|
||||
else if (error==4)
|
||||
{
|
||||
Serial.print("Unknown error at address 0x");
|
||||
if (address<16)
|
||||
Serial.print("0");
|
||||
Serial.println(address,HEX);
|
||||
}
|
||||
}
|
||||
if (nDevices == 0)
|
||||
Serial.println("No I2C devices found\n");
|
||||
else
|
||||
Serial.println("done\n");
|
||||
}
|
||||
|
||||
void testallpins(){
|
||||
for (size_t i = 0; i < 64; i++){
|
||||
if(i != 2 && i != 29){
|
||||
Serial.println(String(i));
|
||||
pinMode(i, OUTPUT);
|
||||
digitalWrite(i, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(i, LOW);
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
HGD4_reversed/test/README
Normal file
11
HGD4_reversed/test/README
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
17
HGD4_reversed/variants/hgd6/pins_arduino.h
Normal file
17
HGD4_reversed/variants/hgd6/pins_arduino.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// API compatibility
|
||||
#include "variant.h"
|
||||
89
HGD4_reversed/variants/hgd6/variant.cpp
Normal file
89
HGD4_reversed/variants/hgd6/variant.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "variant.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[] = {
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
#if GPIO_COUNT > 1
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
58,
|
||||
59,
|
||||
60,
|
||||
61,
|
||||
62,
|
||||
63,
|
||||
#endif
|
||||
};
|
||||
116
HGD4_reversed/variants/hgd6/variant.h
Normal file
116
HGD4_reversed/variants/hgd6/variant.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _VARIANT_GENERIC_
|
||||
#define _VARIANT_GENERIC_
|
||||
|
||||
#include "nrf.h"
|
||||
#include "nrf_peripherals.h"
|
||||
|
||||
/** Master clock frequency */
|
||||
#if defined(NRF52_SERIES)
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
#else
|
||||
#define VARIANT_MCK (16000000ul)
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
// Number of pins defined in PinDescription array
|
||||
#if GPIO_COUNT == 1
|
||||
#define PINS_COUNT (32u)
|
||||
#define NUM_DIGITAL_PINS (32u)
|
||||
#elif GPIO_COUNT == 2
|
||||
#define PINS_COUNT (64u)
|
||||
#define NUM_DIGITAL_PINS (64u)
|
||||
#else
|
||||
#error "Unsupported GPIO_COUNT"
|
||||
#endif
|
||||
#define NUM_ANALOG_INPUTS (6u)
|
||||
#define NUM_ANALOG_OUTPUTS (0u)
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (13) // P0.13
|
||||
#define LED_BUILTIN PIN_LED
|
||||
|
||||
/*
|
||||
* Analog pins
|
||||
*/
|
||||
#define PIN_A0 (1) // P0.01
|
||||
#define PIN_A1 (2) // P0.02
|
||||
#define PIN_A2 (3) // P0.03
|
||||
#define PIN_A3 (4) // P0.04
|
||||
#define PIN_A4 (5) // P0.05
|
||||
#define PIN_A5 (6) // P0.06
|
||||
|
||||
static const uint8_t A0 = PIN_A0 ;
|
||||
static const uint8_t A1 = PIN_A1 ;
|
||||
static const uint8_t A2 = PIN_A2 ;
|
||||
static const uint8_t A3 = PIN_A3 ;
|
||||
static const uint8_t A4 = PIN_A4 ;
|
||||
static const uint8_t A5 = PIN_A5 ;
|
||||
#if defined(NRF52_SERIES)
|
||||
#define ADC_RESOLUTION 14
|
||||
#else
|
||||
#define ADC_RESOLUTION 10
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
// Serial
|
||||
#define PIN_SERIAL_RX (17) // P0.00
|
||||
#define PIN_SERIAL_TX (22) // P0.01
|
||||
|
||||
/*
|
||||
* SPI Interfaces
|
||||
*/
|
||||
#define SPI_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_SPI_MISO (12) // P0.22
|
||||
#define PIN_SPI_MOSI (41) // P0.23
|
||||
#define PIN_SPI_SCK (24) // P0.24
|
||||
|
||||
static const uint8_t SS = 25 ; // P0.25
|
||||
static const uint8_t MOSI = PIN_SPI_MOSI ;
|
||||
static const uint8_t MISO = PIN_SPI_MISO ;
|
||||
static const uint8_t SCK = PIN_SPI_SCK ;
|
||||
|
||||
/*
|
||||
* Wire Interfaces
|
||||
*/
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_WIRE_SDA (15)
|
||||
#define PIN_WIRE_SCL (13)
|
||||
|
||||
static const uint8_t SDA = PIN_WIRE_SDA;
|
||||
static const uint8_t SCL = PIN_WIRE_SCL;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user