If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

python coding for voltage relays

Mon Jul 19, 2021 4:51 pm

hi all, first time posting and know nothing about coding python.
im trying to set a dockerpi relay to switch on/off in a voltage range given by the adc.
so far i have the adc running but cant get my head round the relay side...

Code: Select all

1 #!/usr/bin/env python
2 import time
3 import smbus
4 import sys
5 DEVICE_BUS = 1
6 DEVICE_ADDR = 0x11
7 bus = smbus.SMBus(DEVICE_BUS)
8
9 from ads1015 import ADS1015
10
11 CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref']
12 
13 ads1015 = ADS1015()
14 ads1015.set_mode('single')
15 ads1015.set_programmable_gain(2.048)
16 ads1015.set_sample_rate(1600)
17
18 reference = ads1015.get_reference_voltage()
19
20 print("Reference voltage: {:6.3f}v \n".format(reference))
21
22 try:
23     while True:

24         for channel in CHANNELS:
25             value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)

26             print("{}: {:6.3f}v".format(channel, value))
27 
28         print("")
29         time.sleep(1.0)
30
31     while True:

32             value = ads1015.get_compensated_voltage(channel='in1/ref', reference_voltage=reference)

33         for "value" = range: (13.300 - 16.300v)
34             bus.write_byte_data(DEVICE_ADDR, 1, 0xFF)
35         
36 except KeyboardInterrupt:
37            bus.write_byte_data(DEVICE_ADDR, 1, 0x00) 
38 
39

can anyone show me how to get this running?
thankyou...

[Moderator added code tags]
Last edited by If_i_only_knew101 on Tue Jul 20, 2021 12:31 pm, edited 1 time in total.

pcmanbob
Posts: 11383
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python coding for voltage relays

Tue Jul 20, 2021 11:09 am

Hi.

So first off when posting code you need to use code tags to preserve the indentation that python relies on.

viewtopic.php?f=32&t=84477

As you have not provided a link to thedockerpi relay you are using ,

and you have not said what you have tired or what you don't understand all I can offer is a link to the DockerPi 4 Channel Relay wiki page

assuming this is the correct relay board

https://wiki.52pi.com/index.php/DockerP ... erry_Pi.29

and direct you to sections 11 & 14
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Wed Jul 21, 2021 5:40 pm

hi sorry very new and first post ever.
python code will read voltages and display on the 3 channels,

Code: Select all

#!/usr/bin/env python
import time
import smbus
import sys
DEVICE_BUS = 1
DEVICE_ADDR = 0x11
bus = smbus.SMBus(DEVICE_BUS)

from ads1015 import ADS1015

CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref']

ads1015 = ADS1015()
ads1015.set_mode('single')
ads1015.set_programmable_gain(2.048)
ads1015.set_sample_rate(1600)

reference = ads1015.get_reference_voltage()

print("Reference voltage: {:6.3f}v \n".format(reference))

try:
    while True:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)
            print("{}: {:6.3f}v".format(channel, value))

        print("")
        time.sleep(1.0)

    while True:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel='in1/ref', reference_voltage=reference)
            "value" = range (13.500 - 16.300)
            bus.write_byte_data(DEVICE_ADDR, 1, 0xFF)
        
    while False:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel='in1/ref', reference_voltage=reference)    
        for value range: <(13.499)
            bus.write_byte_data(DEVICE_ADDR, 1, 0x00) 
        
except KeyboardInterrupt:
     pass    
    
its the second art of the code starting at line 31 that i cant get my head around

Code: Select all

 while True:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel='in1/ref', reference_voltage=reference)
            "value" = range (13.500 - 16.300)
            bus.write_byte_data(DEVICE_ADDR, 1, 0xFF)
        
    while False:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel='in1/ref', reference_voltage=reference)    
        for value range: <(13.499)
            bus.write_byte_data(DEVICE_ADDR, 1, 0x00) 
it needs to take the printed 'in1:voltage and if in range between 13.4 to 16:3 volts then
bus.write_byte_data(DEVICE_ADDR, 1, 0xFF) to turn reelay on
if the voltage s less than 13.4v then
bus.write_byte_data(DEVICE_ADDR, 1, 0x00) to either turn relay off or insure it is off.

i have never used and know nothing about python, once i see how i can go from there with in0 and in2 inputs
i am living in a van on solar power and need this to automatically control heavy loads of hot water system, air conditioner etc...
any help is appreciated

.

pcmanbob
Posts: 11383
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python coding for voltage relays

Wed Jul 21, 2021 6:38 pm

You don't use while statements like that what you need is a while loop with if statements within it checking if the value variable falls within your specified range and then taking action on the results.

Something like this

Code: Select all

#!/usr/bin/env python
import time
import smbus
import sys
DEVICE_BUS = 1
DEVICE_ADDR = 0x11
bus = smbus.SMBus(DEVICE_BUS)

from ads1015 import ADS1015

CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref']

ads1015 = ADS1015()
ads1015.set_mode('single')
ads1015.set_programmable_gain(2.048)
ads1015.set_sample_rate(1600)

reference = ads1015.get_reference_voltage()

print("Reference voltage: {:6.3f}v \n".format(reference))

try:
    while True:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)
            print("{}: {:6.3f}v".format(channel, value))
            
            if value >= 13.500 and value =< 16.300:
                bus.write_byte_data(DEVICE_ADDR, 1, 0xFF)
                
            elif Value <= 13.499:
                bus.write_byte_data(DEVICE_ADDR, 1, 0x00) 
                
            else:   
                print("Error voltage to high")

        print("")
        time.sleep(1.0)

except KeyboardInterrupt:
     pass    
     
Untested code

and you should be using python 3 now as python ( which is python 2) is end of life , if you are using thonny then you will be using python 3 by default.
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Thu Jul 22, 2021 3:41 am

I had to change

Code: Select all

 if value >= 13.300 and value =< 16.300
to

Code: Select all

if value >= 13.300 and value <= 16.300
And

Code: Select all

elif Value
to

Code: Select all

elif value
It works...
Sir you are a champion and thankyou so much I am starting to get my head around it.

There is one small problem left-
Every time it cycles through the relay is on for a second and there's a momentary off.
Is there a way to "latch" the relay on untill it gets the

Code: Select all

elif value <= 13.300 
Bus.write_byte_data(DEVICE_ADDR, 1, 0x00) 

command?

Switching a regulator on and off under load every second can blow the regulator and I don't really want to increase the sleep time between voltage measurements just to keep the relay on.
Thankyou.

User avatar
rpdom
Posts: 18871
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: python coding for voltage relays

Thu Jul 22, 2021 5:04 am

If_i_only_knew101 wrote:
Thu Jul 22, 2021 3:41 am
I had to change

Code: Select all

 if value >= 13.300 and value =< 16.300
to

Code: Select all

if value >= 13.300 and value <= 16.300
And

Code: Select all

elif Value
to

Code: Select all

elif value
It works...
Sir you are a champion and thankyou so much I am starting to get my head around it.

There is one small problem left-
Every time it cycles through the relay is on for a second and there's a momentary off.
Is there a way to "latch" the relay on untill it gets the

Code: Select all

elif value <= 13.300 
Bus.write_byte_data(DEVICE_ADDR, 1, 0x00) 

command?

Switching a regulator on and off under load every second can blow the regulator and I don't really want to increase the sleep time between voltage measurements just to keep the relay on.
Thankyou.
You didn't show the colons ":" on the ends of those "if" lines, or the indentation on the following lines. Without those the code won't do what it is supposed to.
Unreadable squiggle

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Thu Jul 22, 2021 6:56 am

My apologies, here is the working code in full with corrections:

Code: Select all

#!/usr/bin/env python
import time
import smbus
import sys
DEVICE_BUS = 1
DEVICE_ADDR = 0x11
bus = smbus.SMBus(DEVICE_BUS)

from ads1015 import ADS1015

CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref']

ads1015 = ADS1015()
ads1015.set_mode('single')
ads1015.set_programmable_gain(2.048)
ads1015.set_sample_rate(1600)

reference = ads1015.get_reference_voltage()

print("Reference voltage: {:6.3f}v \n".format(reference))

try:
    while True:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)
            print("{}: {:6.3f}v".format(channel, value))
            
            if value >= 13.300 and value <= 16.000:
                bus.write_byte_data(DEVICE_ADDR, 1, 0xFF)
                
            elif value <= 13.300:
                bus.write_byte_data(DEVICE_ADDR, 1, 0x00)
                
            else:
                bus.write_byte_data(DEVICE_ADDR, 2, 0xFF)
                print("Error voltage to high")

        print("")
        time.sleep(1.0)

except KeyboardInterrupt:
     pass    
     
as stated the relay has a 1 second on and a momentary off as it cycles
can the relay be latched on to stop this momentary off each cycle?

pcmanbob
Posts: 11383
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python coding for voltage relays

Thu Jul 22, 2021 9:01 am

Ok so your un-wanted off is caused by the the value in the elif, I got it wrong in my example code and you changed and still got it wrong in your code . :lol:

So try changing it to this

Code: Select all

            elif value <= 13.299:
                bus.write_byte_data(DEVICE_ADDR, 1, 0x00)
                
that should solve the problem and along the way I hope you have gained some understanding of python.
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

ame
Posts: 3216
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: python coding for voltage relays

Thu Jul 22, 2021 9:39 am

Or just

Code: Select all

elif value < 13.300:
Also, I'd recommend putting some comments in explaining what you are doing and why. Yes, we can see what the code does, but there is nothing to explain why things are as they are, nor anything to say what you are trying to achieve.

If you do that it will help your future self if you want to change it. It will also help us because we can see if the code does what you want, or if there is a discrepancy. If there is a discrepancy, then maybe that's your bug.

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Thu Jul 22, 2021 5:58 pm

I changed script to

Code: Select all

elif value < 13.300
as suggested- the relay is still switching off for a split second (even though the voltage is more than 14 volts) as it cycles (in loop).

As I said before I am totally new to coding (and forum) never even heard of python before this thread let alone knowingly used it.
Yes pcbobman I am learning alot, I looked at your code when it threw errors and saw the previous format so changed the 2 typos to match, by seeing the code i saw the structure. The code looked like it was doing what it's supposed to the relay switched in and out at right volts (except there was a momentary off each time the loop cycled to give new readings)

I was looking at the code again tonight and trying a few things when I realised 'in1' is not stated as value to command the relay...
I'm not sure which of 'in0, in1, in2' trigger it.
I see

Code: Select all

while True:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)
            print("{}: {:6.3f}v".format(channel, value))
But no single voltage channel commanding relay 1.

I need the code to print the voltage of the 3 inputs 'in0, in1, in2' and
if channel 'in1' is between 13.300v and 16v then turn on relay 1 and keep it on (latch it on) untill the voltage drops below 13.300v which turns relay 1 off (latch it off).

Basically switch loads on or off based on the voltage reading of channel 'in1'
And either fix the momentary off in loop or latch the relay on or off depending on the voltage to stop it bouncing/cycling)
(Please note the relay bounce is code related, relay test.py switched and latched the relay on and off on command without bouncing).
I'm using a pimoroni ads1015 (ADC) and
Greekpi/dockerpi 4 channel relay module
I hope this is everything you need.

ame
Posts: 3216
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: python coding for voltage relays

Thu Jul 22, 2021 9:12 pm

Ok. I think I see the problem.

You have a for loop which is cycling through the channels and getting voltage readings, but you are always switching the same relay (I'll call it the relay, because you are only driving one).

Basically, your program is doing this:

Get voltage from in0
Make a decision and switch the relay
Wait one second

Get voltage from in1
Make a decision and switch the relay
Wait one second

Get voltage from in2
Make a decision and switch the relay
Wait one second

Loop around and do it all again forever

So if in0 is, say, 14V and in1 is, say, 13V then you will get the relay turning on for one second, then turning off again.

Presumably you have three input voltages and three different relays, and you want each voltage input to affect only its own relay?

Again, if you could put comments in it would be helpful. If the comments don't match the code it's a great indicator that something is wrong.

If you don't want to put comments in then just explain, in very simple terms, precisely what you are trying to do.

pcmanbob
Posts: 11383
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python coding for voltage relays

Fri Jul 23, 2021 9:12 am

So looking through your posts I found this
it needs to take the printed 'in1:voltage and if in range between 13.4 to 16:3 volts then
bus.write_byte_data(DEVICE_ADDR, 1, 0xFF) to turn reelay on
if the voltage s less than 13.4v then
bus.write_byte_data(DEVICE_ADDR, 1, 0x00) to either turn relay off or insure it is off.
So it looks like you only want ADC channel 1 to switch relay address 1

So I have adjusted the code to do just that

Code: Select all

#!/usr/bin/env python
import time
import smbus
import sys
DEVICE_BUS = 1
DEVICE_ADDR = 0x11
bus = smbus.SMBus(DEVICE_BUS)

from ads1015 import ADS1015

CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref']

ads1015 = ADS1015()
ads1015.set_mode('single')
ads1015.set_programmable_gain(2.048)
ads1015.set_sample_rate(1600)

reference = ads1015.get_reference_voltage()

print("Reference voltage: {:6.3f}v \n".format(reference))

try:
    while True:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)
            print("{}: {:6.3f}v".format(channel, value))
            
            if channel == "in1/ref": # this will cause the relay 1 only to switch when reading channel 1.
            
                if value >= 13.300 and value <= 16.000:
                    bus.write_byte_data(DEVICE_ADDR, 1, 0xFF)
                    
                elif value <= 13.299:
                    bus.write_byte_data(DEVICE_ADDR, 1, 0x00)
                
                else:   
                    print("Error voltage to high")


        print("")
        time.sleep(1.0)

except KeyboardInterrupt:
     pass   
     
untested code

note I removed the reference to relay address 2 from the else statement because you said you only wanted to control relay 1.
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Sat Jul 24, 2021 4:08 pm

hi the code you gave works well
I bought another dockerpi relay module and dedicated it to system loads rather than use the one i have thats running a alarm system, so had to change a few things
i can not see chargers so used code to show by voltage thresholds by adding elifs
from what you taught me i ended up with following

Code: Select all

#!/usr/bin/env python
import time
import smbus
import sys
DEVICE_BUS = 1
DEVICE_ADDR = 0x11
bus = smbus.SMBus(DEVICE_BUS)

from ads1015 import ADS1015

CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref']

ads1015 = ADS1015()
ads1015.set_mode('single')
ads1015.set_programmable_gain(2.048)
ads1015.set_sample_rate(1600)

reference = ads1015.get_reference_voltage()

print("Reference voltage: {:6.3f}v \n".format(reference))

try:
    while True:
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)
            print("{}: {:6.3f}v".format(channel, value))
 
# in0 used to monitor solar volts and warn of overvoltage.
            if channel == "in0/ref":# This will cause relay 3 only to switch when reading channel 0. unless commanded else where.
            
                if value >= 1.000 and value <= 22.500:# voltage range of print solar voltage.
                    print("SOLAR VOLTAGE")
                    
                elif value <= 0.999:# voltage range of print no solar input.
                    print("NO SOLAR INPUT") 
                
                else:
                    bus.write_byte_data(DEVICE_ADDR, 3, 0xFF)# overvolts trips relay 3 on (relay 3 connected to warning buzzer/audio warning)  
                    print("WARNING: SOLAR SYSTEM OVERVOLTAGE")# print warning and instructions for overvolts to follow.
                    print("WARNING ISOLATE Pi ADC and SOLAR CB")

