From 26fc170964595e475dae8804cbee1799ec980232 Mon Sep 17 00:00:00 2001 From: Remi Clement <remi.clement@inrae.fr> Date: Wed, 10 Jan 2024 21:15:38 +0100 Subject: [PATCH] corrections on some rst file --- doc/build/doctrees/environment.pickle | Bin 88570 -> 89540 bytes .../developing_hardware_components.doctree | Bin 10104 -> 9797 bytes .../source_rst/hardware/mb/mb_2024.doctree | Bin 126102 -> 126529 bytes .../doctrees/source_rst/software.doctree | Bin 38213 -> 4420 bytes .../source_rst/software/architecture.doctree | Bin 0 -> 10705 bytes .../source_rst/software/developments.doctree | Bin 0 -> 2121 bytes .../source_rst/software/installation.doctree | Bin 0 -> 6950 bytes .../source_rst/software/operations.doctree | Bin 0 -> 33042 bytes .../developing_hardware_components.rst.txt | 3 +- .../source_rst/hardware/mb/mb_2024.rst.txt | 3 + .../html/_sources/source_rst/software.rst.txt | 249 +------------ .../source_rst/software/architecture.rst.txt | 52 +++ .../source_rst/software/developments.rst.txt | 0 .../source_rst/software/installation.rst.txt | 49 +++ .../source_rst/software/operations.rst.txt | 230 ++++++++++++ doc/build/html/index.html | 8 +- doc/build/html/objects.inv | Bin 703 -> 733 bytes doc/build/html/searchindex.js | 2 +- doc/build/html/source_rst/api.html | 4 +- .../developing_hardware_components.html | 4 +- .../html/source_rst/hardware/mb/mb_2024.html | 4 + doc/build/html/source_rst/software.html | 262 ++------------ .../source_rst/software/architecture.html | 177 +++++++++ .../source_rst/software/developments.html | 113 ++++++ .../source_rst/software/installation.html | 165 +++++++++ .../html/source_rst/software/operations.html | 335 ++++++++++++++++++ .../source_rst/V2023.x.x/V2023_step_03.rst | 289 --------------- .../developing_hardware_components.rst | 3 +- doc/source/source_rst/software.rst | 2 +- .../source_rst/software/architecture.rst | 4 +- .../source_rst/software/installation.rst | 10 + doc/source/source_rst/software/operations.rst | 17 +- 32 files changed, 1203 insertions(+), 782 deletions(-) create mode 100644 doc/build/doctrees/source_rst/software/architecture.doctree create mode 100644 doc/build/doctrees/source_rst/software/developments.doctree create mode 100644 doc/build/doctrees/source_rst/software/installation.doctree create mode 100644 doc/build/doctrees/source_rst/software/operations.doctree create mode 100644 doc/build/html/_sources/source_rst/software/architecture.rst.txt create mode 100644 doc/build/html/_sources/source_rst/software/developments.rst.txt create mode 100644 doc/build/html/_sources/source_rst/software/installation.rst.txt create mode 100644 doc/build/html/_sources/source_rst/software/operations.rst.txt create mode 100644 doc/build/html/source_rst/software/architecture.html create mode 100644 doc/build/html/source_rst/software/developments.html create mode 100644 doc/build/html/source_rst/software/installation.html create mode 100644 doc/build/html/source_rst/software/operations.html delete mode 100644 doc/source/source_rst/V2023.x.x/V2023_step_03.rst diff --git a/doc/build/doctrees/environment.pickle b/doc/build/doctrees/environment.pickle index 640e7c16a50e5a08abb1cdc852120553036a13f2..9f06e041770a684127515c8483b7d5a2a239ca42 100644 GIT binary patch literal 89540 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 CvfUN{ literal 88570 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 diff --git a/doc/build/doctrees/source_rst/developing_hardware_components.doctree b/doc/build/doctrees/source_rst/developing_hardware_components.doctree index b12600c989698c71f5a68b52c06f4bd49b6d9e74..437534bda016dddb6d5fc6d8765d201d1a2a02d1 100644 GIT binary patch delta 338 zcmez2chrZqfpw~t+D29ZCT2A)t;zDtN<eB#27Bz349*_5;*z5Ly!0uPr)V}#shy&c z!J1(RmJ;hx0x6w*k_kw&im)1INN4CzKFFal`98B4WBg=mrWBS8u^td3Ve&r~E=G^Z z8`+H**)~65)?j1|19LbgKVTNw9Kf2u#FzpW;06kaPX5Whm$3-U=LakJ#}UHJ*Z>v~ z1PjdKv14ZJ0}F_Obxab-n%pf=%{T`vCJhqX>@PTzk#QARKo+daKzIua;|{QZ0$4yt zVg)nfF|dF-Sc|O8Nk+yiU;*9DQgU0E7<o6JS9r`U|2*SKaSvx+Vs2_lWkG5&Fd#CX bcNS+T0_i6iJjIhG)ILlWP#2%9tL_Z|F(Gi4 delta 676 zcmb7>&ubGw6vsRJBQY_CNU4g6X=;saVob5>MaAMFNLh^~7cZuE(@gs|B)ef}SE(Si zVnJbU^Ykz9;7QQ+=%E+ElY)Ohpm^}?O-c_=rnLy3JUr%oX6DVj_x*ml^{Z|^F<<tk z-kBLqe^xGwCG9jxie0T;nuY{F-1og!m-g(ySw?}S4SbB#U~;WoMu;~Nj>%MPXp@(? z?zCsohDo_ulrbfv)I@Ijbj4}o@c06Ta1Jg)7G}bhtbBU#*^(%j$@C25K!;Ox$k)Rb z6<gZX=(sUT$b$H)&yskwXa*WtRFD+0L*GbO<>@Gu0G&Kikcr-;8ajEdU`$jqJLHwh zPe%8Sz9r<ff?RZc^s_<UD;STiocO4dEd^(za&AD#7X_8*TK<D3fBsqcuCH&yfboQD z_h_)zr%WmV+b<YQ3>6tb3TjfXG+Sc<?cMKD#_U!4mt+uAdQ}f3tj@b#$E5`p_@28e z7uyfcOK>DSbOP|gpg`UB{#F%h`+EOx-6rmtmhCji$cUV)vYzeSk!jenVSL#9gtV&m zk8?0*bF)hy&@NgUH-<AKkKet~sL$7LA~%N3qh;_I^Fn`_B2=Wio!jzZX>e-KN~l2I vGNsvba5>~hRy;3oy+G`q`BChQ$(xqOHnD*`-M4*4|ER{WiK;_e>=dov9U1Cr diff --git a/doc/build/doctrees/source_rst/hardware/mb/mb_2024.doctree b/doc/build/doctrees/source_rst/hardware/mb/mb_2024.doctree index b23f498d4f879fcf7ade256089744280d7090c77..06834448c818a05dde7b24827271a79c7ca4a950 100644 GIT binary patch delta 2903 zcmZYBYfw~W7zglu4k+Sn#iqc?3xcpW_9E&M>6BO|XpP!vHTppvZDw0d9nHxuj?k2W zq@asEXo8XsUI?f4wq9V6HBb~Un2HFA5Kf{7<KQ@$qxGEgybbRezbwl+|NZ}XpMB5a z{MZmy*%X$Z2LqIZjw41mwj^|n$zZ^iWsn}2_9@H(=!+SjK}O*EQfL|lW-OTpivz>* zV0nnISITgN7FePkQ-UU+f5Zfwn+N?Nh@L!{h7|}=N~;MY3SeyS?>y1oW)ng!xRoXo zRvv;F%qfC6ypRuJxHTVAjG<<OVdW~1%kvdwADeK&VHizWAEa2I0XLOEIYi;00vOkO z9R*%C`}`&g494`GV5Rew#o)$s+h7R1#-a5T8fVr-NW=w&kcx#rL8@_%%)D!6CebW2 zOSvJN8WuC-k(eZ`FMvqc$e|nxWeX-#Wpa&vS=c3nOr220AI_x@2U)1l39UOxxWl15 z3bhKMnHSPoL_<4SL__Oik%sn<u$pz&P#j%ML)$_%LoDjhlvga6u@ls(($tdh?_GpV z;M7)1C0qD=a$BVDsbV+HZl0{owD9cQ7I}6nxn~>oEVuYlI;|jMGr-5^3+a5Wa5iX8 zDqh$FX~v^6u~!fqbi_HX*g+L%ctO9(Mly!)rv=^P)GkW>C7?C|HSH&8fK{5@zXEEL zA!Vdh+q}JYQ^#;@IRddh*QhXfRedY=T(Yn4`bZ^31ou+#4fX5@98?2QFdqHCLK@yL zg|vZ-WbXr<>4!vRyj2>VvRbt4qn1@Y+zK5RX^m9!MX;2DTO@9?%55HaQkF_t+N_f< ziGl-EP}?Kb$P&5_L8Q_tk_RdIK%&}tW#NZul7ns1BtvbyE82Bnyp3-Iho~mjrftG# zo3sg&aq>~p-Vw0?#on^<E}UpncVQ|<1&I1YrsgsQ6VZP{`##irgtA6-9HWjenfhE$ z%{oq0fryn+Y@47^P?y(2FHATAZyQg^-a+A^&bum#%BiT1y^DHpVHtUkM68lx4~5qu zJa;)QEiyrxVt9f!Md;8`wgldfLF%9zLKQ7KPW=(<OZSBF)trngDoC3qlGT(<RU^D1 zmB|S_%*m%nTq=w6S)_!#CBG3pXQ*c_i(kJWW&}z6StQR>a)%^t7h>*dx@FBh4U>#j zG8+)=b{*Rw%4(_XI<vpatiK+TF}I4?Cn9;7l8+^}OJk>CVKwwYZ#A()?b3V)+Ig3D z=~$PY=UYc*c6@jiM)*#}^aCrujV|g(GuG%GXNjI6($^^co*GF~rrOo<PQlU|QopDn zb)~F+EYzuXdB)$1p6k@}ZI7Dqf_mUQse45FCZ%_?S|rr;T9|4)Cxc}IEYg9uL`5T2 zH1>cuUI5E468K!Cn<@R2!EOQOTq1C!Lz?SL4xVeb48k}ZSx^6gZc{^|L%aB$j{h%y zZJxDtbi<y_sWwWz@8D~Hx`XFgc!i+VGUOG|bcZxb_<<|#P(>C)>-13LRf2xuR6C{i z38+{=rPm0$Btw+~D%L@Na>YHWxXsWXGBg81Frtx`+(7|@lNa+$7-cueh<8d;i*oYR zp6QI&xuTOQlAPMq#yWLVdvcQ&Glx@Ml=@IWvz$D&^Nj?pk)dS*n&p(IwuvhqQN>1v zvh`4(TLk$z)lI1b0xA*E&07Rrm7!_@mFS?mT=9e|?l9EKkkX(&=Ea1kh8PTVGHAk0 zA3;32TA;sDK~I*Z7@Xe%1Jq~EKz0kP2!Yvw=WWmy65(<g3|_nXVpd<`T-bFN#)L(y zzYKGsy&X(%s+lb9e3thHsPEI_)Yp7Ep6OMiS>7NW$@Iq2({JV~PyCuZvsUVvs5biA s!Kw^%1uEKU46qRE@4*$N%;l?#b%aKHkGtsa8;(!!gBt>v_y89D2Z?6+t^fc4 delta 2827 zcmZwJdr(w$6bJA<S7CkBu1uqdr7Q_9Ty|OTmFZ}rHZ7LZ*fgb?8uoD8V0;zUm<^Em zNF0y_PMQg%FcKO{>?}&N%E%b%U_O|D2FS3~1QMsgacb1gy}y(DYw@4m3;Vs_&+OTA z_ilZ=v8c_MSpbhJSv_7e)TRyYnqV+s@+QdiJ)aJ*0p@LjB%gH^v`1s*a(K_TssL6G z!gtCb3E$lX5lXcckCegW&}^5*U1h~oKTL&#m{$l+oVgpE=4PwGu<ip_qH6;MPFb<O z9Fi!IS_IdX>wNB~^wRHE&k<{!(q+Y{Vu-`-MG)aBagFngtcg&D#0p~z<w9bGp&)z( zd1f_Ms(&I@uUC{<4<zdyeq|P)yOqwJ5vv(64K2l>{zpV&b}@u2%Q%-qxg~5Y(hMi& zmVgnLlt8jMOV-x0wn)+nxn&2n<O?k~NZau>X<p9lq+B&?RYF_7kEYftLuVMOlAs<g z$ftro1avhB`l1ZN;Ss#BAEty9QEVtCAAm?)T?eC;&^X*#2+yIr9GoUcoHWBIJW&o4 zAr!+7i5dA}uINDOn5}h;_asIeVWxH{ridqMAj&f%KOEi^(Jv|bhQuw6!>|_OIy0zv zV+G7JZI;asg}GERcZ;GuRD=PuAjrg;N_vmSM7D&oJ_)U1bn`)&Z|ab}AB9&VdACGI zDRulA@VbLM&#=$Kl`vIoV;N;ls=kfNa8<m)!YY_=o~%mqoS=%G9Igg-(#Z|w)bOmT z@BJJ#u=iq|;cB?z;@~$Fe4D8iOkJ*qA$YJF=9st3-bVITNM145R8q|z;q40YrYXlc zR7Iih**ePBO)pt>Ub4DmtC_8%l69MF4pYrv!s-jMqOi|L*TATFeU2eDlza>q*1=QC zh<Gu^d$r`9sU`2}cxjgL@nV)E;sdi>z%5>CnUASHP-)NTX}l-XWz?^6eVlmz7?J55 zK1yM?AXhSJ$)we6se^guJeka9a-~G>=aysCQYy&34<k)}A{#jDr*OR>{Y+l=)3RKX zwKmrLlJ*Z59H)XiLhFB+HnyI$$8BOaPf~caP3-1Kn;7cNdg5l;q<JRV#5_mZ0`q){ z8ycwLMVr2xFW7>16KxG-t>t7RC0DVP#@4+CvI=Eu3tMTDRlyCXsi9n0`+_VBPXB?v zuTFEaiIS(-I;mSuG&Mqsxkt7-**Y1pz<^n&VM^#ZD!41CzXwn$XJ9l~MDQX7$J)gN z$Jn(AI&th-lIGf_2~M$#368Npm>|3=3NBH>%XWQ$3+?|OpamB-k+fa}TPXNGOKVuN zog-<tEakAYMv}f21+7$2DWn4fq?PAMIwykd6g<mPBTF+bkaSCyuCUY?kd%-FajkYx zgMvwI;vS&fAHZc?qE9P^)4x*sNi8kzI`jn1kZ*D(NE4inrOhx=iA;DfK;?Bly^Bs? z`~ZVjw8Ov+$AX{zMApX~zDnVbBr8L+QgCq#q?n3jaHjw>B=9@#xJDg^1K^=xu%L~= zOC0W|@OcSr5@2pFgkbv5bc?$!tJj6vB&ow3;#%#YBBMiJl);YRMcLO*q{_)YN?ILa zC!-x=C)an-=eNKiP4pRuzLOA*(8;%OC6ya)QNuD}Eg4`{|3X$4C;KV+30oW3+I*R; z{jycW)&|L{<%ZkT;1yOiTWtt=9<OzrZ|W6TI|yQY6<6W6L1BhOgTZ~5dfj)lhkgg{ zy#bSqecB(r4s5*vR*RO|roX<;-3r=qN{sgCqW^Do_c<`K8%7P)N?fzGhFRU9D!mS$ oyPJL?z$DD>fs0B`qUXZ+guxc~wnUouI4tj_U#nZNqZi)#7n=p(6aWAK diff --git a/doc/build/doctrees/source_rst/software.doctree b/doc/build/doctrees/source_rst/software.doctree index 85ce1db6a4efc944b4b837cfcf6b42a7179803a3..8bcaf5519f0bfb69616a44bea3c7e4baac683e97 100644 GIT binary patch delta 924 zcmbtT&ubGw6mHTcX-aIVMXSWtts-r)+KW)Uc~DRb^+!E;33Yb&C2wJ~v(C(#R*A8P zS_1<j`=nR#=s_$2Z+g;y!@t3^9&|Rp8myii7-pFFzHi_6y|-WArN5lXJj=YkJh`9w zkV>UnA5-%qsZ9JWvvTdy;x^T30W<o+J@lj{!BHL$EEg2>d}&VU2+sy-DFo~GmO>Mh zysT<WfW-pWLSBnMZx`3RKq?VcAy5|yb0xy#|4TVNNV!9uLW{T_Ka7{+H&?P(b6CUz zp2FeC#=IVNcs1lv;8ILIRhVs;GNf~gJ4yf?ip4B{vVlcCC3z$q*bq`J_w<p@89BlO zNhMm)$JYD0g@c|lRz(6x8$S*~m)T&-bJB$y#vkVUEV1_wOry)YoCxmc7|@AZAqayA zDsB4@{2)F1w~z8pIu9fn^yGD3vlO=+o`|p`^{-kRE<6IChe`7iB<O+{IDX_p+4DQ% zF~UuJf=@w@R@tTtp+dU(%PgI9SlHIIrbjA1x2dVK=(#Qg=60mZ(|;HZqN)u7Tv{E{ zW6D#8pEm-3%OsBpRvYje71r=E)*-_4SjHJ#!r9flX}J^G3{NLhJ7>o1Y>D(lx4Rc= zf`!HdVtCGk=FMI#QG#c^QR(tbL^kv};-kCwQ|WlWIMaHu`!kitPkJ1L;3B@$oNB#o zz8_xESz*j@rTJNOE?`yY+;I;{>U{E`wnAf7op7%yan78C1sT75^?iDW?vfr4nUJti O1u0pj?P>gjR(}Kehi$6> literal 38213 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 OM`t1@xm<Uy{Qm*ziXRLB diff --git a/doc/build/doctrees/source_rst/software/architecture.doctree b/doc/build/doctrees/source_rst/software/architecture.doctree new file mode 100644 index 0000000000000000000000000000000000000000..7ba0552a2506dc8f53c541e5003077e88ce98162 GIT binary patch literal 10705 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 HN5k&`EF-CY literal 0 HcmV?d00001 diff --git a/doc/build/doctrees/source_rst/software/developments.doctree b/doc/build/doctrees/source_rst/software/developments.doctree new file mode 100644 index 0000000000000000000000000000000000000000..8afadea191191b2213ecd5e6275186d5d1b3dd0c GIT binary patch literal 2121 zcmZ8jO>Y}F5OqFeOSUE3NgWhueC$UKmIJf}iX3`LZ${msKzpeIf+D$E!d!Ao&f4-J zKzk^V0KA3$zkS?Y$(9TlUOo<IhHu^s{rBL%ABQ{bPdo~BsqJ#grL<0}km67}(NxM( z`jlS%lisIq;>h#c;2JMfiaW3nr8d$lo8G0k&xyRAH-xj<_KB7u<9ovJ5CGzPV0qPj z4P{f`FXmiadsVbHyQ=_yzI`+MJt!Y$UJ0XeCbOUVl)~)W*XORRYCZd<tbWxq<T~pP z_J5cUgwKL*xmPo(Zj^C#_7SGoNln}%zQ`G*@==_K#^V~q`q)?TaD^CcRl179pop|x zfR~fZ3uzOkg?E;el_~E2!A*mkt(h8-CX)}27RoBm$@#pH9P|*cYAg=AU<?tivE1*M zjW<}0$qANe$-4+TKz9Bv#b<?cWF4soo0pH`I4D83so1h`zDhtQ0oACPa8-M0xcs6+ zR7YiCx0*_}Dh?v{2l{G(0<UW4iJ8n@x_lh>OK#T7K|E1Q4aSI56IMopIFM@IED&x2 z;w>11g;%@+G9u4~%9lzX;zZlJA*QTw5>_dW8Y<3zI1d`%FE=-t^4@t?ax0DUU^}NO zD8(b!(59C`>m|jrt(`3w<@a&YIlWI{b@b)t#@5MroG%c-QVD(xE|lWfaJy*uLV<3H z^<#8Id=Aw*FPT&|B!Vy+`nZa_!r20M1RYwk8miaJRPM$JZ^*HGC_dKE)mS!F&DPoj zt1X}*J8!wk4v$&{)Y_11e-G6`HPW$VmGyM2mbD9tJv`Y;L=d~tL3jE*Vp0b_H~Auc zmV2w7C||@wTqd9kIB93$bljV<LYuCwU*s<YLEB~<ls9{msP_Rz$9f5Up5(@YZ0rIm zG`iB1em?#>PHI&%kfP9zq9yDwBXf@2b7#cQOQJfwxwrrvru7|_&Q6_QT%>rKE!zZO z$w*Zw51|}G;OAey{tkRjd?B{nXXM`fS1b4ERG#&Et^8CgD%u$6{ELz*gJ2`#bF`48 zGF=Yi83b9eb#JaOz(SoB@-ZHVJ4<}YO1&rzej(nc#%0|fhKi%h{%X+F0Yp7-*WHpC zCwNconJ78(LE*b*1IsOiIDOsJ2r)r+?bPXqz(=UZ32h5#U^Nw<<v9_W`IeoovUrW- zT`N9qM-nts&6Py|-XVojDMFA_0jq1KDy|K~Tj5nZ+dssU>^YY_C{uJZ?PGkR>`l6A z=5g4~5;QNQsIAm!4r0XpLQy;QPmmO(MHsB`A@f`C9@B0E?cNK(@K&rBySat%)BxYh zVE;YJ-*i`l)Ay-7!0z~Ad0P9i&?s^a2p=7iyKrUKCH4^M?B1nZ&T8(=y5g<rXItRf zdbHtjw2ImudbZ&o)6`QQ->2KY`kkG)j~O9clP5rm2f`WC5syb=?`@BN!kzz3zd`Rc y_vjovx&amL0<K5J27IuF+aeukD@-G^C>HJOF7q^7HU5a@H?aNRpnTHIr~d=7#$EXU literal 0 HcmV?d00001 diff --git a/doc/build/doctrees/source_rst/software/installation.doctree b/doc/build/doctrees/source_rst/software/installation.doctree new file mode 100644 index 0000000000000000000000000000000000000000..a19904ed774500050fd30d5de5a52e946fa4ad04 GIT binary patch literal 6950 zcmeHMNpBp-71qXOxKoM@A==s!CDVvzMwS%7U=~=RVOS7MD>9SV2#rQfcg<9hy{W63 z%fW#hz<>$VA&J^Z4$0BKAU`3<A;<g$8!%uXzrZJdRn^;!C7O(~9U@@F?y6U>-uvEC zuU<bM`{exjW9FZl7YXChZio1O6#G=<YSNFrEToalpX4upn17Hjt5!;OM4Y7_&DAkb zc#H>rN~8S!T+L~6$pg_T)=voPNghYlayG`s*~I(#GHa<Z$z?zrQ)=d3BqRv}V%BIn zkeynmyL$hT*^hE7&v-(xyUf|5YPprT?4%kmq+C;{0v^$PE$b0AMWjr5FO$$tYjcwO zLQ6j31w;r8;(070p?#Y4v!s6M5pOG{eNB_82}uTeDrfWTJey$`*hzL#{c?3><7a}V zVk4zqKs9n3uNM%CjoUZdF$)vE@iq$|@C^vNVP!1-xT%nM?8_afw80x#bTE^%OZQJ? zJvMC(Q6k9}%6E139Z3`Cl@(_-jv@f>$k>sLIuD6RdNfV<oCiENsJ?JG+5%%Jc+)Dl z#x7|X*=1nIUW9qB;&%<dm+*TTxUlaTJld9=-GIzv%?0X;fQ;=|+MX4$E#o#sY^SA& z?S$u~WUH=fYOPU0UTRd4JBGZm`&4a>a`yueyKE4<1;m0lq6REu8z)KQO(0mJ^{sR@ zQumIA)Ef<?CWnx^WRSYm_OxgQB;!2oQnVVS%LXNAVMvV@hP2XxH0?8r5Oy6!X!#pX zb$i8mm_>$l(=Q$2r97!%vJUtyv^7+{qe101pqhrzE!9HolR-)n*32Rg-{D~r>^TwH z<^v*ORvQM^vi&&lY3h*3chW*53<dEHj|OnFFw`@#RaMe7<Piy0N<a8_u&(h)506K} zE*kfqg}WPE3?8!qhsY#wdqM1NH8Gi8ayo_KI)atzjEq`I!134OfEZV;-7r`Y3DGCO zWRg<kyKOv<^<#Y~?5oLuM1zbBFm|d(u$!7=e82+yq)XC)&b&HNJT7$53AEJVQJKu% z{p;~#$JUX&3aJZEbNU>q(D70V!wOi@N%kazxwd&KGZHv7!c!dS%<FhKN~rH#(ZR5H z1)Q86#y#d>*zsvXBcDbd2b&#^kzTbI^*he%cHT@Q8#^MQ9`AFo1DljS%6MwhyXeSW zIrR%hpAsBgXopGyDzVIC)Z0P;5jnKn(ab|ColIy4OnBl1T*%JUJ*02Vwa_2BIxs3U zeCwy{>rO9?x8TKApHloxU>`WU2j$@fTu`H`J_593XA$?z$qH5F4lN{RB=z-qbHgc5 z9upfpf+zK1V_`%gfrxcFNob15LN@O6K?c*CjBxMPs?)>fqKun5JwM=`!r9*a+rP}9 zpFRGgG3jTI|MY*O{+EneXRY5KJ!_qLTEweAJTr>mbx1BD^=~*k)QPBdbCjvZ{cK(j zV?PV3T;EIsy*-EeT<Y-Bq440n^*7&MdvJICO(#x=W;!}sr5<t&7!l#vb3s(u|9@A& z+8Uo8-5Tc_*7&f@ziMF#2WS*Kzv>pSl!wMQC#rMf&j+0w>^JPU?05U@NpUK$Plk_y z?>5A!jsbQ4E{@~U()B^DEBeYV2h!Bg{N?D-Tx!TvL-YM5x|_tQY`D^omTI?J>9RPa z-5(+&ruvHT<F4`062E_Pbp`U@p9f^8R)|(rd{LC&ZlfSFg=VwFYZoP6U2fW<993Rf zKQ+nAitxaaQ&(>z*O+F>*)di5ofYRUE|1%$f<xSzl>fAIz6AED%WBW~$KgFg7b{;{ za#Mg^gDSPRMn9oQRFD-J3rB5{aWp=uxkeA?uS02v;zTl&xN7e&%G4?V{?psm$bEHq z<jRuudWj&At7B?;$?<$78xty1ODINki@_Sb+v8D}6lj&!KKz0*ayBPXfjm#}EH@;t zZN74^@9f1{bu0yxY}>2kQ)*IFS@v=w_mVn+Jr9e@7Mtgw-qFp`ZYWioV`d2z@+joP zgB7gTpA*(@EkPqEwaxYSPP-JMx&iOC3tZccL%z{7=$P9uvPZen1kbax$AOs&;oXpF zrkUv)TaJ#8^dn9-@&!6L&u*VoJu7xYUyzQgIWJ3fcgwAMSu^E`?P;k=L8VSKXx1%O z-M2n&KoZxRT#f&n1R0uHW&4iJuc_96MmjykX^t0PU!)`n6TD2@ZCvo)!s}G=nxz5W zW@YTTx(B9bvE7)yW$fkZbU%(|6ieEeynkHH>egSBh3>8{-Exe~Aq(=v)yWG>1z4W9 zBh+@vgsW4XTXy2GW3ixU&8?}Kl<ITW4d^xv^7|*$6eB_PI;IxsE(cbU$V`+(V`|K& zy=;K(=5Wu6fE6fke+)6w!ad2OTB-bFHOHeQlP>Oru@9<TwKCanzuFcY&liR#U9{8U z)MaQE1T+QCT2%Cl)O?)DVJ>5aORg@C%#5(u<Om}*XZhALl&dccPmC;93t9&Opco(u z%+-9hyoLjDA9wK+=+UY(=u5__?>4W$z+v3p=rkhScX6lh^WB_{t2vU%*sX`u2@a>4 z^|LT>E5`${X24t-(Jj%Ioi`&uHxk<X^-v;c=Ep8t2%uWfb(ElPbEWYTPrBP&aO<M; zuFnPO1r&<tdnXo7lmWqRs2M0D5CXPo46iB3TwTVShVBdc37eoE(~V_VSab7X@@X`) zt5>+_qK+zfPBefc20Y|4e{10-HJ8xD1t=7;h#N5kn9(D+E>KqohdRfkOvFmJi(%2R zEs0K?4!XHIt0|2DpmZfgKL8P@J16LaUb}e*c+RDLZ-l)bso7sI*&|qqc3Is0JDkeC z*#lwUWikw~Sxb^0qR5vlzdxxi!Y4zw3eQRb*EVnV)q>cIB-wSV_6#~U=r+RLXGBO4 zXpb_)wE$3O%)5PcO&`KSd(lJx0Ew2SHr{};fe@>=vINZ_{Yk*|`HMWT5ATUR9`)e^ zWnwt3Q-#QSBXm4O4+)zQ8;!b)zm>yh!XEVz!h5hTqf}y(vuJ#hEtiIb2QDrPXiVr{ z{>N&u`2GNA4f-~%?W>bGH}uy4HEGic;uo&SBOfgtIG#j{iXuJXOTZ$8f@?{9(}3If zy7&J965i0L{XT$UaO+nu<2r=!X#wLCdeA;EZ>}Q9H(%2S^(uRfZLs&)7wq%RAL!9n z@n5D|npzhJ=KF-9-)F1)Y-68&v2O_XGxj3d@0QC9xU|9L4fZ*64GZ>Vre>QqH$u#M z9G;`KfM9k+hjvM4wQY`AI$!`F343u+xsf6L&d6Xz-5TQ9Dt9%DP7m=%mQJNU7S4|H zDrSzUDI^{*&U7a#SJNK4w6G6!z~M8oT8uvd#2@7k5k%+(BOLMNM!;?ChE@I<8lJ9( cjpe6#<OP|pJ#C<kKIQ8aS!5G^a%a8H*UlR%IRF3v literal 0 HcmV?d00001 diff --git a/doc/build/doctrees/source_rst/software/operations.doctree b/doc/build/doctrees/source_rst/software/operations.doctree new file mode 100644 index 0000000000000000000000000000000000000000..2129f78d343b753896edab13c74b3f8f8f60a514 GIT binary patch literal 33042 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 literal 0 HcmV?d00001 diff --git a/doc/build/html/_sources/source_rst/developing_hardware_components.rst.txt b/doc/build/html/_sources/source_rst/developing_hardware_components.rst.txt index fa97c06a..55736fb5 100644 --- a/doc/build/html/_sources/source_rst/developing_hardware_components.rst.txt +++ b/doc/build/html/_sources/source_rst/developing_hardware_components.rst.txt @@ -1,7 +1,8 @@ Software interface to new hardware components ============================================= -*** DRAFT VERSION - TO BE REVIEWED * +*** DRAFT VERSION - TO BE REVIEWED *** + This section is intended for developers of a new hardware component as part of an OhmPi system. It presents some advices and best practices that should help developing new hardware components to work diff --git a/doc/build/html/_sources/source_rst/hardware/mb/mb_2024.rst.txt b/doc/build/html/_sources/source_rst/hardware/mb/mb_2024.rst.txt index e7c14fe3..57d84aaf 100644 --- a/doc/build/html/_sources/source_rst/hardware/mb/mb_2024.rst.txt +++ b/doc/build/html/_sources/source_rst/hardware/mb/mb_2024.rst.txt @@ -126,6 +126,9 @@ Soldering `DIODE <https://www.fluke.com/en-us/learn/blog/electrical/what-is-a-di | | Installation of female header, 1 by 10 pins, for ADS1115 | | | | +--------+-------------------------------------------------------------------+ + + + +--------+-------------------------------------------------------------------+ | | .. image:: ../../../img/mb.2024.x.x/5.jpg | | 5 +-------------------------------------------------------------------+ | | Installation of female header, 1 by 10 pins, for ADS1115 | diff --git a/doc/build/html/_sources/source_rst/software.rst.txt b/doc/build/html/_sources/source_rst/software.rst.txt index d31d9d8e..01327174 100644 --- a/doc/build/html/_sources/source_rst/software.rst.txt +++ b/doc/build/html/_sources/source_rst/software.rst.txt @@ -1,250 +1,15 @@ -******************************************** Software and operation -******************************************** +###################### .. warning:: **OhmPi is a participative project open to all, it requires skills in electronics and to respect the safety rules. OhmPi must be assembled in a professional context and by people competent in electronics. The OhmPi team cannot be held responsible for any material or human damage which would be associated with the use or the assembly of OhmPi. The OhmPi team cannot be held responsible if the equipment does not work after assembly.** +This section details describes the Python software and how to interact with an OhmPi instrument. -System architecture -------------------- +.. toctree:: -The OhmPi V2023 software is designed around a new architecture whose main components are summarized in the figure below. + Software architecture <software/architecture> + Installation <software/installation> + Operating the instrument <software/operations> + How to contribute <software/developments> -.. figure:: ../img/architecture.png - - Software architecture of OhmPi V2023. - -The general system configuration is defined in the `config.py` file covered in the `Configuration file`_ section. -The acquisition settings (i.e. injection duration, stacks...) are defined in a separate JSON file (default: ohmpi_settings.json). - -The central software component is the ohmpi.py file that contains the OhmPi class that interacts with the hardware. Other python files include utils and handlers (see the `Loggers`_ section for more details). -A communication layer (I/O interface) on top of OhmPi allows for different user interfaces depending on the use cases (see `Interfaces and applications`_). - -Loggers -------- - -Loggers have been introduced in this release. They use the excellent logging python package. -Specific handlers have been implemented for running with ohmpi.py (one for logging to an mqtt broker (see `MQTT interface`_ for more details) and one for creating zipped rotated logs on disk). - -Two loggers have been defined. The first one is dedicated to log operations execution. It is named exec_logger. The second one, named data_logger, is dedicated to log data. A third one is planned to log the state of health (SOH) of the system in a future version. - -By default, logs are written to the console (print-like), stored locally in files (a zip is created after some time i.e. every day and/or when the size of the log exceeds a maximum size) and sent to an MQTT broker. Different logging levels may be defined for the different logs and handlers in the `Configuration file`_. - -Advanced users may write new handlers and edit the `setup_loggers.py` file to customize the logging mechanisms to their needs. - -Configuration file ------------------- - -The configuration of the OhmPi file `config.py` allows to configure the OhmPi. -A default version of `config.py` is provided in the repository. -This file should be edited to customize the configuration following the user's needs and preferences. - -The configuration includes setting the logging level desired for the different loggers and handlers, setting the mqtt broker(s) used for logging and control of the OhmPi and defining the options used for MQTT communication (i.e. username, password, security options...) - -One should make sure to understand the parameters before altering them. It is also recommended to keep a copy of the default configuration. - - - -Interfaces and applications ---------------------------- - -Different interfaces can be used to interact with the OhmPi. - -Available interfaces are: -- `Web interface`_ (=HTTP interface): run in bash: `bash run_http_interface.sh` -- Python API: import the OhmPi class from Python script: `from ohmpi import OhmPi` (see `Python interface`_) -- MQTT: IoT messaging through a broker (see `MQTT interface`_) - - -Web interface -............. - -This is a user friendly graphical interface for new users as well as running quick and easy acquisitions. - -The Raspberry Pi of the OhmPi is used as a Wi-Fi Access Point (AP) and runs -a small webserver to serve the 'index.html' interface. Using a laptop or -a mobile phone connected to the Wi-Fi of the Raspberry Pi, one can see this -interface, upload sequences, change parameters, run a sequence and download data. - -To configure the Raspberry Pi to act as an access point and run -the webserver automatically on start, see instructions on `raspap.com <https://raspap.com/>`_ and in 'runOnStart.sh'. - -Once configured, the webserver should start by itself on start and once -connected to the Pi, the user can go to `10.3.141.1:8080 <http://10.3.141.1:8080>`_ -to access the interface. - -.. figure:: ../img/http-interface-pseudo-section.png - - Web interface with its interactive pseudo-section. - - -.. figure:: ../img/http-interface-evolution.png - - Evolution of quadrupole apparent resistivity with time. - - -.. figure:: ../img/http-interface-rs.png - - Contact resistance check. - - - -Python interface -................ - -This interface offers a more direct access to the software components especially well suited for testing or automation on the Raspberry Pi. - -By importing the `OhmPi` class from the ohmpi.py, one can control the OhmPi using interactive IPython. -Typically, it involves using the terminal or an Python IDE such as Thonny on the Raspberry Pi. One can also connect using -ssh and run the Python interface (see PuTTY on Windows or ssh command on macOS/Linux). - -To access the Python API, make sure the file ohmpi.py is in the same -directory as where you run the commands/script. The file ohmpi.py can -be found on the OhmPi gitlab repository. We recommend downloading the -entire repository as ohmpi.py import other .py files and default configuration -files (.json and .py). - - -.. code-block:: python - :caption: Example of using the Python API to control OhmPi - - import os - import numpy as np - import time - os.chdir("/home/pi/OhmPi") - from ohmpi import OhmPi - - ### Define object from class OhmPi - k = OhmPi() # this loads default parameters from the disk - - ### Default parameters can also be edited manually - k.settings['injection_duration'] = 0.5 # injection time in seconds - k.settings['nb_stack'] = 1 # one stack is two half-cycles - k.settings['nbr_meas'] = 1 # number of time the sequence is repeated - - ### Update settings if needed - k.update_settings({"injection_duration":0.2}) - - ### Set or load sequence - k.sequence = np.array([[1,2,3,4]]) # set numpy array of shape (n,4) - # k.set_sequence('1 2 3 4\n2 3 4 5') # call function set_sequence and pass a string - # k.load_sequence('ABMN.txt') # load sequence from a local file - - ### Run contact resistance check - k.rs_check() - - ### Run sequence (synchronously - it will wait that all - # sequence is measured before returning the prompt - k.run_sequence() - # k.run_sequence_async() # sequence is run in a separate thread and the prompt returns immediately - # time.sleep(2) - # k.interrupt() # kill the asynchron sequence - - ### Run multiple sequences at given time interval - k.settings['nb_meas'] = 3 # run sequence three times - k.settings['sequence_delay'] = 100 # every 100 s - k.run_multiple_sequences() # asynchron - # k.interrupt() # kill the asynchron sequence - - ### Single measurement can also be taken with - k.switch_mux_on([1, 4, 2, 3]) - k.run_measurement() # use default acquisition parameters - k.switch_mux_off([1, 4, 2, 3]) # don't forget this! risk of short-circuit - - ### Custom or adaptative argument, see help(k.run_measurement) - k.run_measurement(nb_stack=4, # do 4 stacks (8 half-cycles) - injection_duration=2, # inject for 2 seconds - autogain=True) # adapt gain of ADS to get good resolution - - - -MQTT interface -.............. - -This is an interface designed for an advanced remote usage of the OhmPi such as remote automation, data consumption by multiple processes and interaction with other sensors in the scope of a monitoring. It is based on the MQTT protocol, designed for the Internet of Things (IoT), to interact with the OhmPi. - -This option allows interacting remotely with a single OhmPi, a network of OhmPis, as well as auxiliary instruments and sensors. The communication is based on a publish/subscribe approach and involves a MQTT broker. - -An example of MQTT broker that can be used is `Mosquitto <https://mosquitto.org/>`_. Depending on the monitoring needs, an MQTT broker can be set up locally on the Raspberry Pi, on a local network or any remote server reachable through the net. A local Mosquitto broker can be set up and enabled to run as a service on the OhmPi using the bash script install_local_mqtt_broker.sh. - -MQTT messages include logging messages from the OhmPi and commands sent to the OhmPi. These messages can be examined easily using a third party software such as `MQTT Explorer <http://mqtt-explorer.com/>`_. - -Commands sent on the broker are received by the ohmpi.py script that runs on the OhmPi (make sure ohmpi.py starts on reboot) and further processed. -MQTT commands are sent in JSON format following the Python API with kwargs as illustrated below: - -.. code-block:: json - :caption: Updating acquisition settings. - - { - "cmd_id": "3fzxv121UITwGjWYgcz4xw", - "cmd": "update_settings", Depending on the experiment needs, MQTT brokers can be set up locally on the Raspberry Pi or on a local or remote server. - "kwargs": { - "config": { - "nb_meas": 2, - "nb_electrodes": 10, - "nb_stack": 2, - "injection_duration": 2, - "sequence_delay": 100 - } - } - } - - -.. code-block:: json - :caption: Check contact resistances - - { - "cmd_id": "3fzxv121UITwGjWYgcz4xw", - "cmd": "rs_check", - } - -.. code-block:: json - :caption: Running a sequence. - - { - "cmd_id": "3fzxv121UITwGjWYgcz4Yw", - "cmd": "run_sequence", - } - -.. code-block:: json - :caption: Running same sequence multiple times (nb_meas). - - { - "cmd_id": "3fzxv121UITwGjWYgcz4Yw", - "cmd": "run_multiple_sequences", - } - -.. code-block:: json - :caption: Interrupt current acquisition. - - { - "cmd_id": "3fzxv121UITwGjWYgcz4xw", - "cmd": "interrupt", - } - -Custom processing of messages and tailor-made dashboards for monitoring experiments may be designed using a browser-based flow editor such as `Node-red <http://mqtt-explorer.com/>`_. -This may help designing complex IoT experiments and monitoring systems in which OhmPi is a component. - -Examples incorporating execution commands and data outputs from OhmPi can be found in the OhmPi examples. Once Node-RED is installed on the OhmPi, these examples can be accessed separately by running a command in the console such as : - -.. code-block:: console - node-red basic_ohmpi_flows_node-red.json - -These examples may require installing some additional node packages in order to work properly. This can be done in the `Palette Manager <https://nodered.org/docs/user-guide/editor/palette/manager> within Node-RED. - -.. figure:: ../img/node-red_flow.png - - Example flow in node-red to interact with an OhmPi. - - -.. figure:: ../img/node-red_interface_control.png - - Example of a dashboard UI created with node-red to interact with an OhmPi - control tab. - -.. figure:: ../img/node-red_interface_data.png - - Example of a dashboard UI created with node-red to interact with an OhmPi - data visualization tab. - - -For more documentation dedicated to node-red, please refer to the Node-red `cookbooks <https://cookbook.nodered.org/>`_. diff --git a/doc/build/html/_sources/source_rst/software/architecture.rst.txt b/doc/build/html/_sources/source_rst/software/architecture.rst.txt new file mode 100644 index 00000000..ca25b7f6 --- /dev/null +++ b/doc/build/html/_sources/source_rst/software/architecture.rst.txt @@ -0,0 +1,52 @@ +Software architecture +********************* + +The OhmPi V2024 software has been completely re-structured to enable increased flexibility for both users and developers. The software is based on an object-oriented module with a class exposing the OhmPi +functionalities used to interact with the OhmPi instrument via a web interface, IoT +communication protocols (e.g. MQTT) and/or directly through the Python API. + +.. figure:: ../../img/architecture.png + + Software architecture of OhmPi V2024. + +The software is organised in several modules describing the system in a hierarchy including three levels of description and +operation of the OhmPi. + +Hardware components +=================== +On the base level, the five main hardware components are represented by distinct classes exposing the +components atomic functionalities. Theses classes are abstract classes in order to provide a common +interface for different implementations of a component. From these abstract classes concrete classes +are implemented representing the default properties, actual capabilities and ways to interact with the +physical modules or boards. +Improving an existing hardware component or introducing a new design may be desirable in order to, +e.g. reduce costs, improve performance, adapt measurement range to specific applications, or +incorporate easily available electronic components. It is at this level that software developments are +mainly expected to occur following updates on the hardware. The component class should expose the +minimal functionalities required by the hardware system (see below) for this type of component. + +Hardware system +=============== +On the medium level, the OhmPiHardware class provides a mean to assemble and operate the +acquisition system. The methods of this class orchestrate atomic operations of the system components +in order to expose basic system functionalities such as cross-MUX switching, square wave voltage +injection or full waveform voltage and current reading during injection cycles. These functionalities +are implemented using synchronization mechanisms between threads in order to insure that each +component keeps in step with the others. +The whole system is described in a configuration file listing the hardware components and versions +used. Through a dynamic import mechanism the modules containing the classes corresponding with +the physical hardware modules of a particular OhmPi system are instantiated and associated with the +system object instantiated from the OhmPiHardware class. In this way, it is relatively simple to build +customised systems once the concrete classes describing the system components have been written. +This part of the software architecture should remain stable if the overall system functionalities do not +evolve. However, the introduction of new functionalities at the system level or radical changes in the +way the components work together will require adaptations at this level. + +Acquisition +=========== +On the top level, the OhmPi class (in ohmpi/ohmpi.py) includes all the higher-level methods and properties allowing to +operate the system (e.g. acquire measurement sequences). The OhmPi class exposes the user-oriented +API, generates logs and handles IoT messages. Generic users are expected to interact with the system +through these higher-level functionalities, which are designed to remain as stable as possible while the +hardware evolves. Only the introduction of new end-user functionalities should imply new +developments at this level. See \ No newline at end of file diff --git a/doc/build/html/_sources/source_rst/software/developments.rst.txt b/doc/build/html/_sources/source_rst/software/developments.rst.txt new file mode 100644 index 00000000..e69de29b diff --git a/doc/build/html/_sources/source_rst/software/installation.rst.txt b/doc/build/html/_sources/source_rst/software/installation.rst.txt new file mode 100644 index 00000000..0052606f --- /dev/null +++ b/doc/build/html/_sources/source_rst/software/installation.rst.txt @@ -0,0 +1,49 @@ +Installation +************ + +Step 1: Connect to the Raspberry Pi +=================================== + +Step 2: Clone the OhmPi project +=============================== + +Step 3: Run the installation script +=================================== + +Simply navigate to the OhmPi folder and run the following command on the terminal: + +.. code-block:: bash + + $ .install.sh + +The install script first creates an python virtual environment called "ohmpy" in which all dependencies will be installed. Dependecies are specified in requirements.txt +When the installation is completed check that requirements are met using pip list. +It then installs a local MQTT broker which will be used to centralise all the communication between the hardware, software and interfaces. +It also properly configures the I2C buses on the raspberry Pi. + +When the installation is performed, we need to add the OhmPi module to the environment by editing the PYTHONPATH or editing the .bashrc file as follows: + +.. code-block:: bash + + $ nano ~/.bashrc + +And add the following line: + +.. code-block:: bash + + $export PYTHONPATH=$PYTHONPATH:/home/<username>/OhmPi + +Step 4: Activate the ohmpy virtual environment +============================================== +Before operating the instrument, we need to activate the ohmpy virtual environment with the following command: + +.. code-block:: bash + + $ cd ~/OhmPi + $ source ohmpy/bin/activate + +If you need to leave the virtual environment, simply type: + +.. code-block:: bash + + $ deactivate \ No newline at end of file diff --git a/doc/build/html/_sources/source_rst/software/operations.rst.txt b/doc/build/html/_sources/source_rst/software/operations.rst.txt new file mode 100644 index 00000000..c19b404c --- /dev/null +++ b/doc/build/html/_sources/source_rst/software/operations.rst.txt @@ -0,0 +1,230 @@ + +Configuration file +================== + +The configuration of the OhmPi file `config.py` allows to configure the OhmPi. +A default version of `config.py` is provided in the repository. +This file should be edited to customize the configuration following the user's needs and preferences. + +The configuration includes setting the logging level desired for the different loggers and handlers, setting the mqtt broker(s) used for logging and control of the OhmPi and defining the options used for MQTT communication (i.e. username, password, security options...) + +One should make sure to understand the parameters before altering them. It is also recommended to keep a copy of the default configuration. + + + +Interfaces and applications +=========================== + +Different interfaces can be used to interact with the OhmPi. + +Available interfaces are: +- `Web interface`_ (=HTTP interface): run in bash: `bash run_http_interface.sh` +- Python API: import the OhmPi class from Python script: `from ohmpi import OhmPi` (see `Python interface`_) +- MQTT: IoT messaging through a broker (see `MQTT interface`_) + + +Web interface +............. + +This is a user friendly graphical interface for new users as well as running quick and easy acquisitions. + +The Raspberry Pi of the OhmPi is used as a Wi-Fi Access Point (AP) and runs +a small webserver to serve the 'index.html' interface. Using a laptop or +a mobile phone connected to the Wi-Fi of the Raspberry Pi, one can see this +interface, upload sequences, change parameters, run a sequence and download data. + +To configure the Raspberry Pi to act as an access point and run +the webserver automatically on start, see instructions on `raspap.com <https://raspap.com/>`_ and in 'runOnStart.sh'. + +Once configured, the webserver should start by itself on start and once +connected to the Pi, the user can go to `10.3.141.1:8080 <http://10.3.141.1:8080>`_ +to access the interface. + +.. figure:: ../../img/http-interface-pseudo-section.png + + Web interface with its interactive pseudo-section. + + +.. figure:: ../../img/http-interface-evolution.png + + Evolution of quadrupole apparent resistivity with time. + + +.. figure:: ../../img/http-interface-rs.png + + Contact resistance check. + + + +Python interface +................ + +This interface offers a more direct access to the software components especially well suited for testing or automation on the Raspberry Pi. + +By importing the `OhmPi` class from the ohmpi.py, one can control the OhmPi using interactive IPython. +Typically, it involves using the terminal or an Python IDE such as Thonny on the Raspberry Pi. One can also connect using +ssh and run the Python interface (see PuTTY on Windows or ssh command on macOS/Linux). + +To access the Python API, make sure the file ohmpi.py is in the same +directory as where you run the commands/script. The file ohmpi.py can +be found on the OhmPi gitlab repository. We recommend downloading the +entire repository as ohmpi.py import other .py files and default configuration +files (.json and .py). + + +.. code-block:: python + :caption: Example of using the Python API to control OhmPi + + import os + import numpy as np + import time + os.chdir("/home/pi/OhmPi") + from ohmpi import OhmPi + + ### Define object from class OhmPi + k = OhmPi() # this loads default parameters from the disk + + ### Default parameters can also be edited manually + k.settings['injection_duration'] = 0.5 # injection time in seconds + k.settings['nb_stack'] = 1 # one stack is two half-cycles + k.settings['nbr_meas'] = 1 # number of time the sequence is repeated + + ### Update settings if needed + k.update_settings({"injection_duration":0.2}) + + ### Set or load sequence + k.sequence = np.array([[1,2,3,4]]) # set numpy array of shape (n,4) + # k.set_sequence('1 2 3 4\n2 3 4 5') # call function set_sequence and pass a string + # k.load_sequence('ABMN.txt') # load sequence from a local file + + ### Run contact resistance check + k.rs_check() + + ### Run sequence (synchronously - it will wait that all + # sequence is measured before returning the prompt + k.run_sequence() + # k.run_sequence_async() # sequence is run in a separate thread and the prompt returns immediately + # time.sleep(2) + # k.interrupt() # kill the asynchron sequence + + ### Run multiple sequences at given time interval + k.settings['nb_meas'] = 3 # run sequence three times + k.settings['sequence_delay'] = 100 # every 100 s + k.run_multiple_sequences() # asynchron + # k.interrupt() # kill the asynchron sequence + + ### Single measurement can also be taken with + k.switch_mux_on([1, 4, 2, 3]) + k.run_measurement() # use default acquisition parameters + k.switch_mux_off([1, 4, 2, 3]) # don't forget this! risk of short-circuit + + ### Custom or adaptative argument, see help(k.run_measurement) + k.run_measurement(nb_stack=4, # do 4 stacks (8 half-cycles) + injection_duration=2, # inject for 2 seconds + autogain=True) # adapt gain of ADS to get good resolution + + + +MQTT interface +.............. + +This is an interface designed for an advanced remote usage of the OhmPi such as remote automation, data consumption by multiple processes and interaction with other sensors in the scope of a monitoring. It is based on the MQTT protocol, designed for the Internet of Things (IoT), to interact with the OhmPi. + +This option allows interacting remotely with a single OhmPi, a network of OhmPis, as well as auxiliary instruments and sensors. The communication is based on a publish/subscribe approach and involves a MQTT broker. + +An example of MQTT broker that can be used is `Mosquitto <https://mosquitto.org/>`_. Depending on the monitoring needs, an MQTT broker can be set up locally on the Raspberry Pi, on a local network or any remote server reachable through the net. A local Mosquitto broker can be set up and enabled to run as a service on the OhmPi using the bash script install_local_mqtt_broker.sh. + +MQTT messages include logging messages from the OhmPi and commands sent to the OhmPi. These messages can be examined easily using a third party software such as `MQTT Explorer <http://mqtt-explorer.com/>`_. + +Commands sent on the broker are received by the ohmpi.py script that runs on the OhmPi (make sure ohmpi.py starts on reboot) and further processed. +MQTT commands are sent in JSON format following the Python API with kwargs as illustrated below: + +.. code-block:: json + :caption: Updating acquisition settings. + + { + "cmd_id": "3fzxv121UITwGjWYgcz4xw", + "cmd": "update_settings", Depending on the experiment needs, MQTT brokers can be set up locally on the Raspberry Pi or on a local or remote server. + "kwargs": { + "config": { + "nb_meas": 2, + "nb_electrodes": 10, + "nb_stack": 2, + "injection_duration": 2, + "sequence_delay": 100 + } + } + } + + +.. code-block:: json + :caption: Check contact resistances + + { + "cmd_id": "3fzxv121UITwGjWYgcz4xw", + "cmd": "rs_check", + } + +.. code-block:: json + :caption: Running a sequence. + + { + "cmd_id": "3fzxv121UITwGjWYgcz4Yw", + "cmd": "run_sequence", + } + +.. code-block:: json + :caption: Running same sequence multiple times (nb_meas). + + { + "cmd_id": "3fzxv121UITwGjWYgcz4Yw", + "cmd": "run_multiple_sequences", + } + +.. code-block:: json + :caption: Interrupt current acquisition. + + { + "cmd_id": "3fzxv121UITwGjWYgcz4xw", + "cmd": "interrupt", + } + +Custom processing of messages and tailor-made dashboards for monitoring experiments may be designed using a browser-based flow editor such as `Node-red <http://mqtt-explorer.com/>`_. +This may help designing complex IoT experiments and monitoring systems in which OhmPi is a component. + +Examples incorporating execution commands and data outputs from OhmPi can be found in the OhmPi examples. Once Node-RED is installed on the OhmPi, these examples can be accessed separately by running a command in the console such as : + +.. code-block:: console + + node-red basic_ohmpi_flows_node-red.json + +These examples may require installing some additional node packages in order to work properly. This can be done in the `Palette Manager <https://nodered.org/docs/user-guide/editor/palette/manager>`_ within Node-RED. + +.. figure:: ../../img/node-red_flow.png + + Example flow in node-red to interact with an OhmPi. + + +.. figure:: ../../img/node-red_interface_control.png + + Example of a dashboard UI created with node-red to interact with an OhmPi - control tab. + +.. figure:: ../../img/node-red_interface_data.png + + Example of a dashboard UI created with node-red to interact with an OhmPi - data visualization tab. + + +For more documentation dedicated to node-red, please refer to the Node-red `cookbooks <https://cookbook.nodered.org/>`_. + + +Loggers +------- + +Loggers have been introduced in this release. They use the excellent logging python package. +Specific handlers have been implemented for running with ohmpi.py (one for logging to an mqtt broker (see `MQTT interface`_ for more details) and one for creating zipped rotated logs on disk). + +Two loggers have been defined. The first one is dedicated to log operations execution. It is named exec_logger. The second one, named data_logger, is dedicated to log data. A third one is planned to log the state of health (SOH) of the system in a future version. + +By default, logs are written to the console (print-like), stored locally in files (a zip is created after some time i.e. every day and/or when the size of the log exceeds a maximum size) and sent to an MQTT broker. Different logging levels may be defined for the different logs and handlers in the `Configuration file`_. + +Advanced users may write new handlers and edit the `setup_loggers.py` file to customize the logging mechanisms to their needs. diff --git a/doc/build/html/index.html b/doc/build/html/index.html index f2fddd23..e9531fa0 100644 --- a/doc/build/html/index.html +++ b/doc/build/html/index.html @@ -131,10 +131,10 @@ </ul> </li> <li class="toctree-l1"><a class="reference internal" href="source_rst/software.html">Software and operation</a><ul> -<li class="toctree-l2"><a class="reference internal" href="source_rst/software.html#system-architecture">System architecture</a></li> -<li class="toctree-l2"><a class="reference internal" href="source_rst/software.html#loggers">Loggers</a></li> -<li class="toctree-l2"><a class="reference internal" href="source_rst/software.html#configuration-file">Configuration file</a></li> -<li class="toctree-l2"><a class="reference internal" href="source_rst/software.html#interfaces-and-applications">Interfaces and applications</a></li> +<li class="toctree-l2"><a class="reference internal" href="source_rst/software/architecture.html">Software architecture</a></li> +<li class="toctree-l2"><a class="reference internal" href="source_rst/software/installation.html">Installation</a></li> +<li class="toctree-l2"><a class="reference internal" href="source_rst/software/operations.html">Configuration file</a></li> +<li class="toctree-l2"><a class="reference internal" href="source_rst/software/operations.html#interfaces-and-applications">Interfaces and applications</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="source_rst/api.html">API reference</a><ul class="simple"> diff --git a/doc/build/html/objects.inv b/doc/build/html/objects.inv index 10e837aff9e127334118bdc6dcd095bfbc428f83..858782b33946935f607520ec583d8222bcb23779 100644 GIT binary patch delta 628 zcmV-)0*n2>1>FUZbbpmikDD+MhVS_mKDLL=CTvcts!~-|+8kDi`myQ_85qEoKag!m z^6zV6vl!M6k#Y#0cb?Z{4?_i<@B+?A>EfB<3@CcoqROqVYt1Oy_kUNTtPpuG@)U=c z*W>;f9U9<BiB{%-FfWkkpKC0O6PAD^D55m!h`u~9&>&Y#6n_Ep#)MtK(qBc<QgGYw zq6=xqi>?KqW-GulucwK2&F1{F@guHaWeZ8A(vOFlHN>xd9&^V~vm-%`6#pRCem;(7 z<01Fkac@qj1PMH!c=sD39TaH?QV~;71T>R5s#`^FRr%xsI-sH<yh?{lN^`*)!GUWP z@wuJkPEnNldVl4Fn`<tyX$LJ3htt>$V~W3{3R4R560vqs>+$1^Swle~Q6k(ll;l{? z3w(DA^M<emzPP6l;1MeYETg9C1(v6DH!x=E8f=RME$UNBcqx|nPUbfpP}6QwaFV0K zykixQ@tc#p18-FB1rjGP39UKZOAINaojp@o<WH=c41c7#VzY141iU0wE3Y>fbYR&M zon>xF09LI8W?Bkm!bBrH^GlOW^0dqylo3Aa`rvJs-Q6y`n9DV`Stntm_IzJ4PUlSi z{9P`=X6)`H??U9APgcWB2m^=kY=F40$j1&D^mguP^8&Ps?1^@6<b{GhZtk%gqcNzp zK3}*%nr&zbUxRSMl{UleTICYl*ACz3aV3a<Kf%SFk4lUF?!Td^By@5(X6Uq;nZdOX zIzAd_DhvKSUG%Blc6~lSzHQUZHbV3i{v3Qm+qKF0L<uujS@hqWr(~FpW-@*byCjP) O$p@F@mdk(OkZP|x-Y~BK delta 598 zcmV-c0;&Do1-}K5bbnRBj+-zLz2_@@Y!AyOB&XbZSZQ;Jg4*q>H)LP{SH`w%L&#tC z8~SB+V$(PThe#a2^X5H|{bs0u5mrEtlrFXuXF$=*3RP}3s&zxr?)<vA!U~?BK_24p zzE5^rbP&Lh;;qa9VOAi1{;shsj#vVcpor3>Bl`5xfCjl}cz-b=E=<@3Ec>1pEd{p? zFFKQ!oOI3EZMFg|^ZGW?uGyR)HlE-L7PgR7D*bw>8$tZq$1!&db(0VzB>xS$_VYjE zWxS61sJCya(je01I=~n}yB&VKC5Zj~v)-cp&tE9x=6HQ69NZ`#w)rjDnae0a0?Tj8 zJl9S-DAEq3B7f%W0z@O2V|A;@tty|nfDR}ZgjMO_hcxGn;0%~n0iDN5?l^d<FYY4D zII6_Pd72{z$E)wIDgKTsOex4yK-xvE##@gYK|vv2A}j<YIo9I>|Eo>&4Pi_8?!Kl7 zUa?ZpWYknW!{s5}4O}yI4c3j567?}9tmJe24(59ssDE*`<c#E~FzsBi5WhIeC+H2z z^(sGtNodXKo<fu|=<E^7QhvuuWFXBIn|&J-u#!}*yxiQRLX*w0H<_D9fK@A@F_yaT zKM!r5^xVMnyaO`8kGga4vC8IYl}$+H5?e;`v{2hWSB%3skzqtVD#2!Ko@CxkF>ick zHOz!*!cQSQ8X)e6b?*@4_ck-_UvsX*T{%Ko@{ij^pS4>>y&3SUbh!#JdI-M-KhY{O kIbSGgh&JQajJtI_G^T0FuhS~=tV(>R5<gP;2WbHJj#9BGb^rhX diff --git a/doc/build/html/searchindex.js b/doc/build/html/searchindex.js index 48c1bd92..de302fc5 100644 --- a/doc/build/html/searchindex.js +++ b/doc/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["index", "source_rst/Ohmpi", "source_rst/V2023.x.x/V2023_step_03", "source_rst/api", "source_rst/archived_version", "source_rst/developing_hardware_components", "source_rst/gallery", "source_rst/hardware", "source_rst/hardware/assembling", "source_rst/hardware/hw_info", "source_rst/hardware/hw_pwr", "source_rst/hardware/hw_rpi", "source_rst/hardware/mb", "source_rst/hardware/mb/mb_2023", "source_rst/hardware/mb/mb_2024", "source_rst/hardware/mux_2023", "source_rst/hardware/mux_2024", "source_rst/software", "source_rst/troubleshooting", "source_rst/v1.xx/V1_01", "source_rst/v1.xx/V1_02"], "filenames": ["index.rst", "source_rst\\Ohmpi.rst", "source_rst\\V2023.x.x\\V2023_step_03.rst", "source_rst\\api.rst", "source_rst\\archived_version.rst", "source_rst\\developing_hardware_components.rst", "source_rst\\gallery.rst", "source_rst\\hardware.rst", "source_rst\\hardware\\assembling.rst", "source_rst\\hardware\\hw_info.rst", "source_rst\\hardware\\hw_pwr.rst", "source_rst\\hardware\\hw_rpi.rst", "source_rst\\hardware\\mb.rst", "source_rst\\hardware\\mb\\mb_2023.rst", "source_rst\\hardware\\mb\\mb_2024.rst", "source_rst\\hardware\\mux_2023.rst", "source_rst\\hardware\\mux_2024.rst", "source_rst\\software.rst", "source_rst\\troubleshooting.rst", "source_rst\\v1.xx\\V1_01.rst", "source_rst\\v1.xx\\V1_02.rst"], "titles": ["OHMPI: Open source and open hardware resistivity-meter", "OhmPi project", "<strong>STEP n\u00b03:</strong> MUX board", "API reference", "Archived versions", "Software interface to new hardware components", "Examples of applications", "Hardware", "Assembling the OhmPi", "OhmPi electronic design", "Power supply", "Raspberry Pi configuration", "Measurement board", "Measurement board v2023", "Measurement board 2024.0.2", "MUX board v2023", "MUX board v2024", "Software and operation", "Troubleshooting", "OhmPi V 1.01 (limited to 32 electrodes)", "OhmPi V 1.02 (limited to 32 electrodes)"], "terms": {"releas": [0, 17], "v2024rc": 0, "date": [0, 19, 20], "jan": 0, "09": [0, 19, 20], "2024": [0, 9, 12], "start": [0, 2, 5, 11, 12, 15, 16, 17, 19, 20], "juli": 0, "2016": 0, "author": [0, 11, 19, 20], "r\u00e9mi": [0, 1], "clement": [0, 1], "nicola": [0, 1], "forquet": [0, 1], "yannick": [0, 1], "fargier": [0, 1], "vivien": [0, 1], "duboi": [0, 1], "h\u00e9l\u00e8ne": [0, 1], "guyard": [0, 1], "olivi": [0, 1], "kaufmann": [0, 1], "guillaum": [0, 1], "blanchi": [0, 1], "arnaud": [0, 1], "watlet": [0, 1], "target": 0, "user": [0, 11, 17, 19, 20], "research": 0, "develop": [0, 1, 5, 11, 13, 14, 19, 20], "statu": 0, "some": [0, 5, 9, 17, 19, 20], "matur": 0, "progress": 0, "offici": 0, "guidelin": 0, "gener": [0, 2, 7, 9, 13, 14, 15, 16, 17, 19, 20], "tutori": 0, "content": 0, "project": [0, 2, 5, 8, 11, 13, 14, 15, 16, 17, 19, 20], "partner": 0, "cite": 0, "introduct": 0, "electron": [0, 1, 2, 7, 8, 11, 12, 13, 14, 15, 16, 17, 19, 20], "design": [0, 5, 7, 17, 19, 20], "measur": [0, 1, 2, 7, 8, 11, 15, 16, 17, 18], "board": [0, 5, 7, 8, 11, 18], "mux": [0, 7, 8, 19, 20], "v2023": [0, 7, 9, 12, 17, 18], "v2024": [0, 7, 9, 12, 18], "power": [0, 2, 7, 8, 12, 13, 14, 15, 16, 19, 20], "suppli": [0, 2, 7, 8, 12, 13, 14, 15, 16, 19, 20], "raspberri": [0, 2, 7, 8, 13, 14, 15, 16, 17], "pi": [0, 7, 8, 13, 14, 17], "configur": [0, 5, 7, 9], "assembl": [0, 1, 7, 11, 17], "softwar": [0, 11, 19, 20], "oper": [0, 5, 8, 9, 11, 12, 13], "system": [0, 5, 11, 19, 20], "architectur": 0, "logger": [0, 1, 19, 20], "file": [0, 5, 7, 11, 13, 19, 20], "interfac": [0, 14], "applic": [0, 1, 5, 7, 9], "api": [0, 17], "refer": [0, 8, 13, 14, 15, 16, 17, 19, 20], "troubleshoot": 0, "issu": 0, "puls": [0, 9, 12, 19, 20], "between": [0, 2, 8, 9, 13, 15, 16, 19, 20], "A": [0, 1, 5, 7, 8, 9, 10, 12, 17, 19, 20], "b": [0, 7, 8, 9, 10, 12, 14], "valu": [0, 2, 9, 13, 15, 16, 19, 20], "given": [0, 9, 17], "correct": [0, 19, 20], "one": [0, 8, 13, 17, 19, 20], "commun": [0, 1, 9, 17], "compon": [0, 9, 11, 17], "exampl": [0, 2, 8, 13, 15, 16, 17, 19, 20], "new": [0, 11, 17, 18, 19, 20], "archiv": 0, "version": [0, 5, 7, 11, 13, 17, 19, 20], "v": [0, 4, 8, 9, 10, 13, 15, 16, 18], "1": [0, 2, 4, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17], "01": [0, 4, 14, 20], "limit": [0, 4, 13], "32": [0, 4, 8, 11, 14], "electrod": [0, 1, 2, 4, 7, 8, 9, 10, 13, 15, 16, 18], "02": [0, 4, 13, 14, 19], "inra": [1, 6], "reversa": [1, 19, 20], "villeurbann": 1, "franc": 1, "universit\u00e9": 1, "de": 1, "mon": 1, "belgium": 1, "ger": 1, "rro": 1, "univ": 1, "gustav": 1, "eiffel": 1, "ifsttar": 1, "lyon": 1, "ig": 1, "grenobl": 1, "alp": 1, "ilvo": 1, "merelbek": 1, "julien": 1, "ganc": 1, "emil": 1, "gro": 1, "et": [1, 13], "al": 1, "an": [1, 2, 5, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20], "open": [1, 2, 5, 8, 11, 13, 14, 15, 16, 17, 18, 19, 20], "sourc": [1, 5, 10, 11, 14, 19, 20], "data": [1, 9, 14, 17], "dedic": [1, 17], "electr": [1, 13, 14], "resist": [1, 8, 9, 13, 17, 18], "imag": [1, 11], "small": [1, 8, 9, 13, 14, 17, 19, 20], "laboratori": [1, 8, 12, 19, 20], "scale": [1, 9], "hardwarex": 1, "elsevi": 1, "2020": 1, "8": [1, 2, 8, 9, 11, 13, 14, 15, 16, 17, 19, 20], "24": [1, 8, 12, 13, 14, 16, 19, 20], "p": [1, 13, 15, 16], "ff10": 1, "1016": 1, "j": 1, "ohx": 1, "e00122ff": 1, "particip": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "all": [1, 2, 5, 8, 11, 13, 14, 15, 16, 17, 19, 20], "requir": [1, 5, 8, 11, 17, 19, 20], "skill": [1, 2, 8, 11, 12, 13, 14, 15, 16, 17, 19, 20], "respect": [1, 2, 8, 9, 11, 13, 14, 15, 16, 17, 19, 20], "safeti": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "rule": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "must": [1, 2, 8, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20], "profession": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "context": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "peopl": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "compet": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "The": [1, 2, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18], "team": [1, 2, 5, 8, 11, 13, 14, 15, 16, 17, 19, 20], "cannot": [1, 2, 8, 9, 11, 13, 14, 15, 16, 17, 19, 20], "held": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "respons": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "ani": [1, 2, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "materi": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "human": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "damag": [1, 2, 8, 11, 13, 14, 15, 16, 17, 18, 19, 20], "which": [1, 2, 8, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20], "would": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "associ": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "us": [1, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "equip": [1, 2, 8, 9, 11, 13, 14, 15, 16, 17, 19, 20], "doe": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "work": [1, 2, 5, 8, 11, 13, 14, 15, 16, 17, 18, 19, 20], "after": [1, 2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "you": [1, 2, 5, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20], "mai": [1, 11, 17, 18, 19, 20], "redistribut": 1, "modifi": [1, 5, 19, 20], "thi": [1, 2, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "document": [1, 7, 17, 19], "make": [1, 2, 5, 9, 15, 16, 17, 19, 20], "product": [1, 13, 14, 15, 16], "under": [1, 8, 19, 20], "term": [1, 5], "cern": 1, "ohl": 1, "v2": 1, "distribut": [1, 9], "without": [1, 2, 9, 15, 16, 18, 19, 20], "express": [1, 5], "OR": 1, "impli": [1, 2, 15, 16], "warranti": 1, "includ": [1, 2, 5, 11, 15, 16, 17, 19, 20], "OF": 1, "merchant": 1, "satisfactori": 1, "qualiti": 1, "AND": 1, "fit": 1, "FOR": 1, "particular": 1, "purpos": [1, 8, 14, 19, 20], "pleas": [1, 8, 17, 19, 20], "see": [1, 9, 17, 18, 19, 20], "condit": [1, 14], "present": [1, 2, 5, 8, 14, 15, 16, 19, 20], "low": [1, 14, 19, 20], "cost": [1, 5, 13, 14, 15, 16, 19, 20], "hardwar": [1, 17, 19, 20], "meter": [1, 8, 19, 20], "provid": [1, 12, 14, 17, 19, 20], "scientif": 1, "robust": [1, 18, 19, 20], "flexibl": 1, "tool": [1, 14], "experi": [1, 17, 18, 19, 20], "call": [1, 2, 8, 9, 11, 15, 16, 17], "basic": [1, 5], "meterfeatur": 1, "current": [1, 7, 9, 10, 12, 13, 14, 17, 18], "inject": [1, 7, 9, 10, 14, 17], "function": [1, 5, 17, 19, 20], "multiplex": [1, 2, 7, 8, 15, 16], "allow": [1, 2, 13, 14, 15, 16, 17, 19, 20], "perform": [1, 5, 11, 14, 19, 20], "automat": [1, 17, 19, 20], "up": [1, 2, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20], "64": [1, 2, 14, 15, 16, 19, 20], "s": [1, 2, 13, 14, 15, 16, 17, 18, 19, 20], "philosophi": 1, "fulli": 1, "toolto": 1, "surfac": 1, "anyon": 1, "who": 1, "want": [1, 20], "get": [1, 11, 13, 17, 19, 20], "involv": [1, 17], "welcom": [1, 5], "join": 1, "ohmpi": [2, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 18], "channel": [2, 12, 14, 15, 16, 19, 20], "mechan": [2, 9, 15, 16, 17, 18, 19, 20], "base": [2, 5, 11, 15, 16, 17, 19, 20], "omron": [2, 14, 15, 16], "manufactur": [2, 13, 14, 15, 16, 19, 20], "relai": [2, 9, 11, 13, 14, 15, 16, 18, 19, 20], "g5le": [2, 14, 15, 16], "vd": [2, 15, 16], "12": [2, 8, 9, 12, 13, 14, 15, 16, 19, 20], "vdc": [2, 12, 14, 15, 16], "each": [2, 8, 9, 11, 12, 15, 16, 19, 20], "combin": [2, 7, 15, 16], "zvn4206a": [2, 15, 16], "mofset": [2, 15, 16], "ha": [2, 9, 11, 12, 14, 15, 16, 18, 19, 20], "onli": [2, 5, 9, 10, 15, 16], "30": [2, 8, 15, 16, 19, 20], "gpio": [2, 8, 9, 11, 14, 15, 16, 19, 20], "enough": [2, 15, 16, 19, 20], "activ": [2, 7, 15, 16], "repres": [2, 15, 16, 19, 20], "512": [2, 15, 16], "we": [2, 7, 9, 10, 11, 13, 15, 16, 17, 18, 19, 20], "expand": [2, 9, 14, 15, 16], "i2c": [2, 9, 11, 13, 14, 15, 16, 18], "mcp23017": [2, 9, 15, 16], "have": [2, 5, 9, 11, 13, 15, 16, 17, 18, 19, 20], "type": [2, 5, 11, 14, 15, 16, 19, 20], "tca9548a": [2, 11, 15, 16], "from": [2, 8, 9, 12, 15, 16, 17, 18, 19, 20], "adafruit": [2, 11, 13, 14, 15, 16, 19, 20], "go": [2, 11, 14, 15, 16, 17], "128": [2, 15, 16], "card": [2, 8, 11, 15, 16], "its": [2, 8, 11, 14, 15, 16, 17, 19, 20], "own": [2, 15, 16], "digit": [2, 9, 13, 14, 15, 16, 19, 20], "0x70": [2, 15, 16], "0x77": [2, 15, 16], "In": [2, 5, 9, 11, 13, 15, 16, 18, 19, 20], "follow": [2, 5, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20], "0x71": [2, 15, 16], "0x72": [2, 15, 16], "m": [2, 8, 9, 11, 13, 15, 16, 19, 20], "0x73": [2, 15, 16], "4": [2, 8, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20], "need": [2, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20], "pcb": [2, 5, 13, 14, 15, 16, 19, 20], "2": [2, 5, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20], "instal": [2, 7, 8, 13, 14, 15, 16, 17], "100": [2, 14, 15, 16, 17, 19, 20], "kohm": [2, 13, 14, 15, 16, 19, 20], "resistor": [2, 9, 12, 13, 14, 15, 16, 18, 19, 20], "mosfet": [2, 14, 15, 16], "diod": [2, 14, 15, 16], "1n4007": [2, 15, 16], "5": [2, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "6": [2, 8, 11, 13, 14, 15, 16, 19, 20], "termin": [2, 8, 11, 13, 14, 15, 16, 17, 19, 20], "screw": [2, 8, 13, 15, 16, 19, 20], "7": [2, 8, 11, 13, 14, 15, 16, 19, 20], "male": [2, 13, 15, 16], "header": [2, 13, 14, 15, 16, 19, 20], "pin": [2, 13, 14, 15, 16, 19, 20], "strip": [2, 8, 13, 14, 15, 16, 19, 20], "16": [2, 8, 9, 13, 14, 15, 16, 19, 20], "9": [2, 8, 11, 13, 14, 15, 16, 19, 20], "dip": [2, 13, 14, 15, 16], "dual": [2, 13, 15, 16, 19, 20], "line": [2, 9, 13, 15, 16, 18, 19, 20], "socket": [2, 13, 14, 15, 16], "14": [2, 8, 13, 14, 15, 16], "10": [2, 8, 13, 14, 15, 16, 17, 19, 20], "duplic": [2, 15, 16], "time": [2, 9, 11, 15, 16, 17, 19, 20], "everi": [2, 15, 16, 17], "To": [2, 13, 15, 16, 17, 18, 19, 20], "build": [2, 7, 15, 16, 19, 20], "necessari": [2, 5, 8, 11, 15, 16, 19, 20], "differ": [2, 7, 8, 9, 11, 13, 14, 15, 16, 17, 19, 20], "It": [2, 5, 10, 11, 14, 15, 16, 17, 18, 19, 20], "therefor": [2, 15, 16, 19, 20], "identifi": [2, 15, 16], "assign": [2, 15, 16], "alloc": [2, 15, 16], "code": [2, 5, 11, 12, 15, 16, 19, 20], "here": [2, 8, 15, 16, 20], "select": [2, 11, 15, 16, 19, 20], "default": [2, 15, 16, 17], "For": [2, 9, 11, 13, 15, 16, 17, 19, 20], "suggest": [2, 13, 15, 16, 19, 20], "mount": [2, 8, 13, 15, 16, 19, 20], "jumper": [2, 15, 16], "note": [2, 8, 15, 16, 19, 20], "name": [2, 5, 15, 16, 17, 19, 20], "zoom": [2, 8, 15, 16], "first": [2, 5, 8, 9, 11, 15, 16, 17], "test": [2, 5, 8, 11, 13, 15, 16, 17, 19, 20], "befor": [2, 8, 9, 15, 16, 17, 19, 20], "them": [2, 15, 16, 17, 19, 20], "definit": [2, 15, 16], "simplifi": [2, 15, 16], "thing": [2, 15, 16, 17], "do": [2, 5, 8, 14, 15, 16, 17], "prepar": [2, 13, 15, 16, 19, 20], "50": [2, 8, 10, 12, 15, 16, 19, 20], "cm": [2, 8, 15, 16, 19, 20], "long": [2, 8, 9, 15, 16], "flat": [2, 15, 16], "wire": [2, 8, 9, 11, 14, 15, 16, 19, 20], "two": [2, 5, 9, 10, 13, 15, 16, 17, 18, 19, 20], "pole": [2, 15, 16, 19, 20], "connector": [2, 8, 15, 16, 19, 20], "cabl": [2, 8, 11, 13, 14, 15, 16, 19, 20], "contact": [2, 13, 15, 16, 17, 19, 20], "connect": [2, 8, 9, 10, 13, 14, 15, 16, 17, 18], "12v": [2, 7, 8, 9, 13, 14, 15, 16, 19, 20], "your": [2, 5, 7, 11, 12, 13, 15, 16, 19, 20], "run": [2, 8, 11, 13, 15, 16, 17, 19, 20], "write": [2, 5, 13, 15, 16, 17, 19, 20], "i2cdetect": [2, 13, 15, 16], "y": [2, 13, 15, 16], "three": [2, 13, 15, 16, 17, 19, 20], "should": [2, 5, 8, 9, 11, 13, 15, 16, 17, 19, 20], "appear": [2, 11, 13, 15, 16, 19, 20], "been": [2, 11, 12, 14, 15, 16, 17, 19, 20], "detect": [2, 15, 16], "script": [2, 5, 15, 16, 17], "test_mux_board": [2, 15, 16], "py": [2, 5, 13, 15, 16, 17, 19, 20], "These": [4, 7, 9, 17, 18, 19, 20], "ar": [4, 5, 8, 9, 10, 11, 12, 13, 17, 18, 19, 20], "support": [4, 11], "anymor": [4, 18], "draft": 5, "TO": [5, 16, 18], "BE": [5, 16, 18], "review": [5, 18], "section": [5, 7, 12, 17, 19, 20], "intend": 5, "part": [5, 7, 9, 12, 18, 19, 20], "advic": [5, 18], "best": 5, "practic": [5, 19, 20], "help": [5, 8, 9, 17], "within": [5, 11, 17, 19, 20], "contribut": 5, "howev": [5, 9, 14, 19, 20], "order": [5, 17, 19, 20], "maintain": 5, "track": [5, 19, 20], "promot": 5, "exchang": 5, "reus": 5, "contributor": 5, "ideal": 5, "few": 5, "step": [5, 11, 13, 15, 16, 19, 20], "case": [5, 11, 17, 18, 19, 20], "distinguish": 5, "when": [5, 8, 10, 17, 18, 19, 20], "deal": 5, "compli": 5, "wai": [5, 11, 19, 20], "Such": 5, "typic": [5, 9, 17, 19, 20], "focu": 5, "improv": [5, 20], "exist": [5, 7, 19, 20], "reduc": [5, 9], "adapt": [5, 13, 17, 19, 20], "rang": [5, 12, 18, 19, 20], "specif": [5, 7, 14, 17, 19, 20], "easili": [5, 17, 18], "avail": [5, 10, 17, 19, 20], "newli": 5, "creat": [5, 9, 11, 17, 19, 20], "expos": 5, "minim": 5, "hardware_system": 5, "introduc": [5, 12, 17, 19, 20], "chang": [5, 13, 15, 16, 17, 18], "singl": [5, 14, 17, 19, 20], "also": [5, 9, 10, 11, 17, 19, 20], "discuss": 5, "ohmpi_hardwar": 5, "class": [5, 17], "initi": 5, "veri": [5, 9, 20], "earli": 5, "stage": 5, "investig": 5, "implement": [5, 17], "solut": [5, 19, 20], "If": [5, 11, 13, 18, 19, 20], "path": [5, 9, 11, 19, 20], "strategi": 5, "readi": 5, "devic": [5, 9, 13, 14, 15, 16], "conceiv": 5, "recommend": [5, 11, 17, 19, 20], "import": [5, 17], "kicad": 5, "both": [5, 19, 20], "schema": 5, "share": 5, "alwai": 5, "branch": 5, "python": [5, 7], "copi": [5, 11, 17], "similar": [5, 18], "modul": [5, 7, 9, 14, 19, 20], "store": [5, 17], "hardware_compon": 5, "directori": [5, 11, 17, 19, 20], "defin": [5, 8, 17], "relev": [5, 8], "abstract": 5, "abstract_hardware_compon": 5, "method": 5, "interact": [5, 17], "accord": [5, 9, 19, 20], "sure": [5, 17, 19, 20], "place": [5, 8, 9, 18, 19, 20], "config": [5, 13, 17, 19, 20], "describ": [5, 8, 11, 12, 13, 19, 20], "hardware_config": 5, "dictionari": 5, "config_xxx": 5, "where": [5, 7, 9, 11, 17, 19, 20], "xxx": 5, "replac": [5, 14, 18, 20], "3": [5, 8, 9, 11, 13, 14, 15, 16, 17, 19, 20], "conduct": [5, 19, 20], "todo": 6, "e": [6, 12, 17, 19, 20], "g": [6, 12, 13, 14, 19, 20], "rocherfort": 6, "contain": [7, 8, 11, 17, 19, 20], "compos": [7, 8], "mb": 7, "voltag": [7, 8, 9, 13, 14, 18, 19, 20], "0": [7, 9, 12, 13, 15, 16, 17, 19, 20], "n": [7, 8, 9, 13, 14, 15, 16, 17, 19, 20], "address": [7, 9, 13, 19, 20], "pwr": 7, "either": [7, 11, 19, 20], "batteri": [7, 8, 13, 19, 20], "more": [7, 8, 9, 17, 18], "advanc": [7, 17], "can": [7, 8, 9, 10, 11, 17, 18, 19, 20], "control": [7, 9, 10, 17, 19, 20], "ctrl": [7, 19, 20], "raspberrypi": [7, 9, 10, 11, 14], "upgrad": [7, 14, 20], "recogn": 7, "c": [7, 12, 19, 20], "valid": [7, 19, 20], "regul": 7, "dps5005": 7, "os": [7, 8, 17], "virtual": 7, "environ": 7, "packag": [7, 14, 17], "thonni": [7, 13, 17], "id": [7, 17], "cut": [8, 14], "ribbon": [8, 15, 16], "proper": 8, "length": [8, 19, 20], "about": [8, 9], "5m": [8, 13], "correspond": [8, 19], "crimp": [8, 19, 20], "idc": [8, 14], "suitabl": [8, 19, 20], "clamp": 8, "pai": [8, 19, 20], "attent": [8, 19, 20], "direct": [8, 17, 19, 20], "unbalanc": 8, "perpendicular": 8, "possibl": [8, 12, 18, 19, 20], "same": [8, 9, 17, 19, 20], "flush": 8, "posit": [8, 14, 19, 20], "spacer": [8, 13, 15, 16], "abov": [8, 19, 20], "below": [8, 9, 11, 17, 19, 20], "profil": 8, "view": [8, 13], "color": 8, "yellow": 8, "tin": [8, 14], "end": [8, 19, 20], "red": [8, 13, 17, 19, 20], "black": [8, 13, 14, 19, 20], "left": [8, 13], "shown": [8, 19, 20], "pictur": 8, "i": [8, 15, 16, 17, 19, 20], "ii": 8, "gnd": [8, 19, 20], "nois": [8, 14], "often": [8, 9], "heard": 8, "clip": 8, "11": [8, 12, 13, 14, 19, 20], "input": [8, 9, 12, 13, 14, 19, 20], "right": [8, 13], "fix": [8, 13, 14], "second": [8, 9, 12, 17, 19, 20], "13": [8, 13, 14, 15, 16, 19, 20], "15": [8, 12, 13, 14, 15, 16, 19, 20], "previou": 8, "procedur": 8, "repeat": [8, 17, 19, 20], "other": [8, 17, 19, 20], "17": [8, 13, 14, 19, 20], "purpl": 8, "18": [8, 13, 14, 19, 20], "third": [8, 17], "19": [8, 13, 14, 19, 20], "fourth": 8, "nylon": 8, "hex": [8, 15, 16], "photograph": 8, "detail": [8, 9, 17, 19], "20": [8, 13, 14, 19, 20], "4th": 8, "togeth": [8, 19, 20], "could": [8, 13, 19, 20], "previous": [8, 11, 19, 20], "21": [8, 13, 14, 19, 20], "tie": 8, "22": [8, 13, 14, 19, 20], "23": [8, 13, 14, 15, 16, 19, 20], "pvc": 8, "plate": 8, "minimum": 8, "dimens": 8, "200": [8, 12, 14], "mm": [8, 13, 15, 16, 19, 20], "150": [8, 9, 19, 20], "drill": 8, "remain": [8, 19, 20], "metal": [8, 14], "tighten": 8, "25": [8, 12, 14, 15, 16, 19, 20], "rpi": [8, 11, 19, 20], "so": [8, 9, 19, 20], "access": [8, 11, 17, 19, 20], "usb": 8, "port": [8, 13, 14], "mark": [8, 13], "hole": [8, 14, 19, 20], "26": [8, 14, 19, 20], "add": [8, 19, 20], "27": [8, 14, 15, 16, 19, 20], "attach": 8, "washer": 8, "nut": 8, "28": [8, 14], "29": [8, 19, 20], "come": 8, "out": [8, 11, 19, 20], "pass": [8, 17], "output": [8, 13, 14, 17, 19, 20], "pre": [8, 13], "led": [8, 14], "simpli": [8, 11, 19, 20], "consid": 8, "temporari": 8, "modif": [8, 11, 19, 20], "orang": 8, "31": [8, 13, 15, 16], "brown": 8, "blue": [8, 19, 20], "block": [8, 14, 19, 20], "top": [8, 13, 17], "secur": [8, 17], "33": [8, 14], "34": [8, 14], "35": [8, 13, 14], "36": [8, 13, 19, 20], "37": [8, 19, 20], "38": [8, 14, 19, 20], "sd": [8, 11, 19, 20], "program": [8, 11, 19, 20], "mous": [8, 11, 19, 20], "keyboard": [8, 11, 19, 20], "monitor": [8, 17, 19, 20], "hdmi": [8, 11], "39": [8, 13, 14, 15, 16, 19, 20], "deliv": [8, 19, 20], "12vdc": 8, "enjoi": 8, "integr": [9, 13], "mn": [9, 18], "ab": 9, "switch": [9, 14, 19, 20], "polar": [9, 14, 19, 20], "half": [9, 17], "cycl": [9, 17], "stack": [9, 14, 17, 19, 20], "explan": 9, "understand": [9, 17], "redirect": 9, "reader": 9, "datasheet": 9, "done": [9, 11, 17, 19, 20], "through": [9, 14, 17, 19, 20], "adc": [9, 13, 14, 18, 19, 20], "analog": [9, 13, 14, 19, 20], "convert": [9, 13, 14, 19, 20], "ads1115": [9, 13, 14, 18, 19, 20], "bit": [9, 13, 14, 19, 20], "programm": [9, 14], "gain": [9, 13, 14, 17, 19, 20], "pga": 9, "mean": 9, "factor": 9, "digitis": 9, "Its": [9, 19, 20], "vari": 9, "With": [9, 19, 20], "precis": [9, 13, 14, 19, 20], "076": 9, "mv": 9, "beyond": 9, "larger": 9, "our": [9, 19, 20], "divid": [9, 19, 20], "receiv": [9, 17], "mb_2023": 9, "bridg": [9, 19, 20], "across": 9, "seri": [9, 19, 20], "instanc": [9, 11], "300": 9, "ohm": [9, 12, 13, 14, 19, 20], "anoth": [9, 11, 18, 19, 20], "techniqu": 9, "consist": [9, 18, 19, 20], "opamp": 9, "amplifi": [9, 13, 14, 19, 20], "multipl": [9, 11, 17], "known": [9, 11, 19, 20], "down": [9, 19, 20], "addit": [9, 17, 19, 20], "mode": 9, "ensur": [9, 11, 19, 20], "high": [9, 14, 19, 20], "imped": [9, 12, 19, 20], "inde": [9, 19, 20], "leak": 9, "while": 9, "affect": 9, "mb_2024": 9, "differenti": 9, "model": [9, 11, 13, 14, 19, 20], "float": 9, "ground": [9, 13, 18, 19, 20], "enabl": [9, 10, 17, 19, 20], "much": 9, "higher": [9, 13, 20], "too": 9, "larg": 9, "usual": 9, "accur": [9, 19, 20], "shunt": [9, 12, 13, 14, 18], "As": [9, 19, 20], "tini": 9, "being": [9, 19, 20], "ina282": [9, 13], "via": [9, 11, 18, 19, 20], "click": [9, 11, 14, 18, 19, 20], "ina": 9, "equival": [9, 13, 19, 20], "alreadi": 9, "solder": [9, 13, 14, 19, 20], "off": 9, "revers": [9, 19, 20], "four": [9, 13, 14], "optic": [9, 13, 18], "transit": 9, "mcp2308": 9, "gpi": 9, "sda": [9, 18], "scl": [9, 18], "protocol": [9, 17, 18, 19, 20], "send": 9, "clock": 9, "transmit": 9, "pull": [9, 18], "rest": [9, 18], "5v": [9, 13, 14, 18, 19, 20], "thei": [9, 17, 18, 19, 20], "entri": 9, "becaus": 9, "mani": 9, "bu": 9, "tcaxxxx": 9, "itself": [9, 17], "rapsberrypi": 9, "now": [10, 19, 20], "actual": [10, 19, 20], "henc": 10, "maximum": [10, 17, 19, 20], "aliment": 10, "modbu": 10, "quantiti": [11, 14, 19, 20], "micro": [11, 19, 20], "comput": [11, 19, 20], "instruct": [11, 17], "well": [11, 17, 19, 20], "websit": [11, 19, 20], "watch": [11, 19, 20], "video": [11, 19, 20], "how": [11, 19, 20], "set": [11, 13, 14, 17, 19, 20], "latest": [11, 12, 19, 20], "stabl": [11, 19, 20], "complet": [11, 13], "raspbian": [11, 19, 20], "visit": 11, "http": [11, 13, 14, 15, 16, 17, 19, 20], "org": [11, 17], "en": [11, 14], "were": [11, 13, 19, 20], "onc": [11, 17, 18, 19, 20], "spi": [11, 19, 20], "remot": [11, 17, 19, 20], "option": [11, 12, 14, 17, 19, 20], "deactiv": [11, 19, 20], "gui": [11, 19, 20], "menu": [11, 19, 20], "failur": [11, 19, 20], "carri": [11, 19, 20], "task": [11, 19, 20], "caus": [11, 18, 19, 20], "shield": [11, 19, 20], "dure": [11, 19, 20], "parallel": 11, "interpret": [11, 13, 19, 20], "discret": 11, "util": [11, 17], "protect": 11, "problem": 11, "depend": [11, 17, 19, 20], "specifi": [11, 19, 20], "txt": [11, 17, 19, 20], "libatla": [11, 19, 20], "dev": [11, 19, 20], "librari": [11, 19, 20], "sudo": [11, 19, 20], "apt": [11, 19, 20], "strongli": [11, 19, 20], "gather": [11, 19, 20], "python3": [11, 19, 20], "venv": [11, 19, 20], "command": [11, 17, 19, 20], "bin": [11, 19, 20], "suffici": [11, 19, 20], "meet": [11, 19, 20], "export": 11, "cflag": 11, "fcommon": 11, "pip": [11, 19, 20], "blinka": [11, 19, 20], "numpi": [11, 17, 19, 20], "panda": [11, 19, 20], "circuitpython": [11, 19, 20], "ads1x15": [11, 19, 20], "mcp230xx": 11, "gpiozero": 11, "check": [11, 12, 17, 18, 19, 20], "met": [11, 19, 20], "list": 11, "leav": [11, 19, 20], "decid": [11, 19, 20], "setup": [11, 19, 20], "pythonid": [11, 19, 20], "root": [11, 19, 20], "usr": [11, 19, 20], "window": [11, 17, 19, 20], "On": [11, 19, 20], "altern": [11, 19, 20], "button": [11, 19, 20], "locat": [11, 19, 20], "execut": [11, 17, 19, 20], "find": [11, 19, 20], "folder": [11, 19, 20], "home": [11, 17, 19, 20], "tab": [11, 17, 19, 20], "close": [11, 18, 19, 20], "ok": [11, 19, 20], "save": [11, 19, 20], "year": 12, "consequ": [12, 19, 20], "group": 12, "varieti": 12, "tailor": [12, 17], "technic": 12, "field": [12, 19, 20], "budget": 12, "characterist": [12, 19, 20], "tabl": [12, 20], "paramet": [12, 17], "unit": [12, 13, 14, 15, 16, 19, 20], "vmn": [12, 14], "number": [12, 13, 15, 16, 17, 19, 20], "temperatur": [12, 19, 20], "max": [12, 13, 14], "permiss": 12, "vab": [12, 14], "40": [12, 15, 16, 19, 20], "ma": [12, 13, 19, 20], "500": [12, 19, 20], "min": [12, 19, 20], "durat": [12, 17, 19, 20], "ms": [12, 19, 20], "80": 12, "mohm": [12, 13, 19, 20], "tohm": 12, "volt": 12, "descript": [], "per": [13, 14, 15, 16, 19, 20], "total": [13, 14, 15, 16, 19, 20], "web": [13, 14, 15, 16], "58": [13, 19, 20], "75": 13, "www": [13, 14, 15, 16, 19, 20], "mouser": [13, 14, 15, 16], "fr": [13, 14, 15, 16, 19, 20], "productdetail": [13, 14, 15, 16], "seeed": 13, "studio": 13, "102110421": 13, "qs": [13, 14, 15, 16], "7mvldsj5uaxen3lyyh3sqw": 13, "3d": [13, 14, 15, 16], "lm158n": 13, "amp": [13, 14, 19, 20], "o": [13, 15, 16, 17, 19, 20], "texa": [13, 19, 20], "instrument": [13, 17, 19, 20], "lm358an": [13, 19, 20], "nopb": [13, 19, 20], "lm158j": 13, "x1j7hmvl2zh8vpefml8": 13, "2ffq": 13, "print": [13, 15, 16, 17, 19, 20], "circuit": [13, 15, 16, 17, 19, 20], "asler": [13, 15, 16, 19, 20], "1085": [13, 14], "2fha2pyfaduh": 13, "2fogzutwiq9iz5vjaqfoyugqalgxpeckigrqvf4hn": 13, "252bg": 13, "capacitor": [13, 14, 20], "100nf": [13, 14, 20], "50vdc": [13, 20], "ceram": [13, 14, 20], "kemet": [13, 20], "c320c104k1": [13, 20], "c320c104k1r5ta7303": 13, "c4uyot": 13, "2flq1th4mcyoetma": 13, "5w": [13, 19, 20], "te": [13, 14, 15, 16, 19, 20], "h81k0bya": [13, 19, 20], "holsworthi": [13, 14], "2fha2pyfaduhuylh7az": 13, "2fmjfh2xjoums6wztux4som": 13, "252bii": 13, "h81k5bya": [13, 19, 20], "2fha2pyfadugy9twham3ru9hmijohywhbin95knm": 13, "252bx": 13, "2fm": 13, "vishai": [13, 14, 15, 16], "ccf071k50gke36": 13, "dale": 13, "qkeozdl6eqpa6lzrlqfvow": 13, "762": 13, "524": 13, "cmf651m0000fkek143": 13, "ciayqk2gdckzia2levalkg": 13, "42": [13, 14], "ohmit": [13, 14], "41f2r0e": 13, "im6toxqzgoauedprb19mha": 13, "08": [13, 15, 16], "pitch": [13, 14, 15, 16, 19, 20], "648": [13, 15, 16, 19, 20], "cui": [13, 15, 16], "tb009": [13, 15, 16], "508": [13, 15, 16], "02be": [13, 15, 16], "vlwxofp3u2wcfk5uckwtka": [13, 15, 16], "dc": [13, 14, 15, 16, 19, 20], "24v": [13, 20], "tracopow": [13, 20], "trn": [13, 20], "1215": [13, 20], "traco": [13, 14, 20], "yca": 13, "2faaymw02gquicgqj0ta": 13, "72": [13, 20], "mill": [13, 14], "110": [13, 14, 16, 19, 20], "43": [13, 14, 19, 20], "308": [13, 14], "41": [13, 14, 16], "001000": [13, 14], "iggadovctstu": 13, "2fqaur8narg": 13, "mgh": 13, "vip": 13, "gclid": 13, "eaiaiqobchmin_taxbcx8wivq5nvch2qaqfpeayyccabegjk1_d_bw": 13, "aqy211eh": 13, "84": [13, 15, 16], "panason": [13, 14], "industri": 13, "wktuvitrialgiu8hcm7dvq": 13, "449": 13, "796": 13, "preci": [13, 16], "83": 13, "304": 13, "001101": [13, 16], "2fha2pyfadujqkqx4wauig": 13, "2fmgndxmcnv": 13, "2f33nj0gbxroculucynpyong": 13, "mcp23008": [13, 14], "593": [13, 14], "sgaepimzzmskedp9slc0yyv4kpdpmd1hts4slctivmw": 13, "1x10": [13, 19, 20], "samtec": [13, 14, 19, 20], "ssw": [13, 14, 19, 20], "ru5fayqh": [13, 14], "252be0w1orxzibqpw": [13, 14], "smt": 13, "breakout": [13, 14], "soic": 13, "1212": 13, "gurawfaegucaqqfvnvtyeg": 13, "eaiaiqobchmit8zjzr6x8wivgdnvch2vbwvseaqyayabegjqg_d_bw": 13, "ina282aid": 13, "ze4": 13, "2fufuz19ilfayzxocfra": 13, "thd": [13, 14], "1211n": [13, 14], "2fha2pyfadugpyeg4idvm": 13, "2fmsr": 13, "252b7an": 13, "2f0t3ruis9pcaqjlt4": 13, "252bnrpuooeq": 13, "53": [13, 14, 20], "ssq": 13, "120": [13, 15, 16], "d": [13, 19, 20], "252be1bmvd": 13, "252bdzonqg": 13, "ejector": [13, 15, 16], "blk": [13, 15, 16], "10120550": [13, 15, 16], "conrad": [13, 15, 16], "com": [13, 14, 15, 16, 17, 19, 20], "bkl": [13, 15, 16], "space": [13, 15, 16], "254": [13, 15, 16], "row": [13, 14, 15, 16], "pc": [13, 15, 16], "741435": [13, 16], "searchterm": [13, 15, 16], "searchtyp": [13, 15, 16], "searchsuggest": [13, 15, 16], "femal": [13, 14, 15, 16, 19, 20], "hexagonal": 13, "87": [13, 14, 16], "48": [13, 14, 19, 20], "harwin": 13, "r25": 13, "3002002": 13, "w0yvoo0ixfenuv0hsdc4": 13, "2fq": 13, "86": [13, 14, 15, 16], "437": [13, 14], "1108331841001101": 13, "318": [13, 14], "ftmup6kvi2tnqoeziaq": 13, "2fpa": 13, "figur": [13, 17, 19, 20], "show": [13, 19, 20], "schemat": [13, 20], "plug": [13, 19, 20], "plai": 13, "propos": [13, 19, 20], "florsch": [13, 19, 20], "advantag": 13, "signal": [13, 14, 19, 20], "lie": [13, 19, 20], "114": [13, 19, 20], "directli": [13, 19, 20], "realiz": 13, "around": [13, 17], "tdh15": 13, "inpout": 13, "than": [13, 19, 20], "just": [13, 20], "decreas": 13, "don": [13, 17], "t": [13, 14, 15, 16, 17, 18], "forget": [13, 17], "kei": 13, "r_shunt": 13, "ohmpi_config": 13, "dict": 13, "adjust": [13, 19, 20], "tow": 13, "dot": 13, "corner": 13, "lm158": 13, "ads115": [13, 19, 20], "3x11": 13, "wurth": [13, 14], "elektronik": [13, 14], "971110321": 13, "305": [13, 15, 16], "apm": [13, 15, 16], "hexseal": [13, 15, 16], "rm3x8mm": [13, 15, 16], "2701": [13, 15, 16], "jjse": [13, 15, 16], "2f12mkns3vxsdryxuhw": [13, 15, 16], "shutdown": 13, "unplug": 13, "bottom": [13, 19, 20], "11mm": 13, "m3": [13, 15, 16], "upper": 13, "everyth": 13, "screen": [13, 19, 20], "1kohm": 13, "r2": [13, 19, 20], "220": 13, "r1": [13, 19, 20], "padboard": 13, "spool": 13, "sample_measurement_exampl": 13, "result": [13, 19, 20], "2023": 14, "offer": [14, 17, 19, 20], "superior": 14, "compar": 14, "predecessor": 14, "evolv": [14, 19, 20], "major": 14, "mikro": 14, "1887": [], "isol": 14, "200v": 14, "bom": [], "140": [15, 16], "560": [15, 16], "62": [15, 16], "92": [15, 16, 19, 20], "tru": [15, 16, 19, 20], "1580994": [15, 16], "256": [15, 16], "091": [15, 16], "296": [15, 16], "incorpor": [14, 15, 16, 17], "sgaepimzzmueqxo7l": [15, 16], "2fbpyakboruumren": [15, 16], "56": [15, 16], "776": [15, 16], "205": [15, 16], "46": [14, 15, 16], "103321": [15, 16], "5twgzeq9e7hsylqaljjyrw": [15, 16], "732": [15, 16], "sgaepimzzmskedp9slc0yfx16nydmpxjueeogolbldi": [15, 16], "325": [15, 16], "over": [15, 16, 18], "503811": [15, 16], "nchannel": [15, 16], "471": [15, 16], "576": [15, 16, 19], "vhuuswq2": [15, 16], "252bsz9b": [15, 16], "2ff6fcxt7g": [15, 16], "100k": [15, 18], "061": [15, 16], "616": [15, 16], "beyschlag": [14, 15, 16], "mba02040c1003frp00": [14, 15, 16], "mzrxyrlhvdt9crf7zyf": [14, 15, 16], "2f5q": [14, 15, 16], "89": [14, 15, 16], "2717": [15, 16], "sgaepimzzmsyydr3r27av4eqf73yoh": [15, 16], "252baqg": [15, 16], "252bz3hvktao": [15, 16], "10120558": [15, 16], "54": [15, 16], "No": [15, 16], "51": [15, 16], "741727": [15, 16], "10120862": [15, 16], "strain": [15, 16], "relief": [15, 16], "44": [14, 15, 16, 19, 20], "742063": [15, 16], "10120158": [15, 16], "x": [15, 16, 19, 20], "multi": [15, 16, 19, 20], "colour": [15, 16], "1012015810": [15, 16], "127": [15, 16], "008": [15, 16], "1548658": [15, 16], "79": [15, 16], "49": [15, 16], "keyston": [15, 16], "24300": [15, 16], "uwqyq": [15, 16], "2f2czwu0ejpozmzc2a": [15, 16], "745": [15, 16], "846": [15, 16], "614": [15, 16], "25515": [15, 16], "2f2czwuxuhumfr": [15, 16], "252bzuq": [15, 16], "updat": [16, 17], "100k\u03c9": 16, "mm\u00b2": [16, 19, 20], "55": [16, 19, 20], "328": 16, "uqd7xcvsscnr3hwd6fta8g": 16, "whose": [17, 19, 20], "main": [17, 19, 20], "summar": 17, "cover": 17, "acquisit": 17, "separ": 17, "json": [17, 20], "ohmpi_set": 17, "central": 17, "handler": 17, "layer": 17, "excel": 17, "log": 17, "broker": 17, "zip": 17, "rotat": 17, "disk": 17, "exec_logg": 17, "data_logg": 17, "plan": 17, "state": 17, "health": 17, "soh": 17, "futur": 17, "By": 17, "written": 17, "consol": 17, "like": [17, 18], "local": 17, "dai": 17, "size": [14, 17], "exce": 17, "sent": 17, "level": [14, 17], "edit": 17, "setup_logg": 17, "custom": 17, "repositori": [17, 19, 20], "prefer": [17, 19, 20], "desir": 17, "usernam": 17, "password": 17, "One": [17, 18], "alter": 17, "keep": 17, "bash": 17, "run_http_interfac": 17, "sh": 17, "iot": 17, "messag": 17, "friendli": 17, "graphic": 17, "quick": 17, "easi": 17, "wi": 17, "fi": 17, "point": [17, 19, 20], "ap": 17, "webserv": 17, "serv": [17, 19, 20], "index": 17, "html": 17, "laptop": 17, "mobil": 17, "phone": 17, "upload": 17, "sequenc": [17, 19, 20], "download": [17, 19, 20], "act": 17, "raspap": 17, "runonstart": 17, "141": 17, "8080": 17, "pseudo": 17, "evolut": 17, "quadrupol": [17, 19, 20], "appar": 17, "especi": 17, "suit": 17, "autom": 17, "ipython": 17, "ssh": 17, "putti": 17, "maco": 17, "linux": 17, "found": 17, "gitlab": [17, 19, 20], "entir": [17, 19, 20], "np": 17, "chdir": 17, "object": 17, "k": [14, 17], "load": 17, "manual": [17, 19, 20], "injection_dur": [17, 19, 20], "nb_stack": 17, "nbr_mea": [17, 19, 20], "update_set": 17, "arrai": [14, 17, 19, 20], "shape": 17, "set_sequ": 17, "n2": 17, "string": 17, "load_sequ": 17, "abmn": [17, 19, 20], "rs_check": 17, "synchron": 17, "wait": 17, "return": [17, 19, 20], "prompt": 17, "run_sequ": 17, "run_sequence_async": 17, "thread": 17, "immedi": 17, "sleep": 17, "interrupt": 17, "kill": 17, "asynchron": 17, "interv": 17, "nb_mea": 17, "sequence_delai": [17, 19, 20], "run_multiple_sequ": 17, "taken": 17, "switch_mux_on": 17, "run_measur": 17, "switch_mux_off": 17, "risk": 17, "short": 17, "argument": 17, "autogain": 17, "true": 17, "ad": [17, 19, 20], "good": 17, "resolut": [17, 19, 20], "usag": 17, "consumpt": [17, 19, 20], "process": 17, "sensor": [14, 17], "scope": 17, "internet": 17, "network": 17, "auxiliari": 17, "publish": [17, 19], "subscrib": 17, "approach": 17, "mosquitto": 17, "server": 17, "reachabl": 17, "net": [14, 17], "servic": 17, "install_local_mqtt_brok": 17, "examin": 17, "parti": 17, "explor": 17, "reboot": 17, "further": 17, "format": 17, "kwarg": 17, "illustr": [17, 19, 20], "cmd_id": 17, "3fzxv121uitwgjwygcz4xw": 17, "cmd": 17, "nb_electrod": [17, 19, 20], "3fzxv121uitwgjwygcz4yw": 17, "made": [17, 19, 20], "dashboard": 17, "browser": 17, "flow": [17, 19, 20], "editor": [17, 19, 20], "node": 17, "complex": 17, "properli": [17, 18], "palett": 17, "manag": [14, 17, 19, 20], "noder": 17, "doc": 17, "guid": 17, "ui": 17, "visual": 17, "cookbook": 17, "due": 18, "quit": 18, "fragil": 18, "still": [18, 19, 20], "conductor": 18, "turn": [18, 19, 20], "multimet": 18, "broken": 18, "shoudn": 18, "wa": [18, 19, 20], "burn": 18, "expect": 18, "try": 18, "effect": 18, "voltmet": [18, 19, 20], "sens": 18, "malfunct": 18, "erron": 18, "solv": 18, "most": 18, "vdd": 18, "reach": 18, "stronger": [18, 19, 20], "smaller": [18, 19, 20], "journal": 19, "bug": 19, "explain": 19, "miss": 19, "invit": 19, "v1": [19, 20], "commerci": [19, 20], "cpu": [19, 20], "w": [14, 19, 20], "storag": [19, 20], "o1": [19, 20], "youtub": [19, 20], "wjwzhv1v3pk": [19, 20], "noob": [19, 20], "simpl": [19, 20], "unexpectedli": [19, 20], "boot": [19, 20], "cd": [19, 20], "gnu": [19, 20], "nano": [19, 20], "At": [19, 20], "op": [14, 19, 20], "dl": [19, 20], "press": [19, 20], "enter": [19, 20], "escap": [19, 20], "studi": [19, 20], "hous": [14, 19, 20], "diagram": [19, 20], "displai": [19, 20], "mimic": [19, 20], "behavior": [19, 20], "soil": [19, 20], "subject": [19, 20], "r11": [19, 20], "r10": [19, 20], "r12": [19, 20], "constitut": [19, 20], "stainless": [19, 20], "steel": [19, 20], "r9": [19, 20], "less": [19, 20], "sum": [19, 20], "000": [19, 20], "intens": [19, 20], "potenti": [19, 20], "calcul": [19, 20], "insert": [19, 20], "1115": [19, 20], "a1": [19, 20], "a0": [19, 20], "increas": [19, 20], "r5": [19, 20], "r8": [19, 20], "r6": [19, 20], "r7": [19, 20], "a2": [19, 20], "a3": [19, 20], "obtain": [19, 20], "ly": [19, 20], "let": [19, 20], "equal": [19, 20], "multipli": [19, 20], "reduct": [19, 20], "despit": [19, 20], "calibr": [19, 20], "variou": [14, 19, 20], "disturb": [19, 20], "estim": [19, 20], "mega": [19, 20], "shortcut": [19, 20], "excess": [19, 20], "lithium": [19, 20], "ion": [19, 20], "automobil": [19, 20], "lead": [14, 19, 20], "acid": [19, 20], "strong": [19, 20], "hazard": [19, 20], "fuse": [19, 20], "onto": [19, 20], "ohmmet": [19, 20], "coeffici": [19, 20], "coef_p0": [19, 20], "coef_p1": [19, 20], "coef_p2": [19, 20], "coef_p3": [19, 20], "coef": [19, 20], "po": [19, 20], "p1": [19, 20], "r3": [19, 20], "r4": [19, 20], "p2": [19, 20], "p3": [19, 20], "r_ref": [19, 20], "slope": [19, 20], "convers": [14, 19, 20], "p0": [19, 20], "accuraci": [19, 20], "lm358n": [19, 20], "appli": [19, 20], "weaker": 19, "tx": [19, 20], "rememb": [19, 20], "holder": [19, 20], "f": [19, 20], "circul": [19, 20], "fig": [19, 20], "common": [19, 20], "neg": [19, 20], "normal": [19, 20], "simultan": [19, 20], "role": [19, 20], "thu": [19, 20], "energ": [19, 20], "next": [19, 20], "featur": [19, 20], "strict": [19, 20], "in1": [19, 20], "in2": [19, 20], "in3": [19, 20], "in4": [19, 20], "5vdc": [14, 19, 20], "5vcc": [19, 20], "mm2": [19, 20], "lastli": [19, 20], "congratul": [19, 20], "construct": [19, 20], "ert": [19, 20], "sever": [19, 20], "ten": [19, 20], "thousand": [19, 20], "stuck": [19, 20], "hand": [19, 20], "cap": [19, 20], "produc": [19, 20], "clean": [19, 20], "distanc": [19, 20], "had": [19, 20], "extra": [19, 20], "final": [19, 20], "horizont": [19, 20], "vertic": [19, 20], "06": [14, 19, 20], "04": [19, 20], "05": [14, 19, 20], "din": [19, 20], "rail": [19, 20], "chosen": [19, 20], "incom": [19, 20], "instead": [19, 20], "moreov": [19, 20], "bought": [19, 20], "velleman": [19, 20], "wpm404": [19, 20], "potentiomet": [14, 19, 20], "scienc": [19, 20], "framework": [19, 20], "manuscript": [19, 20], "osf": [19, 20], "io": [19, 20], "dzwb4": [19, 20], "irstea": [19, 20], "unzip": [19, 20], "master": [19, 20], "readm": [19, 20], "assist": [19, 20], "disconnect": [19, 20], "handl": [19, 20], "charg": [19, 20], "full": [19, 20], "capac": [19, 20], "fewer": [19, 20], "bank": [19, 20], "2a": [19, 20], "ll": [19, 20], "insid": [19, 20], "numer": [19, 20], "optim": [19, 20], "attribut": [19, 20], "the9": [19, 20], "hear": [19, 20], "sound": [19, 20], "permut": [19, 20], "csv": [19, 20], "delai": [19, 20], "repetit": [19, 20], "littl": [19, 20], "public": [19, 20], "articl": [19, 20], "sainsmart": [19, 20], "canal": 19, "pour": 19, "arduino": 19, "dsp": [14, 19], "avr": 19, "pic": 19, "arm": 19, "99": [14, 19, 20], "199": [19, 20], "sain": [19, 20], "smart": [19, 20], "101": [19, 20], "70": [14, 19, 20], "103": [19, 20], "018": [19, 20], "1x1": [19, 20], "66": [14, 19, 20], "1568649": [19, 20], "1x0": [19, 20], "71": [14, 19, 20], "1565235": [19, 20], "68": [19, 20], "rs": [19, 20], "pro": [14, 19, 20], "897": [19, 20], "1332": [19, 20], "858": [19, 20], "627": [19, 20], "52": [14, 19, 20], "upw50b50rv": [19, 20], "1083": [19, 20], "7ah": [19, 20], "537": [19, 20], "5488": [19, 20], "lr20": [19, 20], "9v": [19, 20], "185": [19, 20], "4686": [19, 20], "ferrul": [19, 20], "piec": [19, 20], "weidmul": [19, 20], "9004330000": [19, 20], "966067": [19, 20], "car": 19, "littelfus": [19, 20], "fhac0002zxj": 19, "96": [14, 19], "trn3": 20, "suppress": 20, "10v": 20, "fast": 20, "decoupl": 20, "last": 20, "prevent": 20, "overh": 20, "toler": 20, "orient": 20, "h": [14, 20], "nf": 20, "jason": 20, "ohmpi_param": 20, "export_path": 20, "desktop": 20, "0251001": 20, "pat1l": 20, "2c": 14, "ref": 14, "link": 14, "eur": 14, "excl": 14, "vat": 14, "223": 14, "594": 14, "5063jd100k0ft": 14, "film": 14, "4watt": 14, "100kohm": 14, "8watt": 14, "bodi": 14, "eu": 14, "899": 14, "330": 14, "307": 14, "279": 14, "cfr100j330r": 14, "carbon": 14, "330ohm": 14, "1w": 14, "500ppm": 14, "ddevmfoh4ssvknglsgy0ha": 14, "228": 14, "603": 14, "cfr": 14, "25jb": 14, "4k7": 14, "yageo": 14, "4w": 14, "7k": 14, "588": 14, "wnc2r0fet": 14, "wirewound": 14, "2w": 14, "cdpnwznfzjb5bmolbzti": 14, "252bw": 14, "50v": 14, "1a": 14, "rectifi": 14, "214": 14, "637": 14, "1n4001": 14, "diotec": 14, "semiconductor": 14, "olc7aqgiedlll8na510wma": 14, "284": 14, "cree": 14, "941": 14, "c503bgancd0e0781": 14, "c503b": 14, "gan": 14, "cd0e0781": 14, "standard": 14, "green": 14, "527nm": 14, "mmround": 14, "32900": 14, "64600mcd": 14, "7d1ltpjg0i1j7dm": 14, "252b": 14, "252b5igzw": 14, "116": 14, "schottki": 14, "771": 14, "bat86113": 14, "bat86": 14, "113": 14, "nexperia": 14, "sod68": 14, "me8tqzrmiyx1ahcmzsx1tg": 14, "874": 14, "op27": 14, "ultra": 14, "offset": 14, "8dip": 14, "584": 14, "op27epz": 14, "inc": 14, "wivqp4zgangdp3uwih2ura": 14, "485": 14, "accessori": 14, "gurawfaeguaf08zux7w": 14, "2fuq": 14, "78": 14, "pack": 14, "ic": 14, "amazon": 14, "azdeliveri": 14, "parent": 14, "3x": 14, "dp": 14, "b07qhwltt": 14, "sr_1_5": 14, "__mk_fr_fr": 14, "c3": 14, "85m": 14, "85": 14, "c5": 14, "bd": 14, "95": 14, "91": 14, "crid": 14, "18whxz3e0nur5": 14, "keyword": 14, "qid": 14, "1702140215": 14, "sprefix": 14, "2cap": 14, "2c117": 14, "sr": 14, "ref03gpz": 14, "r": 14, "wivqp4zgangjpdfouwu1bw": 14, "dg411dj": 14, "781": 14, "e3": 14, "speed": 14, "dg411": 14, "xkjjivogybzznzq": 14, "252buwcw1q": 14, "unpolar": 14, "k104k15x7rf5ul2": 14, "multilay": 14, "mlcc": 14, "x7r": 14, "ammo": 14, "bc": 14, "rlgk8caobhbcqsnkgo2hja": 14, "568": 14, "10uf": 14, "667": 14, "eeu": 14, "eb1j100": 14, "aluminum": 14, "electrolyt": 14, "radial": 14, "63volt": 14, "aec": 14, "q200": 14, "ceafgkervibcbemsghcq5g": 14, "60v": 14, "600ma": 14, "700mw": 14, "transistor": 14, "zvn4206astz": 14, "335": 14, "522": 14, "chnl": 14, "onsemi": 14, "fairchild": 14, "2n7000bu": 14, "k2x4el1": 14, "2fkj6oexmhafsm5a": 14, "thd1512": 14, "11n": 14, "495": 14, "thd15": 14, "style": 14, "ckjk83fod0x2iyoeopcnmg": 14, "97": 14, "22n": 14, "1222n": 14, "ckjk83fod0uvycxqxchqfw": 14, "848": 14, "649": 14, "vi02215200j0g": 14, "vi0221520000g": 14, "amphenol": 14, "tb": 14, "ri": 14, "cla": 14, "180": 14, "anytek": 14, "mv7bduzupui3lmtbyxcxvw": 14, "088": 14, "74": 14, "932": 14, "1878": 14, "k5owtxstjao5l2rhk53deg": 14, "4976": 14, "mynhzdoqoqkab6t4ih2naq": 14, "serial": 14, "eeprom": 14, "2kb": 14, "dip8": 14, "03": 14, "474": 14, "bob": 14, "15439": 14, "sparkfun": 14, "translat": 14, "pca9306": 14, "p1jmdcb91o4xonpr": 14, "252b0xi4g": 14, "omhron": 14, "653": 14, "1a4": 14, "dc5": 14, "spst": 14, "NO": 14, "seal": 14, "pwf36butxbgftk6ytlb7nq": 14, "575": 14, "1104731841001000": 14, "47": 14, "standrd": 14, "tail": 14, "5ag0nvq1c4xxooytdz6dow": 14, "113308": 14, "8p": 14, "gld": 14, "cont": 14, "wzeyyeqmoweyjis4txlt7q": 14, "11044316": 14, "316": 14, "16p": 14, "iggadovctsrh": 14, "252bxewrwehkg": 14, "prt": 14, "14017": 14, "tall": 14, "2x20": 14, "a4bxicggsn": 14, "2f": 14, "252baml822b65a": 14, "ribon": 14, "710": 14, "61200623021": 14, "wr": 14, "bhd": 14, "54mm": 14, "6p": 14, "strt": 14, "conn": 14, "phr8rmcireabk1ywkdxzfw": 14, "571": 14, "534237": 14, "rec": 14, "1x05p": 14, "vrt": 14, "eln3i3szm1klmlr": 14, "252bszcsuq": 14, "94": 14, "1x04p": 14, "gygf5pdsjzki3hk2o1eilq": 14, "535541": 14, "1x08p": 14, "xdp7pgunc": 14, "252buqvwkjjvkwqw": 14, "ssw11002g": 14, "tiger": 14, "bui": 14, "ssw10202g": 14, "102": 14, "252be2zeimtlw": 14, "2fblw": 14, "826629": 14, "10p": 14, "fazuumncxom0apli6zggxg": 14, "1761681": 14, "hdr": 14, "vert": 14, "ht": 14, "bqfptycq3dlaez2wzdz7aw": 14, "aisler": 14, "lang": 14, "10k": 14, "sip9": 14, "bournd": 14, "3296w_vertic": 14, "raspberryp": 14, "63": 14, "kiwi": 14, "4gb": 14, "4268": 14, "src": 14, "73": 14, "801": 14, "012": 14, "012000": 14, "5ag0nvq1c4x40xnvdlnkzg": 14, "overview": 14, "machin": 14, "thirteen": 14, "eepow": [], "fundament": [], "what": [], "_": []}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"ohmpi": [0, 1, 8, 9, 19, 20], "open": 0, "sourc": 0, "hardwar": [0, 5, 7], "resist": [0, 19, 20], "meter": 0, "summari": 0, "document": 0, "center": 0, "project": 1, "author": 1, "partner": 1, "cite": 1, "introduct": 1, "step": 2, "n": 2, "3": 2, "mux": [2, 15, 16], "board": [2, 9, 12, 13, 14, 15, 16, 19, 20], "part": [2, 11, 13, 14, 15, 16], "A": [2, 11, 13, 14, 15, 16, 18], "assembl": [2, 8, 12, 13, 14, 15, 16, 19, 20], "requir": [2, 13, 14, 15, 16], "compon": [2, 5, 13, 14, 15, 16, 18, 19, 20], "b": [2, 11, 13, 15, 16, 18, 19, 20], "address": [2, 15, 16], "c": [2, 11, 13, 15, 16], "valid": [2, 15, 16], "api": 3, "refer": 3, "archiv": 4, "version": [4, 12], "softwar": [5, 17], "interfac": [5, 17], "new": 5, "exampl": 6, "applic": [6, 17], "electron": 9, "design": 9, "measur": [9, 12, 13, 14, 19, 20], "multiplex": [9, 19, 20], "power": 10, "suppli": 10, "12v": 10, "batteri": 10, "regul": 10, "dps5005": 10, "raspberri": [11, 19, 20], "pi": [11, 19, 20], "configur": [11, 17, 19, 20], "os": [11, 19, 20], "instal": [11, 19, 20], "virtual": [11, 19, 20], "environ": [11, 19, 20], "packag": [11, 19, 20], "activ": [11, 19, 20], "thonni": [11, 19, 20], "python": [11, 17, 19, 20], "id": [11, 19, 20], "recogn": 12, "specif": 12, "you": 12, "v2023": [13, 15], "list": [13, 14, 15, 16, 19, 20], "descript": [13, 14, 19, 20], "start": 13, "up": 13, "check": 13, "2024": 14, "0": 14, "2": 14, "v2024": 16, "oper": [17, 19, 20], "system": 17, "architectur": 17, "logger": 17, "file": 17, "web": 17, "mqtt": 17, "troubleshoot": 18, "issu": 18, "puls": 18, "between": 18, "valu": 18, "given": 18, "correct": 18, "one": 18, "commun": 18, "v": [19, 20], "1": [19, 20], "01": 19, "limit": [19, 20], "32": [19, 20], "electrod": [19, 20], "The": [19, 20], "philosophi": [19, 20], "technic": [19, 20], "data": [19, 20], "current": [19, 20], "inject": [19, 20], "card": [19, 20], "connect": [19, 20], "electr": [19, 20], "implement": [19, 20], "first": [19, 20], "four": [19, 20], "instruct": [19, 20], "preliminari": [19, 20], "procedur": [19, 20], "onli": [19, 20], "initi": [19, 20], "startup": [19, 20], "paramet": [19, 20], "complet": [19, 20], "tabl": 19, "titl": 19, "02": 20, "schemat": 14, "interact": 14, "bom": 14}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 56}}) \ No newline at end of file +Search.setIndex({"docnames": ["index", "source_rst/Ohmpi", "source_rst/api", "source_rst/archived_version", "source_rst/developing_hardware_components", "source_rst/gallery", "source_rst/hardware", "source_rst/hardware/assembling", "source_rst/hardware/hw_info", "source_rst/hardware/hw_pwr", "source_rst/hardware/hw_rpi", "source_rst/hardware/mb", "source_rst/hardware/mb/mb_2023", "source_rst/hardware/mb/mb_2024", "source_rst/hardware/mux_2023", "source_rst/hardware/mux_2024", "source_rst/software", "source_rst/software/architecture", "source_rst/software/developments", "source_rst/software/installation", "source_rst/software/operations", "source_rst/troubleshooting", "source_rst/v1.xx/V1_01", "source_rst/v1.xx/V1_02"], "filenames": ["index.rst", "source_rst\\Ohmpi.rst", "source_rst\\api.rst", "source_rst\\archived_version.rst", "source_rst\\developing_hardware_components.rst", "source_rst\\gallery.rst", "source_rst\\hardware.rst", "source_rst\\hardware\\assembling.rst", "source_rst\\hardware\\hw_info.rst", "source_rst\\hardware\\hw_pwr.rst", "source_rst\\hardware\\hw_rpi.rst", "source_rst\\hardware\\mb.rst", "source_rst\\hardware\\mb\\mb_2023.rst", "source_rst\\hardware\\mb\\mb_2024.rst", "source_rst\\hardware\\mux_2023.rst", "source_rst\\hardware\\mux_2024.rst", "source_rst\\software.rst", "source_rst\\software\\architecture.rst", "source_rst\\software\\developments.rst", "source_rst\\software\\installation.rst", "source_rst\\software\\operations.rst", "source_rst\\troubleshooting.rst", "source_rst\\v1.xx\\V1_01.rst", "source_rst\\v1.xx\\V1_02.rst"], "titles": ["OHMPI: Open source and open hardware resistivity-meter", "OhmPi project", "API reference", "Archived versions", "Software interface to new hardware components", "Examples of applications", "Hardware", "Assembling the OhmPi", "OhmPi electronic design", "Power supply", "Raspberry Pi configuration", "Measurement board", "Measurement board v2023", "Measurement board 2024.0.2", "MUX board v2023", "MUX board v2024", "Software and operation", "Software architecture", "<no title>", "Installation", "Configuration file", "Troubleshooting", "OhmPi V 1.01 (limited to 32 electrodes)", "OhmPi V 1.02 (limited to 32 electrodes)"], "terms": {"releas": [0, 20], "v2024rc": 0, "date": [0, 22, 23], "jan": 0, "09": [0, 22, 23], "2024": [0, 8, 11], "start": [0, 4, 10, 11, 14, 15, 20, 22, 23], "juli": 0, "2016": 0, "author": [0, 10, 22, 23], "r\u00e9mi": [0, 1], "clement": [0, 1], "nicola": [0, 1], "forquet": [0, 1], "yannick": [0, 1], "fargier": [0, 1], "vivien": [0, 1], "duboi": [0, 1], "h\u00e9l\u00e8ne": [0, 1], "guyard": [0, 1], "olivi": [0, 1], "kaufmann": [0, 1], "guillaum": [0, 1], "blanchi": [0, 1], "arnaud": [0, 1], "watlet": [0, 1], "target": 0, "user": [0, 10, 17, 20, 22, 23], "research": 0, "develop": [0, 1, 4, 10, 12, 13, 17, 22, 23], "statu": 0, "some": [0, 4, 8, 20, 22, 23], "matur": 0, "progress": 0, "offici": 0, "guidelin": 0, "gener": [0, 6, 8, 12, 13, 14, 15, 17, 22, 23], "tutori": 0, "content": 0, "project": [0, 4, 7, 10, 12, 13, 14, 15, 16, 22, 23], "partner": 0, "cite": 0, "introduct": [0, 17], "electron": [0, 1, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 22, 23], "design": [0, 4, 6, 17, 20, 22, 23], "measur": [0, 1, 6, 7, 10, 14, 15, 17, 20, 21], "board": [0, 4, 6, 7, 10, 17, 21], "mux": [0, 6, 7, 17, 22, 23], "v2023": [0, 6, 8, 11, 21], "v2024": [0, 6, 8, 11, 17, 21], "power": [0, 6, 7, 11, 12, 13, 14, 15, 22, 23], "suppli": [0, 6, 7, 11, 12, 13, 14, 15, 22, 23], "raspberri": [0, 6, 7, 12, 13, 14, 15, 16, 20], "pi": [0, 6, 7, 12, 13, 16, 20], "configur": [0, 4, 6, 8, 16, 17, 19], "assembl": [0, 1, 6, 10, 16, 17], "softwar": [0, 10, 19, 20, 22, 23], "oper": [0, 4, 7, 8, 10, 11, 12, 17, 19, 20], "system": [4, 10, 16, 20, 22, 23], "architectur": [0, 16], "logger": [1, 16, 22, 23], "file": [0, 4, 6, 10, 12, 16, 17, 19, 22, 23], "interfac": [0, 13, 16, 17, 19], "applic": [0, 1, 4, 6, 8, 16, 17], "api": [0, 17, 20], "refer": [0, 7, 12, 13, 14, 15, 20, 22, 23], "troubleshoot": 0, "issu": 0, "puls": [0, 8, 11, 22, 23], "between": [0, 7, 8, 12, 14, 15, 17, 19, 22, 23], "A": [0, 1, 4, 6, 7, 8, 9, 11, 20, 22, 23], "b": [0, 6, 7, 8, 9, 11, 13], "valu": [0, 8, 12, 14, 15, 22, 23], "given": [0, 8, 20], "correct": [0, 22, 23], "one": [0, 7, 12, 20, 22, 23], "commun": [0, 1, 8, 17, 19, 20], "compon": [0, 8, 10, 16, 20], "exampl": [0, 7, 12, 14, 15, 20, 22, 23], "new": [0, 10, 17, 20, 21, 22, 23], "archiv": 0, "version": [0, 4, 6, 10, 12, 17, 20, 22, 23], "v": [0, 3, 7, 8, 9, 12, 14, 15, 21], "1": [0, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 20], "01": [0, 3, 13, 23], "limit": [0, 3, 12], "32": [0, 3, 7, 10, 13], "electrod": [0, 1, 3, 6, 7, 8, 9, 12, 14, 15, 21], "02": [0, 3, 12, 13, 22], "inra": [1, 5], "reversa": [1, 22, 23], "villeurbann": 1, "franc": 1, "universit\u00e9": 1, "de": 1, "mon": 1, "belgium": 1, "ger": 1, "rro": 1, "univ": 1, "gustav": 1, "eiffel": 1, "ifsttar": 1, "lyon": 1, "ig": 1, "grenobl": 1, "alp": 1, "ilvo": 1, "merelbek": 1, "julien": 1, "ganc": 1, "emil": 1, "gro": 1, "et": [1, 12], "al": 1, "an": [1, 4, 6, 7, 8, 10, 12, 14, 15, 16, 17, 19, 20, 21, 22, 23], "open": [1, 4, 7, 10, 12, 13, 14, 15, 16, 21, 22, 23], "sourc": [1, 4, 9, 10, 13, 19, 22, 23], "data": [1, 8, 13, 20], "dedic": [1, 20], "electr": [1, 12, 13], "resist": [1, 7, 8, 12, 20, 21], "imag": [1, 10], "small": [1, 7, 8, 12, 13, 20, 22, 23], "laboratori": [1, 7, 11, 22, 23], "scale": [1, 8], "hardwarex": 1, "elsevi": 1, "2020": 1, "8": [1, 7, 8, 10, 12, 13, 14, 15, 20, 22, 23], "24": [1, 7, 11, 12, 13, 15, 22, 23], "p": [1, 12, 14, 15], "ff10": 1, "1016": 1, "j": 1, "ohx": 1, "e00122ff": 1, "particip": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "all": [1, 4, 7, 10, 12, 13, 14, 15, 16, 17, 19, 20, 22, 23], "requir": [1, 4, 7, 10, 16, 17, 19, 20, 22, 23], "skill": [1, 7, 10, 11, 12, 13, 14, 15, 16, 22, 23], "respect": [1, 7, 8, 10, 12, 13, 14, 15, 16, 22, 23], "safeti": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "rule": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "must": [1, 7, 8, 10, 12, 13, 14, 15, 16, 21, 22, 23], "profession": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "context": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "peopl": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "compet": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "The": [1, 4, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21], "team": [1, 4, 7, 10, 12, 13, 14, 15, 16, 22, 23], "cannot": [1, 7, 8, 10, 12, 13, 14, 15, 16, 22, 23], "held": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "respons": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "ani": [1, 7, 10, 11, 12, 13, 14, 15, 16, 20, 21, 22, 23], "materi": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "human": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "damag": [1, 7, 10, 12, 13, 14, 15, 16, 21, 22, 23], "which": [1, 7, 8, 10, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23], "would": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "associ": [1, 7, 10, 12, 13, 14, 15, 16, 17, 22, 23], "us": [1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23], "equip": [1, 7, 8, 10, 12, 13, 14, 15, 16, 22, 23], "doe": [1, 7, 10, 12, 13, 14, 15, 16, 22, 23], "work": [1, 4, 7, 10, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23], "after": [1, 7, 10, 12, 13, 14, 15, 16, 20, 22, 23], "you": [1, 4, 6, 7, 8, 10, 12, 14, 15, 19, 20, 21, 22, 23], "mai": [1, 10, 17, 20, 21, 22, 23], "redistribut": 1, "modifi": [1, 4, 22, 23], "thi": [1, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23], "document": [1, 6, 20, 22], "make": [1, 4, 8, 14, 15, 20, 22, 23], "product": [1, 12, 13, 14, 15], "under": [1, 7, 22, 23], "term": [1, 4], "cern": 1, "ohl": 1, "v2": 1, "distribut": [1, 8], "without": [1, 8, 14, 15, 21, 22, 23], "express": [1, 4], "OR": 1, "impli": [1, 14, 15, 17], "warranti": 1, "includ": [1, 4, 10, 14, 15, 17, 20, 22, 23], "OF": 1, "merchant": 1, "satisfactori": 1, "qualiti": 1, "AND": 1, "fit": 1, "FOR": 1, "particular": [1, 17], "purpos": [1, 7, 13, 22, 23], "pleas": [1, 7, 20, 22, 23], "see": [1, 8, 17, 20, 21, 22, 23], "condit": [1, 13], "present": [1, 4, 7, 13, 14, 15, 22, 23], "low": [1, 13, 22, 23], "cost": [1, 4, 12, 13, 14, 15, 17, 22, 23], "hardwar": [1, 16, 19, 22, 23], "meter": [1, 7, 22, 23], "provid": [1, 11, 13, 17, 20, 22, 23], "scientif": 1, "robust": [1, 21, 22, 23], "flexibl": [1, 17], "tool": [1, 13], "experi": [1, 20, 21, 22, 23], "call": [1, 7, 8, 10, 14, 15, 19, 20], "basic": [1, 4, 17], "meterfeatur": 1, "current": [1, 6, 8, 9, 11, 12, 13, 17, 20, 21], "inject": [1, 6, 8, 9, 13, 17, 20], "function": [1, 4, 17, 20, 22, 23], "multiplex": [1, 6, 7, 14, 15], "allow": [1, 12, 13, 14, 15, 17, 20, 22, 23], "perform": [1, 4, 10, 13, 17, 19, 22, 23], "automat": [1, 20, 22, 23], "up": [1, 8, 9, 10, 11, 13, 14, 15, 20, 21, 22, 23], "64": [1, 13, 14, 15, 22, 23], "s": [1, 12, 13, 14, 15, 20, 21, 22, 23], "philosophi": 1, "fulli": 1, "toolto": 1, "surfac": 1, "anyon": 1, "who": 1, "want": [1, 23], "get": [1, 10, 12, 20, 22, 23], "involv": [1, 20], "welcom": [1, 4], "join": 1, "ohmpi": [3, 4, 5, 6, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21], "channel": [11, 13, 14, 15, 22, 23], "mechan": [8, 14, 15, 17, 20, 21, 22, 23], "base": [4, 10, 14, 15, 17, 20, 22, 23], "omron": [13, 14, 15], "manufactur": [12, 13, 14, 15, 22, 23], "relai": [8, 10, 12, 13, 14, 15, 21, 22, 23], "g5le": [13, 14, 15], "vd": [14, 15], "12": [7, 8, 11, 12, 13, 14, 15, 22, 23], "vdc": [11, 13, 14, 15], "each": [7, 8, 10, 11, 14, 15, 17, 22, 23], "combin": [6, 14, 15], "zvn4206a": [14, 15], "mofset": [14, 15], "ha": [8, 10, 11, 13, 14, 15, 17, 21, 22, 23], "onli": [4, 8, 9, 14, 15, 17], "30": [7, 14, 15, 22, 23], "gpio": [7, 8, 10, 13, 14, 15, 22, 23], "enough": [14, 15, 22, 23], "activ": [6, 14, 15, 16], "repres": [14, 15, 17, 22, 23], "512": [14, 15], "we": [6, 8, 9, 10, 12, 14, 15, 19, 20, 21, 22, 23], "expand": [8, 13, 14, 15], "i2c": [8, 10, 12, 13, 14, 15, 19, 21], "mcp23017": [8, 14, 15], "have": [4, 8, 10, 12, 14, 15, 17, 20, 21, 22, 23], "type": [4, 10, 13, 14, 15, 17, 19, 22, 23], "tca9548a": [10, 14, 15], "from": [7, 8, 11, 14, 15, 17, 20, 21, 22, 23], "adafruit": [10, 12, 13, 14, 15, 22, 23], "go": [10, 13, 14, 15, 20], "128": [14, 15], "card": [7, 10, 14, 15], "its": [7, 10, 13, 14, 15, 20, 22, 23], "own": [14, 15], "digit": [8, 12, 13, 14, 15, 22, 23], "0x70": [14, 15], "0x77": [14, 15], "In": [4, 8, 10, 12, 14, 15, 17, 21, 22, 23], "follow": [4, 7, 8, 10, 11, 12, 14, 15, 17, 19, 20, 22, 23], "0x71": [14, 15], "0x72": [14, 15], "m": [7, 8, 10, 12, 14, 15, 22, 23], "0x73": [14, 15], "4": [7, 8, 10, 12, 13, 14, 15, 16, 20, 21, 22, 23], "need": [6, 8, 9, 11, 12, 14, 15, 19, 20, 21, 22, 23], "pcb": [4, 12, 13, 14, 15, 22, 23], "2": [4, 7, 8, 10, 11, 12, 14, 15, 16, 20, 22, 23], "instal": [0, 6, 7, 12, 13, 14, 15, 16, 20], "100": [13, 14, 15, 20, 22, 23], "kohm": [12, 13, 14, 15, 22, 23], "resistor": [8, 11, 12, 13, 14, 15, 21, 22, 23], "mosfet": [13, 14, 15], "diod": [13, 14, 15], "1n4007": [14, 15], "5": [7, 8, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23], "6": [7, 10, 12, 13, 14, 15, 22, 23], "termin": [7, 10, 12, 13, 14, 15, 19, 20, 22, 23], "screw": [7, 12, 14, 15, 22, 23], "7": [7, 10, 12, 13, 14, 15, 22, 23], "male": [12, 14, 15], "header": [12, 13, 14, 15, 22, 23], "pin": [12, 13, 14, 15, 22, 23], "strip": [7, 12, 13, 14, 15, 22, 23], "16": [7, 8, 12, 13, 14, 15, 22, 23], "9": [7, 10, 12, 13, 14, 15, 22, 23], "dip": [12, 13, 14, 15], "dual": [12, 14, 15, 22, 23], "line": [8, 12, 14, 15, 19, 21, 22, 23], "socket": [12, 13, 14, 15], "14": [7, 12, 13, 14, 15], "10": [7, 12, 13, 14, 15, 20, 22, 23], "duplic": [14, 15], "time": [8, 10, 14, 15, 20, 22, 23], "everi": [14, 15, 20], "To": [12, 14, 15, 20, 21, 22, 23], "build": [6, 14, 15, 17, 22, 23], "necessari": [4, 7, 10, 14, 15, 22, 23], "differ": [6, 7, 8, 10, 12, 13, 14, 15, 17, 20, 22, 23], "It": [4, 9, 10, 13, 14, 15, 17, 19, 20, 21, 22, 23], "therefor": [14, 15, 22, 23], "identifi": [14, 15], "assign": [14, 15], "alloc": [14, 15], "code": [4, 10, 11, 14, 15, 22, 23], "here": [7, 14, 15, 23], "select": [10, 14, 15, 22, 23], "default": [14, 15, 17, 20], "For": [8, 10, 12, 14, 15, 20, 22, 23], "suggest": [12, 14, 15, 22, 23], "mount": [7, 12, 14, 15, 22, 23], "jumper": [14, 15], "note": [7, 14, 15, 22, 23], "name": [4, 14, 15, 20, 22, 23], "zoom": [7, 14, 15], "first": [4, 7, 8, 10, 14, 15, 19, 20], "test": [4, 7, 10, 12, 14, 15, 20, 22, 23], "befor": [7, 8, 14, 15, 19, 20, 22, 23], "them": [14, 15, 20, 22, 23], "definit": [14, 15], "simplifi": [14, 15], "thing": [14, 15, 20], "do": [4, 7, 13, 14, 15, 17, 20], "prepar": [12, 14, 15, 22, 23], "50": [7, 9, 11, 14, 15, 22, 23], "cm": [7, 14, 15, 22, 23], "long": [7, 8, 14, 15], "flat": [14, 15], "wire": [7, 8, 10, 13, 14, 15, 22, 23], "two": [4, 8, 9, 12, 14, 15, 20, 21, 22, 23], "pole": [14, 15, 22, 23], "connector": [7, 14, 15, 22, 23], "cabl": [7, 10, 12, 13, 14, 15, 22, 23], "contact": [12, 14, 15, 20, 22, 23], "connect": [7, 8, 9, 12, 13, 14, 15, 16, 20, 21], "12v": [6, 7, 8, 12, 13, 14, 15, 22, 23], "your": [4, 6, 10, 11, 12, 14, 15, 22, 23], "run": [7, 10, 12, 14, 15, 16, 20, 22, 23], "write": [4, 12, 14, 15, 20, 22, 23], "i2cdetect": [12, 14, 15], "y": [12, 14, 15], "three": [12, 14, 15, 17, 20, 22, 23], "should": [4, 7, 8, 10, 12, 14, 15, 17, 20, 22, 23], "appear": [10, 12, 14, 15, 22, 23], "been": [10, 11, 13, 14, 15, 17, 20, 22, 23], "detect": [14, 15], "script": [4, 14, 15, 16, 20], "test_mux_board": [14, 15], "py": [4, 12, 14, 15, 17, 20, 22, 23], "These": [3, 6, 8, 17, 20, 21, 22, 23], "ar": [3, 4, 7, 8, 9, 10, 11, 12, 17, 19, 20, 21, 22, 23], "support": [3, 10], "anymor": [3, 21], "draft": 4, "TO": [4, 15, 21], "BE": [4, 15, 21], "review": [4, 21], "section": [4, 6, 11, 16, 20, 22, 23], "intend": 4, "part": [4, 6, 8, 11, 17, 21, 22, 23], "advic": [4, 21], "best": 4, "practic": [4, 22, 23], "help": [4, 7, 8, 20], "within": [4, 10, 20, 22, 23], "contribut": 4, "howev": [4, 8, 13, 17, 22, 23], "order": [4, 17, 20, 22, 23], "maintain": 4, "track": [4, 22, 23], "promot": 4, "exchang": 4, "reus": 4, "contributor": 4, "ideal": 4, "few": 4, "step": [4, 10, 12, 14, 15, 16, 17, 22, 23], "case": [4, 10, 21, 22, 23], "distinguish": 4, "when": [4, 7, 9, 19, 20, 21, 22, 23], "deal": 4, "compli": 4, "wai": [4, 10, 17, 22, 23], "Such": 4, "typic": [4, 8, 20, 22, 23], "focu": 4, "improv": [4, 17, 23], "exist": [4, 6, 17, 22, 23], "reduc": [4, 8, 17], "adapt": [4, 12, 17, 20, 22, 23], "rang": [4, 11, 17, 21, 22, 23], "specif": [4, 6, 13, 17, 20, 22, 23], "easili": [4, 17, 20, 21], "avail": [4, 9, 17, 20, 22, 23], "newli": 4, "creat": [4, 8, 10, 19, 20, 22, 23], "expos": [4, 17], "minim": [4, 17], "hardware_system": 4, "introduc": [4, 11, 17, 20, 22, 23], "chang": [4, 12, 14, 15, 17, 20, 21], "singl": [4, 13, 20, 22, 23], "also": [4, 8, 9, 10, 19, 20, 22, 23], "discuss": 4, "ohmpi_hardwar": 4, "class": [4, 17, 20], "initi": 4, "veri": [4, 8, 23], "earli": 4, "stage": 4, "investig": 4, "implement": [4, 17, 20], "solut": [4, 22, 23], "If": [4, 10, 12, 19, 21, 22, 23], "path": [4, 8, 10, 22, 23], "strategi": 4, "readi": 4, "devic": [4, 8, 12, 13, 14, 15], "conceiv": 4, "recommend": [4, 10, 20, 22, 23], "import": [4, 17, 20], "kicad": 4, "both": [4, 17, 22, 23], "schema": 4, "share": 4, "alwai": 4, "branch": 4, "python": [4, 6, 16, 17, 19], "copi": [4, 10, 20], "similar": [4, 21], "modul": [4, 6, 8, 13, 17, 19, 22, 23], "store": [4, 20], "hardware_compon": 4, "directori": [4, 10, 20, 22, 23], "defin": [4, 7, 20], "relev": [4, 7], "abstract": [4, 17], "abstract_hardware_compon": 4, "method": [4, 17], "interact": [4, 16, 17, 20], "accord": [4, 8, 22, 23], "sure": [4, 20, 22, 23], "place": [4, 7, 8, 21, 22, 23], "config": [4, 12, 20, 22, 23], "describ": [4, 7, 10, 11, 12, 16, 17, 22, 23], "hardware_config": 4, "dictionari": 4, "config_xxx": 4, "where": [4, 6, 8, 10, 20, 22, 23], "xxx": 4, "replac": [4, 13, 21, 23], "3": [4, 7, 8, 10, 12, 13, 14, 15, 16, 20, 22, 23], "conduct": [4, 22, 23], "todo": 5, "e": [5, 11, 17, 20, 22, 23], "g": [5, 11, 12, 13, 17, 22, 23], "rocherfort": 5, "contain": [6, 7, 10, 17, 22, 23], "compos": [6, 7], "mb": 6, "voltag": [6, 7, 8, 12, 13, 17, 21, 22, 23], "0": [6, 8, 11, 12, 14, 15, 20, 22, 23], "n": [6, 7, 8, 12, 13, 14, 15, 20, 22, 23], "address": [6, 8, 12, 22, 23], "pwr": 6, "either": [6, 10, 22, 23], "batteri": [6, 7, 12, 22, 23], "more": [6, 7, 8, 20, 21], "advanc": [6, 20], "can": [6, 7, 8, 9, 10, 20, 21, 22, 23], "control": [6, 8, 9, 20, 22, 23], "ctrl": [6, 22, 23], "raspberrypi": [6, 8, 9, 10, 13], "upgrad": [6, 13, 23], "recogn": 6, "c": [6, 11, 22, 23], "valid": [6, 22, 23], "regul": 6, "dps5005": 6, "os": [6, 7, 20], "virtual": [6, 16], "environ": [6, 16], "packag": [6, 13, 20], "thonni": [6, 12, 20], "id": [6, 20], "cut": [7, 13], "ribbon": [7, 14, 15], "proper": 7, "length": [7, 22, 23], "about": [7, 8], "5m": [7, 12], "correspond": [7, 17, 22], "crimp": [7, 22, 23], "idc": [7, 13], "suitabl": [7, 22, 23], "clamp": 7, "pai": [7, 22, 23], "attent": [7, 22, 23], "direct": [7, 20, 22, 23], "unbalanc": 7, "perpendicular": 7, "possibl": [7, 11, 17, 21, 22, 23], "same": [7, 8, 20, 22, 23], "flush": 7, "posit": [7, 13, 22, 23], "spacer": [7, 12, 14, 15], "abov": [7, 22, 23], "below": [7, 8, 10, 17, 20, 22, 23], "profil": 7, "view": [7, 12], "color": 7, "yellow": 7, "tin": [7, 13], "end": [7, 17, 22, 23], "red": [7, 12, 20, 22, 23], "black": [7, 12, 13, 22, 23], "left": [7, 12], "shown": [7, 22, 23], "pictur": 7, "i": [7, 14, 15, 20, 22, 23], "ii": 7, "gnd": [7, 22, 23], "nois": [7, 13], "often": [7, 8], "heard": 7, "clip": 7, "11": [7, 11, 12, 13, 22, 23], "input": [7, 8, 11, 12, 13, 22, 23], "right": [7, 12], "fix": [7, 12, 13], "second": [7, 8, 11, 20, 22, 23], "13": [7, 12, 13, 14, 15, 22, 23], "15": [7, 11, 12, 13, 14, 15, 22, 23], "previou": 7, "procedur": 7, "repeat": [7, 20, 22, 23], "other": [7, 17, 20, 22, 23], "17": [7, 12, 13, 22, 23], "purpl": 7, "18": [7, 12, 13, 22, 23], "third": [7, 20], "19": [7, 12, 13, 22, 23], "fourth": 7, "nylon": 7, "hex": [7, 14, 15], "photograph": 7, "detail": [7, 8, 16, 20, 22], "20": [7, 12, 13, 22, 23], "4th": 7, "togeth": [7, 17, 22, 23], "could": [7, 12, 22, 23], "previous": [7, 10, 22, 23], "21": [7, 12, 13, 22, 23], "tie": 7, "22": [7, 12, 13, 22, 23], "23": [7, 12, 13, 14, 15, 22, 23], "pvc": 7, "plate": 7, "minimum": 7, "dimens": 7, "200": [7, 11, 13], "mm": [7, 12, 14, 15, 22, 23], "150": [7, 8, 22, 23], "drill": 7, "remain": [7, 17, 22, 23], "metal": [7, 13], "tighten": 7, "25": [7, 11, 13, 14, 15, 22, 23], "rpi": [7, 10, 22, 23], "so": [7, 8, 22, 23], "access": [7, 10, 20, 22, 23], "usb": 7, "port": [7, 12, 13], "mark": [7, 12], "hole": [7, 13, 22, 23], "26": [7, 13, 22, 23], "add": [7, 19, 22, 23], "27": [7, 13, 14, 15, 22, 23], "attach": 7, "washer": 7, "nut": 7, "28": [7, 13], "29": [7, 22, 23], "come": 7, "out": [7, 10, 22, 23], "pass": [7, 20], "output": [7, 12, 13, 20, 22, 23], "pre": [7, 12], "led": [7, 13], "simpli": [7, 10, 19, 22, 23], "consid": 7, "temporari": 7, "modif": [7, 10, 22, 23], "orang": 7, "31": [7, 12, 14, 15], "brown": 7, "blue": [7, 22, 23], "block": [7, 13, 22, 23], "top": [7, 12, 17], "secur": [7, 20], "33": [7, 13], "34": [7, 13], "35": [7, 12, 13], "36": [7, 12, 22, 23], "37": [7, 22, 23], "38": [7, 13, 22, 23], "sd": [7, 10, 22, 23], "program": [7, 10, 22, 23], "mous": [7, 10, 22, 23], "keyboard": [7, 10, 22, 23], "monitor": [7, 20, 22, 23], "hdmi": [7, 10], "39": [7, 12, 13, 14, 15, 22, 23], "deliv": [7, 22, 23], "12vdc": 7, "enjoi": 7, "integr": [8, 12], "mn": [8, 21], "ab": 8, "switch": [8, 13, 17, 22, 23], "polar": [8, 13, 22, 23], "half": [8, 20], "cycl": [8, 17, 20], "stack": [8, 13, 20, 22, 23], "explan": 8, "understand": [8, 20], "redirect": 8, "reader": 8, "datasheet": 8, "done": [8, 10, 20, 22, 23], "through": [8, 13, 17, 20, 22, 23], "adc": [8, 12, 13, 21, 22, 23], "analog": [8, 12, 13, 22, 23], "convert": [8, 12, 13, 22, 23], "ads1115": [8, 12, 13, 21, 22, 23], "bit": [8, 12, 13, 22, 23], "programm": [8, 13], "gain": [8, 12, 13, 20, 22, 23], "pga": 8, "mean": [8, 17], "factor": 8, "digitis": 8, "Its": [8, 22, 23], "vari": 8, "With": [8, 22, 23], "precis": [8, 12, 13, 22, 23], "076": 8, "mv": 8, "beyond": 8, "larger": 8, "our": [8, 22, 23], "divid": [8, 22, 23], "receiv": [8, 20], "mb_2023": 8, "bridg": [8, 22, 23], "across": 8, "seri": [8, 22, 23], "instanc": [8, 10], "300": 8, "ohm": [8, 11, 12, 13, 22, 23], "anoth": [8, 10, 21, 22, 23], "techniqu": 8, "consist": [8, 21, 22, 23], "opamp": 8, "amplifi": [8, 12, 13, 22, 23], "multipl": [8, 10, 20], "known": [8, 10, 22, 23], "down": [8, 22, 23], "addit": [8, 20, 22, 23], "mode": 8, "ensur": [8, 10, 22, 23], "high": [8, 13, 22, 23], "imped": [8, 11, 22, 23], "inde": [8, 22, 23], "leak": 8, "while": [8, 17], "affect": 8, "mb_2024": 8, "differenti": 8, "model": [8, 10, 12, 13, 22, 23], "float": 8, "ground": [8, 12, 21, 22, 23], "enabl": [8, 9, 17, 20, 22, 23], "much": 8, "higher": [8, 12, 17, 23], "too": 8, "larg": 8, "usual": 8, "accur": [8, 22, 23], "shunt": [8, 11, 12, 13, 21], "As": [8, 22, 23], "tini": 8, "being": [8, 22, 23], "ina282": [8, 12], "via": [8, 10, 17, 21, 22, 23], "click": [8, 10, 13, 21, 22, 23], "ina": 8, "equival": [8, 12, 22, 23], "alreadi": 8, "solder": [8, 12, 13, 22, 23], "off": 8, "revers": [8, 22, 23], "four": [8, 12, 13], "optic": [8, 12, 21], "transit": 8, "mcp2308": 8, "gpi": 8, "sda": [8, 21], "scl": [8, 21], "protocol": [8, 17, 20, 21, 22, 23], "send": 8, "clock": 8, "transmit": 8, "pull": [8, 21], "rest": [8, 21], "5v": [8, 12, 13, 21, 22, 23], "thei": [8, 20, 21, 22, 23], "entri": 8, "becaus": 8, "mani": 8, "bu": 8, "tcaxxxx": 8, "itself": [8, 20], "rapsberrypi": 8, "now": [9, 22, 23], "actual": [9, 17, 22, 23], "henc": 9, "maximum": [9, 20, 22, 23], "aliment": 9, "modbu": 9, "quantiti": [10, 13, 22, 23], "micro": [10, 22, 23], "comput": [10, 22, 23], "instruct": [10, 20], "well": [10, 20, 22, 23], "websit": [10, 22, 23], "watch": [10, 22, 23], "video": [10, 22, 23], "how": [10, 16, 22, 23], "set": [10, 12, 13, 20, 22, 23], "latest": [10, 11, 22, 23], "stabl": [10, 17, 22, 23], "complet": [10, 12, 17, 19], "raspbian": [10, 22, 23], "visit": 10, "http": [10, 12, 13, 14, 15, 20, 22, 23], "org": 10, "en": [10, 13], "were": [10, 12, 22, 23], "onc": [10, 17, 20, 21, 22, 23], "spi": [10, 22, 23], "remot": [10, 20, 22, 23], "option": [10, 11, 13, 20, 22, 23], "deactiv": [10, 19, 22, 23], "gui": [10, 22, 23], "menu": [10, 22, 23], "failur": [10, 22, 23], "carri": [10, 22, 23], "task": [10, 22, 23], "caus": [10, 21, 22, 23], "shield": [10, 22, 23], "dure": [10, 17, 22, 23], "parallel": 10, "interpret": [10, 12, 22, 23], "discret": 10, "util": 10, "protect": 10, "problem": 10, "depend": [10, 19, 20, 22, 23], "specifi": [10, 19, 22, 23], "txt": [10, 19, 20, 22, 23], "libatla": [10, 22, 23], "dev": [10, 22, 23], "librari": [10, 22, 23], "sudo": [10, 22, 23], "apt": [10, 22, 23], "strongli": [10, 22, 23], "gather": [10, 22, 23], "python3": [10, 22, 23], "venv": [10, 22, 23], "command": [10, 19, 20, 22, 23], "bin": [10, 19, 22, 23], "suffici": [10, 22, 23], "meet": [10, 22, 23], "export": [10, 19], "cflag": 10, "fcommon": 10, "pip": [10, 19, 22, 23], "blinka": [10, 22, 23], "numpi": [10, 20, 22, 23], "panda": [10, 22, 23], "circuitpython": [10, 22, 23], "ads1x15": [10, 22, 23], "mcp230xx": 10, "gpiozero": 10, "check": [10, 11, 19, 20, 21, 22, 23], "met": [10, 19, 22, 23], "list": [10, 17, 19], "leav": [10, 19, 22, 23], "decid": [10, 22, 23], "setup": [10, 22, 23], "pythonid": [10, 22, 23], "root": [10, 22, 23], "usr": [10, 22, 23], "window": [10, 20, 22, 23], "On": [10, 17, 22, 23], "altern": [10, 22, 23], "button": [10, 22, 23], "locat": [10, 22, 23], "execut": [10, 20, 22, 23], "find": [10, 22, 23], "folder": [10, 19, 22, 23], "home": [10, 19, 20, 22, 23], "tab": [10, 20, 22, 23], "close": [10, 21, 22, 23], "ok": [10, 22, 23], "save": [10, 22, 23], "year": 11, "consequ": [11, 22, 23], "group": 11, "varieti": 11, "tailor": [11, 20], "technic": 11, "field": [11, 22, 23], "budget": 11, "characterist": [11, 22, 23], "tabl": [11, 23], "paramet": [11, 20], "unit": [11, 12, 13, 14, 15, 22, 23], "vmn": [11, 13], "number": [11, 12, 14, 15, 20, 22, 23], "temperatur": [11, 22, 23], "max": [11, 12, 13], "permiss": 11, "vab": [11, 13], "40": [11, 14, 15, 22, 23], "ma": [11, 12, 22, 23], "500": [11, 22, 23], "min": [11, 22, 23], "durat": [11, 22, 23], "ms": [11, 22, 23], "80": 11, "mohm": [11, 12, 22, 23], "tohm": 11, "volt": 11, "descript": 17, "per": [12, 13, 14, 15, 22, 23], "total": [12, 13, 14, 15, 22, 23], "web": [12, 13, 14, 15, 16, 17], "58": [12, 22, 23], "75": 12, "www": [12, 13, 14, 15, 22, 23], "mouser": [12, 13, 14, 15], "fr": [12, 13, 14, 15, 22, 23], "productdetail": [12, 13, 14, 15], "seeed": 12, "studio": 12, "102110421": 12, "qs": [12, 13, 14, 15], "7mvldsj5uaxen3lyyh3sqw": 12, "3d": [12, 13, 14, 15], "lm158n": 12, "amp": [12, 13, 22, 23], "o": [12, 14, 15, 22, 23], "texa": [12, 22, 23], "instrument": [12, 16, 17, 19, 20, 22, 23], "lm358an": [12, 22, 23], "nopb": [12, 22, 23], "lm158j": 12, "x1j7hmvl2zh8vpefml8": 12, "2ffq": 12, "print": [12, 14, 15, 20, 22, 23], "circuit": [12, 14, 15, 20, 22, 23], "asler": [12, 14, 15, 22, 23], "1085": [12, 13], "2fha2pyfaduh": 12, "2fogzutwiq9iz5vjaqfoyugqalgxpeckigrqvf4hn": 12, "252bg": 12, "capacitor": [12, 13, 23], "100nf": [12, 13, 23], "50vdc": [12, 23], "ceram": [12, 13, 23], "kemet": [12, 23], "c320c104k1": [12, 23], "c320c104k1r5ta7303": 12, "c4uyot": 12, "2flq1th4mcyoetma": 12, "5w": [12, 22, 23], "te": [12, 13, 14, 15, 22, 23], "h81k0bya": [12, 22, 23], "holsworthi": [12, 13], "2fha2pyfaduhuylh7az": 12, "2fmjfh2xjoums6wztux4som": 12, "252bii": 12, "h81k5bya": [12, 22, 23], "2fha2pyfadugy9twham3ru9hmijohywhbin95knm": 12, "252bx": 12, "2fm": 12, "vishai": [12, 13, 14, 15], "ccf071k50gke36": 12, "dale": 12, "qkeozdl6eqpa6lzrlqfvow": 12, "762": 12, "524": 12, "cmf651m0000fkek143": 12, "ciayqk2gdckzia2levalkg": 12, "42": [12, 13], "ohmit": [12, 13], "41f2r0e": 12, "im6toxqzgoauedprb19mha": 12, "08": [12, 14, 15], "pitch": [12, 13, 14, 15, 22, 23], "648": [12, 14, 15, 22, 23], "cui": [12, 14, 15], "tb009": [12, 14, 15], "508": [12, 14, 15], "02be": [12, 14, 15], "vlwxofp3u2wcfk5uckwtka": [12, 14, 15], "dc": [12, 13, 14, 15, 22, 23], "24v": [12, 23], "tracopow": [12, 23], "trn": [12, 23], "1215": [12, 23], "traco": [12, 13, 23], "yca": 12, "2faaymw02gquicgqj0ta": 12, "72": [12, 23], "mill": [12, 13], "110": [12, 13, 15, 22, 23], "43": [12, 13, 22, 23], "308": [12, 13], "41": [12, 13, 15], "001000": [12, 13], "iggadovctstu": 12, "2fqaur8narg": 12, "mgh": 12, "vip": 12, "gclid": 12, "eaiaiqobchmin_taxbcx8wivq5nvch2qaqfpeayyccabegjk1_d_bw": 12, "aqy211eh": 12, "84": [12, 14, 15], "panason": [12, 13], "industri": 12, "wktuvitrialgiu8hcm7dvq": 12, "449": 12, "796": 12, "preci": [12, 15], "83": 12, "304": 12, "001101": [12, 15], "2fha2pyfadujqkqx4wauig": 12, "2fmgndxmcnv": 12, "2f33nj0gbxroculucynpyong": 12, "mcp23008": [12, 13], "593": [12, 13], "sgaepimzzmskedp9slc0yyv4kpdpmd1hts4slctivmw": 12, "1x10": [12, 22, 23], "samtec": [12, 13, 22, 23], "ssw": [12, 13, 22, 23], "ru5fayqh": [12, 13], "252be0w1orxzibqpw": [12, 13], "smt": 12, "breakout": [12, 13], "soic": 12, "1212": 12, "gurawfaegucaqqfvnvtyeg": 12, "eaiaiqobchmit8zjzr6x8wivgdnvch2vbwvseaqyayabegjqg_d_bw": 12, "ina282aid": 12, "ze4": 12, "2fufuz19ilfayzxocfra": 12, "thd": [12, 13], "1211n": [12, 13], "2fha2pyfadugpyeg4idvm": 12, "2fmsr": 12, "252b7an": 12, "2f0t3ruis9pcaqjlt4": 12, "252bnrpuooeq": 12, "53": [12, 13, 23], "ssq": 12, "120": [12, 14, 15], "d": [12, 22, 23], "252be1bmvd": 12, "252bdzonqg": 12, "ejector": [12, 14, 15], "blk": [12, 14, 15], "10120550": [12, 14, 15], "conrad": [12, 14, 15], "com": [12, 13, 14, 15, 20, 22, 23], "bkl": [12, 14, 15], "space": [12, 14, 15], "254": [12, 14, 15], "row": [12, 13, 14, 15], "pc": [12, 14, 15], "741435": [12, 15], "searchterm": [12, 14, 15], "searchtyp": [12, 14, 15], "searchsuggest": [12, 14, 15], "femal": [12, 13, 14, 15, 22, 23], "hexagonal": 12, "87": [12, 13, 15], "48": [12, 13, 22, 23], "harwin": 12, "r25": 12, "3002002": 12, "w0yvoo0ixfenuv0hsdc4": 12, "2fq": 12, "86": [12, 13, 14, 15], "437": [12, 13], "1108331841001101": 12, "318": [12, 13], "ftmup6kvi2tnqoeziaq": 12, "2fpa": 12, "figur": [12, 22, 23], "show": [12, 22, 23], "schemat": [12, 23], "plug": [12, 22, 23], "plai": 12, "propos": [12, 22, 23], "florsch": [12, 22, 23], "advantag": 12, "signal": [12, 13, 22, 23], "lie": [12, 22, 23], "114": [12, 22, 23], "directli": [12, 17, 22, 23], "realiz": 12, "around": 12, "tdh15": 12, "inpout": 12, "than": [12, 22, 23], "just": [12, 23], "decreas": 12, "don": [12, 20], "t": [12, 13, 14, 15, 20, 21], "forget": [12, 20], "kei": 12, "r_shunt": 12, "ohmpi_config": 12, "dict": 12, "adjust": [12, 22, 23], "tow": 12, "dot": 12, "corner": 12, "lm158": 12, "ads115": [12, 22, 23], "3x11": 12, "wurth": [12, 13], "elektronik": [12, 13], "971110321": 12, "305": [12, 14, 15], "apm": [12, 14, 15], "hexseal": [12, 14, 15], "rm3x8mm": [12, 14, 15], "2701": [12, 14, 15], "jjse": [12, 14, 15], "2f12mkns3vxsdryxuhw": [12, 14, 15], "shutdown": 12, "unplug": 12, "bottom": [12, 22, 23], "11mm": 12, "m3": [12, 14, 15], "upper": 12, "everyth": 12, "screen": [12, 22, 23], "1kohm": 12, "r2": [12, 22, 23], "220": 12, "r1": [12, 22, 23], "padboard": 12, "spool": 12, "sample_measurement_exampl": 12, "result": [12, 22, 23], "2023": 13, "offer": [13, 20, 22, 23], "superior": 13, "compar": 13, "predecessor": 13, "evolv": [13, 17, 22, 23], "major": 13, "mikro": 13, "1887": [], "isol": 13, "200v": 13, "bom": [], "140": [14, 15], "560": [14, 15], "62": [14, 15], "92": [14, 15, 22, 23], "tru": [14, 15, 22, 23], "1580994": [14, 15], "256": [14, 15], "091": [14, 15], "296": [14, 15], "incorpor": [13, 14, 15, 17, 20], "sgaepimzzmueqxo7l": [14, 15], "2fbpyakboruumren": [14, 15], "56": [14, 15], "776": [14, 15], "205": [14, 15], "46": [13, 14, 15], "103321": [14, 15], "5twgzeq9e7hsylqaljjyrw": [14, 15], "732": [14, 15], "sgaepimzzmskedp9slc0yfx16nydmpxjueeogolbldi": [14, 15], "325": [14, 15], "over": [14, 15, 21], "503811": [14, 15], "nchannel": [14, 15], "471": [14, 15], "576": [14, 15, 22], "vhuuswq2": [14, 15], "252bsz9b": [14, 15], "2ff6fcxt7g": [14, 15], "100k": [14, 21], "061": [14, 15], "616": [14, 15], "beyschlag": [13, 14, 15], "mba02040c1003frp00": [13, 14, 15], "mzrxyrlhvdt9crf7zyf": [13, 14, 15], "2f5q": [13, 14, 15], "89": [13, 14, 15], "2717": [14, 15], "sgaepimzzmsyydr3r27av4eqf73yoh": [14, 15], "252baqg": [14, 15], "252bz3hvktao": [14, 15], "10120558": [14, 15], "54": [14, 15], "No": [14, 15], "51": [14, 15], "741727": [14, 15], "10120862": [14, 15], "strain": [14, 15], "relief": [14, 15], "44": [13, 14, 15, 22, 23], "742063": [14, 15], "10120158": [14, 15], "x": [14, 15, 22, 23], "multi": [14, 15, 22, 23], "colour": [14, 15], "1012015810": [14, 15], "127": [14, 15], "008": [14, 15], "1548658": [14, 15], "79": [14, 15], "49": [14, 15], "keyston": [14, 15], "24300": [14, 15], "uwqyq": [14, 15], "2f2czwu0ejpozmzc2a": [14, 15], "745": [14, 15], "846": [14, 15], "614": [14, 15], "25515": [14, 15], "2f2czwuxuhumfr": [14, 15], "252bzuq": [14, 15], "updat": [15, 17, 20], "100k\u03c9": 15, "mm\u00b2": [15, 22, 23], "55": [15, 22, 23], "328": 15, "uqd7xcvsscnr3hwd6fta8g": 15, "whose": [22, 23], "main": [17, 22, 23], "summar": [], "cover": [], "acquisit": [16, 20], "separ": 20, "json": [20, 23], "ohmpi_set": [], "central": [], "handler": 20, "layer": [], "excel": 20, "log": [17, 20], "broker": [19, 20], "zip": 20, "rotat": 20, "disk": 20, "exec_logg": 20, "data_logg": 20, "plan": 20, "state": 20, "health": 20, "soh": 20, "futur": 20, "By": 20, "written": [17, 20], "consol": 20, "like": [20, 21], "local": [19, 20], "dai": 20, "size": [13, 20], "exce": 20, "sent": 20, "level": [13, 17, 20], "edit": [19, 20], "setup_logg": 20, "custom": 20, "repositori": [20, 22, 23], "prefer": [20, 22, 23], "desir": [17, 20], "usernam": [19, 20], "password": 20, "One": [20, 21], "alter": 20, "keep": [17, 20], "bash": 20, "run_http_interfac": 20, "sh": [19, 20], "iot": [17, 20], "messag": [17, 20], "friendli": 20, "graphic": 20, "quick": 20, "easi": 20, "wi": 20, "fi": 20, "point": [20, 22, 23], "ap": 20, "webserv": 20, "serv": [20, 22, 23], "index": 20, "html": 20, "laptop": 20, "mobil": 20, "phone": 20, "upload": 20, "sequenc": [17, 20, 22, 23], "download": [20, 22, 23], "act": 20, "raspap": 20, "runonstart": 20, "141": 20, "8080": 20, "pseudo": 20, "evolut": 20, "quadrupol": [20, 22, 23], "appar": 20, "especi": 20, "suit": 20, "autom": 20, "ipython": 20, "ssh": 20, "putti": 20, "maco": 20, "linux": 20, "found": 20, "gitlab": [20, 22, 23], "entir": [20, 22, 23], "np": 20, "chdir": 20, "object": [17, 20], "k": [13, 20], "load": 20, "manual": [20, 22, 23], "injection_dur": [20, 22, 23], "nb_stack": 20, "nbr_mea": [20, 22, 23], "update_set": 20, "arrai": [13, 20, 22, 23], "shape": 20, "set_sequ": 20, "n2": 20, "string": 20, "load_sequ": 20, "abmn": [20, 22, 23], "rs_check": 20, "synchron": [17, 20], "wait": 20, "return": [20, 22, 23], "prompt": 20, "run_sequ": 20, "run_sequence_async": 20, "thread": [17, 20], "immedi": 20, "sleep": 20, "interrupt": 20, "kill": 20, "asynchron": 20, "interv": 20, "nb_mea": 20, "sequence_delai": [20, 22, 23], "run_multiple_sequ": 20, "taken": 20, "switch_mux_on": 20, "run_measur": 20, "switch_mux_off": 20, "risk": 20, "short": 20, "argument": 20, "autogain": 20, "true": 20, "ad": [20, 22, 23], "good": 20, "resolut": [20, 22, 23], "usag": 20, "consumpt": [20, 22, 23], "process": 20, "sensor": [13, 20], "scope": 20, "internet": 20, "network": 20, "auxiliari": 20, "publish": [20, 22], "subscrib": 20, "approach": 20, "mosquitto": 20, "server": 20, "reachabl": 20, "net": [13, 20], "servic": 20, "install_local_mqtt_brok": 20, "examin": 20, "parti": 20, "explor": 20, "reboot": 20, "further": 20, "format": 20, "kwarg": 20, "illustr": [20, 22, 23], "cmd_id": 20, "3fzxv121uitwgjwygcz4xw": 20, "cmd": 20, "nb_electrod": [20, 22, 23], "3fzxv121uitwgjwygcz4yw": 20, "made": [20, 22, 23], "dashboard": 20, "browser": 20, "flow": [20, 22, 23], "editor": [20, 22, 23], "node": 20, "complex": 20, "properli": [19, 20, 21], "palett": 20, "manag": [13, 20, 22, 23], "noder": [], "doc": [], "guid": [], "ui": 20, "visual": 20, "cookbook": 20, "due": 21, "quit": 21, "fragil": 21, "still": [21, 22, 23], "conductor": 21, "turn": [21, 22, 23], "multimet": 21, "broken": 21, "shoudn": 21, "wa": [21, 22, 23], "burn": 21, "expect": [17, 21], "try": 21, "effect": 21, "voltmet": [21, 22, 23], "sens": 21, "malfunct": 21, "erron": 21, "solv": 21, "most": 21, "vdd": 21, "reach": 21, "stronger": [21, 22, 23], "smaller": [21, 22, 23], "journal": 22, "bug": 22, "explain": 22, "miss": 22, "invit": 22, "v1": [22, 23], "commerci": [22, 23], "cpu": [22, 23], "w": [13, 22, 23], "storag": [22, 23], "o1": [22, 23], "youtub": [22, 23], "wjwzhv1v3pk": [22, 23], "noob": [22, 23], "simpl": [17, 22, 23], "unexpectedli": [22, 23], "boot": [22, 23], "cd": [19, 22, 23], "gnu": [22, 23], "nano": [19, 22, 23], "At": [22, 23], "op": [13, 22, 23], "dl": [22, 23], "press": [22, 23], "enter": [22, 23], "escap": [22, 23], "studi": [22, 23], "hous": [13, 22, 23], "diagram": [22, 23], "displai": [22, 23], "mimic": [22, 23], "behavior": [22, 23], "soil": [22, 23], "subject": [22, 23], "r11": [22, 23], "r10": [22, 23], "r12": [22, 23], "constitut": [22, 23], "stainless": [22, 23], "steel": [22, 23], "r9": [22, 23], "less": [22, 23], "sum": [22, 23], "000": [22, 23], "intens": [22, 23], "potenti": [22, 23], "calcul": [22, 23], "insert": [22, 23], "1115": [22, 23], "a1": [22, 23], "a0": [22, 23], "increas": [17, 22, 23], "r5": [22, 23], "r8": [22, 23], "r6": [22, 23], "r7": [22, 23], "a2": [22, 23], "a3": [22, 23], "obtain": [22, 23], "ly": [22, 23], "let": [22, 23], "equal": [22, 23], "multipli": [22, 23], "reduct": [22, 23], "despit": [22, 23], "calibr": [22, 23], "variou": [13, 22, 23], "disturb": [22, 23], "estim": [22, 23], "mega": [22, 23], "shortcut": [22, 23], "excess": [22, 23], "lithium": [22, 23], "ion": [22, 23], "automobil": [22, 23], "lead": [13, 22, 23], "acid": [22, 23], "strong": [22, 23], "hazard": [22, 23], "fuse": [22, 23], "onto": [22, 23], "ohmmet": [22, 23], "coeffici": [22, 23], "coef_p0": [22, 23], "coef_p1": [22, 23], "coef_p2": [22, 23], "coef_p3": [22, 23], "coef": [22, 23], "po": [22, 23], "p1": [22, 23], "r3": [22, 23], "r4": [22, 23], "p2": [22, 23], "p3": [22, 23], "r_ref": [22, 23], "slope": [22, 23], "convers": [13, 22, 23], "p0": [22, 23], "accuraci": [22, 23], "lm358n": [22, 23], "appli": [22, 23], "weaker": 22, "tx": [22, 23], "rememb": [22, 23], "holder": [22, 23], "f": [22, 23], "circul": [22, 23], "fig": [22, 23], "common": [17, 22, 23], "neg": [22, 23], "normal": [22, 23], "simultan": [22, 23], "role": [22, 23], "thu": [22, 23], "energ": [22, 23], "next": [22, 23], "featur": [22, 23], "strict": [22, 23], "in1": [22, 23], "in2": [22, 23], "in3": [22, 23], "in4": [22, 23], "5vdc": [13, 22, 23], "5vcc": [22, 23], "mm2": [22, 23], "lastli": [22, 23], "congratul": [22, 23], "construct": [22, 23], "ert": [22, 23], "sever": [17, 22, 23], "ten": [22, 23], "thousand": [22, 23], "stuck": [22, 23], "hand": [22, 23], "cap": [22, 23], "produc": [22, 23], "clean": [22, 23], "distanc": [22, 23], "had": [22, 23], "extra": [22, 23], "final": [22, 23], "horizont": [22, 23], "vertic": [22, 23], "06": [13, 22, 23], "04": [22, 23], "05": [13, 22, 23], "din": [22, 23], "rail": [22, 23], "chosen": [22, 23], "incom": [22, 23], "instead": [22, 23], "moreov": [22, 23], "bought": [22, 23], "velleman": [22, 23], "wpm404": [22, 23], "potentiomet": [13, 22, 23], "scienc": [22, 23], "framework": [22, 23], "manuscript": [22, 23], "osf": [22, 23], "io": [22, 23], "dzwb4": [22, 23], "irstea": [22, 23], "unzip": [22, 23], "master": [22, 23], "readm": [22, 23], "assist": [22, 23], "disconnect": [22, 23], "handl": [17, 22, 23], "charg": [22, 23], "full": [17, 22, 23], "capac": [22, 23], "fewer": [22, 23], "bank": [22, 23], "2a": [22, 23], "ll": [22, 23], "insid": [22, 23], "numer": [22, 23], "optim": [22, 23], "attribut": [22, 23], "the9": [22, 23], "hear": [22, 23], "sound": [22, 23], "permut": [22, 23], "csv": [22, 23], "delai": [22, 23], "repetit": [22, 23], "littl": [22, 23], "public": [22, 23], "articl": [22, 23], "sainsmart": [22, 23], "canal": 22, "pour": 22, "arduino": 22, "dsp": [13, 22], "avr": 22, "pic": 22, "arm": 22, "99": [13, 22, 23], "199": [22, 23], "sain": [22, 23], "smart": [22, 23], "101": [22, 23], "70": [13, 22, 23], "103": [22, 23], "018": [22, 23], "1x1": [22, 23], "66": [13, 22, 23], "1568649": [22, 23], "1x0": [22, 23], "71": [13, 22, 23], "1565235": [22, 23], "68": [22, 23], "rs": [22, 23], "pro": [13, 22, 23], "897": [22, 23], "1332": [22, 23], "858": [22, 23], "627": [22, 23], "52": [13, 22, 23], "upw50b50rv": [22, 23], "1083": [22, 23], "7ah": [22, 23], "537": [22, 23], "5488": [22, 23], "lr20": [22, 23], "9v": [22, 23], "185": [22, 23], "4686": [22, 23], "ferrul": [22, 23], "piec": [22, 23], "weidmul": [22, 23], "9004330000": [22, 23], "966067": [22, 23], "car": 22, "littelfus": [22, 23], "fhac0002zxj": 22, "96": [13, 22], "trn3": 23, "suppress": 23, "10v": 23, "fast": 23, "decoupl": 23, "last": 23, "prevent": 23, "overh": 23, "toler": 23, "orient": [17, 23], "h": [13, 23], "nf": 23, "jason": 23, "ohmpi_param": 23, "export_path": 23, "desktop": 23, "0251001": 23, "pat1l": 23, "2c": 13, "ref": 13, "link": 13, "eur": 13, "excl": 13, "vat": 13, "223": 13, "594": 13, "5063jd100k0ft": 13, "film": 13, "4watt": 13, "100kohm": 13, "8watt": 13, "bodi": 13, "eu": 13, "899": 13, "330": 13, "307": 13, "279": 13, "cfr100j330r": 13, "carbon": 13, "330ohm": 13, "1w": 13, "500ppm": 13, "ddevmfoh4ssvknglsgy0ha": 13, "228": 13, "603": 13, "cfr": 13, "25jb": 13, "4k7": 13, "yageo": 13, "4w": 13, "7k": 13, "588": 13, "wnc2r0fet": 13, "wirewound": 13, "2w": 13, "cdpnwznfzjb5bmolbzti": 13, "252bw": 13, "50v": 13, "1a": 13, "rectifi": 13, "214": 13, "637": 13, "1n4001": 13, "diotec": 13, "semiconductor": 13, "olc7aqgiedlll8na510wma": 13, "284": 13, "cree": 13, "941": 13, "c503bgancd0e0781": 13, "c503b": 13, "gan": 13, "cd0e0781": 13, "standard": 13, "green": 13, "527nm": 13, "mmround": 13, "32900": 13, "64600mcd": 13, "7d1ltpjg0i1j7dm": 13, "252b": 13, "252b5igzw": 13, "116": 13, "schottki": 13, "771": 13, "bat86113": 13, "bat86": 13, "113": 13, "nexperia": 13, "sod68": 13, "me8tqzrmiyx1ahcmzsx1tg": 13, "874": 13, "op27": 13, "ultra": 13, "offset": 13, "8dip": 13, "584": 13, "op27epz": 13, "inc": 13, "wivqp4zgangdp3uwih2ura": 13, "485": 13, "accessori": 13, "gurawfaeguaf08zux7w": 13, "2fuq": 13, "78": 13, "pack": 13, "ic": 13, "amazon": 13, "azdeliveri": 13, "parent": 13, "3x": 13, "dp": 13, "b07qhwltt": 13, "sr_1_5": 13, "__mk_fr_fr": 13, "c3": 13, "85m": 13, "85": 13, "c5": 13, "bd": 13, "95": 13, "91": 13, "crid": 13, "18whxz3e0nur5": 13, "keyword": 13, "qid": 13, "1702140215": 13, "sprefix": 13, "2cap": 13, "2c117": 13, "sr": 13, "ref03gpz": 13, "r": 13, "wivqp4zgangjpdfouwu1bw": 13, "dg411dj": 13, "781": 13, "e3": 13, "speed": 13, "dg411": 13, "xkjjivogybzznzq": 13, "252buwcw1q": 13, "unpolar": 13, "k104k15x7rf5ul2": 13, "multilay": 13, "mlcc": 13, "x7r": 13, "ammo": 13, "bc": 13, "rlgk8caobhbcqsnkgo2hja": 13, "568": 13, "10uf": 13, "667": 13, "eeu": 13, "eb1j100": 13, "aluminum": 13, "electrolyt": 13, "radial": 13, "63volt": 13, "aec": 13, "q200": 13, "ceafgkervibcbemsghcq5g": 13, "60v": 13, "600ma": 13, "700mw": 13, "transistor": 13, "zvn4206astz": 13, "335": 13, "522": 13, "chnl": 13, "onsemi": 13, "fairchild": 13, "2n7000bu": 13, "k2x4el1": 13, "2fkj6oexmhafsm5a": 13, "thd1512": 13, "11n": 13, "495": 13, "thd15": 13, "style": 13, "ckjk83fod0x2iyoeopcnmg": 13, "97": 13, "22n": 13, "1222n": 13, "ckjk83fod0uvycxqxchqfw": 13, "848": 13, "649": 13, "vi02215200j0g": 13, "vi0221520000g": 13, "amphenol": 13, "tb": 13, "ri": 13, "cla": 13, "180": 13, "anytek": 13, "mv7bduzupui3lmtbyxcxvw": 13, "088": 13, "74": 13, "932": 13, "1878": 13, "k5owtxstjao5l2rhk53deg": 13, "4976": 13, "mynhzdoqoqkab6t4ih2naq": 13, "serial": 13, "eeprom": 13, "2kb": 13, "dip8": 13, "03": 13, "474": 13, "bob": 13, "15439": 13, "sparkfun": 13, "translat": 13, "pca9306": 13, "p1jmdcb91o4xonpr": 13, "252b0xi4g": 13, "omhron": 13, "653": 13, "1a4": 13, "dc5": 13, "spst": 13, "NO": 13, "seal": 13, "pwf36butxbgftk6ytlb7nq": 13, "575": 13, "1104731841001000": 13, "47": 13, "standrd": 13, "tail": 13, "5ag0nvq1c4xxooytdz6dow": 13, "113308": 13, "8p": 13, "gld": 13, "cont": 13, "wzeyyeqmoweyjis4txlt7q": 13, "11044316": 13, "316": 13, "16p": 13, "iggadovctsrh": 13, "252bxewrwehkg": 13, "prt": 13, "14017": 13, "tall": 13, "2x20": 13, "a4bxicggsn": 13, "2f": 13, "252baml822b65a": 13, "ribon": 13, "710": 13, "61200623021": 13, "wr": 13, "bhd": 13, "54mm": 13, "6p": 13, "strt": 13, "conn": 13, "phr8rmcireabk1ywkdxzfw": 13, "571": 13, "534237": 13, "rec": 13, "1x05p": 13, "vrt": 13, "eln3i3szm1klmlr": 13, "252bszcsuq": 13, "94": 13, "1x04p": 13, "gygf5pdsjzki3hk2o1eilq": 13, "535541": 13, "1x08p": 13, "xdp7pgunc": 13, "252buqvwkjjvkwqw": 13, "ssw11002g": 13, "tiger": 13, "bui": 13, "ssw10202g": 13, "102": 13, "252be2zeimtlw": 13, "2fblw": 13, "826629": 13, "10p": 13, "fazuumncxom0apli6zggxg": 13, "1761681": 13, "hdr": 13, "vert": 13, "ht": 13, "bqfptycq3dlaez2wzdz7aw": 13, "aisler": 13, "lang": 13, "10k": 13, "sip9": 13, "bournd": 13, "3296w_vertic": 13, "raspberryp": 13, "63": 13, "kiwi": 13, "4gb": 13, "4268": 13, "src": 13, "73": 13, "801": 13, "012": 13, "012000": 13, "5ag0nvq1c4x40xnvdlnkzg": 13, "overview": 13, "machin": 13, "thirteen": 13, "eepow": [], "fundament": [], "what": [], "_": [], "clone": 16, "mqtt": [16, 17, 19], "re": 17, "structur": 17, "organis": 17, "hierarchi": 17, "five": 17, "distinct": 17, "atom": 17, "Theses": 17, "concret": 17, "properti": 17, "capabl": 17, "physic": 17, "mainli": 17, "occur": 17, "medium": 17, "ohmpihardwar": 17, "orchestr": 17, "cross": 17, "squar": 17, "wave": 17, "waveform": 17, "read": 17, "insur": 17, "whole": 17, "dynam": 17, "instanti": 17, "rel": 17, "customis": 17, "overal": 17, "radic": 17, "acquir": 17, "navig": 19, "dependeci": 19, "centralis": 19, "buse": 19, "pythonpath": 19, "bashrc": 19, "And": 19, "basic_ohmpi_flows_nod": 20}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"ohmpi": [0, 1, 7, 8, 19, 22, 23], "open": 0, "sourc": 0, "hardwar": [0, 4, 6, 17], "resist": [0, 22, 23], "meter": 0, "summari": 0, "document": 0, "center": 0, "project": [1, 19], "author": 1, "partner": 1, "cite": 1, "introduct": 1, "step": 19, "n": [], "3": 19, "mux": [14, 15], "board": [8, 11, 12, 13, 14, 15, 22, 23], "part": [10, 12, 13, 14, 15], "A": [10, 12, 13, 14, 15, 21], "assembl": [7, 11, 12, 13, 14, 15, 22, 23], "requir": [12, 13, 14, 15], "compon": [4, 12, 13, 14, 15, 17, 21, 22, 23], "b": [10, 12, 14, 15, 21, 22, 23], "address": [14, 15], "c": [10, 12, 14, 15], "valid": [14, 15], "api": 2, "refer": 2, "archiv": 3, "version": [3, 11], "softwar": [4, 16, 17], "interfac": [4, 20], "new": 4, "exampl": 5, "applic": [5, 20], "electron": 8, "design": 8, "measur": [8, 11, 12, 13, 22, 23], "multiplex": [8, 22, 23], "power": 9, "suppli": 9, "12v": 9, "batteri": 9, "regul": 9, "dps5005": 9, "raspberri": [10, 19, 22, 23], "pi": [10, 19, 22, 23], "configur": [10, 20, 22, 23], "os": [10, 22, 23], "instal": [10, 19, 22, 23], "virtual": [10, 19, 22, 23], "environ": [10, 19, 22, 23], "packag": [10, 22, 23], "activ": [10, 19, 22, 23], "thonni": [10, 22, 23], "python": [10, 20, 22, 23], "id": [10, 22, 23], "recogn": 11, "specif": 11, "you": 11, "v2023": [12, 14], "list": [12, 13, 14, 15, 22, 23], "descript": [12, 13, 22, 23], "start": 12, "up": 12, "check": 12, "2024": 13, "0": 13, "2": [13, 19], "v2024": 15, "oper": [16, 22, 23], "system": 17, "architectur": 17, "logger": 20, "file": 20, "web": 20, "mqtt": 20, "troubleshoot": 21, "issu": 21, "puls": 21, "between": 21, "valu": 21, "given": 21, "correct": 21, "one": 21, "commun": 21, "v": [22, 23], "1": [19, 22, 23], "01": 22, "limit": [22, 23], "32": [22, 23], "electrod": [22, 23], "The": [22, 23], "philosophi": [22, 23], "technic": [22, 23], "data": [22, 23], "current": [22, 23], "inject": [22, 23], "card": [22, 23], "connect": [19, 22, 23], "electr": [22, 23], "implement": [22, 23], "first": [22, 23], "four": [22, 23], "instruct": [22, 23], "preliminari": [22, 23], "procedur": [22, 23], "onli": [22, 23], "initi": [22, 23], "startup": [22, 23], "paramet": [22, 23], "complet": [22, 23], "tabl": 22, "titl": 22, "02": 23, "schemat": 13, "interact": 13, "bom": 13, "acquisit": 17, "clone": 19, "run": 19, "script": 19, "4": 19}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 56}}) \ No newline at end of file diff --git a/doc/build/html/source_rst/api.html b/doc/build/html/source_rst/api.html index 4f3f7d33..2f6e29fc 100644 --- a/doc/build/html/source_rst/api.html +++ b/doc/build/html/source_rst/api.html @@ -20,7 +20,7 @@ <link rel="index" title="Index" href="../genindex.html" /> <link rel="search" title="Search" href="../search.html" /> <link rel="next" title="Troubleshooting" href="troubleshooting.html" /> - <link rel="prev" title="Software and operation" href="software.html" /> + <link rel="prev" title="<no title>" href="software/developments.html" /> </head> <body class="wy-body-for-nav"> @@ -89,7 +89,7 @@ </div> </div> <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> - <a href="software.html" class="btn btn-neutral float-left" title="Software and operation" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> + <a href="software/developments.html" class="btn btn-neutral float-left" title="<no title>" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> <a href="troubleshooting.html" class="btn btn-neutral float-right" title="Troubleshooting" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> </div> diff --git a/doc/build/html/source_rst/developing_hardware_components.html b/doc/build/html/source_rst/developing_hardware_components.html index 30ef0b8c..2bd79c1b 100644 --- a/doc/build/html/source_rst/developing_hardware_components.html +++ b/doc/build/html/source_rst/developing_hardware_components.html @@ -79,8 +79,8 @@ <section id="software-interface-to-new-hardware-components"> <h1>Software interface to new hardware components<a class="headerlink" href="#software-interface-to-new-hardware-components" title="Permalink to this heading">ïƒ</a></h1> -<p><a href="#id1"><span class="problematic" id="id2">**</span></a>* DRAFT VERSION - TO BE REVIEWED * -This section is intended for developers of a new hardware component as part of an OhmPi system.</p> +<p><strong>* DRAFT VERSION - TO BE REVIEWED *</strong></p> +<p>This section is intended for developers of a new hardware component as part of an OhmPi system.</p> <p>It presents some advices and best practices that should help developing new hardware components to work within an OhmPi system.</p> <p>OhmPi is an open source system and contributions in terms of hardware and software are welcome. However, in order to diff --git a/doc/build/html/source_rst/hardware/mb/mb_2024.html b/doc/build/html/source_rst/hardware/mb/mb_2024.html index 8528e183..8e2e956e 100644 --- a/doc/build/html/source_rst/hardware/mb/mb_2024.html +++ b/doc/build/html/source_rst/hardware/mb/mb_2024.html @@ -618,6 +618,10 @@ it provides electrical isolation for the Vmn measurement set. This isolation all </tr> <tr class="row-even"><td><p>Installation of female header, 1 by 10 pins, for ADS1115</p></td> </tr> +</tbody> +</table> +<table class="docutils align-default"> +<tbody> <tr class="row-odd"><td rowspan="2"><p>5</p></td> <td><img alt="../../../_images/5.jpg" src="../../../_images/5.jpg" /> </td> diff --git a/doc/build/html/source_rst/software.html b/doc/build/html/source_rst/software.html index 0a8b32b2..d4a588f8 100644 --- a/doc/build/html/source_rst/software.html +++ b/doc/build/html/source_rst/software.html @@ -19,7 +19,7 @@ <script src="../_static/js/theme.js"></script> <link rel="index" title="Index" href="../genindex.html" /> <link rel="search" title="Search" href="../search.html" /> - <link rel="next" title="API reference" href="api.html" /> + <link rel="next" title="Software architecture" href="software/architecture.html" /> <link rel="prev" title="Assembling the OhmPi" href="hardware/assembling.html" /> </head> @@ -46,15 +46,10 @@ <li class="toctree-l1"><a class="reference internal" href="Ohmpi.html">OhmPi project</a></li> <li class="toctree-l1"><a class="reference internal" href="hardware.html">Hardware</a></li> <li class="toctree-l1 current"><a class="current reference internal" href="#">Software and operation</a><ul> -<li class="toctree-l2"><a class="reference internal" href="#system-architecture">System architecture</a></li> -<li class="toctree-l2"><a class="reference internal" href="#loggers">Loggers</a></li> -<li class="toctree-l2"><a class="reference internal" href="#configuration-file">Configuration file</a></li> -<li class="toctree-l2"><a class="reference internal" href="#interfaces-and-applications">Interfaces and applications</a><ul> -<li class="toctree-l3"><a class="reference internal" href="#web-interface">Web interface</a></li> -<li class="toctree-l3"><a class="reference internal" href="#python-interface">Python interface</a></li> -<li class="toctree-l3"><a class="reference internal" href="#mqtt-interface">MQTT interface</a></li> -</ul> -</li> +<li class="toctree-l2"><a class="reference internal" href="software/architecture.html">Software architecture</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/installation.html">Installation</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/operations.html">Configuration file</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/operations.html#interfaces-and-applications">Interfaces and applications</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="api.html">API reference</a></li> @@ -94,225 +89,34 @@ <p class="admonition-title">Warning</p> <p><strong>OhmPi is a participative project open to all, it requires skills in electronics and to respect the safety rules. OhmPi must be assembled in a professional context and by people competent in electronics. The OhmPi team cannot be held responsible for any material or human damage which would be associated with the use or the assembly of OhmPi. The OhmPi team cannot be held responsible if the equipment does not work after assembly.</strong></p> </div> -<section id="system-architecture"> -<h2>System architecture<a class="headerlink" href="#system-architecture" title="Permalink to this heading">ïƒ</a></h2> -<p>The OhmPi V2023 software is designed around a new architecture whose main components are summarized in the figure below.</p> -<figure class="align-default" id="id4"> -<img alt="../_images/architecture.png" src="../_images/architecture.png" /> -<figcaption> -<p><span class="caption-text">Software architecture of OhmPi V2023.</span><a class="headerlink" href="#id4" title="Permalink to this image">ïƒ</a></p> -</figcaption> -</figure> -<p>The general system configuration is defined in the <cite>config.py</cite> file covered in the <a class="reference internal" href="#configuration-file">Configuration file</a> section. -The acquisition settings (i.e. injection duration, stacks…) are defined in a separate JSON file (default: ohmpi_settings.json).</p> -<p>The central software component is the ohmpi.py file that contains the OhmPi class that interacts with the hardware. Other python files include utils and handlers (see the <a class="reference internal" href="#loggers">Loggers</a> section for more details). -A communication layer (I/O interface) on top of OhmPi allows for different user interfaces depending on the use cases (see <a class="reference internal" href="#interfaces-and-applications">Interfaces and applications</a>).</p> -</section> -<section id="loggers"> -<h2>Loggers<a class="headerlink" href="#loggers" title="Permalink to this heading">ïƒ</a></h2> -<p>Loggers have been introduced in this release. They use the excellent logging python package. -Specific handlers have been implemented for running with ohmpi.py (one for logging to an mqtt broker (see <a class="reference internal" href="#mqtt-interface">MQTT interface</a> for more details) and one for creating zipped rotated logs on disk).</p> -<p>Two loggers have been defined. The first one is dedicated to log operations execution. It is named exec_logger. The second one, named data_logger, is dedicated to log data. A third one is planned to log the state of health (SOH) of the system in a future version.</p> -<p>By default, logs are written to the console (print-like), stored locally in files (a zip is created after some time i.e. every day and/or when the size of the log exceeds a maximum size) and sent to an MQTT broker. Different logging levels may be defined for the different logs and handlers in the <a class="reference internal" href="#configuration-file">Configuration file</a>.</p> -<p>Advanced users may write new handlers and edit the <cite>setup_loggers.py</cite> file to customize the logging mechanisms to their needs.</p> -</section> -<section id="configuration-file"> -<h2>Configuration file<a class="headerlink" href="#configuration-file" title="Permalink to this heading">ïƒ</a></h2> -<p>The configuration of the OhmPi file <cite>config.py</cite> allows to configure the OhmPi. -A default version of <cite>config.py</cite> is provided in the repository. -This file should be edited to customize the configuration following the user’s needs and preferences.</p> -<p>The configuration includes setting the logging level desired for the different loggers and handlers, setting the mqtt broker(s) used for logging and control of the OhmPi and defining the options used for MQTT communication (i.e. username, password, security options…)</p> -<p>One should make sure to understand the parameters before altering them. It is also recommended to keep a copy of the default configuration.</p> -</section> -<section id="interfaces-and-applications"> -<h2>Interfaces and applications<a class="headerlink" href="#interfaces-and-applications" title="Permalink to this heading">ïƒ</a></h2> -<p>Different interfaces can be used to interact with the OhmPi.</p> -<p>Available interfaces are: -- <a class="reference internal" href="#web-interface">Web interface</a> (=HTTP interface): run in bash: <cite>bash run_http_interface.sh</cite> -- Python API: import the OhmPi class from Python script: <cite>from ohmpi import OhmPi</cite> (see <a class="reference internal" href="#python-interface">Python interface</a>) -- MQTT: IoT messaging through a broker (see <a class="reference internal" href="#mqtt-interface">MQTT interface</a>)</p> -<section id="web-interface"> -<h3>Web interface<a class="headerlink" href="#web-interface" title="Permalink to this heading">ïƒ</a></h3> -<p>This is a user friendly graphical interface for new users as well as running quick and easy acquisitions.</p> -<p>The Raspberry Pi of the OhmPi is used as a Wi-Fi Access Point (AP) and runs -a small webserver to serve the ‘index.html’ interface. Using a laptop or -a mobile phone connected to the Wi-Fi of the Raspberry Pi, one can see this -interface, upload sequences, change parameters, run a sequence and download data.</p> -<p>To configure the Raspberry Pi to act as an access point and run -the webserver automatically on start, see instructions on <a class="reference external" href="https://raspap.com/">raspap.com</a> and in ‘runOnStart.sh’.</p> -<p>Once configured, the webserver should start by itself on start and once -connected to the Pi, the user can go to <a class="reference external" href="http://10.3.141.1:8080">10.3.141.1:8080</a> -to access the interface.</p> -<figure class="align-default" id="id5"> -<img alt="../_images/http-interface-pseudo-section.png" src="../_images/http-interface-pseudo-section.png" /> -<figcaption> -<p><span class="caption-text">Web interface with its interactive pseudo-section.</span><a class="headerlink" href="#id5" title="Permalink to this image">ïƒ</a></p> -</figcaption> -</figure> -<figure class="align-default" id="id6"> -<img alt="../_images/http-interface-evolution.png" src="../_images/http-interface-evolution.png" /> -<figcaption> -<p><span class="caption-text">Evolution of quadrupole apparent resistivity with time.</span><a class="headerlink" href="#id6" title="Permalink to this image">ïƒ</a></p> -</figcaption> -</figure> -<figure class="align-default" id="id7"> -<img alt="../_images/http-interface-rs.png" src="../_images/http-interface-rs.png" /> -<figcaption> -<p><span class="caption-text">Contact resistance check.</span><a class="headerlink" href="#id7" title="Permalink to this image">ïƒ</a></p> -</figcaption> -</figure> -</section> -<section id="python-interface"> -<h3>Python interface<a class="headerlink" href="#python-interface" title="Permalink to this heading">ïƒ</a></h3> -<p>This interface offers a more direct access to the software components especially well suited for testing or automation on the Raspberry Pi.</p> -<p>By importing the <cite>OhmPi</cite> class from the ohmpi.py, one can control the OhmPi using interactive IPython. -Typically, it involves using the terminal or an Python IDE such as Thonny on the Raspberry Pi. One can also connect using -ssh and run the Python interface (see PuTTY on Windows or ssh command on macOS/Linux).</p> -<p>To access the Python API, make sure the file ohmpi.py is in the same -directory as where you run the commands/script. The file ohmpi.py can -be found on the OhmPi gitlab repository. We recommend downloading the -entire repository as ohmpi.py import other .py files and default configuration -files (.json and .py).</p> -<div class="literal-block-wrapper docutils container" id="id8"> -<div class="code-block-caption"><span class="caption-text">Example of using the Python API to control OhmPi</span><a class="headerlink" href="#id8" title="Permalink to this code">ïƒ</a></div> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span> -<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span> -<span class="kn">import</span> <span class="nn">time</span> -<span class="n">os</span><span class="o">.</span><span class="n">chdir</span><span class="p">(</span><span class="s2">"/home/pi/OhmPi"</span><span class="p">)</span> -<span class="kn">from</span> <span class="nn">ohmpi</span> <span class="kn">import</span> <span class="n">OhmPi</span> - -<span class="c1">### Define object from class OhmPi</span> -<span class="n">k</span> <span class="o">=</span> <span class="n">OhmPi</span><span class="p">()</span> <span class="c1"># this loads default parameters from the disk</span> - -<span class="c1">### Default parameters can also be edited manually</span> -<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'injection_duration'</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="c1"># injection time in seconds</span> -<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'nb_stack'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># one stack is two half-cycles</span> -<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'nbr_meas'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># number of time the sequence is repeated</span> - -<span class="c1">### Update settings if needed</span> -<span class="n">k</span><span class="o">.</span><span class="n">update_settings</span><span class="p">({</span><span class="s2">"injection_duration"</span><span class="p">:</span><span class="mf">0.2</span><span class="p">})</span> - -<span class="c1">### Set or load sequence</span> -<span class="n">k</span><span class="o">.</span><span class="n">sequence</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">]])</span> <span class="c1"># set numpy array of shape (n,4)</span> -<span class="c1"># k.set_sequence('1 2 3 4\n2 3 4 5') # call function set_sequence and pass a string</span> -<span class="c1"># k.load_sequence('ABMN.txt') # load sequence from a local file</span> - -<span class="c1">### Run contact resistance check</span> -<span class="n">k</span><span class="o">.</span><span class="n">rs_check</span><span class="p">()</span> - -<span class="c1">### Run sequence (synchronously - it will wait that all</span> -<span class="c1"># sequence is measured before returning the prompt</span> -<span class="n">k</span><span class="o">.</span><span class="n">run_sequence</span><span class="p">()</span> -<span class="c1"># k.run_sequence_async() # sequence is run in a separate thread and the prompt returns immediately</span> -<span class="c1"># time.sleep(2)</span> -<span class="c1"># k.interrupt() # kill the asynchron sequence</span> - -<span class="c1">### Run multiple sequences at given time interval</span> -<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'nb_meas'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">3</span> <span class="c1"># run sequence three times</span> -<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'sequence_delay'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span> <span class="c1"># every 100 s</span> -<span class="n">k</span><span class="o">.</span><span class="n">run_multiple_sequences</span><span class="p">()</span> <span class="c1"># asynchron</span> -<span class="c1"># k.interrupt() # kill the asynchron sequence</span> - -<span class="c1">### Single measurement can also be taken with</span> -<span class="n">k</span><span class="o">.</span><span class="n">switch_mux_on</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span> -<span class="n">k</span><span class="o">.</span><span class="n">run_measurement</span><span class="p">()</span> <span class="c1"># use default acquisition parameters</span> -<span class="n">k</span><span class="o">.</span><span class="n">switch_mux_off</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span> <span class="c1"># don't forget this! risk of short-circuit</span> - -<span class="c1">### Custom or adaptative argument, see help(k.run_measurement)</span> -<span class="n">k</span><span class="o">.</span><span class="n">run_measurement</span><span class="p">(</span><span class="n">nb_stack</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="c1"># do 4 stacks (8 half-cycles)</span> - <span class="n">injection_duration</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="c1"># inject for 2 seconds</span> - <span class="n">autogain</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="c1"># adapt gain of ADS to get good resolution</span> -</pre></div> -</div> -</div> -</section> -<section id="mqtt-interface"> -<h3>MQTT interface<a class="headerlink" href="#mqtt-interface" title="Permalink to this heading">ïƒ</a></h3> -<p>This is an interface designed for an advanced remote usage of the OhmPi such as remote automation, data consumption by multiple processes and interaction with other sensors in the scope of a monitoring. It is based on the MQTT protocol, designed for the Internet of Things (IoT), to interact with the OhmPi.</p> -<p>This option allows interacting remotely with a single OhmPi, a network of OhmPis, as well as auxiliary instruments and sensors. The communication is based on a publish/subscribe approach and involves a MQTT broker.</p> -<p>An example of MQTT broker that can be used is <a class="reference external" href="https://mosquitto.org/">Mosquitto</a>. Depending on the monitoring needs, an MQTT broker can be set up locally on the Raspberry Pi, on a local network or any remote server reachable through the net. A local Mosquitto broker can be set up and enabled to run as a service on the OhmPi using the bash script install_local_mqtt_broker.sh.</p> -<p>MQTT messages include logging messages from the OhmPi and commands sent to the OhmPi. These messages can be examined easily using a third party software such as <a class="reference external" href="http://mqtt-explorer.com/">MQTT Explorer</a>.</p> -<p>Commands sent on the broker are received by the ohmpi.py script that runs on the OhmPi (make sure ohmpi.py starts on reboot) and further processed. -MQTT commands are sent in JSON format following the Python API with kwargs as illustrated below:</p> -<div class="literal-block-wrapper docutils container" id="id9"> -<div class="code-block-caption"><span class="caption-text">Updating acquisition settings.</span><a class="headerlink" href="#id9" title="Permalink to this code">ïƒ</a></div> -<div class="highlight-json notranslate"><div class="highlight"><pre><span></span>{ - "cmd_id": "3fzxv121UITwGjWYgcz4xw", - "cmd": "update_settings", Depending on the experiment needs, MQTT brokers can be set up locally on the Raspberry Pi or on a local or remote server. - "kwargs": { - "config": { - "nb_meas": 2, - "nb_electrodes": 10, - "nb_stack": 2, - "injection_duration": 2, - "sequence_delay": 100 - } - } -} -</pre></div> -</div> -</div> -<div class="literal-block-wrapper docutils container" id="id10"> -<div class="code-block-caption"><span class="caption-text">Check contact resistances</span><a class="headerlink" href="#id10" title="Permalink to this code">ïƒ</a></div> -<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> -<span class="w"> </span><span class="nt">"cmd_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3fzxv121UITwGjWYgcz4xw"</span><span class="p">,</span> -<span class="w"> </span><span class="nt">"cmd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"rs_check"</span><span class="p">,</span> -<span class="p">}</span> -</pre></div> -</div> -</div> -<div class="literal-block-wrapper docutils container" id="id11"> -<div class="code-block-caption"><span class="caption-text">Running a sequence.</span><a class="headerlink" href="#id11" title="Permalink to this code">ïƒ</a></div> -<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> -<span class="w"> </span><span class="nt">"cmd_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3fzxv121UITwGjWYgcz4Yw"</span><span class="p">,</span> -<span class="w"> </span><span class="nt">"cmd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"run_sequence"</span><span class="p">,</span> -<span class="p">}</span> -</pre></div> -</div> -</div> -<div class="literal-block-wrapper docutils container" id="id12"> -<div class="code-block-caption"><span class="caption-text">Running same sequence multiple times (nb_meas).</span><a class="headerlink" href="#id12" title="Permalink to this code">ïƒ</a></div> -<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> -<span class="w"> </span><span class="nt">"cmd_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3fzxv121UITwGjWYgcz4Yw"</span><span class="p">,</span> -<span class="w"> </span><span class="nt">"cmd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"run_multiple_sequences"</span><span class="p">,</span> -<span class="p">}</span> -</pre></div> -</div> -</div> -<div class="literal-block-wrapper docutils container" id="id13"> -<div class="code-block-caption"><span class="caption-text">Interrupt current acquisition.</span><a class="headerlink" href="#id13" title="Permalink to this code">ïƒ</a></div> -<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> -<span class="w"> </span><span class="nt">"cmd_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3fzxv121UITwGjWYgcz4xw"</span><span class="p">,</span> -<span class="w"> </span><span class="nt">"cmd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"interrupt"</span><span class="p">,</span> -<span class="p">}</span> -</pre></div> -</div> +<p>This section details describes the Python software and how to interact with an OhmPi instrument.</p> +<div class="toctree-wrapper compound"> +<ul> +<li class="toctree-l1"><a class="reference internal" href="software/architecture.html">Software architecture</a><ul> +<li class="toctree-l2"><a class="reference internal" href="software/architecture.html#hardware-components">Hardware components</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/architecture.html#hardware-system">Hardware system</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/architecture.html#acquisition">Acquisition</a></li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="software/installation.html">Installation</a><ul> +<li class="toctree-l2"><a class="reference internal" href="software/installation.html#step-1-connect-to-the-raspberry-pi">Step 1: Connect to the Raspberry Pi</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/installation.html#step-2-clone-the-ohmpi-project">Step 2: Clone the OhmPi project</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/installation.html#step-3-run-the-installation-script">Step 3: Run the installation script</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/installation.html#step-4-activate-the-ohmpy-virtual-environment">Step 4: Activate the ohmpy virtual environment</a></li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="software/operations.html">Configuration file</a></li> +<li class="toctree-l1"><a class="reference internal" href="software/operations.html#interfaces-and-applications">Interfaces and applications</a><ul> +<li class="toctree-l2"><a class="reference internal" href="software/operations.html#web-interface">Web interface</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/operations.html#python-interface">Python interface</a></li> +<li class="toctree-l2"><a class="reference internal" href="software/operations.html#mqtt-interface">MQTT interface</a><ul> +<li class="toctree-l3"><a class="reference internal" href="software/operations.html#loggers">Loggers</a></li> +</ul> +</li> +</ul> +</li> +</ul> </div> -<p>Custom processing of messages and tailor-made dashboards for monitoring experiments may be designed using a browser-based flow editor such as <a class="reference external" href="http://mqtt-explorer.com/">Node-red</a>. -This may help designing complex IoT experiments and monitoring systems in which OhmPi is a component.</p> -<p>Examples incorporating execution commands and data outputs from OhmPi can be found in the OhmPi examples. Once Node-RED is installed on the OhmPi, these examples can be accessed separately by running a command in the console such as :</p> -<p>These examples may require installing some additional node packages in order to work properly. This can be done in the <a href="#id2"><span class="problematic" id="id3">`</span></a>Palette Manager <<a class="reference external" href="https://nodered.org/docs/user-guide/editor/palette/manager">https://nodered.org/docs/user-guide/editor/palette/manager</a>> within Node-RED.</p> -<figure class="align-default" id="id14"> -<img alt="../_images/node-red_flow.png" src="../_images/node-red_flow.png" /> -<figcaption> -<p><span class="caption-text">Example flow in node-red to interact with an OhmPi.</span><a class="headerlink" href="#id14" title="Permalink to this image">ïƒ</a></p> -</figcaption> -</figure> -<figure class="align-default" id="id15"> -<img alt="../_images/node-red_interface_control.png" src="../_images/node-red_interface_control.png" /> -<figcaption> -<p><span class="caption-text">Example of a dashboard UI created with node-red to interact with an OhmPi - control tab.</span><a class="headerlink" href="#id15" title="Permalink to this image">ïƒ</a></p> -</figcaption> -</figure> -<figure class="align-default" id="id16"> -<img alt="../_images/node-red_interface_data.png" src="../_images/node-red_interface_data.png" /> -<figcaption> -<p><span class="caption-text">Example of a dashboard UI created with node-red to interact with an OhmPi - data visualization tab.</span><a class="headerlink" href="#id16" title="Permalink to this image">ïƒ</a></p> -</figcaption> -</figure> -<p>For more documentation dedicated to node-red, please refer to the Node-red <a class="reference external" href="https://cookbook.nodered.org/">cookbooks</a>.</p> -</section> -</section> </section> @@ -320,7 +124,7 @@ This may help designing complex IoT experiments and monitoring systems in which </div> <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> <a href="hardware/assembling.html" class="btn btn-neutral float-left" title="Assembling the OhmPi" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> - <a href="api.html" class="btn btn-neutral float-right" title="API reference" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> + <a href="software/architecture.html" class="btn btn-neutral float-right" title="Software architecture" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> </div> <hr/> diff --git a/doc/build/html/source_rst/software/architecture.html b/doc/build/html/source_rst/software/architecture.html new file mode 100644 index 00000000..577860d7 --- /dev/null +++ b/doc/build/html/source_rst/software/architecture.html @@ -0,0 +1,177 @@ +<!DOCTYPE html> +<html class="writer-html5" lang="en" > +<head> + <meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" /> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Software architecture — OhmPi v2024rc documentation</title> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" /> + <!--[if lt IE 9]> + <script src="../../_static/js/html5shiv.min.js"></script> + <![endif]--> + + <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script> + <script src="../../_static/jquery.js"></script> + <script src="../../_static/underscore.js"></script> + <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script> + <script src="../../_static/doctools.js"></script> + <script src="../../_static/js/theme.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + <link rel="next" title="Installation" href="installation.html" /> + <link rel="prev" title="Software and operation" href="../software.html" /> +</head> + +<body class="wy-body-for-nav"> + <div class="wy-grid-for-nav"> + <nav data-toggle="wy-nav-shift" class="wy-nav-side"> + <div class="wy-side-scroll"> + <div class="wy-side-nav-search" > + + + + <a href="../../index.html" class="icon icon-home"> + OhmPi + </a> +<div role="search"> + <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get"> + <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> +</div> + </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> + <ul class="current"> +<li class="toctree-l1"><a class="reference internal" href="../Ohmpi.html">OhmPi project</a></li> +<li class="toctree-l1"><a class="reference internal" href="../hardware.html">Hardware</a></li> +<li class="toctree-l1 current"><a class="reference internal" href="../software.html">Software and operation</a><ul class="current"> +<li class="toctree-l2 current"><a class="current reference internal" href="#">Software architecture</a><ul> +<li class="toctree-l3"><a class="reference internal" href="#hardware-components">Hardware components</a></li> +<li class="toctree-l3"><a class="reference internal" href="#hardware-system">Hardware system</a></li> +<li class="toctree-l3"><a class="reference internal" href="#acquisition">Acquisition</a></li> +</ul> +</li> +<li class="toctree-l2"><a class="reference internal" href="installation.html">Installation</a></li> +<li class="toctree-l2"><a class="reference internal" href="operations.html">Configuration file</a></li> +<li class="toctree-l2"><a class="reference internal" href="operations.html#interfaces-and-applications">Interfaces and applications</a></li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="../api.html">API reference</a></li> +<li class="toctree-l1"><a class="reference internal" href="../troubleshooting.html">Troubleshooting</a></li> +<li class="toctree-l1"><a class="reference internal" href="../gallery.html">Examples of applications</a></li> +<li class="toctree-l1"><a class="reference internal" href="../developing_hardware_components.html">Software interface to new hardware components</a></li> +<li class="toctree-l1"><a class="reference internal" href="../archived_version.html">Archived versions</a></li> +</ul> + + </div> + </div> + </nav> + + <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > + <i data-toggle="wy-nav-top" class="fa fa-bars"></i> + <a href="../../index.html">OhmPi</a> + </nav> + + <div class="wy-nav-content"> + <div class="rst-content"> + <div role="navigation" aria-label="Page navigation"> + <ul class="wy-breadcrumbs"> + <li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li> + <li class="breadcrumb-item"><a href="../software.html">Software and operation</a></li> + <li class="breadcrumb-item active">Software architecture</li> + <li class="wy-breadcrumbs-aside"> + <a href="../../_sources/source_rst/software/architecture.rst.txt" rel="nofollow"> View page source</a> + </li> + </ul> + <hr/> +</div> + <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> + <div itemprop="articleBody"> + + <section id="software-architecture"> +<h1>Software architecture<a class="headerlink" href="#software-architecture" title="Permalink to this heading">ïƒ</a></h1> +<p>The OhmPi V2024 software has been completely re-structured to enable increased flexibility for both users and developers. The software is based on an object-oriented module with a class exposing the OhmPi +functionalities used to interact with the OhmPi instrument via a web interface, IoT +communication protocols (e.g. MQTT) and/or directly through the Python API.</p> +<figure class="align-default" id="id1"> +<img alt="../../_images/architecture.png" src="../../_images/architecture.png" /> +<figcaption> +<p><span class="caption-text">Software architecture of OhmPi V2024.</span><a class="headerlink" href="#id1" title="Permalink to this image">ïƒ</a></p> +</figcaption> +</figure> +<p>The software is organised in several modules describing the system in a hierarchy including three levels of description and +operation of the OhmPi.</p> +<section id="hardware-components"> +<h2>Hardware components<a class="headerlink" href="#hardware-components" title="Permalink to this heading">ïƒ</a></h2> +<p>On the base level, the five main hardware components are represented by distinct classes exposing the +components atomic functionalities. Theses classes are abstract classes in order to provide a common +interface for different implementations of a component. From these abstract classes concrete classes +are implemented representing the default properties, actual capabilities and ways to interact with the +physical modules or boards. +Improving an existing hardware component or introducing a new design may be desirable in order to, +e.g. reduce costs, improve performance, adapt measurement range to specific applications, or +incorporate easily available electronic components. It is at this level that software developments are +mainly expected to occur following updates on the hardware. The component class should expose the +minimal functionalities required by the hardware system (see below) for this type of component.</p> +</section> +<section id="hardware-system"> +<h2>Hardware system<a class="headerlink" href="#hardware-system" title="Permalink to this heading">ïƒ</a></h2> +<p>On the medium level, the OhmPiHardware class provides a mean to assemble and operate the +acquisition system. The methods of this class orchestrate atomic operations of the system components +in order to expose basic system functionalities such as cross-MUX switching, square wave voltage +injection or full waveform voltage and current reading during injection cycles. These functionalities +are implemented using synchronization mechanisms between threads in order to insure that each +component keeps in step with the others. +The whole system is described in a configuration file listing the hardware components and versions +used. Through a dynamic import mechanism the modules containing the classes corresponding with +the physical hardware modules of a particular OhmPi system are instantiated and associated with the +system object instantiated from the OhmPiHardware class. In this way, it is relatively simple to build +customised systems once the concrete classes describing the system components have been written. +This part of the software architecture should remain stable if the overall system functionalities do not +evolve. However, the introduction of new functionalities at the system level or radical changes in the +way the components work together will require adaptations at this level.</p> +</section> +<section id="acquisition"> +<h2>Acquisition<a class="headerlink" href="#acquisition" title="Permalink to this heading">ïƒ</a></h2> +<p>On the top level, the OhmPi class (in ohmpi/ohmpi.py) includes all the higher-level methods and properties allowing to +operate the system (e.g. acquire measurement sequences). The OhmPi class exposes the user-oriented +API, generates logs and handles IoT messages. Generic users are expected to interact with the system +through these higher-level functionalities, which are designed to remain as stable as possible while the +hardware evolves. Only the introduction of new end-user functionalities should imply new +developments at this level. See</p> +</section> +</section> + + + </div> + </div> + <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> + <a href="../software.html" class="btn btn-neutral float-left" title="Software and operation" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> + <a href="installation.html" class="btn btn-neutral float-right" title="Installation" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> + </div> + + <hr/> + + <div role="contentinfo"> + <p>© Copyright 2022, the OhmPi Team..</p> + </div> + + Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a + <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> + provided by <a href="https://readthedocs.org">Read the Docs</a>. + + +</footer> + </div> + </div> + </section> + </div> + <script> + jQuery(function () { + SphinxRtdTheme.Navigation.enable(true); + }); + </script> + +</body> +</html> \ No newline at end of file diff --git a/doc/build/html/source_rst/software/developments.html b/doc/build/html/source_rst/software/developments.html new file mode 100644 index 00000000..2e74541f --- /dev/null +++ b/doc/build/html/source_rst/software/developments.html @@ -0,0 +1,113 @@ +<!DOCTYPE html> +<html class="writer-html5" lang="en" > +<head> + <meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" /> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title><no title> — OhmPi v2024rc documentation</title> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" /> + <!--[if lt IE 9]> + <script src="../../_static/js/html5shiv.min.js"></script> + <![endif]--> + + <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script> + <script src="../../_static/jquery.js"></script> + <script src="../../_static/underscore.js"></script> + <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script> + <script src="../../_static/doctools.js"></script> + <script src="../../_static/js/theme.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + <link rel="next" title="API reference" href="../api.html" /> + <link rel="prev" title="Configuration file" href="operations.html" /> +</head> + +<body class="wy-body-for-nav"> + <div class="wy-grid-for-nav"> + <nav data-toggle="wy-nav-shift" class="wy-nav-side"> + <div class="wy-side-scroll"> + <div class="wy-side-nav-search" > + + + + <a href="../../index.html" class="icon icon-home"> + OhmPi + </a> +<div role="search"> + <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get"> + <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> +</div> + </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> + <ul> +<li class="toctree-l1"><a class="reference internal" href="../Ohmpi.html">OhmPi project</a></li> +<li class="toctree-l1"><a class="reference internal" href="../hardware.html">Hardware</a></li> +<li class="toctree-l1"><a class="reference internal" href="../software.html">Software and operation</a></li> +<li class="toctree-l1"><a class="reference internal" href="../api.html">API reference</a></li> +<li class="toctree-l1"><a class="reference internal" href="../troubleshooting.html">Troubleshooting</a></li> +<li class="toctree-l1"><a class="reference internal" href="../gallery.html">Examples of applications</a></li> +<li class="toctree-l1"><a class="reference internal" href="../developing_hardware_components.html">Software interface to new hardware components</a></li> +<li class="toctree-l1"><a class="reference internal" href="../archived_version.html">Archived versions</a></li> +</ul> + + </div> + </div> + </nav> + + <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > + <i data-toggle="wy-nav-top" class="fa fa-bars"></i> + <a href="../../index.html">OhmPi</a> + </nav> + + <div class="wy-nav-content"> + <div class="rst-content"> + <div role="navigation" aria-label="Page navigation"> + <ul class="wy-breadcrumbs"> + <li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li> + <li class="breadcrumb-item"><a href="../software.html">Software and operation</a></li> + <li class="breadcrumb-item active"><no title></li> + <li class="wy-breadcrumbs-aside"> + <a href="../../_sources/source_rst/software/developments.rst.txt" rel="nofollow"> View page source</a> + </li> + </ul> + <hr/> +</div> + <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> + <div itemprop="articleBody"> + + + + </div> + </div> + <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> + <a href="operations.html" class="btn btn-neutral float-left" title="Configuration file" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> + <a href="../api.html" class="btn btn-neutral float-right" title="API reference" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> + </div> + + <hr/> + + <div role="contentinfo"> + <p>© Copyright 2022, the OhmPi Team..</p> + </div> + + Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a + <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> + provided by <a href="https://readthedocs.org">Read the Docs</a>. + + +</footer> + </div> + </div> + </section> + </div> + <script> + jQuery(function () { + SphinxRtdTheme.Navigation.enable(true); + }); + </script> + +</body> +</html> \ No newline at end of file diff --git a/doc/build/html/source_rst/software/installation.html b/doc/build/html/source_rst/software/installation.html new file mode 100644 index 00000000..b98a3264 --- /dev/null +++ b/doc/build/html/source_rst/software/installation.html @@ -0,0 +1,165 @@ +<!DOCTYPE html> +<html class="writer-html5" lang="en" > +<head> + <meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" /> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Installation — OhmPi v2024rc documentation</title> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" /> + <!--[if lt IE 9]> + <script src="../../_static/js/html5shiv.min.js"></script> + <![endif]--> + + <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script> + <script src="../../_static/jquery.js"></script> + <script src="../../_static/underscore.js"></script> + <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script> + <script src="../../_static/doctools.js"></script> + <script src="../../_static/js/theme.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + <link rel="next" title="Configuration file" href="operations.html" /> + <link rel="prev" title="Software architecture" href="architecture.html" /> +</head> + +<body class="wy-body-for-nav"> + <div class="wy-grid-for-nav"> + <nav data-toggle="wy-nav-shift" class="wy-nav-side"> + <div class="wy-side-scroll"> + <div class="wy-side-nav-search" > + + + + <a href="../../index.html" class="icon icon-home"> + OhmPi + </a> +<div role="search"> + <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get"> + <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> +</div> + </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> + <ul class="current"> +<li class="toctree-l1"><a class="reference internal" href="../Ohmpi.html">OhmPi project</a></li> +<li class="toctree-l1"><a class="reference internal" href="../hardware.html">Hardware</a></li> +<li class="toctree-l1 current"><a class="reference internal" href="../software.html">Software and operation</a><ul class="current"> +<li class="toctree-l2"><a class="reference internal" href="architecture.html">Software architecture</a></li> +<li class="toctree-l2 current"><a class="current reference internal" href="#">Installation</a><ul> +<li class="toctree-l3"><a class="reference internal" href="#step-1-connect-to-the-raspberry-pi">Step 1: Connect to the Raspberry Pi</a></li> +<li class="toctree-l3"><a class="reference internal" href="#step-2-clone-the-ohmpi-project">Step 2: Clone the OhmPi project</a></li> +<li class="toctree-l3"><a class="reference internal" href="#step-3-run-the-installation-script">Step 3: Run the installation script</a></li> +<li class="toctree-l3"><a class="reference internal" href="#step-4-activate-the-ohmpy-virtual-environment">Step 4: Activate the ohmpy virtual environment</a></li> +</ul> +</li> +<li class="toctree-l2"><a class="reference internal" href="operations.html">Configuration file</a></li> +<li class="toctree-l2"><a class="reference internal" href="operations.html#interfaces-and-applications">Interfaces and applications</a></li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="../api.html">API reference</a></li> +<li class="toctree-l1"><a class="reference internal" href="../troubleshooting.html">Troubleshooting</a></li> +<li class="toctree-l1"><a class="reference internal" href="../gallery.html">Examples of applications</a></li> +<li class="toctree-l1"><a class="reference internal" href="../developing_hardware_components.html">Software interface to new hardware components</a></li> +<li class="toctree-l1"><a class="reference internal" href="../archived_version.html">Archived versions</a></li> +</ul> + + </div> + </div> + </nav> + + <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > + <i data-toggle="wy-nav-top" class="fa fa-bars"></i> + <a href="../../index.html">OhmPi</a> + </nav> + + <div class="wy-nav-content"> + <div class="rst-content"> + <div role="navigation" aria-label="Page navigation"> + <ul class="wy-breadcrumbs"> + <li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li> + <li class="breadcrumb-item"><a href="../software.html">Software and operation</a></li> + <li class="breadcrumb-item active">Installation</li> + <li class="wy-breadcrumbs-aside"> + <a href="../../_sources/source_rst/software/installation.rst.txt" rel="nofollow"> View page source</a> + </li> + </ul> + <hr/> +</div> + <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> + <div itemprop="articleBody"> + + <section id="installation"> +<h1>Installation<a class="headerlink" href="#installation" title="Permalink to this heading">ïƒ</a></h1> +<section id="step-1-connect-to-the-raspberry-pi"> +<h2>Step 1: Connect to the Raspberry Pi<a class="headerlink" href="#step-1-connect-to-the-raspberry-pi" title="Permalink to this heading">ïƒ</a></h2> +</section> +<section id="step-2-clone-the-ohmpi-project"> +<h2>Step 2: Clone the OhmPi project<a class="headerlink" href="#step-2-clone-the-ohmpi-project" title="Permalink to this heading">ïƒ</a></h2> +</section> +<section id="step-3-run-the-installation-script"> +<h2>Step 3: Run the installation script<a class="headerlink" href="#step-3-run-the-installation-script" title="Permalink to this heading">ïƒ</a></h2> +<p>Simply navigate to the OhmPi folder and run the following command on the terminal:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span>.install.sh +</pre></div> +</div> +<p>The install script first creates an python virtual environment called “ohmpy†in which all dependencies will be installed. Dependecies are specified in requirements.txt +When the installation is completed check that requirements are met using pip list. +It then installs a local MQTT broker which will be used to centralise all the communication between the hardware, software and interfaces. +It also properly configures the I2C buses on the raspberry Pi.</p> +<p>When the installation is performed, we need to add the OhmPi module to the environment by editing the PYTHONPATH or editing the .bashrc file as follows:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span>nano<span class="w"> </span>~/.bashrc +</pre></div> +</div> +<p>And add the following line:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="nv">$export</span><span class="w"> </span><span class="nv">PYTHONPATH</span><span class="o">=</span><span class="nv">$PYTHONPATH</span>:/home/<username>/OhmPi +</pre></div> +</div> +</section> +<section id="step-4-activate-the-ohmpy-virtual-environment"> +<h2>Step 4: Activate the ohmpy virtual environment<a class="headerlink" href="#step-4-activate-the-ohmpy-virtual-environment" title="Permalink to this heading">ïƒ</a></h2> +<p>Before operating the instrument, we need to activate the ohmpy virtual environment with the following command:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>~/OhmPi +$<span class="w"> </span><span class="nb">source</span><span class="w"> </span>ohmpy/bin/activate +</pre></div> +</div> +<p>If you need to leave the virtual environment, simply type:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span>deactivate +</pre></div> +</div> +</section> +</section> + + + </div> + </div> + <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> + <a href="architecture.html" class="btn btn-neutral float-left" title="Software architecture" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> + <a href="operations.html" class="btn btn-neutral float-right" title="Configuration file" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> + </div> + + <hr/> + + <div role="contentinfo"> + <p>© Copyright 2022, the OhmPi Team..</p> + </div> + + Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a + <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> + provided by <a href="https://readthedocs.org">Read the Docs</a>. + + +</footer> + </div> + </div> + </section> + </div> + <script> + jQuery(function () { + SphinxRtdTheme.Navigation.enable(true); + }); + </script> + +</body> +</html> \ No newline at end of file diff --git a/doc/build/html/source_rst/software/operations.html b/doc/build/html/source_rst/software/operations.html new file mode 100644 index 00000000..c4ad40ca --- /dev/null +++ b/doc/build/html/source_rst/software/operations.html @@ -0,0 +1,335 @@ +<!DOCTYPE html> +<html class="writer-html5" lang="en" > +<head> + <meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" /> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Configuration file — OhmPi v2024rc documentation</title> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" /> + <!--[if lt IE 9]> + <script src="../../_static/js/html5shiv.min.js"></script> + <![endif]--> + + <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script> + <script src="../../_static/jquery.js"></script> + <script src="../../_static/underscore.js"></script> + <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script> + <script src="../../_static/doctools.js"></script> + <script src="../../_static/js/theme.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + <link rel="next" title="<no title>" href="developments.html" /> + <link rel="prev" title="Installation" href="installation.html" /> +</head> + +<body class="wy-body-for-nav"> + <div class="wy-grid-for-nav"> + <nav data-toggle="wy-nav-shift" class="wy-nav-side"> + <div class="wy-side-scroll"> + <div class="wy-side-nav-search" > + + + + <a href="../../index.html" class="icon icon-home"> + OhmPi + </a> +<div role="search"> + <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get"> + <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> +</div> + </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> + <ul class="current"> +<li class="toctree-l1"><a class="reference internal" href="../Ohmpi.html">OhmPi project</a></li> +<li class="toctree-l1"><a class="reference internal" href="../hardware.html">Hardware</a></li> +<li class="toctree-l1 current"><a class="reference internal" href="../software.html">Software and operation</a><ul class="current"> +<li class="toctree-l2"><a class="reference internal" href="architecture.html">Software architecture</a></li> +<li class="toctree-l2"><a class="reference internal" href="installation.html">Installation</a></li> +<li class="toctree-l2 current"><a class="current reference internal" href="#">Configuration file</a></li> +<li class="toctree-l2"><a class="reference internal" href="#interfaces-and-applications">Interfaces and applications</a><ul> +<li class="toctree-l3"><a class="reference internal" href="#web-interface">Web interface</a></li> +<li class="toctree-l3"><a class="reference internal" href="#python-interface">Python interface</a></li> +<li class="toctree-l3"><a class="reference internal" href="#mqtt-interface">MQTT interface</a><ul> +<li class="toctree-l4"><a class="reference internal" href="#loggers">Loggers</a></li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="../api.html">API reference</a></li> +<li class="toctree-l1"><a class="reference internal" href="../troubleshooting.html">Troubleshooting</a></li> +<li class="toctree-l1"><a class="reference internal" href="../gallery.html">Examples of applications</a></li> +<li class="toctree-l1"><a class="reference internal" href="../developing_hardware_components.html">Software interface to new hardware components</a></li> +<li class="toctree-l1"><a class="reference internal" href="../archived_version.html">Archived versions</a></li> +</ul> + + </div> + </div> + </nav> + + <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > + <i data-toggle="wy-nav-top" class="fa fa-bars"></i> + <a href="../../index.html">OhmPi</a> + </nav> + + <div class="wy-nav-content"> + <div class="rst-content"> + <div role="navigation" aria-label="Page navigation"> + <ul class="wy-breadcrumbs"> + <li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li> + <li class="breadcrumb-item"><a href="../software.html">Software and operation</a></li> + <li class="breadcrumb-item active">Configuration file</li> + <li class="wy-breadcrumbs-aside"> + <a href="../../_sources/source_rst/software/operations.rst.txt" rel="nofollow"> View page source</a> + </li> + </ul> + <hr/> +</div> + <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> + <div itemprop="articleBody"> + + <section id="configuration-file"> +<h1>Configuration file<a class="headerlink" href="#configuration-file" title="Permalink to this heading">ïƒ</a></h1> +<p>The configuration of the OhmPi file <cite>config.py</cite> allows to configure the OhmPi. +A default version of <cite>config.py</cite> is provided in the repository. +This file should be edited to customize the configuration following the user’s needs and preferences.</p> +<p>The configuration includes setting the logging level desired for the different loggers and handlers, setting the mqtt broker(s) used for logging and control of the OhmPi and defining the options used for MQTT communication (i.e. username, password, security options…)</p> +<p>One should make sure to understand the parameters before altering them. It is also recommended to keep a copy of the default configuration.</p> +</section> +<section id="interfaces-and-applications"> +<h1>Interfaces and applications<a class="headerlink" href="#interfaces-and-applications" title="Permalink to this heading">ïƒ</a></h1> +<p>Different interfaces can be used to interact with the OhmPi.</p> +<p>Available interfaces are: +- <a class="reference internal" href="#web-interface">Web interface</a> (=HTTP interface): run in bash: <cite>bash run_http_interface.sh</cite> +- Python API: import the OhmPi class from Python script: <cite>from ohmpi import OhmPi</cite> (see <a class="reference internal" href="#python-interface">Python interface</a>) +- MQTT: IoT messaging through a broker (see <a class="reference internal" href="#mqtt-interface">MQTT interface</a>)</p> +<section id="web-interface"> +<h2>Web interface<a class="headerlink" href="#web-interface" title="Permalink to this heading">ïƒ</a></h2> +<p>This is a user friendly graphical interface for new users as well as running quick and easy acquisitions.</p> +<p>The Raspberry Pi of the OhmPi is used as a Wi-Fi Access Point (AP) and runs +a small webserver to serve the ‘index.html’ interface. Using a laptop or +a mobile phone connected to the Wi-Fi of the Raspberry Pi, one can see this +interface, upload sequences, change parameters, run a sequence and download data.</p> +<p>To configure the Raspberry Pi to act as an access point and run +the webserver automatically on start, see instructions on <a class="reference external" href="https://raspap.com/">raspap.com</a> and in ‘runOnStart.sh’.</p> +<p>Once configured, the webserver should start by itself on start and once +connected to the Pi, the user can go to <a class="reference external" href="http://10.3.141.1:8080">10.3.141.1:8080</a> +to access the interface.</p> +<figure class="align-default" id="id2"> +<img alt="../../_images/http-interface-pseudo-section.png" src="../../_images/http-interface-pseudo-section.png" /> +<figcaption> +<p><span class="caption-text">Web interface with its interactive pseudo-section.</span><a class="headerlink" href="#id2" title="Permalink to this image">ïƒ</a></p> +</figcaption> +</figure> +<figure class="align-default" id="id3"> +<img alt="../../_images/http-interface-evolution.png" src="../../_images/http-interface-evolution.png" /> +<figcaption> +<p><span class="caption-text">Evolution of quadrupole apparent resistivity with time.</span><a class="headerlink" href="#id3" title="Permalink to this image">ïƒ</a></p> +</figcaption> +</figure> +<figure class="align-default" id="id4"> +<img alt="../../_images/http-interface-rs.png" src="../../_images/http-interface-rs.png" /> +<figcaption> +<p><span class="caption-text">Contact resistance check.</span><a class="headerlink" href="#id4" title="Permalink to this image">ïƒ</a></p> +</figcaption> +</figure> +</section> +<section id="python-interface"> +<h2>Python interface<a class="headerlink" href="#python-interface" title="Permalink to this heading">ïƒ</a></h2> +<p>This interface offers a more direct access to the software components especially well suited for testing or automation on the Raspberry Pi.</p> +<p>By importing the <cite>OhmPi</cite> class from the ohmpi.py, one can control the OhmPi using interactive IPython. +Typically, it involves using the terminal or an Python IDE such as Thonny on the Raspberry Pi. One can also connect using +ssh and run the Python interface (see PuTTY on Windows or ssh command on macOS/Linux).</p> +<p>To access the Python API, make sure the file ohmpi.py is in the same +directory as where you run the commands/script. The file ohmpi.py can +be found on the OhmPi gitlab repository. We recommend downloading the +entire repository as ohmpi.py import other .py files and default configuration +files (.json and .py).</p> +<div class="literal-block-wrapper docutils container" id="id5"> +<div class="code-block-caption"><span class="caption-text">Example of using the Python API to control OhmPi</span><a class="headerlink" href="#id5" title="Permalink to this code">ïƒ</a></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span> +<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span> +<span class="kn">import</span> <span class="nn">time</span> +<span class="n">os</span><span class="o">.</span><span class="n">chdir</span><span class="p">(</span><span class="s2">"/home/pi/OhmPi"</span><span class="p">)</span> +<span class="kn">from</span> <span class="nn">ohmpi</span> <span class="kn">import</span> <span class="n">OhmPi</span> + +<span class="c1">### Define object from class OhmPi</span> +<span class="n">k</span> <span class="o">=</span> <span class="n">OhmPi</span><span class="p">()</span> <span class="c1"># this loads default parameters from the disk</span> + +<span class="c1">### Default parameters can also be edited manually</span> +<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'injection_duration'</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="c1"># injection time in seconds</span> +<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'nb_stack'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># one stack is two half-cycles</span> +<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'nbr_meas'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># number of time the sequence is repeated</span> + +<span class="c1">### Update settings if needed</span> +<span class="n">k</span><span class="o">.</span><span class="n">update_settings</span><span class="p">({</span><span class="s2">"injection_duration"</span><span class="p">:</span><span class="mf">0.2</span><span class="p">})</span> + +<span class="c1">### Set or load sequence</span> +<span class="n">k</span><span class="o">.</span><span class="n">sequence</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">]])</span> <span class="c1"># set numpy array of shape (n,4)</span> +<span class="c1"># k.set_sequence('1 2 3 4\n2 3 4 5') # call function set_sequence and pass a string</span> +<span class="c1"># k.load_sequence('ABMN.txt') # load sequence from a local file</span> + +<span class="c1">### Run contact resistance check</span> +<span class="n">k</span><span class="o">.</span><span class="n">rs_check</span><span class="p">()</span> + +<span class="c1">### Run sequence (synchronously - it will wait that all</span> +<span class="c1"># sequence is measured before returning the prompt</span> +<span class="n">k</span><span class="o">.</span><span class="n">run_sequence</span><span class="p">()</span> +<span class="c1"># k.run_sequence_async() # sequence is run in a separate thread and the prompt returns immediately</span> +<span class="c1"># time.sleep(2)</span> +<span class="c1"># k.interrupt() # kill the asynchron sequence</span> + +<span class="c1">### Run multiple sequences at given time interval</span> +<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'nb_meas'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">3</span> <span class="c1"># run sequence three times</span> +<span class="n">k</span><span class="o">.</span><span class="n">settings</span><span class="p">[</span><span class="s1">'sequence_delay'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span> <span class="c1"># every 100 s</span> +<span class="n">k</span><span class="o">.</span><span class="n">run_multiple_sequences</span><span class="p">()</span> <span class="c1"># asynchron</span> +<span class="c1"># k.interrupt() # kill the asynchron sequence</span> + +<span class="c1">### Single measurement can also be taken with</span> +<span class="n">k</span><span class="o">.</span><span class="n">switch_mux_on</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span> +<span class="n">k</span><span class="o">.</span><span class="n">run_measurement</span><span class="p">()</span> <span class="c1"># use default acquisition parameters</span> +<span class="n">k</span><span class="o">.</span><span class="n">switch_mux_off</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span> <span class="c1"># don't forget this! risk of short-circuit</span> + +<span class="c1">### Custom or adaptative argument, see help(k.run_measurement)</span> +<span class="n">k</span><span class="o">.</span><span class="n">run_measurement</span><span class="p">(</span><span class="n">nb_stack</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="c1"># do 4 stacks (8 half-cycles)</span> + <span class="n">injection_duration</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="c1"># inject for 2 seconds</span> + <span class="n">autogain</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="c1"># adapt gain of ADS to get good resolution</span> +</pre></div> +</div> +</div> +</section> +<section id="mqtt-interface"> +<h2>MQTT interface<a class="headerlink" href="#mqtt-interface" title="Permalink to this heading">ïƒ</a></h2> +<p>This is an interface designed for an advanced remote usage of the OhmPi such as remote automation, data consumption by multiple processes and interaction with other sensors in the scope of a monitoring. It is based on the MQTT protocol, designed for the Internet of Things (IoT), to interact with the OhmPi.</p> +<p>This option allows interacting remotely with a single OhmPi, a network of OhmPis, as well as auxiliary instruments and sensors. The communication is based on a publish/subscribe approach and involves a MQTT broker.</p> +<p>An example of MQTT broker that can be used is <a class="reference external" href="https://mosquitto.org/">Mosquitto</a>. Depending on the monitoring needs, an MQTT broker can be set up locally on the Raspberry Pi, on a local network or any remote server reachable through the net. A local Mosquitto broker can be set up and enabled to run as a service on the OhmPi using the bash script install_local_mqtt_broker.sh.</p> +<p>MQTT messages include logging messages from the OhmPi and commands sent to the OhmPi. These messages can be examined easily using a third party software such as <a class="reference external" href="http://mqtt-explorer.com/">MQTT Explorer</a>.</p> +<p>Commands sent on the broker are received by the ohmpi.py script that runs on the OhmPi (make sure ohmpi.py starts on reboot) and further processed. +MQTT commands are sent in JSON format following the Python API with kwargs as illustrated below:</p> +<div class="literal-block-wrapper docutils container" id="id6"> +<div class="code-block-caption"><span class="caption-text">Updating acquisition settings.</span><a class="headerlink" href="#id6" title="Permalink to this code">ïƒ</a></div> +<div class="highlight-json notranslate"><div class="highlight"><pre><span></span>{ + "cmd_id": "3fzxv121UITwGjWYgcz4xw", + "cmd": "update_settings", Depending on the experiment needs, MQTT brokers can be set up locally on the Raspberry Pi or on a local or remote server. + "kwargs": { + "config": { + "nb_meas": 2, + "nb_electrodes": 10, + "nb_stack": 2, + "injection_duration": 2, + "sequence_delay": 100 + } + } +} +</pre></div> +</div> +</div> +<div class="literal-block-wrapper docutils container" id="id7"> +<div class="code-block-caption"><span class="caption-text">Check contact resistances</span><a class="headerlink" href="#id7" title="Permalink to this code">ïƒ</a></div> +<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> +<span class="w"> </span><span class="nt">"cmd_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3fzxv121UITwGjWYgcz4xw"</span><span class="p">,</span> +<span class="w"> </span><span class="nt">"cmd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"rs_check"</span><span class="p">,</span> +<span class="p">}</span> +</pre></div> +</div> +</div> +<div class="literal-block-wrapper docutils container" id="id8"> +<div class="code-block-caption"><span class="caption-text">Running a sequence.</span><a class="headerlink" href="#id8" title="Permalink to this code">ïƒ</a></div> +<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> +<span class="w"> </span><span class="nt">"cmd_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3fzxv121UITwGjWYgcz4Yw"</span><span class="p">,</span> +<span class="w"> </span><span class="nt">"cmd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"run_sequence"</span><span class="p">,</span> +<span class="p">}</span> +</pre></div> +</div> +</div> +<div class="literal-block-wrapper docutils container" id="id9"> +<div class="code-block-caption"><span class="caption-text">Running same sequence multiple times (nb_meas).</span><a class="headerlink" href="#id9" title="Permalink to this code">ïƒ</a></div> +<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> +<span class="w"> </span><span class="nt">"cmd_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3fzxv121UITwGjWYgcz4Yw"</span><span class="p">,</span> +<span class="w"> </span><span class="nt">"cmd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"run_multiple_sequences"</span><span class="p">,</span> +<span class="p">}</span> +</pre></div> +</div> +</div> +<div class="literal-block-wrapper docutils container" id="id10"> +<div class="code-block-caption"><span class="caption-text">Interrupt current acquisition.</span><a class="headerlink" href="#id10" title="Permalink to this code">ïƒ</a></div> +<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> +<span class="w"> </span><span class="nt">"cmd_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3fzxv121UITwGjWYgcz4xw"</span><span class="p">,</span> +<span class="w"> </span><span class="nt">"cmd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"interrupt"</span><span class="p">,</span> +<span class="p">}</span> +</pre></div> +</div> +</div> +<p>Custom processing of messages and tailor-made dashboards for monitoring experiments may be designed using a browser-based flow editor such as <a class="reference external" href="http://mqtt-explorer.com/">Node-red</a>. +This may help designing complex IoT experiments and monitoring systems in which OhmPi is a component.</p> +<p>Examples incorporating execution commands and data outputs from OhmPi can be found in the OhmPi examples. Once Node-RED is installed on the OhmPi, these examples can be accessed separately by running a command in the console such as :</p> +<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">node-red basic_ohmpi_flows_node-red.json</span> +</pre></div> +</div> +<p>These examples may require installing some additional node packages in order to work properly. This can be done in the <a class="reference external" href="https://nodered.org/docs/user-guide/editor/palette/manager">Palette Manager</a> within Node-RED.</p> +<figure class="align-default" id="id11"> +<img alt="../../_images/node-red_flow.png" src="../../_images/node-red_flow.png" /> +<figcaption> +<p><span class="caption-text">Example flow in node-red to interact with an OhmPi.</span><a class="headerlink" href="#id11" title="Permalink to this image">ïƒ</a></p> +</figcaption> +</figure> +<figure class="align-default" id="id12"> +<img alt="../../_images/node-red_interface_control.png" src="../../_images/node-red_interface_control.png" /> +<figcaption> +<p><span class="caption-text">Example of a dashboard UI created with node-red to interact with an OhmPi - control tab.</span><a class="headerlink" href="#id12" title="Permalink to this image">ïƒ</a></p> +</figcaption> +</figure> +<figure class="align-default" id="id13"> +<img alt="../../_images/node-red_interface_data.png" src="../../_images/node-red_interface_data.png" /> +<figcaption> +<p><span class="caption-text">Example of a dashboard UI created with node-red to interact with an OhmPi - data visualization tab.</span><a class="headerlink" href="#id13" title="Permalink to this image">ïƒ</a></p> +</figcaption> +</figure> +<p>For more documentation dedicated to node-red, please refer to the Node-red <a class="reference external" href="https://cookbook.nodered.org/">cookbooks</a>.</p> +<section id="loggers"> +<h3>Loggers<a class="headerlink" href="#loggers" title="Permalink to this heading">ïƒ</a></h3> +<p>Loggers have been introduced in this release. They use the excellent logging python package. +Specific handlers have been implemented for running with ohmpi.py (one for logging to an mqtt broker (see <a class="reference internal" href="#mqtt-interface">MQTT interface</a> for more details) and one for creating zipped rotated logs on disk).</p> +<p>Two loggers have been defined. The first one is dedicated to log operations execution. It is named exec_logger. The second one, named data_logger, is dedicated to log data. A third one is planned to log the state of health (SOH) of the system in a future version.</p> +<p>By default, logs are written to the console (print-like), stored locally in files (a zip is created after some time i.e. every day and/or when the size of the log exceeds a maximum size) and sent to an MQTT broker. Different logging levels may be defined for the different logs and handlers in the <a class="reference internal" href="#configuration-file">Configuration file</a>.</p> +<p>Advanced users may write new handlers and edit the <cite>setup_loggers.py</cite> file to customize the logging mechanisms to their needs.</p> +</section> +</section> +</section> + + + </div> + </div> + <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> + <a href="installation.html" class="btn btn-neutral float-left" title="Installation" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> + <a href="developments.html" class="btn btn-neutral float-right" title="<no title>" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> + </div> + + <hr/> + + <div role="contentinfo"> + <p>© Copyright 2022, the OhmPi Team..</p> + </div> + + Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a + <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> + provided by <a href="https://readthedocs.org">Read the Docs</a>. + + +</footer> + </div> + </div> + </section> + </div> + <script> + jQuery(function () { + SphinxRtdTheme.Navigation.enable(true); + }); + </script> + +</body> +</html> \ No newline at end of file diff --git a/doc/source/source_rst/V2023.x.x/V2023_step_03.rst b/doc/source/source_rst/V2023.x.x/V2023_step_03.rst deleted file mode 100644 index ed1a04e1..00000000 --- a/doc/source/source_rst/V2023.x.x/V2023_step_03.rst +++ /dev/null @@ -1,289 +0,0 @@ - - -.. warning:: - **OhmPi is a participative project open to all, it requires skills in electronics and to respect the safety rules. OhmPi must be assembled in a professional context and by people competent in electronics. The OhmPi team cannot be held responsible for any material or human damage which would be associated with the use or the assembly of OHMPI. The OhmPi team cannot be held responsible if the equipment does not work after assembly.** - - - -**STEP n°3:** MUX board -**************************************************** -The multiplexing of the channels is a mechanical multiplexing based on OMRON's manufacturing relays (G5LE-1-VD 12 VDC). Each relay is combined with -a ZVN4206A power MOFSET. The raspberry has only 30 GPIOs, which is not enough to activate all the 64 electrodes, which represent 512 GPIOs. -We used gpio expander I2C (MCP23017). We have associated these components with an I2C multiplexer of type type TCA9548A from adafruit. -This combination allows to go up to 512 GPIOs and up to 128 electrodes. Each card has its own digital address between 0X70 and 0X77. -In the following presentation for an OhmPi 64 electrodes, we will use the addresses 0X70 for channel A, 0X71 for channel B, 0X72 for channel M and 0X73 for channel N. -0X73 for the N channel. 4 MUX board will be needed to multiplex an OhmPi 64 electrodes. - -**PART A** Assembly of MUX board -====================================================== - - -Required components ----------------------------------------------------- - -.. figure:: ../../img/v2023.x.x/step_n_3/a/MUX_board_components.jpg - :width: 600px - :align: center - :height: 650px - :alt: alternate text - :figclass: align-center - - -.. csv-table:: List of components - :file: ../V2023.x.x/MUX_board_list_2_xx.csv - :header-rows: 1 - - -.. table:: - :align: center - - +--------+--------------------------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_00.jpg | - | 1 +--------------------------------------------------------------------------------+ - | |Mux board pcb | - | | | - +--------+--------------------------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_01.jpg | - | 2 +------------------------------------------------------------+ - | |Installation of the 100 kOhm resistors | - | | | - +--------+------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_02.jpg | - | 3 +------------------------------------------------------------+ - | |Installation of the MOSFET ZVN4206A | - | | | - +--------+------------------------------------------------------------+ - - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_03.jpg | - | 4 +------------------------------------------------------------+ - | |Installation of the diode 1N4007 | - | | | - +--------+------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_04.jpg | - | 5 +------------------------------------------------------------+ - | |Installation of the relay | - | | | - +--------+------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_05.jpg | - | 6 +------------------------------------------------------------+ - | |Installation of the terminal screw | - | | | - +--------+------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_06.jpg | - | 7 +------------------------------------------------------------+ - | |Installation of generic male header | - | | | - +--------+------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_07.jpg | - | 8 +------------------------------------------------------------+ - | |Installation of Pin strip (6 pins) and pin strip (16 pins) | - | | | - +--------+------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_08.jpg | - | 9 +------------------------------------------------------------+ - | |Installation of DIP Dual In Line Socket 2*14 | - | | | - +--------+------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_09.jpg | - | 10 +------------------------------------------------------------+ - | |Installation of Adafruit TCA9548A | - | | | - +--------+------------------------------------------------------------+ - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/a/MUX_10.jpg | - | 10 +------------------------------------------------------------+ - | |Installation of MCP23017 | - | | | - +--------+------------------------------------------------------------+ - -.. note:: - This step must be duplicated 4 times for every Mux card. - - - -**PART B** MUX board address -====================================================== -To build an ohmpi it is necessary to have 4 MUX boards, with 4 different addresses. It is therefore necessary to identify each board, by assigning an address, which will be allocated in the OhmPi code. -We present here the addresses selected by default. - -For the A electrode board, we suggest addressing it with address 0x70: - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/b/A_0x70.jpg | - | 1 +------------------------------------------------------------+ - | |Mount the jumpers and note the value of the address and the | - | |electrode name on the mux board (A). | - | +------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/b/A_0x70-a.jpg | - | +------------------------------------------------------------+ - | |Zoom on the jumper | - | | | - +--------+------------------------------------------------------------+ - - - - -For the B electrode board, we suggest addressing it with address 0x71: - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/b/B_0x71.jpg | - | 2 +------------------------------------------------------------+ - | |Mount the jumpers and note the value of the address and the | - | |electrode name on the mux board (B). | - | +------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/b/B_0x71-a.jpg | - | +------------------------------------------------------------+ - | |Zoom on the jumper | - | | | - +--------+------------------------------------------------------------+ - -For the N electrode board, we suggest addressing it with address 0x72: - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/b/M_0x72.jpg | - | 3 +------------------------------------------------------------+ - | |Mount the jumpers and note the value of the address and the | - | |electrode name on the mux board (B). | - | +------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/b/M_0x72-a.jpg | - | +------------------------------------------------------------+ - | |Zoom on the jumper | - | | | - +--------+------------------------------------------------------------+ - -For the M electrode board, we suggest addressing it with address 0x73: - -.. table:: - :align: center - - +--------+------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/b/N_0x73.jpg | - | 4 +------------------------------------------------------------+ - | |Mount the jumpers and note the value of the address and the | - | |electrode name on the mux board (B). | - | +------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/b/N_0x73-a.jpg | - | +------------------------------------------------------------+ - | |Zoom on the jumper | - | | | - +--------+------------------------------------------------------------+ - -**PART C** Validation of MUX board -====================================================== -The first step is to test the Mux boards before assembling them definitively. -To test the Mux boards, it will be necessary first to make a simplified assembly of the Mux board and the measurement board. - -The first thing to do is to prepare a 50 cm long flat wire with two 6-poles connectors. - - - +--------+-----------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/c/20211207_115706.jpg | - | 1 +-----------------------------------------------------------------+ - | |Build a cable with 6 contacts with 6 pins connector. | - | | | - +--------+-----------------------------------------------------------------+ - - +--------+-----------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/c/20220124_142929.jpg | - | 2 +-----------------------------------------------------------------+ - | |Prepare the measurement board and the first mux board by | - | |example the card with address 0x71. | - +--------+-----------------------------------------------------------------+ - - +--------+-----------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/c/20220124_143105.jpg | - | 3 +-----------------------------------------------------------------+ - | |Connect the 12V power supply cables to the MUX board | - | |without powering the board. | - +--------+-----------------------------------------------------------------+ - - +--------+------------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/c/20220207_154111.jpg | - | 4 +------------------------------------------------------------------+ - | |Connect the 12V power supply screw terminal of the mux | - | |board to the 12V screw terminal power supply of the | - | |measurement board. | - +--------+------------------------------------------------------------------+ - - +--------+------------------------------------------------------------------+ - | | .. image:: ../../img/v2023.x.x/step_n_3/c/20220124_143823.jpg | - | 5 +------------------------------------------------------------------+ - | |Connect the 6-contact cable | - | | | - +--------+------------------------------------------------------------------+ - - -Start your 12V power supply, the raspberry must start. - -Run the terminal and write: - - .. code-block:: python - - i2cdetect -y 1 - -Three addresses should appear, including the address of the MUX board you have selected. This implies that your board has been detected. - -Open the script called "test_mux_board.py". - -Run the script - - - \ No newline at end of file diff --git a/doc/source/source_rst/developing_hardware_components.rst b/doc/source/source_rst/developing_hardware_components.rst index fa97c06a..55736fb5 100644 --- a/doc/source/source_rst/developing_hardware_components.rst +++ b/doc/source/source_rst/developing_hardware_components.rst @@ -1,7 +1,8 @@ Software interface to new hardware components ============================================= -*** DRAFT VERSION - TO BE REVIEWED * +*** DRAFT VERSION - TO BE REVIEWED *** + This section is intended for developers of a new hardware component as part of an OhmPi system. It presents some advices and best practices that should help developing new hardware components to work diff --git a/doc/source/source_rst/software.rst b/doc/source/source_rst/software.rst index 27f7db96..01327174 100644 --- a/doc/source/source_rst/software.rst +++ b/doc/source/source_rst/software.rst @@ -1,5 +1,5 @@ Software and operation -##################### +###################### .. warning:: **OhmPi is a participative project open to all, it requires skills in electronics and to respect the safety rules. OhmPi must be assembled in a professional context and by people competent in electronics. The OhmPi team cannot be held responsible for any material or human damage which would be associated with the use or the assembly of OhmPi. The OhmPi team cannot be held responsible if the equipment does not work after assembly.** diff --git a/doc/source/source_rst/software/architecture.rst b/doc/source/source_rst/software/architecture.rst index be42b03f..ca25b7f6 100644 --- a/doc/source/source_rst/software/architecture.rst +++ b/doc/source/source_rst/software/architecture.rst @@ -1,11 +1,11 @@ Software architecture -******************* +********************* The OhmPi V2024 software has been completely re-structured to enable increased flexibility for both users and developers. The software is based on an object-oriented module with a class exposing the OhmPi functionalities used to interact with the OhmPi instrument via a web interface, IoT communication protocols (e.g. MQTT) and/or directly through the Python API. -.. figure:: ../img/architecture.png +.. figure:: ../../img/architecture.png Software architecture of OhmPi V2024. diff --git a/doc/source/source_rst/software/installation.rst b/doc/source/source_rst/software/installation.rst index 4180a58a..0052606f 100644 --- a/doc/source/source_rst/software/installation.rst +++ b/doc/source/source_rst/software/installation.rst @@ -11,7 +11,9 @@ Step 3: Run the installation script =================================== Simply navigate to the OhmPi folder and run the following command on the terminal: + .. code-block:: bash + $ .install.sh The install script first creates an python virtual environment called "ohmpy" in which all dependencies will be installed. Dependecies are specified in requirements.txt @@ -20,20 +22,28 @@ It then installs a local MQTT broker which will be used to centralise all the co It also properly configures the I2C buses on the raspberry Pi. When the installation is performed, we need to add the OhmPi module to the environment by editing the PYTHONPATH or editing the .bashrc file as follows: + .. code-block:: bash + $ nano ~/.bashrc And add the following line: + .. code-block:: bash + $export PYTHONPATH=$PYTHONPATH:/home/<username>/OhmPi Step 4: Activate the ohmpy virtual environment ============================================== Before operating the instrument, we need to activate the ohmpy virtual environment with the following command: + .. code-block:: bash + $ cd ~/OhmPi $ source ohmpy/bin/activate If you need to leave the virtual environment, simply type: + .. code-block:: bash + $ deactivate \ No newline at end of file diff --git a/doc/source/source_rst/software/operations.rst b/doc/source/source_rst/software/operations.rst index cbe5b0a6..c19b404c 100644 --- a/doc/source/source_rst/software/operations.rst +++ b/doc/source/source_rst/software/operations.rst @@ -40,17 +40,17 @@ Once configured, the webserver should start by itself on start and once connected to the Pi, the user can go to `10.3.141.1:8080 <http://10.3.141.1:8080>`_ to access the interface. -.. figure:: ../img/http-interface-pseudo-section.png +.. figure:: ../../img/http-interface-pseudo-section.png Web interface with its interactive pseudo-section. -.. figure:: ../img/http-interface-evolution.png +.. figure:: ../../img/http-interface-evolution.png Evolution of quadrupole apparent resistivity with time. -.. figure:: ../img/http-interface-rs.png +.. figure:: ../../img/http-interface-rs.png Contact resistance check. @@ -195,20 +195,21 @@ This may help designing complex IoT experiments and monitoring systems in which Examples incorporating execution commands and data outputs from OhmPi can be found in the OhmPi examples. Once Node-RED is installed on the OhmPi, these examples can be accessed separately by running a command in the console such as : .. code-block:: console - node-red basic_ohmpi_flows_node-red.json -These examples may require installing some additional node packages in order to work properly. This can be done in the `Palette Manager <https://nodered.org/docs/user-guide/editor/palette/manager> within Node-RED. + node-red basic_ohmpi_flows_node-red.json -.. figure:: ../img/node-red_flow.png +These examples may require installing some additional node packages in order to work properly. This can be done in the `Palette Manager <https://nodered.org/docs/user-guide/editor/palette/manager>`_ within Node-RED. + +.. figure:: ../../img/node-red_flow.png Example flow in node-red to interact with an OhmPi. -.. figure:: ../img/node-red_interface_control.png +.. figure:: ../../img/node-red_interface_control.png Example of a dashboard UI created with node-red to interact with an OhmPi - control tab. -.. figure:: ../img/node-red_interface_data.png +.. figure:: ../../img/node-red_interface_data.png Example of a dashboard UI created with node-red to interact with an OhmPi - data visualization tab. -- GitLab