check in
Ongoing

RP2040_PV_Panel_Monitor

STDRP2040_PV_Panel_Monitor

tag

121
0
0
0
Mode:Full

License

CERN Open Hardware License

Creation time:2023-01-22 08:07:04Update time:2023-02-17 12:08:46

Description

# RP2040-based Photovoltaic Panel Monitor

# Safety Warning

This project deals with high DCs voltages. Make sure you understand what you are doing. Please read the safety warning below carefully.

 

# This PCB can monitor the volages and current of up to 8 PV cells with up to 50V each.

 

Please see https://github.com/GormR/PV_Supervisor for details.

 

CERN Open Hardware Licence Version 2 - Strongly Reciprocal

 

--------------------------------------------------------------------------------

 

#  Test code for PV Panel Monitor
#
#  copyright 2023 by Gorm Rose
#
#  This example code is licensed under GNU PL V3.0

# GP0: MuxSel1
# GP1: MuxSel0
# GP2: Temperature (DS18B20U)
# GP26: AIO0 voltage of "negative" PV modules
# GP27: AIO1 voltage of "positive" PV modules
# GP28: AIO2 common current
# Vref = external

from machine import Pin, I2C, ADC
#from ssd1306 import SSD1306_I2C
from time import sleep


#### µC pin definitions ####

MuxSel1 = Pin(0, Pin.OUT)                 # select1 for all multiplexers
MuxSel0 = Pin(1, Pin.OUT)                 # select0 (LSB) for all multiplexers
LED = Pin(3, Pin.OUT)                     # LED (high = on)
ADCn = ADC(26)
ADCp = ADC(27)
ADCc = ADC(28)


#### user constants ####
factor1 = 3 * (1 * 470 + 24) / (0x10000 * 24)  # 3 volt reference, 16 bit, divider 470/24
factor2 = 3 * (2 * 470 + 24) / (0x10000 * 24)  # 3 volt reference, 16 bit, divider 940/24
factor3 = 3 * (3 * 470 + 24) / (0x10000 * 24)  # ...
factor4 = 3 * (4 * 470 + 24) / (0x10000 * 24)
factor5 = 3 * 1000 * 2  / (0x10000 * (470 + 2))

#### variables ####

#    neg         _         pos
#     P1 P2 P3 P4 P5 P6 P7 P8
Vpv = [0, 0, 0, 0, 0, 0, 0, 0]
Ppv = [0, 0, 0, 0, 0, 0, 0, 0]
Ipv = 0

def set_mux(channel):
    if (channel & 2) == 0:
        MuxSel1.value(0)
    else:
        MuxSel1.value(1)
    if (channel & 1) == 0:
        MuxSel0.value(0)
    else:
        MuxSel0.value(1)
    

def read_value(channel, number_of_samples):
    global Vpv, Ppv, Ipv
    
    rawVoltNeg = 0
    rawVoltPos = 0
    rawCurrent = 0
    set_mux(channel)
    sleep(0.001)

    for i in range (0, number_of_samples):
        rawVoltNeg += ADCn.read_u16()
        rawVoltPos += ADCp.read_u16()
        rawCurrent += ADCc.read_u16()

    Ipv = factor5 * rawCurrent / number_of_samples
    if channel == 0:
        Vpv[0] = factor4 * (0x10000 - rawVoltNeg / number_of_samples) - Vpv[1] - 3
        Vpv[4] = factor1 * rawVoltPos / number_of_samples
        Ppv[0] = Ipv * Vpv[0]
        Ppv[4] = Ipv * Vpv[4]
    if channel == 1:
        Vpv[1] = factor3 * (0x10000 - rawVoltNeg / number_of_samples) - Vpv[2] - 3
        Vpv[5] = factor2 * rawVoltPos / number_of_samples
        Ppv[1] = Ipv * Vpv[1]
        Ppv[5] = Ipv * Vpv[5]
    if channel == 2:
        Vpv[2] = factor2 * (0x10000 - rawVoltNeg / number_of_samples) - Vpv[3] - 3
        Vpv[6] = factor3 * rawVoltPos / number_of_samples
        Ppv[2] = Ipv * Vpv[2]
        Ppv[6] = Ipv * Vpv[6]
    if channel == 3:
        Vpv[3] = factor1 * (0x10000 - rawVoltNeg / number_of_samples) - 3
        Vpv[7] = factor4 * rawVoltPos / number_of_samples
        Ppv[3] = Ipv * Vpv[3]
        Ppv[7] = Ipv * Vpv[7]
    

print("Hello Solar World!")

for i in range(0, 1000):
    for j in range(0, 4):
        read_value(j, 1000)
    print("voltages: ", Vpv)
    print("current:  ", Ipv)
    print("resulting power: ", Ppv)
    print()

 

Design Drawing

The preview image was not generated, please save it again in the editor.

BOM

Bom empty

Attachments

OrderFile nameDownload times
1
Test_PV_Panel_Monitor.py
0
Clone
Add to Album
0
0
Share
Report

Project Members

Comment

All Comments(1)
Sort by time|Sort by popularity
Followers0|Likes0
Related projects
Empty

Bottom Navigation