Victron MPPT data using Arduino serial: Difference between revisions

From Sensors in Schools
Jump to navigation Jump to search
Line 744: Line 744:


= XBee - MPPT - Saving Data every Five Minutes =
= XBee - MPPT - Saving Data every Five Minutes =
* Set the statement '''if count > 300''' to save data every 5 minutes (300 seconds).


<syntaxhighlight lang="python">
            count += 1
            if count > 300:
                # Save data
                data = date_stamp + "," + V + "," + VPV + "," + PPV + "," + IL + "\n"
                print(f'DATA =  {data}')
                f = open('/home/pi/MPPT/MPPT_data.txt','a')
                f.write(data)
                f.close()
                print("Data saved")
                count = 0
</syntaxhighlight>
== Full code ==
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">


Line 789: Line 807:
              
              
             count += 1
             count += 1
             if count > 10:
             if count > 300:
                 # Save data
                 # Save data
                 data = date_stamp + "," + V + "," + VPV + "," + PPV + "," + IL + "\n"
                 data = date_stamp + "," + V + "," + VPV + "," + PPV + "," + IL + "\n"

Revision as of 10:24, 9 July 2023

Reading Victron MPPT Data

References

Parts Required

  • Victron BlueSolar MPPT 75/15 Retail SCC010015050R - $135 (Note that this unit is not Bluetooth enabled) [1]
  • JST Jumper 4 Wire Assembly - $2.75 [2]
  • Arduino Uno

Voltage considerations for different Victron hardware

  • Victron MPPT operates at 5V.
  • Arduino Uno also operates at 5V so no digital converter required.

VE.Direct Pinout

Serial Port Configuration - VE.Direct

Fritzing Circuit Diagram

Photos of Circuit


Arduino Code - Image

Serial Monitor - Example Output

Arduino Code - Code

/* Connections:
    MPPT pin     MPPT        Arduino     Arduino pin
    1            GND         GND         GND
    2            RX          TX          -              do not use!
    3            TX          RX          7 (UNO)
    4            Power+      none        -              do not use!
 */

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8); // RX, TX

String label, val;

void setup()  
{
  Serial.begin(9600);
  mySerial.begin(19200);
} 

void loop() 
{
  if (mySerial.available())
   {
        label = mySerial.readStringUntil('\t');      
        val = mySerial.readStringUntil('\r\r\n');
        Serial.println(label + val);
   } 
}

Arduino Code - Code - Reading Battery Voltage - V

/* Connections:
    MPPT pin     MPPT        Arduino     Arduino pin
    1            GND         GND         GND
    2            RX          TX          -              do not use!
    3            TX          RX          7 (UNO)
    4            Power+      none        -              do not use!
 */

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8); // RX, TX

String label, val;

void setup()  
{
  Serial.begin(9600);
  mySerial.begin(19200); // baud rate for MPPT
} 

void loop() 
{
  if (mySerial.available())
   {
        label = mySerial.readStringUntil('\t');      
        val = mySerial.readStringUntil('\r\r\n');
        // V = Battery voltage (mV)
        // VPV = Solar Panel voltage (mV)
        // PPV = Solar panel power (W)
        // I = Battery current (mA)
        // IL = Load Current (mA)
        if (label == "V"){
           Serial.println(label + val);
        }
   } 
}


Arduino Code - Code - Reading other Parameters from MPPT

/* Connections:
    MPPT pin     MPPT        Arduino     Arduino pin
    1            GND         GND         GND
    2            RX          TX          -              do not use!
    3            TX          RX          7 (UNO)
    4            Power+      none        -              do not use!
 */

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8); // RX, TX

String label, val;

void setup()  
{
  Serial.begin(9600);
  mySerial.begin(19200); // baud rate for MPPT
} 

void loop() 
{
  if (mySerial.available())
   {
        label = mySerial.readStringUntil('\t');      
        val = mySerial.readStringUntil('\r\r\n');
        // V = Battery voltage (mV)
        // VPV = Solar Panel voltage (mV)
        // PPV = Solar panel power (W)
        // I = Battery current (mA)
        // IL = Load Current (mA)
        if (label == "V"){
           Serial.println(label + val);  // Battery Voltage
        }
        
        if (label == "VPV"){
          Serial.println(label + val); // Solar Panel Voltage
        }

        if (label == "PPV"){
          Serial.println(label + val); // Solar Panel Power (Watts)
        }
   } 
}