# in1 voltage control relay/s.
            if channel == "in1/ref":# this will cause relay 2 and 3 only to switch when reading channel 1, unless commanded else where.
            
                if value >= 13.200 and value <= 14.500:# voltage range to operate hotwater system.
                    bus.write_byte_data(DEVICE_ADDR, 2, 0xFF)# turn on relay 2 hotwater.
                    print("HOTWATER SYSTEM ON")# print status of hotwater system.
                    
                elif value <= 13.199:# voltage range to turn off relay 2 hotwater. 
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# turn off relay 2 hotwater.
                    print("HOTWATER SYSTEM OFF")# print statue of hotwater system.
                
                else:
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# switches off relay 2 hotwater (system may be in fault or calcium mode).
                    print("HOTWATER SYSTEM OFF")
                    bus.write_byte_data(DEVICE_ADDR, 3, 0xFF)# audio warning of fault or calcium mode
                    print("WARNING: CALCIUM MODE ON")# print warning calcium mode.
                    print("CHECK MODE & BATTERIES")
                    time.sleep(0.200)# time delay on warning buzzer.
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.

# in2 displays battery status.
            if channel == "in2/ref":# this will cause relay 4 only to switch when reading channel 2 unless commanded else where.
 
                if value <= 11.000:# range in battery capacity.
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# ensures hotwater system is off and hasnt latched on by other means. (fail safe to protect batteries from accidental drain).
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF)# turns on relay 4 and 300A slave relay (using NC/COM contacts) ON DISCONNECTING BATTERY FROM CIRCUIT.
#                   300A relay not installed (yet to be delivered).
                    print("SYSTEM WARNING")# system warning
                    print("BATTERY SYSTEM DEAD")# system is basically dead.
                    print("URGENT: RECHARGE NOW")
                    print("WARNING: BATTERY DAMAGE WILL OCCURE")

                elif value >= 11.001 and value <= 11.999:# range in battery capacity
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.
                    print("WARNING")# print system status batteries below half charge (sla agm batteries dont like deep discharge)
                    print("BATTERY SYSTEM DYING")
                    print("RECHARGE NOW")

                elif value >= 12.000 and value <= 12.800:# range in battery capacity.
                    print("WARNING")# print system status
                    print("SYSTEM ON BATTERY")

                elif value >= 12.801 and value <= 13.500:# range for bulk mode charging
                    print("CHARGING SYSTEM BULK")# print system status
                  
                elif value >= 13.501 and value <= 13.800:# range of float mode
                    print("CHARGING SYSTEM FLOAT") 

                elif value >= 13.801 and value <= 14.500:# range of absorbsion mode
                    print("CHARGING SYSTEM ABSORBSION")

                elif value >= 14.501 and value <= 15.500:# calcium mode thresholds 15.500v restores full battery capacity in heavily discharged batteries
#                   (not calcified or sulphated sla's which require aditional venting and full 16v charge)
                    print("CHARGING SYSTEM CALCIUM MODE")
                    print("WARNING CALCIUM MODE")

                elif value >= 15.501 and value <= 16.000:# voltage range to trip following code.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF) # relay 4 option to isolate batteries above 15.501v.
                    print("CALCIIUM MODE") 
                    print("WARNING HYDROGEN PRESSURE")
                    print("CHECK BATTERIES")
                    
                else: #value >= 16.001v trips following code.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF) # turns on relay 4 and isolates batteries from overvoltage faults <+16v, 
                    print("in2 WARNING: OVERVOLTAGE")# print warning
                    print("FAULT IN CHARGING SYSTEM")
                    print("ISOLATE CHARGING & SOLAR CBs")

        print("")
        time.sleep(0.5)

except KeyboardInterrupt:
     pass


# installed in a toyota 2000 townace (so far):-
#(deep cycle sla batteries: 14.5v-15.0v charge) 4x 170ah.
# primary solar system 600W through projecta IDC45.
# secondary solar system 380W through 480W regulator feeds hotwater via slave 20A double pole relay to contact NC, battery to NO, COM to hotwater system +Pos.
# 240v projecta 21A smart battery charger and 800W petrol square wave output generator.
# program set at 14.501v max to trip alarm (change made so i know if batteries enter calcium mode)
#deeply discharged batteries require calcium mode of 16v (charge system 16v @ 2amps to try to avoid excessive gas build up/pressure in sla)
# dockerpi 4 channel relay module and pimoroni ads(adc1015) used.
# in0 reads solar pannel voltage.
# in1 reads the main junction/distrubtion board (feeds- 2 sub boxes and microwave/inverter (12v @ 200Amps).
# in2 reads the sub distrubtion board "a" feeds- hotwater system (12v @ 14A), air-conditioner (12v @ 15A) TV, Pi, mast head amp=(12v @ 6A aprox).
# sub distrubtion board "b" feeds- fridge, lights, fan, phone chargers, security lights/one way windows, intruder alarm etc.
# hotwater system 12v @ 14A (Pi module relay conected to the slave 20A relay as stated)
#                
All fixed I had <> reversed.
Code works well. Just need giu display window.
thankyou. :D
Last edited by If_i_only_knew101 on Sat Jul 24, 2021 6:08 pm, edited 2 times in total.

pcmanbob
Posts: 11383
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python coding for voltage relays

Sat Jul 24, 2021 4:30 pm

Glad you code is now working

You probably don't need it looking once every half second as I doubt voltages will change that quick, once every second should be plenty fast enough..

It sounds like you need to add a GUI just to display the voltages, may be this will get you started

https://projects.raspberrypi.org/en/pro ... -with-guis
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Sat Jul 24, 2021 9:31 pm

