Message Boards Message Boards

I2C interface for Mathematica on Raspberrypi

Posted 7 years ago

The ozzmaker.com BerryIMU has a BMP180 temperature-pressure sensor and a LSM9DS0 magnetometer-accelerometer-gyroscope sensor. Mathematica can read-write sensor registers and has advantages in processing the outputs to physical values. This project is intended to evaluate Raspberrypi Zero Mathematica performances on sensors handling.

functions

rGet[reg_] := 
  StringTrim[
   RunProcess[{"i2cget", "-y", "1", chipAdr, reg}, 
    "StandardOutput"]];
rPut[reg_, value_] := 
  StringTrim[
   RunProcess[{"i2cset", "-y", "1", chipAdr, reg, value}, 
    "StandardOutput"]];
(* Get unSigned and Signed Short Integer *)
usGet[reg1_, reg2_] := (
   r = Flatten[{rGet[reg1], rGet[reg2]}];
   r1 = Map[FromDigits[#, 16] &, StringReplace[r, "0x" -> ""]];
   BitShiftLeft[r1[[1]], 8] + r1[[2]]
   );
ssGet[reg1_, reg2_] := (
   r = Flatten[{rGet[reg1], rGet[reg2]}];
   r1 = Map[FromDigits[#, 16] &, StringReplace[r, "0x" -> ""]];
   r2 = BitShiftLeft[r1[[1]], 8] + r1[[2]];
   If[r2 > 32767, -32768 + (r2 - 32768), r2]
   );

LSM9DS0 magnetic field sensor

chipAdr = "0x1e";
(* CTRL_REG5 _XM, 24h set magnetsensor data rate*)

rPut["0x24", "0x00"];
(* CTRL_REG7 _XM, 26h set magnetsensor to continuous conversion*)

rPut["0x26", "0x00"];
d = Table[Pause[0.3]; usGet["0x09", "0x08"], {100}];
ListLinePlot[d]

BMP180 temperature/pressure sensor

chipAdr = "0x77";
ac1 = ssGet["0xaa", "0xab"];
ac2 = ssGet["0xac", "0xad"];
ac3 = ssGet["0xae", "0xaf"];
ac4 = usGet["0xb0", "0xb1"];
ac5 = usGet["0xb2", "0xb3"];
ac6 = usGet["0xb4", "0xb5"];
b1 = ssGet["0xb6", "0xb7"];
b2 = ssGet["0xb8", "0xb9"];
mb = ssGet["0xba", "0xbb"];
mc = ssGet["0xbc", "0xbd"];
md = ssGet["0xbe", "0xbf"];
rPut["0xf4", "0x2e"]; Pause[0.05];
ut = usGet["0xf6", "0xf7"];
x1 = (ut - ac6)*ac5/2.^15;
x2 = mc*2.^11/(x1 + md);
b5 = x1 + x2;
t = (b5 + 8.)/2.^4/10.

(* prssure *)

rPut["0xf4", "0x34"]; Pause[0.05];
up = usGet["0xf6", "0xf7"];
b6 = b5 - 4000.;
x1 = (b2*(b6*b6/2^12))/2^11;
x2 = ac2*b6/2^11;
x3 = x1 + x2;
b3 = ((ac1*4 + x3) + 2)/4.;
x1 = ac3*b6/2^13;
x2 = (b1*(b6*b6/2^12))/2^16;
x3 = ((x1 + x2) + 2)/2^2;
b4 = ac4*(x3 + 32768)/2^15;
b7 = (up - b3)*50000;
If[b7 < FromDigits["80000000", 16], p = b7*2/b4, p = b7/b4*2];
x1 = p/2^8*p/2^8;
x1 = x1*3038/2^16;
x2 = (-7357*p)/2^16;
p = p + (x1 + x2 + 3791)/2^4;
p = p*0.01
2 Replies

Hi Hirokazu,

Mathematica actually has a built-in device driver for interfacing with I2C devices, you can see some examples here : http://reference.wolfram.com/language/ref/device/I2C.html

For example, the code you have that uses RunProcess can be replaced with calls like this:

(*open a connection to the device*)
dev = DeviceOpen["I2C",chipAddr]
(*read a single byte from a register*)
DeviceWrite[dev,reg];DeviceRead[dev]
(*write a single byte value to a register*)
DeviceWrite[dev,reg];DeviceWrite[dev,value];

Thanks,

Ian

POSTED BY: Ian Johnson

hi Ian

My first test was one that followed wolfram reference, DeviceOpen[] etc. as you shown, however in my environment (Mathematica 10.3 on Raspberrypi Zero), I only got errorneous results. For example, FindDevices[] can't find my I2C BerryIMU module, but returns FunctionDemo, GPIO, RandomSignalDemo, RaspberryPiWeatherStation, and WriteDemo.

So, I appreciate if you will show your environment and sample working code.

Thank you,

Kbys

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract