Module for TMP102 temperature sensor

Showroom for MicroPython related hardware projects.
Target audience: Users wanting to show off their project!
randomhuman
Posts: 19
Joined: Mon Jun 09, 2014 1:54 pm

Module for TMP102 temperature sensor

Postby randomhuman » Thu Jun 12, 2014 3:37 pm

I've put together a module for configuring and reading from a Texas Instruments TMP102 temperature sensor over I2C:

https://github.com/khoulihan/micropython-tmp102

I think the only feature that is not supported is the SMBus interrupts that can be enabled for when the temperature passes certain thresholds. I'm not sure if the pyboard hardware itself supports those or how I would go about supporting them if it does.

Sparkfun have a breakout for this sensor, so it is easy to get started with: https://www.sparkfun.com/products/11931

Hope somebody finds it useful (and not too buggy).

pfalcon
Posts: 893
Joined: Fri Feb 28, 2014 2:05 pm

Re: Module for TMP102 temperature sensor

Postby pfalcon » Sat Jun 14, 2014 3:32 pm

Great work! Good documentation, comprehensive support for sensor features. My only comment that perhaps a bit too comprehensive and all-in-one. Did you try to assess memory usage of your module?

I may suggest moving this topic to "Projects" forum, let me know if you agree.

randomhuman
Posts: 19
Joined: Mon Jun 09, 2014 1:54 pm

Re: Module for TMP102 temperature sensor

Postby randomhuman » Sun Jun 15, 2014 11:55 am

Thanks :)

I did implement a lot more functionality than I needed myself - I only needed the shutdown/single conversion stuff, because my application will only need to take readings a few times an hour at most - but once I started it seemed rude not to do the rest! I don't think the code does anything that would cause excessive memory usage, other than being quite large in itself. What's the best way to evaluate it? Call pyb.info() at various points?

I'm fine with moving this post to the projects forum if that is where it belongs.

pfalcon
Posts: 893
Joined: Fri Feb 28, 2014 2:05 pm

Re: Module for TMP102 temperature sensor

Postby pfalcon » Tue Jun 17, 2014 10:04 pm

randomhuman wrote:I did implement a lot more functionality than I needed myself


That's being pretty much a Python way - language is a pleasure to write in, so people tend to provide comprehensive, "batteries included" modules. The question, should MicroPython modules be written the same way?

- I only needed the shutdown/single conversion stuff, because my application will only need to take readings a few times an hour at most


Exactly my thinking of what most people would need of such modules ;-).

- but once I started it seemed rude not to do the rest! I don't think the code does anything that would cause excessive memory usage, other than being quite large in itself. What's the best way to evaluate it? Call pyb.info() at various points?


Nope, I mean just raw bytecode size, even without any runtime memory costs. It's easy to discount that memory usage, but I already had enough of "enlightments" that bytecode does cost you memory, in noticeable figures! Yes, you can use pyb.info() (reminds me that we don't have cross-platform way to do it) immediately before and after "import tmp102". You can try and see if the figure aligns with your expectations (I may confess that my estimate for you module was twice less than I actually saw). The bottom line: only few such modules can exhaust PyBoard's heap (which is pretty big by MCU standards). Consider for example typical smart home application, where you may want bunch of sensors and control application to make something useful of them. With modules written like this, it will be hard to achieve. So, apparently we need to come up with "better" ways to write modules for MicroPython, I'd welcome discussion on this!

I'm fine with moving this post to the projects forum if that is where it belongs.


Done.

randomhuman
Posts: 19
Joined: Mon Jun 09, 2014 1:54 pm

Re: Module for TMP102 temperature sensor

Postby randomhuman » Wed Jun 18, 2014 10:45 am

Let's see... It uses about 22K immediately after import, which does seem excessive. A good chunk of that is the module docstring; with that removed, usage is reduced to 15K. Personally I like to be able to browse around source and have it documented internally, but in this context it is going to have to go.

I can see your point about the functionality being more comprehensive than would likely be useful to any one project. I can see somebody wanting to change the conversion rate OR shutdown the device and poll it infrequently, but hardly both. I suppose what is needed is to put each little bit of functionality into its own module within a package, and allow them to be imported as required. It might be tricky to do so while maintaining a class based approach, but python is so flexible that I'm sure there is a solution.

randomhuman
Posts: 19
Joined: Mon Jun 09, 2014 1:54 pm

Re: Module for TMP102 temperature sensor

Postby randomhuman » Wed Jun 18, 2014 2:41 pm

