JeanLeGrand
Posts: 8
Joined: Fri Jan 19, 2018 11:28 pm

I2C / IOerror 24

Mon Aug 20, 2018 12:48 pm

I'm running a script to measure temperature using SHT31 (I2C sensor). It works fine for hours and hours (measuring almost every minute). And then out of the blue the following error.

Traceback (most recent call last):
File "anemometer1.py", line 144, in <module>
File "/usr/local/lib/python2.7/dist-packages/smbus_cffi-0.5.1-py2.7-linux-armv7l.egg/smbus/smbus.py", line 56, in __init__
File "/usr/local/lib/python2.7/dist-packages/smbus_cffi-0.5.1-py2.7-linux-armv7l.egg/smbus/smbus.py", line 83, in open
IOError: 24

The I restart the script everything works again without doing anything else. In the try / except IOError, I import smbus again, initiate it again and then continue with the rest op the script. but it always gives me this IOError n° 24.

Any solution ??

DirkS
Posts: 9871
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex, UK

Re: I2C / IOerror 24

Mon Aug 20, 2018 12:57 pm

That error indicates that you have too many open files, so I'm guessing your script is at fault...
Can you post your code (in code tags please)

JeanLeGrand
Posts: 8
Joined: Fri Jan 19, 2018 11:28 pm

Re: I2C / IOerror 24

Mon Aug 20, 2018 9:22 pm

Please find the code below

Code: Select all

import RPi.GPIO as GPIO
import time
import smbus
import json
    
GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)

