Kept branch version of /esp32test/Esp32DeepSleepTest/src/main.cpp

This commit is contained in:
Ollo
2022-06-25 17:28:01 +02:00
14 changed files with 617 additions and 581 deletions

View File

@@ -1,112 +0,0 @@
/*
* DS2438.h
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/
#ifndef DS2438_h
#define DS2438_h
#include <Arduino.h>
#include <OneWire.h>
#define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44
#define DS2438_VOLTAGE_CONVERSION_COMMAND 0xb4
#define DS2438_WRITE_SCRATCHPAD_COMMAND 0x4e
#define DS2438_COPY_SCRATCHPAD_COMMAND 0x48
#define DS2438_READ_SCRATCHPAD_COMMAND 0xbe
#define DS2438_RECALL_MEMORY_COMMAND 0xb8
#define PAGE_MIN 0
#define PAGE_MAX 7
#define DS2438_CHA 0
#define DS2438_CHB 1
#define DS2438_MODE_CHA 0x01
#define DS2438_MODE_CHB 0x02
#define DS2438_MODE_TEMPERATURE 0x04
#define DS2438_TEMPERATURE_DELAY 10
#define DS2438_VOLTAGE_CONVERSION_DELAY 8
#define DEFAULT_PAGE0(var) uint8_t var[8] { \
0b00001011 /* X, ADB=0, NVB=0, TB=0, AD=1, EE=0, CA=1, IAD=1 */, \
0, /* Temperatur */ \
0, /* Temperatur */ \
0, /* Voltage */ \
0, /* Voltage */ \
0, /* Current */ \
0, /* Current */ \
0 /* Threashold */ \
}
typedef struct PageOne {
uint8_t eleapsedTimerByte0; /**< LSB of timestamp */
uint8_t eleapsedTimerByte1;
uint8_t eleapsedTimerByte2;
uint8_t eleapsedTimerByte3; /**< MSB of timestamp */
uint8_t ICA; /**< Integrated Current Accumulator (current flowing into and out of the battery) */
uint8_t offsetRegisterByte0; /**< Offset for ADC calibdation */
uint8_t offsetRegisterByte1; /**< Offset for ADC calibdation */
uint8_t reserved;
} PageOne_t;
typedef struct PageSeven {
uint8_t userByte0;
uint8_t userByte1;
uint8_t userByte2;
uint8_t userByte3;
uint8_t CCA0; /**< Charging Current Accumulator (CCA) */
uint8_t CCA1; /**< Charging Current Accumulator (CCA) */
uint8_t DCA0; /**< Discharge Current Accumulator (DCA) */
uint8_t DCA1; /**< Discharge Current Accumulator (DCA) */
} PageSeven_t;
typedef uint8_t DeviceAddress[8];
class DS2438 {
public:
DS2438(OneWire *ow, float currentShunt);
DS2438(OneWire *ow, uint8_t *address);
void begin();
void update();
double getTemperature();
float getVoltage(int channel=DS2438_CHA);
float getCurrent();
boolean isError();
boolean isFound();
private:
bool validAddress(const uint8_t*);
bool validFamily(const uint8_t* deviceAddress);
bool deviceFound = false;
OneWire *_ow;
DeviceAddress _address;
uint8_t _mode;
double _temperature;
float _voltageA;
float _voltageB;
float _current;
float _currentShunt;
boolean _error;
boolean startConversion(int channel, boolean doTemperature);
boolean selectChannel(int channel);
void writePage(int page, uint8_t *data);
boolean readPage(int page, uint8_t *data);
};
#endif

View File