I reorganised the module into a package so that features only need to be imported if required. When the package alone is imported, the Tmp102 class only contains functionality for reading the temperature, but nothing for configuring the device. When a feature submodule is imported, it adds the required methods, properties and constants onto the class dynamically. The modules themselves are empty after the import.

Code: Select all

from tmp102 import Tmp102
import tmp102.extendedmode
import tmp102.shutdown
import tmp102.oneshot
import tmp102.conversionrate
import tmp102.alert


I also stripped out all the docstrings. I initially tried deleting the main module docstring at runtime, so that it would still be available during development, but not take up space when in use, but it appears that __doc__ properties are not implemented yet. I tried assigning it to a variable and then deleting it, but it was not removed by the garbage collector. I guess string constants are retained even if they are not being referenced by anything?

I saw this memory usage when importing the various modules:

Code: Select all

>>> import tmp102  # 4.26K
>>> pyb.gc()  # 3.53K
>>> import tmp102.shutdown  # 5.28K
>>> pyb.gc()  # 4.91K
>>> import tmp102.oneshot  # 6.26K
>>> pyb.gc()  # 6.03K
>>> import tmp102.extendedmode  # 7.23K
>>> pyb.gc()  # 6.87K
>>> import tmp102.conversionrate  # 8.72K
>>> pyb.gc()  # 8.36K
>>> import tmp102.alert  # 12.94K
>>> pyb.gc()  # 12.44K
>>> import tmp102.convertors  # 14.05K
>>> pyb.gc()  # 13.44K

User avatar
fma
Posts: 156
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: Module for TMP102 temperature sensor

Postby fma » Wed Jun 18, 2014 4:17 pm

I like your approach!
Frédéric

pfalcon
Posts: 893
Joined: Fri Feb 28, 2014 2:05 pm

Re: Module for TMP102 temperature sensor

Postby pfalcon » Wed Jun 18, 2014 9:35 pm

A good chunk of that is the module docstring; with that removed, usage is reduced to 15K.


That's weird. @dpgeorge made changes to remove (or rather, not store) docstrings automagically, and I informally saw it working. I agree that this should not be programmer's concern - it's compiler task to either let them say or remove them, based on user (or environment) preference.

pfalcon
Posts: 893
Joined: Fri Feb 28, 2014 2:05 pm

Re: Module for TMP102 temperature sensor

Postby pfalcon » Wed Jun 18, 2014 9:44 pm

I guess string constants are retained even if they are not being referenced by anything?


Yes, all constant strings which appear in script are interned. But again, we made change that expressions consisting of just strings (which covers docstrings) are discarded. Submitting a bug for this issue will make sure it's revisited and not forgotten.

pfalcon
Posts: 893
Joined: Fri Feb 28, 2014 2:05 pm

Re: Module for TMP102 temperature sensor

Postby pfalcon » Wed Jun 18, 2014 10:07 pm

I reorganised the module into a package so that features only need to be imported if required. When the package alone is imported, the Tmp102 class only contains functionality for reading the temperature, but nothing for configuring the device. When a feature submodule is imported, it adds the required methods, properties and constants onto the class dynamically.


I see. Well, converting a monolithic module into a package with submodules is definitely the only way to deal with this issue. Ways to organize and implement submodule vary however. I had similar problem with utemplate module (neighbor topic in this forum). I initially wanted top package to provide "all" functionality, and let user to import submodule for "subset" functionality. But surely, that doesn't work as expected, because for "import foo.bar" Python first does "import foo". Doing it other way around was not logical, so I went for too "specific" submodules (though one submodule actually imports another, so represents "all" functionality).

I would say that your approach is too fine-grained, but actually the way it is done, imports are used as kind of "feature pragmas", so it's actually nice. But you say that you implement it via monkey-patching, and that's not friendly with static approach. Yes, Python is dynamic language, but if we want more efficiency from it, going more static is the only way, so I personally trying to restrict myself to not abuse dynamicity too much.

Note that there's well-known and static-friendly way to add more members/methods/change their behavior - it's subclassing.

Anyway, those are just generic comments. Nobody yet knows how deal with all the variety of requirements, and which way is better. But letting people try and present different approaches, we hopefully over time will come to the best practices.


Again, I suggest reporting issues you saw with docstrings - they're not intended to be there (issues). (And fyi, another known big byte-waster is https://github.com/micropython/micropython/issues/648).


Return to “Hardware Projects”

Who is online

Users browsing this forum: No registered users and 1 guest