GPIO.setup(14,GPIO.IN) # noodstop
GPIO.setup(27, GPIO.IN) # windmeting
GPIO.setup(22, GPIO.IN) # regenhoeveelheidmeting
GPIO.setup(21, GPIO.IN) # neerslagmeting
GPIO.setup(25, GPIO.OUT)
GPIO.setup(26, GPIO.OUT)
GPIO.setup(19, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(6, GPIO.OUT)
GPIO.setup(5, GPIO.OUT)
GPIO.setup(11, GPIO.OUT)

GPIO.output(25,False) # rode led
GPIO.output(26,True)
GPIO.output(19,True)
GPIO.output(13,True)
GPIO.output(6,True)
GPIO.output(5,True)
GPIO.output(11,True)


def sluitraam(raam):
    GPIO.output(26,False)
    GPIO.output(19,False)
    GPIO.output(raam,False)
    #print("Raam ",raam," toe om ",time.strftime("%H:%M:%S"))
    time.sleep(25)
    GPIO.output(raam,True)
    GPIO.output(26,True)
    GPIO.output(19,True)

def openraam(raam,tijd):
    GPIO.output(26,True)
    GPIO.output(19,True)
    GPIO.output(raam,False)
    #print("Raam ",raam," open om ",time.strftime("%H:%M:%S"))
    time.sleep(tijd)
    GPIO.output(raam,True)
    GPIO.output(26,True)
    GPIO.output(19,True)



            
global revcount
revcount = 0

def increaserev(channel):
    global revcount
    revcount += 1

global noodstop
noodstop = 0

def nood(channel):
    global noodstop
    nstop1 =GPIO.input(14)
    time.sleep(0.3)
    nstop2 =GPIO.input(14)
    if nstop1 == 0 and nstop2 == 0:
        noodstop += 1

raam_1 = False
raam_2 = False
raam_3 = False
raam_4 = False
    
global raincount
raincount = 0

raincountquarter = 0
numofhours = 0

def increaserain(channel):
    global raincount
    raincount += 1

global neerslagcount
neerslagcount = 0

    
GPIO.add_event_detect(22, GPIO.RISING, callback=increaserain)    
GPIO.add_event_detect(27, GPIO.RISING, callback=increaserev)
GPIO.add_event_detect(14, GPIO.RISING, callback=nood, bouncetime = 500)


printcounter = 0
vorige_neerslag = GPIO.input(21)
ramen_half = False

while True:
    try:
        # meting = int(time.strftime("%H"))
        maxrevcount = 0
        revcount = 0
        count = 0
        for i in range(0,6):
            GPIO.output(25,True) # rode LED aan
            time.sleep(5)
            GPIO.output(25,False) # rode LED uit
            time.sleep(5)
            if revcount >= maxrevcount:
                maxrevcount = revcount
            if maxrevcount > 100:
                count += 1
            revcount = 0
        windsnelheid = maxrevcount * 2.4 / 10
        printcounter += 1
    except:
        print('probleem met windmeting')

        
    try:
        # Get I2C bus
        bus = smbus.SMBus(1)

        # SHT31 address, 0x44(68)
        # Send measurement command, 0x2C(44)
        #              0x06(06)	High repeatability measurement
        bus.write_i2c_block_data(0x44, 0x2C, [0x06])
        time.sleep(0.1)
        # SHT31 address, 0x44(68)
        # Read data back from 0x00(00), 6 bytes
        # Temp MSB, Temp LSB, Temp CRC, Humididty MSB, Humidity LSB, Humidity CRC
        data = bus.read_i2c_block_data(0x44, 0x00, 6)
        # Convert the data SHT31
        tempSHT31A = data[0] * 256 + data[1]
        cTempSHT31A = -45 + (175 * tempSHT31A / 66550.0) # Was origineel 65535 --> correctie naar .......
        humiditySHT31A = 100 * (data[3] * 256 + data[4]) / 65535.0 
    except IOError:
        print('probleem met tempA meting --> soft reset SHT31', time.strftime("%D-%H:%M:%S"))
        import smbus
        bus = smbus.SMBus(1)
        bus.write_i2c_block_data(0x44, 0x30, 0xA2)
        time.sleep(0.5)


    neerslag = GPIO.input(21)
    
    if vorige_neerslag and not neerslag:     #neerslag = False ==> Regen
        begin_regen = True
    else:
        begin_regen = False
    vorige_neerslag = neerslag

    #try:
        # Store data & Output data to screen

    if printcounter == 15:
        # raincountquarter = raincount - raincountquarter
        regenhoeveelheid = raincount*0.2794
        raincount = 0
        printcounter = 0
            # print("Regenhoeveellheid is {0} mm/15min".format(raincountquarter*0.2794)," om ",time.strftime("%H:%M:%S"))
            # print("Temperature A in Celsius : %.2f C" %cTempSHT31A," om ",time.strftime("%H:%M:%S"))
            # print("Humidity : %.2f %%" %humiditySHT31A," om ",time.strftime("%H:%M:%S"))
            # print("Windsnelheid is %.2f km/h" %windsnelheid," om ",time.strftime("%H:%M:%S"))    
            # print("Count: ",count)
            # print("noodstop: ",noodstop)
            # print('')
            
        with open('/var/www/html/Serre-basis.json', 'r') as outfile:
            data = json.load(outfile)
            data['SERREBASIS'].append({  
                'time': time.strftime("%D-%H:%M:%S"),
                'Windsnelheid': windsnelheid,
                'Temperatuur': cTempSHT31A,
                'Vochtigheid': humiditySHT31A,
                'Regenhoeveelheid': regenhoeveelheid
            })
        with open('/var/www/html/Serre-basis.json', 'w') as outfile:
            json.dump(data, outfile)

            

    try:
        
        if cTempSHT31A >= 15 and cTempSHT31A <= 25 and windsnelheid  < 15:
            if not raam_1 and not raam_2 and not raam_3 and not raam_4 and neerslag:   #neerslag = False ==> Regen
                ramen_half = True
                GPIO.remove_event_detect(27)
                GPIO.remove_event_detect(14)
                GPIO.remove_event_detect(22)   
                openraam(5,15)
                raam_1 = True
                openraam(6,15)
                raam_2 = True
                openraam(11,15)
                raam_3 = True
                openraam(13,15)
                raam_4 = True
                GPIO.add_event_detect(27, GPIO.RISING, callback=increaserev)
                GPIO.add_event_detect(14, GPIO.FALLING, callback=nood, bouncetime = 500)
                GPIO.add_event_detect(22, GPIO.RISING, callback=increaserain)
                with open('/var/www/html/Serre-status.json', 'r') as outfile:
                    data = json.load(outfile)
                data['SERRESTATUS'].append({ 
                    'time': time.strftime("%D-%H:%M:%S"),
                    'Raam-1': 'Half-Open',
                    'Raam-2': 'Half-Open',
                    'Raam-3': 'Half-Open',
                    'Raam-4': 'Half-Open'
                })
                with open('/var/www/html/Serre-status.json', 'w') as outfile:
                    json.dump(data, outfile)

        if cTempSHT31A > 25 and windsnelheid  < 15:
            if ramen_half and neerslag:   #neerslag = False ==> Regen
                ramen_half = False
                GPIO.remove_event_detect(27)
                GPIO.remove_event_detect(14)
                GPIO.remove_event_detect(22)   
                openraam(5,15)
                raam_1 = True
                openraam(6,15)
                raam_2 = True
                openraam(11,15)
                raam_3 = True
                openraam(13,15)
                raam_4 = True
                GPIO.add_event_detect(27, GPIO.RISING, callback=increaserev)
                GPIO.add_event_detect(14, GPIO.FALLING, callback=nood, bouncetime = 500)
                GPIO.add_event_detect(22, GPIO.RISING, callback=increaserain)
                with open('/var/www/html/Serre-status.json', 'r') as outfile:
                    data = json.load(outfile)
                data['SERRESTATUS'].append({ 
                    'time': time.strftime("%D-%H:%M:%S"),
                    'Raam-1': 'Open',
                    'Raam-2': 'Open',
                    'Raam-3': 'Open',
                    'Raam-4': 'Open'
                })
                with open('/var/www/html/Serre-status.json', 'w') as outfile:
                    json.dump(data, outfile)

            if not ramen_half and not raam_1 and not raam_2 and not raam_3 and not raam_4 and neerslag:   #neerslag = False ==> Regen
                ramen_half = False
                GPIO.remove_event_detect(27)
                GPIO.remove_event_detect(14)
                GPIO.remove_event_detect(22)   
                openraam(5,30)
                raam_1 = True
                openraam(6,30)
                raam_2 = True
                openraam(11,30)
                raam_3 = True
                openraam(13,30)
                raam_4 = True
                GPIO.add_event_detect(27, GPIO.RISING, callback=increaserev)
                GPIO.add_event_detect(14, GPIO.FALLING, callback=nood, bouncetime = 500)
                GPIO.add_event_detect(22, GPIO.RISING, callback=increaserain)
                with open('/var/www/html/Serre-status.json', 'r') as outfile:
                    data = json.load(outfile)
                data['SERRESTATUS'].append({ 
                    'time': time.strftime("%D-%H:%M:%S"),
                    'Raam-1': 'Open',
                    'Raam-2': 'Open',
                    'Raam-3': 'Open',
                    'Raam-4': 'Open'
                })
                with open('/var/www/html/Serre-status.json', 'w') as outfile:
                    json.dump(data, outfile)


        
            
        if windsnelheid > 26 and count >=3 or noodstop >= 1 or begin_regen:
            if raam_1 and raam_2 and raam_3 and raam_4: 
                # print("begin van de regen: ", begin_regen)
                # print("noodstop: ", noodstop)
                # print("windsnelheid: ", windsnelheid, "  count: ", count)
                GPIO.remove_event_detect(27)
                GPIO.remove_event_detect(14)
                GPIO.remove_event_detect(22)
            
                sluitraam(5)
                raam_1 = False
                sluitraam(6)
                raam_2 = False
                sluitraam(11)
                raam_3 = False
                sluitraam(13)
                raam_4 = False

                noodstop = 0
            
                GPIO.add_event_detect(22, GPIO.RISING, callback=increaserain) 
                GPIO.add_event_detect(27, GPIO.RISING, callback=increaserev)
                GPIO.add_event_detect(14, GPIO.FALLING, callback=nood, bouncetime = 500)
                with open('/var/www/html/Serre-status.json', 'r') as outfile:
                    data = json.load(outfile)
                data['SERRESTATUS'].append({ 
                    'time': time.strftime("%D-%H:%M:%S"),
                    'Raam-1': 'Dicht',
                    'Raam-2': 'Dicht',
                    'Raam-3': 'Dicht',
                    'Raam-4': 'Dicht'
                })
                with open('/var/www/html/Serre-status.json', 'w') as outfile:
                    json.dump(data, outfile)


     
    except:
        print('Er was een error')
        #GPIO.cleanup()




        

DirkS
Posts: 9871
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex, UK

Re: I2C / IOerror 24

Mon Aug 20, 2018 9:46 pm

i see a lot of lines opening a file

Code: Select all

                with open('/var/www/html/Serre-status.json', 'w') as outfile:
but it doesn't seem to be closed at any time.
So you're running out of file handles.

JeanLeGrand
Posts: 8
Joined: Fri Jan 19, 2018 11:28 pm

Re: I2C / IOerror 24

Mon Aug 20, 2018 10:02 pm

Searching on how to close the json files, I found this article

https://stackoverflow.com/questions/365 ... -in-python

JeanLeGrand
Posts: 8
Joined: Fri Jan 19, 2018 11:28 pm

Re: I2C / IOerror 24

Mon Aug 20, 2018 10:03 pm

It seems there is no real need to close them ??

In addition the script only uses two files which are updated frequently

maurice1
Posts: 37
Joined: Tue Mar 05, 2013 8:55 am
Location: Dublin

Re: I2C / IOerror 24

Wed Aug 22, 2018 7:23 am

Hi Jean,
Here is an idea for a Band-aid which should at least get you an approx time of when your script fails and restarts it.

Make a script /home/pi/nohupstart.sh
Copy code below into /home/pi/nohupstart.sh
Edit Crontab with */3 * * * * sh /home/pi/nohupstart.sh
Restart Cron

Check you can send an email from putty

Code: Select all

#!/bin/bash
#check if abc is running


#Edit  Crontab with */3 * * * * sh /home/pi/nohupstart.sh



if pgrep -f "[F]ireRead2" >/dev/null 2>&1
  then
	echo FireRead2 is running
  else
	echo Trying to starting fileread2
	nohup python /home/pi/FirePanel/FireRead2.py >/dev/null 2>&1 &
	echo $! > /home/pi/FirePanel/save_pid.txt
	echo " FireRead2 starting" | mail -s " FireRead2 restarted $(date) " me@eircom.net
	echo Run FireRead2 again
fi	
Hope this helps.

JeanLeGrand
Posts: 8
Joined: Fri Jan 19, 2018 11:28 pm

Re: I2C / IOerror 24

Wed Aug 22, 2018 7:40 am

Thanks Maurice, will try it out.

Meanwhile I've added "outfile.close()" commands every time a "while open(....." is started - and still no result.

the program still crashes here :
try:
# Get I2C bus
bus = smbus.SMBus(1)

# SHT31 address, 0x44(68)
# Send measurement command, 0x2C(44)
# 0x06(06) High repeatability measurement
bus.write_i2c_block_data(0x44, 0x2C, [0x06])
time.sleep(0.1)
# SHT31 address, 0x44(68)
# Read data back from 0x00(00), 6 bytes
# Temp MSB, Temp LSB, Temp CRC, Humididty MSB, Humidity LSB, Humidity CRC
data = bus.read_i2c_block_data(0x44, 0x00, 6)
# Convert the data SHT31
tempSHT31A = data[0] * 256 + data[1]
cTempSHT31A = -45 + (175 * tempSHT31A / 66550.0) # Was origineel 65535 --> correctie naar .......
humiditySHT31A = 100 * (data[3] * 256 + data[4]) / 65535.0
except IOError:
print('probleem met tempA meting --> soft reset SHT31', time.strftime("%D-%H:%M:%S"))
import smbus
bus = smbus.SMBus(1)
bus.write_i2c_block_data(0x44, 0x30, 0xA2)
time.sleep(0.5)
Where there is up to my knowledge no IO to a any file done. Just writing a command to the I2C bus and reading the result back from the I2C bus. Or should communication towards the I2C bus be closed as well ?? Never saw this before.

User avatar
joan
Posts: 14073
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C / IOerror 24

Wed Aug 22, 2018 9:15 am

JeanLeGrand wrote:
Wed Aug 22, 2018 7:40 am
...
Where there is up to my knowledge no IO to a any file done. Just writing a command to the I2C bus and reading the result back from the I2C bus. Or should communication towards the I2C bus be closed as well ?? Never saw this before.
The earlier comment was probably correct, too many open files. But as you seem to have identified the files are the SMBus connection.

Personally I would open SMBus just once at the start of the script. If you open it within a loop then you also need to close it in the loop. Otherwise you will run out of file descriptors.

DirkS
Posts: 9871
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex, UK

Re: I2C / IOerror 24

Wed Aug 22, 2018 9:32 am

I would also take out the the superfluous 'import smbus' in the except block.
Don't think it causes errors, but it cleans up the code a bit.

JeanLeGrand
Posts: 8
Joined: Fri Jan 19, 2018 11:28 pm

Re: I2C / IOerror 24

Fri Aug 24, 2018 11:03 am

Problem is solved !!

the initialisation of the smBus, works in a similar way as a file handler and consumes resources from the RPi. So it is advisable to put bus initialisation commands outside any loop in your scripts or use the close function inside the loop.

Thanks to everybody

Idahowalker
Posts: 445
Joined: Wed Jan 03, 2018 5:43 pm

Re: I2C / IOerror 24

Fri Aug 24, 2018 11:41 am

Using a MPU6050 I, on occasion, once a week - at most, get the same error. To solve the issue, I made a class cMPU6050 and I use the class methods is accessed once a second. The cMPU6050 object oMPU sits in a try:/execpt/finally: block. One of the lines in the except: block sets oMPU = None. In the try: block I have

Code: Select all

if (oMPU is None):
    oMPU = cMPU6050.cMPU6050()
    
that instantiates, a restart, the class in case there was a fault.
Without knowing why you are deleting my postings, I will not know how...

Return to “Python”