Jump to content

Orange pi pc monitor battery voltage - please help to adapt python script from raspberry pi


kris85pl

Recommended Posts

Hi. I have orange pi pc with armbian installed. I'm powering opi pc with battery, I would like to make something like ups. 

Some time ago I found solution to monitor battery voltage for raspberry pi wit ADC, exactly mcp3002. It uses script in python. Here is link for this solution: http://raspi.tv/2013/controlled-shutdown-duration-test-of-pi-model-a-with-2-cell-lipo

I made prepared everything like is shown on diagram, I'm using breadboard and also mcp3002. With raspberry pi it works with python script from: http://raspi.tv/download/batt_test_raspi.tv.py.gzbut I have a problem with adapt this script with OPi PC.

 

I think, that here is a problem with some libraries, some libraries are different for rpi. 

 

Here is contains of "batt_test_raspi.tv.py.gz":

 

 

#!/usr/bin/env python2.7

# script by Alex Eames http://RasPi.tv
# explained here...
# DO NOT use this script without a Voltage divider or other means of
# reducing battery voltage to the ADC. This is exaplained on the above blog page
import time
import os
import subprocess
import smtplib
import string
import RPi.GPIO as GPIO
from time import gmtime, strftime
 
GPIO.setmode(GPIO.BCM)
 
################################################################################
######################### Program Variables you MUST SET #######################
# email variables
fromaddr = 'your_gmail_account@gmail.com'
toaddr  = 'destination email address'
# Googlemail login details
username = 'your googlemail/gmail username'
password = 'your googlemail/gmail password'
 
########## Program variables you might want to tweak ###########################
# voltage divider connected to channel 0 of mcp3002
adcs = [0] # 0 battery voltage divider
reps = 10 # how many times to take each measurement for averaging
cutoff = 7.5 # cutoff voltage for the battery
previous_voltage = cutoff + 1 # initial value
time_between_readings = 60 # seconds between clusters of readings
 
# Define Pins/Ports
SPICLK = 8             # FOUR SPI ports on the ADC
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
 
####### You shouldn't need to change anything below here #######################
################################################################################
 
# read SPI data from MCP3002 chip, 2 possible adc's (0 & 1)
# this uses a bitbang method rather than Pi hardware spi
# modified code based on an adafruit example for mcp3008
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
    if ((adcnum > 1) or (adcnum < 0)):
        return -1
    if (adcnum == 0):
        commandout = 0x6
    else:
        commandout = 0x7
 
    GPIO.output(cspin, True)
 
    GPIO.output(clockpin, False)  # start clock low
    GPIO.output(cspin, False)     # bring CS low
 
    commandout <<= 5    # we only need to send 3 bits here
    for i in range(3):
        if (commandout & 0x80):
            GPIO.output(mosipin, True)
        else:
            GPIO.output(mosipin, False)
        commandout <<= 1
        GPIO.output(clockpin, True)
        GPIO.output(clockpin, False)
 
    adcout = 0
    # read in one empty bit, one null bit and 10 ADC bits
    for i in range(12):
        GPIO.output(clockpin, True)
        GPIO.output(clockpin, False)
        adcout <<= 1
        if (GPIO.input(misopin)):
            adcout |= 0x1
 
    GPIO.output(cspin, True)
 
    adcout /= 2       # first bit is 'null' so drop it
    return adcout
 
# this function creates and logs to a file called battery_log.txt
# you can change the name if you want, but you'll have to change line 98 as well
def write_log(logline):
    logfile = open('battery_log.txt', 'a')
    logfile.write(logline + '\n')
    logfile.close()
 
# you can edit the text for the email to suit your requirements
def send_email():
    BODY = string.join((
        "From: %s" % fromaddr,
        "To: %s" % toaddr,
        "Subject: Shutting down the model A now",
        "",
        "Your battery voltage was just measured at or below threshold.",
        "If it happens twice in a row, we shut down.",
        ), "\r\n")
 
    # send the email
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(username,password)
    server.sendmail(fromaddr, toaddr, BODY)
    server.quit()
 
#Set up ports
GPIO.setup(SPIMOSI, GPIO.OUT)       # set up the SPI interface pins
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
 
# create log file
item = 'Battery log data'
logfile = open('battery_log.txt', 'w')
logfile.write(item + '\n')
logfile.close()
 
