Wednesday, June 14, 2023

Settiing up power monitor tool for Miniature Solar Power System



Prerequisites 


Information about Current Monitor HAT

See the link below for more details about Current/Power Monitor HAT

https://www.waveshare.com/wiki/Current/Power_Monitor_HAT


Setting up Raspberry Pi

Install python3 if it is not installed. There will be a lot of resources available on the Internet.


Demo Code from Waveshare

https://www.waveshare.com/w/upload/6/69/Current-Power_Monitor_HAT_Code.7z (see link in the Information about Current Monitor HAT section if this link not working)

Download the demo code to Raspberry Pi and extract 7z file to a folder.

Change the directory to the RaspberyPi folder in the extracted folder.

Execute Demo code as follows and then you can see the power reading as follows.


If you can see above with proper reading. your hardware setup is ready.

This demo code is logging reading to on-screen only. I did a small modification to the above to write logs into a text file (tab-delimited fields)

Copy ina219.py to your preferred folder. My folder name is esps

See the changed code below.


Now you are good to go live and it will create one text file per day.


Run the modified code from your new folder.


Files will be generated as follows.




Example file



Full Python code is as follows.


import datetime
import os
import smbus
import time

# Config Register (R/W)
_REG_CONFIG                 = 0x00
# SHUNT VOLTAGE REGISTER (R)
_REG_SHUNTVOLTAGE           = 0x01

# BUS VOLTAGE REGISTER (R)
_REG_BUSVOLTAGE             = 0x02

# POWER REGISTER (R)
_REG_POWER                  = 0x03

# CURRENT REGISTER (R)
_REG_CURRENT                = 0x04

# CALIBRATION REGISTER (R/W)
_REG_CALIBRATION            = 0x05

class BusVoltageRange:
    """Constants for ``bus_voltage_range``"""
    RANGE_16V               = 0x00      # set bus voltage range to 16V
    RANGE_32V               = 0x01      # set bus voltage range to 32V (default)

class Gain:
    """Constants for ``gain``"""
    DIV_1_40MV              = 0x00      # shunt prog. gain set to  1, 40 mV range
    DIV_2_80MV              = 0x01      # shunt prog. gain set to /2, 80 mV range
    DIV_4_160MV             = 0x02      # shunt prog. gain set to /4, 160 mV range
    DIV_8_320MV             = 0x03      # shunt prog. gain set to /8, 320 mV range

class ADCResolution:
    """Constants for ``bus_adc_resolution`` or ``shunt_adc_resolution``"""
    ADCRES_9BIT_1S          = 0x00      #  9bit,   1 sample,     84us
    ADCRES_10BIT_1S         = 0x01      # 10bit,   1 sample,    148us
    ADCRES_11BIT_1S         = 0x02      # 11 bit,  1 sample,    276us
    ADCRES_12BIT_1S         = 0x03      # 12 bit,  1 sample,    532us
    ADCRES_12BIT_2S         = 0x09      # 12 bit,  2 samples,  1.06ms
    ADCRES_12BIT_4S         = 0x0A      # 12 bit,  4 samples,  2.13ms
    ADCRES_12BIT_8S         = 0x0B      # 12bit,   8 samples,  4.26ms
    ADCRES_12BIT_16S        = 0x0C      # 12bit,  16 samples,  8.51ms
    ADCRES_12BIT_32S        = 0x0D      # 12bit,  32 samples, 17.02ms
    ADCRES_12BIT_64S        = 0x0E      # 12bit,  64 samples, 34.05ms
    ADCRES_12BIT_128S       = 0x0F      # 12bit, 128 samples, 68.10ms

class Mode:
    """Constants for ``mode``"""
    POWERDOW                = 0x00      # power down
    SVOLT_TRIGGERED         = 0x01      # shunt voltage triggered
    BVOLT_TRIGGERED         = 0x02      # bus voltage triggered
    SANDBVOLT_TRIGGERED     = 0x03      # shunt and bus voltage triggered
    ADCOFF                  = 0x04      # ADC off
    SVOLT_CONTINUOUS        = 0x05      # shunt voltage continuous
    BVOLT_CONTINUOUS        = 0x06      # bus voltage continuous
    SANDBVOLT_CONTINUOUS    = 0x07      # shunt and bus voltage continuous


class INA219:
    def __init__(self, i2c_bus=1, addr=0x40):
        self.bus = smbus.SMBus(i2c_bus);
        self.addr = addr

        # Set chip to known config values to start
        self._cal_value = 0
        self._current_lsb = 0
        self._power_lsb = 0
        self.set_calibration_32V_2A()

    def read(self,address):
        data = self.bus.read_i2c_block_data(self.addr, address, 2)
        return ((data[0] * 256 ) + data[1])

    def write(self,address,data):
        temp = [0,0]
        temp[1] = data & 0xFF
        temp[0] =(data & 0xFF00) >> 8
        self.bus.write_i2c_block_data(self.addr,address,temp)

    def set_calibration_32V_2A(self):
        """Configures to INA219 to be able to measure up to 32V and 2A of current. Counter
           overflow occurs at 3.2A.
           ..note :: These calculations assume a 0.1 shunt ohm resistor is present
        """
        # By default we use a pretty huge range for the input voltage,
        # which probably isn't the most appropriate choice for system
        # that don't use a lot of power.  But all of the calculations
        # are shown below if you want to change the settings.  You will
        # also need to change any relevant register settings, such as
        # setting the VBUS_MAX to 16V instead of 32V, etc.

        # VBUS_MAX = 32V             (Assumes 32V, can also be set to 16V)
        # VSHUNT_MAX = 0.32          (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)
        # RSHUNT = 0.1               (Resistor value in ohms)

        # 1. Determine max possible current
        # MaxPossible_I = VSHUNT_MAX / RSHUNT
        # MaxPossible_I = 3.2A

        # 2. Determine max expected current
        # MaxExpected_I = 2.0A

        # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
        # MinimumLSB = MaxExpected_I/32767
        # MinimumLSB = 0.000061              (61uA per bit)
        # MaximumLSB = MaxExpected_I/4096
        # MaximumLSB = 0,000488              (488uA per bit)

        # 4. Choose an LSB between the min and max values
        #    (Preferrably a roundish number close to MinLSB)
        # CurrentLSB = 0.0001 (100uA per bit)
        self._current_lsb = .1  # Current LSB = 100uA per bit

        # 5. Compute the calibration register
        # Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
        # Cal = 4096 (0x1000)

        self._cal_value = 4096

        # 6. Calculate the power LSB
        # PowerLSB = 20 * CurrentLSB
        # PowerLSB = 0.002 (2mW per bit)
        self._power_lsb = .002  # Power LSB = 2mW per bit

        # 7. Compute the maximum current and shunt voltage values before overflow
        #
        # Max_Current = Current_LSB * 32767
        # Max_Current = 3.2767A before overflow
        #
        # If Max_Current > Max_Possible_I then
        #    Max_Current_Before_Overflow = MaxPossible_I
        # Else
        #    Max_Current_Before_Overflow = Max_Current
        # End If
        #
        # Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
        # Max_ShuntVoltage = 0.32V
        #
        # If Max_ShuntVoltage >= VSHUNT_MAX
        #    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
        # Else
        #    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
        # End If

        # 8. Compute the Maximum Power
        # MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
        # MaximumPower = 3.2 * 32V
        # MaximumPower = 102.4W

        # Set Calibration register to 'Cal' calculated above
        self.write(_REG_CALIBRATION,self._cal_value)

        # Set Config register to take into account the settings above
        self.bus_voltage_range = BusVoltageRange.RANGE_32V
        self.gain = Gain.DIV_8_320MV
        self.bus_adc_resolution = ADCResolution.ADCRES_12BIT_32S
        self.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_32S
        self.mode = Mode.SANDBVOLT_CONTINUOUS
        self.config = self.bus_voltage_range << 13 | \
                      self.gain << 11 | \
                      self.bus_adc_resolution << 7 | \
                      self.shunt_adc_resolution << 3 | \
                      self.mode
        self.write(_REG_CONFIG,self.config)
       
    def getShuntVoltage_mV(self):
        self.write(_REG_CALIBRATION,self._cal_value)
        value = self.read(_REG_SHUNTVOLTAGE)
        if value > 32767:
            value -= 65535
        return value * 0.01
       
    def getBusVoltage_V(self):  
        self.write(_REG_CALIBRATION,self._cal_value)
        self.read(_REG_BUSVOLTAGE)
        return (self.read(_REG_BUSVOLTAGE) >> 3) * 0.004
       
    def getCurrent_mA(self):
        value = self.read(_REG_CURRENT)
        if value > 32767:
            value -= 65535
        return value * self._current_lsb
       
    def getPower_W(self):
        value = self.read(_REG_POWER)
        if value > 32767:
            value -= 65535
        return value * self._power_lsb    
   
    def append_lines_solar_gen_log(self, line):
        file_name = "solar_gen_{0}.log".format(datetime.datetime.now().strftime("%d_%m_%Y"))
        if os.path.isfile(file_name):
            with open(file_name, 'a') as file:
                file.write(line + '\n')
        else:
            with open(file_name, 'w') as file:
                file.write("Date_Time\tPSU_Voltage_V\tShunt_Voltage\tLoad_Voltage\tPower_W\tCurrent_A\n")
                file.write(line + '\n')
     
