Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for different parity settings and YTL meter #37

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions version2/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Ignoring files according to http://microchip.wikidot.com/faq:72
/SmartEVSE2.X/build/
#Ingoring private Makefiles, to create them open the MPLAB IDE or use the C:\Program Files (x86)\Microchip\MPLABX\<VERSION>\mplab_ide\bin\prjMakefilesGenerator.bat script
#Ignoring private Makefiles, to create them open the MPLAB IDE or use the C:\Program Files (x86)\Microchip\MPLABX\<VERSION>\mplab_ide\bin\prjMakefilesGenerator.bat script
/SmartEVSE2.X/nbproject/Makefile-*
/SmartEVSE2.X/nbproject/Package-*
/SmartEVSE2.X/nbproject/private/
/SmartEVSE2.X/nbproject/private/
/SmartEVSE2.X/dist/default/debug/
/SmartEVSE2.X/dist/default/production/
204 changes: 162 additions & 42 deletions version2/SmartEVSE2.X/EVSE.c

Large diffs are not rendered by default.

96 changes: 62 additions & 34 deletions version2/SmartEVSE2.X/EVSE.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
//#define SPECIAL // if defined, it will modify program so that some menu options are not shown
// should be undefined by default

//#define MODBUSPRINT // debug print the modbus messages
//#define MODBUSPRINT // debug print the modbus messages
#define MODBUS_REQUEST_INTERVAL 100 // Minimum interval between modbus requests (set to 100ms to maximize compatibility)

#define ICAL 1.00 // Irms Calibration value (for Current transformers)
#define MAX_MAINS 25 // max Current the Mains connection can supply
Expand Down Expand Up @@ -72,8 +73,11 @@
#define EV_METER 0
#define EV_METER_ADDRESS 12
#define EMCUSTOM_ENDIANESS 0
#define EMCUSTOM_DATAFORMAT 0
#define EMCUSTOM_IREGISTER 0
#define EMCUSTOM_IDIVISOR 0
#define EMCUSTOM_EREGISTER 0
#define EMCUSTOM_EDIVISOR 0

// Mode settings
#define MODE_NORMAL 0
Expand Down Expand Up @@ -150,9 +154,12 @@
#define MENU_EVMETER 22
#define MENU_EVMETERADDRESS 23
#define MENU_EMCUSTOM_ENDIANESS 24
#define MENU_EMCUSTOM_IREGISTER 25
#define MENU_EMCUSTOM_IDIVISOR 26
#define MENU_EXIT 27
#define MENU_EMCUSTOM_DATAFORMAT 25
#define MENU_EMCUSTOM_IREGISTER 26
#define MENU_EMCUSTOM_IDIVISOR 27
#define MENU_EMCUSTOM_EREGISTER 28
#define MENU_EMCUSTOM_EDIVISOR 29
#define MENU_EXIT 30

#define STATUS_STATE 64
#define STATUS_ERROR 65
Expand All @@ -164,12 +171,6 @@
#define STATUS_ACCESS 71
#define STATUS_MODE 72

#define EM_SENSORBOX 1 // Mains meter types
#define EM_PHOENIX_CONTACT 2
#define EM_FINDER 3
#define EM_EASTRON 4
#define EM_CUSTOM 5

#define MODBUS_INVALID 0
#define MODBUS_OK 1
#define MODBUS_REQUEST 2
Expand All @@ -189,6 +190,19 @@
#define _A0_0 LATCbits.LATC0 = 0;
#define _A0_1 LATCbits.LATC0 = 1;

#define DATAFORMAT_8N1 0
#define DATAFORMAT_8N2 1
#define DATAFORMAT_8E1 2
#define DATAFORMAT_8O1 3

#define ENDIANESS_LBF_LWF 0
#define ENDIANESS_LBF_HWF 1
#define ENDIANESS_HBF_LWF 2
#define ENDIANESS_HBF_HWF 3

// Validate defines


extern char GLCDbuf[512]; // GLCD buffer (half of the display)

extern unsigned int MaxMains; // Max Mains Amps (hard limit, limited by the MAINS connection)
Expand All @@ -215,6 +229,7 @@ extern unsigned char EVMeter;
extern unsigned char EVMeterAddress;

