├── Cicada ├── Cicada.v07 │ ├── BMA280.cpp │ ├── BMA280.h │ ├── BME280.cpp │ ├── BME280.h │ ├── Cicada.v07.ino │ ├── SPIFlash.cpp │ ├── SPIFlash.h │ ├── VEML6040.cpp │ └── VEML6040.h ├── eraseSPIFlash_Cicada ├── readSPIFlash_Cicada │ ├── BME280.cpp │ ├── BME280.h │ ├── SPIFlash.cpp │ ├── SPIFlash.h │ └── readSPIFlash_Cicada.ino └── testSPIFlash_Cicada │ ├── SPIFlash.cpp │ ├── SPIFlash.h │ └── testSPIFlash_Cicada.ino ├── CricketAssetTracker ├── AssetTracker_Cricket.v02 │ ├── AssetTracker_Cricket.v02.ino │ ├── BMA280.cpp │ ├── BMA280.h │ ├── BME280.cpp │ ├── BME280.h │ ├── Readme.md │ ├── SPIFlash.cpp │ └── SPIFlash.h ├── AssetTracker_Cricket │ ├── BMA280.cpp │ ├── BMA280.h │ ├── BME280.cpp │ ├── BME280.h │ ├── Examples │ │ └── AssetTracker_Cricket.v04.ino │ ├── Readme.md │ ├── SPIFlash.cpp │ └── SPIFlash.h ├── Blink_Cricket.ino ├── GNSS_externl_test.ino ├── I2CScan_Cricket.ino ├── Readme.md ├── SPIFlash_Cricket.ino └── readSPIFlash_CricketAssetTracker │ ├── SPIFlash.cpp │ ├── SPIFlash.h │ └── readSPIFlash_CricketAssetTracker.ino ├── GasCap ├── AssetTracker_GasCap_v.02e │ ├── AssetTracker_GasCap_v.02e.ino │ ├── BME280.cpp │ ├── BME280.h │ ├── I2Cdev.cpp │ ├── I2Cdev.h │ ├── LIS2DW12.cpp │ ├── LIS2DW12.h │ ├── SPIFlash.cpp │ └── SPIFlash.h ├── GasCap.v01f.schematics.pdf ├── GasCap.v02f.BOM.csv ├── GasCap.v02f.step ├── Readme.md ├── SPIFlash_Test_GasCap.ino └── readSPIFlash_GasCapAssetTracker │ ├── SPIFlash.cpp │ ├── SPIFlash.h │ └── readSPIFlash_GasCapAssetTracker.ino ├── Gnat ├── AssetTracker_Gnat.v02.ino ├── AssetTracker_Gnat.v03d │ ├── AssetTracker_Gnat.v03d.ino │ ├── Gnat.03d.schematics.pdf │ ├── Gnat.v03d.step │ ├── I2Cdev.cpp │ ├── I2Cdev.h │ ├── LIS2DW12.cpp │ ├── LIS2DW12.h │ └── readme.md ├── BMA400.cpp ├── BMA400.h └── Readme.md ├── Grasshopper ├── BlinkLEDPWM.ino ├── Blink_Grasshopper.ino ├── DAC_ADC_Grasshopper.ino ├── I2CslaveGrasshopper │ ├── Grasshopper_Wire_Slave.ino │ ├── Master_I2C_Dragonfly.ino │ └── Readme.md ├── LSM6DSM_LIS2MDL_LPS22HB_Grasshopper │ ├── LIS2MDL.cpp │ ├── LIS2MDL.h │ ├── LPS22HB.cpp │ ├── LPS22HB.h │ ├── LSM6DSM.cpp │ ├── LSM6DSM.h │ ├── MadgwickFilter.ino │ ├── Readme.md │ └── examples │ │ └── LSM6DSM_LIS2MDL_LPS22HB_Grasshopper.ino ├── LoRaWAN_GetDevEUI.ino ├── LoRaWANtest.ino ├── RTC_Grasshopper.ino ├── Readme.md └── sharpmemtest_Grasshopper.ino ├── LoRaSensorTile ├── Blink_LoRaSensorTile.ino ├── LoRaSensorTile.v02 │ ├── BMA280.cpp │ ├── BMA280.h │ ├── BME280.cpp │ ├── BME280.h │ ├── LoRaSensorTile.v02.ino │ ├── Readme.md │ ├── SPIFlashClass.cpp │ ├── SPIFlashClass.h │ ├── VEML6040.cpp │ └── VEML6040.h ├── LoRaSensorTile.v05 │ ├── BMA280.cpp │ ├── BMA280.h │ ├── BME280.cpp │ ├── BME280.h │ ├── LoRaSensorTile.v05.ino │ ├── Readme.md │ ├── SPIFlashClass.cpp │ ├── SPIFlashClass.h │ ├── VEML6040.cpp │ └── VEML6040.h ├── LoRaWANtest.ino ├── Readme.md └── readSPIFlash_LoRaSensorTile.ino ├── README.md ├── SBUS Grasshopper - En.pdf ├── TurtleTracker ├── AssetTracker_IoT_Cricket │ ├── AssetTracker_IoT_Cricket.ino │ ├── I2CDev.cpp │ ├── I2CDev.h │ ├── LIS2MDL.cpp │ ├── LIS2MDL.h │ ├── LSM303AGR.cpp │ ├── LSM303AGR.h │ ├── MS5803.cpp │ ├── MS5803.h │ ├── MS5837.cpp │ ├── MS5837.h │ ├── SPIFlash.cpp │ ├── SPIFlash.h │ ├── VEML6030.cpp │ └── VEML6030.h └── Readme.md ├── longCricketAssetTracker ├── AssetTracker_longCricket.v04i │ ├── AssetTracker_longCricket.v04i.ino │ ├── BMA400.cpp │ ├── BMA400.h │ ├── BME280.cpp │ ├── BME280.h │ ├── SPIFlash.cpp │ └── SPIFlash.h └── Readme.md └── privateCore ├── Readme.md └── STM32L0.zip /Cicada/Cicada.v07/BMA280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | * The BMA280 is an inexpensive (~$1), three-axis, high-resolution (14-bit) acclerometer in a tiny 2 mm x 2 mm LGA12 package with 32-slot FIFO, 6 | * two multifunction interrupts and widely configurable sample rate (15 - 2000 Hz), full range (2 - 16 g), low power modes, 7 | * and interrupt detection behaviors. This accelerometer is nice choice for low-frequency sound and vibration analysis, 8 | * tap detection and simple orientation estimation. 9 | * 10 | * Library may be used freely and without limit with attribution. 11 | * 12 | */ 13 | 14 | #ifndef BMA280_h 15 | #define BMA280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* Register Map BMA280 21 | // http://www.mouser.com/ds/2/783/BST-BMA280-DS000-11_published-786496.pdf 22 | */ 23 | #define BMA280_BGW_CHIPID 0x00 24 | #define BMA280_ACCD_X_LSB 0x02 25 | #define BMA280_ACCD_X_MSB 0x03 26 | #define BMA280_ACCD_Y_LSB 0x04 27 | #define BMA280_ACCD_Y_MSB 0x05 28 | #define BMA280_ACCD_Z_LSB 0x06 29 | #define BMA280_ACCD_Z_MSB 0x07 30 | #define BMA280_ACCD_TEMP 0x08 31 | #define BMA280_INT_STATUS_0 0x09 32 | #define BMA280_INT_STATUS_1 0x0A 33 | #define BMA280_INT_STATUS_2 0x0B 34 | #define BMA280_INT_STATUS_3 0x0C 35 | #define BMA280_FIFO_STATUS 0x0E 36 | #define BMA280_PMU_RANGE 0x0F 37 | #define BMA280_PMU_BW 0x10 38 | #define BMA280_PMU_LPW 0x11 39 | #define BMA280_PMU_LOW_POWER 0x12 40 | #define BMA280_ACCD_HBW 0x13 41 | #define BMA280_BGW_SOFTRESET 0x14 42 | #define BMA280_INT_EN_0 0x16 43 | #define BMA280_INT_EN_1 0x17 44 | #define BMA280_INT_EN_2 0x18 45 | #define BMA280_INT_MAP_0 0x19 46 | #define BMA280_INT_MAP_1 0x1A 47 | #define BMA280_INT_MAP_2 0x1B 48 | #define BMA280_INT_SRC 0x1E 49 | #define BMA280_INT_OUT_CTRL 0x20 50 | #define BMA280_INT_RST_LATCH 0x21 51 | #define BMA280_INT_0 0x22 52 | #define BMA280_INT_1 0x23 53 | #define BMA280_INT_2 0x24 54 | #define BMA280_INT_3 0x25 55 | #define BMA280_INT_4 0x26 56 | #define BMA280_INT_5 0x27 57 | #define BMA280_INT_6 0x28 58 | #define BMA280_INT_7 0x29 59 | #define BMA280_INT_8 0x2A 60 | #define BMA280_INT_9 0x2B 61 | #define BMA280_INT_A 0x2C 62 | #define BMA280_INT_B 0x2D 63 | #define BMA280_INT_C 0x2E 64 | #define BMA280_INT_D 0x2F 65 | #define BMA280_FIFO_CONFIG_0 0x30 66 | #define BMA280_PMU_SELF_TEST 0x32 67 | #define BMA280_TRIM_NVM_CTRL 0x33 68 | #define BMA280_BGW_SPI3_WDT 0x34 69 | #define BMA280_OFC_CTRL 0x36 70 | #define BMA280_OFC_SETTING 0x37 71 | #define BMA280_OFC_OFFSET_X 0x38 72 | #define BMA280_OFC_OFFSET_Y 0x39 73 | #define BMA280_OFC_OFFSET_Z 0x3A 74 | #define BMA280_TRIM_GP0 0x3B 75 | #define BMA280_TRIM_GP1 0x3C 76 | #define BMA280_FIFO_CONFIG_1 0x3E 77 | #define BMA280_FIFO_DATA 0x3F 78 | 79 | #define BMA280_ADDRESS 0x18 // if ADO is 0 (default) 80 | 81 | #define AFS_2G 0x03 82 | #define AFS_4G 0x05 83 | #define AFS_8G 0x08 84 | #define AFS_16G 0x0C 85 | 86 | #define BW_7_81Hz 0x08 // 15.62 Hz sample rate, etc 87 | #define BW_15_63Hz 0x09 88 | #define BW_31_25Hz 0x0A 89 | #define BW_62_5Hz 0x0B 90 | #define BW_125Hz 0x0C // 250 Hz sample rate 91 | #define BW_250Hz 0x0D 92 | #define BW_500Hz 0x0E 93 | #define BW_1000Hz 0x0F // 2 kHz sample rate == unfiltered data 94 | 95 | #define normal_Mode 0x00 //define power modes 96 | #define deepSuspend_Mode 0x01 97 | #define lowPower_Mode 0x02 98 | #define suspend_Mode 0x04 99 | 100 | #define lp_mode_1 0x00 // two types of low power mode 101 | #define lp_mode_2 0x40 102 | 103 | #define sleep_0_5ms 0x05 // define sleep duration in low power modes 104 | #define sleep_1ms 0x06 105 | #define sleep_2ms 0x07 106 | #define sleep_4ms 0x08 107 | #define sleep_6ms 0x09 108 | #define sleep_10ms 0x0A 109 | #define sleep_25ms 0x0B 110 | #define sleep_50ms 0x0C 111 | #define sleep_100ms 0x0D 112 | #define sleep_500ms 0x0E 113 | #define sleep_1000ms 0x0F 114 | 115 | class BMA280 116 | { 117 | public: 118 | BMA280(uint8_t intPin1, uint8_t intPin2); 119 | float getAres(uint8_t Ascale); 120 | uint8_t getChipID(); 121 | uint8_t getTapType(); 122 | uint8_t getTapStatus(); 123 | void initBMA280(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, uint8_t sleep_dur); 124 | void initBMA280_MotionManager(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, 125 | uint8_t sleep_dur, uint8_t low_power_Mode, 126 | uint8_t motion_threshold); 127 | void activateNoMotionInterrupt(); 128 | void deactivateNoMotionInterrupt(); 129 | void activateSlopeInterrupt(); 130 | void deactivateSlopeInterrupt(); 131 | void fastCompensationBMA280(); 132 | void resetBMA280(); 133 | void selfTestBMA280(); 134 | void readBMA280AccelData(int16_t * destination); 135 | int16_t readBMA280TempData(); 136 | void I2Cscan(); 137 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 138 | uint8_t readByte(uint8_t address, uint8_t subAddress); 139 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 140 | private: 141 | uint8_t _intPin1; 142 | uint8_t _intPin2; 143 | float _aRes; 144 | }; 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /Cicada/Cicada.v07/BME280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | This sketch uses SDA/SCL on pins 42/43 (back pads), respectively, and it uses the Dragonfly STM32L476RE Breakout Board. 6 | The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution 7 | mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of 8 | only 1 microAmp. The choice will depend on the application. 9 | 10 | Library may be used freely and without limit with attribution. 11 | 12 | */ 13 | 14 | #ifndef BME280_h 15 | #define BME280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* BME280 registers 21 | * http://www.mouser.com/ds/2/783/BST-BME280_DS001-11-844833.pdf 22 | */ 23 | #define BME280_HUM_LSB 0xFE 24 | #define BME280_HUM_MSB 0xFD 25 | #define BME280_TEMP_XLSB 0xFC 26 | #define BME280_TEMP_LSB 0xFB 27 | #define BME280_TEMP_MSB 0xFA 28 | #define BME280_PRESS_XLSB 0xF9 29 | #define BME280_PRESS_LSB 0xF8 30 | #define BME280_PRESS_MSB 0xF7 31 | #define BME280_CONFIG 0xF5 32 | #define BME280_CTRL_MEAS 0xF4 33 | #define BME280_STATUS 0xF3 34 | #define BME280_CTRL_HUM 0xF2 35 | #define BME280_RESET 0xE0 36 | #define BME280_ID 0xD0 // should be 0x60 37 | #define BME280_CALIB00 0x88 38 | #define BME280_CALIB26 0xE1 39 | 40 | #define BME280_ADDRESS 0x77 // Address of BMP280 altimeter when ADO = 0 41 | 42 | 43 | #define P_OSR_01 0x01 44 | #define P_OSR_02 0x02 45 | #define P_OSR_04 0x03 46 | #define P_OSR_08 0x04 47 | #define P_OSR_16 0x05 48 | 49 | #define H_OSR_01 0x01 50 | #define H_OSR_02 0x02 51 | #define H_OSR_04 0x03 52 | #define H_OSR_08 0x04 53 | #define H_OSR_16 0x05 54 | 55 | #define T_OSR_01 0x01 56 | #define T_OSR_02 0x02 57 | #define T_OSR_04 0x03 58 | #define T_OSR_08 0x04 59 | #define T_OSR_16 0x05 60 | 61 | #define full 0x00 62 | #define BW0_223ODR 0x01 63 | #define BW0_092ODR 0x02 64 | #define BW0_042ODR 0x03 65 | #define BW0_021ODR 0x04 66 | 67 | #define Sleep 0x00 68 | #define Forced 0x01 69 | #define Forced2 0x02 70 | #define Normal 0x03 71 | 72 | #define t_00_5ms 0x00 73 | #define t_62_5ms 0x01 74 | #define t_125ms 0x02 75 | #define t_250ms 0x03 76 | #define t_500ms 0x04 77 | #define t_1000ms 0x05 78 | #define t_10ms 0x06 79 | #define t_20ms 0x07 80 | 81 | 82 | class BME280 83 | { 84 | public: 85 | BME280(); 86 | uint8_t getChipID(); 87 | void resetBME280(); 88 | int32_t readBME280Temperature(); 89 | int32_t readBME280Pressure(); 90 | int32_t readBME280Humidity(); 91 | void BME280forced(); 92 | void BME280Init(uint8_t Posr, uint8_t Hosr, uint8_t Tosr, uint8_t Mode, uint8_t IIRFilter, uint8_t SBy); 93 | int32_t BME280_compensate_T(int32_t adc_T); 94 | uint32_t BME280_compensate_P(int32_t adc_P); 95 | uint32_t BME280_compensate_H(int32_t adc_H); 96 | double BME280_compensate_T_double(int32_t adc_T); 97 | double BME280_compensate_P_double(int32_t adc_P); 98 | double BME280_compensate_H_double(int32_t adc_H); 99 | void I2Cscan(); 100 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 101 | uint8_t readByte(uint8_t address, uint8_t subAddress); 102 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 103 | private: 104 | uint8_t _dig_H1, _dig_H3, _dig_H6; 105 | uint16_t _dig_T1, _dig_P1, _dig_H4, _dig_H5; 106 | int16_t _dig_T2, _dig_T3, _dig_P2, _dig_P3, _dig_P4, _dig_P5, _dig_P6, _dig_P7, _dig_P8, _dig_P9, _dig_H2; 107 | int32_t _t_fine; 108 | }; 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /Cicada/Cicada.v07/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /Cicada/Cicada.v07/VEML6040.cpp: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | VEML6040 color sensor senses red, green, blue, and white light and incorporates photodiodes, amplifiers, 6 | and analog / digital circuits into a single chip using CMOS process. With the color sensor applied, 7 | the brightness, and color temperature of backlight can be adjusted base on ambient light source 8 | that makes panel looks more comfortable for end user’s eyes. VEML6040’s adoption of FiltronTM 9 | technology achieves the closest ambient light spectral sensitivity to real human eye responses. 10 | 11 | VEML6040 provides excellent temperature compensation capability for keeping the output stable 12 | under changing temperature. VEML6040’s function are easily operated via the simple command format 13 | of I2C (SMBus compatible) interface protocol. VEML6040’s operating voltage ranges from 2.5 V to 14 | 3.6 V. VEML6040 is packaged in a lead (Pb)-free 4 pin OPLGA package which offers the best market-proven reliability. 15 | 16 | * 17 | * Library may be used freely and without limit with attribution. 18 | * 19 | */ 20 | #include "VEML6040.h" 21 | 22 | VEML6040::VEML6040(){ 23 | } 24 | 25 | 26 | uint16_t VEML6040::getRGBWdata(uint16_t * destination) 27 | { 28 | for (int j = 0; j < 4; j++) 29 | { 30 | uint8_t rawData[2] = {0, 0}; 31 | Wire.beginTransmission(VEML6040_ADDRESS); 32 | Wire.write(VEML6040_R_DATA + j); // Command code for reading rgbw data channels in sequence 33 | Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive 34 | 35 | Wire.requestFrom(VEML6040_ADDRESS, 2); // Read two bytes from slave register address 36 | uint8_t i = 0; 37 | while (Wire.available()) 38 | { 39 | rawData[i++] = Wire.read(); // Put read results in the Rx buffer 40 | } 41 | destination[j] = ((uint16_t) rawData[1] << 8) | rawData[0]; 42 | } 43 | 44 | } 45 | 46 | void VEML6040::enableVEML6040(uint8_t IT) 47 | { 48 | uint8_t MSB = 0x00; 49 | uint8_t data = VEML6040_CONF; 50 | Wire.beginTransmission(VEML6040_ADDRESS); 51 | Wire.write(data); // Command code for configuration register 52 | Wire.write(IT << 4); // Bit 3 must be 0, bit 0 is 0 for run and 1 for shutdown, LS Byte 53 | Wire.write(MSB); // MS Byte 54 | Wire.endTransmission(); 55 | } 56 | 57 | void VEML6040::disableVEML6040(uint8_t IT) 58 | { 59 | uint8_t MSB = 0x00; 60 | uint8_t data = VEML6040_CONF; 61 | Wire.beginTransmission(VEML6040_ADDRESS); 62 | Wire.write(data); // Command code for configuration register 63 | Wire.write(IT << 4 | 0x01); // Bit 3 must be 0, bit 0 is 0 for run and 1 for shutdown, LS Byte 64 | Wire.write(MSB); // MS Byte 65 | Wire.endTransmission(); 66 | } 67 | 68 | // simple function to scan for I2C devices on the bus 69 | void VEML6040::I2Cscan() 70 | { 71 | // scan for i2c devices 72 | byte error, address; 73 | int nDevices; 74 | 75 | Serial.println("Scanning..."); 76 | 77 | nDevices = 0; 78 | for(address = 1; address < 127; address++ ) 79 | { 80 | // The i2c_scanner uses the return value of 81 | // the Write.endTransmisstion to see if 82 | // a device did acknowledge to the address. 83 | Wire.beginTransmission(address); 84 | error = Wire.endTransmission(); 85 | 86 | if (error == 0) 87 | { 88 | Serial.print("I2C device found at address 0x"); 89 | if (address<16) 90 | Serial.print("0"); 91 | Serial.print(address,HEX); 92 | Serial.println(" !"); 93 | 94 | nDevices++; 95 | } 96 | else if (error==4) 97 | { 98 | Serial.print("Unknown error at address 0x"); 99 | if (address<16) 100 | Serial.print("0"); 101 | Serial.println(address,HEX); 102 | } 103 | } 104 | if (nDevices == 0) 105 | Serial.println("No I2C devices found\n"); 106 | else 107 | Serial.println("done\n"); 108 | } 109 | 110 | -------------------------------------------------------------------------------- /Cicada/Cicada.v07/VEML6040.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | VEML6040 color sensor senses red, green, blue, and white light and incorporates photodiodes, amplifiers, 6 | and analog / digital circuits into a single chip using CMOS process. With the color sensor applied, 7 | the brightness, and color temperature of backlight can be adjusted base on ambient light source 8 | that makes panel looks more comfortable for end user’s eyes. VEML6040’s adoption of FiltronTM 9 | technology achieves the closest ambient light spectral sensitivity to real human eye responses. 10 | 11 | VEML6040 provides excellent temperature compensation capability for keeping the output stable 12 | under changing temperature. VEML6040’s function are easily operated via the simple command format 13 | of I2C (SMBus compatible) interface protocol. VEML6040’s operating voltage ranges from 2.5 V to 14 | 3.6 V. VEML6040 is packaged in a lead (Pb)-free 4 pin OPLGA package which offers the best market-proven reliability. 15 | 16 | Library may be used freely and without limit with attribution. 17 | 18 | */ 19 | 20 | #ifndef VEML6040_h 21 | #define VEML6040_h 22 | 23 | #include "Arduino.h" 24 | #include "Wire.h" 25 | 26 | // http://www.mouser.com/pdfdocs/veml6040.PDF 27 | //////////////////////////// 28 | // VEML6040 Command Codes // 29 | //////////////////////////// 30 | #define VEML6040_CONF 0x00 // command codes 31 | #define VEML6040_R_DATA 0x08 32 | #define VEML6040_G_DATA 0x09 33 | #define VEML6040_B_DATA 0x0A 34 | #define VEML6040_W_DATA 0x0B 35 | 36 | #define VEML6040_ADDRESS 0x10 37 | 38 | #define IT_40 0 // 40 ms 39 | #define IT_80 1 // 80 ms 40 | #define IT_160 2 // 160 ms 41 | #define IT_320 3 // 320 ms 42 | #define IT_640 4 // 640 ms 43 | #define IT_1280 5 // 1280 ms 44 | 45 | class VEML6040 46 | { 47 | public: 48 | VEML6040(); 49 | uint16_t getRGBWdata(uint16_t * destination); 50 | void enableVEML6040(uint8_t IT); 51 | void disableVEML6040(uint8_t IT); 52 | void I2Cscan(); 53 | private: 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /Cicada/readSPIFlash_Cicada/BME280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | This sketch uses SDA/SCL on pins 42/43 (back pads), respectively, and it uses the Dragonfly STM32L476RE Breakout Board. 6 | The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution 7 | mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of 8 | only 1 microAmp. The choice will depend on the application. 9 | 10 | Library may be used freely and without limit with attribution. 11 | 12 | */ 13 | 14 | #ifndef BME280_h 15 | #define BME280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* BME280 registers 21 | * http://www.mouser.com/ds/2/783/BST-BME280_DS001-11-844833.pdf 22 | */ 23 | #define BME280_HUM_LSB 0xFE 24 | #define BME280_HUM_MSB 0xFD 25 | #define BME280_TEMP_XLSB 0xFC 26 | #define BME280_TEMP_LSB 0xFB 27 | #define BME280_TEMP_MSB 0xFA 28 | #define BME280_PRESS_XLSB 0xF9 29 | #define BME280_PRESS_LSB 0xF8 30 | #define BME280_PRESS_MSB 0xF7 31 | #define BME280_CONFIG 0xF5 32 | #define BME280_CTRL_MEAS 0xF4 33 | #define BME280_STATUS 0xF3 34 | #define BME280_CTRL_HUM 0xF2 35 | #define BME280_RESET 0xE0 36 | #define BME280_ID 0xD0 // should be 0x60 37 | #define BME280_CALIB00 0x88 38 | #define BME280_CALIB26 0xE1 39 | 40 | #define BME280_ADDRESS 0x77 // Address of BMP280 altimeter when ADO = 0 41 | 42 | 43 | #define P_OSR_01 0x01 44 | #define P_OSR_02 0x02 45 | #define P_OSR_04 0x03 46 | #define P_OSR_08 0x04 47 | #define P_OSR_16 0x05 48 | 49 | #define H_OSR_01 0x01 50 | #define H_OSR_02 0x02 51 | #define H_OSR_04 0x03 52 | #define H_OSR_08 0x04 53 | #define H_OSR_16 0x05 54 | 55 | #define T_OSR_01 0x01 56 | #define T_OSR_02 0x02 57 | #define T_OSR_04 0x03 58 | #define T_OSR_08 0x04 59 | #define T_OSR_16 0x05 60 | 61 | #define full 0x00 62 | #define BW0_223ODR 0x01 63 | #define BW0_092ODR 0x02 64 | #define BW0_042ODR 0x03 65 | #define BW0_021ODR 0x04 66 | 67 | #define Sleep 0x00 68 | #define Forced 0x01 69 | #define Forced2 0x02 70 | #define Normal 0x03 71 | 72 | #define t_00_5ms 0x00 73 | #define t_62_5ms 0x01 74 | #define t_125ms 0x02 75 | #define t_250ms 0x03 76 | #define t_500ms 0x04 77 | #define t_1000ms 0x05 78 | #define t_10ms 0x06 79 | #define t_20ms 0x07 80 | 81 | 82 | class BME280 83 | { 84 | public: 85 | BME280(); 86 | uint8_t getChipID(); 87 | void resetBME280(); 88 | int32_t readBME280Temperature(); 89 | int32_t readBME280Pressure(); 90 | int32_t readBME280Humidity(); 91 | void BME280forced(); 92 | void BME280Init(uint8_t Posr, uint8_t Hosr, uint8_t Tosr, uint8_t Mode, uint8_t IIRFilter, uint8_t SBy); 93 | int32_t BME280_compensate_T(int32_t adc_T); 94 | uint32_t BME280_compensate_P(int32_t adc_P); 95 | uint32_t BME280_compensate_H(int32_t adc_H); 96 | double BME280_compensate_T_double(int32_t adc_T); 97 | double BME280_compensate_P_double(int32_t adc_P); 98 | double BME280_compensate_H_double(int32_t adc_H); 99 | void I2Cscan(); 100 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 101 | uint8_t readByte(uint8_t address, uint8_t subAddress); 102 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 103 | private: 104 | uint8_t _dig_H1, _dig_H3, _dig_H6; 105 | uint16_t _dig_T1, _dig_P1, _dig_H4, _dig_H5; 106 | int16_t _dig_T2, _dig_T3, _dig_P2, _dig_P3, _dig_P4, _dig_P5, _dig_P6, _dig_P7, _dig_P8, _dig_P9, _dig_H2; 107 | int32_t _t_fine; 108 | }; 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /Cicada/readSPIFlash_Cicada/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include "SPI.h" 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void SPIFlashinit(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /Cicada/testSPIFlash_Cicada/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /Cicada/testSPIFlash_Cicada/testSPIFlash_Cicada.ino: -------------------------------------------------------------------------------- 1 | /* SPIFlash_Cicada.ino 2 | Sketch by Kris Winer December 16, 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #include 31 | #include "SPIFlash.h" 32 | 33 | // 64 MBit (8 MByte) SPI Flash 32,767, 256-byte pages 34 | #define csPin 25 // SPI Flash chip select pin (PH0) 35 | #define myLed 10 // blue led active LOW 36 | 37 | uint16_t page_number = 0xEFF; // set the page mumber for flash page write 38 | uint8_t sector_number = 0; // set the sector number for sector write 39 | uint8_t flashPage[256]; // array to hold the data for flash page write 40 | uint32_t t_start = 0; 41 | 42 | SPIFlash SPIFlash(csPin); 43 | 44 | 45 | void setup(void) 46 | { 47 | pinMode(csPin, OUTPUT); 48 | digitalWrite(csPin, HIGH); 49 | 50 | pinMode(myLed, OUTPUT); 51 | digitalWrite(myLed, HIGH); // start with led off 52 | 53 | Serial.begin(115200); 54 | delay(4000); 55 | Serial.println("Serial enabled!"); 56 | 57 | // power up the chip 58 | SPIFlash.init(); 59 | SPIFlash.powerUp(); 60 | SPIFlash.getChipID(); 61 | 62 | /* Initialize the array to 0,1,2,3 etc.*/ 63 | for(uint16_t i = 0; i < 256; i++) { 64 | flashPage[i] = i; 65 | } 66 | 67 | /* Write the page to page_number - this page MUST be in the erased state*/ 68 | Serial.print("Write page: 0x"); Serial.println(page_number, HEX); 69 | t_start = micros(); 70 | SPIFlash.flash_page_program(flashPage, page_number); 71 | t_start = micros() - t_start; 72 | Serial.print("time (us) = "); Serial.println(t_start); 73 | 74 | /* Read back page_number and print its contents which should be 0,1,2,3...*/ 75 | Serial.print("Read Page 0x"); Serial.println(page_number, HEX); 76 | t_start = micros(); 77 | SPIFlash.flash_read_pages(flashPage, page_number, 1); 78 | t_start = micros() - t_start; 79 | Serial.print("time (us) = "); Serial.println(t_start); 80 | 81 | for(uint16_t i = 0; i < 256; i++) { 82 | Serial.print(" 0x"); Serial.print(flashPage[i], HEX); 83 | if (i % 16==0) Serial.println(); 84 | } 85 | Serial.println(""); 86 | 87 | /* Erase the entire chip which includes page_number*/ 88 | t_start = millis(); 89 | SPIFlash.flash_chip_erase(true); 90 | t_start = millis() - t_start; 91 | Serial.print("time (ms) = "); Serial.println(t_start); 92 | 93 | /* Now read back the page. It should now be all 0xFF*/ 94 | Serial.print( "Read Page 0x"); Serial.println(page_number, HEX); 95 | t_start = micros(); 96 | SPIFlash.flash_read_pages(flashPage, page_number, 1); 97 | t_start = micros() - t_start; 98 | 99 | Serial.print("time (us) = "); Serial.println(t_start); 100 | for(uint16_t i = 0; i < 256; i++) { 101 | Serial.print(" 0x"); Serial.print(flashPage[i], HEX); 102 | if (i % 16==0) Serial.println(); 103 | } 104 | Serial.println(""); 105 | Serial.flush(); 106 | 107 | digitalWrite(myLed, LOW); // when done turn led off 108 | } 109 | 110 | void loop(void) 111 | { 112 | } 113 | 114 | 115 | -------------------------------------------------------------------------------- /CricketAssetTracker/AssetTracker_Cricket.v02/BMA280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | * The BMA280 is an inexpensive (~$1), three-axis, high-resolution (14-bit) acclerometer in a tiny 2 mm x 2 mm LGA12 package with 32-slot FIFO, 6 | * two multifunction interrupts and widely configurable sample rate (15 - 2000 Hz), full range (2 - 16 g), low power modes, 7 | * and interrupt detection behaviors. This accelerometer is nice choice for low-frequency sound and vibration analysis, 8 | * tap detection and simple orientation estimation. 9 | * 10 | * Library may be used freely and without limit with attribution. 11 | * 12 | */ 13 | 14 | #ifndef BMA280_h 15 | #define BMA280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* Register Map BMA280 21 | // http://www.mouser.com/ds/2/783/BST-BMA280-DS000-11_published-786496.pdf 22 | */ 23 | #define BMA280_BGW_CHIPID 0x00 24 | #define BMA280_ACCD_X_LSB 0x02 25 | #define BMA280_ACCD_X_MSB 0x03 26 | #define BMA280_ACCD_Y_LSB 0x04 27 | #define BMA280_ACCD_Y_MSB 0x05 28 | #define BMA280_ACCD_Z_LSB 0x06 29 | #define BMA280_ACCD_Z_MSB 0x07 30 | #define BMA280_ACCD_TEMP 0x08 31 | #define BMA280_INT_STATUS_0 0x09 32 | #define BMA280_INT_STATUS_1 0x0A 33 | #define BMA280_INT_STATUS_2 0x0B 34 | #define BMA280_INT_STATUS_3 0x0C 35 | #define BMA280_FIFO_STATUS 0x0E 36 | #define BMA280_PMU_RANGE 0x0F 37 | #define BMA280_PMU_BW 0x10 38 | #define BMA280_PMU_LPW 0x11 39 | #define BMA280_PMU_LOW_POWER 0x12 40 | #define BMA280_ACCD_HBW 0x13 41 | #define BMA280_BGW_SOFTRESET 0x14 42 | #define BMA280_INT_EN_0 0x16 43 | #define BMA280_INT_EN_1 0x17 44 | #define BMA280_INT_EN_2 0x18 45 | #define BMA280_INT_MAP_0 0x19 46 | #define BMA280_INT_MAP_1 0x1A 47 | #define BMA280_INT_MAP_2 0x1B 48 | #define BMA280_INT_SRC 0x1E 49 | #define BMA280_INT_OUT_CTRL 0x20 50 | #define BMA280_INT_RST_LATCH 0x21 51 | #define BMA280_INT_0 0x22 52 | #define BMA280_INT_1 0x23 53 | #define BMA280_INT_2 0x24 54 | #define BMA280_INT_3 0x25 55 | #define BMA280_INT_4 0x26 56 | #define BMA280_INT_5 0x27 57 | #define BMA280_INT_6 0x28 58 | #define BMA280_INT_7 0x29 59 | #define BMA280_INT_8 0x2A 60 | #define BMA280_INT_9 0x2B 61 | #define BMA280_INT_A 0x2C 62 | #define BMA280_INT_B 0x2D 63 | #define BMA280_INT_C 0x2E 64 | #define BMA280_INT_D 0x2F 65 | #define BMA280_FIFO_CONFIG_0 0x30 66 | #define BMA280_PMU_SELF_TEST 0x32 67 | #define BMA280_TRIM_NVM_CTRL 0x33 68 | #define BMA280_BGW_SPI3_WDT 0x34 69 | #define BMA280_OFC_CTRL 0x36 70 | #define BMA280_OFC_SETTING 0x37 71 | #define BMA280_OFC_OFFSET_X 0x38 72 | #define BMA280_OFC_OFFSET_Y 0x39 73 | #define BMA280_OFC_OFFSET_Z 0x3A 74 | #define BMA280_TRIM_GP0 0x3B 75 | #define BMA280_TRIM_GP1 0x3C 76 | #define BMA280_FIFO_CONFIG_1 0x3E 77 | #define BMA280_FIFO_DATA 0x3F 78 | 79 | #define BMA280_ADDRESS 0x18 // if ADO is 0 (default) 80 | 81 | #define AFS_2G 0x03 82 | #define AFS_4G 0x05 83 | #define AFS_8G 0x08 84 | #define AFS_16G 0x0C 85 | 86 | #define BW_7_81Hz 0x08 // 15.62 Hz sample rate, etc 87 | #define BW_15_63Hz 0x09 88 | #define BW_31_25Hz 0x0A 89 | #define BW_62_5Hz 0x0B 90 | #define BW_125Hz 0x0C // 250 Hz sample rate 91 | #define BW_250Hz 0x0D 92 | #define BW_500Hz 0x0E 93 | #define BW_1000Hz 0x0F // 2 kHz sample rate == unfiltered data 94 | 95 | #define normal_Mode 0x00 //define power modes 96 | #define deepSuspend_Mode 0x01 97 | #define lowPower_Mode 0x02 98 | #define suspend_Mode 0x04 99 | 100 | #define lp_mode_1 0x00 // two types of low power mode 101 | #define lp_mode_2 0x40 102 | 103 | #define sleep_0_5ms 0x05 // define sleep duration in low power modes 104 | #define sleep_1ms 0x06 105 | #define sleep_2ms 0x07 106 | #define sleep_4ms 0x08 107 | #define sleep_6ms 0x09 108 | #define sleep_10ms 0x0A 109 | #define sleep_25ms 0x0B 110 | #define sleep_50ms 0x0C 111 | #define sleep_100ms 0x0D 112 | #define sleep_500ms 0x0E 113 | #define sleep_1000ms 0x0F 114 | 115 | class BMA280 116 | { 117 | public: 118 | BMA280(uint8_t intPin1, uint8_t intPin2); 119 | float getAres(uint8_t Ascale); 120 | uint8_t getChipID(); 121 | uint8_t getTapType(); 122 | uint8_t getTapStatus(); 123 | void initBMA280(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, uint8_t sleep_dur); 124 | void initBMA280_MotionManager(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, 125 | uint8_t sleep_dur, uint8_t low_power_Mode, 126 | uint8_t motion_threshold); 127 | void activateNoMotionInterrupt(); 128 | void deactivateNoMotionInterrupt(); 129 | void activateSlopeInterrupt(); 130 | void deactivateSlopeInterrupt(); 131 | void fastCompensationBMA280(); 132 | void resetBMA280(); 133 | void selfTestBMA280(); 134 | void readBMA280AccelData(int16_t * destination); 135 | int16_t readBMA280TempData(); 136 | void I2Cscan(); 137 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 138 | uint8_t readByte(uint8_t address, uint8_t subAddress); 139 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 140 | private: 141 | uint8_t _intPin1; 142 | uint8_t _intPin2; 143 | float _aRes; 144 | }; 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /CricketAssetTracker/AssetTracker_Cricket.v02/BME280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | This sketch uses SDA/SCL on pins 42/43 (back pads), respectively, and it uses the Dragonfly STM32L476RE Breakout Board. 6 | The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution 7 | mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of 8 | only 1 microAmp. The choice will depend on the application. 9 | 10 | Library may be used freely and without limit with attribution. 11 | 12 | */ 13 | 14 | #ifndef BME280_h 15 | #define BME280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* BME280 registers 21 | * http://www.mouser.com/ds/2/783/BST-BME280_DS001-11-844833.pdf 22 | */ 23 | #define BME280_HUM_LSB 0xFE 24 | #define BME280_HUM_MSB 0xFD 25 | #define BME280_TEMP_XLSB 0xFC 26 | #define BME280_TEMP_LSB 0xFB 27 | #define BME280_TEMP_MSB 0xFA 28 | #define BME280_PRESS_XLSB 0xF9 29 | #define BME280_PRESS_LSB 0xF8 30 | #define BME280_PRESS_MSB 0xF7 31 | #define BME280_CONFIG 0xF5 32 | #define BME280_CTRL_MEAS 0xF4 33 | #define BME280_STATUS 0xF3 34 | #define BME280_CTRL_HUM 0xF2 35 | #define BME280_RESET 0xE0 36 | #define BME280_ID 0xD0 // should be 0x60 37 | #define BME280_CALIB00 0x88 38 | #define BME280_CALIB26 0xE1 39 | 40 | #define BME280_ADDRESS 0x77 // Address of BMP280 altimeter when ADO = 0 41 | 42 | 43 | #define P_OSR_01 0x01 44 | #define P_OSR_02 0x02 45 | #define P_OSR_04 0x03 46 | #define P_OSR_08 0x04 47 | #define P_OSR_16 0x05 48 | 49 | #define H_OSR_01 0x01 50 | #define H_OSR_02 0x02 51 | #define H_OSR_04 0x03 52 | #define H_OSR_08 0x04 53 | #define H_OSR_16 0x05 54 | 55 | #define T_OSR_01 0x01 56 | #define T_OSR_02 0x02 57 | #define T_OSR_04 0x03 58 | #define T_OSR_08 0x04 59 | #define T_OSR_16 0x05 60 | 61 | #define full 0x00 62 | #define BW0_223ODR 0x01 63 | #define BW0_092ODR 0x02 64 | #define BW0_042ODR 0x03 65 | #define BW0_021ODR 0x04 66 | 67 | #define Sleep 0x00 68 | #define Forced 0x01 69 | #define Forced2 0x02 70 | #define Normal 0x03 71 | 72 | #define t_00_5ms 0x00 73 | #define t_62_5ms 0x01 74 | #define t_125ms 0x02 75 | #define t_250ms 0x03 76 | #define t_500ms 0x04 77 | #define t_1000ms 0x05 78 | #define t_10ms 0x06 79 | #define t_20ms 0x07 80 | 81 | 82 | class BME280 83 | { 84 | public: 85 | BME280(); 86 | uint8_t getChipID(); 87 | void resetBME280(); 88 | int32_t readBME280Temperature(); 89 | int32_t readBME280Pressure(); 90 | int32_t readBME280Humidity(); 91 | void BME280forced(); 92 | void BME280Init(uint8_t Posr, uint8_t Hosr, uint8_t Tosr, uint8_t Mode, uint8_t IIRFilter, uint8_t SBy); 93 | int32_t BME280_compensate_T(int32_t adc_T); 94 | uint32_t BME280_compensate_P(int32_t adc_P); 95 | uint32_t BME280_compensate_H(int32_t adc_H); 96 | void I2Cscan(); 97 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 98 | uint8_t readByte(uint8_t address, uint8_t subAddress); 99 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 100 | private: 101 | uint8_t _dig_H1, _dig_H3, _dig_H6; 102 | uint16_t _dig_T1, _dig_P1, _dig_H4, _dig_H5; 103 | int16_t _dig_T2, _dig_T3, _dig_P2, _dig_P3, _dig_P4, _dig_P5, _dig_P6, _dig_P7, _dig_P8, _dig_P9, _dig_H2; 104 | int32_t _t_fine; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /CricketAssetTracker/AssetTracker_Cricket.v02/Readme.md: -------------------------------------------------------------------------------- 1 | Retro Cricket Asset Tracker sketch, variation on previous versions but tuned for highest GNSS position accuracy. 2 | 3 | Typical usage is read and log sensor data at 1 minute intervals, get GNSS fix every two hours but every minute when motion is detected and keep tracking until EPHE (estimated horizontal position error ) is less than 10 meter, and update all data via LoRaWAN every ten minutes. 4 | 5 | At EPHE = 10, the Cricket will use ~550 uA, at EPHE = 20 the Cricket will use ~0.440 uA, and at EPHE = 50 the Cricket will use ~320 uA in this mode, depending on how often the device is in motion. The base current with all of the above but without the GNSS engine is ~40 uA, and the lowest power sleep current with everything off is ~14 uA. 6 | 7 | If motion is expected less frequently, say once per day, then setting the long duty cycle to 12 or 24 hours will reduce the current usage proportionally; i.e., at 12 hours, the current usage should be ~(320 - 40) *2/12 + 40 ~ 90 uA, etc. 8 | 9 | YMMV so test using a 105 or 150 mAH LiPo battery to see how many days the Cricket lasts with your specific duty cycle. 10 | 11 | -------------------------------------------------------------------------------- /CricketAssetTracker/AssetTracker_Cricket.v02/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include "SPI.h" 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /CricketAssetTracker/AssetTracker_Cricket/BMA280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | * The BMA280 is an inexpensive (~$1), three-axis, high-resolution (14-bit) acclerometer in a tiny 2 mm x 2 mm LGA12 package with 32-slot FIFO, 6 | * two multifunction interrupts and widely configurable sample rate (15 - 2000 Hz), full range (2 - 16 g), low power modes, 7 | * and interrupt detection behaviors. This accelerometer is nice choice for low-frequency sound and vibration analysis, 8 | * tap detection and simple orientation estimation. 9 | * 10 | * Library may be used freely and without limit with attribution. 11 | * 12 | */ 13 | 14 | #ifndef BMA280_h 15 | #define BMA280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* Register Map BMA280 21 | // http://www.mouser.com/ds/2/783/BST-BMA280-DS000-11_published-786496.pdf 22 | */ 23 | #define BMA280_BGW_CHIPID 0x00 24 | #define BMA280_ACCD_X_LSB 0x02 25 | #define BMA280_ACCD_X_MSB 0x03 26 | #define BMA280_ACCD_Y_LSB 0x04 27 | #define BMA280_ACCD_Y_MSB 0x05 28 | #define BMA280_ACCD_Z_LSB 0x06 29 | #define BMA280_ACCD_Z_MSB 0x07 30 | #define BMA280_ACCD_TEMP 0x08 31 | #define BMA280_INT_STATUS_0 0x09 32 | #define BMA280_INT_STATUS_1 0x0A 33 | #define BMA280_INT_STATUS_2 0x0B 34 | #define BMA280_INT_STATUS_3 0x0C 35 | #define BMA280_FIFO_STATUS 0x0E 36 | #define BMA280_PMU_RANGE 0x0F 37 | #define BMA280_PMU_BW 0x10 38 | #define BMA280_PMU_LPW 0x11 39 | #define BMA280_PMU_LOW_POWER 0x12 40 | #define BMA280_ACCD_HBW 0x13 41 | #define BMA280_BGW_SOFTRESET 0x14 42 | #define BMA280_INT_EN_0 0x16 43 | #define BMA280_INT_EN_1 0x17 44 | #define BMA280_INT_EN_2 0x18 45 | #define BMA280_INT_MAP_0 0x19 46 | #define BMA280_INT_MAP_1 0x1A 47 | #define BMA280_INT_MAP_2 0x1B 48 | #define BMA280_INT_SRC 0x1E 49 | #define BMA280_INT_OUT_CTRL 0x20 50 | #define BMA280_INT_RST_LATCH 0x21 51 | #define BMA280_INT_0 0x22 52 | #define BMA280_INT_1 0x23 53 | #define BMA280_INT_2 0x24 54 | #define BMA280_INT_3 0x25 55 | #define BMA280_INT_4 0x26 56 | #define BMA280_INT_5 0x27 57 | #define BMA280_INT_6 0x28 58 | #define BMA280_INT_7 0x29 59 | #define BMA280_INT_8 0x2A 60 | #define BMA280_INT_9 0x2B 61 | #define BMA280_INT_A 0x2C 62 | #define BMA280_INT_B 0x2D 63 | #define BMA280_INT_C 0x2E 64 | #define BMA280_INT_D 0x2F 65 | #define BMA280_FIFO_CONFIG_0 0x30 66 | #define BMA280_PMU_SELF_TEST 0x32 67 | #define BMA280_TRIM_NVM_CTRL 0x33 68 | #define BMA280_BGW_SPI3_WDT 0x34 69 | #define BMA280_OFC_CTRL 0x36 70 | #define BMA280_OFC_SETTING 0x37 71 | #define BMA280_OFC_OFFSET_X 0x38 72 | #define BMA280_OFC_OFFSET_Y 0x39 73 | #define BMA280_OFC_OFFSET_Z 0x3A 74 | #define BMA280_TRIM_GP0 0x3B 75 | #define BMA280_TRIM_GP1 0x3C 76 | #define BMA280_FIFO_CONFIG_1 0x3E 77 | #define BMA280_FIFO_DATA 0x3F 78 | 79 | #define BMA280_ADDRESS 0x18 // if ADO is 0 (default) 80 | 81 | #define AFS_2G 0x03 82 | #define AFS_4G 0x05 83 | #define AFS_8G 0x08 84 | #define AFS_16G 0x0C 85 | 86 | #define BW_7_81Hz 0x08 // 15.62 Hz sample rate, etc 87 | #define BW_15_63Hz 0x09 88 | #define BW_31_25Hz 0x0A 89 | #define BW_62_5Hz 0x0B 90 | #define BW_125Hz 0x0C // 250 Hz sample rate 91 | #define BW_250Hz 0x0D 92 | #define BW_500Hz 0x0E 93 | #define BW_1000Hz 0x0F // 2 kHz sample rate == unfiltered data 94 | 95 | #define normal_Mode 0x00 //define power modes 96 | #define deepSuspend_Mode 0x01 97 | #define lowPower_Mode 0x02 98 | #define suspend_Mode 0x04 99 | 100 | #define lp_mode_1 0x00 // two types of low power mode 101 | #define lp_mode_2 0x40 102 | 103 | #define sleep_0_5ms 0x05 // define sleep duration in low power modes 104 | #define sleep_1ms 0x06 105 | #define sleep_2ms 0x07 106 | #define sleep_4ms 0x08 107 | #define sleep_6ms 0x09 108 | #define sleep_10ms 0x0A 109 | #define sleep_25ms 0x0B 110 | #define sleep_50ms 0x0C 111 | #define sleep_100ms 0x0D 112 | #define sleep_500ms 0x0E 113 | #define sleep_1000ms 0x0F 114 | 115 | class BMA280 116 | { 117 | public: 118 | BMA280(uint8_t intPin1, uint8_t intPin2); 119 | float getAres(uint8_t Ascale); 120 | uint8_t getChipID(); 121 | uint8_t getTapType(); 122 | uint8_t getTapStatus(); 123 | void initBMA280(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, uint8_t sleep_dur); 124 | void initBMA280_MotionManager(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, 125 | uint8_t sleep_dur, uint8_t low_power_Mode, 126 | uint8_t motion_threshold); 127 | void activateNoMotionInterrupt(); 128 | void deactivateNoMotionInterrupt(); 129 | void activateSlopeInterrupt(); 130 | void deactivateSlopeInterrupt(); 131 | void fastCompensationBMA280(); 132 | void resetBMA280(); 133 | void selfTestBMA280(); 134 | void readBMA280AccelData(int16_t * destination); 135 | int16_t readBMA280TempData(); 136 | void I2Cscan(); 137 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 138 | uint8_t readByte(uint8_t address, uint8_t subAddress); 139 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 140 | private: 141 | uint8_t _intPin1; 142 | uint8_t _intPin2; 143 | float _aRes; 144 | }; 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /CricketAssetTracker/AssetTracker_Cricket/BME280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | This sketch uses SDA/SCL on pins 42/43 (back pads), respectively, and it uses the Dragonfly STM32L476RE Breakout Board. 6 | The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution 7 | mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of 8 | only 1 microAmp. The choice will depend on the application. 9 | 10 | Library may be used freely and without limit with attribution. 11 | 12 | */ 13 | 14 | #ifndef BME280_h 15 | #define BME280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* BME280 registers 21 | * http://www.mouser.com/ds/2/783/BST-BME280_DS001-11-844833.pdf 22 | */ 23 | #define BME280_HUM_LSB 0xFE 24 | #define BME280_HUM_MSB 0xFD 25 | #define BME280_TEMP_XLSB 0xFC 26 | #define BME280_TEMP_LSB 0xFB 27 | #define BME280_TEMP_MSB 0xFA 28 | #define BME280_PRESS_XLSB 0xF9 29 | #define BME280_PRESS_LSB 0xF8 30 | #define BME280_PRESS_MSB 0xF7 31 | #define BME280_CONFIG 0xF5 32 | #define BME280_CTRL_MEAS 0xF4 33 | #define BME280_STATUS 0xF3 34 | #define BME280_CTRL_HUM 0xF2 35 | #define BME280_RESET 0xE0 36 | #define BME280_ID 0xD0 // should be 0x60 37 | #define BME280_CALIB00 0x88 38 | #define BME280_CALIB26 0xE1 39 | 40 | #define BME280_ADDRESS 0x77 // Address of BMP280 altimeter when ADO = 0 41 | 42 | 43 | #define P_OSR_01 0x01 44 | #define P_OSR_02 0x02 45 | #define P_OSR_04 0x03 46 | #define P_OSR_08 0x04 47 | #define P_OSR_16 0x05 48 | 49 | #define H_OSR_01 0x01 50 | #define H_OSR_02 0x02 51 | #define H_OSR_04 0x03 52 | #define H_OSR_08 0x04 53 | #define H_OSR_16 0x05 54 | 55 | #define T_OSR_01 0x01 56 | #define T_OSR_02 0x02 57 | #define T_OSR_04 0x03 58 | #define T_OSR_08 0x04 59 | #define T_OSR_16 0x05 60 | 61 | #define full 0x00 62 | #define BW0_223ODR 0x01 63 | #define BW0_092ODR 0x02 64 | #define BW0_042ODR 0x03 65 | #define BW0_021ODR 0x04 66 | 67 | #define Sleep 0x00 68 | #define Forced 0x01 69 | #define Forced2 0x02 70 | #define Normal 0x03 71 | 72 | #define t_00_5ms 0x00 73 | #define t_62_5ms 0x01 74 | #define t_125ms 0x02 75 | #define t_250ms 0x03 76 | #define t_500ms 0x04 77 | #define t_1000ms 0x05 78 | #define t_10ms 0x06 79 | #define t_20ms 0x07 80 | 81 | 82 | class BME280 83 | { 84 | public: 85 | BME280(); 86 | uint8_t getChipID(); 87 | void resetBME280(); 88 | int32_t readBME280Temperature(); 89 | int32_t readBME280Pressure(); 90 | int32_t readBME280Humidity(); 91 | void BME280forced(); 92 | void BME280Init(uint8_t Posr, uint8_t Hosr, uint8_t Tosr, uint8_t Mode, uint8_t IIRFilter, uint8_t SBy); 93 | int32_t BME280_compensate_T(int32_t adc_T); 94 | uint32_t BME280_compensate_P(int32_t adc_P); 95 | uint32_t BME280_compensate_H(int32_t adc_H); 96 | void I2Cscan(); 97 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 98 | uint8_t readByte(uint8_t address, uint8_t subAddress); 99 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 100 | private: 101 | uint8_t _dig_H1, _dig_H3, _dig_H6; 102 | uint16_t _dig_T1, _dig_P1, _dig_H4, _dig_H5; 103 | int16_t _dig_T2, _dig_T3, _dig_P2, _dig_P3, _dig_P4, _dig_P5, _dig_P6, _dig_P7, _dig_P8, _dig_P9, _dig_H2; 104 | int32_t _t_fine; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /CricketAssetTracker/AssetTracker_Cricket/Readme.md: -------------------------------------------------------------------------------- 1 | Latest version of the Cricket Asset Tracker library. Typical current usage at 1 minute sensor logging, ten minute LoRaWAN Tx, and 2 hour GNSS fix intervals is 300 - 400 uA depending on outdoor position and frequency of wake-on-motion fix intervals. Output data to CayenneLPP dashboard. 2 | 3 | ![CayenneLPP](https://user-images.githubusercontent.com/6698410/42728893-1e30cec8-877b-11e8-87dc-08c81cae580e.jpg) 4 | -------------------------------------------------------------------------------- /CricketAssetTracker/AssetTracker_Cricket/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include "SPI.h" 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /CricketAssetTracker/Blink_Cricket.ino: -------------------------------------------------------------------------------- 1 | /* LED Blink, for Cricket 2 | 3 | This example code is in the public domain. 4 | */ 5 | #include 6 | #include 7 | 8 | #define myLed 10 // blue led 9 | 10 | float VDDA, Temperature; 11 | uint32_t UID[3] = {0, 0, 0}; 12 | 13 | void setup() 14 | { 15 | Serial.begin(38400); 16 | delay(2000); 17 | Serial.println("Serial enabled!"); 18 | 19 | pinMode(myLed, OUTPUT); 20 | digitalWrite(myLed, HIGH); // start with led off, since active LOW 21 | 22 | STM32L0.getUID(UID); 23 | Serial.print("STM32L0 MCU UID = 0x"); Serial.print(UID[0], HEX); Serial.print(UID[1], HEX); Serial.println(UID[2], HEX); 24 | } 25 | 26 | void loop() 27 | { 28 | digitalWrite(myLed, LOW); // toggle blue led on 29 | delay(100); // wait 100 milliseconds 30 | digitalWrite(myLed, HIGH); // toggle blue led off 31 | delay(1000); // wait 1000 milliseconds 32 | 33 | VDDA = STM32L0.getVDDA(); 34 | Temperature = STM32L0.getTemperature(); 35 | 36 | Serial.print("VDDA = "); Serial.println(VDDA, 2); 37 | Serial.print("STM32L0 MCU Temperature = "); Serial.println(Temperature, 2); 38 | 39 | // STM32L0.stop(2000); 40 | } 41 | -------------------------------------------------------------------------------- /CricketAssetTracker/I2CScan_Cricket.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | 5 | Serial.begin(115200); 6 | delay(4000); 7 | 8 | // SDA/SCL are pins 14, 15 9 | pinMode(14, OUTPUT); // hold SDA low to wake up ECC608A 10 | digitalWrite(14, LOW); 11 | delay(1000); 12 | 13 | Wire.begin(); // set master mode 14 | Wire.setClock(400000); // I2C frequency at 400 kHz 15 | delay(1000); 16 | 17 | I2Cscan(); 18 | 19 | } 20 | 21 | 22 | void loop() { 23 | 24 | } 25 | 26 | // I2C scan function 27 | void I2Cscan() 28 | { 29 | // scan for i2c devices 30 | byte error, address; 31 | int nDevices; 32 | 33 | Serial.println("Scanning..."); 34 | 35 | nDevices = 0; 36 | for(address = 1; address < 127; address++ ) 37 | { 38 | // The i2c_scanner uses the return value of 39 | // the Write.endTransmission to see if 40 | // a device did acknowledge to the address. 41 | Wire.beginTransmission(address); 42 | error = Wire.endTransmission(); 43 | 44 | if (error == 0) 45 | { 46 | Serial.print("I2C device found at address 0x"); 47 | if (address<16) 48 | Serial.print("0"); 49 | Serial.print(address,HEX); 50 | Serial.println(" !"); 51 | 52 | nDevices++; 53 | } 54 | else if (error==4) 55 | { 56 | Serial.print("Unknown error at address 0x"); 57 | if (address<16) 58 | Serial.print("0"); 59 | Serial.println(address,HEX); 60 | } 61 | } 62 | if (nDevices == 0) 63 | Serial.println("No I2C devices found\n"); 64 | else 65 | Serial.println("done\n"); 66 | 67 | } 68 | 69 | // I2C read/write functions for the CaliPile sensor 70 | 71 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data) 72 | { 73 | Wire.beginTransmission(address); // Initialize the Tx buffer 74 | Wire.write(subAddress); // Put slave register address in Tx buffer 75 | Wire.write(data); // Put data in Tx buffer 76 | Wire.endTransmission(); // Send the Tx buffer 77 | } 78 | 79 | uint8_t readByte(uint8_t address, uint8_t subAddress) 80 | { 81 | uint8_t data; // `data` will store the register data 82 | Wire.beginTransmission(address); // Initialize the Tx buffer 83 | Wire.write(subAddress); // Put slave register address in Tx buffer 84 | Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive 85 | Wire.requestFrom(address, 1); // Read one byte from slave register address 86 | data = Wire.read(); // Fill Rx buffer with result 87 | return data; // Return data read from slave register 88 | } 89 | 90 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) 91 | { 92 | Wire.beginTransmission(address); // Initialize the Tx buffer 93 | Wire.write(subAddress); // Put slave register address in Tx buffer 94 | Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive 95 | uint8_t i = 0; 96 | Wire.requestFrom(address, count); // Read bytes from slave register address 97 | while (Wire.available()) {dest[i++] = Wire.read(); } // Put read results in the Rx buffer 98 | } 99 | -------------------------------------------------------------------------------- /CricketAssetTracker/Readme.md: -------------------------------------------------------------------------------- 1 | Cricket is a 23 mm x 46 mm CMWX1ZZABZ-hosted asset tracker using the concurrent GNSS engine CAM M8Q and includes STBC08 battery charger, 8 MByte SPI NOR Flash for data logging, BMA280 accelerometer for motion detection and BME280 for environmental sensing. See [here](https://hackaday.io/project/35169-hackable-cmwx1zzabz-lora-devices) for more discussion. 2 | 3 | ![Cricket](https://user-images.githubusercontent.com/6698410/34909788-8f515fe0-f85c-11e7-8de5-30879457ddd1.jpg) 4 | 5 | Cricket is for sale at [Tindie](https://www.tindie.com/products/TleraCorp/cricket-lorawangnss-asset-tracker/). 6 | -------------------------------------------------------------------------------- /CricketAssetTracker/readSPIFlash_CricketAssetTracker/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include "SPI.h" 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void powerUp(); 61 | void getChipID(); 62 | void write_pause(void); 63 | int page_to_address(int pn); 64 | int address_to_page(int addr); 65 | void flash_read_id(unsigned char *idt); 66 | unsigned char flash_read_status(void); 67 | void flash_hard_reset(void); 68 | void flash_chip_erase(boolean wait); 69 | void flash_erase_pages_sector(int pn); 70 | void flash_erase_pages_block32k(int pn); 71 | void flash_erase_pages_block64k(int pn); 72 | void flash_page_program(unsigned char *wp,int pn); 73 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 74 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 75 | private: 76 | uint8_t _csPin; 77 | unsigned char flash_wait_for_write = 0; 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /GasCap/AssetTracker_GasCap_v.02e/BME280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | This sketch uses SDA/SCL on pins 42/43 (back pads), respectively, and it uses the Dragonfly STM32L476RE Breakout Board. 6 | The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution 7 | mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of 8 | only 1 microAmp. The choice will depend on the application. 9 | 10 | Library may be used freely and without limit with attribution. 11 | 12 | */ 13 | 14 | #ifndef BME280_h 15 | #define BME280_h 16 | 17 | #include "Arduino.h" 18 | #include "I2Cdev.h" 19 | #include 20 | 21 | /* BME280 registers 22 | * http://www.mouser.com/ds/2/783/BST-BME280_DS001-11-844833.pdf 23 | */ 24 | #define BME280_HUM_LSB 0xFE 25 | #define BME280_HUM_MSB 0xFD 26 | #define BME280_TEMP_XLSB 0xFC 27 | #define BME280_TEMP_LSB 0xFB 28 | #define BME280_TEMP_MSB 0xFA 29 | #define BME280_PRESS_XLSB 0xF9 30 | #define BME280_PRESS_LSB 0xF8 31 | #define BME280_PRESS_MSB 0xF7 32 | #define BME280_CONFIG 0xF5 33 | #define BME280_CTRL_MEAS 0xF4 34 | #define BME280_STATUS 0xF3 35 | #define BME280_CTRL_HUM 0xF2 36 | #define BME280_RESET 0xE0 37 | #define BME280_ID 0xD0 // should be 0x60 38 | #define BME280_CALIB00 0x88 39 | #define BME280_CALIB26 0xE1 40 | 41 | #define BME280_ADDRESS 0x76 // Address of BMP280 altimeter when ADO = 0 42 | 43 | #define P_OSR_01 0x01 44 | #define P_OSR_02 0x02 45 | #define P_OSR_04 0x03 46 | #define P_OSR_08 0x04 47 | #define P_OSR_16 0x05 48 | 49 | #define H_OSR_01 0x01 50 | #define H_OSR_02 0x02 51 | #define H_OSR_04 0x03 52 | #define H_OSR_08 0x04 53 | #define H_OSR_16 0x05 54 | 55 | #define T_OSR_01 0x01 56 | #define T_OSR_02 0x02 57 | #define T_OSR_04 0x03 58 | #define T_OSR_08 0x04 59 | #define T_OSR_16 0x05 60 | 61 | #define full 0x00 62 | #define BW0_223ODR 0x01 63 | #define BW0_092ODR 0x02 64 | #define BW0_042ODR 0x03 65 | #define BW0_021ODR 0x04 66 | 67 | #define Sleep 0x00 68 | #define Forced 0x01 69 | #define Forced2 0x02 70 | #define Normal 0x03 71 | 72 | #define t_00_5ms 0x00 73 | #define t_62_5ms 0x01 74 | #define t_125ms 0x02 75 | #define t_250ms 0x03 76 | #define t_500ms 0x04 77 | #define t_1000ms 0x05 78 | #define t_10ms 0x06 79 | #define t_20ms 0x07 80 | 81 | class BME280 82 | { 83 | public: 84 | BME280(I2Cdev *i2c_bus); 85 | uint8_t getChipID(); 86 | void reset(); 87 | int32_t readTemperature(); 88 | int32_t readPressure(); 89 | int32_t readHumidity(); 90 | void forced(); 91 | void init(uint8_t Posr, uint8_t Hosr, uint8_t Tosr, uint8_t Mode, uint8_t IIRFilter, uint8_t SBy); 92 | int32_t compensate_T(int32_t adc_T); 93 | uint32_t compensate_P(int32_t adc_P); 94 | uint32_t compensate_H(int32_t adc_H); 95 | 96 | private: 97 | uint8_t _dig_H1, _dig_H3, _dig_H6; 98 | uint16_t _dig_T1, _dig_P1, _dig_H4, _dig_H5; 99 | int16_t _dig_T2, _dig_T3, _dig_P2, _dig_P3, _dig_P4, _dig_P5, _dig_P6, _dig_P7, _dig_P8, _dig_P9, _dig_H2; 100 | int32_t _t_fine; 101 | I2Cdev *_i2c_bus; 102 | }; 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /GasCap/AssetTracker_GasCap_v.02e/I2Cdev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Tlera Corp. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal with the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimers. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimers in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Tlera Corp, nor the names of its contributors 17 | * may be used to endorse or promote products derived from this Software 18 | * without specific prior written permission. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 26 | * WITH THE SOFTWARE. 27 | */ 28 | 29 | #ifndef _I2CDEV_H_ 30 | #define _I2CDEV_H_ 31 | 32 | #include 33 | 34 | class I2Cdev 35 | { 36 | public: 37 | I2Cdev(TwoWire *); 38 | ~I2Cdev(); // Class destructor for durable instances 39 | uint8_t readByte(uint8_t address, uint8_t subAddress); 40 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t *dest); 41 | void writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); 42 | void writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t count, uint8_t *dest); 43 | void I2Cscan(); 44 | uint8_t pollAddress(uint8_t address); 45 | 46 | private: 47 | TwoWire *_i2c_bus; // Class constructor argument 48 | }; 49 | 50 | #endif //_I2CDEV_H_ 51 | -------------------------------------------------------------------------------- /GasCap/AssetTracker_GasCap_v.02e/LIS2DW12.h: -------------------------------------------------------------------------------- 1 | /* 9/18/21 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | * The LIS2DW12 is an inexpensive (~$1), three-axis, medium-resolution (12- or 14-bit), ultra-low power 6 | * (<1 uA low power mode) accelerometer in a tiny 2 mm x 2 mm LGA12 package with a 192-byte FIFO, 7 | * two multifunction interrupts and widely configurable sample rate (1.6 - 1600 Hz), full range (2 - 16 g), 8 | * low power modes, and interrupt detection behaviors. This accelerometer is nice choice for motion-based 9 | * wake/sleep, tap detection, step counting, and simple orientation estimation. 10 | * 11 | * Library may be used freely and without limit with attribution. 12 | * 13 | */ 14 | 15 | #ifndef LIS2DW12_h 16 | #define LIS2DW12_h 17 | 18 | #include "Arduino.h" 19 | #include "I2Cdev.h" 20 | #include 21 | 22 | /* Register Map LIS2DW12 23 | // https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-LIS2DW12-DS000-02.pdf 24 | */ 25 | #define LIS2DW12_OUT_T_L 0x0D 26 | #define LIS2DW12_OUT_T_H 0x0E 27 | #define LIS2DW12_WHO_AM_I 0x0F // should be 0x44 28 | #define LIS2DW12_CTRL1 0x20 29 | #define LIS2DW12_CTRL2 0x21 30 | #define LIS2DW12_CTRL3 0x22 31 | #define LIS2DW12_CTRL4_INT1_PAD_CTRL 0x23 32 | #define LIS2DW12_CTRL5_INT2_PAD_CTRL 0x24 33 | #define LIS2DW12_CTRL6 0x25 34 | #define LIS2DW12_OUT_T 0x26 35 | #define LIS2DW12_STATUS 0x27 36 | #define LIS2DW12_OUT_X_L 0x28 37 | #define LIS2DW12_OUT_X_H 0x29 38 | #define LIS2DW12_OUT_Y_L 0x2A 39 | #define LIS2DW12_OUT_Y_H 0x2B 40 | #define LIS2DW12_OUT_Z_L 0x2C 41 | #define LIS2DW12_OUT_Z_H 0x2D 42 | #define LIS2DW12_FIFO_CTRL 0x2E 43 | #define LIS2DW12_FIFO_SAMPLES 0x2F 44 | #define LIS2DW12_TAP_THS_X 0x30 45 | #define LIS2DW12_TAP_THS_Y 0x31 46 | #define LIS2DW12_TAP_THS_Z 0x32 47 | #define LIS2DW12_INT_DUR 0x33 48 | #define LIS2DW12_WAKE_UP_THS 0x34 49 | #define LIS2DW12_WAKE_UP_DUR 0x35 50 | #define LIS2DW12_FREE_FALL 0x36 51 | #define LIS2DW12_STATUS_DUP 0x37 52 | #define LIS2DW12_WAKE_UP_SRC 0x38 53 | #define LIS2DW12_TAP_SRC 0x39 54 | #define LIS2DW12_SIXD_SRC 0x3A 55 | #define LIS2DW12_ALL_INT_SRC 0x3B 56 | #define LIS2DW12_X_OFS_USR 0x3C 57 | #define LIS2DW12_Y_OFS_USR 0x3D 58 | #define LIS2DW12_Z_OFS_USR 0x3E 59 | #define LIS2DW12_CTRL_REG7 0x3F 60 | 61 | 62 | #define LIS2DW12_ADDRESS 0x19 // if ADO is 1 (default since internally pulled up by ~30 kOhm resistor) 63 | // #define LIS2DW12_ADDRESS 0x18 // if ADO is pulled to GND 64 | 65 | typedef enum { 66 | LIS2DW12_LP_MODE_1 = 0x00, 67 | LIS2DW12_LP_MODE_2 = 0x01, 68 | LIS2DW12_LP_MODE_3 = 0x02, 69 | LIS2DW12_LP_MODE_4 = 0x03 70 | } LPMODE; 71 | 72 | 73 | typedef enum { 74 | LIS2DW12_MODE_LOW_POWER = 0x00, 75 | LIS2DW12_MODE_HIGH_PERF = 0x01, 76 | LIS2DW12_MODE_SINGLE_CONV = 0x02 77 | } MODE; 78 | 79 | 80 | typedef enum { 81 | LIS2DW12_ODR_POWER_DOWN = 0x00, 82 | LIS2DW12_ODR_12_5_1_6HZ = 0x01, 83 | LIS2DW12_ODR_12_5Hz = 0x02, 84 | LIS2DW12_ODR_25Hz = 0x03, 85 | LIS2DW12_ODR_50Hz = 0x04, 86 | LIS2DW12_ODR_100Hz = 0x05, 87 | LIS2DW12_ODR_200Hz = 0x06, 88 | LIS2DW12_ODR_400_200Hz = 0x07, 89 | LIS2DW12_ODR_800_200Hz = 0x08, 90 | LIS2DW12_ODR_1600_200Hz = 0x09 91 | } ODR; 92 | 93 | 94 | typedef enum { 95 | LIS2DW12_FS_2G = 0x00, 96 | LIS2DW12_FS_4G = 0x01, 97 | LIS2DW12_FS_8G = 0x02, 98 | LIS2DW12_FS_16G = 0x03 99 | } FS; 100 | 101 | 102 | typedef enum { 103 | LIS2DW12_BW_FILT_ODR2 = 0x00, 104 | LIS2DW12_BW_FILT_ODR4 = 0x01, 105 | LIS2DW12_BW_FILT_ODR10 = 0x02, 106 | LIS2DW12_BW_FILT_ODR20 = 0x03 107 | } BW_FILT; 108 | 109 | 110 | typedef enum { 111 | BYPASS = 0x00, 112 | FIFO = 0x01, 113 | CONT_TO_FIFO = 0x03, 114 | BYPASS_TO_CONT = 0x04, 115 | CONTINUOUS = 0x06 116 | } FIFOMODE; 117 | 118 | 119 | 120 | class LIS2DW12 121 | { 122 | public: 123 | LIS2DW12(I2Cdev* i2c_bus); 124 | uint8_t getChipID(); 125 | void init(uint8_t fs, uint8_t odr, uint8_t mode, uint8_t lpMode, uint8_t bw, bool lowNoise); 126 | void Compensation(uint8_t fs, uint8_t odr, uint8_t mode, uint8_t lpMode, uint8_t bw, bool lowNoise, float * offset); 127 | void reset(); 128 | void selfTest(float * destination); 129 | void readAccelData(int16_t * destination); 130 | int16_t readTempData(); 131 | uint8_t readRawTempData(); 132 | void activateNoMotionInterrupt(); 133 | void deactivateNoMotionInterrupt(); 134 | uint8_t getStatus(); 135 | void powerDown(); 136 | void powerUp(uint8_t odr); 137 | uint8_t getWakeSource(); 138 | void configureFIFO(uint8_t FIFOMode, uint8_t FIFOThreshold); 139 | uint8_t FIFOsamples(); 140 | 141 | private: 142 | float _aRes; 143 | I2Cdev* _i2c_bus; 144 | }; 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /GasCap/AssetTracker_GasCap_v.02e/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(uint8_t *dest); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp, int pn); 74 | void flash_read_pages(unsigned char *p, int pn, const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p, int pn, const int n_pages); 76 | 77 | private: 78 | uint8_t _csPin; 79 | unsigned char flash_wait_for_write = 0; 80 | }; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /GasCap/GasCap.v01f.schematics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriswiner/CMWX1ZZABZ/ed8b70dd992d7130fc21175beab8a3ec1e173b53/GasCap/GasCap.v01f.schematics.pdf -------------------------------------------------------------------------------- /GasCap/GasCap.v02f.BOM.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriswiner/CMWX1ZZABZ/ed8b70dd992d7130fc21175beab8a3ec1e173b53/GasCap/GasCap.v02f.BOM.csv -------------------------------------------------------------------------------- /GasCap/Readme.md: -------------------------------------------------------------------------------- 1 | The **GasCap Asset Tracker** is inspired by the GPS position tracker hidden in a car's gas cap featured in the *Breaking Bad* spin-off *[Better Call Saul](https://www.thewrap.com/better-call-saul-mike-just-explained/)*. The fictional device requires some kind of large military receiver and such a system (if it even existed) would likely cost 100x what the LoRaWAN-enabled GasCap Asset Tracker costs. 2 | 3 | "[Typical](https://www.walmart.com/ip/Stant-OEM-Replacement-Fuel-Cap-10834/44580281?athcpid=44580281&athpgid=AthenaItempage&athcgid=null&athznid=siext&athieid=v0&athstid=CS004&athguid=wWXGV-gRkWU2q6UUWRoStCm3JRDTDs7Vwa6c&athancid=null&athena=true)" gas cap shell outer dimensions (lots of variation here) are 2 5/8 inch wide by 1 5/8 inch deep (or ~67 mm x ~41 mm); I sized the device to fit within these dimensions while being powered by a single AA-sized 3.6 V, 2400 mAH LiSOCl2 battery. This would allow the device to remain in operation for weeks or months, depending on the GNSS duty cycle. 4 | 5 | While I don't seriously expect anyone to install one of these devices into a car gas cap, it will fit in some surprisingly tight spaces. And at just 7.1 g w/o battery, it is light enough to enable small animal tracking; at 16 mm x 62 mm, unobtrusive enough to enable bicycle tracking; and at less than $90, inexpensive enough to satisfy the requirements of many position tracking use cases. 6 | 7 | ![GasCap.v02f](https://user-images.githubusercontent.com/6698410/213895220-9aa72419-d91f-4d79-871d-34e62ef75ffd.jpg) 8 | 9 | Ultra-low-power, 16 mm x 62 mm asset tracker consisting of CMWX1ZZABZ-078 (SX1276 LoRa radio and STM32L082 host MCU), 10 | CAM M8Q concurrent GNSS module, MX25R6435 8 MByte SPI NOR flash memory for data logging, LIS2DW12 accelerometer for wake-on-motion/sleep-on-no-motion functionality, and BME280 for P/T/H environmental sensing. 11 | 12 | Use the **Cricket** board variant and Thomas Roell's superb [Arduino core](https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0) to program the GasCap via USB and the Arduino IDE. 13 | 14 | I use the SPIFlash_Test sketch to erase the flash before data logging. One could also construct a circular buffer and block erase in a FIFO scheme. Simply erasing the whole flash and page writing every 256 bytes starting on page 1 is the simplest way and the one I have been using. 15 | 16 | Use the readSPIFlash sketch to decode the logged data into comma-delimited CSV suitable for plotting in a spreadsheet. 17 | 18 | Available for sale on [Tindie](https://www.tindie.com/products/tleracorp/gascap-loragnss-asset-tracker/)! 19 | 20 | I measured the following power usage for the first hour of operation with 32 MHz CPU clock, 5 minute GNSS interval and an EPHE GNSS sleep criterion of 40 using the sketch above. 21 | 22 | ![GasCap Power Usage](https://user-images.githubusercontent.com/6698410/239995207-2bb264f2-0468-4393-9bd0-bcd967eb0693.png) 23 | 24 | Average power usage for the first 12 GNSS location fixes is 7.32 mA, which means <0.61 mA per fix. GasCap sleep current with watchdog accelerometer and GNSS backup on is ~17.5 uA. More typically, the average current usage over several days is less such that with one GNSS fix every two hours, average current usage would be ~250 uA. 25 | 26 | Copyright 2022 Tlera Corporation 27 | -------------------------------------------------------------------------------- /GasCap/readSPIFlash_GasCapAssetTracker/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include "SPI.h" 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void powerUp(); 61 | void getChipID(); 62 | void write_pause(void); 63 | int page_to_address(int pn); 64 | int address_to_page(int addr); 65 | void flash_read_id(unsigned char *idt); 66 | unsigned char flash_read_status(void); 67 | void flash_hard_reset(void); 68 | void flash_chip_erase(boolean wait); 69 | void flash_erase_pages_sector(int pn); 70 | void flash_erase_pages_block32k(int pn); 71 | void flash_erase_pages_block64k(int pn); 72 | void flash_page_program(unsigned char *wp, int pn); 73 | void flash_read_pages(unsigned char *p, int pn, const int n_pages); 74 | void flash_fast_read_pages(unsigned char *p, int pn, const int n_pages); 75 | 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /Gnat/AssetTracker_Gnat.v03d/Gnat.03d.schematics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriswiner/CMWX1ZZABZ/ed8b70dd992d7130fc21175beab8a3ec1e173b53/Gnat/AssetTracker_Gnat.v03d/Gnat.03d.schematics.pdf -------------------------------------------------------------------------------- /Gnat/AssetTracker_Gnat.v03d/I2Cdev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Tlera Corp. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal with the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimers. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimers in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Tlera Corp, nor the names of its contributors 17 | * may be used to endorse or promote products derived from this Software 18 | * without specific prior written permission. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 26 | * WITH THE SOFTWARE. 27 | */ 28 | 29 | #ifndef _I2CDEV_H_ 30 | #define _I2CDEV_H_ 31 | 32 | #include 33 | 34 | class I2Cdev { 35 | public: 36 | I2Cdev(TwoWire*); 37 | ~I2Cdev(); // Class destructor for durable instances 38 | uint8_t readByte(uint8_t address, uint8_t subAddress); 39 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 40 | void writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); 41 | void writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t count, uint8_t *dest); 42 | void I2Cscan(); 43 | private: 44 | TwoWire* _i2c_bus; // Class constructor argument 45 | }; 46 | 47 | #endif //_I2CDEV_H_ 48 | -------------------------------------------------------------------------------- /Gnat/AssetTracker_Gnat.v03d/LIS2DW12.h: -------------------------------------------------------------------------------- 1 | /* 9/18/21 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | * The LIS2DW12 is an inexpensive (~$1), three-axis, medium-resolution (12- or 14-bit), ultra-low power 6 | * (<1 uA low power mode) accelerometer in a tiny 2 mm x 2 mm LGA12 package with a 192-byte FIFO, 7 | * two multifunction interrupts and widely configurable sample rate (1.6 - 1600 Hz), full range (2 - 16 g), 8 | * low power modes, and interrupt detection behaviors. This accelerometer is nice choice for motion-based 9 | * wake/sleep, tap detection, step counting, and simple orientation estimation. 10 | * 11 | * Library may be used freely and without limit with attribution. 12 | * 13 | */ 14 | 15 | #ifndef LIS2DW12_h 16 | #define LIS2DW12_h 17 | 18 | #include "Arduino.h" 19 | #include "I2CDev.h" 20 | #include 21 | 22 | /* Register Map LIS2DW12 23 | // https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-LIS2DW12-DS000-02.pdf 24 | */ 25 | #define LIS2DW12_OUT_T_L 0x0D 26 | #define LIS2DW12_OUT_T_H 0x0E 27 | #define LIS2DW12_WHO_AM_I 0x0F // should be 0x44 28 | #define LIS2DW12_CTRL1 0x20 29 | #define LIS2DW12_CTRL2 0x21 30 | #define LIS2DW12_CTRL3 0x22 31 | #define LIS2DW12_CTRL4_INT1_PAD_CTRL 0x23 32 | #define LIS2DW12_CTRL5_INT2_PAD_CTRL 0x24 33 | #define LIS2DW12_CTRL6 0x25 34 | #define LIS2DW12_OUT_T 0x26 35 | #define LIS2DW12_STATUS 0x27 36 | #define LIS2DW12_OUT_X_L 0x28 37 | #define LIS2DW12_OUT_X_H 0x29 38 | #define LIS2DW12_OUT_Y_L 0x2A 39 | #define LIS2DW12_OUT_Y_H 0x2B 40 | #define LIS2DW12_OUT_Z_L 0x2C 41 | #define LIS2DW12_OUT_Z_H 0x2D 42 | #define LIS2DW12_FIFO_CTRL 0x2E 43 | #define LIS2DW12_FIFO_SAMPLES 0x2F 44 | #define LIS2DW12_TAP_THS_X 0x30 45 | #define LIS2DW12_TAP_THS_Y 0x31 46 | #define LIS2DW12_TAP_THS_Z 0x32 47 | #define LIS2DW12_INT_DUR 0x33 48 | #define LIS2DW12_WAKE_UP_THS 0x34 49 | #define LIS2DW12_WAKE_UP_DUR 0x35 50 | #define LIS2DW12_FREE_FALL 0x36 51 | #define LIS2DW12_STATUS_DUP 0x37 52 | #define LIS2DW12_WAKE_UP_SRC 0x38 53 | #define LIS2DW12_TAP_SRC 0x39 54 | #define LIS2DW12_SIXD_SRC 0x3A 55 | #define LIS2DW12_ALL_INT_SRC 0x3B 56 | #define LIS2DW12_X_OFS_USR 0x3C 57 | #define LIS2DW12_Y_OFS_USR 0x3D 58 | #define LIS2DW12_Z_OFS_USR 0x3E 59 | #define LIS2DW12_CTRL_REG7 0x3F 60 | 61 | 62 | #define LIS2DW12_ADDRESS 0x19 // if ADO is 1 (default since internally pulled up by ~30 kOhm resistor) 63 | // #define LIS2DW12_ADDRESS 0x18 // if ADO is pulled to GND 64 | 65 | typedef enum { 66 | LIS2DW12_LP_MODE_1 = 0x00, 67 | LIS2DW12_LP_MODE_2 = 0x01, 68 | LIS2DW12_LP_MODE_3 = 0x02, 69 | LIS2DW12_LP_MODE_4 = 0x03 70 | } LPMODE; 71 | 72 | 73 | typedef enum { 74 | LIS2DW12_MODE_LOW_POWER = 0x00, 75 | LIS2DW12_MODE_HIGH_PERF = 0x01, 76 | LIS2DW12_MODE_SINGLE_CONV = 0x02 77 | } MODE; 78 | 79 | 80 | typedef enum { 81 | LIS2DW12_ODR_POWER_DOWN = 0x00, 82 | LIS2DW12_ODR_12_5_1_6HZ = 0x01, 83 | LIS2DW12_ODR_12_5Hz = 0x02, 84 | LIS2DW12_ODR_25Hz = 0x03, 85 | LIS2DW12_ODR_50Hz = 0x04, 86 | LIS2DW12_ODR_100Hz = 0x05, 87 | LIS2DW12_ODR_200Hz = 0x06, 88 | LIS2DW12_ODR_400_200Hz = 0x07, 89 | LIS2DW12_ODR_800_200Hz = 0x08, 90 | LIS2DW12_ODR_1600_200Hz = 0x09 91 | } ODR; 92 | 93 | 94 | typedef enum { 95 | LIS2DW12_FS_2G = 0x00, 96 | LIS2DW12_FS_4G = 0x01, 97 | LIS2DW12_FS_8G = 0x02, 98 | LIS2DW12_FS_16G = 0x03 99 | } FS; 100 | 101 | 102 | typedef enum { 103 | LIS2DW12_BW_FILT_ODR2 = 0x00, 104 | LIS2DW12_BW_FILT_ODR4 = 0x01, 105 | LIS2DW12_BW_FILT_ODR10 = 0x02, 106 | LIS2DW12_BW_FILT_ODR20 = 0x03 107 | } BW_FILT; 108 | 109 | 110 | typedef enum { 111 | BYPASS = 0x00, 112 | FIFO = 0x01, 113 | CONT_TO_FIFO = 0x03, 114 | BYPASS_TO_CONT = 0x04, 115 | CONTINUOUS = 0x06 116 | } FIFOMODE; 117 | 118 | 119 | 120 | class LIS2DW12 121 | { 122 | public: 123 | LIS2DW12(I2Cdev* i2c_bus); 124 | uint8_t getChipID(); 125 | void init(uint8_t fs, uint8_t odr, uint8_t mode, uint8_t lpMode, uint8_t bw, bool lowNoise); 126 | void Compensation(uint8_t fs, uint8_t odr, uint8_t mode, uint8_t lpMode, uint8_t bw, bool lowNoise, float * offset); 127 | void reset(); 128 | void selfTest(float * destination); 129 | void readAccelData(int16_t * destination); 130 | int16_t readTempData(); 131 | void activateNoMotionInterrupt(); 132 | void deactivateNoMotionInterrupt(); 133 | uint8_t getStatus(); 134 | void powerDown(); 135 | void powerUp(uint8_t odr); 136 | uint8_t getWakeSource(); 137 | void configureFIFO(uint8_t FIFOMode, uint8_t FIFOThreshold); 138 | uint8_t FIFOsamples(); 139 | 140 | private: 141 | float _aRes; 142 | I2Cdev* _i2c_bus; 143 | }; 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /Gnat/AssetTracker_Gnat.v03d/readme.md: -------------------------------------------------------------------------------- 1 | Newly redesigned Gnat.v03d 2 | 3 | ![Gnat v.03d top](https://user-images.githubusercontent.com/6698410/184700709-015d5128-973a-4eb7-bca8-28984120e0fd.jpg) 4 | 5 | ![Gnat.v03d bottom](https://user-images.githubusercontent.com/6698410/184700747-68b2873b-2f5d-41ef-9c2c-3c4938003d30.jpg) 6 | 7 | Same basic design using the CMWX1ZZABZ-078 LoRaWAN module and MAX M8Q-0-10 GNSS engine. 8 | Replaced the LDOs with the super low Iq (25 nA) TPS7A031 and the wake-on-motion accelerometer with the LIS2DW12. 9 | 10 | Design was created using Altium Designer so there is a step file with the design available for planning enclosures, etc. 11 | 12 | Gnat.v03d available for purchase on [Tindie](https://www.tindie.com/products/tleracorp/gnat-loragnss-asset-tracker/). 13 | -------------------------------------------------------------------------------- /Gnat/Readme.md: -------------------------------------------------------------------------------- 1 | Ultra-low power 20 mm x 20 mm asset tracker consisting of CMWX1ZZABZ (SX1276 LoRa radio and STM32L082 host MCU), 2 | MAX M8Q concurrent GNSS module, BMA400 accelerometer for wake-on-motion/sleep-on-no-motion functionality. 3 | 4 | ![GnatTop](https://user-images.githubusercontent.com/6698410/47467809-f637d100-d7ac-11e8-96e4-18dce376081b.jpg) 5 | ![GnatBottom](https://user-images.githubusercontent.com/6698410/47467808-f506a400-d7ac-11e8-9fa0-d7acf583e157.jpg) 6 | 7 | Molex PicoBlade connector exposes 3V3/GND/SDA/SCL as well as two digital pins (SWD/UART) and two analog pins for connecting daughter boards. 8 | 9 | Total sleep current is 2.5 uA with BMA400 motion watchdog continuously monitoring state of motion. 10 | Total current with LoRaWAN updated every 10 minutes and GNSS updated every two hours is < 250 uA. 11 | 12 | Full power control on the MAX M8Q with GPIO-enabled VDD through a dedicated 3.0 V LDO and a separate GPIO-enabled RTC backup. MAX M8Q may be 13 | powered down with RTC backup to allow hot start fixes every four hours (when ephemeris expires) or less. 14 | The MAX M8Q RTC backup can also be powered off with zero current draw for cold fixes at longer-than-4-hour intervals. 15 | 16 | Gnat is wired to support LoRa (FSK, GFSK, LoRa radio), LoRaWAN, and SigFox. 17 | 18 | External [whip](https://www.mouser.com/ProductDetail/Anaren/66089-0930?qs=pH7abCSN9NM0tHwbfikfEQ%3d%3d) (LoRa) and active [patch](https://www.mouser.com/ProductDetail/Inventek/ACTPAT184-01-IP?qs=sGAEpiMZZMuBTKBKvsBmlN73K%2f2BcYXlCZkEPYT616pzDXusmnq0TA%3d%3d) (GNSS) antennas are required. 19 | 20 | Board is intended to be powered by a 1S 3.7 V LiPo battery but any source between 3.6 and 5.5 V will do. 21 | [LiSOCl2](https://www.eemb.com/battery/primary-battery/li-socl2-battery.html) batteries are ideal for long-term deployment. A 2600 mAH 3.6 V LiSOCl2 AA-sized battery @ 1 location fix per day will last more than ten years. 22 | 23 | Programmable via the USB connector using the Arduino IDE, of course! 24 | -------------------------------------------------------------------------------- /Grasshopper/BlinkLEDPWM.ino: -------------------------------------------------------------------------------- 1 | /* LED Blink, Teensyduino Tutorial #1 2 | http://www.pjrc.com/teensy/tutorial.html 3 | 4 | This example code is in the public domain. 5 | */ 6 | // use PWM-capable pins on Grasshopper 7 | const uint8_t ledPin1 = A3; // Red 8 | const uint8_t ledPin2 = A2; // Green 9 | const uint8_t ledPin3 = A4; // Blue 10 | 11 | const boolean invert = false; // set true if common anode, false if common cathode 12 | 13 | uint8_t color = 0; // a value from 0 to 255 representing the hue 14 | uint8_t R, G, B; // the Red Green and Blue color components 15 | uint8_t brightness = 255; // 255 is maximum brightness 16 | 17 | int ii = 0; 18 | 19 | void setup() 20 | { 21 | 22 | for(ii = 0; ii < 256; ii++) { 23 | analogWrite(ledPin1, ii); 24 | delay(10); 25 | } 26 | 27 | for(ii = 0; ii < 256; ii++) { 28 | analogWrite(ledPin1, 255 - ii); 29 | delay(10); 30 | } 31 | 32 | for(ii = 0; ii < 256; ii++) { 33 | analogWrite(ledPin2, ii); 34 | delay(10); 35 | } 36 | 37 | for(ii = 0; ii < 256; ii++) { 38 | analogWrite(ledPin2, 255 - ii); 39 | delay(10); 40 | } 41 | 42 | for(ii = 0; ii < 256; ii++) { 43 | analogWrite(ledPin3, ii); 44 | delay(10); 45 | } 46 | 47 | for(ii = 0; ii < 256; ii++) { 48 | analogWrite(ledPin3, 255 - ii); 49 | delay(10); 50 | } 51 | 52 | } 53 | 54 | void loop() 55 | { 56 | for (color = 0; color < 256; color++) { // Slew through the color spectrum 57 | 58 | hueToRGB(color, brightness); // call function to convert hue to RGB 59 | 60 | // write the RGB values to the pins 61 | analogWrite(ledPin1, R); 62 | analogWrite(ledPin2, G); 63 | analogWrite(ledPin3, B); 64 | 65 | delay(100); 66 | } 67 | 68 | } 69 | 70 | 71 | // Courtesy http://www.instructables.com/id/How-to-Use-an-RGB-LED/?ALLSTEPS 72 | // function to convert a color to its Red, Green, and Blue components. 73 | 74 | void hueToRGB(uint8_t hue, uint8_t brightness) 75 | { 76 | uint16_t scaledHue = (hue * 6); 77 | uint8_t segment = scaledHue / 256; // segment 0 to 5 around the 78 | // color wheel 79 | uint16_t segmentOffset = 80 | scaledHue - (segment * 256); // position within the segment 81 | 82 | uint8_t complement = 0; 83 | uint16_t prev = (brightness * ( 255 - segmentOffset)) / 256; 84 | uint16_t next = (brightness * segmentOffset) / 256; 85 | 86 | if(invert) 87 | { 88 | brightness = 255 - brightness; 89 | complement = 255; 90 | prev = 255 - prev; 91 | next = 255 - next; 92 | } 93 | 94 | switch(segment ) { 95 | case 0: // red 96 | R = brightness; 97 | G = next; 98 | B = complement; 99 | break; 100 | case 1: // yellow 101 | R = prev; 102 | G = brightness; 103 | B = complement; 104 | break; 105 | case 2: // green 106 | R = complement; 107 | G = brightness; 108 | B = next; 109 | break; 110 | case 3: // cyan 111 | R = complement; 112 | G = prev; 113 | B = brightness; 114 | break; 115 | case 4: // blue 116 | R = next; 117 | G = complement; 118 | B = brightness; 119 | break; 120 | case 5: // magenta 121 | default: 122 | R = brightness; 123 | G = complement; 124 | B = prev; 125 | break; 126 | } 127 | } 128 | 129 | -------------------------------------------------------------------------------- /Grasshopper/Blink_Grasshopper.ino: -------------------------------------------------------------------------------- 1 | /* LED Blink, for Grasshopper 2 | 3 | This example code is in the public domain. 4 | */ 5 | #include 6 | 7 | #define myLed 13 // red led 8 | 9 | float VDDA, VBAT, VUSB, Temperature; 10 | uint32_t UID[3] = {0, 0, 0}; 11 | char buffer[32]; 12 | 13 | void setup() 14 | { 15 | Serial.begin(38400); 16 | delay(2000); 17 | Serial.println("Serial enabled!"); 18 | 19 | pinMode(myLed, OUTPUT); 20 | digitalWrite(myLed, LOW); // start with leds off, since active HIGH 21 | 22 | STM32L0.getUID(UID); 23 | Serial.print("STM32L0 MCU UID = 0x"); Serial.print(UID[0], HEX); Serial.print(UID[1], HEX); Serial.println(UID[2], HEX); 24 | LoRaWAN.getDevEui(buffer, 18); 25 | Serial.print("STM32L0 Device EUI = "); Serial.println(buffer); 26 | } 27 | 28 | void loop() 29 | { 30 | digitalWrite(myLed, HIGH); // toggle red led on 31 | delay(100); // wait 100 millisecond 32 | digitalWrite(myLed, LOW); // toggle red led off 33 | delay(1000); // wait 1000 milliseconds 34 | 35 | VDDA = STM32L0.getVDDA(); 36 | VUSB = STM32L0.getVBUS(); 37 | Temperature = STM32L0.getTemperature(); 38 | 39 | // Internal STM32L0 functions 40 | Serial.print("VDDA = "); Serial.println(VDDA, 2); 41 | if(VUSB == 1) Serial.println("USB Connected!"); 42 | Serial.print("STM32L0 MCU Temperature = "); Serial.println(Temperature, 2); 43 | 44 | STM32L0.stop(5000); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Grasshopper/DAC_ADC_Grasshopper.ino: -------------------------------------------------------------------------------- 1 | /* DAC and ADC example, for Grasshopper 2 | 3 | This example code is in the public domain. 4 | */ 5 | #include 6 | #include "LoRaWAN.h" 7 | 8 | #define myLed 13 // red led 9 | 10 | float VDDA, VBUS, Temperature; 11 | uint32_t UID[3] = {0, 0, 0}; 12 | char buffer[32]; 13 | 14 | #define myADC A2 15 | #define myDAC A0 16 | 17 | float DACvalue = 0.0f, ADCvalue = 0.0f; 18 | 19 | void setup() 20 | { 21 | Serial.begin(115200); 22 | delay(2000); 23 | Serial.println("Serial enabled!"); 24 | 25 | pinMode(myLed, OUTPUT); 26 | digitalWrite(myLed, LOW); // start with leds off, since active HIGH 27 | 28 | STM32L0.getUID(UID); 29 | Serial.print("STM32L0 MCU UID = 0x"); Serial.print(UID[0], HEX); Serial.print(UID[1], HEX); Serial.println(UID[2], HEX); 30 | LoRaWAN.getDevEui(buffer, 18); 31 | Serial.print("STM32L0 Device EUI = "); Serial.println(buffer); 32 | 33 | pinMode(myADC, INPUT); 34 | analogReadResolution(12); // 12-bit ADC instead of 8-bit default 35 | pinMode(myDAC, OUTPUT); 36 | 37 | } 38 | 39 | void loop() 40 | { 41 | digitalWrite(myLed, HIGH); // toggle red led on 42 | delay(100); // wait 100 millisecond 43 | digitalWrite(myLed, LOW); // toggle red led off 44 | delay(1000); // wait 1000 milliseconds 45 | 46 | VDDA = STM32L0.getVDDA(); 47 | VBUS = STM32L0.getVBUS(); 48 | Temperature = STM32L0.getTemperature(); 49 | 50 | // Internal STM32L0 functions 51 | Serial.print("VDDA = "); Serial.println(VDDA, 2); 52 | if(VBUS == 1) Serial.println("USB Connected!"); 53 | Serial.print("STM32L0 MCU Temperature = "); Serial.println(Temperature, 2); 54 | 55 | for (int ii = 0; ii <256; ii++) 56 | { 57 | analogWrite(myDAC, ii); // write/read voltage in 3.3/256 V increments every 100 milliseconds 58 | DACvalue = 3.30f * ((float) ii)/255.0f; // should be written 59 | delay(100); 60 | ADCvalue = VDDA * ((float) analogRead(myADC))/4095.0f; // is actually read 61 | Serial.print("DAC output is "); Serial.print(DACvalue, 3); 62 | Serial.print(" V, ADC input is "); Serial.print(ADCvalue, 3);Serial.println(" V"); 63 | // Serial.print(ii); Serial.print(",");Serial.print(DACvalue);Serial.print(",");Serial.println(ADCvalue); 64 | } 65 | 66 | // STM32L0.stop(5000); 67 | } 68 | -------------------------------------------------------------------------------- /Grasshopper/I2CslaveGrasshopper/Grasshopper_Wire_Slave.ino: -------------------------------------------------------------------------------- 1 | /* Wire Slave example (see Wire_Master.ino for the master) 2 | * 3 | * The myReceiveCallback tracking the received data sets 4 | * tx_index into tx_data[], if only one byte had been 5 | * transferred. The myRequestCallback puts 32 bytes from 6 | * tx_data[] starting at tx_index into the transmit buffer. 7 | * Finally the myTransmitCallback adjusts tx_index with 8 | * the number of transferred bytes. 9 | * 10 | * The code roughly simluates a slave device with a FIFO. 11 | * Sunce the myRequestCallback cannot know how many bytes 12 | * need to be send, it fills up the buffer to the max. 13 | * Only at the myTransmitCallback the number of bytes 14 | * transmitted is known. 15 | * 16 | * 17 | * This example code is in the public domain. 18 | */ 19 | 20 | #include "Wire.h" 21 | #include 22 | #include "TimerMillis.h" 23 | 24 | TimerMillis SensorTimer; 25 | 26 | int tx_index = 0; 27 | bool newData = true; 28 | uint8_t intPin = 10, myLed = 13; 29 | 30 | // MCU VDDA and temperature definitions 31 | float VDDA, STM32L0Temp; 32 | 33 | //uint8_t tx_data[] = "The quick brown fox jumps over the lazy dog\r\n"; 34 | uint8_t tx_data[4]; 35 | 36 | void myReceiveCallback(int count) 37 | { 38 | if (count == 1) 39 | { 40 | tx_index = Wire.read(); 41 | 42 | while (tx_index >= sizeof(tx_data)) 43 | { 44 | tx_index -= sizeof(tx_data); 45 | } 46 | } 47 | } 48 | 49 | void myRequestCallback(void) 50 | { 51 | for (int i = 0, n = tx_index; i < BUFFER_LENGTH; i++) 52 | { 53 | Wire.write(tx_data[n]); 54 | 55 | n++; 56 | 57 | if (n >= sizeof(tx_data)) { n = 0; } 58 | } 59 | } 60 | 61 | void myTransmitCallback(int count) 62 | { 63 | tx_index += count; 64 | 65 | while (tx_index >= sizeof(tx_data)) 66 | { 67 | tx_index -= sizeof(tx_data); 68 | } 69 | } 70 | 71 | void mySensorCallback() 72 | { 73 | newData = true; 74 | STM32L0.wakeup(); 75 | } 76 | 77 | void setup() 78 | { 79 | pinMode(myLed, OUTPUT); 80 | digitalWrite(myLed, LOW); // start with led off since active HIGH 81 | pinMode(intPin, OUTPUT); 82 | 83 | Wire.begin(0x7c); 84 | 85 | Wire.onReceive(myReceiveCallback); 86 | Wire.onRequest(myRequestCallback); 87 | Wire.onTransmit(myTransmitCallback); 88 | 89 | SensorTimer.start(mySensorCallback, 1000, 1000); // 1 second period, delayed 1 seconds 90 | } 91 | 92 | void loop() 93 | { 94 | if(newData) 95 | { 96 | newData = false; 97 | 98 | VDDA = STM32L0.getVDDA(); 99 | STM32L0Temp = STM32L0.getTemperature(); 100 | 101 | tx_data[0] = (((uint16_t) (100.0f * VDDA)) & 0xFF00) >> 8; 102 | tx_data[1] = (((uint16_t) (100.0f * VDDA)) & 0x00FF); 103 | tx_data[2] = (((uint16_t) (100.0f * STM32L0Temp)) & 0xFF00) >> 8; 104 | tx_data[3] = (((uint16_t) (100.0f * STM32L0Temp)) & 0x00FF); 105 | 106 | digitalWrite(intPin, HIGH); delay(1); digitalWrite(intPin,LOW); 107 | digitalWrite(myLed, HIGH); delay(1); digitalWrite(myLed,LOW); 108 | } 109 | 110 | STM32L0.stop(); 111 | } 112 | -------------------------------------------------------------------------------- /Grasshopper/I2CslaveGrasshopper/Master_I2C_Dragonfly.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint8_t intPin = 9; 4 | 5 | uint8_t rx_data[4] = {0, 0, 0, 0}; 6 | bool newData = false; 7 | float VDDA = 0.0f, Temp = 0.0f; 8 | 9 | void setup() { 10 | // put your setup code here, to run once: 11 | Serial.begin(115200); 12 | delay(4000); 13 | 14 | pinMode(intPin, INPUT); 15 | 16 | Wire.begin(TWI_PINS_20_21); // set master mode 17 | Wire.setClock(400000); // I2C frequency at 400 kHz 18 | delay(1000); 19 | 20 | I2Cscan(); 21 | 22 | Serial.println("I2C scan done"); 23 | 24 | attachInterrupt(intPin, myInterruptHandler, RISING); 25 | 26 | } 27 | 28 | 29 | void loop() { 30 | 31 | if(newData) 32 | { 33 | newData = false; 34 | 35 | readBytes(0x7C, 4, rx_data); 36 | for (uint8_t i = 0; i < 4; i++) 37 | { 38 | Serial.print("0x"); Serial.println(rx_data[i], HEX); 39 | } 40 | Serial.println(" "); 41 | 42 | VDDA = (float) ( (uint16_t)rx_data[0] << 8 | (uint16_t)rx_data[1] ); 43 | VDDA /= 100.0f; 44 | Temp = (float) ( (uint16_t)rx_data[2] << 8 | (uint16_t)rx_data[3]); 45 | Temp /= 100.0f; 46 | Serial.print(" VDDA = "); Serial.print(VDDA, 2); Serial.println(" V"); 47 | Serial.print(" Temp = "); Serial.print(Temp, 2); Serial.println(" C"); 48 | Serial.println(" "); 49 | } 50 | 51 | } 52 | 53 | // Useful function 54 | 55 | void myInterruptHandler() 56 | { 57 | newData = true; 58 | } 59 | 60 | // I2C scan function 61 | void I2Cscan() 62 | { 63 | // scan for i2c devices 64 | byte error, address; 65 | int nDevices; 66 | 67 | Serial.println("Scanning..."); 68 | 69 | nDevices = 0; 70 | for(address = 1; address < 127; address++ ) 71 | { 72 | // The i2c_scanner uses the return value of 73 | // the Write.endTransmission to see if 74 | // a device did acknowledge to the address. 75 | // Wire.beginTransmission(address); 76 | // error = Wire.endTransmission(); 77 | error = Wire.transfer(address, NULL, 0, NULL, 0); 78 | 79 | if (error == 0) 80 | { 81 | Serial.print("I2C device found at address 0x"); 82 | if (address<16) 83 | Serial.print("0"); 84 | Serial.print(address,HEX); 85 | Serial.println(" !"); 86 | 87 | nDevices++; 88 | } 89 | else if (error==4) 90 | { 91 | Serial.print("Unknown error at address 0x"); 92 | if (address<16) 93 | Serial.print("0"); 94 | Serial.println(address,HEX); 95 | } 96 | } 97 | if (nDevices == 0) 98 | Serial.println("No I2C devices found\n"); 99 | else 100 | Serial.println("done\n"); 101 | 102 | } 103 | 104 | void readBytes(uint8_t address, uint8_t count, uint8_t * dest) 105 | { 106 | Wire.beginTransmission(address); // Initialize the Tx buffer 107 | // Wire.write(subAddress); // Put slave register address in Tx buffer 108 | Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive 109 | uint8_t i = 0; 110 | Wire.requestFrom(address, (size_t) count); // Read bytes from slave register address 111 | while (Wire.available()) 112 | { 113 | dest[i++] = Wire.read(); 114 | } // Put read results in the Rx buffer 115 | } 116 | -------------------------------------------------------------------------------- /Grasshopper/I2CslaveGrasshopper/Readme.md: -------------------------------------------------------------------------------- 1 | Basic example sketch showing how to make use of the Grasshopper (STM32L082) development board as an I2C slave to a Dragonfly (STM32L476) host MCU. 2 | 3 | Grasshopper I2C slave (I2C address 0x7C) is set to read its analog voltage and MCU temperature at 1 Hz, then send a data ready interrupt from slave pin 10 to the master pin 9. The Dragonfly master sets a newData flag in the interrupt handler, checks in the main loop for newData, then reads four bytes from the slave Grasshopper and recostructs the slave temperature and analog voltage, which is output on the serial monitor via master UASB serial. 4 | 5 | This is probably the simplest example of an I2C slave. Missing is a register structure where configuration of the Grasshopper and sensor data could be stored. This would provide a more definite mechanism for the master to configure the data rate, query slave ID, and even send slave data via LoRaWAN, etc. 6 | -------------------------------------------------------------------------------- /Grasshopper/LSM6DSM_LIS2MDL_LPS22HB_Grasshopper/LIS2MDL.h: -------------------------------------------------------------------------------- 1 | /* 09/23/2017 Copyright Tlera Corporation 2 | 3 | Created by Kris Winer 4 | 5 | This sketch uses SDA/SCL on pins 21/20 (Butterfly default), respectively, and it uses the Butterfly STM32L433CU Breakout Board. 6 | The LIS2MDL is a low power magnetometer, here used as 3 DoF in a 9 DoF absolute orientation solution. 7 | 8 | Library may be used freely and without limit with attribution. 9 | 10 | */ 11 | 12 | #ifndef LIS2MDL_h 13 | #define LIS2MDL_h 14 | 15 | #include "Arduino.h" 16 | #include 17 | 18 | //Register map for LIS2MDL' 19 | // http://www.st.com/content/ccc/resource/technical/document/datasheet/group3/29/13/d1/e0/9a/4d/4f/30/DM00395193/files/DM00395193.pdf/jcr:content/translations/en.DM00395193.pdf 20 | #define LIS2MDL_OFFSET_X_REG_L 0x45 21 | #define LIS2MDL_OFFSET_X_REG_L 0x46 22 | #define LIS2MDL_OFFSET_X_REG_L 0x47 23 | #define LIS2MDL_OFFSET_X_REG_L 0x48 24 | #define LIS2MDL_OFFSET_X_REG_L 0x49 25 | #define LIS2MDL_OFFSET_X_REG_L 0x4A 26 | #define LIS2MDL_WHO_AM_I 0x4F 27 | #define LIS2MDL_CFG_REG_A 0x60 28 | #define LIS2MDL_CFG_REG_B 0x61 29 | #define LIS2MDL_CFG_REG_C 0x62 30 | #define LIS2MDL_INT_CTRL_REG 0x63 31 | #define LIS2MDL_INT_SOURCE_REG 0x64 32 | #define LIS2MDL_INT_THS_L_REG 0x65 33 | #define LIS2MDL_INT_THS_H_REG 0x66 34 | #define LIS2MDL_STATUS_REG 0x67 35 | #define LIS2MDL_OUTX_L_REG 0x68 36 | #define LIS2MDL_OUTX_H_REG 0x69 37 | #define LIS2MDL_OUTY_L_REG 0x6A 38 | #define LIS2MDL_OUTY_H_REG 0x6B 39 | #define LIS2MDL_OUTZ_L_REG 0x6C 40 | #define LIS2MDL_OUTZ_H_REG 0x6D 41 | #define LIS2MDL_TEMP_OUT_L_REG 0x6E 42 | #define LIS2MDL_TEMP_OUT_H_REG 0x6F 43 | 44 | #define LIS2MDL_ADDRESS 0x1E 45 | 46 | #define MODR_10Hz 0x00 47 | #define MODR_20Hz 0x01 48 | #define MODR_50Hz 0x02 49 | #define MODR_100Hz 0x03 50 | 51 | 52 | class LIS2MDL 53 | { 54 | public: 55 | LIS2MDL(uint8_t intPin); 56 | uint8_t getChipID(); 57 | void init(uint8_t MODR); 58 | void offsetBias(float * dest1, float * dest2); 59 | void reset(); 60 | void selfTest(); 61 | uint8_t status(); 62 | void readData(int16_t * destination); 63 | int16_t readTemperature(); 64 | void I2Cscan(); 65 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 66 | uint8_t readByte(uint8_t address, uint8_t subAddress); 67 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 68 | private: 69 | uint8_t _intPin; 70 | float _mRes; 71 | 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /Grasshopper/LSM6DSM_LIS2MDL_LPS22HB_Grasshopper/LPS22HB.cpp: -------------------------------------------------------------------------------- 1 | /* 09/23/2017 Copyright Tlera Corporation 2 | 3 | Created by Kris Winer 4 | 5 | This sketch uses SDA/SCL on pins 21/20 (Butterfly default), respectively, and it uses the Butterfly STM32L433CU Breakout Board. 6 | The LPS22HB is a low power barometerr. 7 | 8 | Library may be used freely and without limit with attribution. 9 | 10 | */ 11 | 12 | #include "LPS22HB.h" 13 | #include "Wire.h" 14 | 15 | LPS22H::LPS22H(uint8_t intPin) 16 | { 17 | pinMode(intPin, INPUT); 18 | _intPin = intPin; 19 | } 20 | 21 | uint8_t LPS22H::getChipID() 22 | { 23 | // Read the WHO_AM_I register of the altimeter this is a good test of communication 24 | uint8_t temp = readByte(LPS22H_ADDRESS, LPS22H_WHOAMI); // Read WHO_AM_I register for LPS22H 25 | return temp; 26 | } 27 | 28 | uint8_t LPS22H::status() 29 | { 30 | // Read the status register of the altimeter 31 | uint8_t temp = readByte(LPS22H_ADDRESS, LPS22H_STATUS); 32 | return temp; 33 | } 34 | 35 | int32_t LPS22H::readAltimeterPressure() 36 | { 37 | uint8_t rawData[3]; // 24-bit pressure register data stored here 38 | readBytes(LPS22H_ADDRESS, (LPS22H_PRESS_OUT_XL | 0x80), 3, &rawData[0]); // bit 7 must be one to read multiple bytes 39 | return (int32_t) ((int32_t) rawData[2] << 16 | (int32_t) rawData[1] << 8 | rawData[0]); 40 | } 41 | 42 | int16_t LPS22H::readAltimeterTemperature() 43 | { 44 | uint8_t rawData[2]; // 16-bit pressure register data stored here 45 | readBytes(LPS22H_ADDRESS, (LPS22H_TEMP_OUT_L | 0x80), 2, &rawData[0]); // bit 7 must be one to read multiple bytes 46 | return (int16_t)((int16_t) rawData[1] << 8 | rawData[0]); 47 | } 48 | 49 | 50 | void LPS22H::Init(uint8_t PODR) 51 | { 52 | // set sample rate by setting bits 6:4 53 | // enable low-pass filter by setting bit 3 to one 54 | // bit 2 == 0 means bandwidth is odr/9, bit 2 == 1 means bandwidth is odr/20 55 | // make sure data not updated during read by setting block data udate (bit 1) to 1 56 | writeByte(LPS22H_ADDRESS, LPS22H_CTRL_REG1, PODR << 4 | 0x08 | 0x02); 57 | writeByte(LPS22H_ADDRESS, LPS22H_CTRL_REG3, 0x04); // enable data ready as interrupt source 58 | } 59 | 60 | // I2C scan function 61 | void LPS22H::I2Cscan() 62 | { 63 | // scan for i2c devices 64 | byte error, address; 65 | int nDevices; 66 | 67 | Serial.println("Scanning..."); 68 | 69 | nDevices = 0; 70 | for(address = 1; address < 127; address++ ) 71 | { 72 | // The i2c_scanner uses the return value of 73 | // the Write.endTransmission to see if 74 | // a device did acknowledge to the address. 75 | Wire.beginTransmission(address); 76 | error = Wire.endTransmission(); 77 | 78 | 79 | if (error == 0) 80 | { 81 | Serial.print("I2C device found at address 0x"); 82 | if (address<16) 83 | Serial.print("0"); 84 | Serial.print(address,HEX); 85 | Serial.println(" !"); 86 | 87 | nDevices++; 88 | } 89 | else if (error==4) 90 | { 91 | Serial.print("Unknown error at address 0x"); 92 | if (address<16) 93 | Serial.print("0"); 94 | Serial.println(address,HEX); 95 | } 96 | } 97 | if (nDevices == 0) 98 | Serial.println("No I2C devices found\n"); 99 | else 100 | Serial.println("done\n"); 101 | 102 | } 103 | 104 | void LPS22H::writeByte(uint8_t address, uint8_t subAddress, uint8_t data) 105 | { 106 | Wire.beginTransmission(address); // Initialize the Tx buffer 107 | Wire.write(subAddress); // Put slave register address in Tx buffer 108 | Wire.write(data); // Put data in Tx buffer 109 | Wire.endTransmission(); // Send the Tx buffer 110 | } 111 | 112 | uint8_t LPS22H::readByte(uint8_t address, uint8_t subAddress) 113 | { 114 | uint8_t data; // `data` will store the register data 115 | Wire.beginTransmission(address); // Initialize the Tx buffer 116 | Wire.write(subAddress); // Put slave register address in Tx buffer 117 | Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive 118 | Wire.requestFrom(address, (size_t) 1); // Read one uint8_t from slave register address 119 | data = Wire.read(); // Fill Rx buffer with result 120 | return data; // Return data read from slave register 121 | } 122 | 123 | void LPS22H::readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) 124 | { 125 | Wire.beginTransmission(address); // Initialize the Tx buffer 126 | Wire.write(subAddress); // Put slave register address in Tx buffer 127 | Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive 128 | uint8_t i = 0; 129 | Wire.requestFrom(address, (size_t)count); // Read bytes from slave register address 130 | Wire.read(dest, count); // Put read results in the Rx buffer 131 | } 132 | -------------------------------------------------------------------------------- /Grasshopper/LSM6DSM_LIS2MDL_LPS22HB_Grasshopper/LPS22HB.h: -------------------------------------------------------------------------------- 1 | /* 09/23/2017 Copyright Tlera Corporation 2 | 3 | Created by Kris Winer 4 | 5 | This sketch uses SDA/SCL on pins 21/20 (Butterfly default), respectively, and it uses the Butterfly STM32L433CU Breakout Board. 6 | The LPS22HB is a low power barometerr. 7 | 8 | Library may be used freely and without limit with attribution. 9 | 10 | */ 11 | 12 | #ifndef LPS22HB_h 13 | #define LPS22HB_h 14 | 15 | #include "Arduino.h" 16 | #include "Wire.h" 17 | 18 | // See LPS22H "MEMS pressure sensor: 260-1260 hPa absolute digital output barometer" Data Sheet 19 | // http://www.st.com/content/ccc/resource/technical/document/datasheet/bf/c1/4f/23/61/17/44/8a/DM00140895.pdf/files/DM00140895.pdf/jcr:content/translations/en.DM00140895.pdf 20 | #define LPS22H_INTERRUPT_CFG 0x0B 21 | #define LPS22H_THS_P_L 0x0C 22 | #define LPS22H_THS_P_H 0x0D 23 | #define LPS22H_WHOAMI 0x0F // should return 0xB1 24 | #define LPS22H_CTRL_REG1 0x10 25 | #define LPS22H_CTRL_REG2 0x11 26 | #define LPS22H_CTRL_REG3 0x12 27 | #define LPS22H_FIFO_CTRL 0x14 28 | #define LPS22H_REF_P_XL 0x15 29 | #define LPS22H_REF_P_L 0x16 30 | #define LPS22H_REF_P_H 0x17 31 | #define LPS22H_RPDS_L 0x18 32 | #define LPS22H_RPDS_H 0x19 33 | #define LPS22H_RES_CONF 0x1A 34 | #define LPS22H_INT_SOURCE 0x25 35 | #define LPS22H_FIFO_STATUS 0x26 36 | #define LPS22H_STATUS 0x27 37 | #define LPS22H_PRESS_OUT_XL 0x28 38 | #define LPS22H_PRESS_OUT_L 0x29 39 | #define LPS22H_PRESS_OUT_H 0x2A 40 | #define LPS22H_TEMP_OUT_L 0x2B 41 | #define LPS22H_TEMP_OUT_H 0x2C 42 | #define LPS22H_LPFP_RES 0x33 43 | 44 | #define LPS22H_ADDRESS 0x5C // Address of altimeter 45 | 46 | // Altimeter output data rate 47 | #define P_1shot 0x00; 48 | #define P_1Hz 0x01; 49 | #define P_10Hz 0x02; 50 | #define P_25Hz 0x03; // 25 Hz output data rate 51 | #define P_50Hz 0x04; 52 | #define P_75Hz 0x05; 53 | 54 | class LPS22H 55 | { 56 | public: 57 | LPS22H(uint8_t intPin); 58 | void Init(uint8_t PODR); 59 | uint8_t getChipID(); 60 | uint8_t status(); 61 | int32_t readAltimeterPressure(); 62 | int16_t readAltimeterTemperature(); 63 | void I2Cscan(); 64 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 65 | uint8_t readByte(uint8_t address, uint8_t subAddress); 66 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 67 | private: 68 | uint8_t _intPin; 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /Grasshopper/LSM6DSM_LIS2MDL_LPS22HB_Grasshopper/MadgwickFilter.ino: -------------------------------------------------------------------------------- 1 | // Implementation of Sebastian Madgwick's "...efficient orientation filter for... inertial/magnetic sensor arrays" 2 | // (see http://www.x-io.co.uk/category/open-source/ for examples and more details) 3 | // which fuses acceleration, rotation rate, and magnetic moments to produce a quaternion-based estimate of absolute 4 | // device orientation -- which can be converted to yaw, pitch, and roll. Useful for stabilizing quadcopters, etc. 5 | // The performance of the orientation filter is at least as good as conventional Kalman-based filtering algorithms 6 | // but is much less computationally intensive---it can be performed on a 3.3 V Pro Mini operating at 8 MHz! 7 | __attribute__((optimize("O3"))) void MadgwickQuaternionUpdate(float ax, float ay, float az, float gx, float gy, float gz, float mx, float my, float mz) 8 | { 9 | float q1 = q[0], q2 = q[1], q3 = q[2], q4 = q[3]; // short name local variable for readability 10 | float norm; 11 | float hx, hy, _2bx, _2bz; 12 | float s1, s2, s3, s4; 13 | float qDot1, qDot2, qDot3, qDot4; 14 | 15 | // Auxiliary variables to avoid repeated arithmetic 16 | float _2q1mx; 17 | float _2q1my; 18 | float _2q1mz; 19 | float _2q2mx; 20 | float _4bx; 21 | float _4bz; 22 | float _2q1 = 2.0f * q1; 23 | float _2q2 = 2.0f * q2; 24 | float _2q3 = 2.0f * q3; 25 | float _2q4 = 2.0f * q4; 26 | float _2q1q3 = 2.0f * q1 * q3; 27 | float _2q3q4 = 2.0f * q3 * q4; 28 | float q1q1 = q1 * q1; 29 | float q1q2 = q1 * q2; 30 | float q1q3 = q1 * q3; 31 | float q1q4 = q1 * q4; 32 | float q2q2 = q2 * q2; 33 | float q2q3 = q2 * q3; 34 | float q2q4 = q2 * q4; 35 | float q3q3 = q3 * q3; 36 | float q3q4 = q3 * q4; 37 | float q4q4 = q4 * q4; 38 | 39 | // Normalise accelerometer measurement 40 | norm = sqrtf(ax * ax + ay * ay + az * az); 41 | if (norm == 0.0f) return; // handle NaN 42 | norm = 1.0f/norm; 43 | ax *= norm; 44 | ay *= norm; 45 | az *= norm; 46 | 47 | // Normalise magnetometer measurement 48 | norm = sqrtf(mx * mx + my * my + mz * mz); 49 | if (norm == 0.0f) return; // handle NaN 50 | norm = 1.0f/norm; 51 | mx *= norm; 52 | my *= norm; 53 | mz *= norm; 54 | 55 | // Reference direction of Earth's magnetic field 56 | _2q1mx = 2.0f * q1 * mx; 57 | _2q1my = 2.0f * q1 * my; 58 | _2q1mz = 2.0f * q1 * mz; 59 | _2q2mx = 2.0f * q2 * mx; 60 | hx = mx * q1q1 - _2q1my * q4 + _2q1mz * q3 + mx * q2q2 + _2q2 * my * q3 + _2q2 * mz * q4 - mx * q3q3 - mx * q4q4; 61 | hy = _2q1mx * q4 + my * q1q1 - _2q1mz * q2 + _2q2mx * q3 - my * q2q2 + my * q3q3 + _2q3 * mz * q4 - my * q4q4; 62 | _2bx = sqrtf(hx * hx + hy * hy); 63 | _2bz = -_2q1mx * q3 + _2q1my * q2 + mz * q1q1 + _2q2mx * q4 - mz * q2q2 + _2q3 * my * q4 - mz * q3q3 + mz * q4q4; 64 | _4bx = 2.0f * _2bx; 65 | _4bz = 2.0f * _2bz; 66 | 67 | // Gradient decent algorithm corrective step 68 | s1 = -_2q3 * (2.0f * q2q4 - _2q1q3 - ax) + _2q2 * (2.0f * q1q2 + _2q3q4 - ay) - _2bz * q3 * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (-_2bx * q4 + _2bz * q2) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + _2bx * q3 * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz); 69 | s2 = _2q4 * (2.0f * q2q4 - _2q1q3 - ax) + _2q1 * (2.0f * q1q2 + _2q3q4 - ay) - 4.0f * q2 * (1.0f - 2.0f * q2q2 - 2.0f * q3q3 - az) + _2bz * q4 * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (_2bx * q3 + _2bz * q1) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + (_2bx * q4 - _4bz * q2) * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz); 70 | s3 = -_2q1 * (2.0f * q2q4 - _2q1q3 - ax) + _2q4 * (2.0f * q1q2 + _2q3q4 - ay) - 4.0f * q3 * (1.0f - 2.0f * q2q2 - 2.0f * q3q3 - az) + (-_4bx * q3 - _2bz * q1) * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (_2bx * q2 + _2bz * q4) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + (_2bx * q1 - _4bz * q3) * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz); 71 | s4 = _2q2 * (2.0f * q2q4 - _2q1q3 - ax) + _2q3 * (2.0f * q1q2 + _2q3q4 - ay) + (-_4bx * q4 + _2bz * q2) * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (-_2bx * q1 + _2bz * q3) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + _2bx * q2 * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz); 72 | norm = sqrtf(s1 * s1 + s2 * s2 + s3 * s3 + s4 * s4); // normalise step magnitude 73 | norm = 1.0f/norm; 74 | s1 *= norm; 75 | s2 *= norm; 76 | s3 *= norm; 77 | s4 *= norm; 78 | 79 | // Compute rate of change of quaternion 80 | qDot1 = 0.5f * (-q2 * gx - q3 * gy - q4 * gz) - beta * s1; 81 | qDot2 = 0.5f * (q1 * gx + q3 * gz - q4 * gy) - beta * s2; 82 | qDot3 = 0.5f * (q1 * gy - q2 * gz + q4 * gx) - beta * s3; 83 | qDot4 = 0.5f * (q1 * gz + q2 * gy - q3 * gx) - beta * s4; 84 | 85 | // Integrate to yield quaternion 86 | q1 += qDot1 * deltat; 87 | q2 += qDot2 * deltat; 88 | q3 += qDot3 * deltat; 89 | q4 += qDot4 * deltat; 90 | norm = sqrtf(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4); // normalise quaternion 91 | norm = 1.0f/norm; 92 | q[0] = q1 * norm; 93 | q[1] = q2 * norm; 94 | q[2] = q3 * norm; 95 | q[3] = q4 * norm; 96 | 97 | } 98 | -------------------------------------------------------------------------------- /Grasshopper/LSM6DSM_LIS2MDL_LPS22HB_Grasshopper/Readme.md: -------------------------------------------------------------------------------- 1 | Demonstration of Grasshopper use on a breadboard and running an [all-ST sensor breakout](https://www.tindie.com/products/onehorse/all-st-motion-sensor-breakout-board/) with the LSM6DSM accel/gyro, LIS2MDL magnetometer, and LPS22HB pressure/temperature sensor. The STM32L082 at 32 MHz runs the open-source Madgwick sensor fusion at 680 Hz, which is quite sufficient for ~3 degree heading accuracy with this fine sensor suite when properly calibrated. 2 | 3 | This is a nice test of the interrupt handling capability of the STM32L082 since the three sensors each have a data ready interrupt (the LSM6DSM has one for the accel and one for the gyro, or one for data ready and one for motion detect, etc.) being used here. 4 | 5 | ![GrasshopperBreadboard](https://user-images.githubusercontent.com/6698410/34959692-7793e4ea-f9ec-11e7-8213-1dd3e37eee73.jpg) 6 | -------------------------------------------------------------------------------- /Grasshopper/LoRaWAN_GetDevEUI.ino: -------------------------------------------------------------------------------- 1 | /* Simple getDevEUI 2 | 3 | This example code is in the public domain. 4 | */ 5 | 6 | #include "LoRaWAN.h" 7 | 8 | char buffer[32]; 9 | 10 | void setup( void ) { 11 | Serial.begin(9600); 12 | LoRaWAN.begin(EU868); 13 | Serial.println("devEUI request"); 14 | LoRaWAN.getDevEui(buffer,18); 15 | Serial.println(buffer); 16 | } 17 | 18 | void loop( void ) { 19 | } 20 | -------------------------------------------------------------------------------- /Grasshopper/LoRaWANtest.ino: -------------------------------------------------------------------------------- 1 | #include "LoRaWAN.h" 2 | 3 | #define myLed 13 // red led 4 | 5 | const char *appEui = "70B3D57ED00093FB"; 6 | const char *appKey = "6E47CC3C9B1F7F155600EE8A4FEEAFA3"; 7 | const char *devEui = "4473632393936313"; 8 | 9 | void setup( void ) 10 | { 11 | pinMode(myLed, OUTPUT); 12 | digitalWrite(myLed, LOW); 13 | 14 | /* 15 | - Asia AS923 16 | - Australia AU915 17 | - Europe EU868 18 | - India IN865 19 | - Korea KR920 20 | - US US915 (64 + 8 channels) 21 | */ 22 | LoRaWAN.begin(US915); 23 | LoRaWAN.setADR(false); 24 | LoRaWAN.setDataRate(1); 25 | LoRaWAN.setTxPower(10); 26 | LoRaWAN.setSubBand(2); // for TTN 27 | 28 | LoRaWAN.joinOTAA(appEui, appKey, devEui); 29 | } 30 | 31 | void loop( void ) 32 | { 33 | delay(60000); 34 | 35 | if (!LoRaWAN.busy() && LoRaWAN.joined()) 36 | { 37 | LoRaWAN.beginPacket(3); 38 | LoRaWAN.write(0xef); 39 | LoRaWAN.write(0xbe); 40 | LoRaWAN.write(0xad); 41 | LoRaWAN.write(0xde); 42 | LoRaWAN.endPacket(); 43 | } 44 | 45 | digitalWrite(myLed, HIGH); delay(10); digitalWrite(myLed, LOW); 46 | } 47 | -------------------------------------------------------------------------------- /Grasshopper/RTC_Grasshopper.ino: -------------------------------------------------------------------------------- 1 | /* RTC demo sketch, for Grasshopper 2 | 3 | This example code is in the public domain. 4 | */ 5 | #include 6 | #include 7 | #include 8 | 9 | #define myLed 13 // red led 10 | 11 | float VDDA, Temperature; 12 | uint32_t UID[3] = {0, 0, 0}; 13 | 14 | // RTC set up 15 | /* Change these values to set the current initial time */ 16 | 17 | uint8_t seconds = 0; 18 | uint8_t minutes = 51; 19 | uint8_t hours = 10; 20 | 21 | /* Change these values to set the current initial date */ 22 | 23 | uint8_t day = 14; 24 | uint8_t month = 1; 25 | uint8_t year = 18; 26 | 27 | uint8_t Seconds, Minutes, Hours, Day, Month, Year, count = 0; 28 | 29 | bool alarmFlag = false; 30 | 31 | void setup() 32 | { 33 | Serial.begin(38400); 34 | delay(2000); 35 | Serial.println("Serial enabled!"); 36 | 37 | pinMode(myLed, OUTPUT); 38 | digitalWrite(myLed, LOW); // start with led off, since active HIGH 39 | 40 | STM32L0.getUID(UID); 41 | Serial.print("STM32L0 MCU UID = 0x"); Serial.print(UID[0], HEX); Serial.print(UID[1], HEX);Serial.println(UID[2], HEX); 42 | 43 | // Set the time 44 | RTC.setDay(day); 45 | RTC.setMonth(month); 46 | RTC.setYear(year); 47 | RTC.setHours(hours); 48 | RTC.setMinutes(minutes); 49 | RTC.setSeconds(seconds); 50 | 51 | // set alarm to update the RTC every second 52 | RTC.enableAlarm(RTC.MATCH_ANY); // alarm once a second 53 | 54 | RTC.attachInterrupt(alarmMatch); 55 | 56 | } 57 | 58 | void loop() 59 | { 60 | 61 | if(alarmFlag) { // update RTC output (serial display) whenever the RTC alarm condition is achieved 62 | alarmFlag = false; 63 | 64 | VDDA = STM32L0.getVDDA(); 65 | Temperature = STM32L0.getTemperature(); 66 | 67 | Serial.print("VDDA = "); Serial.println(VDDA, 2); 68 | Serial.print("STM32L0 MCU Temperature = "); Serial.println(Temperature, 2); 69 | 70 | // Read RTC 71 | Serial.println("RTC:"); 72 | Day = RTC.getDay(); 73 | Month = RTC.getMonth(); 74 | Year = RTC.getYear(); 75 | Seconds = RTC.getSeconds(); 76 | Minutes = RTC.getMinutes(); 77 | Hours = RTC.getHours(); 78 | if(Hours < 10) {Serial.print("0"); Serial.print(Hours);} else Serial.print(Hours); 79 | Serial.print(":"); 80 | if(Minutes < 10) {Serial.print("0"); Serial.print(Minutes);} else Serial.print(Minutes); 81 | Serial.print(":"); 82 | if(Seconds < 10) {Serial.print("0"); Serial.println(Seconds);} else Serial.println(Seconds); 83 | 84 | Serial.print(Month); Serial.print("/"); Serial.print(Day); Serial.print("/"); Serial.println(Year); 85 | Serial.println(" "); 86 | 87 | digitalWrite(myLed, HIGH); delay(10); digitalWrite(myLed, LOW); 88 | 89 | STM32L0.stop(); 90 | 91 | } 92 | } 93 | 94 | void alarmMatch() 95 | { 96 | alarmFlag = true; // Just set flag when interrupt received, don't try reading data in an interrupt handler 97 | STM32L0.wakeup(); 98 | } 99 | -------------------------------------------------------------------------------- /Grasshopper/Readme.md: -------------------------------------------------------------------------------- 1 | **Grasshopper** is a small (0.71 " x 1.76") development board with Murata's CMWX1ZZABZ-078 FCC certified module containing ST Microelectronics' STM32L082 32 MHz Cortex M0+ MCU with 192 kByte of flash and 20 kBytes of RAM and Semtech's SX1276 LoRa radio. The development board exposes 19 GPIOs to the user as well as 3V3, GND, VIN, and VREF (for the analog sector), has an indicator led on GPIO 13 as well as a power-on led that can be disabled via a solder jumper for lowest power usage, and has an on-board antenna suitable for either 868 or 915 MHz. See [here](https://hackaday.io/project/35169-hackable-cmwx1zzabz-lora-devices) for more discussion. 2 | 3 | ![Grasshopper](https://user-images.githubusercontent.com/6698410/36012124-d9014574-0d10-11e8-8275-7a671b7dc455.jpg) 4 | 5 | Grasshopper [power consumption](https://hackaday.io/project/35169-hackable-cmwx1zzabz-lora-devices/log/78179-grasshopper-power-usage) is proportional to the CPU clock speed chosen and just 2 uA in stop mode. That's ultra-low power! 6 | 7 | ![GrasshopperPowerUsage](https://cdn.hackaday.io/images/9386191516388081021.JPG) 8 | 9 | [Grasshopper](https://www.tindie.com/products/TleraCorp/grasshopper-lora-development-board/) is available for sale at Tindie. 10 | -------------------------------------------------------------------------------- /LoRaSensorTile/Blink_LoRaSensorTile.ino: -------------------------------------------------------------------------------- 1 | /* LED Blink, for LoRa Sensor Tile 2 | 3 | This example code is in the public domain. 4 | */ 5 | #include 6 | #include 7 | 8 | #define myLed 10 // blue led 9 | 10 | float VDDA, Temperature; 11 | uint32_t UID[3] = {0, 0, 0}; 12 | 13 | void setup() 14 | { 15 | Serial.begin(38400); 16 | delay(2000); 17 | Serial.println("Serial enabled!"); 18 | 19 | pinMode(myLed, OUTPUT); 20 | digitalWrite(myLed, HIGH); // start with leds off, since active LOW 21 | 22 | STM32L0.getUID(UID); 23 | Serial.print("STM32L0 MCU UID = 0x"); Serial.print(UID[0], HEX); Serial.print(UID[1], HEX); Serial.println(UID[2], HEX); 24 | } 25 | 26 | void loop() 27 | { 28 | digitalWrite(myLed, LOW); // toggle blue led on 29 | delay(100); // wait 100 milliseconds 30 | digitalWrite(myLed, HIGH); // toggle blue led off 31 | delay(1000); // wait 1000 milliseconds 32 | 33 | VDDA = STM32L0.getVREF(); 34 | Temperature = STM32L0.getTemperature(); 35 | 36 | Serial.print("VDDA = "); Serial.println(VDDA, 2); 37 | Serial.print("STM32L0 MCU Temperature = "); Serial.println(Temperature, 2); 38 | 39 | // STM32L0.stop(2000); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v02/BMA280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | * The BMA280 is an inexpensive (~$1), three-axis, high-resolution (14-bit) acclerometer in a tiny 2 mm x 2 mm LGA12 package with 32-slot FIFO, 6 | * two multifunction interrupts and widely configurable sample rate (15 - 2000 Hz), full range (2 - 16 g), low power modes, 7 | * and interrupt detection behaviors. This accelerometer is nice choice for low-frequency sound and vibration analysis, 8 | * tap detection and simple orientation estimation. 9 | * 10 | * Library may be used freely and without limit with attribution. 11 | * 12 | */ 13 | 14 | #ifndef BMA280_h 15 | #define BMA280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* Register Map BMA280 21 | // http://www.mouser.com/ds/2/783/BST-BMA280-DS000-11_published-786496.pdf 22 | */ 23 | #define BMA280_BGW_CHIPID 0x00 24 | #define BMA280_ACCD_X_LSB 0x02 25 | #define BMA280_ACCD_X_MSB 0x03 26 | #define BMA280_ACCD_Y_LSB 0x04 27 | #define BMA280_ACCD_Y_MSB 0x05 28 | #define BMA280_ACCD_Z_LSB 0x06 29 | #define BMA280_ACCD_Z_MSB 0x07 30 | #define BMA280_ACCD_TEMP 0x08 31 | #define BMA280_INT_STATUS_0 0x09 32 | #define BMA280_INT_STATUS_1 0x0A 33 | #define BMA280_INT_STATUS_2 0x0B 34 | #define BMA280_INT_STATUS_3 0x0C 35 | #define BMA280_FIFO_STATUS 0x0E 36 | #define BMA280_PMU_RANGE 0x0F 37 | #define BMA280_PMU_BW 0x10 38 | #define BMA280_PMU_LPW 0x11 39 | #define BMA280_PMU_LOW_POWER 0x12 40 | #define BMA280_ACCD_HBW 0x13 41 | #define BMA280_BGW_SOFTRESET 0x14 42 | #define BMA280_INT_EN_0 0x16 43 | #define BMA280_INT_EN_1 0x17 44 | #define BMA280_INT_EN_2 0x18 45 | #define BMA280_INT_MAP_0 0x19 46 | #define BMA280_INT_MAP_1 0x1A 47 | #define BMA280_INT_MAP_2 0x1B 48 | #define BMA280_INT_SRC 0x1E 49 | #define BMA280_INT_OUT_CTRL 0x20 50 | #define BMA280_INT_RST_LATCH 0x21 51 | #define BMA280_INT_0 0x22 52 | #define BMA280_INT_1 0x23 53 | #define BMA280_INT_2 0x24 54 | #define BMA280_INT_3 0x25 55 | #define BMA280_INT_4 0x26 56 | #define BMA280_INT_5 0x27 57 | #define BMA280_INT_6 0x28 58 | #define BMA280_INT_7 0x29 59 | #define BMA280_INT_8 0x2A 60 | #define BMA280_INT_9 0x2B 61 | #define BMA280_INT_A 0x2C 62 | #define BMA280_INT_B 0x2D 63 | #define BMA280_INT_C 0x2E 64 | #define BMA280_INT_D 0x2F 65 | #define BMA280_FIFO_CONFIG_0 0x30 66 | #define BMA280_PMU_SELF_TEST 0x32 67 | #define BMA280_TRIM_NVM_CTRL 0x33 68 | #define BMA280_BGW_SPI3_WDT 0x34 69 | #define BMA280_OFC_CTRL 0x36 70 | #define BMA280_OFC_SETTING 0x37 71 | #define BMA280_OFC_OFFSET_X 0x38 72 | #define BMA280_OFC_OFFSET_Y 0x39 73 | #define BMA280_OFC_OFFSET_Z 0x3A 74 | #define BMA280_TRIM_GP0 0x3B 75 | #define BMA280_TRIM_GP1 0x3C 76 | #define BMA280_FIFO_CONFIG_1 0x3E 77 | #define BMA280_FIFO_DATA 0x3F 78 | 79 | #define BMA280_ADDRESS 0x18 // if ADO is 0 (default) 80 | 81 | #define AFS_2G 0x03 82 | #define AFS_4G 0x05 83 | #define AFS_8G 0x08 84 | #define AFS_16G 0x0C 85 | 86 | #define BW_7_81Hz 0x08 // 15.62 Hz sample rate, etc 87 | #define BW_15_63Hz 0x09 88 | #define BW_31_25Hz 0x0A 89 | #define BW_62_5Hz 0x0B 90 | #define BW_125Hz 0x0C // 250 Hz sample rate 91 | #define BW_250Hz 0x0D 92 | #define BW_500Hz 0x0E 93 | #define BW_1000Hz 0x0F // 2 kHz sample rate == unfiltered data 94 | 95 | #define normal_Mode 0x00 //define power modes 96 | #define deepSuspend_Mode 0x01 97 | #define lowPower_Mode 0x02 98 | #define suspend_Mode 0x04 99 | 100 | #define sleep_0_5ms 0x05 // define sleep duration in low power modes 101 | #define sleep_1ms 0x06 102 | #define sleep_2ms 0x07 103 | #define sleep_4ms 0x08 104 | #define sleep_6ms 0x09 105 | #define sleep_10ms 0x0A 106 | #define sleep_25ms 0x0B 107 | #define sleep_50ms 0x0C 108 | #define sleep_100ms 0x0D 109 | #define sleep_500ms 0x0E 110 | #define sleep_1000ms 0x0F 111 | 112 | class BMA280 113 | { 114 | public: 115 | BMA280(uint8_t intPin1, uint8_t intPin2); 116 | float getAres(uint8_t Ascale); 117 | uint8_t getChipID(); 118 | uint8_t getTapType(); 119 | uint8_t getTapStatus(); 120 | void initBMA280(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, uint8_t sleep_dur); 121 | void fastCompensationBMA280(); 122 | void resetBMA280(); 123 | void selfTestBMA280(); 124 | void readBMA280AccelData(int16_t * destination); 125 | int16_t readBMA280TempData(); 126 | void I2Cscan(); 127 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 128 | uint8_t readByte(uint8_t address, uint8_t subAddress); 129 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 130 | private: 131 | uint8_t _intPin1; 132 | uint8_t _intPin2; 133 | float _aRes; 134 | }; 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v02/BME280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | This sketch uses SDA/SCL on pins 42/43 (back pads), respectively, and it uses the Dragonfly STM32L476RE Breakout Board. 6 | The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution 7 | mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of 8 | only 1 microAmp. The choice will depend on the application. 9 | 10 | Library may be used freely and without limit with attribution. 11 | 12 | */ 13 | 14 | #ifndef BME280_h 15 | #define BME280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* BME280 registers 21 | * http://www.mouser.com/ds/2/783/BST-BME280_DS001-11-844833.pdf 22 | */ 23 | #define BME280_HUM_LSB 0xFE 24 | #define BME280_HUM_MSB 0xFD 25 | #define BME280_TEMP_XLSB 0xFC 26 | #define BME280_TEMP_LSB 0xFB 27 | #define BME280_TEMP_MSB 0xFA 28 | #define BME280_PRESS_XLSB 0xF9 29 | #define BME280_PRESS_LSB 0xF8 30 | #define BME280_PRESS_MSB 0xF7 31 | #define BME280_CONFIG 0xF5 32 | #define BME280_CTRL_MEAS 0xF4 33 | #define BME280_STATUS 0xF3 34 | #define BME280_CTRL_HUM 0xF2 35 | #define BME280_RESET 0xE0 36 | #define BME280_ID 0xD0 // should be 0x60 37 | #define BME280_CALIB00 0x88 38 | #define BME280_CALIB26 0xE1 39 | 40 | #define BME280_ADDRESS 0x77 // Address of BMP280 altimeter when ADO = 0 41 | 42 | 43 | #define P_OSR_01 0x01 44 | #define P_OSR_02 0x02 45 | #define P_OSR_04 0x03 46 | #define P_OSR_08 0x04 47 | #define P_OSR_16 0x05 48 | 49 | #define H_OSR_01 0x01 50 | #define H_OSR_02 0x02 51 | #define H_OSR_04 0x03 52 | #define H_OSR_08 0x04 53 | #define H_OSR_16 0x05 54 | 55 | #define T_OSR_01 0x01 56 | #define T_OSR_02 0x02 57 | #define T_OSR_04 0x03 58 | #define T_OSR_08 0x04 59 | #define T_OSR_16 0x05 60 | 61 | #define full 0x00 62 | #define BW0_223ODR 0x01 63 | #define BW0_092ODR 0x02 64 | #define BW0_042ODR 0x03 65 | #define BW0_021ODR 0x04 66 | 67 | #define Sleep 0x00 68 | #define Forced 0x01 69 | #define Forced2 0x02 70 | #define Normal 0x03 71 | 72 | #define t_00_5ms 0x00 73 | #define t_62_5ms 0x01 74 | #define t_125ms 0x02 75 | #define t_250ms 0x03 76 | #define t_500ms 0x04 77 | #define t_1000ms 0x05 78 | #define t_10ms 0x06 79 | #define t_20ms 0x07 80 | 81 | 82 | class BME280 83 | { 84 | public: 85 | BME280(); 86 | uint8_t getChipID(); 87 | void resetBME280(); 88 | int32_t readBME280Temperature(); 89 | int32_t readBME280Pressure(); 90 | int32_t readBME280Humidity(); 91 | void BME280forced(); 92 | void BME280Init(uint8_t Posr, uint8_t Hosr, uint8_t Tosr, uint8_t Mode, uint8_t IIRFilter, uint8_t SBy); 93 | int32_t BME280_compensate_T(int32_t adc_T); 94 | uint32_t BME280_compensate_P(int32_t adc_P); 95 | uint32_t BME280_compensate_H(int32_t adc_H); 96 | void I2Cscan(); 97 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 98 | uint8_t readByte(uint8_t address, uint8_t subAddress); 99 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 100 | private: 101 | uint8_t _dig_H1, _dig_H3, _dig_H6; 102 | uint16_t _dig_T1, _dig_P1, _dig_H4, _dig_H5; 103 | int16_t _dig_T2, _dig_T3, _dig_P2, _dig_P3, _dig_P4, _dig_P5, _dig_P6, _dig_P7, _dig_P8, _dig_P9, _dig_H2; 104 | int32_t _t_fine; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v02/Readme.md: -------------------------------------------------------------------------------- 1 | This version of the LoRaSensorTile sketch sends BME280 data (pressure, temperature, humidity) as well as battery voltage to the Things Network via LoRaWAN just to demonstrate the process, etc. The data looked like this: 2 | 3 | ![data](https://user-images.githubusercontent.com/6698410/35026323-42420b1e-faff-11e7-9c01-a1dca39500c2.jpg) 4 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v02/SPIFlashClass.h: -------------------------------------------------------------------------------- 1 | /* SPIFlashClass.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlashClass_h 31 | #define SPIFlashClass_h 32 | 33 | #include "Arduino.h" 34 | #include 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlashClass 56 | { 57 | public: 58 | SPIFlashClass(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v02/VEML6040.cpp: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | VEML6040 color sensor senses red, green, blue, and white light and incorporates photodiodes, amplifiers, 6 | and analog / digital circuits into a single chip using CMOS process. With the color sensor applied, 7 | the brightness, and color temperature of backlight can be adjusted base on ambient light source 8 | that makes panel looks more comfortable for end user’s eyes. VEML6040’s adoption of FiltronTM 9 | technology achieves the closest ambient light spectral sensitivity to real human eye responses. 10 | 11 | VEML6040 provides excellent temperature compensation capability for keeping the output stable 12 | under changing temperature. VEML6040’s function are easily operated via the simple command format 13 | of I2C (SMBus compatible) interface protocol. VEML6040’s operating voltage ranges from 2.5 V to 14 | 3.6 V. VEML6040 is packaged in a lead (Pb)-free 4 pin OPLGA package which offers the best market-proven reliability. 15 | 16 | * 17 | * Library may be used freely and without limit with attribution. 18 | * 19 | */ 20 | #include "VEML6040.h" 21 | 22 | VEML6040::VEML6040(){ 23 | } 24 | 25 | 26 | uint16_t VEML6040::getRGBWdata(uint16_t * destination) 27 | { 28 | for (int j = 0; j < 4; j++) 29 | { 30 | uint8_t rawData[2] = {0, 0}; 31 | Wire.beginTransmission(VEML6040_ADDRESS); 32 | Wire.write(VEML6040_R_DATA + j); // Command code for reading rgbw data channels in sequence 33 | Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive 34 | 35 | Wire.requestFrom(VEML6040_ADDRESS, 2); // Read two bytes from slave register address 36 | uint8_t i = 0; 37 | while (Wire.available()) 38 | { 39 | rawData[i++] = Wire.read(); // Put read results in the Rx buffer 40 | } 41 | destination[j] = ((uint16_t) rawData[1] << 8) | rawData[0]; 42 | } 43 | 44 | } 45 | 46 | void VEML6040::enableVEML6040(uint8_t IT) 47 | { 48 | uint8_t MSB = 0x00; 49 | uint8_t data = VEML6040_CONF; 50 | Wire.beginTransmission(VEML6040_ADDRESS); 51 | Wire.write(data); // Command code for configuration register 52 | Wire.write(IT << 4); // Bit 3 must be 0, bit 0 is 0 for run and 1 for shutdown, LS Byte 53 | Wire.write(MSB); // MS Byte 54 | Wire.endTransmission(); 55 | } 56 | 57 | void VEML6040::disableVEML6040(uint8_t IT) 58 | { 59 | uint8_t MSB = 0x00; 60 | uint8_t data = VEML6040_CONF; 61 | Wire.beginTransmission(VEML6040_ADDRESS); 62 | Wire.write(data); // Command code for configuration register 63 | Wire.write(IT << 4 | 0x01); // Bit 3 must be 0, bit 0 is 0 for run and 1 for shutdown, LS Byte 64 | Wire.write(MSB); // MS Byte 65 | Wire.endTransmission(); 66 | } 67 | 68 | // simple function to scan for I2C devices on the bus 69 | void VEML6040::I2Cscan() 70 | { 71 | // scan for i2c devices 72 | byte error, address; 73 | int nDevices; 74 | 75 | Serial.println("Scanning..."); 76 | 77 | nDevices = 0; 78 | for(address = 1; address < 127; address++ ) 79 | { 80 | // The i2c_scanner uses the return value of 81 | // the Write.endTransmisstion to see if 82 | // a device did acknowledge to the address. 83 | Wire.beginTransmission(address); 84 | error = Wire.endTransmission(); 85 | 86 | if (error == 0) 87 | { 88 | Serial.print("I2C device found at address 0x"); 89 | if (address<16) 90 | Serial.print("0"); 91 | Serial.print(address,HEX); 92 | Serial.println(" !"); 93 | 94 | nDevices++; 95 | } 96 | else if (error==4) 97 | { 98 | Serial.print("Unknown error at address 0x"); 99 | if (address<16) 100 | Serial.print("0"); 101 | Serial.println(address,HEX); 102 | } 103 | } 104 | if (nDevices == 0) 105 | Serial.println("No I2C devices found\n"); 106 | else 107 | Serial.println("done\n"); 108 | } 109 | 110 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v02/VEML6040.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | VEML6040 color sensor senses red, green, blue, and white light and incorporates photodiodes, amplifiers, 6 | and analog / digital circuits into a single chip using CMOS process. With the color sensor applied, 7 | the brightness, and color temperature of backlight can be adjusted base on ambient light source 8 | that makes panel looks more comfortable for end user’s eyes. VEML6040’s adoption of FiltronTM 9 | technology achieves the closest ambient light spectral sensitivity to real human eye responses. 10 | 11 | VEML6040 provides excellent temperature compensation capability for keeping the output stable 12 | under changing temperature. VEML6040’s function are easily operated via the simple command format 13 | of I2C (SMBus compatible) interface protocol. VEML6040’s operating voltage ranges from 2.5 V to 14 | 3.6 V. VEML6040 is packaged in a lead (Pb)-free 4 pin OPLGA package which offers the best market-proven reliability. 15 | 16 | Library may be used freely and without limit with attribution. 17 | 18 | */ 19 | 20 | #ifndef VEML6040_h 21 | #define VEML6040_h 22 | 23 | #include "Arduino.h" 24 | #include "Wire.h" 25 | 26 | // http://www.mouser.com/pdfdocs/veml6040.PDF 27 | //////////////////////////// 28 | // VEML6040 Command Codes // 29 | //////////////////////////// 30 | #define VEML6040_CONF 0x00 // command codes 31 | #define VEML6040_R_DATA 0x08 32 | #define VEML6040_G_DATA 0x09 33 | #define VEML6040_B_DATA 0x0A 34 | #define VEML6040_W_DATA 0x0B 35 | 36 | #define VEML6040_ADDRESS 0x10 37 | 38 | #define IT_40 0 // 40 ms 39 | #define IT_80 1 // 80 ms 40 | #define IT_160 2 // 160 ms 41 | #define IT_320 3 // 320 ms 42 | #define IT_640 4 // 640 ms 43 | #define IT_1280 5 // 1280 ms 44 | 45 | class VEML6040 46 | { 47 | public: 48 | VEML6040(); 49 | uint16_t getRGBWdata(uint16_t * destination); 50 | void enableVEML6040(uint8_t IT); 51 | void disableVEML6040(uint8_t IT); 52 | void I2Cscan(); 53 | private: 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v05/BMA280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | * The BMA280 is an inexpensive (~$1), three-axis, high-resolution (14-bit) acclerometer in a tiny 2 mm x 2 mm LGA12 package with 32-slot FIFO, 6 | * two multifunction interrupts and widely configurable sample rate (15 - 2000 Hz), full range (2 - 16 g), low power modes, 7 | * and interrupt detection behaviors. This accelerometer is nice choice for low-frequency sound and vibration analysis, 8 | * tap detection and simple orientation estimation. 9 | * 10 | * Library may be used freely and without limit with attribution. 11 | * 12 | */ 13 | 14 | #ifndef BMA280_h 15 | #define BMA280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* Register Map BMA280 21 | // http://www.mouser.com/ds/2/783/BST-BMA280-DS000-11_published-786496.pdf 22 | */ 23 | #define BMA280_BGW_CHIPID 0x00 24 | #define BMA280_ACCD_X_LSB 0x02 25 | #define BMA280_ACCD_X_MSB 0x03 26 | #define BMA280_ACCD_Y_LSB 0x04 27 | #define BMA280_ACCD_Y_MSB 0x05 28 | #define BMA280_ACCD_Z_LSB 0x06 29 | #define BMA280_ACCD_Z_MSB 0x07 30 | #define BMA280_ACCD_TEMP 0x08 31 | #define BMA280_INT_STATUS_0 0x09 32 | #define BMA280_INT_STATUS_1 0x0A 33 | #define BMA280_INT_STATUS_2 0x0B 34 | #define BMA280_INT_STATUS_3 0x0C 35 | #define BMA280_FIFO_STATUS 0x0E 36 | #define BMA280_PMU_RANGE 0x0F 37 | #define BMA280_PMU_BW 0x10 38 | #define BMA280_PMU_LPW 0x11 39 | #define BMA280_PMU_LOW_POWER 0x12 40 | #define BMA280_ACCD_HBW 0x13 41 | #define BMA280_BGW_SOFTRESET 0x14 42 | #define BMA280_INT_EN_0 0x16 43 | #define BMA280_INT_EN_1 0x17 44 | #define BMA280_INT_EN_2 0x18 45 | #define BMA280_INT_MAP_0 0x19 46 | #define BMA280_INT_MAP_1 0x1A 47 | #define BMA280_INT_MAP_2 0x1B 48 | #define BMA280_INT_SRC 0x1E 49 | #define BMA280_INT_OUT_CTRL 0x20 50 | #define BMA280_INT_RST_LATCH 0x21 51 | #define BMA280_INT_0 0x22 52 | #define BMA280_INT_1 0x23 53 | #define BMA280_INT_2 0x24 54 | #define BMA280_INT_3 0x25 55 | #define BMA280_INT_4 0x26 56 | #define BMA280_INT_5 0x27 57 | #define BMA280_INT_6 0x28 58 | #define BMA280_INT_7 0x29 59 | #define BMA280_INT_8 0x2A 60 | #define BMA280_INT_9 0x2B 61 | #define BMA280_INT_A 0x2C 62 | #define BMA280_INT_B 0x2D 63 | #define BMA280_INT_C 0x2E 64 | #define BMA280_INT_D 0x2F 65 | #define BMA280_FIFO_CONFIG_0 0x30 66 | #define BMA280_PMU_SELF_TEST 0x32 67 | #define BMA280_TRIM_NVM_CTRL 0x33 68 | #define BMA280_BGW_SPI3_WDT 0x34 69 | #define BMA280_OFC_CTRL 0x36 70 | #define BMA280_OFC_SETTING 0x37 71 | #define BMA280_OFC_OFFSET_X 0x38 72 | #define BMA280_OFC_OFFSET_Y 0x39 73 | #define BMA280_OFC_OFFSET_Z 0x3A 74 | #define BMA280_TRIM_GP0 0x3B 75 | #define BMA280_TRIM_GP1 0x3C 76 | #define BMA280_FIFO_CONFIG_1 0x3E 77 | #define BMA280_FIFO_DATA 0x3F 78 | 79 | #define BMA280_ADDRESS 0x18 // if ADO is 0 (default) 80 | 81 | #define AFS_2G 0x03 82 | #define AFS_4G 0x05 83 | #define AFS_8G 0x08 84 | #define AFS_16G 0x0C 85 | 86 | #define BW_7_81Hz 0x08 // 15.62 Hz sample rate, etc 87 | #define BW_15_63Hz 0x09 88 | #define BW_31_25Hz 0x0A 89 | #define BW_62_5Hz 0x0B 90 | #define BW_125Hz 0x0C // 250 Hz sample rate 91 | #define BW_250Hz 0x0D 92 | #define BW_500Hz 0x0E 93 | #define BW_1000Hz 0x0F // 2 kHz sample rate == unfiltered data 94 | 95 | #define normal_Mode 0x00 //define power modes 96 | #define deepSuspend_Mode 0x01 97 | #define lowPower_Mode 0x02 98 | #define suspend_Mode 0x04 99 | 100 | #define lp_mode_1 0x00 // two types of low power mode 101 | #define lp_mode_2 0x40 102 | 103 | #define sleep_0_5ms 0x05 // define sleep duration in low power modes 104 | #define sleep_1ms 0x06 105 | #define sleep_2ms 0x07 106 | #define sleep_4ms 0x08 107 | #define sleep_6ms 0x09 108 | #define sleep_10ms 0x0A 109 | #define sleep_25ms 0x0B 110 | #define sleep_50ms 0x0C 111 | #define sleep_100ms 0x0D 112 | #define sleep_500ms 0x0E 113 | #define sleep_1000ms 0x0F 114 | 115 | class BMA280 116 | { 117 | public: 118 | BMA280(uint8_t intPin1, uint8_t intPin2); 119 | float getAres(uint8_t Ascale); 120 | uint8_t getChipID(); 121 | uint8_t getTapType(); 122 | uint8_t getTapStatus(); 123 | void initBMA280(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, uint8_t sleep_dur); 124 | void initBMA280_MotionManager(uint8_t Ascale, uint8_t BW, uint8_t power_Mode, 125 | uint8_t sleep_dur, uint8_t low_power_Mode, 126 | uint8_t motion_threshold); 127 | void activateNoMotionInterrupt(); 128 | void deactivateNoMotionInterrupt(); 129 | void activateSlopeInterrupt(); 130 | void deactivateSlopeInterrupt(); 131 | void fastCompensationBMA280(); 132 | void resetBMA280(); 133 | void selfTestBMA280(); 134 | void readBMA280AccelData(int16_t * destination); 135 | int16_t readBMA280TempData(); 136 | void I2Cscan(); 137 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 138 | uint8_t readByte(uint8_t address, uint8_t subAddress); 139 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 140 | private: 141 | uint8_t _intPin1; 142 | uint8_t _intPin2; 143 | float _aRes; 144 | }; 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v05/BME280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | This sketch uses SDA/SCL on pins 42/43 (back pads), respectively, and it uses the Dragonfly STM32L476RE Breakout Board. 6 | The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution 7 | mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of 8 | only 1 microAmp. The choice will depend on the application. 9 | 10 | Library may be used freely and without limit with attribution. 11 | 12 | */ 13 | 14 | #ifndef BME280_h 15 | #define BME280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* BME280 registers 21 | * http://www.mouser.com/ds/2/783/BST-BME280_DS001-11-844833.pdf 22 | */ 23 | #define BME280_HUM_LSB 0xFE 24 | #define BME280_HUM_MSB 0xFD 25 | #define BME280_TEMP_XLSB 0xFC 26 | #define BME280_TEMP_LSB 0xFB 27 | #define BME280_TEMP_MSB 0xFA 28 | #define BME280_PRESS_XLSB 0xF9 29 | #define BME280_PRESS_LSB 0xF8 30 | #define BME280_PRESS_MSB 0xF7 31 | #define BME280_CONFIG 0xF5 32 | #define BME280_CTRL_MEAS 0xF4 33 | #define BME280_STATUS 0xF3 34 | #define BME280_CTRL_HUM 0xF2 35 | #define BME280_RESET 0xE0 36 | #define BME280_ID 0xD0 // should be 0x60 37 | #define BME280_CALIB00 0x88 38 | #define BME280_CALIB26 0xE1 39 | 40 | #define BME280_ADDRESS 0x77 // Address of BMP280 altimeter when ADO = 0 41 | 42 | 43 | #define P_OSR_01 0x01 44 | #define P_OSR_02 0x02 45 | #define P_OSR_04 0x03 46 | #define P_OSR_08 0x04 47 | #define P_OSR_16 0x05 48 | 49 | #define H_OSR_01 0x01 50 | #define H_OSR_02 0x02 51 | #define H_OSR_04 0x03 52 | #define H_OSR_08 0x04 53 | #define H_OSR_16 0x05 54 | 55 | #define T_OSR_01 0x01 56 | #define T_OSR_02 0x02 57 | #define T_OSR_04 0x03 58 | #define T_OSR_08 0x04 59 | #define T_OSR_16 0x05 60 | 61 | #define full 0x00 62 | #define BW0_223ODR 0x01 63 | #define BW0_092ODR 0x02 64 | #define BW0_042ODR 0x03 65 | #define BW0_021ODR 0x04 66 | 67 | #define Sleep 0x00 68 | #define Forced 0x01 69 | #define Forced2 0x02 70 | #define Normal 0x03 71 | 72 | #define t_00_5ms 0x00 73 | #define t_62_5ms 0x01 74 | #define t_125ms 0x02 75 | #define t_250ms 0x03 76 | #define t_500ms 0x04 77 | #define t_1000ms 0x05 78 | #define t_10ms 0x06 79 | #define t_20ms 0x07 80 | 81 | 82 | class BME280 83 | { 84 | public: 85 | BME280(); 86 | uint8_t getChipID(); 87 | void resetBME280(); 88 | int32_t readBME280Temperature(); 89 | int32_t readBME280Pressure(); 90 | int32_t readBME280Humidity(); 91 | void BME280forced(); 92 | void BME280Init(uint8_t Posr, uint8_t Hosr, uint8_t Tosr, uint8_t Mode, uint8_t IIRFilter, uint8_t SBy); 93 | int32_t BME280_compensate_T(int32_t adc_T); 94 | uint32_t BME280_compensate_P(int32_t adc_P); 95 | uint32_t BME280_compensate_H(int32_t adc_H); 96 | void I2Cscan(); 97 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 98 | uint8_t readByte(uint8_t address, uint8_t subAddress); 99 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 100 | private: 101 | uint8_t _dig_H1, _dig_H3, _dig_H6; 102 | uint16_t _dig_T1, _dig_P1, _dig_H4, _dig_H5; 103 | int16_t _dig_T2, _dig_T3, _dig_P2, _dig_P3, _dig_P4, _dig_P5, _dig_P6, _dig_P7, _dig_P8, _dig_P9, _dig_H2; 104 | int32_t _t_fine; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v05/Readme.md: -------------------------------------------------------------------------------- 1 | **LoRaSensorTile** 2 | Added the capability to detect wake on any motion and sleep on no motion using the BMA280 accelerometer. The wake and sleep states are used to determine the frequency of activity in the sketch. There is a no-motion timer that will carry out the activity infrequently, like say once an hour or once a day, and there is a in-motion timer that will carry out the activity when motion is detected. This way when the device experiences no motion, presumably due to nothing interesting happening, the data is collected and sent via LoRaWAN at longer intervals to minimize power usage while when motion is detected, presumably an interesting event to track, the data is sent at the higher frequency rate. This has a lot of uses. For example, one could create a motion-activated camera, keep track of or alert when a door or cabinet is opened, when a car or bike is moving, a mailbox is opened, etc. The motion-activation allows the device to expend the least amount of energy (~12 uA is the stop current of the LoRaSensorTile) most of the time while gathering data, sending data, actuating circuits, etc at an appropriate rate when the expected event(s) occur. 3 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v05/SPIFlashClass.h: -------------------------------------------------------------------------------- 1 | /* SPIFlashClass.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlashClass_h 31 | #define SPIFlashClass_h 32 | 33 | #include "Arduino.h" 34 | #include 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlashClass 56 | { 57 | public: 58 | SPIFlashClass(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v05/VEML6040.cpp: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | VEML6040 color sensor senses red, green, blue, and white light and incorporates photodiodes, amplifiers, 6 | and analog / digital circuits into a single chip using CMOS process. With the color sensor applied, 7 | the brightness, and color temperature of backlight can be adjusted base on ambient light source 8 | that makes panel looks more comfortable for end user’s eyes. VEML6040’s adoption of FiltronTM 9 | technology achieves the closest ambient light spectral sensitivity to real human eye responses. 10 | 11 | VEML6040 provides excellent temperature compensation capability for keeping the output stable 12 | under changing temperature. VEML6040’s function are easily operated via the simple command format 13 | of I2C (SMBus compatible) interface protocol. VEML6040’s operating voltage ranges from 2.5 V to 14 | 3.6 V. VEML6040 is packaged in a lead (Pb)-free 4 pin OPLGA package which offers the best market-proven reliability. 15 | 16 | * 17 | * Library may be used freely and without limit with attribution. 18 | * 19 | */ 20 | #include "VEML6040.h" 21 | 22 | VEML6040::VEML6040(){ 23 | } 24 | 25 | 26 | uint16_t VEML6040::getRGBWdata(uint16_t * destination) 27 | { 28 | for (int j = 0; j < 4; j++) 29 | { 30 | uint8_t rawData[2] = {0, 0}; 31 | Wire.beginTransmission(VEML6040_ADDRESS); 32 | Wire.write(VEML6040_R_DATA + j); // Command code for reading rgbw data channels in sequence 33 | Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive 34 | 35 | Wire.requestFrom(VEML6040_ADDRESS, 2); // Read two bytes from slave register address 36 | uint8_t i = 0; 37 | while (Wire.available()) 38 | { 39 | rawData[i++] = Wire.read(); // Put read results in the Rx buffer 40 | } 41 | destination[j] = ((uint16_t) rawData[1] << 8) | rawData[0]; 42 | } 43 | 44 | } 45 | 46 | void VEML6040::enableVEML6040(uint8_t IT) 47 | { 48 | uint8_t MSB = 0x00; 49 | uint8_t data = VEML6040_CONF; 50 | Wire.beginTransmission(VEML6040_ADDRESS); 51 | Wire.write(data); // Command code for configuration register 52 | Wire.write(IT << 4); // Bit 3 must be 0, bit 0 is 0 for run and 1 for shutdown, LS Byte 53 | Wire.write(MSB); // MS Byte 54 | Wire.endTransmission(); 55 | } 56 | 57 | void VEML6040::disableVEML6040(uint8_t IT) 58 | { 59 | uint8_t MSB = 0x00; 60 | uint8_t data = VEML6040_CONF; 61 | Wire.beginTransmission(VEML6040_ADDRESS); 62 | Wire.write(data); // Command code for configuration register 63 | Wire.write(IT << 4 | 0x01); // Bit 3 must be 0, bit 0 is 0 for run and 1 for shutdown, LS Byte 64 | Wire.write(MSB); // MS Byte 65 | Wire.endTransmission(); 66 | } 67 | 68 | // simple function to scan for I2C devices on the bus 69 | void VEML6040::I2Cscan() 70 | { 71 | // scan for i2c devices 72 | byte error, address; 73 | int nDevices; 74 | 75 | Serial.println("Scanning..."); 76 | 77 | nDevices = 0; 78 | for(address = 1; address < 127; address++ ) 79 | { 80 | // The i2c_scanner uses the return value of 81 | // the Write.endTransmisstion to see if 82 | // a device did acknowledge to the address. 83 | Wire.beginTransmission(address); 84 | error = Wire.endTransmission(); 85 | 86 | if (error == 0) 87 | { 88 | Serial.print("I2C device found at address 0x"); 89 | if (address<16) 90 | Serial.print("0"); 91 | Serial.print(address,HEX); 92 | Serial.println(" !"); 93 | 94 | nDevices++; 95 | } 96 | else if (error==4) 97 | { 98 | Serial.print("Unknown error at address 0x"); 99 | if (address<16) 100 | Serial.print("0"); 101 | Serial.println(address,HEX); 102 | } 103 | } 104 | if (nDevices == 0) 105 | Serial.println("No I2C devices found\n"); 106 | else 107 | Serial.println("done\n"); 108 | } 109 | 110 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaSensorTile.v05/VEML6040.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | VEML6040 color sensor senses red, green, blue, and white light and incorporates photodiodes, amplifiers, 6 | and analog / digital circuits into a single chip using CMOS process. With the color sensor applied, 7 | the brightness, and color temperature of backlight can be adjusted base on ambient light source 8 | that makes panel looks more comfortable for end user’s eyes. VEML6040’s adoption of FiltronTM 9 | technology achieves the closest ambient light spectral sensitivity to real human eye responses. 10 | 11 | VEML6040 provides excellent temperature compensation capability for keeping the output stable 12 | under changing temperature. VEML6040’s function are easily operated via the simple command format 13 | of I2C (SMBus compatible) interface protocol. VEML6040’s operating voltage ranges from 2.5 V to 14 | 3.6 V. VEML6040 is packaged in a lead (Pb)-free 4 pin OPLGA package which offers the best market-proven reliability. 15 | 16 | Library may be used freely and without limit with attribution. 17 | 18 | */ 19 | 20 | #ifndef VEML6040_h 21 | #define VEML6040_h 22 | 23 | #include "Arduino.h" 24 | #include "Wire.h" 25 | 26 | // http://www.mouser.com/pdfdocs/veml6040.PDF 27 | //////////////////////////// 28 | // VEML6040 Command Codes // 29 | //////////////////////////// 30 | #define VEML6040_CONF 0x00 // command codes 31 | #define VEML6040_R_DATA 0x08 32 | #define VEML6040_G_DATA 0x09 33 | #define VEML6040_B_DATA 0x0A 34 | #define VEML6040_W_DATA 0x0B 35 | 36 | #define VEML6040_ADDRESS 0x10 37 | 38 | #define IT_40 0 // 40 ms 39 | #define IT_80 1 // 80 ms 40 | #define IT_160 2 // 160 ms 41 | #define IT_320 3 // 320 ms 42 | #define IT_640 4 // 640 ms 43 | #define IT_1280 5 // 1280 ms 44 | 45 | class VEML6040 46 | { 47 | public: 48 | VEML6040(); 49 | uint16_t getRGBWdata(uint16_t * destination); 50 | void enableVEML6040(uint8_t IT); 51 | void disableVEML6040(uint8_t IT); 52 | void I2Cscan(); 53 | private: 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /LoRaSensorTile/LoRaWANtest.ino: -------------------------------------------------------------------------------- 1 | #include "LoRaWAN.h" 2 | 3 | const char *appEui = "70B3D57ED00093FB"; 4 | const char *appKey = "D3FC12149485EA7B9A4D8F5B6484830E"; 5 | const char *devEui = "0101010101010101"; 6 | 7 | void setup( void ) 8 | { 9 | /* 10 | - Asia AS923 11 | - Australia AU915 12 | - Europe EU868 13 | - India IN865 14 | - Korea KR920 15 | - US US915 (64 + 8 channels) 16 | */ 17 | LoRaWAN.begin(US915); // for US, select appropriate region 18 | LoRaWAN.setSubBand(2); // for TTN 19 | 20 | LoRaWAN.joinOTAA(appEui, appKey, devEui); 21 | } 22 | 23 | void loop( void ) 24 | { 25 | delay(10000); 26 | 27 | if (LoRaWAN.connected()) 28 | { 29 | LoRaWAN.beginPacket(3); 30 | LoRaWAN.write(0xef); 31 | LoRaWAN.write(0xbe); 32 | LoRaWAN.write(0xad); 33 | LoRaWAN.write(0xde); 34 | LoRaWAN.endPacket(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LoRaSensorTile/Readme.md: -------------------------------------------------------------------------------- 1 | The LoRa SensorTile is a 23 mm x 23 mm sensor tile with BME280, BMA280, and VEML6040 with 16 MByte SPI flash for logging, STBC08 LiPo battery charger, programmable via USB using the Arduino IDE. See [here](https://hackaday.io/project/35169-hackable-cmwx1zzabz-lora-devices) for more discussion. 2 | 3 | ![LoRaSensorTile_top](https://www.thethingsnetwork.org/forum/uploads/default/optimized/2X/a/a1ecaf75873262e0c6389440567fcd82dbbf9f2f_1_521x500.jpg) 4 | 5 | ![LoRaSensorTile_bottom](https://www.thethingsnetwork.org/forum/uploads/default/optimized/2X/1/1d02002770c579938731e5242924e013e15bc6f4_1_529x500.jpg) 6 | 7 | ![AveragePowerUsage](https://cdn.hackaday.io/images/3908751516424429114.jpg) 8 | 9 | The LoRa SensorTile will be available for sale at Tindie in the Spring. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CMWX1ZZABZ 2 | Collection of Arduino sketches (make sure you have the latest [Ardino core](https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0) installed!) for various devices with embedded CMWX1ZZABZ (STM32L082 and SX1276) as host. The devices include the 18 mm x 45 mm [Grasshopper](https://www.tindie.com/products/TleraCorp/grasshopper-lora-development-board/) development board, the 23 mm x 23 mm LoRa SensorTile, and the 23 mm x 46 mm Cricket Asset Tracker. See [here](https://hackaday.io/project/35169-hackable-cmwx1zzabz-lora-devices) for more discussion. 3 | 4 | ![Grasshopper](https://cdn.tindiemedia.com/images/resize/c_x89ytFnAr30fkHcu39abhKS1A=/p/full-fit-in/2400x1600/i/32456/products/2018-01-13T17%3A24%3A25.696Z-2017-07-12T23-06-47.405Z-Grasshopper.top.jpg) 5 | 6 | ![pinmap](https://cdn.tindiemedia.com/images/resize/p-ocqSG5bsCiji8X8jmffaipCYs=/p/full-fit-in/2400x1600/i/32456/products/2017-07-13T19%3A34%3A48.587Z-Grasshopper.pinmap.jpg) 7 | -------------------------------------------------------------------------------- /SBUS Grasshopper - En.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriswiner/CMWX1ZZABZ/ed8b70dd992d7130fc21175beab8a3ec1e173b53/SBUS Grasshopper - En.pdf -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/I2CDev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Tlera Corp. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal with the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimers. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimers in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Tlera Corp, nor the names of its contributors 17 | * may be used to endorse or promote products derived from this Software 18 | * without specific prior written permission. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 26 | * WITH THE SOFTWARE. 27 | */ 28 | 29 | #ifndef _I2CDEV_H_ 30 | #define _I2CDEV_H_ 31 | 32 | #include 33 | 34 | class I2Cdev { 35 | public: 36 | I2Cdev(TwoWire*); 37 | ~I2Cdev(); // Class destructor for durable instances 38 | uint8_t readByte(uint8_t address, uint8_t subAddress); 39 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 40 | void writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); 41 | void writeCommand(uint8_t devAddr, uint8_t command, bool hold); 42 | void writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t count, uint8_t *dest); 43 | void I2Cscan(); 44 | private: 45 | TwoWire* _i2c_bus; // Class constructor argument 46 | }; 47 | 48 | #endif //_I2CDEV_H_ 49 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/LIS2MDL.h: -------------------------------------------------------------------------------- 1 | /* 09/23/2017 Copyright Tlera Corporation 2 | 3 | Created by Kris Winer 4 | 5 | This sketch uses SDA/SCL on pins 21/20 (Butterfly default), respectively, and it uses the Butterfly STM32L433CU Breakout Board. 6 | The LIS2MDL is a low power magnetometer, here used as 3 DoF in a 9 DoF absolute orientation solution. 7 | 8 | Library may be used freely and without limit with attribution. 9 | 10 | */ 11 | 12 | #ifndef LIS2MDL_h 13 | #define LIS2MDL_h 14 | 15 | #include "Arduino.h" 16 | #include 17 | #include "I2CDev.h" 18 | 19 | //Register map for LIS2MDL' 20 | // http://www.st.com/content/ccc/resource/technical/document/datasheet/group3/29/13/d1/e0/9a/4d/4f/30/DM00395193/files/DM00395193.pdf/jcr:content/translations/en.DM00395193.pdf 21 | 22 | #define LIS2MDL_OFFSET_X_REG_L 0x45 23 | #define LIS2MDL_OFFSET_X_REG_L 0x46 24 | #define LIS2MDL_OFFSET_X_REG_L 0x47 25 | #define LIS2MDL_OFFSET_X_REG_L 0x48 26 | #define LIS2MDL_OFFSET_X_REG_L 0x49 27 | #define LIS2MDL_OFFSET_X_REG_L 0x4A 28 | #define LIS2MDL_WHO_AM_I 0x4F // should be 0x40 29 | #define LIS2MDL_CFG_REG_A 0x60 30 | #define LIS2MDL_CFG_REG_B 0x61 31 | #define LIS2MDL_CFG_REG_C 0x62 32 | #define LIS2MDL_INT_CTRL_REG 0x63 33 | #define LIS2MDL_INT_SOURCE_REG 0x64 34 | #define LIS2MDL_INT_THS_L_REG 0x65 35 | #define LIS2MDL_INT_THS_H_REG 0x66 36 | #define LIS2MDL_STATUS_REG 0x67 37 | #define LIS2MDL_OUTX_L_REG 0x68 38 | #define LIS2MDL_OUTX_H_REG 0x69 39 | #define LIS2MDL_OUTY_L_REG 0x6A 40 | #define LIS2MDL_OUTY_H_REG 0x6B 41 | #define LIS2MDL_OUTZ_L_REG 0x6C 42 | #define LIS2MDL_OUTZ_H_REG 0x6D 43 | 44 | #define LIS2MDL_ADDRESS 0x1E 45 | 46 | #define MODR_10Hz 0x00 47 | #define MODR_20Hz 0x01 48 | #define MODR_50Hz 0x02 49 | #define MODR_100Hz 0x03 50 | 51 | 52 | class LIS2MDL 53 | { 54 | public: 55 | LIS2MDL(I2Cdev* i2c_bus); 56 | uint8_t getChipID(); 57 | void init(uint8_t MODR); 58 | void offsetBias(float * dest1, float * dest2); 59 | void reset(); 60 | void selfTest(); 61 | uint8_t status(); 62 | void readData(int16_t * destination); 63 | private: 64 | float _mRes; 65 | I2Cdev* _i2c_bus; 66 | }; 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/LSM303AGR.h: -------------------------------------------------------------------------------- 1 | /* 09/23/2017 Copyright Tlera Corporation 2 | 3 | Created by Kris Winer 4 | 5 | This sketch uses SDA/SCL on pins 21/20 (Butterfly default), respectively, and it uses the Butterfly STM32L433CU Breakout Board. 6 | The LSM303AGR is a sensor hub with embedded accel and gyro, here used as 6 DoF in a 9 DoF absolute orientation solution. 7 | 8 | Library may be used freely and without limit with attribution. 9 | 10 | */ 11 | 12 | #ifndef LSM303AGR_h 13 | #define LSM303AGR_h 14 | 15 | #include "Arduino.h" 16 | #include 17 | #include "I2CDev.h" 18 | 19 | //Register map for LSM303AGR' 20 | //https://www.st.com/content/ccc/resource/technical/document/datasheet/74/c4/19/54/62/c5/46/13/DM00177685.pdf/files/DM00177685.pdf/jcr:content/translations/en.DM00177685.pdf 21 | 22 | #define LSM303AGR_STATUS_REG_AUX_A 0x07 23 | #define LSM303AGR_OUT_TEMP_L_A 0x0C 24 | #define LSM303AGR_OUT_TEMP_H_A 0x0D 25 | #define LSM303AGR_INT_COUNTER_REG_A 0x0E 26 | #define LSM303AGR_WHO_AM_I 0x0F // should return 0x33 27 | #define LSM303AGR_TMP_CFG_REG_A 0x1F 28 | #define LSM303AGR_CTRL_REG1_A 0x20 29 | #define LSM303AGR_CTRL_REG2_A 0x21 30 | #define LSM303AGR_CTRL_REG3_A 0x22 31 | #define LSM303AGR_CTRL_REG4_A 0x23 32 | #define LSM303AGR_CTRL_REG5_A 0x24 33 | #define LSM303AGR_CTRL_REG6_A 0x25 34 | #define LSM303AGR_REF_DATACAPTURE_A 0x26 35 | #define LSM303AGR_STATUS_REG_A 0x27 36 | #define LSM303AGR_OUT_X_L_A 0x28 37 | #define LSM303AGR_OUT_X_H_A 0x29 38 | #define LSM303AGR_OUT_Y_L_A 0x2A 39 | #define LSM303AGR_OUT_Y_H_A 0x2B 40 | #define LSM303AGR_OUT_Z_L_A 0x2C 41 | #define LSM303AGR_OUT_Z_H_A 0x2D 42 | #define LSM303AGR_FIFO_CTRL_REG_A 0x2E 43 | #define LSM303AGR_FIFO_SRC_REG_A 0x2F 44 | #define LSM303AGR_INT1_CFG_A 0x30 45 | #define LSM303AGR_INT1_SRC_A 0x31 46 | #define LSM303AGR_INT1_THS_A 0x32 47 | #define LSM303AGR_INT1_DUR_A 0x33 48 | #define LSM303AGR_INT2_CFG_A 0x34 49 | #define LSM303AGR_INT2_SRC_A 0x35 50 | #define LSM303AGR_INT2_THS_A 0x36 51 | #define LSM303AGR_INT2_DUR_A 0x37 52 | #define LSM303AGR_CLICK_CFG_A 0x38 53 | #define LSM303AGR_CLICK_SRC_A 0x39 54 | #define LSM303AGR_CLICK_THS_A 0x3A 55 | #define LSM303AGR_TIME_LIMIT_A 0x3B 56 | #define LSM303AGR_TIME_LATENCY_A 0x3C 57 | #define LSM303AGR_TIME_WNDOW_A 0x3D 58 | #define LSM303AGR_ACT_THS_A 0x3E 59 | #define LSM303AGR_ACT_DUR_A 0x3F 60 | 61 | #define LSM303AGR_ADDRESS 0x19 // Address of LSM303AGR accel/gyro when ADO = 0 62 | 63 | #define AFS_2G 0x00 64 | #define AFS_4G 0x01 65 | #define AFS_8G 0x02 66 | #define AFS_16G 0x03 67 | 68 | #define AODR_1Hz 0x01 69 | #define AODR_10Hz 0x02 70 | #define AODR_25Hz 0x03 71 | #define AODR_50Hz 0x04 72 | #define AODR_100Hz 0x05 73 | #define AODR_200Hz 0x06 74 | #define AODR_400Hz 0x07 75 | #define AODR_1620Hz 0x08 // low power mode only 76 | #define AODR_5376Hz 0x09 // low power mode only 77 | #define AODR_1344Hz 0x09 // normal/ HR power mode only 78 | 79 | class LSM303AGR 80 | { 81 | public: 82 | LSM303AGR(I2Cdev* i2c_bus); 83 | float getAres(uint8_t Ascale); 84 | void reset(); 85 | uint8_t getChipID(); 86 | void init(uint8_t Ascale, uint8_t AODR); 87 | void offsetBias(float * dest); 88 | void selfTest(); 89 | void readAccData(int16_t * destination); 90 | int16_t readAccTempData(); 91 | private: 92 | float _aRes; 93 | I2Cdev* _i2c_bus; 94 | }; 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/MS5803.cpp: -------------------------------------------------------------------------------- 1 | /* 07/01/2019 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | The MS5803-14BA is a new generation of high resolution pressure sensors with SPI and I2C bus interface. 6 | It is optimized for depth measurement systems with a water depth resolution of 1cm and below. The sensor 7 | module includes a high linear pressure sensor and an ultra low power 24 bit ΔΣ ADC with 8 | internal factory calibrated coefficients. It provides a precise digital 24 Bit pressure and 9 | temperature value and different operation modes that allow the user to optimize for conversion 10 | speed and current consumption. A high resolution temperature output allows the implementation of 11 | a depth measurement systems and thermometer function without any additional sensor. 12 | The MS5803-14BA can be interfaced to any microcontroller. The communication protocol is simple, 13 | without the need to programming internal registers in the device. The gel protection and 14 | antimagnetic stainless steel cap protects against 30 bar overpressure water resistant. 15 | 16 | https://www.te.com/commerce/DocumentDelivery/DDEController?Action=showdoc&DocId=Data+Sheet%7FMS5803-01BA%7FB3%7Fpdf%7FEnglish%7FENG_DS_MS5803-01BA_B3.pdf%7FCAT-BLPS0038 17 | https://www.parallax.com/sites/default/files/downloads/29124-APPNote_520_C_code.pdf 18 | 19 | Library may be used freely and without limit with attribution. 20 | 21 | */ 22 | 23 | #include "MS5803.h" 24 | #include "I2Cdev.h" 25 | 26 | MS5803::MS5803(I2Cdev* i2c_bus) 27 | { 28 | _i2c_bus = i2c_bus; 29 | } 30 | 31 | 32 | void MS5803::Reset() 33 | { 34 | _i2c_bus->writeCommand(MS5803_ADDRESS, MS5803_RESET, true); 35 | } 36 | 37 | 38 | uint32_t MS5803::DataRead(uint8_t CMD, uint8_t OSR) 39 | { 40 | uint8_t data[3] = {0,0,0}; 41 | _i2c_bus->writeCommand(MS5803_ADDRESS, CMD | OSR, false); 42 | 43 | switch (OSR) 44 | { 45 | case ADC_256: delay(1); break; // delay for conversion to complete 46 | case ADC_512: delay(3); break; 47 | case ADC_1024: delay(4); break; 48 | case ADC_2048: delay(6); break; 49 | case ADC_4096: delay(10); break; 50 | } 51 | 52 | _i2c_bus->readBytes(MS5803_ADDRESS, MS5803_ADC_READ, 3, &data[0]);// Put read results in the Rx buffer 53 | return (uint32_t) (((uint32_t) data[0] << 16) | (uint32_t) data[1] << 8 | data[2]); // construct PROM data for return to main program 54 | } 55 | 56 | 57 | void MS5803::PromRead(uint16_t * destination) 58 | { 59 | uint8_t data[2] = {0,0}; 60 | for (uint8_t ii = 0; ii < 8; ii++) 61 | { 62 | _i2c_bus->readBytes(MS5803_ADDRESS, 0xA0 | ii << 1, 2, &data[0]);// Put read results in the Rx buffer 63 | destination[ii] = (uint16_t) (((uint16_t) data[0] << 8) | data[1]); // construct PROM data for return to main program 64 | } 65 | } 66 | 67 | 68 | unsigned char MS5803::checkCRC(uint16_t * n_prom) 69 | { 70 | int cnt; 71 | unsigned int n_rem; 72 | unsigned int crc_read; 73 | unsigned char n_bit; 74 | 75 | n_rem = 0x00; 76 | crc_read = n_prom[7]; 77 | n_prom[7] = ( 0xFF00 & ( n_prom[7] ) ); 78 | 79 | for (cnt = 0; cnt < 16; cnt++) 80 | { // choose LSB or MSB 81 | if ( cnt%2 == 1 ) n_rem ^= (unsigned short) ( ( n_prom[cnt>>1] ) & 0x00FF ); 82 | else n_rem ^= (unsigned short) ( n_prom[cnt>>1] >> 8 ); 83 | for ( n_bit = 8; n_bit > 0; n_bit-- ) 84 | { 85 | if ( n_rem & ( 0x8000 ) ) 86 | { 87 | n_rem = ( n_rem << 1 ) ^ 0x3000; 88 | } 89 | else { 90 | n_rem = ( n_rem << 1 ); 91 | } 92 | } 93 | } 94 | 95 | n_rem = ( 0x000F & ( n_rem >> 12 ) );// // final 4-bit remainder is CRC code 96 | n_prom[7] = crc_read; // restore the crc_read to its original place 97 | 98 | return ( n_rem ^ 0x00 ); // The calculated CRC should match what the device initally returned. 99 | } 100 | 101 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/MS5803.h: -------------------------------------------------------------------------------- 1 | /* 07/01/2019 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | The MS5803-14BA is a new generation of high resolution pressure sensors with SPI and I2C bus interface. 6 | It is optimized for depth measurement systems with a water depth resolution of 1cm and below. The sensor 7 | module includes a high linear pressure sensor and an ultra low power 24 bit ΔΣ ADC with 8 | internal factory calibrated coefficients. It provides a precise digital 24 Bit pressure and 9 | temperature value and different operation modes that allow the user to optimize for conversion 10 | speed and current consumption. A high resolution temperature output allows the implementation of 11 | a depth measurement systems and thermometer function without any additional sensor. 12 | The MS5803-14BA can be interfaced to any microcontroller. The communication protocol is simple, 13 | without the need to programming internal registers in the device. The gel protection and 14 | antimagnetic stainless steel cap protects against 30 bar overpressure water resistant. 15 | 16 | Library may be used freely and without limit with attribution. 17 | 18 | */ 19 | 20 | #ifndef MS5803_h 21 | #define MS5803_h 22 | 23 | #include "Arduino.h" 24 | #include "Wire.h" 25 | #include "I2Cdev.h" 26 | 27 | // 28 | //////////////////////////// 29 | // MS5803 Command Codes // 30 | //////////////////////////// 31 | // See MS5803-302BA Low Voltage Barometric Pressure Sensor Data Sheet 32 | // http://www.mouser.com/ds/2/418/MS5803-30BA-736494.pdf 33 | #define MS5803_RESET 0x1E 34 | #define MS5803_CONVERT_D1 0x40 35 | #define MS5803_CONVERT_D2 0x50 36 | #define MS5803_ADC_READ 0x00 37 | 38 | #define MS5803_ADDRESS 0x77 // Address of altimeter 39 | 40 | #define ADC_256 0x00 // define pressure and temperature conversion rates 41 | #define ADC_512 0x02 42 | #define ADC_1024 0x04 43 | #define ADC_2048 0x06 44 | #define ADC_4096 0x08 45 | 46 | #define ADC_D1 0x40 47 | #define ADC_D2 0x50 48 | 49 | class MS5803 50 | { 51 | public: 52 | MS5803(I2Cdev* i2c_bus); 53 | void Reset(); 54 | void PromRead(uint16_t * destination); 55 | uint32_t DataRead(uint8_t CMD, uint8_t OSR); 56 | unsigned char checkCRC(uint16_t * n_prom); 57 | private: 58 | I2Cdev* _i2c_bus; 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/MS5837.cpp: -------------------------------------------------------------------------------- 1 | /* 07/01/2019 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | The MS5837-30BA is a new generation of high resolution pressure sensors with I2C bus interface for 6 | depth measurement systems with a water depth resolution of 2 mm. The sensor module includes a high linearity 7 | pressure sensor and an ultra-lowpower 24 bit ΔΣADC with internal factory calibrated coefficients. It provides 8 | a precise digital 24 Bit pressure and temperature value and different operation modes that allow the user to 9 | optimize for conversion speed and current consumption. A high resolution temperature output allows the 10 | implementation in depth measurement systems and thermometer function without any additional sensor. 11 | The MS5837-30BA can be interfaced to virtually any microcontroller. The communication protocol is simple, 12 | without the need of programming internal registers in the device. The gel protection and antimagnetic stainless 13 | steel cap make the module water resistant. 14 | 15 | Library may be used freely and without limit with attribution. 16 | 17 | */ 18 | 19 | #include "MS5837.h" 20 | #include "I2Cdev.h" 21 | 22 | MS5837::MS5837(I2Cdev* i2c_bus) 23 | { 24 | _i2c_bus = i2c_bus; 25 | } 26 | 27 | 28 | void MS5837::Reset() 29 | { 30 | _i2c_bus->writeCommand(MS5837_ADDRESS, MS5837_RESET, true); 31 | } 32 | 33 | 34 | uint32_t MS5837::DataRead(uint8_t CMD, uint8_t OSR) 35 | { 36 | uint8_t data[3] = {0,0,0}; 37 | _i2c_bus->writeCommand(MS5837_ADDRESS, CMD | OSR, false); 38 | 39 | switch (OSR) 40 | { 41 | case ADC_256: delay(1); break; // delay for conversion to complete 42 | case ADC_512: delay(3); break; 43 | case ADC_1024: delay(4); break; 44 | case ADC_2048: delay(6); break; 45 | case ADC_4096: delay(10); break; 46 | case ADC_8192: delay(20); break; 47 | } 48 | 49 | _i2c_bus->readBytes(MS5837_ADDRESS, MS5837_ADC_READ, 3, &data[0]);// Put read results in the Rx buffer 50 | return (uint32_t) (((uint32_t) data[0] << 16) | (uint32_t) data[1] << 8 | data[2]); // construct PROM data for return to main program 51 | } 52 | 53 | 54 | void MS5837::PromRead(uint16_t * destination) 55 | { 56 | uint8_t data[2] = {0,0}; 57 | for (uint8_t ii = 0; ii < 7; ii++) 58 | { 59 | _i2c_bus->readBytes(MS5837_ADDRESS, 0xA0 | ii << 1, 2, &data[0]);// Put read results in the Rx buffer 60 | destination[ii] = (uint16_t) (((uint16_t) data[0] << 8) | data[1]); // construct PROM data for return to main program 61 | } 62 | } 63 | 64 | 65 | unsigned char MS5837::checkCRC(uint16_t * n_prom) 66 | { 67 | int cnt; 68 | unsigned int n_rem = 0; 69 | unsigned char n_bit; 70 | 71 | n_prom[0] = ((n_prom[0]) & 0x0FFF); // replace CRC byte by 0 for checksum calculation 72 | n_prom[7] = 0; 73 | for(cnt = 0; cnt < 16; cnt++) 74 | { 75 | if(cnt%2==1) n_rem ^= (unsigned short) ((n_prom[cnt>>1]) & 0x00FF); 76 | else n_rem ^= (unsigned short) (n_prom[cnt>>1]>>8); 77 | for(n_bit = 8; n_bit > 0; n_bit--) 78 | { 79 | if(n_rem & 0x8000) n_rem = (n_rem<<1) ^ 0x3000; 80 | else n_rem = (n_rem<<1); 81 | } 82 | } 83 | n_rem = ((n_rem>>12) & 0x000F); 84 | return (n_rem ^ 0x00); 85 | } 86 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/MS5837.h: -------------------------------------------------------------------------------- 1 | /* 07/01/2019 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | The MS5837-30BA is a new generation of high resolution pressure sensors with I2C bus interface for 6 | depth measurement systems with a water depth resolution of 2 mm. The sensor module includes a high linearity 7 | pressure sensor and an ultra-lowpower 24 bit ΔΣADC with internal factory calibrated coefficients. It provides 8 | a precise digital 24 Bit pressure and temperature value and different operation modes that allow the user to 9 | optimize for conversion speed and current consumption. A high resolution temperature output allows the 10 | implementation in depth measurement systems and thermometer function without any additional sensor. 11 | The MS5837-30BA can be interfaced to virtually any microcontroller. The communication protocol is simple, 12 | without the need of programming internal registers in the device. The gel protection and antimagnetic stainless 13 | steel cap make the module water resistant. 14 | 15 | Library may be used freely and without limit with attribution. 16 | 17 | */ 18 | 19 | #ifndef MS5837_h 20 | #define MS5837_h 21 | 22 | #include "Arduino.h" 23 | #include "Wire.h" 24 | #include "I2Cdev.h" 25 | 26 | // 27 | //////////////////////////// 28 | // MS5837 Command Codes // 29 | //////////////////////////// 30 | // See MS5837-302BA Low Voltage Barometric Pressure Sensor Data Sheet 31 | // http://www.mouser.com/ds/2/418/MS5837-30BA-736494.pdf 32 | #define MS5837_RESET 0x1E 33 | #define MS5837_CONVERT_D1 0x40 34 | #define MS5837_CONVERT_D2 0x50 35 | #define MS5837_ADC_READ 0x00 36 | 37 | #define MS5837_ADDRESS 0x76 // Address of altimeter 38 | 39 | #define ADC_256 0x00 // define pressure and temperature conversion rates 40 | #define ADC_512 0x02 41 | #define ADC_1024 0x04 42 | #define ADC_2048 0x06 43 | #define ADC_4096 0x08 44 | #define ADC_8192 0x0A 45 | #define ADC_D1 0x40 46 | #define ADC_D2 0x50 47 | 48 | class MS5837 49 | { 50 | public: 51 | MS5837(I2Cdev* i2c_bus); 52 | void Reset(); 53 | void PromRead(uint16_t * destination); 54 | uint32_t DataRead(uint8_t CMD, uint8_t OSR); 55 | unsigned char checkCRC(uint16_t * n_prom); 56 | private: 57 | I2Cdev* _i2c_bus; 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/VEML6030.cpp: -------------------------------------------------------------------------------- 1 | /* 07/01/2019 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | VEML6030 is a high accuracy ambient light digital 16-bit resolution sensor in a miniature transparent 6 | 2 mm x 2 mm package. It includes a high sensitive photodiode, a low noise amplifier, a 16-bit A/D 7 | converter and supports an easy to use I2C bus communication interface and additional interrupt feature. 8 | 9 | VEML6030’s functions are easily operated via the simple command format 10 | of I2C (SMBus compatible) interface protocol. VEML6030’s operating voltage ranges from 2.5 V to 11 | 3.6 V. 12 | 13 | Library may be used freely and without limit with attribution. 14 | 15 | */ 16 | #include "VEML6030.h" 17 | #include "I2Cdev.h" 18 | 19 | VEML6030::VEML6030(I2Cdev* i2c_bus) 20 | { 21 | _i2c_bus = i2c_bus; 22 | } 23 | 24 | 25 | void VEML6030::init(uint8_t IT, uint8_t Gain, uint8_t Persistance) 26 | { 27 | // byte structure is (Low Byte, High Byte) 28 | // High byte, set gain and integration time high bits, 29 | // Low byte, set integration time low bits, set persistance, enable interrupt, set ALS power on 30 | uint8_t data[2] = {((IT & 0x03) << 6) | Persistance << 4 | 0x02, (Gain << 3) | ((IT & 0x0C) >> 2)}; 31 | _i2c_bus->writeBytes(VEML6030_ADDRESS, VEML6030_ALS_CONF, 2, &data[0]); 32 | } 33 | 34 | 35 | uint16_t VEML6030::getALSData() 36 | { 37 | uint8_t rawData[2] = {0, 0}; 38 | _i2c_bus->readBytes(VEML6030_ADDRESS, VEML6030_ALS, 2, &rawData[0]); 39 | return ((uint16_t) rawData[1] << 8) | rawData[0]; 40 | } 41 | 42 | 43 | uint16_t VEML6030::getWhiteData() 44 | { 45 | uint8_t rawData[2] = {0, 0}; 46 | _i2c_bus->readBytes(VEML6030_ADDRESS, VEML6030_WHITE, 2, &rawData[0]); 47 | return ((uint16_t) rawData[1] << 8) | rawData[0]; 48 | } 49 | 50 | 51 | uint16_t VEML6030::getIntStatus() 52 | { 53 | uint8_t rawData[2] = {0, 0}; 54 | _i2c_bus->readBytes(VEML6030_ADDRESS, VEML6030_ALS_INT, 2, &rawData[0]); 55 | return (((uint16_t) rawData[1]) << 8) | rawData[0]; 56 | } 57 | 58 | 59 | uint16_t VEML6030::getHighThreshold() 60 | { 61 | uint8_t rawData[2] = {0, 0}; 62 | _i2c_bus->readBytes(VEML6030_ADDRESS, VEML6030_ALS_WH, 2, &rawData[0]); 63 | return (((uint16_t) rawData[1]) << 8) | rawData[0]; 64 | } 65 | 66 | 67 | uint16_t VEML6030::getLowThreshold() 68 | { 69 | uint8_t rawData[2] = {0, 0}; 70 | _i2c_bus->readBytes(VEML6030_ADDRESS, VEML6030_ALS_WL, 2, &rawData[0]); 71 | return ((uint16_t) rawData[1] << 8) | rawData[0]; 72 | } 73 | 74 | 75 | void VEML6030::setLowThreshold(uint16_t Threshold) 76 | { 77 | uint8_t data[2] = {(Threshold & 0x00FF), (Threshold & 0xFF00) >> 8}; 78 | _i2c_bus->writeBytes(VEML6030_ADDRESS, VEML6030_ALS_WL, 2, &data[0]); 79 | } 80 | 81 | 82 | void VEML6030::setHighThreshold(uint16_t Threshold) 83 | { 84 | uint8_t data[2] = {Threshold & 0x00FF, (Threshold & 0xFF00) >> 8}; 85 | _i2c_bus->writeBytes(VEML6030_ADDRESS, VEML6030_ALS_WH, 2, &data[0]); 86 | } 87 | 88 | 89 | void VEML6030::enablepowerSave(uint8_t powerMode) 90 | { 91 | 92 | uint8_t data[2] = {powerMode << 1 | 0x01, 0x00}; 93 | _i2c_bus->writeBytes(VEML6030_ADDRESS, VEML6030_PWR_SAVE, 2, &data[0]); 94 | } 95 | 96 | void VEML6030::disablepowerSave() 97 | { 98 | uint8_t data[2] = {0x00, 0x00}; 99 | _i2c_bus->writeBytes(VEML6030_ADDRESS, VEML6030_PWR_SAVE, 2, &data[0]); 100 | } 101 | 102 | 103 | void VEML6030::enable() 104 | { 105 | uint8_t rawData[2] = {0, 0}; 106 | _i2c_bus->readBytes(VEML6030_ADDRESS, VEML6030_ALS_CONF, 2, &rawData[0]); // read existing configuration data 107 | uint8_t data[2] = {rawData[0] & ~(0x01), rawData[1]}; // ALS power on 108 | _i2c_bus->writeBytes(VEML6030_ADDRESS, VEML6030_ALS_CONF, 2, &data[0]); 109 | } 110 | 111 | 112 | void VEML6030::disable() 113 | { 114 | uint8_t rawData[2] = {0, 0}; 115 | _i2c_bus->readBytes(VEML6030_ADDRESS, VEML6030_ALS_CONF, 2, &rawData[0]); // read existing configuration data 116 | uint8_t data[2] = {rawData[0] | 0x01, rawData[1]}; // ALS power off 117 | _i2c_bus->writeBytes(VEML6030_ADDRESS, VEML6030_ALS_CONF, 2, &data[0]); 118 | } 119 | -------------------------------------------------------------------------------- /TurtleTracker/AssetTracker_IoT_Cricket/VEML6030.h: -------------------------------------------------------------------------------- 1 | /* 07/01/2019 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | VEML6030 is a high accuracy ambient light digital 16-bit resolution sensor in a miniature transparent 6 | 2 mm x 2 mm package. It includes a high sensitive photodiode, a low noise amplifier, a 16-bit A/D 7 | converter and supports an easy to use I2C bus communication interface and additional interrupt feature. 8 | 9 | VEML6030’s functions are easily operated via the simple command format 10 | of I2C (SMBus compatible) interface protocol. VEML6030’s operating voltage ranges from 2.5 V to 11 | 3.6 V. 12 | 13 | Library may be used freely and without limit with attribution. 14 | 15 | */ 16 | 17 | #ifndef VEML6030_h 18 | #define VEML6030_h 19 | 20 | #include "Arduino.h" 21 | #include "Wire.h" 22 | #include "I2Cdev.h" 23 | 24 | // https://www.vishay.com/docs/84366/veml6030.pdf 25 | // https://www.vishay.com/docs/84367/designingveml6030.pdf 26 | //////////////////////////// 27 | // VEML6030 Command Codes // 28 | //////////////////////////// 29 | #define VEML6030_ALS_CONF 0x00 // command codes 30 | #define VEML6030_ALS_WH 0x01 31 | #define VEML6030_ALS_WL 0x02 32 | #define VEML6030_PWR_SAVE 0x03 33 | #define VEML6030_ALS 0x04 34 | #define VEML6030_WHITE 0x05 35 | #define VEML6030_ALS_INT 0x06 36 | 37 | #define VEML6030_ADDRESS 0x10 // 0x10 when address pin LOW, 0x48 when HIGH 38 | 39 | #define IT_100 0x00 // 100 ms /ALS integration time setting 40 | #define IT_200 0x01 // 200 ms 41 | #define IT_400 0x02 // 400 ms 42 | #define IT_800 0x03 // 800 ms 43 | #define IT_50 0x08 // 50 ms 44 | #define IT_25 0x0C // 25 ms 45 | 46 | #define Gain_1x 0x00 // 1x gain 47 | #define Gain_2x 0x01 // 2x gain 48 | #define Gain_0_125x 0x02 // 1/8 x gain 49 | #define Gain_0_25x 0x03 // 1/4 x gain 50 | 51 | class VEML6030 52 | { 53 | public: 54 | VEML6030(I2Cdev* i2c_bus); 55 | void init(uint8_t IT, uint8_t Gain, uint8_t Persistance); 56 | uint16_t getALSData(); 57 | uint16_t getWhiteData(); 58 | void setHighThreshold(uint16_t Threshold); 59 | uint16_t getHighThreshold(); 60 | void setLowThreshold(uint16_t Threshold); 61 | uint16_t getLowThreshold(); 62 | uint16_t getIntStatus(); 63 | void enablepowerSave(uint8_t powerMode); 64 | void disablepowerSave(); 65 | void enable(); 66 | void disable(); 67 | private: 68 | I2Cdev* _i2c_bus; 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /TurtleTracker/Readme.md: -------------------------------------------------------------------------------- 1 | **Indian Ocean sea Turtle (IoT) Tracker** 2 | 3 | See [here](https://ocean-indien.ifremer.fr/en/Projects/Technological-innovations/pIOT-2018-2020-IOT-2018-2021/IOT-2018-2021) and [here](https://archimer.ifremer.fr/doc/00773/88525/94245.pdf) for details. 4 | 5 | Based on the CMWX1ZZABZ LoRaWAN module (STM32L082 Cortex M0+ MCU + SX1276 LoRa Radio modem) and using UBLOX's MAX M8Q GNSS engine this 20.7 x 37.5 mm animal tracker 6 | embeds two barometers (MS5803-01BA and MS5837-30BA) for underwater depth measurement, a VEML6030 ambient light sensor, and a combination accelerometer/magnetometer 7 | (LSM303AGR e-compass) for simple heading mearurements. The LoRaWAN chip/pcb antenna is intended to serve as backup for an external LoRaWAN antenna. 8 | The device has an 8 MByte SPI NOR flash memory for data logging, a 500 mA (STBC08) LiPo battery charger, a dual MOSFET for battery voltage measurement, 9 | and an indicator led. There is a resistance circuit for an external seawater immersion detector. The device is designed to use very little power with 10 | components chosen for their low quiescent current; the CMWX1ZZABZ has sleep current of 1.65 uA. All sensors and GNSS engine can be switched off so the 11 | power usage can be configured to match the particular conditions/application. The goal is a one year battery life using a small LiPo battery. 12 | 13 | ![IoT Turtle Tracker top](https://user-images.githubusercontent.com/6698410/60612972-c8b11780-9d7e-11e9-9736-92715d28e852.jpg) 14 | ![IoT Turtle Tracker bottom](https://user-images.githubusercontent.com/6698410/60612987-d23a7f80-9d7e-11e9-9c5e-ad036ecf305e.jpg) 15 | -------------------------------------------------------------------------------- /longCricketAssetTracker/AssetTracker_longCricket.v04i/BME280.h: -------------------------------------------------------------------------------- 1 | /* 06/16/2017 Copyright Tlera Corporation 2 | * 3 | * Created by Kris Winer 4 | * 5 | This sketch uses SDA/SCL on pins 42/43 (back pads), respectively, and it uses the Dragonfly STM32L476RE Breakout Board. 6 | The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution 7 | mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of 8 | only 1 microAmp. The choice will depend on the application. 9 | 10 | Library may be used freely and without limit with attribution. 11 | 12 | */ 13 | 14 | #ifndef BME280_h 15 | #define BME280_h 16 | 17 | #include "Arduino.h" 18 | #include 19 | 20 | /* BME280 registers 21 | * http://www.mouser.com/ds/2/783/BST-BME280_DS001-11-844833.pdf 22 | */ 23 | #define BME280_HUM_LSB 0xFE 24 | #define BME280_HUM_MSB 0xFD 25 | #define BME280_TEMP_XLSB 0xFC 26 | #define BME280_TEMP_LSB 0xFB 27 | #define BME280_TEMP_MSB 0xFA 28 | #define BME280_PRESS_XLSB 0xF9 29 | #define BME280_PRESS_LSB 0xF8 30 | #define BME280_PRESS_MSB 0xF7 31 | #define BME280_CONFIG 0xF5 32 | #define BME280_CTRL_MEAS 0xF4 33 | #define BME280_STATUS 0xF3 34 | #define BME280_CTRL_HUM 0xF2 35 | #define BME280_RESET 0xE0 36 | #define BME280_ID 0xD0 // should be 0x60 37 | #define BME280_CALIB00 0x88 38 | #define BME280_CALIB26 0xE1 39 | 40 | #define BME280_ADDRESS 0x77 // Address of BMP280 altimeter when ADO = 0 41 | 42 | 43 | #define P_OSR_01 0x01 44 | #define P_OSR_02 0x02 45 | #define P_OSR_04 0x03 46 | #define P_OSR_08 0x04 47 | #define P_OSR_16 0x05 48 | 49 | #define H_OSR_01 0x01 50 | #define H_OSR_02 0x02 51 | #define H_OSR_04 0x03 52 | #define H_OSR_08 0x04 53 | #define H_OSR_16 0x05 54 | 55 | #define T_OSR_01 0x01 56 | #define T_OSR_02 0x02 57 | #define T_OSR_04 0x03 58 | #define T_OSR_08 0x04 59 | #define T_OSR_16 0x05 60 | 61 | #define full 0x00 62 | #define BW0_223ODR 0x01 63 | #define BW0_092ODR 0x02 64 | #define BW0_042ODR 0x03 65 | #define BW0_021ODR 0x04 66 | 67 | #define Sleep 0x00 68 | #define Forced 0x01 69 | #define Forced2 0x02 70 | #define Normal 0x03 71 | 72 | #define t_00_5ms 0x00 73 | #define t_62_5ms 0x01 74 | #define t_125ms 0x02 75 | #define t_250ms 0x03 76 | #define t_500ms 0x04 77 | #define t_1000ms 0x05 78 | #define t_10ms 0x06 79 | #define t_20ms 0x07 80 | 81 | 82 | class BME280 83 | { 84 | public: 85 | BME280(); 86 | uint8_t getChipID(); 87 | void resetBME280(); 88 | int32_t readBME280Temperature(); 89 | int32_t readBME280Pressure(); 90 | int32_t readBME280Humidity(); 91 | void BME280forced(); 92 | void BME280Init(uint8_t Posr, uint8_t Hosr, uint8_t Tosr, uint8_t Mode, uint8_t IIRFilter, uint8_t SBy); 93 | int32_t BME280_compensate_T(int32_t adc_T); 94 | uint32_t BME280_compensate_P(int32_t adc_P); 95 | uint32_t BME280_compensate_H(int32_t adc_H); 96 | void I2Cscan(); 97 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data); 98 | uint8_t readByte(uint8_t address, uint8_t subAddress); 99 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest); 100 | private: 101 | uint8_t _dig_H1, _dig_H3, _dig_H6; 102 | uint16_t _dig_T1, _dig_P1, _dig_H4, _dig_H5; 103 | int16_t _dig_T2, _dig_T3, _dig_P2, _dig_P3, _dig_P4, _dig_P5, _dig_P6, _dig_P7, _dig_P8, _dig_P9, _dig_H2; 104 | int32_t _t_fine; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /longCricketAssetTracker/AssetTracker_longCricket.v04i/SPIFlash.h: -------------------------------------------------------------------------------- 1 | /* SPIFlash.h 2 | Sketch by Kris Winer December 16. 2016 3 | 4 | License: Use this sketch any way you choose; if you like it, buy me a beer sometime 5 | 6 | Purpose: Checks function of a variety of SPI NOR flash memory chips hosted by the STM32L4 7 | Dragonfly (STM32L476), Butterfly (STM32L433), and Ladybug (STML432) development boards or their variants. 8 | 9 | Sketch takes advantage of the SPI.beginTransaction/SPI.EndTransaction protocol for efficiency 10 | and maximum speed. 11 | 12 | Sketch based on the work of Pete (El Supremo) as follows: 13 | * Copyright (c) 2014, Pete (El Supremo), el_supremo@shaw.ca 14 | * 15 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 16 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 17 | * open source software by purchasing Teensy or other PJRC products. 18 | * 19 | * Permission is hereby granted, free of charge, to any person obtaining a copy 20 | * of this software and associated documentation files (the "Software"), to deal 21 | * in the Software without restriction, including without limitation the rights 22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | * copies of the Software, and to permit persons to whom the Software is 24 | * furnished to do so, subject to the following conditions: 25 | * 26 | * The above copyright notice, development funding notice, and this permission 27 | * notice shall be included in all copies or substantial portions of the Software. 28 | */ 29 | 30 | #ifndef SPIFlash_h 31 | #define SPIFlash_h 32 | 33 | #include "Arduino.h" 34 | #include "SPI.h" 35 | 36 | #define STAT_WIP 1 37 | #define STAT_WEL 2 38 | 39 | #define CMD_WRITE_STATUS_REG 0x01 40 | #define CMD_PAGE_PROGRAM 0x02 41 | #define CMD_READ_DATA 0x03 42 | #define CMD_WRITE_DISABLE 0x04 43 | #define CMD_READ_STATUS_REG 0x05 44 | #define CMD_WRITE_ENABLE 0x06 45 | #define CMD_READ_HIGH_SPEED 0x0B 46 | #define CMD_SECTOR_ERASE 0x20 47 | #define CMD_BLOCK32K_ERASE 0x52 48 | #define CMD_RESET_DEVICE 0xF0 49 | #define CMD_READ_ID 0x9F 50 | #define CMD_RELEASE_POWER_DOWN 0xAB 51 | #define CMD_POWER_DOWN 0xB9 52 | #define CMD_CHIP_ERASE 0xC7 53 | #define CMD_BLOCK64K_ERASE 0xD8 54 | 55 | class SPIFlash 56 | { 57 | public: 58 | SPIFlash(uint8_t CSPIN); 59 | void init(); 60 | void getChipID(); 61 | void powerDown(); 62 | void powerUp(); 63 | void write_pause(void); 64 | int page_to_address(int pn); 65 | int address_to_page(int addr); 66 | void flash_read_id(unsigned char *idt); 67 | unsigned char flash_read_status(void); 68 | void flash_hard_reset(void); 69 | void flash_chip_erase(boolean wait); 70 | void flash_erase_pages_sector(int pn); 71 | void flash_erase_pages_block32k(int pn); 72 | void flash_erase_pages_block64k(int pn); 73 | void flash_page_program(unsigned char *wp,int pn); 74 | void flash_read_pages(unsigned char *p,int pn,const int n_pages); 75 | void flash_fast_read_pages(unsigned char *p,int pn,const int n_pages); 76 | private: 77 | uint8_t _csPin; 78 | unsigned char flash_wait_for_write = 0; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /longCricketAssetTracker/Readme.md: -------------------------------------------------------------------------------- 1 | Long Cricket Asset Tracker 2 | 3 | Arduino sketch to manage the long Cricket Asset Tracker available on [Tindie](https://www.tindie.com/products/TleraCorp/long-cricket-loralorawangnss-asset-tracker/). 4 | 5 | ![longCricket](https://user-images.githubusercontent.com/6698410/50252240-337aa280-039b-11e9-89bd-95fb6a15dbd0.jpg) 6 | -------------------------------------------------------------------------------- /privateCore/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /privateCore/STM32L0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriswiner/CMWX1ZZABZ/ed8b70dd992d7130fc21175beab8a3ec1e173b53/privateCore/STM32L0.zip --------------------------------------------------------------------------------