False readings from Digital ports

Can you go and check the following class implementation?

If you investigate and try to understand the above module, then you will know how to implement your own solution. Just look at what I did with the ifMutexAcquire and ifMutexRelease functions.

Note: the 2 functions ifMutexAcquire and ifMutexRelease are just some lazy solutions to do mutex around the line follower in this case. Generally, I’d have gone with what’s in di_mutex.py, but since we used the above functions from ever since, the incentive to change that is rather low, since it would break the consistency across most of our modules. The bottom line is that it doesn’t affect the user and we can always do it later on.

Let me know if you now know how to do it.

Thank you!

Thanks for your help.

Sadly its just hard for me to understand.
Fistly I do not have a line follower.
I am trying to create my own BMP280 driver and reader scripts by looking at the BME280 Drivers in that collection.
I notice that you do not have a python version of the BMP280 in the Dextor GrovePi library.
Also what is happening the the Grovepi, as there is no reference to in the Dl-Sensors.
I purchased my Grovepi(s) because they was fairly easy to programme and easy to use.

Are you moving away from the Grove pi in favour of something else?

I not sure I will ever be able to work it out, unless there are some simple examples for people like me to follow.
I have another try over the weekend, but do hold much hope of ahaving any success.

Sory for my last email I may have got confused just how the Grove Pi works.
Am I correct in thinking that 12c sensors do not totally rely on Grove Drivers?
Also am I write in thinking that the digital and analog ports do?
What I have found that for reason recent updates to either the Raspberry pi or Grovepi have the grove ports not to like being used at the same time as 12c devices. Or in some way cause each other tho create a error.

I have merged my two weather station programs into one.

you will notice that thare are two processes

  1. Process(target=station.timer_loop).start() , this collects data from my sensors (mostly 12c) ever 5 seconds

  2. Process(target=station.read_vane).start(), this reads pulses fron an anemometer, and rainbucket, both of which have magnetic switches.
    These are constantly being monitored using while loop to pulses to get wind speed and rain fall.
    Its this section of the program that causes 12c devices to fail. This never happened before recent updates.

You will see that I have disabled, and have found the progam works, when enabled it fails.

I’m not sure if there is much I can do about the problem, and if even locks or mutex would help.

I hope this info may help
Thanks

sorry forget to post scriptweather-station-v2.01c.py (11.2 KB)

Yeah, and therein lies the problem. Let me show you an example program with locks in Python. The following program runs for 10 seconds and while it’s running analog port 0 is being read and an LED is being blinked on digital port 2. I’m also using an Event object to bring both threads to an end after those 10 seconds have elapsed.

from grovepi import *
from threading import Thread, Lock, Event
from time import sleep

i2c_lock = Lock()
stopper = Event()

def printingAnalogSensor():
    while not stopper.is_set():

        i2c_lock.acquire()
        value = analogRead(0)
        i2c_lock.release()

        print(value)
        sleep(0.1)

def blinkingLED():
    state = 0
    while not stopper.is_set():

        i2c_lock.acquire()
        digitalWrite(2, state)
        i2c_lock.release()

        state = 1 if state == 0 else 0
        sleep(0.5)

if __name__ == "__main__":
    t1 = Thread(target=printingAnalogSensor)
    t2 = Thread(target=blinkingLED)

    sleep(10)

    stopper.set()
    t1.join()
    t2.join()

I haven’t tested the code, but I think it should work.

Another thing I can say about your implementation is that you really don’t need to fire up different processes for what you actually need. Threads will be more than enough for your application, plus they are much more easy to handle than processes.

Good luck! :slight_smile:

1 Like

Thanks for your suggestion.

How would this work, if I was running a continous loop that reads two digital ports with magnetic switches constanly count pulses to get wind speed and rain. with out stopping it.

Or would the lock only need to be on the function reading the 12c sensors?

see below

def read_vane(self):
	print("Wind Loop Running", self.Software_Version)
	
	while True:
		
		start_time = time.time()
		max_time = start_time + 5
		false_rain = start_time + 1
		spin_distance = 0
		adjustment = 1.18  # Adjustment for weight of cups
		wind_trigger = 0
		rain_trigger = 0
		bucket_tip = 0
		spin_delay = 0.04
		while time.time() <= max_time:
			
			if grovepi.digitalRead(anemometer) == 1 and wind_trigger == 0:  # Read Anemometer D7
				spin_distance += 28.2743 / 12.5  # cm
				wind_trigger = 1
				digitalWrite(red_led, 1)
			if grovepi.digitalRead(rain_tipper) == 1 and rain_trigger == 0:  # Read rain Bucket D8
				bucket_tip = 1
				rain_trigger = 1
			time.sleep(spin_delay)
			if time.time() <= false_rain:
				bucket_tip = 0
				rain_trigger = 1
			if grovepi.digitalRead(anemometer) == 0 and wind_trigger == 1:  # Read Anemometer D7
				wind_trigger = 0
			if grovepi.digitalRead(rain_tipper) == 0 and rain_trigger == 1:  # Read rain Bucket D8
				rain_trigger = 0
			digitalWrite(red_led, 0)
			
		self.elapsed = round(time.time() - start_time, 5)
		mps = round(((spin_distance / self.elapsed) * adjustment), 2)

Probally what needed is a multi channel 12c counter to count pulses, that could accessed when needed.

Hi All,

Just to let you know that I have been playing with my script and have tried to used mutex.
How ever much I tried I still keep getting all these errors:

OSError: [Errno 5] Input/output error
TypeError: type NoneType doesn’t define round method

when triying to two continous loop that read mutliple 12c sensors and grovepi digital or analog ports

is there any solution?

Michael

You might be better off using this function, although, unfortunately, you can only set up one at a time. I might have a look at the firmware’s source code and see if I can make 2 of them run at the same time - it should.

The lock has to be wrapped around every call to any I2C resource, just like I did in my example.

Have you tried adding every call you need incrementally to the script I have provided you? And gradually test it until everything works?

Thank you!

Hi,
Thanks for your reply.

I will try out your suggestion regarding locks and work through the sensors using locks.

I have a few other ideas which I am testing at this moment in time, and it appears to be working for now.

Meantime I’m trying to understand and learn mutex and locks.

Michael

That’s great to hear that! Challenges are always awesome! Well, almost all the time, hehe! :smiley: