The easiest (and preferred, according to Victron) way to connect an Arduino to Victron Equipment is through the VE Direct port, shown above, which is available on most of their newer equipment. This protocol/connection reminds me of a lot of NMEA0183, with the slow speed, use of simple messages, and checksums.
One thing to watch out for is the voltage- it varies by product, so may need to use a level converter (or voltage divider of low resistance values, suggest 120 and 60 ohms to bring 5V to 3.3V) depending on a match with the chosen microcontroller’s logic level.
- BMV-700: 3v3
- MPPT all models: 5v
- Newer MPPTs (as now under development) will be 5V.
- MPPT RS, Multi RS, any other RS: 3v3
- VE.Direct Inverters 250…500VA – 3V3
- VE.Direct Inverters 800VA & 1200VA 3V3
- Smart Inverters 1600VA…5000VA – 3V3
Here’s the Tx signal measured with no ground reference (note, it may not look it due to effects of the oscilloscope, but this is a 5v amplitude signal when measured with a multimeter or the Arduino’s digital inputs):
There are two versions of VE Direct, Text and HEX. Text is more intuitive but only allows reading of values, not writing. All I want to do is read, so I’ll stick with Text.
Wiring guide:
Code
See here if using an Arduino Uno. “SoftwareSerial” is used to produce a makeshift Serial Port on other digital IO pins, because the Uno only comes with one dedicated UART(Pins 0 and 1), which is used for programming/USB functions (shared hardware). I got this working without trouble, just update the rxPin definitions to be “7” instead of “d7”, 8 instead of “d8”. There are some limitations of SoftwareSerial, here. A common issue if things are not working w/ SoftwareSerial (not the case for Victron, but NMEA0183 yes) is that the signal may need to be inverted. To invert, use the extra 1:
SoftwareSerial mySerial(7, 8, 1); // RX pin, TX pin, then note the 1 to invert!
For the ESP32 Arduino, things were more difficult, I had no luck with GitHub code so wrote functions myself with the help of this reference.
It works. Currently set up only to read main BatteryVoltage and main BatteryCurrent, but other parameters would be easy to add.
And for inverting logic, if needed for Espduino (ESP32), same idea:
Serial1.begin(4800, SERIAL_8N1, 16, 17, 1); // note the "1" for inversion of logic