Ik heb een probleem met de GPIO uitlezen. Onder Python 2.7 blijft hij een LOW uitlezen. Draait onder Ubuntu Armbian..
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import OPi.GPIO as GPIO
from time import sleep # this lets us have a time delay
X=(23)
GPIO.setboard(GPIO.ZERO) # Orange Pi Zero board
GPIO.setmode(GPIO.BOARD) # set up BOARD GPIO numbering
GPIO.setup(X, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
#GPIO.setup(X, GPIO.IN) # set pin X as input (button)
try:
while True: # this will carry on until you hit CTRL+C
if GPIO.input(X): # if pin X == 1
print ("Port",X," is 1/HIGH/True")
else:
print ("Port",X," is 0/LOW/False")
sleep(0.5) # wait 0.1 seconds
finally: # this block will run no matter how the try block exits
print("Finally")
Onder Python 3 werkt het wel, maar dan moet ik setboard weghalen. Is er een betere Pythondriver hiervoor. De driver van de raspberry doet het i.i.g. niet.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Ik zou nu geen nieuwe Python2 code meer willen schrijven(*).
Als dan de "setboard' onder python 3 niet werkt, moet je uitzoeken waarom dat is. Eventueel fixen of gewoon zonder doen.
Dus m.i. moet de vraag iets zijn van: "Wat is er mis met setboard onder python3?". En een antwoord begint dan met: wat werkt er niet aan setboard? Krijg je en foutmelding? Welke?
(*) Nu kan je nog apt install python2.7 doen, maar over X jaar niet meer en hopelijk is er dan nog WEL python 3, dus dat je dan nog niet je programme hoeft te herschrijven.
[Bericht gewijzigd door rew op (50%)]
Python3 zal het zijn dan. Daar ziet hij wel de waarde. Alleen het rissing en falling gebeuren uit die doc werkt niet. Dus als de sensor geactiveerd wordt dan blijft hij tellen. Maar ik heb geen goed idee hoe ik het regel dat het signaal eerst weer laag geweest moet zijn voor hij er weer 1 bij mag tellen.
Dit is het tot nu toe:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import OPi.GPIO as GPIO
from time import sleep # this lets us have a time delay
GPIO.setmode(GPIO.BOARD) # set up BOARD GPIO numbering
GPIO.setwarnings(False) # No more 'pin in use' errors
GPIO.setup(5, GPIO.IN) # set pin X as input (button)
W=0
try:
while True: # this will carry on until you hit CTRL+C
if GPIO.input(5): # if pin X == 1
pass # No use for
else:
W=W+1
print (W, "Liter")
sleep(0.1) # wait 0.1 seconds
finally: # this block will run no matter how the try block exits
print("Finally")
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Gegarandeerd dat die lib gewoon het sysfs gpio filesystem gebruikt.
Dus ik zou eerst proberen of dat (gpio sysfs) wel werkt zoals het hoort, even in een shell proberen.
In /sys/class/gpio .... etc de pin exporteren en dat de waarde teruglezen etc.
Is genoeg over te vinden hoe dat moet.
Over P2.7 vs P3.x, tsja typisch python. Die grossieren in incompatible interfaces, daarom heb ik er ook een hekel aan.
[Bericht gewijzigd door henri62 op (17%)]
Ik heb wel iets gevonden dat ik min of meer 'werkend' heb gekregen.
https://raspi.tv/2014/rpi-gpio-update-and-detecting-both-rising-and-fa…
Er dit van gefabriekt met m'n beperkte programmeurskils.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import OPi.GPIO as GPIO
from time import sleep # this lets us have a time delay
GPIO.setmode(GPIO.BOARD) # set up BOARD GPIO numbering
GPIO.setwarnings(False) # No more 'pin in use' errors
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # set pin X as input (button)
# Define a threaded callback function to run in another thread when events are detected
def my_callback(channel):
if GPIO.input(5): # if port 5 == 1
print ("Up")
else: # if port 5 != 1
print ("Down")
# when a changing edge is detected on port 5, regardless of whatever
# else is happening in the program, the function my_callback will be run
GPIO.add_event_detect(5, GPIO.BOTH, callback=my_callback)
try:
while True: # this will carry on until you hit CTRL+C
if GPIO.input(5): # if pin X == 1
pass
sleep(0.1) # wait 0.1 seconds
except KeyboardInterrupt:
GPIO.cleanup() # clean up GPIO on CTRL+C exit
GPIO.cleanup() # clean up GPIO on normal exit
resultaat:
Er zit wat 'rommel' op het Up signal
Daar het kennelijk alleen op het Up signaal zit, lijkt het mij dat ik er een soort softwarematige flipflop met een set en reset in moet brouwen.
Alleen krijg ik de 'data' niet uit dat def routine gepeuterd. Anders zou ik ook nog alleen de downs als hele liter tellen overwegen. Alhoewel een heel rondje van het 1 liter wijzertje mij beter lijkt.
Toch nog iets gevonden deze ochtend 
Het lijkt kennelijk heel eenvoudig.
De code uit deze tutorial gevist.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import OPi.GPIO as GPIO
from time import sleep # this lets us have a time delay
GPIO.setmode(GPIO.BOARD) # set up BOARD Pin GPIO numbering
GPIO.setwarnings(False) # No more 'pin in use' errors
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Pin 5 set up as an input, pulled down on detection
W=0
try:
while True: # this will carry on until you hit CTRL+C
GPIO.wait_for_edge(5, GPIO.FALLING) # Wait for pin 5 go to low
W=W+1 # If Pin 5 is going low count one liter
print (W,"Liter") # Show me how well this works.
except KeyboardInterrupt:
GPIO.cleanup() # clean up GPIO on CTRL+C exit
GPIO.cleanup() # clean up GPIO on normal exit
Het resultaat lijkt stabiel, geen valse Upjes. 
De nieuwe sensor op de nieuwe watermeter in de bestaande 'digitale' gefrommeld. Cron @ reboot opdracht aangepast naar in Python3 starten. Gereboot. 1 Liter in een maatbeker getapt, lijkt te kloppen. Ik zal de stand van de mechanische meter opschrijven en dan over een tijd eens kijken hoeveel de afwijking bedraagt. Dit is i.i.g. de uiteindelijke code geworden.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
import OPi.GPIO as GPIO
from time import sleep # this lets us have a time delay
GPIO.setmode(GPIO.BOARD) # set up BOARD Pin GPIO numbering
GPIO.setwarnings(False) # No more 'pin in use' errors
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Pin 5 set up as an input, pulled down on detection
f = open("/water/Liter", "r") # Read Liters on startup
wa=float(f.read())
f.close()
def datum(): # Format datum
return format(time.strftime('%d-%m-%Y'))
def tijd(): # Format time
return format(time.strftime('%H:%M:%S'))
wam=0 # Set and declare daily counter
while True: # Run forever
f = open("/water/Liter", "r") # Read from liter
wah=float(f.read()) # Declare and put liter in wah
f.close() # Close reading file
GPIO.wait_for_edge(5, GPIO.FALLING) # Wait for pin 5 go to low
wa=wa+1 # If Pin 5 is going low add one liter to counter
wam=wam+1 # If Pin 5 is going low add one liter to daily counter
if wa != wah: # If wa not equal to wah then
f = open("/water/Liter", 'w') # open Liter file
f.write(str(wa)) # write new wa value to Liter file
f.close() # close Liter file
m3=round(float(wa)/1000, 3) # Calculate wa liters to metric volume
f = open("/water/M3", 'w') # open metric file
f.write(str(m3)) # write new metric value to metric file
f.close() # close metric file
f = open("/water/Dagteller: "+str(datum()), 'w') # Write daily file and consumption in
f.write(str(wam)) # liters to daily file
f.close # Close writing file
if tijd() == "00:00:00": # If there is a new day then
wam=0 # reset daily counter to zero
pass
De watermetersensor werkt al een speer tot nu toe. Nog nul afwijking tussen de mechanische meter en het digitale meet proces. En dan ben ik al weer 300 liter verder. 
Het is zinvol om namen van variabelen zo goed mogelijk te beschrijven. Vb :
wa -> waterteller_stand_liter
wam -> waterteller_stand_m3
wah ->waterverbruik_uur
Idealerwijze heb je dan ook geen commentaar meer nodig. Denk eraan, code wordt 100 maal meer gelezen (hoe had ik dat weeral gedaan) dan geschreven !
Flankdetectie kan ook zeer eenvoudig met een hulp variabele worden gedaan :
if((water_sensor==high)&(old_watersensor==low)) {watercount++);
old_watersensor=watersensor;Hier zal er geteld worden bij een opgaande flank. Omdat het in de loop gebeurt, moet het signaal wel langer actief zijn dan de tijd die de loop nodig heeft voor één doorgang !
Voor zeer korte signalen, kan je beter voor interrupts kiezen.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Ter info: Ik heb de python "wacht op flank" gebruikt om te wachten totdat ik op een knop druk. Als ik op die knop heb gedrukt dan moet er een scan gemaakt worden. (kan ook via het fontpaneel van de scanner, maar dan kost het 32 toetsaanslagen).
Het wachten op de flank in de loop is dus letterlijk wachten. Daar kwam ik achter toen de dagteller niet gereset werd. Dat betekent dat er heel veel uitgesloopt kon worden. Uiteindelijk heb ik alleen het aantal liters nodig om te uploaden naar PVoutput, de extended data. Daar gaat ook het gasverbruik naar toe en wat er actueel in huis verbruikt wordt.
@ RP6conrad:
Ik meen daar C-code te herkennen. Maar ik wil sowieso de opgaande flank niet gebruiken omdat die regelmatig valse spikes geeft. Zelfs nog als ik de IO pin rechtstreeks aan de nul leg middels een draadbrug. De neergaande flank vertoont die fratsen niet.
Ik heb i.i.g. geprobeerd de commentaren in het Python3 script zo duidelijk mogelijk te maken. Ik zag net ook dat de code tags of het tekstvenster van CO wat moeite had met de tabs. Kennelijk is in mijn editor Geany een tab 4 posities en op CO 10 o.i.d. Dus ik moest de ctrl-c-v effe handmatig corrigeren. 
@ rew: 
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Watermeter with LJ18A3-8-Z/BX - 5V detector on Elster/Honeywell e.d. V200 watermeter.
import OPi.GPIO as GPIO # IO pins acces for Python
GPIO.setmode(GPIO.BOARD) # set up BOARD Pin GPIO numbering
GPIO.setwarnings(False) # No more 'pin in use' errors
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Pin 5 set up as an input, pulled down on detection
f = open("/water/Liter", "r") # Read from Liter on startup
wa=float(f.read()) # Declare wa in liters and set counter to last value
f.close() # Close file reading
while True: # Run forever
GPIO.wait_for_edge(5, GPIO.FALLING) # Wait for pin 5 go to low
wa=wa+1 # If Pin 5 is going low add one liter to counter
f = open("/water/Liter", 'w') # open Liter file
f.write(str(wa)) # write new wa value to Liter file
f.close() # close Liter file
m3=round(float(wa)/1000, 3) # Calculate wa liters to metric volume
f = open("/water/M3", 'w') # open metric file
f.write(str(m3)) # write new metric value to metric file
f.close() # close metric file
pass