2blackeyes
Posts: 11
Joined: Sun Feb 26, 2017 12:58 am

[SOLVED] "Segmentation fault" running a Python3 script

Sat Mar 14, 2020 2:04 pm

Hoping someone can tell me what's wrong with my code (referring the the third block of code below, at the bottom of this post) - I am guessing it's a syntax error because until I started editing the code, the script ran without issue, but now I get "Segmentation fault", when running 'Sudo pythong3 script.py'.

For context, I have a ratio-controller Pi HAT, which is used to operate a remote-power-socket. In addition, I have a temp/humidity sensor wired into the Pi. The idea being, when temp is greater than threshold, the fan (plugged into remote-power-socket) kicks on. When temp drops, it turns off.

I have sort of mashed up the following two scripts, to try get where I am trying to go.

EDIT (15/MAR) - move to bottom page.

This first one is meant to do what I want, in its entirety. But, only the temp/humidity reading + forward readings to web-server parts of it work. This because the the part that operates the Pi HAT that talks to the remote-power-board, is for a different Pi HAT to the one I have):

Code: Select all

#!/usr/bin/python3
 
# monitor.py - For Terrarium Controllers using Adafruit
# DHT sensors, Energenie Pimote sockets, and ThingSpeak.
# MIT license.
# https://www.carnivorousplants.co.uk/resources/raspberry-pi-terrarium-controller/
 
# Imports
from gpiozero import Energenie
import Adafruit_DHT
import requests
 
# Attempt to get a sensor reading. The read_retry method will
# retry up to 15 times, waiting 2 seconds between attempts
sensormodel = Adafruit_DHT.AM2302
sensorpin = 4
humidity, temperature = Adafruit_DHT.read_retry(sensormodel, sensorpin)
 
# If either reading has failed after repeated retries,
# abort and log message to ThingSpeak
thingspeak_key = 'XXXXXXXXXXXXXXXX'
if humidity is None or temperature is None:
    f = requests.post('https://api.thingspeak.com/update.json', data = {'api_key':thingspeak_key, 'status':'failed to get reading'})
 
# Otherwise, check if temperature is above threshold,
# and if so, activate Energenie socket for cooling fan
else:
    fansocket = 1
    tempthreshold = 28
 
    if temperature > tempthreshold:
        # Activate cooling fans
        f = Energenie(fansocket, initial_value=True)
 
    else:
        # Deactivate cooling fans
        f = Energenie(fansocket, initial_value=False)
 
    # Send the data to Thingspeak
    r = requests.post('https://api.thingspeak.com/update.json', data = {'api_key':thingspeak_key, 'field1':temperature, 'field2':humidity})
    