XBee Test - with MPPT

  • Noticed that as soon as Software Serial added for MPPT communication is only one way from Arduino MPPT to XBee receiver for Pi.
/*****************************************************************
XBee_Serial_Passthrough.ino

Set up a software serial port to pass data between an XBee Shield
and the serial monitor.

Hardware Hookup:
  The XBee Shield makes all of the connections you'll need
  between Arduino and XBee. If you have the shield make
  sure the SWITCH IS IN THE "DLINE" POSITION. That will connect
  the XBee's DOUT and DIN pins to Arduino pins 2 and 3.

*****************************************************************/
// We'll use SoftwareSerial to communicate with the XBee:
#include <SoftwareSerial.h>

//For Atmega328P's
// XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX)
// XBee's DIN (RX) is connected to pin 3 (Arduino's Software TX)
SoftwareSerial XBee(2, 3); // RX, TX
SoftwareSerial mySerial(7, 8); // RX, TX

String label, val;

void setup()
{
  // Set up both ports at 9600 baud. This value is most important
  // for the XBee. Make sure the baud rate matches the config
  // setting of your XBee.
  XBee.begin(9600);
  mySerial.begin(19200); // baud rate for MPPT is 19200
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available())
  { // If data comes in from serial monitor, send it out to XBee
    XBee.write(Serial.read());
  }
  if (mySerial.available())
  { // If data comes in from serial monitor, send it out to XBee
    //XBee.write(mySerial.read());
     label = mySerial.readStringUntil('\t');      
     val = mySerial.readStringUntil('\r\r\n');
     if (label =="V"){
          XBee.write(55); // DEC 55 = HEX #37
     }
  }

  if (XBee.available())
  { // If data comes in from XBee, send it out to serial monitor
    Serial.write(XBee.read());
  }
}


XBee - MPPT Test to send Battery Voltage data using XBee

/*****************************************************************
XBee_Serial_Passthrough.ino

Set up a software serial port to pass data between an XBee Shield
and the serial monitor.

Hardware Hookup:
  The XBee Shield makes all of the connections you'll need
  between Arduino and XBee. If you have the shield make
  sure the SWITCH IS IN THE "DLINE" POSITION. That will connect
  the XBee's DOUT and DIN pins to Arduino pins 2 and 3.

*****************************************************************/
// We'll use SoftwareSerial to communicate with the XBee:
#include <SoftwareSerial.h>

//For Atmega328P's
// XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX)
// XBee's DIN (RX) is connected to pin 3 (Arduino's Software TX)
SoftwareSerial XBee(2, 3); // RX, TX
SoftwareSerial mySerial(7, 8); // RX, TX

String label, val;
char char_array[10]; // for data from MPPT to XBee

void setup()
{
  // Set up both ports at 9600 baud. This value is most important
  // for the XBee. Make sure the baud rate matches the config
  // setting of your XBee.
  XBee.begin(9600);
  mySerial.begin(19200); // baud rate for MPPT is 19200
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available())
  { // If data comes in from serial monitor, send it out to XBee
    XBee.write(Serial.read());
  }
  if (mySerial.available())
  { // If data comes in from serial monitor, send it out to XBee
    //XBee.write(mySerial.read());
     label = mySerial.readStringUntil('\t');      
     val = mySerial.readStringUntil('\r\r\n');
     if (label =="V"){
          //XBee.write(55); // DEC 55 = HEX #37
          int str_len = val.length() + 1; 
          val.toCharArray(char_array, str_len);
          XBee.write(char_array);
     }
  }

  if (XBee.available())
  { // If data comes in from XBee, send it out to serial monitor
    Serial.write(XBee.read());
  }
}

XBee XCTU Console output


XBee - MPPT Test to send All Data using XBee