pcmanbob wrote:
Sat Jul 24, 2021 4:30 pm
Glad you code is now working

You probably don't need it looking once every half second as I doubt voltages will change that quick, once every second should be plenty fast enough..

It sounds like you need to add a GUI just to display the voltages, may be this will get you started

https://projects.raspberrypi.org/en/pro ... -with-guis
Thanks, now I can sell tickets to see how lost I am...
Is the above a app?
Is there something easier to understand and imports a .py file to execute?

pcmanbob
Posts: 11383
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python coding for voltage relays

Sun Jul 25, 2021 8:37 am

It a module / app that allows you to easily created Graphic User interfaces , that you can display on the desktop.

I suggest you experiment with it on a fresh install of RPI OS on another SD card so you do end mess up your existing build which is now working.

If you work through the tutorial you will get an idea of what your can do then you will need to read the documentation to see how to add your voltage readings and your existing code.

I think guizero is about as simple as it gets..

Edit...

I have never used guizero but it took me about 30 min to get to this stage just working from the tutorial examples.

Image

and this is the code that made it

Code: Select all

from guizero import App, Text

app = App(title="Battery Voltages", width=300, height=200, layout="grid")

B1V = Text(app, text="Battery 1 voltage", size=20, font="Times New Roman", color="darkblue", grid=[2,1], align="left")

B2V = Text(app, text="Battery 2 voltage", size=20, font="Times New Roman", color="darkblue", grid=[2,3], align="left")

B3V = Text(app, text="Battery 3 voltage", size=20, font="Times New Roman", color="darkblue", grid=[2,5], align="left")


app.display()
one point were in the tutorial they say use IDLE you now need to use Thonny
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

ame
Posts: 3216
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: python coding for voltage relays

Sun Jul 25, 2021 10:13 am

If_i_only_knew101 wrote:
Sat Jul 24, 2021 9:31 pm
Thanks, now I can sell tickets to see how lost I am...
Is the above a app?
Is there something easier to understand and imports a .py file to execute?
Try the tutorial, without thinking about your particular purpose. Have a go at making the demo as shown in the tutorial, then, once that has settled in your mind, think about how you could use the techniques you just learned to make something for your specific requirements.

pcmanbob
Posts: 11383
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python coding for voltage relays

Sun Jul 25, 2021 2:20 pm

Now I don't know how this is going to look as I can run your code on my pi because I don't have the hardware you have,

but if you don't want to go to the trouble of writing a GUI , which might be complex looking at your working code,

You could simply try clearing the screen between each run of your code so only the lines you want shown are displayed.

Code: Select all

#!/usr/bin/env python
import time
import smbus
import sys
import os
DEVICE_BUS = 1
DEVICE_ADDR = 0x11
bus = smbus.SMBus(DEVICE_BUS)

from ads1015 import ADS1015

CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref']

ads1015 = ADS1015()
ads1015.set_mode('single')
ads1015.set_programmable_gain(2.048)
ads1015.set_sample_rate(1600)

reference = ads1015.get_reference_voltage()

print("Reference voltage: {:6.3f}v \n".format(reference))

try:
    while True:
        os.system('clear')
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)
            print("{}: {:6.3f}v".format(channel, value))
 
# in0 used to monitor solar volts and warn of overvoltage.
            if channel == "in0/ref":# This will cause relay 3 only to switch when reading channel 0. unless commanded else where.
            
                if value >= 1.000 and value <= 22.500:# voltage range of print solar voltage.
                    print("SOLAR VOLTAGE")
                    
                elif value <= 0.999:# voltage range of print no solar input.
                    print("NO SOLAR INPUT") 
                
                else:
                    bus.write_byte_data(DEVICE_ADDR, 3, 0xFF)# overvolts trips relay 3 on (relay 3 connected to warning buzzer/audio warning)  
                    print("WARNING: SOLAR SYSTEM OVERVOLTAGE")# print warning and instructions for overvolts to follow.
                    print("WARNING ISOLATE Pi ADC and SOLAR CB")

# in1 voltage control relay/s.
            if channel == "in1/ref":# this will cause relay 2 and 3 only to switch when reading channel 1, unless commanded else where.
            
                if value >= 13.200 and value <= 14.500:# voltage range to operate hotwater system.
                    bus.write_byte_data(DEVICE_ADDR, 2, 0xFF)# turn on relay 2 hotwater.
                    print("HOTWATER SYSTEM ON")# print status of hotwater system.
                    
                elif value <= 13.199:# voltage range to turn off relay 2 hotwater. 
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# turn off relay 2 hotwater.
                    print("HOTWATER SYSTEM OFF")# print statue of hotwater system.
                
                else:
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# switches off relay 2 hotwater (system may be in fault or calcium mode).
                    print("HOTWATER SYSTEM OFF")
                    bus.write_byte_data(DEVICE_ADDR, 3, 0xFF)# audio warning of fault or calcium mode
                    print("WARNING: CALCIUM MODE ON")# print warning calcium mode.
                    print("CHECK MODE & BATTERIES")
                    time.sleep(0.200)# time delay on warning buzzer.
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.