@@ -0,0 +1,187 @@
#ifndef ULP_PWM_h
#define ILP_PWM_h
#include <Arduino.h>
#include "driver/rtc_io.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc.h"
#include "esp32/ulp.h"
#define LBL_START 1
#define LBL_DELAY_ON 2
#define LBL_DELAY_OFF 3
#define LBL_SKIP_ON 4
#define LBL_SKIP_OFF 5
#define REGISTER_DELAY_LOOP_COUNTER R0
#define REGISTER_TICKS_ON R1
#define REGISTER_TICKS_OFF R2
#define TOTAL_TICKS_DELAY 255
#define PIN GPIO_NUM_12
//support 20 vars
const size_t ulp_var_offset = CONFIG_ULP_COPROC_RESERVE_MEM - 20;
//use the first for dimming
const size_t ulp_dimm_offset = ulp_var_offset + 1;
const size_t ulp_alive_offset = ulp_var_offset + 2;
//see https://github.com/perseus086/ESP32-notes
const uint32_t rtc_bit[40] = {
25, //gpio0
0, //gpio1
26, //gpio2
0, //gpio3
24, //gpio4
0, //gpio5
0, //gpio6
0, //gpio7
0, //gpio8
0, //gpio9
0, //gpio10
0, //gpio11
29, //gpio12
28, //gpio13
30, //gpio14
27, //gpio15
0, //gpio16
31, //gpio17
0, //gpio18
0, //gpio19
0, //gpio20
0, //gpio21
0, //gpio22
0, //gpio23
0, //gpio24
20, //gpio25
21, //gpio26
0, //gpio27
0, //gpio28
0, //gpio29
0, //gpio30
0, //gpio31
23, //gpio32
22, //gpio33
18, //gpio34
19, //gpio35
14, //gpio36
15, //gpio37
16, //gpio38
17 //gpio39
};
static inline void ulp_data_write(size_t offset, uint16_t value)
{
if (offset >= CONFIG_ULP_COPROC_RESERVE_MEM || offset <= ulp_var_offset)
{
Serial.print("Invalid ULP offset detected, refusing write!");
Serial.print(offset);
Serial.print("-");
Serial.print(ulp_var_offset);
Serial.print("-");
Serial.println(CONFIG_ULP_COPROC_RESERVE_MEM);
return;
}
else
{
RTC_SLOW_MEM[offset] = value;
}
}
static inline uint16_t ulp_data_read(size_t offset)
{
if (offset >= CONFIG_ULP_COPROC_RESERVE_MEM || offset <= ulp_var_offset)
{
Serial.print("Invalid ULP offset detected");
Serial.print(offset);
Serial.print("-");
Serial.print(ulp_var_offset);
Serial.print("-");
Serial.println(CONFIG_ULP_COPROC_RESERVE_MEM);
}
return RTC_SLOW_MEM[offset] & 0xffff;
}
static inline uint32_t rtc_io_number_get(gpio_num_t gpio_num)
{
assert(rtc_gpio_is_valid_gpio(gpio_num) && "Invalid GPIO for RTC");
uint32_t bit = rtc_bit[gpio_num];
Serial.print("Resolved GPIO ");
Serial.print(gpio_num);
Serial.print(" to rtc bit ");
Serial.println(bit);
return bit;
}
void ulp_pwm_start(void)
{
rtc_gpio_init(PIN);
rtc_gpio_set_direction(PIN, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(PIN, 0);
const uint32_t rtc_gpio = rtc_io_number_get(PIN);
// Define ULP program
const ulp_insn_t ulp_prog[] = {
M_LABEL(LBL_START),
I_MOVI(REGISTER_DELAY_LOOP_COUNTER, 1),
I_MOVI(REGISTER_TICKS_ON, 0),
I_ST(REGISTER_DELAY_LOOP_COUNTER, REGISTER_TICKS_ON, ulp_alive_offset), //store 1 with 0 offset into alive
I_LD(REGISTER_TICKS_ON, REGISTER_TICKS_ON, ulp_dimm_offset), //REGISTER_TICKS_ON = RTC_DATA[0+ulp_dimm_offset]
//in total there is always 255 delay loop iterations, but in different duty cycle
I_MOVI(REGISTER_TICKS_OFF, TOTAL_TICKS_DELAY),
I_SUBR(REGISTER_TICKS_OFF, REGISTER_TICKS_OFF, REGISTER_TICKS_ON),
//on phase
I_MOVR(REGISTER_DELAY_LOOP_COUNTER, REGISTER_TICKS_ON),
M_BL(LBL_SKIP_ON, 1), //if never on, skip on phase
I_WR_REG(RTC_GPIO_OUT_REG, rtc_gpio, rtc_gpio, HIGH), // on
M_LABEL(LBL_DELAY_ON),
I_DELAY(1), //wait 1 clock
I_SUBI(REGISTER_DELAY_LOOP_COUNTER, REGISTER_DELAY_LOOP_COUNTER, 1), // REGISTER_DELAY_LOOP_COUNTER--
M_BGE(LBL_DELAY_ON, 1), //if time left, goto start of on loop
M_LABEL(LBL_SKIP_ON),
//off phase
I_MOVR(REGISTER_DELAY_LOOP_COUNTER, REGISTER_TICKS_OFF),
M_BL(LBL_SKIP_OFF, 1), //if never off, skip on phase
I_WR_REG(RTC_GPIO_OUT_REG, rtc_gpio, rtc_gpio, LOW), // on
M_LABEL(3),
I_DELAY(1), //wait 1 clock
I_SUBI(REGISTER_DELAY_LOOP_COUNTER, REGISTER_DELAY_LOOP_COUNTER, 1), // REGISTER_DELAY_LOOP_COUNTER--
M_BGE(3, 1), //if time left, goto start of on loop
M_LABEL(LBL_SKIP_OFF),
M_BX(LBL_START),
};
// Run ULP program
size_t size = sizeof(ulp_prog) / sizeof(ulp_insn_t);
assert(size < ulp_var_offset && "ULP_DATA_OFFSET needs to be greater or equal to the program size");
esp_err_t error = ulp_process_macros_and_load(0, ulp_prog, &size);
Serial.print("ULP bootstrap status ");
Serial.println(error);
//allow glitchless start
ulp_data_write(ulp_alive_offset, 0);
error = ulp_run(0);
Serial.print("ULP start status ");
Serial.println(error);
}
static inline void ulp_pwm_set_level(uint8_t level)
{
ulp_data_write(ulp_dimm_offset, level);
}
static inline void ulp_pwm_init()
{
ulp_data_write(ulp_alive_offset, 0);
delay(10);
if (ulp_data_read(ulp_alive_offset) == 0)
{
ulp_pwm_start();
}
}
#endif

View File

@@ -1,286 +0,0 @@
/*
* DS2438.cpp
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/
#include "DS2438.h"
// DSROM FIELDS
#define DSROM_FAMILY 0
#define DSROM_CRC 7
#define DS2438MODEL 0x26
DS2438::DS2438(OneWire *ow, float currentShunt = 1.0f) {
_ow = ow;
_currentShunt = currentShunt;
};
void DS2438::begin(){
DeviceAddress searchDeviceAddress;
_ow->reset_search();
memset(searchDeviceAddress,0, 8);
_temperature = 0;
_voltageA = 0.0;
_voltageB = 0.0;
_error = true;
_mode = (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE);
deviceFound = false; // Reset the number of devices when we enumerate wire devices
while (_ow->search(searchDeviceAddress)) {
if (validAddress(searchDeviceAddress)) {
if (validFamily(searchDeviceAddress)) {
memcpy(_address,searchDeviceAddress,8);
DEFAULT_PAGE0(defaultConfig);
writePage(0, defaultConfig);
deviceFound = true;
}
}
}
}
bool DS2438::isFound(){
return deviceFound;
}
bool DS2438::validAddress(const uint8_t* deviceAddress) {
return (_ow->crc8(deviceAddress, 7) == deviceAddress[DSROM_CRC]);
}
bool DS2438::validFamily(const uint8_t* deviceAddress) {
switch (deviceAddress[DSROM_FAMILY]) {
case DS2438MODEL:
return true;
default:
return false;
}
}
void DS2438::update() {
uint8_t data[9];
_error = true;
if(!isFound()){
return;
}
if (_mode & DS2438_MODE_CHA || _mode == DS2438_MODE_TEMPERATURE) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE;
if (!startConversion(DS2438_CHA, doTemperature)) {
Serial.println("Error starting temp conversion ds2438 channel a");
return;
}
if (!readPage(0, data)){
Serial.println("Error reading zero page ds2438 channel a");
return;
}
Serial.print(data[0],16);
Serial.print(" ");
Serial.print(data[1],16);
Serial.print(" ");
Serial.print(data[2],16);
Serial.print(" ");
Serial.print(data[3],16);
Serial.print(" ");
Serial.print(data[4],16);
Serial.print(" ");
Serial.print(data[5],16);
Serial.print(" ");
Serial.print(data[6],16);
Serial.print(" ");
Serial.println(data[7],16);
if (doTemperature) {
_temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125;
}
if (_mode & DS2438_MODE_CHA) {
_voltageA = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
}
if (_mode & DS2438_MODE_CHB) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE && !(_mode & DS2438_MODE_CHA);
if (!startConversion(DS2438_CHB, doTemperature)) {
Serial.println("Error starting temp conversion channel b ds2438");
return;
}
if (!readPage(0, data)){
Serial.println("Error reading zero page ds2438 channel b");
return;
}
if (doTemperature) {
int16_t upperByte = ((int16_t)data[2]) << 8;
int16_t lowerByte = data[1] >> 3;
int16_t fullByte = (upperByte | lowerByte);
_temperature = ((double)fullByte) * 0.03125;
}
_voltageB = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
int16_t upperByte = ((int16_t)data[6]) << 8;
int16_t lowerByte = data[5];
int16_t fullByte = (int16_t)(upperByte | lowerByte);
float fullByteb = fullByte;
_current = (fullByteb) / ((4096.0f * _currentShunt));
_error = false;
Serial.print(data[0],16);
Serial.print(" ");
Serial.print(data[1],16);
Serial.print(" ");
Serial.print(data[2],16);
Serial.print(" ");
Serial.print(data[3],16);
Serial.print(" ");
Serial.print(data[4],16);
Serial.print(" ");
Serial.print(data[5],16);
Serial.print(" ");
Serial.print(data[6],16);
Serial.print(" ");
Serial.println(data[7],16);
Serial.println("-");
uint16_t ICA = 0;
if (readPage(1, data)){
PageOne_t *pOne = (PageOne_t *) data;
Serial.println(pOne->ICA);
float Ah = pOne->ICA / (2048.0f * _currentShunt);
Serial.print("Ah=");
Serial.println(Ah);
ICA = pOne->ICA;
}
if (readPage(7, data)){
PageSeven_t *pSeven = (PageSeven_t *) data;
int16_t CCA = pSeven->CCA0 | ((int16_t) pSeven->CCA1) << 8;
int16_t DCA = pSeven->DCA0 | ((int16_t) pSeven->DCA1) << 8;
Serial.println("ICA, DCA, CCA");
Serial.print(ICA);
Serial.print(", ");
Serial.print(DCA);
Serial.print(", ");
Serial.println(CCA);
}
}
double DS2438::getTemperature() {
return _temperature;
}
float DS2438::getVoltage(int channel) {
if (channel == DS2438_CHA) {
return _voltageA;
} else if (channel == DS2438_CHB) {
return _voltageB;
} else {
return 0.0;
}
}
float DS2438::getCurrent() {
return _current;
}
boolean DS2438::isError() {
return _error;
}
boolean DS2438::startConversion(int channel, boolean doTemperature) {
if(!isFound()){
return false;
}
if (!selectChannel(channel)){
return false;
}
_ow->reset();
_ow->select(_address);
if (doTemperature) {
_ow->write(DS2438_TEMPERATURE_CONVERSION_COMMAND, 0);
delay(DS2438_TEMPERATURE_DELAY);
_ow->reset();
_ow->select(_address);
}
_ow->write(DS2438_VOLTAGE_CONVERSION_COMMAND, 0);
delay(DS2438_VOLTAGE_CONVERSION_DELAY);
return true;
}
boolean DS2438::selectChannel(int channel) {
if(!isFound()){
return false;
}
uint8_t data[9];
if (readPage(0, data)) {
if (channel == DS2438_CHB){
data[0] = data[0] | 0x08;
}
else {
data[0] = data[0] & 0xf7;
}
writePage(0, data);
return true;
}
Serial.println("Could not read page zero data");
return false;
}
void DS2438::writePage(int page, uint8_t *data) {
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_WRITE_SCRATCHPAD_COMMAND, 0);
if ((page >= PAGE_MIN) && (page <= PAGE_MAX)) {
_ow->write(page, 0);
} else {
return;
}
for (int i = 0; i < 8; i++){
_ow->write(data[i], 0);
}
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_COPY_SCRATCHPAD_COMMAND, 0);
_ow->write(page, 0);
}
boolean DS2438::readPage(int page, uint8_t *data) {
//TODO if all data is 0 0 is a valid crc, but most likly not as intended
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_RECALL_MEMORY_COMMAND, 0);
if ((page >= PAGE_MIN) && (page <= PAGE_MAX)) {
_ow->write(page, 0);
} else {
return false;
}
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_READ_SCRATCHPAD_COMMAND, 0);
_ow->write(page, 0);
for (int i = 0; i < 9; i++){
data[i] = _ow->read();
}
return _ow->crc8(data, 8) == data[8];
}

View File

@@ -13,7 +13,10 @@ int16_t pulses2 = 0;
int plantId = 0;
void setup() {
RTC_SLOW_ATTR uint8_t tick = 0;
RTC_SLOW_ATTR bool dir = true;
void setup()
{
Serial.begin(115200);
pinMode(OUTPUT_SENSOR, OUTPUT);
@@ -55,4 +58,4 @@ void loop() {
pcnt_counter_clear(PCNT_UNIT_0);
Serial.println(pulses*2);
}
}