In[]:=
(*WewillfirstsetupthemicrocontrollertoreceivedatafromtheMPU-6050sensor.*)
In[]:=
addr="0x68";
In[]:=
i2cread=Join[{"START","0x3B","START"},Sequence@@Table[{"READ","ACK"},{13}],{"READ","STOP"}]
Out[]=
{START,0x3B,START,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,ACK,READ,STOP}
In[]:=
(*3accelerometer,1thermostat,and3gyrospopereadingsarestoredintwobyteseachstartingfromaddress0x3B.14bytesarereadwithanacknoledgementaftereachreadingexceptthelastone.*)
In[]:=
(*TheSensorneedstobeinitializedbeforeitcansendoutthedata*)
In[]:=
i2cinit="Initialization"{"START","0x6B","0x0","STOP"};
In[]:=
"Initialization"{"START","0x6B","0x0","STOP"}
Out[]=
Initialization{START,0x6B,0x0,STOP}
In[]:=
(*ThecompleteI2Cspecificationsforthesensor.*)
In[]:=
i2cspecs=addr{i2cread,i2cinit};
In[]:=
(*Theaccelerationsandangularvelocitiesaresentas2'scomplements.Createautilitytoconvertstodecimalfromthe2’scomplementvalue,this2'scomplementsisreferringtobinarycode.Sowecreateatranslationutilitytoconvertfrombinarytodecimal.\/*)
In[]:=
Needs["SymbolicC`"]co=COperator;ca=CAssign;a[rhs_]:=ca[rhs,co[BitOr,{co[BitShiftLeft,{"hbyte",8}],"lbyte"}]];
In[]:=
from2C=CFunction["double","twosC_To_D",{{"uint8_t","hbyte"},{"uint8_t","lbyte"}},{CDeclare["double","d"],CDeclare["uint16_t",a["sxtnBit"]],CIf[co[BitAnd,{"hbyte","0x80"}],{ca["sxtnBit",co[BitXor,{"sxtnBit","0xFFFF"}]],co[Increment,"sxtnBit"],ca["d",co[Times,{-1.0,"sxtnBit"}]]},ca["d",co[Times,{1.0,"sxtnBit"}]]],CReturn["d"]}];
In[]:=
ToCCodeString[from2C]//StringTrim
Out[]=
double twosC_To_D(uint8_t hbyte, uint8_t lbyte){double d;uint16_t sxtnBit = hbyte << 8 | lbyte;if( hbyte & 0x80){sxtnBit = sxtnBit ^ 0xFFFF;sxtnBit++;d = -1. * sxtnBit;}else{d = 1. * sxtnBit;}return d;}
In[]:=
utils={from2C};
In[]:=
(*Asecondmasterutilitytohandleallmeasurementsbasedoniftheyneedsuchaconversion^*)
In[]:=
from2B=CFunction["double","sxtnb_To_D",{{"uint8_t","hbyte"},{"uint8_t","lbyte"},{"uint8_t","i"}},{CDeclare["double","d"],CIf[co[Equal,{"i",3}],a["d"],ca["d",CCall["twosC_To_D",{"hbyte","lbyte"}]]],CReturn["d"]}];
In[]:=
ToCCodeString[from2B]//StringTrim
Out[]=
double sxtnb_To_D(uint8_t hbyte, uint8_t lbyte, uint8_t i){double d;if( i == 3){d = hbyte << 8 | lbyte;}else{d = twosC_To_D(hbyte, lbyte);}return d;}
In[]:=
AppendTo[utils,from2B];
In[]:=
(*\/TheMasterutilityfunctionusedtoconvertthe14bytesto7decimalvalue.*)
In[]:=
MapIndexed[(#1[Repeated[_,2#2-2],byte1_,byte2_,___]:=CCall["sxtnb_To_D",{byte1,byte2,#2-1}])&,{aX,aY,aZ,T,wX,wY,wZ}];
In[]:=
Grid[Table[{f,ToCCodeString[f@@Table["b"<>ToString@i,{i,0,13}]]},{f,{aX,aY,aZ,T,wX,wY,wZ}}],Background{None,{{LightBlue,White}}},FrameAll]
Out[]=
aX | sxtnb_To_D(b0, b1, 0) |
aY | sxtnb_To_D(b2, b3, 1) |
aZ | sxtnb_To_D(b4, b5, 2) |
T | sxtnb_To_D(b6, b7, 3) |
wX | sxtnb_To_D(b8, b9, 4) |
wY | sxtnb_To_D(b10, b11, 5) |
wZ | sxtnb_To_D(b12, b13, 6) |
In[]:=
(*The7valuesareobtainedfromthesamedatalineSDA,whichispin2ontheArduinoYun.^*)
In[]:=
ics=Table["2"<|"Type""I2C","SlaveAddress""0x68","Conversion"fn|>,{fn,{aX,aY,aZ,T,wX,wY,wZ}}];
In[]:=
ics//Length
Out[]=
7
In[]:=
(*Amodeltoconverttheaccelerationtounitsofm/s^2,temperaturetodegreeC,andangularvelocitytorad/sfromthedecimalvalues.*)
In[]:=
sys=NonlinearStateSpaceModel[{{},{u1*(9.8/16384.),u2*(9.8/16384.),u3*(9.8/16384.),36.53+u4/340.0,u5*(3.14/(131*180)),u6*(3.14/(131*180)),u7*(3.14/(131*180))}},{},{{u1,0},{u2,0},{u3,9.8},{u4,0},{u5,0},{u6,0},{u7,0}},SamplingPeriod0.1]
Out[]=
0.000598145u1 |
0.000598145u2 |
0.000598145u3 |
36.53+0.00294118u4 |
0.000133164u5 |
0.000133164u6 |
0.000133164u7 |
0.1
In[]:=
(*WewillnowcreatethedatabinandsetuptheoutputchannelstouploadthedatausingArduino’sbridgelibrarytothedatadroprepository.*)
In[]:=
bin=CreateDatabin[<|"Name""mpu6050"|>]
Out[]=
Databin
In[]:=
(*Thelocationofthebridgelibrarythatisneededtouploadvaluestothedatabin.WhichIbelieveweareaccessingfromtheArduinoYunitself*)
In[]:=
bridgeLib=FileNameJoin[{"/Applications","Arduino.app","Contents","Java","libraries","Bridge","src"}];
In[]:=
(*Theheaderfilealongwiththeutilitiesandinitializationcode.*)
In[]:=
i={"Bridge.h"};AppendTo[utils,"Process p"];inits={"USBDevice.attach()","Bridge.begin()","double val"};
In[]:=
(*TheRESfullapicodewhichaddstothedatabin*)
In[]:=
ocs=Table[<|"Type""ExternalLibrary","Loop"{"val","p.begin(\"curl\")","p.addParameter(\"--insecure\")","p.addParameter(\"--location\")","p.addParameter(\"https://datadrop.wolframcloud.com/api/v1.0/Add?bin="<>bin[[1]]<>"&"<>m<>"=\"+String(val))","p.run()"}|>,{m,{"ax","ay","az","tp","wx","wy","wz"}}];
In[]:=
(*Thecodesnippetthatuploadsthefirstdataentry.*)
In[]:=
ocs[[1]]["Loop"]//ToCCodeString
Out[]=
val;p.begin("curl");p.addParameter("--insecure");p.addParameter("--location");p.addParameter("https://datadrop.wolframcloud.com/api/v1.0/Add?bin=SERPLvd2&ax="+String(val));p.run();
In[]:=
(*Loadthepackage*)
In[]:=
Needs["MicrocontrollerKit`"]