# in2 displays battery status.
            if channel == "in2/ref":# this will cause relay 4 only to switch when reading channel 2 unless commanded else where.
 
                if value <= 11.000:# range in battery capacity.
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# ensures hotwater system is off and hasnt latched on by other means. (fail safe to protect batteries from accidental drain).
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF)# turns on relay 4 and 300A slave relay (using NC/COM contacts) ON DISCONNECTING BATTERY FROM CIRCUIT.
#                   300A relay not installed (yet to be delivered).
                    print("SYSTEM WARNING")# system warning
                    print("BATTERY SYSTEM DEAD")# system is basically dead.
                    print("URGENT: RECHARGE NOW")
                    print("WARNING: BATTERY DAMAGE WILL OCCURE")

                elif value >= 11.001 and value <= 11.999:# range in battery capacity
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.
                    print("WARNING")# print system status batteries below half charge (sla agm batteries dont like deep discharge)
                    print("BATTERY SYSTEM DYING")
                    print("RECHARGE NOW")

                elif value >= 12.000 and value <= 12.800:# range in battery capacity.
                    print("WARNING")# print system status
                    print("SYSTEM ON BATTERY")

                elif value >= 12.801 and value <= 13.500:# range for bulk mode charging
                    print("CHARGING SYSTEM BULK")# print system status
                  
                elif value >= 13.501 and value <= 13.800:# range of float mode
                    print("CHARGING SYSTEM FLOAT") 

                elif value >= 13.801 and value <= 14.500:# range of absorbsion mode
                    print("CHARGING SYSTEM ABSORBSION")

                elif value >= 14.501 and value <= 15.500:# calcium mode thresholds 15.500v restores full battery capacity in heavily discharged batteries
#                   (not calcified or sulphated sla's which require aditional venting and full 16v charge)
                    print("CHARGING SYSTEM CALCIUM MODE")
                    print("WARNING CALCIUM MODE")

                elif value >= 15.501 and value <= 16.000:# voltage range to trip following code.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF) # relay 4 option to isolate batteries above 15.501v.
                    print("CALCIIUM MODE") 
                    print("WARNING HYDROGEN PRESSURE")
                    print("CHECK BATTERIES")
                    
                else: #value >= 16.001v trips following code.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF) # turns on relay 4 and isolates batteries from overvoltage faults <+16v, 
                    print("in2 WARNING: OVERVOLTAGE")# print warning
                    print("FAULT IN CHARGING SYSTEM")
                    print("ISOLATE CHARGING & SOLAR CBs")

        print("")
        time.sleep(1)

except KeyboardInterrupt:
     pass


# installed in a toyota 2000 townace (so far):-
#(deep cycle sla batteries: 14.5v-15.0v charge) 4x 170ah.
# primary solar system 600W through projecta IDC45.
# secondary solar system 380W through 480W regulator feeds hotwater via slave 20A double pole relay to contact NC, battery to NO, COM to hotwater system +Pos.
# 240v projecta 21A smart battery charger and 800W petrol square wave output generator.
# program set at 14.501v max to trip alarm (change made so i know if batteries enter calcium mode)
#deeply discharged batteries require calcium mode of 16v (charge system 16v @ 2amps to try to avoid excessive gas build up/pressure in sla)
# dockerpi 4 channel relay module and pimoroni ads(adc1015) used.
# in0 reads solar pannel voltage.
# in1 reads the main junction/distrubtion board (feeds- 2 sub boxes and microwave/inverter (12v @ 200Amps).
# in2 reads the sub distrubtion board "a" feeds- hotwater system (12v @ 14A), air-conditioner (12v @ 15A) TV, Pi, mast head amp=(12v @ 6A aprox).
# sub distrubtion board "b" feeds- fridge, lights, fan, phone chargers, security lights/one way windows, intruder alarm etc.
# hotwater system 12v @ 14A (Pi module relay conected to the slave 20A relay as stated)
#                
I have added the 2 required lines to do this and update the sleep to 1 second at the end of the loop, you may find increasing this might help if the display is flashing, your voltage are not going to change that much over 1 or 2 seconds.
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Sun Jul 25, 2021 5:54 pm

pcmanbob wrote:
Sun Jul 25, 2021 2:20 pm
Now I don't know how this is going to look as I can run your code on my pi because I don't have the hardware you have,

but if you don't want to go to the trouble of writing a GUI , which might be complex looking at your working code,

You could simply try clearing the screen between each run of your code so only the lines you want shown are displayed.

Code: Select all

#!/usr/bin/env python
import time
import smbus
import sys
import os
DEVICE_BUS = 1
DEVICE_ADDR = 0x11
bus = smbus.SMBus(DEVICE_BUS)

from ads1015 import ADS1015

CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref']

ads1015 = ADS1015()
ads1015.set_mode('single')
ads1015.set_programmable_gain(2.048)
ads1015.set_sample_rate(1600)

reference = ads1015.get_reference_voltage()

print("Reference voltage: {:6.3f}v \n".format(reference))

try:
    while True:
        os.system('clear')
        for channel in CHANNELS:
            value = ads1015.get_compensated_voltage(channel=channel, reference_voltage=reference)
            print("{}: {:6.3f}v".format(channel, value))
 