if __name__=='__main__':

    ina1 = INA219(addr=0x40)
    # ina2 = INA219(addr=0x41)
    # ina3 = INA219(addr=0x42)
    # ina4 = INA219(addr=0x43)
   
    while True:
        now = datetime.datetime.now()
       
        bus_voltage1 = ina1.getBusVoltage_V()             # voltage on V- (load side)
        shunt_voltage1 = ina1.getShuntVoltage_mV() / 1000 # voltage between V+ and V- across the shunt
        current1 = ina1.getCurrent_mA()                   # current in mA
        power1 = ina1.getPower_W()                        # power in watts

        # bus_voltage2 = ina2.getBusVoltage_V()             # voltage on V- (load side)
        # shunt_voltage2 = ina2.getShuntVoltage_mV() / 1000 # voltage between V+ and V- across the shunt
        # current2 = ina2.getCurrent_mA()                   # current in mA
        # power2 = ina2.getPower_W()                        # power in watts

        # bus_voltage3 = ina3.getBusVoltage_V()             # voltage on V- (load side)
        # shunt_voltage3 = ina3.getShuntVoltage_mV() / 1000 # voltage between V+ and V- across the shunt
        # current3 = ina3.getCurrent_mA()                   # current in mA
        # power3 = ina3.getPower_W()                        # power in watts

        # bus_voltage4 = ina4.getBusVoltage_V()             # voltage on V- (load side)
        # shunt_voltage4 = ina4.getShuntVoltage_mV() / 1000 # voltage between V+ and V- across the shunt
        # current4 = ina4.getCurrent_mA()                   # current in mA
        # power4 = ina4.getPower_W()                        # power in watts
       
        # INA219 measure bus voltage on the load side. So PSU voltage = bus_voltage + shunt_voltage
        # print("PSU Voltage:{:6.3f}V    Shunt Voltage:{:9.6f}V    Load Voltage:{:6.3f}V    Power:{:9.6f}W    Current:{:9.6f}A".format((bus_voltage1 + shunt_voltage1),(shunt_voltage1),(bus_voltage1),(power1),(current1/1000)))
        # print("PSU Voltage:{:6.3f}V    Shunt Voltage:{:9.6f}V    Load Voltage:{:6.3f}V    Power:{:9.6f}W    Current:{:9.6f}A".format((bus_voltage2 + shunt_voltage2),(shunt_voltage2),(bus_voltage2),(power2),(current2/1000)))
        # print("PSU Voltage:{:6.3f}V    Shunt Voltage:{:9.6f}V    Load Voltage:{:6.3f}V    Power:{:9.6f}W    Current:{:9.6f}A".format((bus_voltage3 + shunt_voltage3),(shunt_voltage3),(bus_voltage3),(power3),(current3/1000)))
        # print("PSU Voltage:{:6.3f}V    Shunt Voltage:{:9.6f}V    Load Voltage:{:6.3f}V    Power:{:9.6f}W    Current:{:9.6f}A".format((bus_voltage4 + shunt_voltage4),(shunt_voltage4),(bus_voltage4),(power4),(current3/1000)))
        print("")

        log_hader = "Date_Time\tPSU_Voltage_V\tShunt_Voltage\tLoad_Voltage\tPower_W\tCurrent_A"
        log_entry =  "{:}\t{:6.3f}\t{:9.6f}\t{:6.3f}\t{:9.6f}\t{:9.6f}".format(now.strftime("%d/%m/%Y %H:%M:%S"), (bus_voltage1 + shunt_voltage1),(shunt_voltage1),(bus_voltage1),(power1),(current1/1000))
        ina1.append_lines_solar_gen_log(log_entry)

        print("PSU Voltage:{:6.3f}V    Shunt Voltage:{:9.6f}V    Load Voltage:{:6.3f}V    Power:{:9.6f}W    Current:{:9.6f}A".format((bus_voltage1 + shunt_voltage1),(shunt_voltage1),(bus_voltage1),(power1),(current1/1000)))
       
        time.sleep(30)