try:
    while True:
        for adcnum in adcs:
            # read the analog pin
            adctot = 0
            for i in range(reps):
                read_adc = readadc(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS)
                adctot += read_adc
                time.sleep(0.05)
            read_adc = adctot / reps / 1.0
            print read_adc
 
            # convert analog reading to Volts = ADC * ( 3.33 / 1024 )
            # 3.33 tweak according to the 3v3 measurement on the Pi
            volts = read_adc * ( 3.33 / 1024.0) * 2.837
            voltstring = str(volts)[0:5]
            print "Battery Voltage: %.2f" % volts
            # now we need to log the time and voltage in the log file
            logline = str(strftime("%Y-%m-%d %H:%M:%S", gmtime()))
            logline += ', '
            logline += voltstring
            print "adding %s to log file" % logline
 
            write_log(logline)
            # put safeguards in here so that it takes 2 or 3 successive readings
            if volts <= cutoff:
                # get it to send you an email at this point before full cutoff
                try:
                    send_email()
                    print "email sent"
                except:
                    print "email failed"
                if previous_voltage <= cutoff:
                    logline = 'Shutting down due to low V at '
                    logline += str(strftime("%Y-%m-%d %H:%M:%S", gmtime()))
                    write_log(logline)
                    # initiate shutdown process
                    print "OK. Syncing file system, then we're shutting down."
                    command = os.system("sync")
                    command = 0
                    if command == 0:
                        print "we're shutting down now"
                        command = "/usr/bin/sudo /sbin/shutdown -h now"
                        process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
                        output = process.communicate()[0]
                        print output
            previous_voltage = volts
        time.sleep(time_between_readings)
 
except KeyboardInterrupt:             # trap a CTRL+C keyboard interrupt
    GPIO.cleanup()
    time.sleep(5)
GPIO.cleanup()
 

 

Friend suggest me to install GPIO libraries for my OPi PC with armbian from this tutorial : http://www.instructables.com/id/Orange-Pi-One-Python-GPIO-basic/, I made all procedure. Next he suggest to change in original script in line from: "import RPi.GPIO as GPIO" to "import pyA20.gpio as GPIO" and in line which contains :

 # Define Pins/Ports

SPICLK = 8             # FOUR SPI ports on the ADC
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
 
I changed to :
 
# Define Pins/Ports
SPICLK = port.PC2             # FOUR SPI ports on the ADC
SPIMISO = port.PC1
SPIMOSI = port.PC0
SPICS = port.PC3
 
But script doesn't work. I've got error:
"Traceback (most recent call last):  File "batt_test_raspi.tv.py", line 15, in <module> GPIO.setmode(GPIO.BCM)"
 
I set # in this line, next I got error:
 
"Traceback (most recent call last):
  File "batt_test_raspi.tv.py", line 35, in <module>
    SPICLK = port.PC2             # FOUR SPI ports on the ADC
NameError: name 'port' is not defined"
 

So I add on the top of script: "from pyA20.gpio import port"

 

Now I have error:

 

Traceback (most recent call last):

  File "batt_test_raspi.tv.py", line 110, in <module>
    GPIO.setup(SPIMOSI, GPIO.OUT)       # set up the SPI interface pins
AttributeError: 'module' object has no attribute 'setup'
 
I don't know what to do next, my linux and python knowledge is not good. Please anyone to help me get it to work. 
 
Regards, Kris
 
P.S. Sorry for my english.
Link to comment
Share on other sites

Well, I can't help with the Python stuff so just as a suggestion: Instead of adding missing features to the wrong device (one without PMIC support like Raspberries or H3 based Oranges) choosing the right one might be an alternative. Boards with Allwinner's A10, A13 (also known as R8 on the C.H.I.P) or A20 are accompanied by AXP209 power management IC (PMIC) and support battery/UPS mode by default. Some boards (Olimex Lime, Lime2 for example) even support powering a connected SATA disk from battery since they use step-up converters.

 

With Armbian you can monitor battery conditions easily through sysfs since AX209 already contains ADC to be used for exactly that (that's the good thing when choosing a SoC made for tablets in the first place -- ready to deal with battery by design)

Link to comment
Share on other sites

Yes, you should not mix 2 kind of GPIO libraries in the same project, it is even dangerous.

 

For GPIO.setup() issue, it should be GPIO.setcfg(), but no needs to do it for SPIMOSI or SPIMISO, since the SPI.open() will do that for you.

from pyA20 import spi
spi.open("/dev/spidev0.0")
Link to comment
Share on other sites

I added :

 

 

from pyA20 import spi
spi
.open("/dev/spidev0.0")

to the bottom of file, and changed GPIO.setup to GPIO.setcfg but i have now error: 

 

Traceback (most recent call last):

  File "batt_test_raspi.tv.py", line 113, in <module>
    GPIO.setcfg(SPIMOSI, GPIO.OUT)       # set up the SPI interface pins
AttributeError: 'module' object has no attribute 'setcfg'
 

Any suggestion ?

Link to comment
Share on other sites

 

Hi. I have orange pi pc with armbian installed. I'm powering opi pc with battery, I would like to make something like ups.

 

 

If all you need is some buffered power supply ( board not stopping on power cuts ) use two dirt cheap 18650 power banks and connect them on the battery side ( BAT+/BAT+  BAT-/BAT- ). Charge through one circuit and draw power through the other. Adjusting OPI PC for power consumption ( see http://forum.armbian.com/index.php/topic/1614-running-h3-boards-with-minimal-consumption/) helps when running from batteries.

Link to comment
Share on other sites

If you are using orangepi_PC_gpio_pyH3 and not mixing with other libs, the following is working for me (note the lower cases) :

from pyA20.gpio import gpio
from pyA20.gpio import port

gpio.init()
gpio.setcfg(port.PA1, gpio.OUTPUT)
gpio.setcfg(port.PA20, gpio.OUTPUT)
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines