From 7bb5fd8ec73f8e0bfe543310da4d17bd25eeb667 Mon Sep 17 00:00:00 2001 From: Mihai Tudor Panu Date: Wed, 26 Nov 2014 17:37:06 +0000 Subject: [PATCH] tp401: grove air quality sensor and examples Signed-off-by: Mihai Tudor Panu Signed-off-by: Brendan Le Foll --- docs/images/tp401.jpeg | Bin 0 -> 14438 bytes examples/CMakeLists.txt | 2 + examples/javascript/tp401.js | 68 +++++++++++++++++++++++++++++ examples/python/tp401.py | 54 +++++++++++++++++++++++ examples/tp401.cxx | 70 ++++++++++++++++++++++++++++++ src/gas/CMakeLists.txt | 4 +- src/gas/README.txt | 4 +- src/gas/jsupm_gas.i | 5 +++ src/gas/pyupm_gas.i | 4 ++ src/gas/tp401.cxx | 39 +++++++++++++++++ src/gas/tp401.h | 81 +++++++++++++++++++++++++++++++++++ 11 files changed, 328 insertions(+), 3 deletions(-) create mode 100644 docs/images/tp401.jpeg create mode 100644 examples/javascript/tp401.js create mode 100644 examples/python/tp401.py create mode 100644 examples/tp401.cxx create mode 100644 src/gas/tp401.cxx create mode 100644 src/gas/tp401.h diff --git a/docs/images/tp401.jpeg b/docs/images/tp401.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..70feb425c5ea0b99a3f4fd76fba5acb4b05e7541 GIT binary patch literal 14438 zcmch72UJsCv}RBQq=@tm(xnU1TSTM_C`t_w5s(sk4J{}ty$A>>RVgARgdR#D^o~gH zy(1-|86d#qpPBXM&3kWVy_vOUPVUaSD>?Vx^PO_{{`PmSr>>U(cXc&&Gyz0JM1UT` z2XK7_c%kX!Vt>!u-Pg<3Uh$rzkB^6L4e0PJn==I!n!?(E?JxSj>518xuz{d4^Ha`V>Be+mgP z@y%PLB&4MO7};%#+hk?i0nm^Ex`@bb67c|T&=B3EA-e7WZ~*{Bw+LPEPcQuULUiLM@huWUlgKFu6>9Dh znt$`=4MJmY5fc+?hY6>jEYW5{+yDU_T_7OZeD)DkHVit#g$dnHMPjP`i8dlj?S*`p5DHZ(XsJ~$*Jj? z<(1X7^^MJ~?H%ml(ecUYU)?RHI zEpAB?TD9k-HlB1mQt!y}>A;Mo&$9n1Ce@ifEs zlL!uv1@1{PzS;^TUuZwuV-u$@z5~rhH)C%Tbp}?;gCr5pH9yd=oPM^;1Y-F13SIFD zs)e+#oJPG%1R0Sr`g+#@qQF1HdmFIN_&2!ArGx2%mPt;2EF$tafzr_rrLvIcQ6VCG zo95fai1s7-xSL9TBxn(!D;Ot#b@8kT^}CsLE5`=8Fbs?eR&)JYz;aKe=7%S<^4-5I zE)J4HEQlCscPiL#FvfT&<_Ii^=TlW2yXTR{T9yZ#t`4D;7ElvLYJo3ccCE<51}P{T^C zE%~R>Ke#AZy?$=qhcANvG)~qZ^V9c$p$ZE3u3nxW-+Az#UrUc$e0ie*7MeH&*6`GQ?bT%na_j zhZg2klbQ>}+w$BY#*_{xzJ=Kd_t*V2>AnVp#fG*%hRMK2xM=X|%UqEb<3F+rw*0$T zf|b4x04tJ-SQVu5GYWhq_1Ke@!fAPPyO{5v=^niNDBfZ8w9PH=UZ!m!aP$x{35C3G zMnq&{eZ`BrCgLajoEA&=3YrWDynhKmGoSE={}?S0w_EsYp`s`fu=x8Nc|}f&?Ovu% zsD>*U;%vp{C)|vJrcDjg+kVN9@_VxPBy6PKvwsOFs08ijP+aDqmJhhbeqa_TQfJtvVHECG6SF0a`+;r% zfwcKjHDZ-VkThK^tquw;y{(8QlnCZx8M(`~WR3?e|9OaYSam}4ACd@EjOa)DH(N|TRwoX0yNU_fte%J`fA@5mfYQYB z`sb?h%<=^@e5LJ2mgien3b@8R9OsUnNJbRGH_4kZ`A356TC9g%cR!QL9HJJoo-_4l zJBFB zSH+X9dGoG%zH!?fSbWI-*Ci)-@`&HT!q{Fh36;M;J6?OzxW5Q~__t58fLZf_iH=1- zg!diRuVlrL0S7i3lc{$*mbhav`*mM>kUq5`8+ZVQzwR>Ese0>@7bWV{lB2CXo?gEx1J7yX>t zwiZFwv?-@bNI#>}ROS>wK7Rh|&Xz0?^yWzQ{Rg4-!-3o?e&|lk%$`%|@ZXA6Pibrk z5%6cTxl`?FbM2)mBnQq#awW6{WK(5xyb{5572H95gVgr>+6OQ``by3IzOU|Hi4dSf zi1>!2m4-)X6}YXRD=ddZT7q)BHg$s0!m2J_DadD<5|HF~zjw)jMNp81FA37PP~W8q ztJyV7`+Dd)axq&l#FL&BW-Jy2aYanD4L{;;xa(LXdOtTB@V~bB&wytJx3s*yQj40V zgyZWGM3)u7r2;Mr;A<7OUsz=1>iZY<34@ixqR*^${<`-PYvln&F-M9qWPNhW8gF(fmPhmfXCtmCCb6K??4Wt3R=Pn< zck8HIT;AwDaeCKx&Hy^=`!C3pVf%|V>_Cn)Gun%Kh3h}phc?uN%AHFzaglz-cF>(d$&Nw;u3|#b`#?jq6ZOo|D(Rjn z*2s_?ua|TU(835573?6N;ej|v>CD0cq;h-X$(ZzPmZqRo#vg5Sch>ROpPq&@U-dR< z-axm3-x9nob!(hRyW)5o4%E#>;j7hvaY-kQa9K~VtQ)pL*4B-Qm2S!+M41?qr!@S; z_xIqLtaZT{lJ-l|&VBW|aE-IM#mH>Ny#Dg)F@6%n{#MpZgQ3r{esAsh zkJ7ZU^?Fgr3$vLjuNMZB{_YNt7pMAe#^Mhid?vOe0rVGYe+EGc9gcn(P&3 zemvR`-ktA6V`-&dxFELuCN)I9#f~mtd%?nbPCAKY7oOBif(3?eVi2*u9Bd{P5RRZH z4e7rQ`-~_+gLI!0}k0_qfevF^SW+mqo!GwpdDa z3`Kjk9OnIwH4WCS1VU6jF(FrXH5jlO4d!W^=5`caRp&ckD5y#A7wv+st0Hb=IVH%7 z^*98!^%g8AU8QUEN(_cxrdxphhIpf-beXdai$sjA|2S=p1~rKlOr$kV%w!I=AaH`{ z1hgYHY3GW}$cY}1)LAbE(l4f{^5(B`taXM`LgkbwR=JBQ-p?+8M@p17;IWJBqTyxn z6%}%i;Lt}kF%E56U~B9Em~>qmWx5(?3Ia(0%nF*mhwuD-*7Ts=Rpzov%jMIY1-#>E zI*~7_$8Ya=@f}yCL;C^yHK0`y6^cpd60{moRm^oxuPs^0X}uD6#+1?e6&f z6>4<9%AGikHks+GkX7G>HCF~20=yk;f*Zzy+ZRdqt5x)@RN04pE*1OLMiDh4hLnqz z@EON$tN7Vx@xK=4^BW!aln=9YviP#420h9$9KLq(vVdl6HaX2?N1b~$W=1CPbN#Lv zK^i3%UYTX_vq2;ogU<4<@ora2)FD=3!AD%4;B?FHs^8;Cb&7G{%ZlX*2%s<7oN|YRyH4;`@ys?>BKtg z`3>Nokv02!qvxj94tvxc)VC~f?dlCRb;fpe%x8x4%1dDiq`%`Mvd0IZ?j5S!*`N?X zqhb8)2PL-}+4`69_Ed*G6~#$*HoZoVh&eqvAr38}tja(vX$xbva7`1bX8pT;isX7Y zs;SK`*n?Bn)P&=MuVv&{1L(YP_&`s2+H%37`~i_{=z##n^A*KLy*pS1Z6s69V<1VxV`a)3*j zp|wmOfG!f#`-|q7l+FhA+&P{6d8Zw1SCth$%?B-9;@VHVx;kzcU%e{hVA^`%CGtm5 zw?J@rr$oms`>(3CjMJFqan{PIBf;+_h5d&dlEB|$lYokAum{0jn8KD&l6h!E=N0cT zUMAOqI{WYQMs04Y_`7ud3R^U4Z}7lrmxulPv%C8rm5+g?ca9e!pSNuD-?sd{DEC z&u-Sr`uOXCS-ibwad3l*>)AePA|gAq)dTHl$Oiibt`NHhLqOM-;$&z`0?+v8ioEJOY+AO#z5N;h(EZy?HS9|~c5o6AwPf{rpFi=Q_H)eD zlh>wR`z0HyEqTtj`S3f8w*&5qj&K|4Cbq75Q6rBKQ&28pcv$~jNqef7>zoJ zzaa1!9vywe%8Y8&%se0~QE@|zmt~v&dEIBp&Gu=Zd6VPTvu15~#N$%0K~LK7DF6kt z%51ZmU{~S5F?1d!cw2oA-tHxYW;FAO0A(qFX(}K*z=_J;3I|%9b)Rl*JNJVZ z21|_!Vj1CObCz<6HcrxMxA{9v9$M-M6ry@P4u^iSP5!degWRB{TU{i9(c=VH4L>Mr zEUTznj^S0X;FqY%Yruy)`&Wk(lWj(~W=3b`58|fX>=m@vK8IvV*Iv|8UAY?0_@82{ zamlM$Tr1Ye44WTdN@@(v8D(?O=cN%JYS_%gOm2llz}#-m&URrCGo=ExVLa?Mwuar% zLbix-Rm*C05C>c8JZms=TqZZ!Z6>Hh{luEB-6We_+!*LDW|UwM2QFynnXSQ$WbYyZj z#GX>xhCT^-j8^ikpTGkzbMfAo+3ru!g z)Fbv+$qUVC1iEa0)tk+6S>zLw<EFc=ee6J4&6%x`F_1a-2_En1dtC2GAX zA7Y=)O?}+!>Sd;xIOyrRZC4+i7c8SMG&X!uY&a|?9s0dB{Z;*5WHf3Si5fX_n;hrx zZ+D-*1}uZyhr&47u;?yF6l9e{byFktqAipvm^qEHw`jKGP^Hf~aG)=7rrljq(o&t| z4c)vul|;Jw8TupIks>r2U7Ojkk%#%)&PhJ{ZIn@rw;e_irWa#K(n;*ZF4fDrPo5-h zQ&$&2qf>7lo%e*cDQ6WAtjg&?5aP{IWjg;doJjldw3Yf#h?osS^z7g%y=;ZPw{)7T zXXDFw&5Y-XFm3VGTZQq&vUp%O*DM57hZ9<%jsTM3B@6KEm|J`4PJsoT`KxAFrg)bL zsW{HU62&|eWjzVAty$zk;ZXcjQ#YIBN%)KDh8LM@89D{bZDQ5c7T{hlgh2dLPTR+^ z3YYn|%r$;F4?mY8N+vhXa=xEaT?2@*mkr7^-r`kG-_(mhc=`I~tG=-sDqRNTh5mW5 z;A!4H`FH{Dl~&QKCz49|?dp(tG$SE0abOGD19mdKFvr1034zR)Y}Z&r*~}X{y`tIE zEPz+A7on|^z&AsYp|n7Upg)6PE!41&m?EE}%%1P9k7Z5v>{@-P_tr=bYXe*rjNf*y z({MwxGQQ)Yuo)fMK#VjiG74`e%@vW&`Mh9zraQ81UGLsqhC`R!I15n!rwnfnl+nO9 z{M1vaEBol4;*dZyCFvXrojXj92U2etvI&$6mvO#4fyCI zB^$N!>OA|~6tJ;}o7aU==~&mPYf!gJp&ReQ|ojF^l4o)R)>i3PYq|!2+*C^Rj*FCvDM->e>kzTc%?8rtn zIQdq&SI#;>a)9wGC>2(N{Qc4Cva(C1z}-NtUCC>}Ek^Lv;_2i#-hJ7fY7XkKd=Pb_ z@NGPpiK=a0EahFDmlzL>;YZEuL7HW?dDa~9$B=VLoIO@T6IZnq$JJrYIp$guLTz0Y zf8KUVBB1oeN?jy&Dfa#Ew=HXT$q;MNi+r~pO+A0BNErg89zk0YnD30l%!_WhK!R^p zWnVB~bOut}hFKZ4zxXVdQm{~6w4p}F$sxEfQi-7HO}z%B4(1F)`?({=dE<<9J#>Hv zVhuYpFxQ&GC$NxqbJT>;a=IIxYZ(dw%i^-CnJfXm-pY?d-j}X9vpK)}T!S9)ukFJs z=gGTOL{y+eJAxYQJhM?)xOHywl_vY}{Cr1=kgRIy4dC~pVVaL*flnv&gCn>wUZSBi z;MHI8f74j!yW5EhXZSzRNEV_euv za1xz#6apMl9~eBk{i=MVL-UTl&m}l%Cn$8U^BO=ZfOBsZI8wt2X<#W%i?I3W*MJ0+c?mA4TYj2KYu+t$jM;gHFkfd@A_;miV{gYqZPZbqOaN`;t__jaKMLJ|J zGrRKQJWz!9P;^qZYt^o~{BnNG59|*%_0o_1&G4+7rKfAxf6bq34V!*^4S35{DcCtQ z<8G+0*LFoVS<|Q~&st7kiRuYo_{UqHe7gC`FV)@BbOeaeU7VuR#5EP@VAWR`b2y8Z zOM;5Tq&XPvsa#73>AtMj)seF84z?)O#r_GOVbZ&e$ z3Vi4h8sX1!$%>J~Gl+mk4_3f*!Kx!~-U1H*9@Wvw&r3-eoOi z)$Csb=vBG!3IwE|uZB#9cm7iOyZ;nQc!HI7T64Z)Yh-@mE(CmVe>X;~O17Ic%=mjM ziW1$a?BaZXb-T0kB+Ln+B*%9NR7n7{EtlPS=GAIo*`J^8gdfol1#v|)Jv|y2*0pdl zBpDelkJ^)tU>Wkf2E^A`j8rGhe5}t70(swK#HRX&O^nETX6;Xr=K-p+if?QJ$WIqp zVQtn@IPemXdB=29?cEiZm324VOx=T*apKe~-&9W3F5?9hk|ncRJ2WHCJua62(f({a zSnA+e%8Hh_&mXVHQTCQYLfzV{t*yL2mUOPR5aS+G17c0^Ct&AlG}m-pZf*(hoW7-HB-& zH&$ObemLDfygjGp{{yA?0ozd?LlJXkleGR?s{wzNt)kx6uwU>UlA6}w9;vM2%O73< z@d0E{IA-PA2gkab8pU1x{`J5VND!DVQ&hQOBi-6#YauWy+7)ni8)3BDWcy2e}d*DTBMnyx=cQnhFRNFqhyk;j3GhcBWpo*NX2cDai0tPQSp9X_hG(oCb(pjGy#wc&V^&FmEH zby+GV0TaPLYsPWduYlj9@4%$D5~rYztw`EgE3Htal1rp>vb0BD+A9Q$d4*X28!mYb zf)wLaJL6grzpy|7Wr=CXCE7?HCkS|SffXC*N4@fNbXLW6$lcXE_)Ey(&<}^mwGIvKIiFn}!ZQpR z<03HKx-}6R=t-20XGYfJZWHom)*2L_a?+RFuVpgK@7KSDuYU`hf270PC{%~H$I5kD zi{mC&OtI84HI0|vCWjpldIMWB%)C2McYo5f-dNiU=Z}}!%@b6j10mCgd&s4d*aFVd zScvJS5Wq-aoXBeEn<($gn9}}y2F*0%gs0gc3aeE={;ZcgQuyz0@6fL?QWikg>{HjK z`9gAa+4l%~ATsf|qI)9%^;vu^H#I{dr-=H!Z=9YX#&;u&;a5SS1>}G8a(z9tR?Qu7S)(p;u$SpQAEVmr*>-RnY7jSF}C zFYY_%R1b9{F){_Kpm{APZ!eAF@StfP$KmJvyfhtcjs;Sm-_VeB*#DZjEV&E|T?*&C zahWZB!SSM#u^bu!ib@R?H>+}DFZPP(4Vj%cAnz6OHzEQ{6nHu)>#2)d_r(VM7;!pw z+P!jkW1jf33+-fl*eVMTs&So6Jj=VF32kMD@m!7lC1^JVE)9ke%%x#Fjs-N9+<^UP z0plc?NGapDlRU`rYAqW zo)GQ$Ra`AS&)VRxuSHNAu`9xXYDmES&^Ou;vB1%&l)+1U0!mc_T4Iu_(c zAKm%=Z**27W;cdIf+vePeSo|yM!!j*aq2+|Y~ORQ5kyeuUJMlUytwS4xQpS=80NP64l7?>E!3RMgxf>xP~)I2e( z(P!M(166BLRtyx9e(zS>RihLUmbj~?`eo9uk|J_MHpT2!1b{C3QjOpo4+xnfsTyh$ zXp9-IX}RP+--z@DBMK}1`en2_!1uW)>)o4DSp}HZNCom$UznX^Go2x=^Qi@M#%?d% zTD_2ka1YZ>`N;C)w&s9i#6l(emHaMG=^k{Of0GdAawTqjl`hBS*oZWu{YS5eE)W>G zw$w#Zv;%c`I%gJD(_mT5GMkW1!rQc@GgU|`X?0R+uQJD~3KZWuT>a;Od8;}}5dgpFw@OHKrb3gBSFSp+imnwZM1Mf*!-!(uV3ye|LUv?GasTzlI?j(b{Av9Aa zZ7!A;(zc|+MZy{_N>;MI#HKxH_Rv>*4tm(ss-HL$zJ^hE%lXzq%~|p4>GWrZnvuJV zj^$=WT6bukXuu4mz#FEK-bKR63l?alKcQbQZ?QUQ+;^!4i-{eo8q3PbrjB$eH@-}| zR}ehHG454bGWyoy=}*Bsp0T$mPQZ9NQD?t|Reh;tH+1D1tLs5p6RN_Cb)980Gm3*Z zR%iNyC`6ktUr3v*vslRVmy5rZochMth3WM0yNtL{ z!UKj?Zv=}qj-S9a`?WCZ$pPo76@E{I{2xA`QRfWc<+pvp(YxwRqw7mwEu^7k0u{v5 z8=eN^Y*mX8!5X-)uJ9c{3)6_w($~LAq_&$m)A#A<)1x2f-JLu05Fx~8C}L3Ct(t)a z0)bQCNd!45cCOAi(+<57=dY=qaDzWJwa8SP;v1f2|3Vpg^USi+edfiw%!LqUbEP@w z!UHdbTPz!NLbqirj2~1F3edK&RO>m49e;LNS`E?&x~HP`g^Yy(*SY-1KDuwgiKP&g zN-Slm>#s!hEpe2*e$#m=Bye&U#@=xB(NcNivMVKfcr`q z$38OfWNTv3N@gu21*5d2T8Q<&x?Qo-#Mas@h~>pK8igIa{LmgG7H!^DsYP`frj?1L zHI(W}((+uZ&2|{$9IFUwe9v!4aM%`%=tBPQw)qRVkMA)_ z&q{CBrqj~r`^;0@9tNykkgeE(T?hBHJnXH}El9p>K~WrwTi1_Tng!j|184<({E{ZT z+@RzG9e~fc#l+Gskh;@-W~g(Kex*^bKO;nbXF|swZdj zx{oBfr{_=}NzGev@{sd(=lB3`OuMn(f@@>2l1%O}x^XBd8%7#~DQ{C&fy(8YG#w1@ zoPa}ml>ZS4se^C*hOrDTQ%UGz588%UdP}y@G(Lk+y`m{~+V-2||e^e%rOZCkd5!MsmZA(M+{C+&FdJ$e5eHP_8hj zx8!G83_Nw-Ff$eSU=UPjWSAsUm~>%Sa)K9!{#0f!eEo}jzA@Rpd)I0+l`ztrsH5`y$lzh2xVZ?i z_M_E9l}im#rWe~)F)>aX$W-2eUWwE`YIa%8huxENFVAH&yjMarTzz_A(_V+7p+X(c z6<(2S?CSu1yk`*%e}{HK1VTeX=(`y`4oFv&VED0ucB-T=*@YfAU_->quX}8H)5J6W z^#NEZ6DvzC5o64;KFy_;;&Cd%I{JJ)!7o^3X)!$gZ$diPu9d`Ig?2Bym*rfy9nt_g zOO`mEXmMoxTQ<2YdAjTEcIcG(`x=|Lct*Y z0h?_4+1WYQHyfy**^`3zMNTgJWjX!*-?0byyG*ChahL>bI+~K?pPXQyYyuV?y9S@qkvmxO)(hF5+(5WAWFOW21FF$(PtXFhY zchu5KK~RFXLUbTR2OkdDZ)rhf3?2!_mlYrW>=M!x@`?4ch80$%uK&5MGrHmBS}%K! zY&;~tpNp#cP56HM?~JS`H?it{d^OP$8uQ$WtJM@;B^X(V#n;LK7H0w zTK}3vN8z4u!q+dwKl$E)`%M}{T))i@0>;pl-Cr~?D>%ofjd8L3Qtp@rud z_BDT1J-PqA`q16PPu!I)O1@YK~woO!z05C|(XD*cqbqvML;; z60~Q8Gc~TGb$d11RMXU%)$zr|L{h9WO_N84*kRLf+W&MKdHDe*2+e6TDJl+rgp&&> zf=^CY|2bwYOAai50{^)!Cps%v`o7=J|8Spi?(XJ+{w}y?a+j@?5M^kh9+E~9l9cYW zIN-|e8@}j`cFl1yyi%#TCdUSa@Ari>9m;RN2JE68<-W?1sk-ER>{$1GU`#LRvsjs0 zk$P&CQ&`wH8QqJuF=`e~P&s8y`&wAit2>tQT?)&Xp;oR4&b#QYtumQK zrbS$qW`L2{p4jWhT6y}ocu3m`diKRiA)bMD(+G)`iw1Ql*1-3gv%Z^K}{b4#F>6u)GX(6ryiFnSLC6s58dufUWwu^+PRpU@97ZL6LQYW4(aaH`_Yg5 z=XdxS5V__|84zfP(kjXFfO(S2S-Fqt1?}d~(~+I4)XCp{w4ElQd-|H$$g0VM=9u%b z^P_G~*%9EYYXDBL&0^c@XkJsTss7m3=gxjX0fR!uB|{-k6$e0G&# z#dIe#%i$PLh3Z?PoEFpktMSE}%}6vPAqsg;$T|{6WxlDyCb?h#n^gBYVV9g}u6FO? z3dp{La-t5q2rq%=6V9&`DD#9Zn5V;xG4De#9+dCIATJ6L#d%=__%He%s4$RUA zo0d!OFe(3(SN5h%A_ng1`b~|3n~g9R{A7%`%vW1pLrMg*h~|9orL5lXO^f9urdQjv z08iA%n^(kvft$ZsPr0VSr^L9Zi$`74_$s!SM?5`R8ZPNDH-$K7fub1(_;gpMg0U~DrNmc`Ygjg8p#p-wm-s6?cW zb%ind4RC80JJ6A=)XiTRASJY_DhnHLet4ND?fTGQ!WW{x3@6vIA2}8iCq|C?^zyro z+%lf$6<_fa9nt1~vEI3^^#NQ2Ev~Df{yC_jbn)x&$ulQ#gX?VX7W6^;aGTJjAN!C# z1ANikXLn+wyJc~PKh(~UVSdqZ#yE?R8bUoRtLcha0qH-Z@QO^fP?XdjsI<_IQ<9h# ztR^(Vr&5pouBP(EN?O86XiO;0i6Ij%6$BxW;GILa#wL(9yr->Lirh+mm!wWEkn##zni64NyB`^)QuZ8&DI}u zJp{OA+a}T8A<qHtT3K23JFB>PX~xe6!k|G#&;hs|CI1_sRgTE1IB;p zE|BescX)Q~`3e!)#=3ch07%z4H{+WEO~<*)5Ad{zmC(J>5Qfg|FAb(2vm!D|tT<|0 zIP%}NQ+xRx)p&Bf?gxL%!5DyXazjsWL9Pxf;Fud6{xACsq^nJ26YJOy=8p^vy;=m7 zwG!*DzT>>x89C{Pzm<=|xvQ#bHMGCSJuW6})F;}02mZR5=?kU_G?VG&yfkd?tJ95R zEMCb`MiU3aFDOG>xvp4XU4Ew)u_o_3vW2T-d3KOL<<#~l1BCAGs9IJKhx;oC{&9SL zx2u@s##_K~;k#&&B?koqgBSiT=Ubf`7Q#LEJLzA3rhl#h_}^K8`yTj0-YKVgvdzk{ zT`>zq*B*4&s`AG%AA4;4(jnP?X?yG%jQeT=hK5U@EO!EpM$96D{&(2x% zTsg$c3M?$#o^`th1mIKg5S$u3m}P8_>1F!L%E%eNS$+f3(Y`8O;lb-fHhwP-7Hxiz z9}#8ct>s{iV&^NFQRzPvF~m*v6*^)rKjKG#drBln1LbE-&oz zLvg}_cslBKV6|ZT?B(MjgX-urBh9$%*&&dQ^+To^#(TX@c_yO8R%*fu47kDzalGPW zGi_+=BNz)V$O>6Ed{P2r+V*fyJlsv1*G!xvA*K4%f-gLvq=k2e>}#aAvps%UVSW59 zGi4$Pbj6tit39(E6^H6pWV6l3&X|I_-3QKu#PRyYoi}RXE3=LA^xb43COc-i#7TaV zUZkXDL6;(9s&uXV$cP#a&XI-l%}!OJ<{ER$LC%R-E@56?S+MvKy_EKf%njv~F31iS z^9(`ZMt;BxVwpPAMPaNM>eyon^X|y~6JFQV`!XWX3AP^Bw>oSc6{tvly^I*IPPfN; zMdn|!UL;muqD~Mu@T^T3iTBbRq>n~x;%zwy+9Boc#^~6E z%Q_})yYoHUSpOP=QeoD!6yOv#owQ2}F`Ae+-F_1=g_M`AfTpevJI|iU6()-Zi(f`d z4}Ab~E*z~)R21Suf`Q+~;hyXkpCJJSVDUU#4iv3m8qdHxad=_;6B~#Ss@7f6(FXOQ zb>(0-ryI;5?M?xeYaQ0W9QILs<*u}1$gj%OFLHH#@}O3-BXwl%tN5*I&kdDN9RjKH z+!V`KqF6Wh>NSAD@{jesaT%*n5c;!@_s<>Eq=kh!ogT^~UA>BK_KMZ$1GMe*r0!*r zDyK6YD5QAQ0LzhK^$jTMco^WC{9Bd15+SO+bVuKBc7q9eY}>QoUiv23P)1W@w{2vrJ#@2_2?feGSBW=%taG%*ED$7~})((4WAPqedo z72MBUZ9YFE63Hg*e+d%}Z6#6V!3$Ijj>lSagB&S6oUgcQL9S{bVxiP=tz?h4yK^Md zvPEZ63W$XvKyD7%_EhYBkdO73EfH%FbffE7tDDz@lmWNvZD}cdVKx>#*?bN7(Y^h! zWtkAc=#tO6z=UA!XpEa`750Xn``utubdK7nTtL(hP!F(LJX!FD4t>g7n(E3YW}ENs z-JAR)v3qjC2PHjyh51+(vxL60eJ++#yv)cPmi$XcH9uQNIk}f_vVd&t4!!rD-bh84 zZOKZpV#>Oo2^WR#2Zj4xJsL(2lQTz#HM}^8H0YoGXYH0gL@&l{^at__iO#3*q;sY# zp?F5bsl-GxX|Vn%Obo}^$Dw42+5gU2z(1H$swXTGAISCp^t9IK+Pyf!-J3p<^iEa@>Uv(}oFC2#vW>@K}8m}rrqf?BrX{E%d za<-pOy|3KGH%u9}yOf9)Ffem(K4XIYD@02c6d6I$wXU}E976_R>WqR7vHy?G IiLR&r3zMuicK`qY literal 0 HcmV?d00001 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 85d8929e..b9e77baf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -36,6 +36,7 @@ add_executable (mq2-example mq2.cxx) add_executable (mq3-example mq3.cxx) add_executable (mq5-example mq5.cxx) add_executable (mq9-example mq9.cxx) +add_executable (tp401-example tp401.cxx) add_executable (tcs3414cs-example tcs3414cs.cxx) add_executable (th02-example th02.cxx) add_executable (lsm303-example lsm303.cxx) @@ -121,6 +122,7 @@ target_link_libraries (mq2-example gas ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (mq3-example gas ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (mq5-example gas ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (mq9-example gas ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (tp401-example gas ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (tcs3414cs-example tcs3414cs ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (th02-example th02 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (lsm303-example lsm303 ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/javascript/tp401.js b/examples/javascript/tp401.js new file mode 100644 index 00000000..af0198d0 --- /dev/null +++ b/examples/javascript/tp401.js @@ -0,0 +1,68 @@ +/* + * Author: Mihai Tudor Panu + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +var upmTP401 = require('jsupm_gas'); +//var time = require('sleep'); + +//give a qualitative meaning to the value from the sensor +function airQuality(value) +{ + if(value < 50) return "Fresh Air"; + if(value < 200) return "Normal Indoor Air"; + if(value < 400) return "Low Pollution"; + if(value < 600) return "High Pollution - Action Recommended"; + return "Very High Pollution - Take Action Immediately"; +} + +function loop() +{ + //read values (consecutive reads might vary slightly) + var value = airSensor.getSample(); + var ppm = airSensor.getPPM(); + + //write the sensor values to the console + console.log("raw: " + value + " ppm: " + (" " + ppm.toFixed(2)).substring(-5, 5) + " " + airQuality(value)); + + //wait 2.5 s then call function again + setTimeout(loop, 2500); +} + +//setup sensor on Analog pin #0 (A0) +var airSensor = new upmTP401.TP401(0); + +//warm up sensor +console.log("Sensor is warming up for 3 minutes.."); +var i = 1; + +//print a message every passing minute +var waiting = setInterval(function() { + console.log(i++ + " minute(s) passed."); + if(i == 3) clearInterval(waiting); + }, 60000); + +//start loop in 3 minutes +setTimeout(function(){ + console.log("Sensor is ready!"); + loop(); + }, 180000); diff --git a/examples/python/tp401.py b/examples/python/tp401.py new file mode 100644 index 00000000..34fecdd5 --- /dev/null +++ b/examples/python/tp401.py @@ -0,0 +1,54 @@ +# Author: Mihai Tudor Panu +# Copyright (c) 2014 Intel Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +from time import sleep +import pyupm_gas as TP401 + +# Give a qualitative meaning to the value from the sensor +def airQuality(value): + if(value < 50): return "Fresh Air" + if(value < 200): return "Normal Indoor Air" + if(value < 400): return "Low Pollution" + if(value < 600): return "High Pollution - Action Recommended" + return "Very High Pollution - Take Action Immediately" + +# New Grove Air Quality Sensor on AIO pin 0 +airSensor = TP401.TP401(0) + +# Wait for sensor to warm up +print "Sensor is warming up for 3 minutes..." +for i in range (1, 4): + sleep(60) + print i, "minute(s) passed." +print "Sensor is ready!" + +# Loop indefinitely +while True: + + # Read values (consecutive reads might vary slightly) + value = airSensor.getSample() + ppm = airSensor.getPPM() + + print "raw: %4d" % value , " ppm: %5.2f " % ppm , airQuality(value) + + # Sleep for 2.5 s + sleep(2.5) diff --git a/examples/tp401.cxx b/examples/tp401.cxx new file mode 100644 index 00000000..82755b5c --- /dev/null +++ b/examples/tp401.cxx @@ -0,0 +1,70 @@ +/* + * Author: Mihai Tudor Panu + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include +#include +#include "tp401.h" + +using namespace std; + +//! [Interesting] +// Give a qualitative meaning to the value from the sensor +std::string +airQuality(uint16_t value) +{ + if(value < 50) return "Fresh Air"; + if(value < 200) return "Normal Indoor Air"; + if(value < 400) return "Low Pollution"; + if(value < 600) return "High Pollution - Action Recommended"; + return "Very High Pollution - Take Action Immediately"; +} + +int main () +{ + upm::TP401* airSensor = new upm::TP401(0); // Instantiate new grove air quality sensor on analog pin A0 + + cout << airSensor->name() << endl; + + fprintf(stdout, "Heating sensor for 3 minutes...\n"); + // wait 3 minutes for sensor to warm up + for(int i = 0; i < 3; i++) { + if(i) { + fprintf(stdout, "Please wait, %d minute(s) passed..\n", i); + } + sleep(60); + } + fprintf(stdout, "Sensor ready!\n"); + + while(true) { + uint16_t value = airSensor->getSample(); // Read raw value + float ppm = airSensor->getPPM(); // Read CO ppm (can vary slightly from previous read) + fprintf(stdout, "raw: %4d ppm: %5.2f %s\n", value, ppm, airQuality(value).c_str()); + usleep(2500000); // Sleep for 2.5s + } + + delete airSensor; + return 0; +} +//! [Interesting] diff --git a/src/gas/CMakeLists.txt b/src/gas/CMakeLists.txt index e8b52d82..1795d927 100644 --- a/src/gas/CMakeLists.txt +++ b/src/gas/CMakeLists.txt @@ -1,5 +1,5 @@ set (libname "gas") set (libdescription "Gas sensors") -set (module_src ${libname}.cxx mq2.cxx mq3.cxx mq5.cxx mq9.cxx) -set (module_h ${libname}.h mq2.h mq3.h mq5.h mq9.h) +set (module_src ${libname}.cxx mq2.cxx mq3.cxx mq5.cxx mq9.cxx tp401.cxx) +set (module_h ${libname}.h mq2.h mq3.h mq5.h mq9.h tp401.h) upm_module_init() diff --git a/src/gas/README.txt b/src/gas/README.txt index 4eeab52b..44f7f717 100644 --- a/src/gas/README.txt +++ b/src/gas/README.txt @@ -3,4 +3,6 @@ Grove - Gas Sensor(MQ-3):Alcohol and Benzine [high sensitivity] Long warm-up Grove - Gas Sensor(MQ-5):LPG, Natural Gas, Town Gas [high sensitivity] Grove - Gas Sensor(MQ-9):LPG, CO, CH4 [low sensitivity] -Note - Gas sensors need to be heated, first minute the data is incorrect. +Note - Gas sensors need to be heated, first minute the data is incorrect. Air +Quality sensor needs 48h to stabilize + diff --git a/src/gas/jsupm_gas.i b/src/gas/jsupm_gas.i index 01a5e8c4..98216102 100644 --- a/src/gas/jsupm_gas.i +++ b/src/gas/jsupm_gas.i @@ -26,3 +26,8 @@ %{ #include "mq9.h" %} + +%include "tp401.h" +%{ + #include "tp401.h" +%} diff --git a/src/gas/pyupm_gas.i b/src/gas/pyupm_gas.i index aa4c61c2..5b419962 100644 --- a/src/gas/pyupm_gas.i +++ b/src/gas/pyupm_gas.i @@ -31,3 +31,7 @@ #include "mq9.h" %} +%include "tp401.h" +%{ + #include "tp401.h" +%} diff --git a/src/gas/tp401.cxx b/src/gas/tp401.cxx new file mode 100644 index 00000000..0cf0c174 --- /dev/null +++ b/src/gas/tp401.cxx @@ -0,0 +1,39 @@ +/* + * Author: Mihai Tudor Panu + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "tp401.h" + +using namespace upm; + +TP401::TP401 (int gasPin) : Gas (gasPin) { + m_name = "Grove Air Quality Sensor"; +} + +TP401::~TP401 () { +} + +float +TP401::getPPM() { + return 25.0 * (float)TP401::getSample() / 1023.0; +} diff --git a/src/gas/tp401.h b/src/gas/tp401.h new file mode 100644 index 00000000..a1cc524e --- /dev/null +++ b/src/gas/tp401.h @@ -0,0 +1,81 @@ +/* + * Author: Mihai Tudor Panu + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include +#include +#include "gas.h" + +namespace upm { + /** + * @brief C++ API for Grove TP401 Air Quality Sensor + * + * The Grove TP401 Air Quality Sensor module is useful for monitoring air purity indoors. + * It can detect CO and a wide range of other harmful gases, but due to limited sensing + * range should be used only when qualitative results are needed. Example applications + * are air recirculation, ventilation systems, and refreshing sprayers. + * The sensor is linear and should be roughly sensitive to 0 ~ 20 ppm CO from 0 ~ 4V. + * Also note that the sensor requires 2-3 minutes to warm up initially and 48 hours of + * operation to stabilize completely. + * + * @ingroup gas analog + * @snippet tp401.cxx Interesting + * @image html tp401.jpeg + */ + class TP401 : public Gas { + public: + /** + * TP401 constructor + * + * @param gasPin analog pin where sensor was connected + */ + TP401 (int gasPin); + + /** + * TP401 destructor + */ + ~TP401 (); + + /** + * Return name of the component + * + * @return a string with the name of the sensor + */ + std::string name() + { + return m_name; + } + + /** + * Returns one sample in parts per million (ppm) of CO in the air based on + * the following sensor calibration: 0 ~ 4V is roughly 0 ~ 20 ppm CO + * + * @return a new sample converted to ppm CO + */ + float getPPM(); + + private: + std::string m_name; + }; +}