Friday, June 9, 2023

Solar Simulater and Data Logger - 09/06/2023

 

09/06/2023





Solar Simulater and Data Logger - 08/06/2023

 Solar Panel Simulator and Data Collector



Friday, October 12, 2018

Monday, October 12, 2009

How to identify your SQL Server version and edition

Execute following on SQL Server Management studio.

SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')

Friday, September 25, 2009

Shrinking the Transaction Log in SQL Server

Shrinking the Transaction Log in SQL Server 2000 / 2005 with DBCC SHRINKFILE

SQL Server 2000

1.

Run this code:

DBCC SHRINKFILE(pubs_log, 2)

NOTE: If the target size is not reached, proceed to the next step.

2.

Run this code if you want to truncate the transaction log and not keep a backup of the transaction log. Truncate_only invalidates your transaction log backup sequence. Take a full backup of your database after you perform backup log with truncate_only:

BACKUP LOG pubs WITH TRUNCATE_ONLY

-or-

Run this code if you want to keep a backup of your transaction log and keep your transaction log backup sequence intact. See SQL Server Books Online topic "BACKUP" for more information:

BACKUP LOG pubs TO pubslogbackup

3.

Run this code:

DBCC SHRINKFILE(pubs_log,2)

The transaction log has now been shrunk to the target size.


Source : http://support.microsoft.com/kb/907511/en-us

SQL Server 2005

  1. Back up the transaction log file to make most of the active virtual log files inactive. Therefore, the inactive virtual log files can be removed in a later step. To do this, run a Transact-SQL statement that is similar to the following Transact-SQL statement.

BACKUP LOG TO DISK = ''

Note In this statement, is a placeholder for the name of the database that you are backing up. In this statement, is a placeholder for the full path of the backup file.
For example, run the following Transact-SQL statement.

BACKUP LOG TestDB TO DISK='C:\TestDB1.bak'

2. Shrink the transaction log file. To do this, run a Transact-SQL statement that is similar to the following Transact-SQL statement.

DBCC SHRINKFILE (, ) WITH NO_INFOMSGS

Note In this statement, is a placeholder for the name of the transaction log file. In this statement, is a placeholder for the target size that you want the transaction log file to be. The target size must be reasonable. For example, you cannot shrink the transaction log file to a size that is less than 2 virtual log files.

3. If the DBCC SHRINKFILE statement does not shrink the transaction log file to the target size, run the BACKUP LOG statement that is mentioned in step 1 to make more of the virtual log files inactive.

4. Run the DBCC SHRINKFILE statement that is mentioned in step 2. After this operation, the transaction log file should be similar to the target size.

Source : http://support.microsoft.com/kb/907511/en-us

Wednesday, June 17, 2009

Running IIS and SQL server in same machine with diferent IP and Same Port

Introduction
In this artical I will explain how to configure IIS and SQL server 2005 in same maching diferent IP and same port.

IIS web site need to start on 
IP : 192.168.10.105  Port : 6666

SQL server need to start on
IP : 192.168.10.28 Port : 6666


Configuring Net work Connection
First we need to assign 2 ip addresses to the NIC. Go to Network connections TCP/IP properties and configure as follows.









Configuring IIS

Go to Web site properties from IIS manager and change settings as follows.




















Then use HttpCfg.exe to configure IIS lisning IPs. In windows 2003 this tool can be found SUPPORT\ folder on installation CD. for more informantion click here

type floowing commands in command prompt. By default httpcfg.exe winn install on "c:\program files\Support tools\"

By default iis will listen for all ips configured to machine. using following command will delete entry for all ip listening. 

httpcfg delete iplisten -i 0.0.0.0

Then add the IP we need to listen using following command

httpcfg set iplisten -i 192.168.10.105

then restart the IIS / Web site from IIS manager.

you can user netstat (netstat -an -p tcp) command to see how the ports are listening.


Configuring SQL Server 2005

Go to Sql Server Configuration Manager. and select correct Sql server instance and double click on TCP/IP appear in right pan.









Then change the settins as follows.












After changes are done re start SQL server.

Again you can user netstat (netstat -an -p tcp) command to see how the ports are listening.

netstat will display as follows.




Monday, January 5, 2009

Model Popup (Ajax Control Toolkit) and ASP.MVC