# in0 used to monitor solar volts and warn of overvoltage.
            if channel == "in0/ref":# This will cause relay 3 only to switch when reading channel 0. unless commanded else where.
            
                if value >= 1.000 and value <= 22.500:# voltage range of print solar voltage.
                    print("SOLAR VOLTAGE")
                    
                elif value <= 0.999:# voltage range of print no solar input.
                    print("NO SOLAR INPUT") 
                
                else:
                    bus.write_byte_data(DEVICE_ADDR, 3, 0xFF)# overvolts trips relay 3 on (relay 3 connected to warning buzzer/audio warning)  
                    print("WARNING: SOLAR SYSTEM OVERVOLTAGE")# print warning and instructions for overvolts to follow.
                    print("WARNING ISOLATE Pi ADC and SOLAR CB")

# in1 voltage control relay/s.
            if channel == "in1/ref":# this will cause relay 2 and 3 only to switch when reading channel 1, unless commanded else where.
            
                if value >= 13.200 and value <= 14.500:# voltage range to operate hotwater system.
                    bus.write_byte_data(DEVICE_ADDR, 2, 0xFF)# turn on relay 2 hotwater.
                    print("HOTWATER SYSTEM ON")# print status of hotwater system.
                    
                elif value <= 13.199:# voltage range to turn off relay 2 hotwater. 
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# turn off relay 2 hotwater.
                    print("HOTWATER SYSTEM OFF")# print statue of hotwater system.
                
                else:
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# switches off relay 2 hotwater (system may be in fault or calcium mode).
                    print("HOTWATER SYSTEM OFF")
                    bus.write_byte_data(DEVICE_ADDR, 3, 0xFF)# audio warning of fault or calcium mode
                    print("WARNING: CALCIUM MODE ON")# print warning calcium mode.
                    print("CHECK MODE & BATTERIES")
                    time.sleep(0.200)# time delay on warning buzzer.
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.

# in2 displays battery status.
            if channel == "in2/ref":# this will cause relay 4 only to switch when reading channel 2 unless commanded else where.
 
                if value <= 11.000:# range in battery capacity.
                    bus.write_byte_data(DEVICE_ADDR, 2, 0x00)# ensures hotwater system is off and hasnt latched on by other means. (fail safe to protect batteries from accidental drain).
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF)# turns on relay 4 and 300A slave relay (using NC/COM contacts) ON DISCONNECTING BATTERY FROM CIRCUIT.
#                   300A relay not installed (yet to be delivered).
                    print("SYSTEM WARNING")# system warning
                    print("BATTERY SYSTEM DEAD")# system is basically dead.
                    print("URGENT: RECHARGE NOW")
                    print("WARNING: BATTERY DAMAGE WILL OCCURE")

                elif value >= 11.001 and value <= 11.999:# range in battery capacity
                    bus.write_byte_data(DEVICE_ADDR, 3, 0x00)# turns off relay 3 audio alarm.
                    print("WARNING")# print system status batteries below half charge (sla agm batteries dont like deep discharge)
                    print("BATTERY SYSTEM DYING")
                    print("RECHARGE NOW")

                elif value >= 12.000 and value <= 12.800:# range in battery capacity.
                    print("WARNING")# print system status
                    print("SYSTEM ON BATTERY")

                elif value >= 12.801 and value <= 13.500:# range for bulk mode charging
                    print("CHARGING SYSTEM BULK")# print system status
                  
                elif value >= 13.501 and value <= 13.800:# range of float mode
                    print("CHARGING SYSTEM FLOAT") 

                elif value >= 13.801 and value <= 14.500:# range of absorbsion mode
                    print("CHARGING SYSTEM ABSORBSION")

                elif value >= 14.501 and value <= 15.500:# calcium mode thresholds 15.500v restores full battery capacity in heavily discharged batteries
#                   (not calcified or sulphated sla's which require aditional venting and full 16v charge)
                    print("CHARGING SYSTEM CALCIUM MODE")
                    print("WARNING CALCIUM MODE")

                elif value >= 15.501 and value <= 16.000:# voltage range to trip following code.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF) # relay 4 option to isolate batteries above 15.501v.
                    print("CALCIIUM MODE") 
                    print("WARNING HYDROGEN PRESSURE")
                    print("CHECK BATTERIES")
                    
                else: #value >= 16.001v trips following code.
#                   bus.write_byte_data(DEVICE_ADDR, 4, 0xFF) # turns on relay 4 and isolates batteries from overvoltage faults <+16v, 
                    print("in2 WARNING: OVERVOLTAGE")# print warning
                    print("FAULT IN CHARGING SYSTEM")
                    print("ISOLATE CHARGING & SOLAR CBs")

        print("")
        time.sleep(1)

except KeyboardInterrupt:
     pass


# installed in a toyota 2000 townace (so far):-
#(deep cycle sla batteries: 14.5v-15.0v charge) 4x 170ah.
# primary solar system 600W through projecta IDC45.
# secondary solar system 380W through 480W regulator feeds hotwater via slave 20A double pole relay to contact NC, battery to NO, COM to hotwater system +Pos.
# 240v projecta 21A smart battery charger and 800W petrol square wave output generator.
# program set at 14.501v max to trip alarm (change made so i know if batteries enter calcium mode)
#deeply discharged batteries require calcium mode of 16v (charge system 16v @ 2amps to try to avoid excessive gas build up/pressure in sla)
# dockerpi 4 channel relay module and pimoroni ads(adc1015) used.
# in0 reads solar pannel voltage.
# in1 reads the main junction/distrubtion board (feeds- 2 sub boxes and microwave/inverter (12v @ 200Amps).
# in2 reads the sub distrubtion board "a" feeds- hotwater system (12v @ 14A), air-conditioner (12v @ 15A) TV, Pi, mast head amp=(12v @ 6A aprox).
# sub distrubtion board "b" feeds- fridge, lights, fan, phone chargers, security lights/one way windows, intruder alarm etc.
# hotwater system 12v @ 14A (Pi module relay conected to the slave 20A relay as stated)
#                
I have added the 2 required lines to do this and update the sleep to 1 second at the end of the loop, you may find increasing this might help if the display is flashing, your voltage are not going to change that much over 1 or 2 seconds.
Thankyou Im extremely new to python and haven't wrote code in 30+ years not that I remember anything of basic, logo or Pascal.
I'm having trouble remembering to turn loads on and off this project of automation is a necessity, and as I can't see the charger the modes displayed on screen is useful.
yes I changed the sleep to 1 second (0.5sec was more for overvoltage warning)
I might play with a GUI but it seems complex I don't need buttons or sliders etc and had no idea between this file, and a app, or how to import it, the link isn't a good explanation of how to do what I needed,
Cheers and thankyou for the help

pcmanbob
Posts: 11383
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: python coding for voltage relays

Sun Jul 25, 2021 6:48 pm

Yes I think it would be a big project to add a GUI to your existing code , I did try but as I said I have never used guizero and I soon ran in to problems.

That's why I suggested using the code above that clears the screen at the start of each loop so you only have one copy of the printed data on the screen it's like a very simple gui that just displays the required data.

How well did it work when reading the value from the ADC ?

I did do some testing replacing the ADC with a random number generator just so I had some values to display and it seemed to work ok.

You can even add colour to the messages if you want, I can add this and repost the code if you wish.
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Mon Jul 26, 2021 6:54 am

I think a GUI is too advanced for a total noob like me.
The voltage readings are very close to my multimeter reading (-0.1v) so it works well.
Yes it would be great to have the readouts in different colours and red warnings.
I posted what I was doing on FB and there's a few people interested for their mobile homes, they too are noobs looking for similar.
Thankyou for your time it helps alot

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Mon Jul 26, 2021 6:56 am

pcmanbob wrote:
Sun Jul 25, 2021 6:48 pm
Yes I think it would be a big project to add a GUI to your existing code , I did try but as I said I have never used guizero and I soon ran in to problems.

That's why I suggested using the code above that clears the screen at the start of each loop so you only have one copy of the printed data on the screen it's like a very simple gui that just displays the required data.

How well did it work when reading the value from the ADC ?

I did do some testing replacing the ADC with a random number generator just so I had some values to display and it seemed to work ok.

You can even add colour to the messages if you want, I can add this and repost the code if you wish.
I think a GUI is too advanced for a total noob like me.
The voltage readings are very close to my multimeter reading (-0.1v) so it works well.
Yes it would be great to have the readouts in different colours and red warnings.
I posted what I was doing on FB and there's a few people interested for their mobile homes, they too are noobs looking for similar.
Thankyou for your time it helps alot

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Mon Jul 26, 2021 6:58 am

pcmanbob wrote:
Sun Jul 25, 2021 6:48 pm
Yes I think it would be a big project to add a GUI to your existing code , I did try but as I said I have never used guizero and I soon ran in to problems.

That's why I suggested using the code above that clears the screen at the start of each loop so you only have one copy of the printed data on the screen it's like a very simple gui that just displays the required data.

How well did it work when reading the value from the ADC ?

I did do some testing replacing the ADC with a random number generator just so I had some values to display and it seemed to work ok.

You can even add colour to the messages if you want, I can add this and repost the code if you wish.
I think a GUI is too advanced for a total noob like me.
The voltage readings are very close to my multimeter reading (-0.1v) so it works well.
Yes it would be great to have the readouts in different colours and red warnings.
I posted what I was doing on FB and there's a few people interested for their mobile homes, they too are noobs looking for similar.
Thankyou for your time it helps alot

ame
Posts: 3216
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: python coding for voltage relays

Mon Jul 26, 2021 7:16 am

Sooo, then, how cool would it be to have a small display dedicated to the task of showing the numbers? You'll probably be even more excited to learn you can turn LEDs on and off under the control of your program.

If you really want to get your hands dirty then stick around and ask questions. For starters, here's an example of using a cheap character display on the Pi.

https://phppot.com/web/guide-to-setup-r ... -backpack/

Do not be intimidated. Most stuff like this is basically:

Collect data
Process data (and optionally store data)
Display data

Then repeat ad infinitum. During the process data step you might want to do some other tasks, but basically it boils down to these steps.

So, since you have a program that collects and displays the data on the screen, displaying it somewhere else should be a simple incremental task. Incremental because it shouldn't affect what has gone before (which is already working).

By the way, it would be worth your while thinking about what happens to your system if something goes wrong. For example, maybe your program turns on the relay and then the Pi crashes. Or maybe you turn on the Pi but the program doesn't start (or you forget to start it). If something like that could cause something bad to happen then you need ways to prevent it, which is usually possible, but you do need to think about what and how.

If you determine that nothing bad is likely to happen, even better.

If_i_only_knew101
Posts: 19
Joined: Mon Jul 19, 2021 12:54 am

Re: python coding for voltage relays

Mon Jul 26, 2021 7:27 am

My apologies my phone duplicated a response a few times above. And I can't delete them.

I will look at warnings of pi shut off a bit later.

Return to “Python”