This second one operates both types of Pi HATs (the one I do and and the one I don't). You'll see in there it's split into two sections. Purple On and Green On. So running through this script just cycles through both types, but only the Green On works for my gear (and it does work.)

Code: Select all

# combined.py  15/05/2016  D.J.Whale
#
# A simple demo of combining both FSK (MiHome) and OOK (green button legacy)
#
# NOTE: This is only a test harness.
# If you really want a nice way to control these devices, wait for the 'device classes'
# issues to be implemented and tested on top of the raw radio interface, as these
# will be much nicer to use.
 
import time
from energenie import Messages, OpenThings, radio, encoder, Devices
 
# build FSK messages for MiHome purple
 
OpenThings.init(Devices.CRYPT_PID)
 
PURPLE_ID = 0x68B # captured from a real device using Monitor.py
m = OpenThings.alterMessage(
    Messages.SWITCH,
    header_sensorid=PURPLE_ID,
    recs_0_value=1)
purple_on = OpenThings.encode(m)
 
m = OpenThings.alterMessage(
    Messages.SWITCH,
    header_sensorid=PURPLE_ID,
    recs_0_value=0)
purple_off = OpenThings.encode(m)
 
# build OOK messages for legacy green button
 
GREEN_ON  = encoder.build_switch_msg(True, device_address=1)
GREEN_OFF = encoder.build_switch_msg(False, device_address=1)
 
def switch_loop():
    print("Turning green ON")
    radio.modulation(ook=True)
    radio.transmit(GREEN_ON)
    time.sleep(0.5)
 
    print("Turning purple ON")
    radio.modulation(fsk=True)
    radio.transmit(purple_on, inner_times=2)
    time.sleep(2)
 
    print("Turning green OFF")
    radio.modulation(ook=True)
    radio.transmit(GREEN_OFF)
    time.sleep(0.5)
 
    print("Turning purple OFF")
    radio.modulation(fsk=True)
    radio.transmit(purple_off, inner_times=2)
    time.sleep(2)
 
if __name__ == "__main__":
 
    print("starting combined switch tester")
    print("radio init")
    radio.init()
 
    try:
        while True:
            switch_loop()
 
    finally:
        radio.finished()
 
# END

So if all that makes sense, hopefully you can see what I've tried to do in the third one below - get (1) the the temp/humidity reading + push reading to web-server from the first scrip, and (2) getting the 'Green On' parts from the second script, to operate the hardware (based on some if/else decisions).

Code: Select all

from gpiozero import Energenie
from energenie import radio, encoder
import requests
import Adafruit_DHT

fansocket = 1
tempthreshold = 20
sensormodel = Adafruit_DHT.AM2302
sensorpin = 26
humidity, temperature = Adafruit_DHT.read_retry(sensormodel, sensorpin)
fansocket_on  = encoder.build_switch_msg(True, device_address=1)
fansocket_off = encoder.build_switch_msg(False, device_address=1)
thingspeak_key = 'SUPERSECRETAPIKEY'

if humidity is None or temperature is None:
	f = requests.post('https://api.thingspeak.com/update.json', data = {'api_key':thingspeak_key, 'status':'failed to get reading'})
else:
	if temperature > tempthreshold:
		radio.modulation(ook=True)
		radio.transmit(fansocket_on)
	else:
		radio.modulation(ook=True)
		radio.transmit(fansocket_off)
		r = requests.post('https://api.thingspeak.com/update.json', data = {'api_key':thingspeak_key, 'field1':temperature, 'field2':humidity})

EDIT

OK, so I've got a little further. I've cut down the Pi HAT/power-board switcher to the below. All it does is switch the first socket on and off in an infinite loop (But the important bit it, it works). Now all I need to do is work the conditions in from the temp/humidity/push to server script, so that it switches on when above X temp, and off when it's below X temp. I have no idea how to mash the two - they're different languages by the looks?

Code: Select all

from energenie import radio, encoder

GREEN_ON  = encoder.build_switch_msg(True, device_address=1)
GREEN_OFF = encoder.build_switch_msg(False, device_address=1)

def switch_loop():
    radio.modulation(ook=True)
    radio.transmit(GREEN_ON)

    radio.modulation(ook=True)
    radio.transmit(GREEN_OFF)

if __name__ == "__main__":

    print("starting combined switch tester")
    print("radio init")
    radio.init()

    try:
        while True:
            switch_loop()

    finally:
        radio.finished()
Last edited by 2blackeyes on Sun Mar 15, 2020 10:23 am, edited 2 times in total.

Heater
Posts: 15838
Joined: Tue Jul 17, 2012 3:02 pm

Re: "Segmentation fault" running a Python3 script

Sat Mar 14, 2020 5:48 pm

You have not shown us the actual error message you are getting there. How is anyone supposed to help without knowing what the failure is.

Unless something is up with Python itself it is most likely that a segfault is occurring in some module you are using, which is likely written in C or C++.

Normally syntax errors and such in Python result in an almost sensible error message, not a segfault.
Memory in C++ is a leaky abstraction .

2blackeyes
Posts: 11
Joined: Sun Feb 26, 2017 12:58 am

Re: "Segmentation fault" running a Python3 script

Sat Mar 14, 2020 10:53 pm

The actual error is "Segmentation fault". There's no more information in Terminal once I make the run call. It just returns "Segmentation fault'...

EDIT:

Re-running this morning after another reboot, I now get the following when I run 'sudo python3 script.py'

Code: Select all

warning: method is untested:<function receive_len at 0x7647f348>
Segmentation fault

pifan5
Posts: 1
Joined: Sat Mar 14, 2020 11:12 pm

Re: "Segmentation fault" running a Python3 script

Sat Mar 14, 2020 11:15 pm

Try running another Python script, or just typing "python" to access the interactive shell. It seems somethings wrong with the installation of Python

2blackeyes
Posts: 11
Joined: Sun Feb 26, 2017 12:58 am

Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 1:43 am

pifan5 wrote:
Sat Mar 14, 2020 11:15 pm
Try running another Python script, or just typing "python" to access the interactive shell. It seems somethings wrong with the installation of Python
Thanks, but nothing wrong with Python. Scripts run fine as does the shell.

Garvan
Posts: 41
Joined: Sun Jan 05, 2020 9:59 am

Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 6:43 am

A segmentation fault is a memory error, you are accessing (reading or writing) an un-initialized function or memory address. Normally in this case you will go through your code commenting out one line at a time, until you find our which line is causing the error. You might insert print statements to narrow down the location. When you find the line of code causing the memory error, you have someplace to start in looking for the cause.

I have no idea how your sensors work, or what your code does. Is it only the third script that fails? Where is radio.init()?

PS: You are editing your post at the same time as I am replying. I will come back later to see if you got it working.

2blackeyes
Posts: 11
Joined: Sun Feb 26, 2017 12:58 am

Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 6:55 am

Garvan wrote:
Sun Mar 15, 2020 6:43 am
A segmentation fault is a memory error, you are accessing (reading or writing) an un-initialized function or memory address. Normally in this case you will go through your code commenting out one line at a time, until you find our which line is causing the error. You might insert print statements to narrow down the location. When you find the line of code causing the memory error, you have someplace to start in looking for the cause.

I have no idea how your sensors work, or what your code does. Is it only the third script that fails? Where is radio.init()?

PS: You are editing your post at the same time as I am replying. I will come back later to see if you got it working.
Thanks for your response!

Short answer is, I'm very new to coding. I can sort of read/decipher the basic stuff, but when it starts pulling in various libraries and missing languages, I'm lost.

radio.int() - I can't say for sure, but the top of the script appears to import 'radio' from 'energenie'. But I know the EDIT script, at the bottom of the original post, doesn't work when I comment out radio.int().

This is all in an attempt to adapt this guide (https://www.carnivorousplants.co.uk/res ... ontroller/), as I have slightly different hardware than the writer (different PiHAT and remote powerboard).

Garvan
Posts: 41
Joined: Sun Jan 05, 2020 9:59 am

Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 9:01 am

I find it difficult to tell what is working and what is not working, so forgive the silly questions.

Does this work?

Code: Select all

# Imports
import Adafruit_DHT
 
# Attempt to get a sensor reading. The read_retry method will
# retry up to 15 times, waiting 2 seconds between attempts
sensormodel = Adafruit_DHT.AM2302
sensorpin = 4
humidity, temperature = Adafruit_DHT.read_retry(sensormodel, sensorpin)
print (humidity)
print(temperature)

and does this work?

Code: Select all

from energenie import radio, encoder

GREEN_ON  = encoder.build_switch_msg(True, device_address=1)
GREEN_OFF = encoder.build_switch_msg(False, device_address=1)

def switch_loop():
    radio.modulation(ook=True)
    radio.transmit(GREEN_ON)

    radio.modulation(ook=True)
    radio.transmit(GREEN_OFF)

if __name__ == "__main__":

    print("starting combined switch tester")
    print("radio init")
    radio.init()

    try:
        while True:
            switch_loop()

    finally:
        radio.finished()

2blackeyes
Posts: 11
Joined: Sun Feb 26, 2017 12:58 am

Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 9:28 am

Garvan wrote:
Sun Mar 15, 2020 9:01 am
I find it difficult to tell what is working and what is not working, so forgive the silly questions.

Does this work?
etc...
Sorry - my fault - my post it quite messy.

Most of this works. The sensor reading parts works and then the push to ThingSpeak webserver (the "# Send the data to Thingspeak" comments) works. But the parts in there that activate the sockets ( the "# Activate cooling fans" and "# Deactivate cooling fans" comments) don't work because they are assuming I have a different (newer PiHAT).

Code: Select all

#!/usr/bin/python3
 
# monitor.py - For Terrarium Controllers using Adafruit
# DHT sensors, Energenie Pimote sockets, and ThingSpeak.
# MIT license.
# https://www.carnivorousplants.co.uk/resources/raspberry-pi-terrarium-controller/
 
# Imports
from gpiozero import Energenie
import Adafruit_DHT
import requests
 
# Attempt to get a sensor reading. The read_retry method will
# retry up to 15 times, waiting 2 seconds between attempts
sensormodel = Adafruit_DHT.AM2302
sensorpin = 4
humidity, temperature = Adafruit_DHT.read_retry(sensormodel, sensorpin)
 
# If either reading has failed after repeated retries,
# abort and log message to ThingSpeak
thingspeak_key = 'XXXXXXXXXXXXXXXX'
if humidity is None or temperature is None:
    f = requests.post('https://api.thingspeak.com/update.json', data = {'api_key':thingspeak_key, 'status':'failed to get reading'})
 
# Otherwise, check if temperature is above threshold,
# and if so, activate Energenie socket for cooling fan
else:
    fansocket = 1
    tempthreshold = 28
 
 if temperature > tempthreshold:
        # Activate cooling fans
        f = Energenie(fansocket, initial_value=True)
 
   else:
        # Deactivate cooling fans
        f = Energenie(fansocket, initial_value=False)
 
    # Send the data to Thingspeak
    r = requests.post('https://api.thingspeak.com/update.json', data = {'api_key':thingspeak_key, 'field1':temperature, 'field2':humidity})
And then yes - this codes (which I stripped out all the irrelevant parts from the original long-form one, works to control the radio-power-sockets.

Code: Select all

from energenie import radio, encoder

GREEN_ON  = encoder.build_switch_msg(True, device_address=1)
GREEN_OFF = encoder.build_switch_msg(False, device_address=1)

def switch_loop():
    radio.modulation(ook=True)
    radio.transmit(GREEN_ON)

    radio.modulation(ook=True)
    radio.transmit(GREEN_OFF)

if __name__ == "__main__":

    print("starting combined switch tester")
    print("radio init")
    radio.init()

    try:
        while True:
            switch_loop()

    finally:
        radio.finished()
So I am trying to mesh the two. but've had no luck so far. Been looking at how to write C if/then statements (because I'm guessing that's what the second script is written in, though I can actually run it in a python shell...) but keep running into syntax errors. NFI what I'm doing.

Garvan
Posts: 41
Joined: Sun Jan 05, 2020 9:59 am

Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 9:36 am

Ok. I recommend holding the web code until you get the sensor and switches working.

Code: Select all

# Imports
import Adafruit_DHT
from energenie import radio, encoder
 
sensormodel = Adafruit_DHT.AM2302
sensorpin = 4
tempthreshold = 20

GREEN_ON  = encoder.build_switch_msg(True, device_address=1)
GREEN_OFF = encoder.build_switch_msg(False, device_address=1)

def switch_loop():
	if temperature > tempthreshold:
		radio.modulation(ook=True)
		radio.transmit(GREEN_ON)
		time.sleep(0.5)
	else:
		radio.modulation(ook=True)
		radio.transmit(GREEN_OFF)
		time.sleep(0.5)

if __name__ == "__main__":

    print("starting combined switch tester")
    print("radio init")
    radio.init()

    try:		
        humidity, temperature = Adafruit_DHT.read_retry(sensormodel, sensorpin)
        if humidity is None or temperature is None:
            print ("Error getting humidity & temperature") 
        else:
            switch_loop()

    finally:
        radio.finished()

2blackeyes
Posts: 11
Joined: Sun Feb 26, 2017 12:58 am

Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 9:45 am

Garvan wrote:
Sun Mar 15, 2020 9:36 am
Ok. I recommend holding the web code until you get the sensor and switches working.
code...
I get the following , after it hangs for about 10 seconds.

Code: Select all

warning: method is untested:<function receive_len at 0x765f5bb8>
starting combined switch tester
radio init
Error getting humidity & temperature

EDIT - disregard. It works! (I had the wrong sensor pin number).

You, sir. Are a scholar and a gent. Thank you very much!

How might we get the ThingSpeak part back in now?

Garvan
Posts: 41
Joined: Sun Jan 05, 2020 9:59 am

Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 10:11 am

Do you have a "thingspeak_key"? You could push the results in the try section for testing, and when you have it working, adjust to your liking.

Code: Select all

    thingspeak_key = 'XXXXXXXXXXXXXXXX'
    
    try:		
        humidity, temperature = Adafruit_DHT.read_retry(sensormodel, sensorpin)
        if humidity is None or temperature is None:        
            f = requests.post('https://api.thingspeak.com/update.json', data = {'api_key':thingspeak_key, 'status':'failed to get reading'})
        else:
            switch_loop()
            r = requests.post('https://api.thingspeak.com/update.json', data = {'api_key':thingspeak_key, 'field1':temperature, 'field2':humidity})
    

2blackeyes
Posts: 11
Joined: Sun Feb 26, 2017 12:58 am

[SOLVED] Re: "Segmentation fault" running a Python3 script

Sun Mar 15, 2020 10:21 am

Garvan wrote:
Sun Mar 15, 2020 10:11 am
Do you have a "thingspeak_key"? You could push the results in the try section for testing, and when you have it working, adjust to your liking.
I do indeed, and that's worked perfectly.

Thank you again! You've saved me countless hours/days/weeks. Cheers!

Return to “Python”