/*****************************************************************
XBee_Serial_Passthrough.ino

Set up a software serial port to pass data between an XBee Shield
and the serial monitor.

Hardware Hookup:
  The XBee Shield makes all of the connections you'll need
  between Arduino and XBee. If you have the shield make
  sure the SWITCH IS IN THE "DLINE" POSITION. That will connect
  the XBee's DOUT and DIN pins to Arduino pins 2 and 3.

*****************************************************************/
// We'll use SoftwareSerial to communicate with the XBee:
#include <SoftwareSerial.h>

//For Atmega328P's
// XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX)
// XBee's DIN (RX) is connected to pin 3 (Arduino's Software TX)
SoftwareSerial XBee(2, 3); // RX, TX
SoftwareSerial mySerial(7, 8); // RX, TX

String label, val;
String V_data = "0";
String VPV_data = "0";
String PPV_data = "0";
String IL_data = "0";
String ALL_data = "";

char ALL_char_array[25];
        // V = Battery voltage (mV)
        // VPV = Solar Panel voltage (mV)
        // PPV = Solar panel power (W)
        // I = Battery current (mA)
        // IL = Load Current (mA)

void setup()
{
  // Set up both ports at 9600 baud. This value is most important
  // for the XBee. Make sure the baud rate matches the config
  // setting of your XBee.
  XBee.begin(9600);
  mySerial.begin(19200); // baud rate for MPPT is 19200
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available())
  { // If data comes in from serial monitor, send it out to XBee
    XBee.write(Serial.read());
  }
  if (mySerial.available())
  { // If data comes in from serial monitor, send it out to XBee
     label = mySerial.readStringUntil('\t');      
     val = mySerial.readStringUntil('\r\r\n');
     if (label =="V"){
          V_data = val;
     }
     
     if (label =="VPV"){
          VPV_data = val;
     }

     if (label =="PPV"){
          PPV_data = val;
     }

     if (label =="IL"){
          IL_data = val;
     }   
     

     if (label == "LOAD"){
          ALL_data = V_data + "," + VPV_data + "," + PPV_data + "," + IL_data;
          int str_len = ALL_data.length() + 1; 
          ALL_data.toCharArray(ALL_char_array, str_len);
          XBee.write(ALL_char_array);
     }
     
  }

  if (XBee.available())
  { // If data comes in from XBee, send it out to serial monitor
    Serial.write(XBee.read());
  }
}


XBee - MPPT Test to send All Data using XBee with End of Line

  • Data stored in Strings trimmed to remove white space
  • New line character added to end of String so that Python can determine end of transmission
  • During programming the XBee was plugged into Arduino.
  • XBee Explorere shield switch permanently on DLine (not UART)
/*****************************************************************
XBee_Serial_Passthrough.ino

Set up a software serial port to pass data between an XBee Shield
and the serial monitor.

Hardware Hookup:
  The XBee Shield makes all of the connections you'll need
  between Arduino and XBee. If you have the shield make
  sure the SWITCH IS IN THE "DLINE" POSITION. That will connect
  the XBee's DOUT and DIN pins to Arduino pins 2 and 3.

*****************************************************************/
// We'll use SoftwareSerial to communicate with the XBee:
#include <SoftwareSerial.h>

//For Atmega328P's
// XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX)
// XBee's DIN (RX) is connected to pin 3 (Arduino's Software TX)
SoftwareSerial XBee(2, 3); // RX, TX
SoftwareSerial mySerial(7, 8); // RX, TX

String label, val;
String V_data = "0";
String VPV_data = "0";
String PPV_data = "0";
String IL_data = "0";
String ALL_data = "";

char ALL_char_array[25];
        // V = Battery voltage (mV)
        // VPV = Solar Panel voltage (mV)
        // PPV = Solar panel power (W)
        // I = Battery current (mA)
        // IL = Load Current (mA)

void setup()
{
  // Set up both ports at 9600 baud. This value is most important
  // for the XBee. Make sure the baud rate matches the config
  // setting of your XBee.
  XBee.begin(9600);
  mySerial.begin(19200); // baud rate for MPPT is 19200
  //Serial.begin(9600);
}

void loop()
{
  if (Serial.available())
  { // If data comes in from serial monitor, send it out to XBee
    XBee.write(Serial.read());
  }
  if (mySerial.available())
  { // If data comes in from serial monitor, send it out to XBee
     label = mySerial.readStringUntil('\t');      
     val = mySerial.readStringUntil('\r\r\n');

     if (label =="V"){
          V_data = val;
          V_data.trim();
     }
     
     if (label =="VPV"){
          VPV_data = val;
          VPV_data.trim();
     }

     if (label =="PPV"){
          PPV_data = val;
          PPV_data.trim();
     }

     if (label =="IL"){
          IL_data = val;
          IL_data.trim();
     }   
     

     if (label == "LOAD"){
          ALL_data = V_data + "," + VPV_data + "," + PPV_data + "," + IL_data + "\n";
          int str_len = ALL_data.length() + 1; 
          ALL_data.toCharArray(ALL_char_array, str_len);
          XBee.write(ALL_char_array);
          //Serial.println(ALL_data);
     }
     
  }

  if (XBee.available())
  { // If data comes in from XBee, send it out to serial monitor
    Serial.write(XBee.read());
  }
}

XBee - MPPT Test - Printing data to the Arduino IDE Serial Monitor

  • Serial monitor uses pins 0 and 1


/*****************************************************************
XBee_Serial_Passthrough.ino

Set up a software serial port to pass data between an XBee Shield
and the serial monitor.

Hardware Hookup:
  The XBee Shield makes all of the connections you'll need
  between Arduino and XBee. If you have the shield make
  sure the SWITCH IS IN THE "DLINE" POSITION. That will connect
  the XBee's DOUT and DIN pins to Arduino pins 2 and 3.

*****************************************************************/
// We'll use SoftwareSerial to communicate with the XBee:
#include <SoftwareSerial.h>

//For Atmega328P's
// XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX)
// XBee's DIN (RX) is connected to pin 3 (Arduino's Software TX)
SoftwareSerial XBee(2, 3); // RX, TX
SoftwareSerial mySerial(7, 8); // RX, TX

String label, val;
String V_data = "0";
String VPV_data = "0";
String PPV_data = "0";
String IL_data = "0";
String ALL_data = "";

char ALL_char_array[25];
        // V = Battery voltage (mV)
        // VPV = Solar Panel voltage (mV)
        // PPV = Solar panel power (W)
        // I = Battery current (mA)
        // IL = Load Current (mA)

void setup()
{
  // Set up both ports at 9600 baud. This value is most important
  // for the XBee. Make sure the baud rate matches the config
  // setting of your XBee.
  XBee.begin(9600);
  mySerial.begin(19200); // baud rate for MPPT is 19200
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available())
  { // If data comes in from serial monitor, send it out to XBee
    XBee.write(Serial.read());
  }
  if (mySerial.available())
  { // If data comes in from serial monitor, send it out to XBee
     label = mySerial.readStringUntil('\t');      
     val = mySerial.readStringUntil('\r\r\n');

     if (label =="V"){
          V_data = val;
          V_data.trim();
     }
     
     if (label =="VPV"){
          VPV_data = val;
          VPV_data.trim();
     }

     if (label =="PPV"){
          PPV_data = val;
          PPV_data.trim();
     }

     if (label =="IL"){
          IL_data = val;
          IL_data.trim();
     }   
     

     if (label == "LOAD"){
          ALL_data = V_data + "," + VPV_data + "," + PPV_data + "," + IL_data + "\n";
          int str_len = ALL_data.length() + 1; 
          ALL_data.toCharArray(ALL_char_array, str_len);
          XBee.write(ALL_char_array);
          Serial.println(ALL_data);
     }
  }

  if (XBee.available())
  { // If data comes in from XBee, send it out to serial monitor
    Serial.write(XBee.read());
  }
}


XBee - MPPT Test - Python code

#!/usr/bin/env python3
import serial
import time


if __name__ == '__main__':
    ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
    ser.reset_input_buffer()
    count = 0

    while True:
        if ser.in_waiting > 0:
            print(count)
            time.sleep(0.1)
            try: 
                #line = ser.readline()
                line = ser.readline().decode('utf-8').rstrip()
                print(line)
            except:
                print("fail")
            count += 1


XBee - MPPT - Separating incoming data into separate variables

  • Incoming data separated into separate variable.
    • V = Battery voltage (mV)
    • VPV = Solar Panel voltage (mV)
    • PPV = Solar panel power (W)
    • IL = Load Current (mA)


#!/usr   /bin/env python3
import serial
import time


if __name__ == '__main__':
    ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
    ser.reset_input_buffer()
    count = 0

    while True:
        if ser.in_waiting > 0:
            #print(count)
            time.sleep(0.1)
            try: 
                #line = ser.readline()
                line = ser.readline().decode('utf-8').rstrip()

                print(f"Data separated using commas {line.split(',')}")
                mylist = line.split(',')
                #print(f'My List {mylist}')

                V = mylist[0]  ## Battery Voltage (nV)
                VPV = mylist[1] ## Solar Panel Voltage (mV)
                PPV = mylist[2] ## Solar Panel Power (W)
                IL = mylist[3] ## Load Current (mA)

                print(f'Battery voltage {V}, Solar Panel voltage {VPV}')
                print(f'Solar Panel power {PPV}, Load current {IL}')
            except:
                V = "0"
                VPV = "0"
                PPV = "0"
                IL = "0"
                print("Read serial fail")
            #count += 1

XBee - MPPT - Add Datetime Stamp

  • Add DateTime stamp
  • import datetime required.
#!/usr   /bin/env python3
import serial
import time
import datetime


if __name__ == '__main__':
    ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
    ser.reset_input_buffer()
    count = 0

    while True:
        if ser.in_waiting > 0:
            #print(count)
            time.sleep(0.1)
            print()
            now = datetime.datetime.now()
            date_stamp = now.strftime("%Y-%m-%d %H:%M:%S")
            print(f'The current date and time is {date_stamp}')
            
            try: 
                line = ser.readline().decode('utf-8').rstrip()

                print(f"Data separated using commas {line.split(',')}")
                mylist = line.split(',')
                #print(f'My List {mylist}')

                V = mylist[0]  ## Battery Voltage (nV)
                VPV = mylist[1] ## Solar Panel Voltage (mV)
                PPV = mylist[2] ## Solar Panel Power (W)
                IL = mylist[3] ## Load Current (mA)

                print(f'Battery voltage {V}, Solar Panel voltage {VPV}')
                print(f'Solar Panel power {PPV}, Load current {IL}')
            except:
                V = "0"
                VPV = "0"
                PPV = "0"
                IL = "0"
                print("Read serial fail")
            
            #count += 1

XBee - MPPT - Saving Data every Five Minutes

  • Set the statement if count > 300 to save data every 5 minutes (300 seconds).
            count += 1
            if count > 300:
                # Save data
                data = date_stamp + "," + V + "," + VPV + "," + PPV + "," + IL + "\n"
                print(f'DATA =  {data}')
                f = open('/home/pi/MPPT/MPPT_data.txt','a')
                f.write(data)
                f.close()
                print("Data saved")
                count = 0


Full code

#!/usr   /bin/env python3
import serial
import time
import datetime


if __name__ == '__main__':
    ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
    ser.reset_input_buffer()
    count = 0

    while True:
        if ser.in_waiting > 0:
            #print(count)
            time.sleep(0.1)
            print()
            now = datetime.datetime.now()
            date_stamp = now.strftime("%Y-%m-%d %H:%M:%S")
            print(f'The current date and time is {date_stamp}')
            
            try: 
                line = ser.readline().decode('utf-8').rstrip()

                print(f"Data separated using commas {line.split(',')}")
                mylist = line.split(',')
                #print(f'My List {mylist}')

                V = mylist[0]  ## Battery Voltage (nV)
                VPV = mylist[1] ## Solar Panel Voltage (mV)
                PPV = mylist[2] ## Solar Panel Power (W)
                IL = mylist[3] ## Load Current (mA)

                print(f'Battery voltage {V}, Solar Panel voltage {VPV}')
                print(f'Solar Panel power {PPV}, Load current {IL}')
            except:
                V = "0"
                VPV = "0"
                PPV = "0"
                IL = "0"
                print("Read serial fail")
            
            count += 1
            if count > 300:
                # Save data
                data = date_stamp + "," + V + "," + VPV + "," + PPV + "," + IL + "\n"
                print(f'DATA =  {data}')
                f = open('/home/pi/MPPT/MPPT_data.txt','a')
                f.write(data)
                f.close()
                print("Data saved")
                count = 0