False readings from Digital ports

That traceback you’ve put up there doesn’t seem to be complete. Anyhow, when updating the package in RFR_Tools/miscellaneous, did you make sure you were on my specific branch? That is the hotfix/sw_i2c_on_hw branch.

And just a couple of minutes ago, the patch for this issue has been merged into the master branch of the official repo, so running curl -kL dexterindustries.com/update_grovepi | bash again should fix all problems. Can you try that and see if it fixes it?

And also, other I2C devices will also work side-by-side with the GrovePi. You only have to make sure they don’t attempt to communicate over I2C at the same time.

Thank you!

Hi, RobertLucian,

Thanks for the hard work. I installed curl -kL dexterindustries.com/update_grovepi | bash as recommended,

The update works to a point but sadly it does appear that some of my 12c devices/sensors together without causing errors for example

/Dexter/GrovePi/Software/Python/grove_i2c_temp_hum_hdc1000 $ sudo python3 grove_hdc_1000_example.py

Temp : 13.06 C

Humidity: 100.00 %

-----------------

Temp : 14.35 C

Humidity: 99.61 %

-----------------

No ACK!

Traceback (most recent call last):

File "grove_hdc_1000_example.py", line 44, in <module>

print('Temp : %.2f C' % hdc.Temperature())

TypeError: a float is required

Since I am running two scripts at the same time both use 12c with switchdoclabs/Adafruit drivers and devices.

These do not use CircuitPython.

The drivers are

Adafruit_Python_ADS1x15

Adafruit_Python_BMP280

Adafruit_Python_GPIO

Adafruit_Python_PureIO

And these devices

SDL_DS3231

I2C FRAM.

All of these worked with the GrovePi until the recent changes.

You state in your email ‘make sure they don’t attempt to communicate over I2C at the same time’, is the way of doing this, as both scripts could be calling devices at the similar times.

Have you any advice as to how this could be fixed.

Regards Michael

You state in your email ‘make sure they don’t attempt to communicate over I2C at the same time’, is the way of doing this, as both scripts could be calling devices at the similar times.

Yes, exactly. You cannot have 2 processes running at the same time and trying to access the same device. I’m pretty sure this didn’t work even before.

Can you try using mutexes around each sensor that you are using?

We have a library that we wrote specifically for this type of problems here, although I’m pretty certain you can find others / (other tutorials) on the web for it:

The benefit of our module called dexter_mutex.py is that it already gets installed with the GrovePi, so that’s one less thing to think about. And it’s also reliable - there aren’t any bugs with it.

Thank you!

Hi RobertLucian,

Thankyou for your suggestion regarding python mutex, I will look in tro it and have a play.

How ever I may havr been a little misleading it my last email.

The two pythom3 scripts may bay be running at the together each with a 5 second while loop.
The first script runs my weather station and has a 5 second while loop that reads a number of 12c devices on after each other.
and include a BMP280, HDC1000, SI1145, TSL2561 all of which are 12c.

The second script reads which is runs the weather vane monitors a anemometer socket connected to D4. and rain bucket on D3 both are magnetic switch these are in a continious while loop and reads the switchs with a delay of 'time.sleep (0.4), for each cycle. if a connection is made a led lights connected to D8.
After 5 seconds an ADC ADS1115 measures wind direction.

I am sending the two scripts hoping they help.

Regards Michael

weather_vane_v1.4e.py (12.0 KB)
weather_station_v1.57a.py (28.3 KB)

Hi RobertLucian,

Unfortuntatly I have not been able to figue out how to use mutex.py, despite trying to readup about it on the net. Sadly it is very much above coding skills.

Did you take a look at the two scripts I sent you and have they given you any clue, what may be going wrong. I notice that you use Adafruit_I2C.py, could this be one cause?

Sadly I clutching t straws for ideas !!!

Regards Michael

I think you might be better off running everything from the same Python process.

You could get away with making threads for each of your sensor or application and then use the mutexes that come with Python to synchronize them properly. Here’s what you have to use:
https://docs.python.org/3/library/threading.html#threading.Lock

And we don’t use the Adafruit_I2C.py. This is an old module that we keep it in there for historical reasons. We are now only using the di_i2c.py and di_mutex.py modules.

Let me know if you get to somewhere.

Thank you!

I took a look at you suggestion and did some research.

How would this work since I am running two seprate python3 scripts at the same time, the weather_vane feeding the weather-station via a json file.

Michael

That’s what I’m saying: merge the 2 applications together and use locks around the I2C devices. Every application would probably go in a thread of its own. This is how I’m imagining it.

This is the alternative to using the di_mutex.py module for mutexing the devices while having different processes. Personally, I’d have used the di_mutex module - I find it more versatile. If you still want to give that a shot, I’d suggest you look at our source code - primarily the source code in di-sensors repo: https://github.com/DexterInd/DI_Sensors.

Cheers! :slight_smile:

Thank s the advice, one of the reasons for having th two scripts was because of timing issues, say thay I will try to merge parts of the scripts to see what happens. I’m not sue I fully understand yet how dl-mutex works, but I will give it a try.

I notice that at pressent there is not a grove python2/3 version of BMP280 sensor. Do you have one any were you can send me?

Many Thanks Michael

I have spent many happy hours trying to solve the problem(s).

Firstly many of the Grove/ Seeed studio do use the Adafruit 12c libraries, sbus etc. Adrafruit has updated them to updated to use CircuitPython.

And since your last updates have caused these to create errors when using multiple scripts. I have tried to merge the two scripts and that caused even more problems, not least with timing.

Looking at mutex I not been able to findout easesly how to us it, and need a large a rewriteof my scripts and grove12c drivers to work. Both of which beyond my programming skills.

I sure that others may have or soon have simular problems.

I would be grateful for any solution you may have.

Michael

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: