I think this could be an update application based on my previous application simple power meter.
In my previous application, I wanted to develop a measuring system to calculate the usage of electricity in average.
After some dicsussion with my friends, I would like to try to develop a whole system with solar system on controling and monitoring the plantation system.
For providing a better monitoring system with alert, I have used Blynk rather than Adafruit IO for the cloud platfrom.
Structure:
From the image above, the measuring method using MAX471 are the same as with my simple power meter application.
The main difference is the power souce has changed to solar panel and it IOT platform has used Blynk.
For my application, the solar panels are connected in parallel to enlarge the current value.
This is related to this readings of MAX471 still have a slight measuring error. Thus, it will showed some werid reuslt in low current values.
For the loads of the circuit, I had used 6 x 2K resistors in parallel to try to withdraw more currents from Soloar panel.
Step 1: Create codes to collect readings from MAX471From my previous project, I had made codes has the ability to read those readings and show it into an understandable words.
Those codes has been calibrated for one of the MAX471.
About the method, please refer to my previous project.
TestingCodes:
import board
import busio
import digitalio
import time
import MAX471
meter = MAX471.MAX471(voltage_pin = board.A0, current_pin = board.A1)
while True:
voltage = meter.Voltage()
print (("{} V").format(voltage))
current = meter.Current()
print (("{} mA").format(current))
power = meter.Power()
print(("{} W").format(power))
time.sleep (0.1)
These codes could easily calculate the current, voltage and power from the solar panel.
Step 2: How to communicate with Blynk Platform?For this section, it is a bit complicated comparing with previous IOT platform.
The difference are Blynk used TCP directly communicate with the platfrom that comes with specific Blynk tokens.
Secondly, it does not have specfic circuitpython library to work on WIZnet products.
However, I found a way to combine two libraries to make this happens.
From the help of ChatGPT and my knowledge of WIZnet's solution, I had found a way to work Blynk codes in my working environment.
The structure is like the following:
- Copy the Blynk class to the main file.
- Use the whole example for WIZnet's TCP client codes
- Create a module based on MAX471 class
- Collect the readings from the while loop
- Delivery the data to Blynk
Codes:
import board
import digitalio
import time
import busio
import struct
import BlynkLib
import MAX471
import adafruit_requests as requests
from adafruit_wiznet5k.adafruit_wiznet5k import * #active WIZnet chip library
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket #open socket from WIZnet library
BLYNK_TEMPLATE_ID = "aaaaaaa"
BLYNK_DEVICE_NAME = "bbbbbbbbbbb"
BLYNK_AUTH_TOKEN = "cccccccccccccccc"
# Activate GPIO pins for SPI communication
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17
# Activate Reset pin for communication with W5500 chip
W5x00_RSTn = board.GP20
# Create a module to read values from the solar pane
meter = MAX471.MAX471(voltage_pin = board.A0, current_pin = board.A1)
print("Wiznet5k SimpleServer Test (DHCP)")
class Blynk(BlynkLib.BlynkProtocol):
def __init__(self, auth, **kwargs):
self.insecure = kwargs.pop('insecure', True)
self.server = kwargs.pop('server', 'blynk.cloud')
self.port = kwargs.pop('port', 80 if self.insecure else 443)
BlynkLib.BlynkProtocol.__init__(self, auth, **kwargs)
#self.on('redirect', self.redirect)
def _write(self, data):
#print('<', data)
client.send(data)
# TODO: handle disconnect
def run(self):
data = b''
try:
data = client.recv()
#print('>', data)
except KeyboardInterrupt:
raise
#except socket.timeout:
# No data received, call process to send ping messages when needed
#pass
except: # TODO: handle disconnect
return
self.process(data)
# Setup your network configuration below
# random MAC, later should change this value on your vendor ID
MY_MAC = (0x00, 0x08, 0xDC, 0x11, 0x22, 0x33)
IP_ADDRESS = (192, 168, 0, 111)
SUBNET_MASK = (255, 255, 0, 0)
GATEWAY_ADDRESS = (192, 168, 0, 1)
DNS_SERVER = (8, 8, 8, 8)
# Set LED for checking the network system working
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
# Set reset function
ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT
# Set this SPI for selecting the correct chip
cs = digitalio.DigitalInOut(SPI0_CSn)
# Set the GPIO pins for SPI communication
spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)
# Reset WIZnet's chip first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True
# Initialize ethernet interface with DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=True, mac=MY_MAC, debug=False)
# Show all information
print("Chip Version:", eth.chip)
print("MAC Address:", [hex(i) for i in eth.mac_address])
print("My IP address is:", eth.pretty_ip(eth.ip_address))
# Initialize steps for WIZnet's socket to create TCP server
socket.set_interface(eth)
client = socket.socket() # Set and name the socket to be a TCP server
client_ip = "128.199.144.129" #bkynk.cloud
client_port = 80 # HTTP port for Blynk Port
client.connect((client_ip, client_port), None)
# register handler for virtual pin V5 write event
blynk = Blynk(BLYNK_AUTH_TOKEN)
while True:
# Maintain DHCP lease (continue the DHCP setting while TCP is connected)
eth.maintain_dhcp_lease()
led.value = not led.value #showing the light is blinking
time.sleep(0.1) #transmit data speed
#print (client.status)
if client.status == SNSR_SOCK_ESTABLISHED:
blynk.run()
#Collect reading and send to Blynk with virtual_write function
voltage = meter.Voltage()
blynk.virtual_write(0, voltage)
current = meter.Current()
blynk.virtual_write(1, current)
power = meter.Power()
blynk.virtual_write(2, power)
print (("{} V").format(voltage))
print (("{} mA").format(current))
print(("{} W").format(power))
time.sleep(1)
elif client.status == SNSR_SOCK_CLOSE_WAIT:
client.disconnect() #close the connection
elif client.status == SNSR_SOCK_CLOSED:
client.connect((client_ip, client_port), None)
Results from Blynk:
Solar Panel has a issue on providing a stable energy source to the sytem. The energy source will easily change weak when the sun light is not directly providing energy to the panel.
Thus, I think having an alert as a notification to my application is important.
For easily providing an alert to allow me to make adjustment manually, I had used Blynk's notification sytem - log_event.
It just required 1 line of coding to make this happen.
blynk.log_event("low_voltage")
After adding this code, Blynk will provide a notification to the cloud.
For details, please refer to this link.
Since Blynk has created his own mobile APP, I could easily to push a nofication to my phone to alert me the voltage for my panels has turn low.
After all the setup has been done, it showed a nofication as follow.
The procedure are not complicated. We could add different kinds of alert to allow us to easily notified the situation of our system.
Result:YouTube Video for my development.
Comments