From 7d96ee397a908774231c2fdddc15d32dd3604e1e Mon Sep 17 00:00:00 2001 From: lincomatic Date: Mon, 25 Jan 2016 13:41:33 -0800 Subject: [PATCH] V3.11.3 release - rollup of changes from dev branch --- Adafruit_MCP9808.cpp | 117 ---------------------------------------- Adafruit_MCP9808.h | 65 ---------------------- CHANGELOG | 34 +++++++++++- I2CIO.cpp | 2 +- J1772EvseController.cpp | 21 +++++--- LiquidTWI2.h | 5 -- MCP9808.cpp | 77 ++++++++++++++++++++++++++ MCP9808.h | 65 ++++++++++++++++++++++ RTClib.cpp | 2 +- i2caddr.h | 46 ++++++++++++++++ open_evse.h | 17 ++++-- open_evse.ino | 48 ++++++++++------- rapi_proc.cpp | 104 ++++++++++++++++++++++++++++++++++- rapi_proc.h | 47 +++++++++++++--- 14 files changed, 421 insertions(+), 229 deletions(-) delete mode 100644 Adafruit_MCP9808.cpp delete mode 100644 Adafruit_MCP9808.h create mode 100644 MCP9808.cpp create mode 100644 MCP9808.h create mode 100644 i2caddr.h diff --git a/Adafruit_MCP9808.cpp b/Adafruit_MCP9808.cpp deleted file mode 100644 index 8e0480d1..00000000 --- a/Adafruit_MCP9808.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************/ -/*! - @file Adafruit_MCP9808.cpp - @author K.Townsend (Adafruit Industries) - @license BSD (see license.txt) - - I2C Driver for Microchip's MCP9808 I2C Temp sensor - - This is a library for the Adafruit MCP9808 breakout - ----> http://www.adafruit.com/products/1782 - - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - @section HISTORY - - v1.0 - First release -*/ -/**************************************************************************/ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#ifdef __AVR_ATtiny85__ - #include "TinyWireM.h" - #define Wire TinyWireM -#else - #include "./Wire.h" -#endif - -static inline void wiresend(uint8_t x) { -#if ARDUINO >= 100 - Wire.write((uint8_t)x); -#else - Wire.send(x); -#endif -} - -static inline uint8_t wirerecv(void) { -#if ARDUINO >= 100 - return Wire.read(); -#else - return Wire.receive(); -#endif -} - -#include "Adafruit_MCP9808.h" - -/**************************************************************************/ -/*! - @brief Instantiates a new MCP9808 class -*/ -/**************************************************************************/ -Adafruit_MCP9808::Adafruit_MCP9808() { -} - -/**************************************************************************/ -/*! - @brief Setups the HW -*/ -/**************************************************************************/ -boolean Adafruit_MCP9808::begin(uint8_t addr) { - _i2caddr = addr; - //don't need - open_evse.ino does it Wire.begin(); - - if (read16(MCP9808_REG_MANUF_ID) != 0x0054) return false; - if (read16(MCP9808_REG_DEVICE_ID) != 0x0400) return false; - - return true; -} - -/**************************************************************************/ -/*! - @brief Reads the 16-bit temperature register and returns Centigrade*10 - -*/ -/**************************************************************************/ -int16_t Adafruit_MCP9808::readTempC10( void ) -{ - uint16_t t = read16(MCP9808_REG_AMBIENT_TEMP); - - uint32_t temp = ((t & 0x0FFF)*10)/16; - if (t & 0x1000) temp -= 256; - - return (int16_t) temp; -} - -/**************************************************************************/ -/*! - @brief Low level 16 bit read and write procedures! -*/ -/**************************************************************************/ - -void Adafruit_MCP9808::write16(uint8_t reg, uint16_t value) { - Wire.beginTransmission(_i2caddr); - wiresend((uint8_t)reg); - wiresend(value >> 8); - wiresend(value & 0xFF); - Wire.endTransmission(); -} - -uint16_t Adafruit_MCP9808::read16(uint8_t reg) { - uint16_t val; - - Wire.beginTransmission(_i2caddr); - wiresend((uint8_t)reg); - Wire.endTransmission(); - - Wire.requestFrom((uint8_t)_i2caddr, (uint8_t)2); - val = wirerecv(); - val <<= 8; - val |= wirerecv(); - return val; -} diff --git a/Adafruit_MCP9808.h b/Adafruit_MCP9808.h deleted file mode 100644 index f4242f8e..00000000 --- a/Adafruit_MCP9808.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************/ -/*! - @file Adafruit_MCP9808.h - @author K. Townsend (Adafruit Industries) - @license BSD (see license.txt) - - This is a library for the Adafruit MCP9808 Temp Sensor breakout board - ----> http://www.adafruit.com/products/1782 - - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - @section HISTORY - - v1.0 - First release -*/ -/**************************************************************************/ -#pragma once -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#ifdef __AVR_ATtiny85__ - #include "TinyWireM.h" - #define Wire TinyWireM -#else - #include "./Wire.h" -#endif - -#define MCP9808_I2CADDR_DEFAULT 0x18 -#define MCP9808_REG_CONFIG 0x01 - -#define MCP9808_REG_CONFIG_SHUTDOWN 0x0100 -#define MCP9808_REG_CONFIG_CRITLOCKED 0x0080 -#define MCP9808_REG_CONFIG_WINLOCKED 0x0040 -#define MCP9808_REG_CONFIG_INTCLR 0x0020 -#define MCP9808_REG_CONFIG_ALERTSTAT 0x0010 -#define MCP9808_REG_CONFIG_ALERTCTRL 0x0008 -#define MCP9808_REG_CONFIG_ALERTSEL 0x0002 -#define MCP9808_REG_CONFIG_ALERTPOL 0x0002 -#define MCP9808_REG_CONFIG_ALERTMODE 0x0001 - -#define MCP9808_REG_UPPER_TEMP 0x02 -#define MCP9808_REG_LOWER_TEMP 0x03 -#define MCP9808_REG_CRIT_TEMP 0x04 -#define MCP9808_REG_AMBIENT_TEMP 0x05 -#define MCP9808_REG_MANUF_ID 0x06 -#define MCP9808_REG_DEVICE_ID 0x07 - -class Adafruit_MCP9808 { - public: - Adafruit_MCP9808(); - boolean begin(uint8_t a = MCP9808_I2CADDR_DEFAULT); - // float readTempF( void ); - int16_t readTempC10( void ); - - void write16(uint8_t reg, uint16_t val); - uint16_t read16(uint8_t reg); - - private: - uint8_t _i2caddr; -}; diff --git a/CHANGELOG b/CHANGELOG index f71b2644..83be6e44 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,38 @@ Change Log -SC: 20151011 +SCL 20160125 +-> promoted vD3.11.3 to v3.11.3 stable + +vD3.11.3 SCL 20160125 +- replace Adafruit_MCP9808 with new MCP9808 code +- fix bug handling negative temperatures from MCP9808 + +vD3.11.2 SCL 20160120 +- fix error displaying negative temperatures... extra - sign leading decimals when negative temperature + +vD3.11.1 SCL 20160120 +- fix bug in handling negative temperatures from DS3231 + +vD3.11.0 SCL 20160112 +- added RAPI_I2C. Serial RAPI now enabled by RAPI_SERIAL. + *WARNING* RAPI_I2C not tested yet and probably doesn't work + both RAPI_I2C and RAPI_SERIAL may be enabled simultaneously +- call RapiSendEvseState() if POST error +- fix bug, wasn't calling RapiSendEvseState() if HardFault() +- in J1772EvseController::Init() - call RapiSendCommand() with EVSE_STATE_UNKNOWN + +SCL 20160111 +- change VOLT_PIN to PILOT_PIN + +SCL 20151211 +- change static inline to inline for wiresend/wirerecv() to fix compiler error + in Arduino 1.6.6 + +SCL 20151125 +- added i2caddr.h +- take Wire.begin() out of RTClib.cpp + +SCL: 20151011 v3.10.4 - vD3.10.4 promoted to stable diff --git a/I2CIO.cpp b/I2CIO.cpp index 99061552..03e583e5 100644 --- a/I2CIO.cpp +++ b/I2CIO.cpp @@ -58,7 +58,7 @@ int I2CIO::begin ( uint8_t i2cAddr ) { _i2cAddr = i2cAddr; - Wire.begin ( ); +//don't need - open_evse.ino does it Wire.begin ( ); _initialised = Wire.requestFrom ( _i2cAddr, (uint8_t)1 ); diff --git a/J1772EvseController.cpp b/J1772EvseController.cpp index 0db508a5..f43fe64e 100644 --- a/J1772EvseController.cpp +++ b/J1772EvseController.cpp @@ -140,7 +140,7 @@ uint32_t MovingAverage(uint32_t samp) #endif // AMMETER J1772EVSEController::J1772EVSEController() : - adcPilot(VOLT_PIN) + adcPilot(PILOT_PIN) #ifdef CURRENT_PIN , adcCurrent(CURRENT_PIN) #endif @@ -191,7 +191,9 @@ void J1772EVSEController::Reboot() void J1772EVSEController::DisabledTest_P(PGM_P message) { g_OBD.LcdMsg_P(g_psDisabledTests, message); +#ifndef NOCHECKS delay(SHOW_DISABLED_DELAY); +#endif } void J1772EVSEController::ShowDisabledTests() @@ -272,6 +274,7 @@ void J1772EVSEController::HardFault() { SetHardFault(); g_OBD.Update(OBD_UPD_HARDFAULT); + RapiSendEvseState(); while (1) { ProcessInputs(); // spin forever or until user resets via menu // if we're in P12 state, we can recover from the hard fault when EV @@ -449,7 +452,7 @@ void J1772EVSEController::Disable() chargingOff(); g_OBD.Update(OBD_UPD_FORCE); #ifdef RAPI - g_ERP.sendEvseState(); + RapiSendEvseState(); #endif // RAPI } } @@ -472,7 +475,7 @@ void J1772EVSEController::Sleep() g_OBD.Update(OBD_UPD_FORCE); #ifdef RAPI - g_ERP.sendEvseState(); + RapiSendEvseState(); #endif // RAPI // try to prevent arcing of our relay by waiting for EV to open its contacts first // use the charge end time variable temporarily to count down @@ -773,6 +776,11 @@ uint8_t J1772EVSEController::doPost() void J1772EVSEController::Init() { + m_EvseState = EVSE_STATE_UNKNOWN; + m_PrevEvseState = EVSE_STATE_UNKNOWN; + + RapiSendEvseState(0); + // read settings from EEPROM uint16_t rflgs = eeprom_read_word((uint16_t*)EOFS_FLAGS); @@ -879,10 +887,6 @@ void J1772EVSEController::Init() m_NoGndStart = 0; #endif // ADVPWR - m_EvseState = EVSE_STATE_UNKNOWN; - m_PrevEvseState = EVSE_STATE_UNKNOWN; - - #ifdef ADVPWR #ifdef FT_READ_AC_PINS @@ -911,6 +915,7 @@ void J1772EVSEController::Init() if (fault) { #ifdef UL_COMPLIANT // UL wants EVSE to hard fault until power cycle if POST fails + RapiSendEvseState(); while (1) { // spin forever ProcessInputs(); } @@ -1357,7 +1362,7 @@ if (TempChkEnabled()) { } #ifdef RAPI - g_ERP.sendEvseState(); + RapiSendEvseState(); #endif // RAPI #ifdef SERDBG if (SerDbgEnabled()) { diff --git a/LiquidTWI2.h b/LiquidTWI2.h index a6da6950..8f5e2637 100644 --- a/LiquidTWI2.h +++ b/LiquidTWI2.h @@ -43,8 +43,6 @@ // (the Panelolu2 encoder bits are subset of these bits) #define ALL_BUTTON_BITS (BUTTON_UP|BUTTON_DOWN|BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SELECT) -#define MCP23008_ADDRESS 0x20 - // registers #define MCP23008_IODIR 0x00 #define MCP23008_IPOL 0x01 @@ -58,8 +56,6 @@ #define MCP23008_GPIO 0x09 #define MCP23008_OLAT 0x0A -#define MCP23017_ADDRESS 0x20 - // registers #define MCP23017_IODIRA 0x00 #define MCP23017_IPOLA 0x02 @@ -180,7 +176,6 @@ class LiquidTWI2 : public Print { #endif //defined(MCP23017)&&defined(MCP23008) } - private: void send(uint8_t, uint8_t); #ifdef MCP23017 diff --git a/MCP9808.cpp b/MCP9808.cpp new file mode 100644 index 00000000..1c20311e --- /dev/null +++ b/MCP9808.cpp @@ -0,0 +1,77 @@ +/**************************************************************************/ +/*! + * 2016 hacked from Adafruit_MCP9808.cpp by Sam C. Lin + + @file Adafruit_MCP9808.cpp + @author K.Townsend (Adafruit Industries) + @license BSD (see license.txt) + + I2C Driver for Microchip's MCP9808 I2C Temp sensor + + This is a library for the Adafruit MCP9808 breakout + ----> http://www.adafruit.com/products/1782 + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + @section HISTORY + + v1.0 - First release +*/ +#include "open_evse.h" + +#ifdef MCP9808_IS_ON_I2C + +inline uint8_t wirerecv(void) { +#if ARDUINO >= 100 + return Wire.read(); +#else + return Wire.receive(); +#endif +} + +inline void wiresend(uint8_t x) { +#if ARDUINO >= 100 + Wire.write((uint8_t)x); +#else + Wire.send(x); +#endif +} + +int8_t MCP9808::begin() +{ + if ((read16(MCP9808_REG_MANUF_ID) == 0x0054) && + (read16(MCP9808_REG_DEVICE_ID) == 0x0400)) isPresent = 1; + else isPresent = 0; + return isPresent; +} + + +int16_t MCP9808::read16(uint8_t reg) { + int16_t val; + Wire.beginTransmission(MCP9808_ADDRESS); + wiresend(reg); + Wire.endTransmission(); + + Wire.requestFrom((uint8_t)MCP9808_ADDRESS, (uint8_t)2); + val = wirerecv(); + val <<= 8; + val |= wirerecv(); + + return val; +} + +// return C*10 +int16_t MCP9808::readAmbient() +{ + if (isPresent) { + int16_t temp = read16(MCP9808_REG_AMBIENT_TEMP) & 0x1FFF; + if (temp & 0x1000) temp |= 0xF000; // sign extend negative number + return (temp * 10) / 16; + } + else { + return 0; + } +} +#endif // MCP9808_IS_ON_I2C diff --git a/MCP9808.h b/MCP9808.h new file mode 100644 index 00000000..bb565f80 --- /dev/null +++ b/MCP9808.h @@ -0,0 +1,65 @@ +// -*- C++ -*- +/* + * Open EVSE Firmware + * + * Copyright (c) 2013-2014 Sam C. Lin + * + * This file is part of Open EVSE. + + * Open EVSE is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + + * Open EVSE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Open EVSE; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ +#pragma once +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #include "WProgram.h" +#endif +#include "./Wire.h" + + +#include "./i2caddr.h" + +//n.b. defines copied from Adafruit_MCP9808.h +#define MCP9808_REG_CONFIG 0x01 + +#define MCP9808_REG_CONFIG_SHUTDOWN 0x0100 +#define MCP9808_REG_CONFIG_CRITLOCKED 0x0080 +#define MCP9808_REG_CONFIG_WINLOCKED 0x0040 +#define MCP9808_REG_CONFIG_INTCLR 0x0020 +#define MCP9808_REG_CONFIG_ALERTSTAT 0x0010 +#define MCP9808_REG_CONFIG_ALERTCTRL 0x0008 +#define MCP9808_REG_CONFIG_ALERTSEL 0x0002 +#define MCP9808_REG_CONFIG_ALERTPOL 0x0002 +#define MCP9808_REG_CONFIG_ALERTMODE 0x0001 + +#define MCP9808_REG_UPPER_TEMP 0x02 +#define MCP9808_REG_LOWER_TEMP 0x03 +#define MCP9808_REG_CRIT_TEMP 0x04 +#define MCP9808_REG_AMBIENT_TEMP 0x05 +#define MCP9808_REG_MANUF_ID 0x06 +#define MCP9808_REG_DEVICE_ID 0x07 + +class MCP9808 { + int8_t isPresent; + int16_t read16(uint8_t reg); + +public: + MCP9808() { isPresent = 0; } + int8_t begin(); + + int16_t readAmbient(); +}; diff --git a/RTClib.cpp b/RTClib.cpp index 32aa526a..c50bdeda 100644 --- a/RTClib.cpp +++ b/RTClib.cpp @@ -4,8 +4,8 @@ #include "./Wire.h" #include #include "RTClib.h" +#include "i2caddr.h" -#define DS1307_ADDRESS 0x68 #define SECONDS_PER_DAY 86400L #define SECONDS_FROM_1970_TO_2000 946684800 diff --git a/i2caddr.h b/i2caddr.h new file mode 100644 index 00000000..55b191e0 --- /dev/null +++ b/i2caddr.h @@ -0,0 +1,46 @@ +// -*- C++ -*- +/* + * Copyright (c) 2015 Sam C. Lin + * + * Open EVSE Firmware + * + * This file is part of Open EVSE. + + * Open EVSE is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + + * Open EVSE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Open EVSE; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _I2CADDR_H_ +#define _I2CADDR_H_ +// +// I2C addresses +// +// LiquidTWI2 +#define MCP23017_ADDRESS 0x20 +#define MCP23008_ADDRESS 0x20 + +//RTClib +#define DS1307_ADDRESS 0x68 + +// MCP9808 +#define MCP9808_ADDRESS 0x18 + + +//RAPI_I2C +#define RAPI_I2C_LOCAL_ADDR 0x05 +#define RAPI_I2C_REMOTE_ADDR 0x06 + + +#endif // _I2CADDR_H_ diff --git a/open_evse.h b/open_evse.h index d661f2c4..dc82db02 100644 --- a/open_evse.h +++ b/open_evse.h @@ -30,13 +30,15 @@ #include "./Wire.h" #include "./Time.h" #include "avrstuff.h" +#include "i2caddr.h" + #if defined(ARDUINO) && (ARDUINO >= 100) #include "Arduino.h" #else #include "WProgram.h" // shouldn't need this but arduino sometimes messes up and puts inside an #ifdef #endif // ARDUINO -#define VERSION "3.10.4" +#define VERSION "3.11.3" //-- begin features @@ -49,6 +51,12 @@ // serial remote api #define RAPI +// RAPI over serial +#define RAPI_SERIAL + +// RAPI over I2C +//#define RAPI_I2C + // serial port command line // For the RTC version, only CLI or LCD can be defined at one time. // There is a directive to take care of that if you forget. @@ -267,6 +275,7 @@ #define LCD_MAX_CHARS_PER_LINE 16 + #ifdef SERIALCLI #define TMP_BUF_SIZE 64 #else @@ -292,7 +301,7 @@ //J1772EVSEController #define CURRENT_PIN 0 // analog current reading pin ADCx -#define VOLT_PIN 1 // analog pilot voltage reading pin ADCx +#define PILOT_PIN 1 // analog pilot voltage reading pin ADCx #ifdef OPENEVSE_2 #define VOLTMETER_PIN 2 // analog AC Line voltage voltemeter pin ADCx // This pin must match the last write to CHARGING_PIN, modulo a delay. If @@ -752,7 +761,7 @@ class OnboardDisplay #endif // GFI #ifdef TEMPERATURE_MONITORING -#include "./Adafruit_MCP9808.h" // adding the ambient temp sensor to I2C +#include "./MCP9808.h" // adding the ambient temp sensor to I2C #include "./Adafruit_TMP007.h" // adding the TMP007 IR I2C sensor #define TEMPMONITOR_UPDATE_INTERVAL 1000ul @@ -765,7 +774,7 @@ class TempMonitor { unsigned long m_LastUpdate; public: #ifdef MCP9808_IS_ON_I2C - Adafruit_MCP9808 m_tempSensor; + MCP9808 m_tempSensor; #endif //MCP9808_IS_ON_I2C #ifdef TMP007_IS_ON_I2C Adafruit_TMP007 m_tmp007; diff --git a/open_evse.ino b/open_evse.ino index df42dfa7..fb02058c 100644 --- a/open_evse.ino +++ b/open_evse.ino @@ -51,7 +51,7 @@ //#include "./LiquidCrystal_I2C.h" #ifdef TEMPERATURE_MONITORING #ifdef MCP9808_IS_ON_I2C - #include "./Adafruit_MCP9808.h" // adding the ambient temp sensor to I2C + #include "MCP9808.h" // adding the ambient temp sensor to I2C #endif #ifdef TMP007_IS_ON_I2C #include "./Adafruit_TMP007.h" // adding the TMP007 IR I2C sensor @@ -290,30 +290,36 @@ void TempMonitor::Read() m_TMP007_temperature = m_tmp007.readObjTempC10(); // using the TI TMP007 IR sensor #endif #ifdef MCP9808_IS_ON_I2C - m_MCP9808_temperature = m_tempSensor.readTempC10(); // for the MCP9808 - if (m_MCP9808_temperature == 2303) { - m_MCP9808_temperature = 0; } // return 0 if the sensor is not present on the I2C bus + m_MCP9808_temperature = m_tempSensor.readAmbient(); // for the MCP9808 #endif #ifdef RTC - // This code chunck below reads the DS3231 RTC's internal temperature sensor - Wire.beginTransmission(0x68); +#ifdef OPENEVSE_2 + m_DS3231_temperature = 0; // If the DS3231 is not present then return 0, OpenEVSE II does not use the DS3231 +#else // !OPENEVSE_2 + // This code chunk below reads the DS3231 RTC's internal temperature sensor + Wire.beginTransmission(DS1307_ADDRESS); wiresend(uint8_t(0x0e)); wiresend( 0x20 ); // write bit 5 to initiate conversion of temperature Wire.endTransmission(); - Wire.beginTransmission(0x68); + Wire.beginTransmission(DS1307_ADDRESS); wiresend(uint8_t(0x11)); Wire.endTransmission(); - Wire.requestFrom(0x68, 2); - m_DS3231_temperature = 10 * wirerecv(); // Here's the MSB - m_DS3231_temperature = m_DS3231_temperature + (5*(wirerecv()>>6))/2; // keep the reading like 235 meaning 23.5C - if (m_DS3231_temperature == 0x09FD) m_DS3231_temperature = 0; // If the DS3231 is not present then return 0 -#ifdef OPENEVSE_2 - m_DS3231_temperature = 0; // If the DS3231 is not present then return 0, OpenEVSE II does not use the DS3231 -#endif + Wire.requestFrom(DS1307_ADDRESS, 2); + m_DS3231_temperature = (((int16_t)wirerecv()) << 2) | (wirerecv() >> 6); + if (m_DS3231_temperature == 0x3FF) { + // assume chip not present + m_DS3231_temperature = 0; // If the DS3231 is not present then return 0 + } + else { + if (m_DS3231_temperature & 0x0200) m_DS3231_temperature |= 0xFE00; // sign extend negative number + // convert from .25C to .1C + m_DS3231_temperature = (m_DS3231_temperature * 10) / 4; + } +#endif // OPENEVSE_2 #endif // RTC m_LastUpdate = curms; @@ -741,21 +747,21 @@ void OnboardDisplay::Update(int8_t updmode) const char *tempfmt = "%2d.%1dC"; #ifdef MCP9808_IS_ON_I2C if ( g_TempMonitor.m_MCP9808_temperature != 0 ) { // it returns 0 if it is not present - sprintf(g_sTmp,tempfmt,g_TempMonitor.m_MCP9808_temperature/10, g_TempMonitor.m_MCP9808_temperature % 10); // Ambient sensor near or on the LCD + sprintf(g_sTmp,tempfmt,g_TempMonitor.m_MCP9808_temperature/10, abs(g_TempMonitor.m_MCP9808_temperature % 10)); // Ambient sensor near or on the LCD LcdPrint(0,1,g_sTmp); } #endif #ifdef RTC if ( g_TempMonitor.m_DS3231_temperature != 0) { // it returns 0 if it is not present - sprintf(g_sTmp,tempfmt,g_TempMonitor.m_DS3231_temperature/10, g_TempMonitor.m_DS3231_temperature % 10); // sensor built into the DS3231 RTC Chip + sprintf(g_sTmp,tempfmt,g_TempMonitor.m_DS3231_temperature/10, abs(g_TempMonitor.m_DS3231_temperature % 10)); // sensor built into the DS3231 RTC Chip LcdPrint(5,1,g_sTmp); } #endif #ifdef TMP007_IS_ON_I2C if ( g_TempMonitor.m_TMP007_temperature != 0 ) { // it returns 0 if it is not present - sprintf(g_sTmp,tempfmt,g_TempMonitor.m_TMP007_temperature/10, g_TempMonitor.m_TMP007_temperature % 10); // Infrared sensor probably looking at 30A fuses + sprintf(g_sTmp,tempfmt,g_TempMonitor.m_TMP007_temperature/10, abs(g_TempMonitor.m_TMP007_temperature % 10)); // Infrared sensor probably looking at 30A fuses LcdPrint(11,1,g_sTmp); } #endif @@ -893,7 +899,7 @@ void Btn::read() else if (sample && vlongDebounceTime && (buttonState == BTN_STATE_LONG)) { if ((millis() - vlongDebounceTime) >= BTN_PRESS_VERYLONG) { vlongDebounceTime = 0; - g_ERP.setWifiMode(WIFI_MODE_AP_DEFAULT); + RapiSetWifiMode(WIFI_MODE_AP_DEFAULT); } } #endif // RAPI @@ -2207,7 +2213,7 @@ void DelayTimer::PrintTimerIcon(){ void ProcessInputs() { #ifdef RAPI - g_ERP.doCmd(); + RapiDoCmd(); #endif #ifdef SERIALCLI g_CLI.getInput(); @@ -2238,6 +2244,10 @@ void EvseReset() g_OBD.Init(); +#ifdef RAPI + RapiInit(); +#endif + g_EvseController.Init(); } diff --git a/rapi_proc.cpp b/rapi_proc.cpp index 5a194b66..e21c5bc0 100644 --- a/rapi_proc.cpp +++ b/rapi_proc.cpp @@ -61,13 +61,26 @@ uint32_t dtou32(const char *s) return u; } +#ifdef RAPI_I2C +//get data from master - HINT: this is a ISR call! +//HINT2: do not handle stuff here!! this will NOT work +//collect only data here and process it in the main loop! +void receiveEvent(int numBytes) +{ + //do nothing here +} +#endif // RAPI_I2C + EvseRapiProcessor::EvseRapiProcessor() +{ +} + +void EvseRapiProcessor::init() { echo = 0; reset(); } -//extern HardwareSerial Serial; int EvseRapiProcessor::doCmd() { int rc = 1; @@ -108,16 +121,21 @@ int EvseRapiProcessor::doCmd() return rc; } + void EvseRapiProcessor::sendEvseState() { sprintf(g_sTmp,"%cST %02x%c",ESRAPI_SOC,g_EvseController.GetState(),ESRAPI_EOC); + writeStart(); write(g_sTmp); + writeEnd(); } void EvseRapiProcessor::setWifiMode(uint8_t mode) { sprintf(g_sTmp,"%cWF %02x%c",ESRAPI_SOC,(int)mode,ESRAPI_EOC); + writeStart(); write(g_sTmp); + writeEnd(); } int EvseRapiProcessor::tokenize() @@ -486,6 +504,8 @@ int EvseRapiProcessor::processCmd() void EvseRapiProcessor::response(uint8_t ok) { + writeStart(); + write(ESRAPI_SOC); write(ok ? "OK " : "NK "); @@ -494,8 +514,88 @@ void EvseRapiProcessor::response(uint8_t ok) } write(ESRAPI_EOC); if (echo) write('\n'); + + writeEnd(); +} + +EvseSerialRapiProcessor::EvseSerialRapiProcessor() +{ +} + +void EvseSerialRapiProcessor::init() +{ + EvseRapiProcessor::init(); +} + + +#ifdef RAPI_I2C + +EvseI2cRapiProcessor::EvseI2cRapiProcessor() +{ +} + +void EvseI2cRapiProcessor::init() +{ + Wire.begin(RAPI_I2C_LOCAL_ADDR); + Wire.onReceive(receiveEvent); // define the receive function for receiving data from master + + EvseRapiProcessor::init(); +} + + +#endif // RAPI_I2C + +#ifdef RAPI_SERIAL +EvseSerialRapiProcessor g_ESRP; +#endif +#ifdef RAPI_I2C +EvseI2cRapiProcessor g_EIRP; +#endif + +void RapiInit() +{ +#ifdef RAPI_SERIAL + g_ESRP.init(); +#endif +#ifdef RAPI_I2C + g_EIRP.init(); +#endif } +void RapiDoCmd() +{ +#ifdef RAPI_SERIAL + g_ESRP.doCmd(); +#endif +#ifdef RAPI_I2C + g_EIRP.doCmd(); +#endif +} + +void RapiSendEvseState(uint8_t nodupe) +{ + static uint8_t evseStateSent = EVSE_STATE_UNKNOWN; + uint8_t es = g_EvseController.GetState(); + + if (!nodupe || (evseStateSent != es)) { +#ifdef RAPI_SERIAL + g_ESRP.sendEvseState(); +#endif +#ifdef RAPI_I2C + g_EIRP.sendEvseState(); +#endif + evseStateSent = es; + } +} + +void RapiSetWifiMode(uint8_t mode) +{ +#ifdef RAPI_SERIAL + g_ESRP.setWifiMode(mode); +#endif +#ifdef RAPI_I2C + g_EIRP.setWifiMode(mode); +#endif +} -EvseRapiProcessor g_ERP; #endif // RAPI diff --git a/rapi_proc.h b/rapi_proc.h index 6bbc1c77..f01f3951 100644 --- a/rapi_proc.h +++ b/rapi_proc.h @@ -99,7 +99,7 @@ SE 0|1 - disable/enable command echo $SE 1*0D use this for interactive terminal sessions with RAPI. RAPI will echo back characters as they are typed, and add a character - after its replies + after its replies. Valid only over a serial connection, DO NOT USE on I2C SF 0|1 - disable/enable GFI self test $SF 0*0D $SF 1*0E @@ -207,10 +207,12 @@ class EvseRapiProcessor { int8_t tokenCnt; char echo; - int available() { return Serial.available(); } - int read() { return Serial.read(); } - void write(const char *str) { Serial.write(str); } - void write(uint8_t u8) { Serial.write(u8); } + virtual int available() = 0; + virtual int read() = 0; + virtual void writeStart() {} + virtual void writeEnd() {} + virtual int write(uint8_t u8) = 0; + virtual int write(const char *str) = 0; void reset() { buffer[0] = 0; @@ -224,11 +226,44 @@ class EvseRapiProcessor { public: EvseRapiProcessor(); + int doCmd(); void sendEvseState(); void setWifiMode(uint8_t mode); // WIFI_MODE_xxx + + virtual void init(); +}; + + +class EvseSerialRapiProcessor : public EvseRapiProcessor { + int available() { return Serial.available(); } + int read() { return Serial.read(); } + int write(const char *str) { return Serial.write(str); } + int write(uint8_t u8) { return Serial.write(u8); } + +public: + EvseSerialRapiProcessor(); + void init(); +}; + +#ifdef RAPI_I2C +class EvseI2cRapiProcessor : public EvseRapiProcessor { + int available() { return Wire.available(); } + int read() { return Wire.read(); } + void writeStart() { Wire.beginTransmission(RAPI_I2C_REMOTE_ADDR); } + void writeEnd() { Wire.endTransmission(); } + int write(const char *str) { return Wire.write(str); } + int write(uint8_t u8) { return Wire.write(u8); } + +public: + EvseI2cRapiProcessor(); + void init(); }; +#endif // RAPI_I2C -extern EvseRapiProcessor g_ERP; +void RapiInit(); +void RapiDoCmd(); +void RapiSendEvseState(uint8_t nodupe=1); +void RapiSetWifiMode(uint8_t mode); #endif // RAPI