extern signed double Irms[3]; // Momentary current per Phase (Amps *10) (23 = 2.3A)
extern double EVIrms[3]; // Momentary current per Phase to the EV (Amps *10) (23 = 2.3A)

extern unsigned char State;
extern unsigned char Error;
Expand Down Expand Up @@ -247,7 +262,35 @@ extern unsigned int SolarStopTimer;
extern unsigned char SolarTimerEnable;
extern signed double EnergyCharged;

extern unsigned char MenuItems[27];
#define EM_SENSORBOX 1 // Mains meter types
#define EM_PHOENIX_CONTACT 2
#define EM_FINDER 3
#define EM_EASTRON 4
#define EM_YTL 5
#define EM_CUSTOM 6

struct {
unsigned char Desc[10];
unsigned char Endianness; // 0: low byte first, low word first, 1: low byte first, high word first, 2: high byte first, low word first, 3: high byte first, high word first
unsigned char DataFormat; // Stop bits / Parity
unsigned char Function; // Modbus function: 3 = holding registers, 4 = input registers
unsigned int IRegister; // Single phase current (A)
unsigned char IDivisor; // 10^x / 8:double
unsigned int ERegister; // Total energy (kWh)
unsigned char EDivisor; // 10^x / 8:double
unsigned int PRegister; // Total power (W)
unsigned char PDivisor; // 10^x / 8:double
} EMConfig[7] = {
{"Disabled", ENDIANESS_LBF_LWF, DATAFORMAT_8N1, 0, 0, 0, 0, 0, 0, 0}, // First entry!
{"Sensorbox", ENDIANESS_HBF_HWF, DATAFORMAT_8N1, 4, 0, 0, 0xFFFF, 0, 0xFFFF, 0}, // Sensorbox (Own routine for request/receive)
{"Phoenix C", ENDIANESS_HBF_LWF, DATAFORMAT_8N1, 4, 0xC, 3, 0x3E, 1, 0x28, 1}, // PHOENIX CONTACT EEM-350-D-MCB (mA / 0,1kWh / 0,1W)
{"Finder", ENDIANESS_HBF_HWF, DATAFORMAT_8N1, 4, 0x100E, 8, 0x1106, 8, 0x1026, 8}, // Finder 7E.78.8.400.0212 (A / Wh / W)
{"Eastron", ENDIANESS_HBF_HWF, DATAFORMAT_8N1, 4, 0x6, 8, 0x156, 8, 0x34, 8}, // Eastron SDM630 (Own routine for request/receive) (A / kWh / W)
{"YTL", ENDIANESS_HBF_HWF, DATAFORMAT_8N2, 3, 0x16, 8, 0x100, 8, 0x2e, 8}, // YTL DTS353F-2
{"Custom", ENDIANESS_LBF_LWF, DATAFORMAT_8N1, 4, 0, 0, 0, 0, 0xFFFF, 0} // Last entry!
};

extern unsigned char MenuItems[];

