Skip to content
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
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ Provides:
- Defaults set to read Volts, Power, Current, State of Charge (SOC), Alarm
- Easily extendible by adding labels for any other stats and settings of interest
- A diagnostic "full dump" of everything coming from the device

This branch implements SoftwareSerial primarily for ESP8266 boards that need their native USB port for debug purposes.

### Usage:
```C
#include "VEDirect.h"

VEDirect my_bmv(Serial3);
// Serial pins
#define rxPin D7
#define txPin D8

VEDirect my_bmv(rxPin, txPin);
my_int32 = my_bmv.read(VE_SOC);

// VE_SOC, VE_VOLTAGE, VE_CURRENT, VE_POWER, VE_ALARM
Expand Down
132 changes: 69 additions & 63 deletions examples/ReadVEDirect/ReadVEDirect.ino
Original file line number Diff line number Diff line change
@@ -1,63 +1,69 @@
/******************************************************************
VEDirect Arduino

Copyright 2018, 2019, Brendan McLearie
Distributed under MIT license - see LICENSE.txt

See README.md

File: ReadVEDirect.ino / ReadVEDirect.cpp
- Provides example use of the VEDirect library
******************************************************************/

#include "Arduino.h"
#include "VEDirect.h"

// 32 bit ints to collect the data from the device
int32_t VE_soc, VE_power, VE_voltage, VE_current;
// Boolean to collect an ON/OFF value
uint8_t VE_alarm;

// VEDirect instantiated with relevant serial object
VEDirect myve(Serial3);

void setup() {
Serial.begin(9600); // Adjust as needed
}

void loop() {
Serial.println("Reading values from Victron Energy device using VE.Direct text mode");
Serial.println();

// Read the data
if(myve.begin()) { // test connection
VE_soc = myve.read(VE_SOC);
VE_power = myve.read(VE_POWER);
VE_voltage = myve.read(VE_VOLTAGE);
VE_current = myve.read(VE_CURRENT);
VE_alarm = myve.read(VE_ALARM);
} else {
Serial.println("Could not open serial port to VE device");
while (1);
}

// Print each of the values
Serial.print("State of Charge (SOC): ");
Serial.println(VE_soc, DEC);
Serial.print("Power: ");
Serial.println(VE_power, DEC);
Serial.print("Voltage ");
Serial.println(VE_voltage, DEC);
Serial.print("Current ");
Serial.println(VE_current, DEC);
Serial.print("Alarm ");
Serial.println(VE_alarm, DEC);
Serial.println();

// Copy the raw data stream (minus the \r) to Serial0
// Call read() with a token that won't match any VE.Direct labels
Serial.println("All data from device:");
myve.read(VE_DUMP);
Serial.println();
delay(10000);
}
/******************************************************************
VEDirect Arduino

Copyright 2018, 2019, Brendan McLearie
Distributed under MIT license - see LICENSE.txt

See README.md

File: ReadVEDirect.ino / ReadVEDirect.cpp
- Provides example use of the VEDirect library

2020.04.10 - convert to SoftwareSerial
******************************************************************/

#include "Arduino.h"
#include "VEDirect.h"

// Serial pins
#define rxPin D7
#define txPin D8

// 32 bit ints to collect the data from the device
int32_t VE_soc, VE_power, VE_voltage, VE_current;
// Boolean to collect an ON/OFF value
uint8_t VE_alarm;

// VEDirect instantiated with relevant serial object
VEDirect myve(rxPin, txPin);

void setup() {
Serial.begin(19200); // Adjust as needed - DEBUG serial port
}

void loop() {
Serial.println("Reading values from Victron Energy device using VE.Direct text mode");
Serial.println();

// Read the data
if(myve.begin()) { // test connection
VE_soc = myve.read(VE_SOC);
VE_power = myve.read(VE_POWER);
VE_voltage = myve.read(VE_VOLTAGE);
VE_current = myve.read(VE_CURRENT);
VE_alarm = myve.read(VE_ALARM);
} else {
Serial.println("Could not open serial port to VE device");
while (1);
}

// Print each of the values
Serial.print("State of Charge (SOC): ");
Serial.println(VE_soc, DEC);
Serial.print("Power: ");
Serial.println(VE_power, DEC);
Serial.print("Voltage ");
Serial.println(VE_voltage, DEC);
Serial.print("Current ");
Serial.println(VE_current, DEC);
Serial.print("Alarm ");
Serial.println(VE_alarm, DEC);
Serial.println();

// Copy the raw data stream (minus the \r) to Serial0
// Call read() with a token that won't match any VE.Direct labels
Serial.println("All data from device:");
myve.read(VE_DUMP);
Serial.println();
delay(10000);
}
50 changes: 28 additions & 22 deletions src/VEDirect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
- Implementation
Updates:
- 2019-07-14 See VEDirect.h
- 2020-04-10 Converted to SoftwareSerial, added checks for null pointers for ESP8266
- 2020-08-31 Removed errant constructor
******************************************************************/

#include "VEDirect.h"

VEDirect::VEDirect(HardwareSerial& port):
VESerial(port)
VEDirect::VEDirect(byte rxPin, byte txPin):
VESerial(*new SoftwareSerial(rxPin, txPin))
// Initialise the serial port that the
// VE.Direct device is connected to and
// store it for later use.
Expand All @@ -28,7 +30,7 @@ VEDirect::~VEDirect() {

uint8_t VEDirect::begin() {
// Check connection the serial port
VESerial.begin(19200);
VESerial.begin(VED_BAUD_RATE);
if (VESerial) {
delay(500);
if(VESerial.available()) {
Expand Down Expand Up @@ -85,26 +87,30 @@ int32_t VEDirect::read(uint8_t target) {
}

label = strtok(line, "\t");
if (strcmp_P(label, ved_labels[target]) == 0) {
value_str = strtok(0, "\t");
if (value_str[0] == 'O') { //ON OFF type
if (value_str[1] == 'N') {
ret = 1; // ON
break;
} else {
ret = 0; // OFF
break;
}
} else {
sscanf(value_str, "%ld", &ret);
break;
if (label) {
if (strcmp_P(label, ved_labels[target]) == 0) {
value_str = strtok(0, "\t");
if (value_str) {
if (value_str[0] == 'O') { //ON OFF type
if (value_str[1] == 'N') {
ret = 1; // ON
break;
} else {
ret = 0; // OFF
break;
}
} else {
sscanf(value_str, "%ld", &ret);
break;
}
}
} else { // Line not of interest
lines--;
loops = VED_MAX_READ_LOOPS;
line[0] = '\0';
idx = 0;
}
} else { // Line not of interest
lines--;
loops = VED_MAX_READ_LOOPS;
line[0] = '\0';
idx = 0;
}
}
}
}
return ret;
Expand Down
7 changes: 5 additions & 2 deletions src/VEDirect.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
- Target labels extendible with enum and PROGMEM strings
- Retired copy_raw_to_serial0() code - use VE_DUMP on read
- Added some tunable parameters see #defines
- 2020-04-10:
- Convert to SoftwareSerial so ESP8266 can use native usb serial for debug
******************************************************************/

#ifndef VEDIRECT_H_
#define VEDIRECT_H_

#include <Arduino.h>
#include <SoftwareSerial.h>

// Tunable parameters - defaults tested on mega2560 R3
#define VED_LINE_SIZE 30 // Seems to be plenty. VE.Direct protocol could change
Expand Down Expand Up @@ -52,13 +55,13 @@ const char ved_labels[VE_LAST_LABEL][VED_MAX_LEBEL_SIZE] PROGMEM = {

class VEDirect {
public:
VEDirect(HardwareSerial& port);
VEDirect(byte rxPin, byte txPin);
virtual ~VEDirect();
uint8_t begin();
int32_t read(uint8_t target);
void copy_raw_to_serial0(); // kept for backwards compatibility
private:
HardwareSerial& VESerial;
SoftwareSerial& VESerial;
};

#endif /* VEDIRECT_H_ */