Model popup is another usefull tool in web applications. Therefore I thought to create easy way to include Model popup in ASP.NET MVC Projects as Stephen Walther (ASP.NET MVC Tip #36 – Create a Popup Calendar Helper) did for Calender Control. 



Added Following Class ModelPopupExtensions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace AjaxControlToolkitMvc
{
public static class ModelPopupExtensions
{
public static string ModelPopup(this AjaxHelper helper,
string BackgroundCssClass,
string CancelControlID,
string DropShadow,
string OkControlID,
string OnOkScript,
string PopupControlID,
string PopupDragHandleControlID,
string dynamicServicePath,
string id,
string elementId)
{
var sb = new StringBuilder();

// Add Microsoft Ajax library
sb.AppendLine(helper.MicrosoftAjaxLibraryInclude());

// Add toolkit scripts
sb.AppendLine(helper.ToolkitInclude
(
"AjaxControlToolkit.ExtenderBase.BaseScripts.js",
"AjaxControlToolkit.Common.Common.js",
"AjaxControlToolkit.DynamicPopulate.DynamicPopulateBehavior.js",
"AjaxControlToolkit.RoundedCorners.RoundedCornersBehavior.js",
"AjaxControlToolkit.Compat.Timer.Timer.js",
"AjaxControlToolkit.DropShadow.DropShadowBehavior.js",
"AjaxControlToolkit.Compat.DragDrop.DragDropScripts.js",
"AjaxControlToolkit.DragPanel.FloatingBehavior.js",
"AjaxControlToolkit.ModalPopup.ModalPopupBehavior.js"
));

// Perform $create
string properties = "";
properties = string.Format(@"""BackgroundCssClass"": ""{0}"", ""CancelControlID"": ""{1}"", ""DropShadow"": {2}, ""OkControlID"": ""{3}"", ""OnOkScript"": ""{4}"", ""PopupControlID"": ""{5}"", ""PopupDragHandleControlID"": ""{6}"", ""dynamicServicePath"": ""{7}"", ""id"": ""{8}""",
BackgroundCssClass, CancelControlID, DropShadow, OkControlID, OnOkScript, PopupControlID, PopupDragHandleControlID, dynamicServicePath, id);
properties = "{ " + properties + " }";
sb.AppendLine(helper.Create("AjaxControlToolkit.ModalPopupBehavior", properties, elementId));

return sb.ToString();
}
}
}

Added New overloaded method to the AjaxExtensions class. This method takes an extra parameter for properties.
1
2
3
4
5
6
7
8
9
10
        public static string Create(this AjaxHelper helper, string clientType, string properties, string elementId)
{
var sb = new StringBuilder();
sb.AppendLine("<script type='text/javascript'>");
sb.AppendLine("Sys.Application.add_init(function(){");
sb.AppendFormat(@"$create({0}, {1},null,null,$get('{2}'))", clientType, properties, elementId);
sb.AppendLine("});");
sb.AppendLine("</script>");
return sb.ToString();
}





Wednesday, December 24, 2008

Microsoft ASP.NET MVC Frame Work And LINQ to Entity

I have started to learn Microsoft ASP.NET MVC framework and LINQ to entity. I thought to create working example with above. 

I am not going to explain what ASP.NET MVS is and What LINQ To Entities are, But I will explain how I have do a order form with using those two.

You can refere following urls to find out more on ASP.NET MVC and LINQ to SQL.






This example will show how to create a Order form with ASP.NET MVC and Linq To Entity.

1.  Starting Fresh ASP.NET MVC Project.

1. You need to install ASP.NET MVC Framework (Beta).  http://www.asp.net/mvc
    Create a MVC Project by Selecting "ASP.NET MVC Web Application"


Solution Explorer will look like as follows.

The freash MVC project will have pages to login, change password etc. 

2.  Database Design



Table Name                                   Description
------------                                    -----------------------------------------
Item Item Master Table
Customer Customer Master Table
Order Order Header Table
OrderDetail Order Detail Table
Tempdata This table will use to save orders temporary until finished adding new Items. Because order can have maney Items.

3.  Creating Business Layer (dll) with LINQ to Entity

Add  a new Project (Type Class Library)  names "LM.Core". In this project will handle business layer functionalities.


Solution explorer after adding "LM.Core" Project.

In "LM.Core" there will be a Class called "Class1" (Class1.cs). Delete "Class1.cs" from "LM.Core", we can add necessory classes later as required.



No we can add ADO.NET Entity Model. Right click on "LM.Core" Add-> New Item.
Item name will be LMModel.



A wizard will begin just after click "Add" Button. Wizard steps will be as follows.

Step 1



Step 2 - Choose Data Connection




Step 3 - Select Tables



Solution Explorer after adding Entity Model to "LM.Core" Project.



LMModel.edmx will show following diagram.

We can extend the Linq to entity classes to add our own methods as follows.

Extending Item Class

Add a new class to LM.Core named Item (Item.cs). I have added twi new methods "GetItem()" and "GetByID()"



Customer, Order, OrderDetail and TempData classes need to be extended as required.


4.  Create Order Form

Order Form UI need to be created on Application project. According to ASP.NET MVC framework we need to add Controller and views for the order.

Add new Item named OrderController to the Controllers Folder located in application project.



and also add another class called BaseController to the Controller folder.

BaseController is inherited from "System.Web.Mvc.Controller"



Originally OrderController class wil inherited from "System.Web.Mvc.Controller", change it to "BaseController" (which we created).




Sorry .........., Still Updating ........................
Even though I am still updating this blog,  you can help me to improve the quality of this blog by providing your valuble comments.