const far struct {
char Key[8];
Expand All @@ -256,7 +299,7 @@ const far struct {
unsigned int Min;
unsigned int Max;
unsigned int Default;
} MenuStr[28] = {
} MenuStr[] = {
{"", "", "Not in menu", 0, 0, 0},
{"", "", "Hold 2 sec", 0, 0, 0},
{"CONFIG", "CONFIG", "Set to Fixed Cable or Type 2 Socket", 0, 1, CONFIG},
Expand All @@ -273,38 +316,23 @@ const far struct {
{"MODE", "MODE", "Set to Normal, Smart or Solar EVSE mode", 0, 2, MODE},
{"MAINS", "MAINS", "Set Max MAINS Current", 10, 100, MAX_MAINS},
{"CAL", "CAL", "Calibrate CT1 (CT2+3 will also change)", 30, 200, (unsigned int) (ICAL * 100)}, // valid range is 0.3 - 2.0 times measured value
{"MAINEM", "MAINSMET", "Type of mains electric meter", 1, 5, MAINS_METER},
{"MAINEM", "MAINSMET", "Type of mains electric meter", 1, sizeof(EMConfig)/sizeof(EMConfig[0])-1, MAINS_METER},
{"GRID", "GRID", "Grid type to which the Sensorbox is connected", 0, 1, GRID},
{"MAINAD", "MAINSADR", "Address of mains electric meter", 5, 255, MAINS_METER_ADDRESS},
{"MAINM", "MAINSMES", "Mains electric meter scope (What does it measure?)", 0, 1, MAINS_METER_MEASURE},
{"PVEM", "PV METER", "Type of PV electric meter", 0, 5, PV_METER},
{"PVEM", "PV METER", "Type of PV electric meter", 0, sizeof(EMConfig)/sizeof(EMConfig[0])-1, PV_METER},
{"PVAD", "PV ADDR", "Address of PV electric meter", 5, 255, PV_METER_ADDRESS},
{"EVEM", "EV METER", "Type of EV electric meter", 0, 4, EV_METER},
{"EVEM", "EV METER", "Type of EV electric meter", 0, sizeof(EMConfig)/sizeof(EMConfig[0])-1, EV_METER},
{"EVAD", "EV ADDR", "Address of EV electric meter", 5, 255, EV_METER_ADDRESS},
{"EMBO" , "BYTE ORD", "Byte order of custom electric meter", 0, 3, EMCUSTOM_ENDIANESS},
{"EMIREG", "CUR REGI", "Register for Current of custom electric meter", 0, 255, EMCUSTOM_IREGISTER},
{"EMDF" , "PROTOCOL", "Data format of custom electric meter", 0, 3, EMCUSTOM_DATAFORMAT},
{"EMIREG", "CUR REGI", "Register for Current of custom electric meter", 0, 65535, EMCUSTOM_IREGISTER},
{"ENIDIV", "CUR DIVI", "Divisor for Current of custom electric meter", 0, 8, EMCUSTOM_IDIVISOR},
{"EMEREG", "ENE REGI", "Register for Energy of custom electric meter", 0, 65535, EMCUSTOM_EREGISTER},
{"ENEDIV", "ENE DIVI", "Divisor for Energy of custom electric meter", 0, 8, EMCUSTOM_EDIVISOR},
{"EXIT", "EXIT", "EXIT", 0, 0, 0}
};

struct {
unsigned char Desc[10];
unsigned char Endianness; // 0: low byte first, low word first, 1: low byte first, high word first, 2: high byte first, low word first, 3: high byte first, high word first
unsigned int IRegister; // Single phase current (A)
unsigned char IDivisor; // 10^x / 8:double
unsigned int ERegister; // Total energy (kWh)
unsigned char EDivisor; // 10^x / 8:double
unsigned int PRegister; // Total power (W)
unsigned char PDivisor; // 10^x / 8:double
} EMConfig[6] = {
{"Disabled", 0, 0, 0, 0, 0, 0, 0}, // First entry!
{"Sensorbox", 3, 0, 0, 0xFFFF, 0, 0xFFFF, 0}, // Sensorbox (Own routine for request/receive)
{"Phoenix C", 2, 0xC, 3, 0x3E, 1, 0x28, 1}, // PHOENIX CONTACT EEM-350-D-MCB (mA / 0,1kWh / 0,1W)
{"Finder", 3, 0x100E, 8, 0x1106, 8, 0x1026, 8}, // Finder 7E.78.8.400.0212 (A / Wh / W)
{"Eastron", 3, 0x6, 8, 0x156, 8, 0x34, 8}, // Eastron SDM630 (Own routine for request/receive) (A / kWh / W)
{"Custom", 0, 0, 0, 0xFFFF, 0, 0xFFFF, 0} // Last entry!
};

void delay(unsigned int d);
void read_settings(void);
void write_settings(void);
Expand Down
93 changes: 51 additions & 42 deletions version2/SmartEVSE2.X/GLCD.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,33 +159,33 @@ const far unsigned char font[] = {
0x02, 0x01, 0x02, 0x04, 0x02, // 0x7E ~
0x3C, 0x26, 0x23, 0x26, 0x3C, // 0x7F
0x1E, 0xA1, 0xA1, 0x61, 0x12, // 0x80
0x3A, 0x40, 0x40, 0x20, 0x7A, // 0x81 �
0x38, 0x54, 0x54, 0x55, 0x59, // 0x82 �
0x21, 0x55, 0x55, 0x79, 0x41, // 0x83 �
0x21, 0x54, 0x54, 0x78, 0x41, // 0x84 �
0x21, 0x55, 0x54, 0x78, 0x40, // 0x85 �
0x20, 0x54, 0x55, 0x79, 0x40, // 0x86 �
0x3A, 0x40, 0x40, 0x20, 0x7A, // 0x81 �
0x38, 0x54, 0x54, 0x55, 0x59, // 0x82 �
0x21, 0x55, 0x55, 0x79, 0x41, // 0x83 �
0x21, 0x54, 0x54, 0x78, 0x41, // 0x84 �
0x21, 0x55, 0x54, 0x78, 0x40, // 0x85 �
0x20, 0x54, 0x55, 0x79, 0x40, // 0x86 �
0x0C, 0x1E, 0x52, 0x72, 0x12, // 0x87
0x39, 0x55, 0x55, 0x55, 0x59, // 0x88 �
0x39, 0x55, 0x55, 0x55, 0x59, // 0x88 �
0x39, 0x54, 0x54, 0x54, 0x59, // 0x89
0x39, 0x55, 0x54, 0x54, 0x58, // 0x8A �
0x39, 0x55, 0x54, 0x54, 0x58, // 0x8A �
0x00, 0x00, 0x45, 0x7C, 0x41, // 0x8B
0x00, 0x02, 0x45, 0x7D, 0x42, // 0x8C
0x00, 0x01, 0x45, 0x7C, 0x40, // 0x8D �
0xF0, 0x29, 0x24, 0x29, 0xF0, // 0x8E �
0x00, 0x01, 0x45, 0x7C, 0x40, // 0x8D �
0xF0, 0x29, 0x24, 0x29, 0xF0, // 0x8E �
0xF0, 0x28, 0x25, 0x28, 0xF0, // 0x8F
0x7C, 0x54, 0x55, 0x45, 0x00, // 0x90 �
0x7C, 0x54, 0x55, 0x45, 0x00, // 0x90 �
0x20, 0x54, 0x54, 0x7C, 0x54, // 0x91
0x7C, 0x0A, 0x09, 0x7F, 0x49, // 0x92
0x32, 0x49, 0x49, 0x49, 0x32, // 0x93 �
0x32, 0x48, 0x48, 0x48, 0x32, // 0x94 �
0x32, 0x4A, 0x48, 0x48, 0x30, // 0x95 �
0x3A, 0x41, 0x41, 0x21, 0x7A, // 0x96 �
0x3A, 0x42, 0x40, 0x20, 0x78, // 0x97 �
0x32, 0x49, 0x49, 0x49, 0x32, // 0x93 �
0x32, 0x48, 0x48, 0x48, 0x32, // 0x94 �
0x32, 0x4A, 0x48, 0x48, 0x30, // 0x95 �
0x3A, 0x41, 0x41, 0x21, 0x7A, // 0x96 �
0x3A, 0x42, 0x40, 0x20, 0x78, // 0x97 �
0x00, 0x9D, 0xA0, 0xA0, 0x7D, // 0x98
0x39, 0x44, 0x44, 0x44, 0x39, // 0x99 �
0x3D, 0x40, 0x40, 0x40, 0x3D, // 0x9A �
0x3C, 0x24, 0xFF, 0x24, 0x24, // 0x9B �
0x39, 0x44, 0x44, 0x44, 0x39, // 0x99 �
0x3D, 0x40, 0x40, 0x40, 0x3D, // 0x9A �
0x3C, 0x24, 0xFF, 0x24, 0x24, // 0x9B �
0x48, 0x7E, 0x49, 0x43, 0x66, // 0x9C
0x2B, 0x2F, 0xFC, 0x2F, 0x2B, // 0x9D
0xFF, 0x09, 0x29, 0xF6, 0x20, // 0x9E
Expand Down Expand Up @@ -226,7 +226,7 @@ const far unsigned char font[] = {
0x10, 0x10, 0x10, 0xF0, 0x10, // 0xC1
0x00, 0x00, 0x00, 0xFF, 0x10, // 0xC2
0x10, 0x10, 0x10, 0x10, 0x10, // 0xC3
0x7D, 0x12, 0x11, 0x12, 0x7D, // 0xC4 �
0x7D, 0x12, 0x11, 0x12, 0x7D, // 0xC4 �
0x00, 0x00, 0x00, 0xFF, 0x14, // 0xC5
0x00, 0x00, 0xFF, 0x00, 0xFF, // 0xC6
0x00, 0x00, 0x1F, 0x10, 0x17, // 0xC7
Expand All @@ -244,21 +244,21 @@ const far unsigned char font[] = {
0x00, 0x00, 0x00, 0x1F, 0x14, // 0xD3
0x00, 0x00, 0x00, 0xFC, 0x14, // 0xD4
0x00, 0x00, 0xF0, 0x10, 0xF0, // 0xD5
0x3D, 0x42, 0x42, 0x42, 0x3D, // 0xD6 �
0x3D, 0x42, 0x42, 0x42, 0x3D, // 0xD6 �
0x14, 0x14, 0x14, 0xFF, 0x14, // 0xD7
0x10, 0x10, 0x10, 0x1F, 0x00, // 0xD8
0x00, 0x00, 0x00, 0xF0, 0x10, // 0xD9
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xDA
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, // 0xDB
0x22, 0x54, 0x54, 0x78, 0x42, // 0xDC � (tbd)
0x22, 0x54, 0x54, 0x78, 0x42, // 0xDC � (tbd)
0x00, 0x00, 0x00, 0xFF, 0xFF, // 0xDD
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, // 0xDE
0x38, 0x44, 0x44, 0x38, 0x44, // 0xDF
0x7C, 0x2A, 0x2A, 0x3E, 0x14, // 0xE0
0x7E, 0x02, 0x02, 0x06, 0x06, // 0xE1
0x02, 0x7E, 0x02, 0x7E, 0x02, // 0xE2
0x63, 0x55, 0x49, 0x41, 0x63, // 0xE3
0x22, 0x54, 0x54, 0x78, 0x42, // 0xE4 �
0x22, 0x54, 0x54, 0x78, 0x42, // 0xE4 �
0x40, 0x7E, 0x20, 0x1E, 0x20, // 0xE5
0x06, 0x02, 0x7E, 0x02, 0x02, // 0xE6
0x99, 0xA5, 0xE7, 0xA5, 0x99, // 0xE7
Expand All @@ -276,13 +276,13 @@ const far unsigned char font[] = {
0x00, 0x00, 0xFF, 0x01, 0x03, // 0xF3
0xE0, 0x80, 0xFF, 0x00, 0x00, // 0xF4
0x08, 0x08, 0x6B, 0x6B, 0x08, // 0xF5
0x3A, 0x44, 0x44, 0x44, 0x3A, // 0xF6 �
0x3A, 0x44, 0x44, 0x44, 0x3A, // 0xF6 �
0x06, 0x0F, 0x09, 0x0F, 0x06, // 0xF7
0x00, 0x00, 0x03, 0x03, 0x00, // 0xF8 �
0x00, 0x00, 0x03, 0x03, 0x00, // 0xF8 �
0x00, 0x00, 0x10, 0x10, 0x00, // 0xF9
0x30, 0x40, 0xFF, 0x01, 0x01, // 0xFA
0x00, 0x1F, 0x01, 0x01, 0x1E, // 0xFB
0x00, 0x19, 0x1D, 0x17, 0x12, // 0xFC � (tbd)
0x00, 0x19, 0x1D, 0x17, 0x12, // 0xFC � (tbd)
0x00, 0x3C, 0x3C, 0x3C, 0x3C, // 0xFD
0x08, 0x1C, 0x1C, 0x1C, 0x08 // 0xFE Energy blob
};
Expand Down Expand Up @@ -505,18 +505,15 @@ void GLCD(void) {
if (Error & LESS_6A) {
GLCD_print_buf2(2, (const far char *) "WAITING");
GLCD_print_buf2(4, (const far char *) "FOR POWER");
}

else if (State == STATE_C) { // STATE C
} else if (State == STATE_C) { // STATE C

BACKLIGHT_ON; // LCD backlight on
BacklightTimer = BACKLIGHT;

GLCD_print_buf2(2, (const far char *) "CHARGING");
sprintfd(Str, "%u.%uA", Balanced[0] / 10.0, 1);
GLCD_print_buf2(4, Str);
} else
{ // STATE A and STATE B
} else { // STATE A and STATE B
if (Access_bit) {
GLCD_print_buf2(2, (const far char *) "READY TO");
GLCD_print_buf2(4, (const far char *) "CHARGE ");
Expand Down Expand Up @@ -570,8 +567,9 @@ void GLCD(void) {
if (abs(Isum) >3 ) GLCD_write_buf(0xFE); // Show energy flow 'blob' between Grid and House
// If current flow is < 0.3A don't show the blob
if (EVMeter) { // If we have a EV kWh meter configured, Show total charged energy in kWh on LCD.
sprintfd(Str, "%2u.%1ukWh", EnergyCharged, 1);
GLCD_print_buf(89,1, Str); // print to buffer
sprintfd(Str, "%2u.%1u", EnergyCharged, 1);
GLCD_print_buf(100, 0, Str); // print to buffer
GLCD_print_buf(106, 1, "kWh"); // print to buffer
}

if (State == STATE_C) {
Expand All @@ -586,8 +584,17 @@ void GLCD(void) {
GLCDy = 3;
GLCD_write_buf(0xFE); // Show energy flow 'blob' between House and Car

sprintfd(Str, "%2uA", Balanced[0] / 10.0, 0);
GLCD_print_buf(77, 2, Str); // print to buffer
if (EVMeter) {
for (x = 0; x < 3; x++) // Display L1, L2 and L3 currents on LCD
{
sprintfd(Str, "%2uA", EVIrms[x] / 10.0, 0); // TODO
GLCD_print_buf(77, x, Str); // print to buffer
}
}
else {
sprintfd(Str, "%2uA", Balanced[0] / 10.0, 0);
GLCD_print_buf(77, 2, Str); // print to buffer
}
}

if (LCDTimer < 5 && Mode == MODE_SOLAR) // Show Sum of currents when solar charging.
Expand Down Expand Up @@ -616,11 +623,13 @@ void GLCD(void) {
if (LCDTimer < 5) {
GLCD_print_buf2(5, (const far char *) "WAITING");
} else GLCD_print_buf2(5, (const far char *) "FOR SOLAR");
} else if (State == STATE_A || State == STATE_B) { // STATE A +B message
if (ChargeDelay) {
sprintf(Str, "READY %u", ChargeDelay);
GLCD_print_buf2(5, Str);
} else GLCD_print_buf2(5, (const far char *) "READY");
} else if (ChargeDelay && (State == STATE_A|| State == STATE_B)) { // STATE A + B message, when waiting for charge delay
sprintf(Str, "READY %u", ChargeDelay);
GLCD_print_buf2(5, Str);
} else if (State == STATE_A) { // STATE A message
GLCD_print_buf2(5, (const far char *) "READY");
} else if (State == STATE_B) { // STATE B message
GLCD_print_buf2(5, (const far char *) "CONNECTED");
} else if (State == STATE_C) {
BACKLIGHT_ON; // LCD backlight on
BacklightTimer = BACKLIGHT;
Expand All @@ -632,7 +641,7 @@ void GLCD(void) {

} else GLCD_print_buf2(5, (const far char *) "CHARGING");
} else { //LCDTimer 6-9 sec
sprintfd(Str, "%u.%uA", Balanced[0] / 10.0, 1);
sprintfd(Str, "< %u.%uA", Balanced[0] / 10.0, 1);
GLCD_print_buf2(5, Str);
}
}
Expand Down Expand Up @@ -804,7 +813,7 @@ void GLCDMenu(unsigned char Buttons) {
break;
}

sprintf(Str, "%3i\370C", TempEVSE); // \370 is the octal representation of the � symbol
sprintf(Str, "%3i\370C", TempEVSE); // \370 is the octal representation of the � symbol
GLCD_print(0,7, Str);
GLCD_print(122-(strlen(VERSION)*6),7, (const far char *) "v"VERSION);// show software version in bottom right corner.
}
Expand Down
Loading