development of a module for the bmp180 pressure sensor

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: development of a module for the bmp180 pressure sensor

Post by Turbinenreiter » Wed Jul 02, 2014 1:34 pm

Okay, I will use the second version. Lowercase the object, uppercase the class.
Thanks.

fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: development of a module for the bmp180 pressure sensor

Post by fma » Wed Jul 02, 2014 1:49 pm

Automatically instanciatint objects may have sens for Singleton or so (global logger...)
Frédéric

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

Re: development of a module for the bmp180 pressure sensor

Post by pfalcon » Wed Jul 02, 2014 3:12 pm

edit: also: is class.__dict__ not implemented yet (I'm still on the version the board shipped with, need to update that)?
No, and it's not going to be implemented (as in: "there's strong opposition to implementing it"). Over-dynamicity features like that is the cause of slowness. Nowadays, one should expect the code to be compiled to efficient machine code, rather than the fact that object is implemented in particular way (like with a dictionary). To achieve the former, one needs to give up the latter. Besides, if one wants to write object-oriented apps, one should write them as such, again, without relying on particular underlying implementation.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: development of a module for the bmp180 pressure sensor

Post by dhylands » Wed Jul 02, 2014 4:06 pm

fma covered the import things.

I was just going to say that according to the datasheet, this device is hardcoded at I2C address 0b1110111 which is 0x77. Since that's the only address that the BMP180 device can live at, you should just hard code it.

Otherwise your code will break if a second device happens to be on the bus and that other device gets returned first in the scan.

Some devices can have multiple addresses, and the address is selected by how the chip is wired up. For these devices, you normally allow the caller to determine the address.

Also, you might want to look at PEP8, which is a fairly common coding style guideline for python.

There is actually a tool called pep8 you can run on your python source, and it will tell you things that deviate.
I also use pylint. I've found that using these finds errors in my code and gives my code some consistency of appearance.

Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: development of a module for the bmp180 pressure sensor

Post by Turbinenreiter » Wed Jul 02, 2014 5:52 pm

pfalcon wrote:No, and it's not going to be implemented (as in: "there's strong opposition to implementing it"). Over-dynamicity features like that is the cause of slowness. Nowadays, one should expect the code to be compiled to efficient machine code, rather than the fact that object is implemented in particular way (like with a dictionary). To achieve the former, one needs to give up the latter. Besides, if one wants to write object-oriented apps, one should write them as such, again, without relying on particular underlying implementation.
I have never thought about that. I just remembered using it once and I thought I could use it for debugging.
Thank you, I'm learning a lot here.

@dhylands

You are right with the hardcoded address and the scan function. Will change that.
PEP8 I know already, using the tools is a great idea, especially because I really hope that my implementation can be useful for others. The better the code and coding-style, the easier it is to use.

Is there a philosophy on whether to make variables and functions public or non-public?
Obviously there are functions and variables that don't need to be public, however they are nice to have public to inspect and debug what's going on.
i.E. the calibration values - they should not be needed by the user, who only cares about temperature, pressure and altitude - however, what do I know about others wanna do?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: development of a module for the bmp180 pressure sensor

Post by dhylands » Wed Jul 02, 2014 6:02 pm

Turbinenreiter wrote:Is there a philosophy on whether to make variables and functions public or non-public?
Obviously there are functions and variables that don't need to be public, however they are nice to have public to inspect and debug what's going on.
i.E. the calibration values - they should not be needed by the user, who only cares about temperature, pressure and altitude - however, what do I know about others wanna do?
In Python you don't really have a choice. Everything is public. There are only conventions to indicate that something should be public or private, there isn't actually any way to enforce it like you can do in C++

As for calibration values, a user might like to get access to them for debugging purposes (to say validate the calculations)

Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: development of a module for the bmp180 pressure sensor

Post by Turbinenreiter » Wed Jul 02, 2014 8:13 pm

Say I do:

Code: Select all

Python 2.7.6 |Anaconda 1.9.2 (64-bit)| (default, Jan 17 2014, 10:13:17) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class test():
...     def __init__(self):
...             t=1
...             self.a=2
... 
>>> br = test()
>>> br.t
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: test instance has no attribute 't'
>>> br.a
2
>>> 
t will raisees an AttributeError, self.a prints 2.

That's what I meant with public/non-public.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: development of a module for the bmp180 pressure sensor

Post by dhylands » Wed Jul 02, 2014 8:47 pm

OK - this is just a terminology thing.

I would call t a local variable. It's scope is local to the function that its declared in and can't be accessed outside that function (i.e. it can't even be accessed by other functions in the same class).

Probably due to my C/C++ background, I would consider a private variable to be a variable that other functions in the same class can access, but which users of the class can't access. Python doesn't have this concept.

Looking at your code again, I would expect that the constants calculated from the calibration data should be class attributes (i.e. self.AC1)

In a function like calc_temp, I would make X1, X2, B5, and T just be local variables. Those values aren't re-used in any other function, so there really isn't much point in saving them in self (they just take up memory that way).

You're also reading the chip_id from the wrong address (the code shows 0xAA, but it lives at 0xD0).

You should probably write a test (probably in a separate file) which sets the calibration data as presented in the datasheet, so that you can verify you at least get the same results as the datasheet for the example.

You need to careful with casts. For example, AC3 is signed and can be negative. This implies that in X1 = AC3 * B6 / 2**13, X1 can be negative. X1 is used to calculate X3, and B4 has a cast to unsigned long. If somehow the right hand side can become negative, then the cast in C will give a different result than what you can get in Python.

You can achieve the same sort of thing in Python by doing val = val & 0xffffffff. For example, -2 & 0xffffffff will give 4294967294 (which is now positive and the same value you would have gotten in C if you did (unsigned long)-2

Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: development of a module for the bmp180 pressure sensor

Post by Turbinenreiter » Thu Jul 03, 2014 5:25 am

Ok, so it's local vs. self instead of public vs. non-public.
You're also reading the chip_id from the wrong address (the code shows 0xAA, but it lives at 0xD0).
Copy paste error, already catched and fixed that. I went through all variables and looked what's in there.
In a function like calc_temp, I would make X1, X2, B5, and T just be local variables. Those values aren't re-used in any other function, so there really isn't much point in saving them in self (they just take up memory that way).
True. I will keep them in self for now, until everything runs correctly, but after that just have them local.
You should probably write a test (probably in a separate file) which sets the calibration data as presented in the datasheet, so that you can verify you at least get the same results as the datasheet for the example.
That's a very good idea. The datasheet also shows all the values of all variables, so that will help me find my bug.
You need to careful with casts.
I completley ignored that because I didn't understand what AC2*(unsigned long) meant. will look that up now.

Again, thanks for education me!
I will try to pay you back in the form of modules for the bmp180, mpu6050/9150 and adxl3xx.

torwag
Posts: 220
Joined: Fri Dec 13, 2013 9:25 am

Re: development of a module for the bmp180 pressure sensor

Post by torwag » Thu Jul 03, 2014 8:49 am

Hi,

a totally OT answer but just a generic remark,
whenever I face trouble with i2c or similar protocols, I use my handy bus-pirate.

http://www.seeedstudio.com/depot/bus-pi ... Path=61_68

This little board allows testing, debugging and tinkering with many inter-chip protocols via a terminal on a PC.
It can also sniff the traffic between different chips, thus one can check if what you mean to send or receive is really what was send/received.
It's simply a great tool to tackle dev problems like there was described above.
No ad, just a happy bus-pirate user experience sharing.

On a side note, I believe that micropython could take the buspirate to the next level. Now it is all hard-coded in C for a PIC. Using micro-python would allow much more flexibility and a much easier maintenance plus, a lot of more features due to the ARM SoC (e.g. data logging to SD card.)

Post Reply