Connect units to PbHUB
-
I am trying to connect a
LIGHTand anEARTHunit to thePbHUB. I connected thePbHUBtoPortA, theEARTHsensor toHub 0and theLIGHTsensor toHub 1.
My code looks like this:
pbhub = unit.get(unit.PBHUB, unit.PORTA) earth = pbhub.analogRead(0x00) light = pbhub.analogRead(0x01)I am able to read values from both sensors, however with strange behaviours. E.g. the lux value increases when it gets darker and vice versa. I guess the problem is, that I am lacking the logic of the
analogReadfunction in theLIGHTandEARTHunits:
https://github.com/m5stack/UIFlow-Code/blob/a0dbef98fe29323d6b1837b479764fdab50c3836/units/_light.py
https://github.com/m5stack/UIFlow-Code/blob/a0dbef98fe29323d6b1837b479764fdab50c3836/units/_earth.pyHowever I do not see how I would have to connect this unit correctly to the
PbHUB. Do I have to copy paste theanalogReadlogic or is there another way to connect these units?
@ajb2k3 Do you know how this should be handled? -
Hey I made a video on the PBHUB https://www.youtube.com/watch?v=NG9SBKfxX5w maybe it can help you. Often when I want to write some micropython code I make it in Uiflow first. Since the micropython documentation is lacking this is a good way to find out what might be missing from your code and what the micropython commands you need are.
-
@maechler You caught me here at a loss. Check out @lukasmaximus video on youtube.
-
@lukasmaximus @ajb2k3 Thanks for your support! Although the video does not really answer my question.
I am able to read values from the PbHUB like this:
pbhub = unit.get(unit.PBHUB, unit.PORTA) earth = pbhub.analogRead(0x00) light = pbhub.analogRead(0x01)The problem is, that these values seem to be wrong. The lux value increases when it gets darker, similarly the earth unit says the earth gets dryer when it actually gets wetter. I think the problem is, that reading directly from
PbHUB, the logic from theLIGHT.analogValuefunction is missing:class Light: @property def analogValue(self): data = 0 max = 0 min = 4096 for i in range(0, 10): newdata = 4095 - self.adc.readraw() data += newdata if newdata > max: max = newdata if newdata < min: min = newdata data -= (max + min) data >>= 3 return round(1024 * data / 4095, 2)This function seems to transform the data in a way that is missing when reading the value directly from
PbHUB. My question is whether I do have to copy paste this logic or whether there is some way to reuse theLIGHTunit withPbHUB?I would like to be able to do something like this:
pbhub = unit.get(unit.PBHUB, unit.PORTA) earth = unit.get(unit.EARTH, pbhub.HUB0) # Not M5Stack API yet light = unit.get(unit.LIGHT, pbhub.HUB1) # Not M5Stack API yet # This should read the value correctly, using the `LIGHT.analogValue` logic print(earth.analogValue()) print(light.analogValue()) -
I think the Python code in these units was not implemented with PbHUB in mind at all. I agree with your suggested interface will be very useful. You can probably do this by deriving a
HubAwareLightclass fromLight. The job ofHubAwareLightis to just setnewdatavalue inLight -
@maechler are you saying the values are inverted?
-
@ws1088 Thanks for the clarification!
Do you say that the value I get withpbhub.analogRead(0x00)should be plugged in fornewdatainLight.analogValue?
I would have placed it where the Light unit callsself.adc.readraw().
Do I also have to callpbhub.analogRead(0x00)10 times in a loop, as the Light unit does?@ajb2k3 Yes, kind of. I have tested what the Light unit does for increasing values of
self.adc.readraw()it will output decreasing values. This inversion is missing when reading directly fromPbHUB.class Light: @staticmethod def analogValue(value): data = 0 max = 0 min = 4096 for i in range(0, 10): newdata = 4095 - value data += newdata if newdata > max: max = newdata if newdata < min: min = newdata data -= (max + min) data >>= 3 return round(1024 * data / 4095, 2) print(400, Light.analogValue(400)) # 400 923.98 print(500, Light.analogValue(500)) # 500 898.97 print(600, Light.analogValue(600)) # 600 873.96 print(700, Light.analogValue(700)) # 700 848.96 print(800, Light.analogValue(800)) # 800 823.95 print(900, Light.analogValue(900)) # 900 798.95 -
I ended up copy pasting the method from the
Lightunit with some slight adjustments:def pbhubAnalogRead(pbhub, pbhub_address): data = 0 max_val = 30 min_val = 750 for i in range(0, 10): newdata = 750 - pbhub.analogRead(pbhub_address) data += newdata if newdata > max_val: max_val = newdata if newdata < min_val: min_val = newdata data -= (max_val + min_val) data >>= 3 return round(max(1024 * data / 750, 0), 2) pbhub = unit.get(unit.PBHUB, unit.PORTA) light = pbhubAnalogRead(pbhub, 0x01)The magic number
min_valI got by pressing my finger on the light sensor (blocking all the light from entering) and reading the analog value. The value750seems to be the minimum value the light sensor would emit. The numbermax_valI got by pointing a strong light at the sensor, it seems to be the maximum value the sensor emits. The min max values are mixed up because it measures the resistance and decreasing resistance means increasing light intensity. Using this method I get values that are somewhat similar to what I get by connecting theLightunit toPortBdirectly.If anyone knows how this should be done properly, please let me know!