From fbab1fb6d8a357fed250e3c1688eec4ad3d851aa Mon Sep 17 00:00:00 2001 From: jonnew Date: Wed, 14 Aug 2024 17:16:52 -0400 Subject: [PATCH 1/6] Started creating breakout board tutorial - Need to finish documenting workflow - Need to add data loading scripts and explaination --- images/breakout-tut-0.png | Bin 0 -> 6475 bytes images/breakout-tut-1.png | Bin 0 -> 83913 bytes images/breakout-tut-2.png | Bin 0 -> 6942 bytes images/breakout-tut-3.png | Bin 0 -> 3691 bytes images/breakout-tut-4.png | Bin 0 -> 7291 bytes images/breakout-tut-5.png | Bin 0 -> 6383 bytes images/breakout-tut-6.png | Bin 0 -> 4030 bytes images/breakout-tut-7.png | Bin 0 -> 4662 bytes images/breakout-tut-8.png | Bin 0 -> 2677 bytes tutorials/breakoutboard-tut.md | 73 +++++++ workflows/examples/BreakoutBoard.bonsai | 272 ++++++++++++++++++++++++ 11 files changed, 345 insertions(+) create mode 100644 images/breakout-tut-0.png create mode 100644 images/breakout-tut-1.png create mode 100644 images/breakout-tut-2.png create mode 100644 images/breakout-tut-3.png create mode 100644 images/breakout-tut-4.png create mode 100644 images/breakout-tut-5.png create mode 100644 images/breakout-tut-6.png create mode 100644 images/breakout-tut-7.png create mode 100644 images/breakout-tut-8.png create mode 100644 tutorials/breakoutboard-tut.md create mode 100644 workflows/examples/BreakoutBoard.bonsai diff --git a/images/breakout-tut-0.png b/images/breakout-tut-0.png new file mode 100644 index 0000000000000000000000000000000000000000..d7015136ad71232b508e3c4f20d19afb2399c7ae GIT binary patch literal 6475 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 literal 0 HcmV?d00001 diff --git a/images/breakout-tut-2.png b/images/breakout-tut-2.png new file mode 100644 index 0000000000000000000000000000000000000000..81810319149c4d304d3e9b855cb2591a646b12d1 GIT binary patch literal 6942 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 JPDHLkV1oKb8&UuO literal 0 HcmV?d00001 diff --git a/images/breakout-tut-4.png b/images/breakout-tut-4.png new file mode 100644 index 0000000000000000000000000000000000000000..c1aa5a716f3227fc8632819deb9da6aaf92f7597 GIT binary patch literal 7291 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 literal 0 HcmV?d00001 diff --git a/images/breakout-tut-5.png b/images/breakout-tut-5.png new file mode 100644 index 0000000000000000000000000000000000000000..cdeaa543b27e469dc9ab6081354181e924adbc6a GIT binary patch literal 6383 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 literal 0 HcmV?d00001 diff --git a/images/breakout-tut-6.png b/images/breakout-tut-6.png new file mode 100644 index 0000000000000000000000000000000000000000..365879faa38b50baca1683b0ba7a51dce16e8f13 GIT binary patch literal 4030 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 literal 0 HcmV?d00001 diff --git a/images/breakout-tut-7.png b/images/breakout-tut-7.png new file mode 100644 index 0000000000000000000000000000000000000000..1c2d0c2c812ee6ae6490aa5f043035586cfad26d GIT binary patch literal 4662 zcmV-663Oj}P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf5z9$LK~#8N?VW#c z6y+JmpCbg3pTS57n0N`1G%1IofCjCY2)36-X=SL|@yCoNb#TV9c6yPS`Varq8BAuJ zc67=(VVEh-RHh8J)sz&0L`Dh@KNL8cloE1B1Va!_Fd~AOzTbD>z1!Q{z1vIfl6x=j zXJ&J|@9o~+?e6z|p7(j5_l;|iK?;RJ8perNg+d_-O0)`vWGK-p6q2Dtt58UW60JfZ z8A`MYg=8qvDio5Dw0_!?Uw%qgzyD5bX_V&{i8Vz$dQW~y*RFmqwlrp!=ZZB&JlcD| zr7PDWALZL-PZVpJ#gIkY|Lp)B{H&c0o%=5x?fsu9jpmja1+-{Z8CBf0fM!n05v7W6 z`oE>X!5#`8I!B)#?G>fb2(>+=@9gb><{ds`%p4HTrk(5?>B_R`hM)N*Pcy?gS*D9aj;y3w`BZxHjvTsSQkE!@ zlY~Uuejz}w9rz0u?oi1dH=dqd_;XsyEbmz3v-S)0{%Z%haED4(_BdMh>_RG8I!Ba@ z9gcibl83lm zK5&U)VN(Ix#=8Os#Fi%5=H_PFyLT^Lym(QR$_-p%SlCqHZ#hNnyMkgXGl5GC3!4hi zHh!=DE3qXHF-40AG1{=na*3^Y>v#(V`+N9$R#q0>eDlqG{nV*b{8eTUAx0ZESuU{^ z``Do?o@N+-A>0rrwNm?DQ8aNQFT-ZAHQ=#Y-JW(j`j~L=mheojHk_y z74Y^ef>35qA#6U}C${9kRqQp7q@69x83oHBHeKwV1Cr{$Dhrndy2wICvb&ProaFA?coS9-uvDCGx_^wvCGu9wH585 za~)!BWI%S6PEJk^WoKv8*I$24SFaAePjfUurjr$RT{Xyj0tj3I^vB-w^a6V7&7V-s z%S-w4_!|#!OKc@xSldhjnNDU9lrk>5b%YhwdEuU1ZduQL^&Q{mbf2^5$Lf6Pilu1L zjzuonaTnhQImkbHCOV@m(etJ&-43lI#EEo9v`Jx6f6c5cKwt@$RtNjN{YgJP z`Sz#O+G+nhIkn28jiqS&z8xL^9@bW8>eQ+HwZFfgzskg=zGy2E3w<{cnLaU`Tre=8xrLJ^$v1{{QjUGsj2X0NAy~9uvB1LWE^+BH%}q7}w-|yo z?x&L}L-rCGI;RJqAj%ECz7L^7N7uAbhL;V9?fZCZv?#S`)uYHV0gLB!mI*zn;(TYgZ5lk(LkG5K{p4_W;XXgT>8HHk7UISGy0CRn zp6gD3*UkwLT)xFD6Yu}3C}L@T#?ALdR}BJENXS5Y7G+x=FXa0`tUBl#Lc+zm2lAq3 zu|NfY_hrCRv|v$wxmX(+Zp)j;g$w%n`gl?W5-hN!I~Oiop#A&z^Wd2d+*m90?i(F* zQiTpIY0Il0MU*4xga8)?A($z=EsqN~Q@GoZAsp?<|!V&(qP-!AJPy=jYSJiE>PVX&eXK-QCS!!R-&no(=}lVz|n1 zgNH-B^T>)Zr+BF7$rb4LwM*Ja#(74Pn4*ORMBiyD!3>Q?i>|i|^^rcZP*kMN@r;p4 zsB{1!5Yn+SjE!ISPbclJyM&J^^ynH5IFKLBm+vQ^iM7!-o z8?}EP?vr#1GOZpdUom1)>CpnSNy5^?#b35;Swuh$qD5lFP{fOjr^SzyWo#SP2}qv6 z(7PjN6BjQsp3p{?tqp4?VbSVfUZ;=F9_KSo#G97p*1UOCF=sw4E4*ElWHv|)*|B2> zZ{I?&6%`eHB#RNuG|~0ZS^jEHM>JD#YaY$5m`$b23Pp(mV`x7(^)-KuH{=e96P0r( z^StCtV92610_%J7i|#1#mfu*++pgwz>sSE7-M4Qacas4|Dq+Nu6|lN?|1}S7*RjxU z9S*R*?dL51Yu+4f;x`%Ft+7aoXchJxKYpAq01;+P5nE8eDl!SuGZpEH672|pf#^tc z)aP+Vgc(^>g@uI~_3uv6yrw(r1%Edw1o^m3&>HaEcP`D1ZPJ1Ptuj zxeA3HO0)`vWW)(ewo$#yMXvhr|Jnh;jn(9GRnx}I{)cS}MOxyZFTqP*e>0P>PLOtP zZ4v7VC$!bGiVu~aSWI=GLr{UnuPAY@sLyY!Cs*}GcIRY67>$S}9gGFOSG_?Kz^ZI$ zSl&Ye4n*rAkEfBE^$!W|q^;y5Uu2%Y!Uo)cDr)7^z-mi?%GM7>xRq4nYoU%Vv1v&g zH8=XG#yq03vVjJ-*AoAK1;LF}EtPK{I`Sch5UOSH z&Do7!?{A_&gHc6ps@*tpnlP|>E3MH5)yM?T%Ujv;RkVgS@O@f+!gAx- zt*a>@j%{T&DI~@g53NOcLoL;=4ObfMAZ|_8)@uLfCY?bA*WxMBESx2g?w?jM1??*- z_Q2BCo#KJTz3`CF=Ormq%Z>*jU|H4a;*faF6x!DyExQI1?>*&G2w^Q3tK26^5s%~LHOEpUpI@V}0LX`%it(p8y&l^5Bz44aW z+r8k%_3XC=-iOdq)RZ{L1?CN)rc7@oz@YGO4jfd%2yY*ciE#xT?S2I-U znXLSVCh~fj^@qF69#Go~*Yfz$ppmM?v!y*>9%{vRa{Aq|pOs;VdAy&>Hi-Q_b@Y0h z>AGoq*KE9v{$5E<%ww7ExBzf|kHF^fy{s`n1Je zOKX{XRTNQ)h1;y*fEt2Rtlh8ez_G2Q(5_{*b5}`;u)gdvmJsdS*`c*(MVS+ZQ{j#_ zPQQDUVG!4Rc)uOi(9om8Ft)Yr?yKE7QQoM#(Cl3pa`UY8*&h`{UZ0qOLu4SOf8#;ezAM^2} zM(lg;^t(swXSi@qj>o;z4vD;O`hAExo@0MsEzijaKO^2jZ`A#b#Dza>=k$g()Lm7~ zb!M)GttD0{#t3qVR-sUYNT5xtP$<%YIHDDu#HI#1Z$J+<2NbTZqYi32B0H}6B1!N> zp-2V}ENzkp3?wBFHnQ&y9p-U`D_zd5LSc;q(Wd`^fy#yeHTl=8p@NDrfulBULIVbL zi^ttya}K9oj`cWsuo0gVFAo;|W?}>k_SZiHi`BU-_faV1z*!(F-hctyq55~~GS%7-7;u>MAB*99PFsBy zHTu?u@}k4XVdRTgHQ{6*g(4ksF4|ZF2An4Sn{k)0ilB}iTTg8XeNN;UOKvqqd)HmN zmONrul*?5_b$aiV;apvI`zRC=pwbu>3du;o(kc{+bU=w#p^ywET7^O~lxP(S$xxzI sC?rFPR-up#C0d0-GL&c)3aKFaKdh@!QhcOMr2qf`07*qoM6N<$f)V=xKmY&$ literal 0 HcmV?d00001 diff --git a/images/breakout-tut-8.png b/images/breakout-tut-8.png new file mode 100644 index 0000000000000000000000000000000000000000..8600dd7509aa1873d90a3c3ed1c8cf6acf5d159c GIT binary patch literal 2677 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 literal 0 HcmV?d00001 diff --git a/tutorials/breakoutboard-tut.md b/tutorials/breakoutboard-tut.md new file mode 100644 index 00000000..09e2fdab --- /dev/null +++ b/tutorials/breakoutboard-tut.md @@ -0,0 +1,73 @@ +--- +uid: breakout-tut +title: Breakout Board Tutorial +--- + +# Breakout Board Tutorial + +:::workflow +![BreakoutBoard](../workflows/examples/BreakoutBoard.bonsai) +::: + +In this example, we will explore the breakout board's functionality by demoing its capabilities. The workflow above can by copied and pasted int your bonsai editor using the clipboard icon in the top right. This workflow capures data from the analog and digital inputs on the breakout board and streams and streams them to disk. The analog and digital outputs are both driven by an internally generated ramp signals. The hardware memory use is monitored and saved. + +> [!TIP] +> If you want a less busy starting point for using the breakout board then have a look at the in the user guide. + +## Configuring the breakout board +We start by configuring the hardware using a configuration chain. This chain creates a hardware context using , adds a breakout board configuration using , and then starts acquisition using . + +![Breakout board configuration chain](../images/breakout-tut-0.png) + +- The operator determines the device driver and host-computer index that the system communicates through. The `Driver` property is to ["riffa"](https://github.com/open-ephys/liboni/tree/main/drivers/riffa), which is the name of the the PCIe device used by ONIX. In our case, we have a single ONIX system, the the `Index` property is set to 0. +- The operator is used to configure the breakout board. The configuration settings for the breakout board can be examined and edited by clicking on the operator to highlight it, which opens its property pane to the right of the editor. Expanding of the members of the property pane allows you to configure the operation of each device within the breakout board. In this demo, the breakout board properties are set to their default values with two exceptions: + - Analog channel 0 is set to be an Output by setting its `Direction0` property to `Output`. + - The MemoryMonitor is enabled by setting its `Enable` property to `True`. + ![Breakout board configuration settings](../images/breakout-tut-1.png){width=650px} +- The operator begins acquisition after the hardware has been configured. In this example, we are going to be capturing data from the breakout board only, so the rate of data being produced by the hardware will be relatively modest (~2.5 MB/s), and dominated by the analog inputs. We are using a `BlockReadSize` of 2048 bytes. This means that the data reading thread will block until 2048 bytes of data have been produced by the hardware. At 2.5 MB/s +the hardware will produce 2048 every 800 microseconds or so. This is a hard bound on the latency of the system. If lower latencies were required, the hardware would need to produce data more quickly or the `BlockReadSize` would need to be reduced. The and `BlockWriteSize` is also set to 2048 bytes. This determines the amount of memory that is preallocated for temporarily holding data before it is sent to hardware. It is less critical to performance unless the rat that data be written to the hardware is comparable to the rate that the hardware produces data, which is not a common scenario. +- Aside from the configuration operations, the output of the operator is timestamped and then saved to a CSV file. This file will contain the wall-clock time that data collection start along with metadata concerning important system configuration settings, such as the `BlockReadSize` and `BlockWriteSize`. + +## Streaming breakout board data +Following the configuration chain, the the remaining processing graphs of the workflow are used to capture from or send data to the breakout board. We will step through each of these. + +### Analog inputs + +![Breakout board analog input processing graph](../images/breakout-tut-2.png) + +The first processing graph captures data from the breakout board's analog inputs using which is configured as follows: +- The `DeviceName` is set to `BreakoutBoard/AnalogIO`. In our system, this is the only selection available in the drop down menue since only a single breakout board was configured in the configuration chain. +- The `BufferSize` is set to 50. This means that 50 samples will be collected from each of the the 12 analog inputs and packed into a that is propagated downstream (each frames will contain a 50-element `Clock` vector and a 12x50 `AnalogData` matrix). The analog inputs are sampled at 100 kHz per channel so this corresponds to 500 microseconds of data. That's lower than the minimal latency introduced by the `BlockReadSize` setting. Therefore, our choosen `BufferSize` will not impose a significant effect on processing latency: the buffer will be filled essentially every time hardware is accessed and propagated nearly instantly. +- The `DataType` is set to `Volts`. This means that samples will be represented as single-precision floating point voltages. +The sequence is split into `Clock` and `AnalogData` sequences, which contain the acquisition clock sample times and sample values, respectively (right-click the operator and select `Output` to examine and expand output types). Both of these streams are saved to disk using a `MatrixWriter`. The `AnalogData` is passed through is passed through a 1 kHz low-pass Butterworth filter for demonstration purposes. Note that although analog channel 0 is set to an output, it is still recorded. This provides a automatic and hardware-synchronized measurement of the output voltage being sent to channel 0. + +### Analog outputs + +![Breakout board analog output processing graph](../images/breakout-tut-3.png) + +A ~100 Hz timer is used to update analog output 0. If the value in the `ScalarBuffer` node is changed while the workflow is running, channel 0's voltage will be updated. + +### Digital inputs + +![Breakout board digital input processing graph](../images/breakout-tut-5.png) + +Digital input data is passed through `HasFlag` filters that can be used to determine if a certain digital input pin is logic-high or to check if a certain button has been depressed. + +### Digital outputs + +![Breakout board digital output processing graph](../images/breakout-tut-6.png) + +A ~10 Hz timer drives the digital output port with counter. The LEDs on the breakout board will show a binary count for 0 to 255 before the pattern repeats + +### Memory monitor + +![Breakout board memory monitor processing graph](../images/breakout-tut-7.png) + +### Heartbeat + +![Breakout board heartbeat](../images/breakout-tut-8.png) + +## Loading data + + + diff --git a/workflows/examples/BreakoutBoard.bonsai b/workflows/examples/BreakoutBoard.bonsai new file mode 100644 index 00000000..52ee53bf --- /dev/null +++ b/workflows/examples/BreakoutBoard.bonsai @@ -0,0 +1,272 @@ + + + + + + + riffa + 0 + + + + + BreakoutBoard + + BreakoutBoard/Heartbeat + 0 + true + 10 + + + BreakoutBoard/AnalogIO + 6 + true + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + Output + Input + Input + Input + Input + Input + Input + Input + Input + Input + Input + Input + + + BreakoutBoard/DigitalIO + 7 + true + + + BreakoutBoard/MemoryMonitor + 10 + true + 10 + + + + + + 2048 + 2048 + + + + + + + start-time_.csv + false + false + Timestamp + false + Timestamp,Value + + + + BreakoutBoard/AnalogIO + 50 + Volts + + + + Clock + + + + analog-clock_.raw + Timestamp + false + ColumnMajor + + + + AnalogData + + + + analog-data_.raw + Timestamp + false + ColumnMajor + + + + + 100000 + 1000 + 0 + 3 + LowPass + + + + Ramp Generator + + + + + PT0S + PT0.01S + + + + + 0.2 + + + + + + 20 + + + + + -10 + + + + + 12 + 1 + + + + + + + + + + + + + + + + + + + + + BreakoutBoard/AnalogIO + Volts + + + + + BreakoutBoard/DigitalIO + + + + digital-data_.csv + false + false + Timestamp + false + Clock,DigitalInputs,Buttons + + + DigitalInputs + + + + Pin0 + + + + Buttons + + + + Moon Square + + + + + PT0S + PT0.1S + + + + + 1 + + + + + + BreakoutBoard/DigitalIO + + + + + BreakoutBoard/MemoryMonitor + + + + memory-use_.csv + false + false + Timestamp + false + Clock,BytesUsed,PercentUsed + + + PercentUsed + + + + BreakoutBoard/Heartbeat + + + + Clock + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 62803606f53928e8ff4baf60084a06a3ad82500c Mon Sep 17 00:00:00 2001 From: jonnew Date: Tue, 20 Aug 2024 18:39:26 -0400 Subject: [PATCH 2/6] First draft of breakout board tutorial text - It still needs a data loading section --- tutorials/breakoutboard-tut.md | 55 ++++++++++++++++--------- tutorials/toc.yml | 2 + workflows/examples/BreakoutBoard.bonsai | 4 +- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/tutorials/breakoutboard-tut.md b/tutorials/breakoutboard-tut.md index 09e2fdab..05a5879e 100644 --- a/tutorials/breakoutboard-tut.md +++ b/tutorials/breakoutboard-tut.md @@ -4,70 +4,87 @@ title: Breakout Board Tutorial --- # Breakout Board Tutorial +In this example, we will explore the breakout board's functionality by demoing its capabilities. The workflow below can by copy/pasted into the Bonsai editor using the clipboard icon in the top right. This workflow captures data from the analog and digital inputs on the breakout board and streams them to disk. Additionally, the analog and digital outputs are driven using signals generated in the workflow and the hardware memory use is monitored and saved. In the following sections, we break this workflow into components and provide an explanation for each. :::workflow ![BreakoutBoard](../workflows/examples/BreakoutBoard.bonsai) ::: -In this example, we will explore the breakout board's functionality by demoing its capabilities. The workflow above can by copied and pasted int your bonsai editor using the clipboard icon in the top right. This workflow capures data from the analog and digital inputs on the breakout board and streams and streams them to disk. The analog and digital outputs are both driven by an internally generated ramp signals. The hardware memory use is monitored and saved. - > [!TIP] > If you want a less busy starting point for using the breakout board then have a look at the in the user guide. ## Configuring the breakout board -We start by configuring the hardware using a configuration chain. This chain creates a hardware context using , adds a breakout board configuration using , and then starts acquisition using . +We start by configuring the hardware using a configuration chain. This chain creates a hardware context using , adds a breakout board configuration using , and then starts acquisition using . Here we break down each of these operators. ![Breakout board configuration chain](../images/breakout-tut-0.png) -- The operator determines the device driver and host-computer index that the system communicates through. The `Driver` property is to ["riffa"](https://github.com/open-ephys/liboni/tree/main/drivers/riffa), which is the name of the the PCIe device used by ONIX. In our case, we have a single ONIX system, the the `Index` property is set to 0. -- The operator is used to configure the breakout board. The configuration settings for the breakout board can be examined and edited by clicking on the operator to highlight it, which opens its property pane to the right of the editor. Expanding of the members of the property pane allows you to configure the operation of each device within the breakout board. In this demo, the breakout board properties are set to their default values with two exceptions: - - Analog channel 0 is set to be an Output by setting its `Direction0` property to `Output`. - - The MemoryMonitor is enabled by setting its `Enable` property to `True`. - ![Breakout board configuration settings](../images/breakout-tut-1.png){width=650px} -- The operator begins acquisition after the hardware has been configured. In this example, we are going to be capturing data from the breakout board only, so the rate of data being produced by the hardware will be relatively modest (~2.5 MB/s), and dominated by the analog inputs. We are using a `BlockReadSize` of 2048 bytes. This means that the data reading thread will block until 2048 bytes of data have been produced by the hardware. At 2.5 MB/s -the hardware will produce 2048 every 800 microseconds or so. This is a hard bound on the latency of the system. If lower latencies were required, the hardware would need to produce data more quickly or the `BlockReadSize` would need to be reduced. The and `BlockWriteSize` is also set to 2048 bytes. This determines the amount of memory that is preallocated for temporarily holding data before it is sent to hardware. It is less critical to performance unless the rat that data be written to the hardware is comparable to the rate that the hardware produces data, which is not a common scenario. -- Aside from the configuration operations, the output of the operator is timestamped and then saved to a CSV file. This file will contain the wall-clock time that data collection start along with metadata concerning important system configuration settings, such as the `BlockReadSize` and `BlockWriteSize`. +### CreateContext +The operator determines the device driver and host-computer index that the system communicates through. The `Driver` property is set to "riffa", which is the name of the the PCIe device used by ONIX. In our case, because we are using a single ONIX system, the the `Index` property is set to 0. If second system was used on the same computer, a second operator would be required and its `Index` property set to 1. + +### ConfigureBreakoutBoard +The operator is used to configure the breakout board. Configuration settings for the breakout board can be examined and edited by clicking on the operator to highlight it and open its property pane to the right of the editor. Expanding of the members of the property pane allows you to configure each of the devices within the breakout board. In this demo, the breakout board properties are set to their default values with two exceptions: +- `AnalogIO` channel 0 is configured as an output by setting its `Direction0` property to `Output` +- The `MemoryMonitor` is enabled by setting its `Enable` property to `True` + +![Breakout board configuration settings](../images/breakout-tut-1.png){width=650px} + +Aside from the configuration operations, the output of the operator is timestamped and then saved to a CSV file. This file will contain the wall-clock time that data collection start along with metadata concerning important system configuration settings, such as the `BlockReadSize`, `BlockWriteSize`, `AcquisitionClockHz` (rate of clock that produces all `Clock` values in the workflow), etc. + +### StartAcquisition +The operator begins acquisition after the hardware has been configured. In this example, we are going to be capturing data from the breakout board only, so the rate of data being produced by the hardware will be relatively modest (~2.5 MB/s), and dominated by the analog inputs. We are using a `BlockReadSize` of 2048 bytes. This means that the data reading thread will block until 2048 bytes of data have been produced by the hardware. At 2.5 MB/s the hardware will produce 2048 bytes every 800 microseconds or so. This is a hard bound on the latency of the system. If lower latencies were required, the hardware would need to produce data more quickly or the `BlockReadSize` would need to be reduced. The `BlockWriteSize` is also set to 2048 bytes. This determines the amount of memory that is preallocated for temporarily holding data before it is sent to hardware. It is less critical to performance unless the rate that data be written to the hardware is comparable to the rate that the hardware produces data, which is not a common scenario. ## Streaming breakout board data -Following the configuration chain, the the remaining processing graphs of the workflow are used to capture from or send data to the breakout board. We will step through each of these. +Following the configuration chain, the the remaining processing graphs of the workflow are used to capture data from, or send data to, the breakout board. We will step through each of these. + +> [!TIP] +> When trying to understand a workflow's operation, its very useful to visualize the data that being generated by each operator. You can open an operator's visualizer by double clicking the operator while the workflow is running. The type of visualizer that opens well depend on the type of data handled by the operator and whether or not the appropriate Design library has been installed. ### Analog inputs ![Breakout board analog input processing graph](../images/breakout-tut-2.png) -The first processing graph captures data from the breakout board's analog inputs using which is configured as follows: -- The `DeviceName` is set to `BreakoutBoard/AnalogIO`. In our system, this is the only selection available in the drop down menue since only a single breakout board was configured in the configuration chain. -- The `BufferSize` is set to 50. This means that 50 samples will be collected from each of the the 12 analog inputs and packed into a that is propagated downstream (each frames will contain a 50-element `Clock` vector and a 12x50 `AnalogData` matrix). The analog inputs are sampled at 100 kHz per channel so this corresponds to 500 microseconds of data. That's lower than the minimal latency introduced by the `BlockReadSize` setting. Therefore, our choosen `BufferSize` will not impose a significant effect on processing latency: the buffer will be filled essentially every time hardware is accessed and propagated nearly instantly. +The first processing graph captures data from the breakout board's analog inputs using a operator which is configured as follows: +- The `DeviceName` is set to `BreakoutBoard/AnalogIO`. In our system, this is the only selection available in the drop down menu since only a single breakout board was configured in the configuration chain. +- The `BufferSize` is set to 50. This means that 50 samples will be collected from each of the the 12 analog inputs and packed into a that is propagated downstream (each frames will contain a 50-element `Clock` vector and a 12-channel x 50-sample `AnalogData` matrix). The analog inputs are sampled at 100 kHz per channel so this corresponds to 500 microseconds of data. That's lower than the minimal latency introduced by the `BlockReadSize` setting. Therefore, our chosen `BufferSize` will not impose a significant effect on processing latency: the buffer will be filled essentially every time hardware is accessed and propagated instantly. - The `DataType` is set to `Volts`. This means that samples will be represented as single-precision floating point voltages. -The sequence is split into `Clock` and `AnalogData` sequences, which contain the acquisition clock sample times and sample values, respectively (right-click the operator and select `Output` to examine and expand output types). Both of these streams are saved to disk using a `MatrixWriter`. The `AnalogData` is passed through is passed through a 1 kHz low-pass Butterworth filter for demonstration purposes. Note that although analog channel 0 is set to an output, it is still recorded. This provides a automatic and hardware-synchronized measurement of the output voltage being sent to channel 0. +The sequence is split into `Clock` and `AnalogData` sequences (right-click the operator and hovering over `Output` in the context menu to examine and expand output types), which contain the acquisition clock sample times and sample values, respectively . Both of these streams are saved to disk using a `MatrixWriter`. The `AnalogData` is passed through is passed through a 1 kHz low-pass Butterworth filter, after the raw data is saved, for demonstration purposes. Note that although analog channel 0 is set to an output, its voltage is looped back and recorded. This provides a automatic and hardware-synchronized measurement of the output voltage being sent to channel 0. ### Analog outputs ![Breakout board analog output processing graph](../images/breakout-tut-3.png) -A ~100 Hz timer is used to update analog output 0. If the value in the `ScalarBuffer` node is changed while the workflow is running, channel 0's voltage will be updated. +This portion of the workflow generates an ramping analog signal and sends it to each of the analog outputs using a operator. The `RampGenerator` is a [`GroupWorkflow`](https://bonsai-rx.org/docs/articles/editor.html#workflow) that contains an number of Bonsai operators. You can look at how it works hitting Ctrl + Enter when the operator is highlighted to expand the internal workflow in a new tab. The `RampGenerator` contains a ~100 Hz timer that is used to create an array of 12 ramping voltage values, one for each channel. Although a voltage ramp is sent to all the channels, only channel 0 was selected to be a output, so this is the only channel that will be affected. If other channels are configured as outputs (see [ConfigureBreakoutBoard](#configurebreakoutboard)), then they will also ramp their voltage. ### Digital inputs ![Breakout board digital input processing graph](../images/breakout-tut-5.png) -Digital input data is passed through `HasFlag` filters that can be used to determine if a certain digital input pin is logic-high or to check if a certain button has been depressed. +The 8-bit, 5-V tolerant digital input port along with the breakout board's button and switch states are captured using a operator. The digital inputs are sampled at 5 MHz. However, they will only produce data when a change in state occurs (e.g. a digital input pin toggles from logic low to logic high or a button is pressed). Whenever a change in digital state occurs data will be propagated and saved by the `CsvWriter`. Because the `CsvWriter` is a [Sink](https://bonsai-rx.org/docs/articles/operators.html#sink), the produced by the operator will pass right through it and can be expanded by right-click the operator and hovering over `Output` in the context menu. In this case we have exposed `DigitalInputs` and `Buttons`, which represent the 8-bit digital input port state and the button/switch state, respectively. Each of these outputs is followed by a `HasFlag` filter that is used to determine if a certain digital input pin is logic-high (Pins 0, 1, and 7 in this example) or to check if a certain button (☾ or □ in this example) has been depressed. ### Digital outputs ![Breakout board digital output processing graph](../images/breakout-tut-6.png) -A ~10 Hz timer drives the digital output port with counter. The LEDs on the breakout board will show a binary count for 0 to 255 before the pattern repeats +The 8-bit digital output port is updated using a operator. A ~10 Hz timer is used to drive a counter. Although this produced a 32-bit integer that counts from 1 to 2147483647, operator will only use the lower 8-bits to update the digital output state. This can be seen reflected on the LEDs on the breakout board will show a binary count for 0 to 255 before the pattern repeats. ### Memory monitor ![Breakout board memory monitor processing graph](../images/breakout-tut-7.png) +The hardware first-in-first-out (FIFO) memory use is monitored using 8-bit digital output port is updated using a operator. A snapshot of the hardware FIFO's use is taken at regular intervals at a rate determined in the configuration [breakout board configuration](#configurebreakoutboard). The s are saved and re-emitted by a produced by a `CsvWriter`. They can then be expanded by right-click the operator and hovering over `Output` in the context menu, in this case to access the `PercentUsed`, which shows the amount of the percent of hardware FIFO that occupied by data. This is a diagnostic data stream that is most useful in the context of closed-loop performance. It tells the user if data is being consumed rapidly enough by the host PC to keep up with data production by the hardware. The hardware FIFO is a buffer that is required to deal with the fact that computers with normal operating systems cannot perform operations with strict regularity. When there are hiccups in acquisition, the hardware FIFO picks up the slack, but should then be cleared immediately. To get the lowest latencies, the `BlockReadSize` should be as small as possible *while the memory use percentage remains around 0%*. + +> [!WARNING] +> If the hardware FIFO's `PercentUsed` is non-zero for long time periods, or is increasing, the `BlockReadSize` is setting is too small (see [StartAcquisition](#startacquisition)). A small `BlockReadSize` will mean that the host computer does not have to wait long for enough data to become available to propagate it forward, but will reduce overall bandwidt by increasing the frquency at which the host computer checks if data is available and performs hardware reads. + ### Heartbeat ![Breakout board heartbeat](../images/breakout-tut-8.png) +Finally, heartbeat data is monitored using a operator, which produces xref:OpenEphys.Onix1.HeartbeatDataFrames> at a regular interval defined in [breakout board configuration](#configurebreakoutboard). + ## Loading data +> [!TODO] +> Python script for loading the data produced by this workflow diff --git a/tutorials/toc.yml b/tutorials/toc.yml index 838b74b5..62cb74b7 100644 --- a/tutorials/toc.yml +++ b/tutorials/toc.yml @@ -1,4 +1,6 @@ - href: landing-page.md +- name: Breakout Board + href: breakoutboard-tut.md - name: Headstage64 href: headstage64-tut.md - name: NeuropixelsV1e diff --git a/workflows/examples/BreakoutBoard.bonsai b/workflows/examples/BreakoutBoard.bonsai index 52ee53bf..717dfad3 100644 --- a/workflows/examples/BreakoutBoard.bonsai +++ b/workflows/examples/BreakoutBoard.bonsai @@ -67,7 +67,7 @@ - 2048 + 4096 2048 @@ -192,7 +192,7 @@ - Pin0 + Pin0 Pin1 Pin7 From 0ebc29525246667642e92be8a4610d4d2f66b4fd Mon Sep 17 00:00:00 2001 From: jonnew Date: Wed, 21 Aug 2024 15:59:31 -0400 Subject: [PATCH 3/6] Address breakotu board tutorial review comments - Replace pngs of partial workflows with svgs - Fixe many typos, etc --- images/breakout-tut-0.png | Bin 6475 -> 0 bytes images/breakout-tut-2.png | Bin 6942 -> 0 bytes images/breakout-tut-3.png | Bin 3691 -> 0 bytes images/breakout-tut-4.png | Bin 7291 -> 0 bytes images/breakout-tut-5.png | Bin 6383 -> 0 bytes images/breakout-tut-6.png | Bin 4030 -> 0 bytes images/breakout-tut-7.png | Bin 4662 -> 0 bytes images/breakout-tut-8.png | Bin 2677 -> 0 bytes images/breakout-tut_analog-input-graph.svg | 3 + images/breakout-tut_analog-output-graph.svg | 3 + images/breakout-tut_config-chain.svg | 3 + ...-1.png => breakout-tut_device-options.png} | Bin images/breakout-tut_digital-input-graph.svg | 3 + images/breakout-tut_digital-output-graph.svg | 3 + images/breakout-tut_heartbeat-graph.svg | 3 + images/breakout-tut_mem-monitor-graph.svg | 3 + images/breakout-tut_ramp-gen.svg | 3 + tutorials/breakoutboard-tut.md | 55 +++++++++++------- workflows/examples/BreakoutBoard.bonsai | 2 +- 19 files changed, 58 insertions(+), 23 deletions(-) delete mode 100644 images/breakout-tut-0.png delete mode 100644 images/breakout-tut-2.png delete mode 100644 images/breakout-tut-3.png delete mode 100644 images/breakout-tut-4.png delete mode 100644 images/breakout-tut-5.png delete mode 100644 images/breakout-tut-6.png delete mode 100644 images/breakout-tut-7.png delete mode 100644 images/breakout-tut-8.png create mode 100644 images/breakout-tut_analog-input-graph.svg create mode 100644 images/breakout-tut_analog-output-graph.svg create mode 100644 images/breakout-tut_config-chain.svg rename images/{breakout-tut-1.png => breakout-tut_device-options.png} (100%) create mode 100644 images/breakout-tut_digital-input-graph.svg create mode 100644 images/breakout-tut_digital-output-graph.svg create mode 100644 images/breakout-tut_heartbeat-graph.svg create mode 100644 images/breakout-tut_mem-monitor-graph.svg create mode 100644 images/breakout-tut_ramp-gen.svg diff --git a/images/breakout-tut-0.png b/images/breakout-tut-0.png deleted file mode 100644 index d7015136ad71232b508e3c4f20d19afb2399c7ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6475 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 JPDHLkV1oKb8&UuO diff --git a/images/breakout-tut-4.png b/images/breakout-tut-4.png deleted file mode 100644 index c1aa5a716f3227fc8632819deb9da6aaf92f7597..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7291 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 diff --git a/images/breakout-tut-5.png b/images/breakout-tut-5.png deleted file mode 100644 index cdeaa543b27e469dc9ab6081354181e924adbc6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6383 zcmb7pcUV*H($PCAhL+|vbuDi1Q4T_+)>MP6s-<-X4?~2R zb{2LSWCLV-mv%!m<~JV>X5A8Ix;dw&@a}EnZ(0FiR&jVlf=jL~3phUvsY4r04FC!V zbNye0c}i_B4hWxT2hYDE6LAj$4}y;e2SeKQf}fQKuUiMMB$1?@zgz05Ho~DA-eNM@ zPnnwV5sf?bp|sNkS+(EUXD!4hJG0ot;5RShHBQF1-u>|7X2MSpHiC7-|7;S(X5ELH z*VKb{p8e6kR6d7YiQ5iZ#n$YVpZyf#2>%mngZ(F4^*Ai>xI@D+N0{G|s075!JlA-t zdw#5QyyQT10hp(#H3TcNG&n5}ZZ&R?3$4r+*qog9AK8MeroN5e4qE2b2WL5n%Zm1t)_^v@uo`>8Sl;zN%n{}rLkVAZT? z^onNK-5=SAx9ePz>u8S0P9icK4!bsbH6B+{!oKv}!U8w7>B2Hh$ zoymne8)YVjd9C{MDmWb26xrs52aTwgBBJJ9efqW>TUZ=i`gm>ILU#V~kyvAX19M9*X)a9VCu#=NlPr<58o9?>hi#r;=-l}9A zP9a3pvB9aG1G*YSY@3%op(5NTt4QT*@jmh1)}HfKufpOv*g*_`Y9orIIyj{lx?;Jb zZFz1z0~tm$T}VY7M>$aMLsfYaC#!a{3^sc!G;I8#++8lQbPSe{ zafb@Ih-Nhs6sBdXW647BtVgwi7QoZ#m4af2^)5+XeoY41NgUs=l9#;f@!2-0w`yYr z(axq<;%PcKB~NrB4Dk`ZSzd&1XZ1P3-%mSn`#BPD&Vk3#29w2^sP1?^D5ZO-2G&bG z#`%~^$7t9!DxVV1RMq|ythEgM)p&-ej&)T{b%`xPM2-BgEZSu>=8eu}cCyQ$(~Lk3 zK3mjcyHn!E+TJw^!u->6a-iFqqaLivf@yAU28r^c!8yxd?*ZB5wBAQ+He>fJ ztEJhpiULX)FNr3mYB>Hrik%Z#tD+#UmV~6}Q#JYi^H?jL*;VVC@2>=&DPG+O)p+7` zr8@o*07&g~pJaP&P1URU$Wjm<$;5ZpI?^LEGjq!HeeRAvee?~j_jxverjsPt!Lk5E ze`Q2;K&K_gC<3bT;;Ep|C*hki9hS^tct!BNL2A#5%GuI*+zg{w{G=*jgo5ze>eKq`Vc)HpD8O$faTE|Y<8s_(hVxi%}N&j z(_6TVKRqzL+pb18$>oeb zK$OCxL1CodLOY5C!?0F43X;h`!_4#2Ik!+>V|-2QSI_s(Y@(g29((?B{6YIW9mZl+ zI~P3PfUKTKkNy)0o|I^Da)|N%B6ENUuKLxT zRWUR;#uS*nOoCpSkj#vvth%HZ?k~VZY1nFp`MAueTH39dLWIma9kwVIl@_m#d9wZ; zU8^z_Kg^y|&QP$v6LN!R40xsjQrrpB3Ztu*HcjL+&N@9M3aZQOfCON}Y*MjVzIhs5WrV6w@f7sq)_>^ZRd-F#%}d zD(qeRY%!d190PEzE^`Y+mKf5HQCs3;tLB3smQG|`22gHRI3gjB*u@nuBDB~I?g?cU zi;jRKS8gevUBAccibdTSK3;0cwIzqBrGBaPoSS{2GE-ofAp`#)P(02xy!l2HW8F<} z8ZRPa?{Y&Bnen{6Cf)ZZEKG+*?!#?SytoUmwg|nNbRr4qqP=;wson#(UBBP=f)dG+ri(k?R zDFwqwF=ACL7|)pJ=Eq;~O}r;cQqlW1yMr+TH%NAe@^eZP<7GRq=#l z$}7$S%BGumY{4_*$TBLpd@afxhx}wq15CVVGReWqBm~bU>(^% z`*j^T%bKafC^TCp7H*N7BVCs#Xu+1sA$Qmvv({@HC3jkpYO7^F4U~?$Vu|8pW4?6Q ztW|r+C4b8xvadKtH16%+hv?Eb9z{dVv=xTqFXXv$O{i%I@`sx7)8{(SuVM{xpaZF9hVfSFN%eiuD9lH9eEWq4^(@# zoS5W=2V;6zhoT(uVp;x@E@kZ|-Ie#WXD|Pew2!HdDAZVjHz!VF?cN;1Z~fR{Z6tEh zr;;sbDO3$M?2w8ih+X#lkG9nyU#xcRZjIAqc?!+AmjAHP;R?ll5*fV=4=6cACd3Uj zziKITbD1r1tHzzBuK?Mqa9)qwM)}v;85X z#r>p>rUFUF=%|^Qo$?RGUIbVl_1{^{>k7wLC;kYUG&x;I;M`qTR$WP z2L^%x0OVU%GwscDy9PLSC$AS^_D_=uQ!iDI4JMJ}8w58VqTq`8-jp2xD4A(F7VZDR zODzgf-sHX8lU7=lmQ9e&Njj@Ei4zuVX)yiXmuYzpuGh}r%Jlh7L2ydM=|9X-JuB@| zXcF)L$iL3(0ibek|7#C9*Whrj4!V}B?hiEqC&GC}dgyRs>z+cP_u^n7)^{tEH5FL3 zOuHWxug)pD-@McxY@z~NwDNIxCpkI0y_biR?+v~WJZVqsuu=cbJM-ho=NspBC#Mu0 z<@`l~;>LGJ4}9Lj<>H@j>%jsJya7%h31Vw(p=UM;`Y)EHG#;MHs5#FOCyu<>`a^%+ z{6OFsno*T0ZDQE^Y+LVdSOmqa-5eSh23aE6iJGkaaiac0Yg-J9(zHDLz31j#ht%nK zg(q#*5G(PfilKrhudav6OMd^`TCRWWOt)cO8-!~}&kl7JpIbg1m!qr*b)P>$`^hSuP4~&Y zitiVP4pz;77Oe9cS8~&IXzPQv-fG2z1LhY8=*4n$1KjwEycgU1-S1f672{~&!TZRD z`Si&I$yrt9yM%feK$P^M8VbFcs`ir3;;=J_msDt5Br22XhQ!7R(|KPR{;M{{?uVyD zWARz-q)_@44`fPr3k-iCyEJ)r9ORbDR2i$hs3bI05l=xr8xMqxsf=3 z+9s*&AImj-KO!Z2QL$oCinow35J@p~z$up91p6}eYb#7KCaBEUb=b%^X97ZVm)`}3 z@I6XDJvvv*nLZV><@V}vzmq-JB-S_C!UH}x{Ek%b*^BR&l+`{JFfX?W2?(um{TZ2J zbBzc#*1J45^e8#;n&ZNOEANNfDDQm*)|Iy5=R#sqOP_~oY;NCV5?*NjVC%0; z@px0|@GX1ryJ9abEFtU~>n(5lD@r zfGdMHo5kLEg!y#W-woDi7G3hLCUA^axh_G!CwbGi7slxp!K{gvm3{AuQ9;b=<*yyg zLrQjLK+WU|l;~Qmd%dit#-1+{N715d-_Z=C^bd_F)~S2;WU#Pk47X0i$K56VfCSug zoQCfEE5}Syyak~TECa3<=McOTjYn&t>)LICTE8DIGTARE6*acA$=^#mEoY%ZQ%1W= zEP)GEs{RzDkg;Q?YoEr7!wcX1NV_NcPkzAr#>c)Br_Wq*jOK3iG}GS-Iqc8d0P^Z? zw3epV-`uS!R&xR`^ySMoe^A|cLBi3FT!JO19GHSa$b5i2~=EV$9yGeUCy{k zN$-k)6m$x5M8qJFDKWj3ltuiS>==PCad!s?hwCk+da3bUNYv{b`Y<3G`DEUwhRU5Q zkt!p>hZZ>cFNBfEPs|+;4Bmq1l_*PpczicSivV4*@MZ7B;$0f49xZw8%4I5hxs~C_ zVt??RhDcN3P4W9|puwg4yqr#n;rRu$=olXS=J`drBn`%q78jPOeHi2>6B4kwwu$v^ zl9%BFVSmq2w#hoU2&4{>^s!iD0{{`}Y+`r65C{Yhbiy`C7quW5S}02b<;s_2`85gv z(3R>AqL7IsP$GFM&$CUO&`d^M_Lte$Z9pP*?xRQ(E<=)9F5K%YG$g6{U8s=^O^_z% zLPOOqFmPsTbJNi(qLzXR?R$yiROq2*n_yO3QL_GwNu}PS>wSWrB)(*|i=%7lNE(2A z5dLJn%<6M>^5Y-%e?A0mWkCUV*4fZRl6jv7_~H(3D{y;tFmn4A_fEr*nzx+G+{x0d z?GHYDU!H5=wMoku_D6hF=tHoTp+u}ssv+kE_4&vIfj+os*KZ8~a4ohJ zR?$#aR_0NvUgBX{gc##h4_2G$_;NMrB05-x%zotmyclp1hCxzM@<>~wOHO|Pag6Af+Bs4>k zPYE2qq?RIMrTeP!G~q4t9Ea}YP4`3aeGC2dO#e2pq!_Q!zK7;K3k(dLvb_5L(`@Uu z3DUG|Kw_~`17i<>^0XGbO z4p}Dr9Kx;z*$1DJK)4(;e6No)*3$woH@uig3or#1za@jfS3Puj740HEiVApu2HI86 z-D{W(F-%0$%APQm*VWAbubu6M19quCBpKpLeqZ4w>xQSF`HiA#`JGk0dg46hjQXOo z0`QZsjuuGZ-ZWu$TIhx;{b#3nLs@w?Pdk#@OXaSy8F8SxL4C`i;W8DP;c^Rwe`;3! z;nQ88Rfh6gC+q`Va>HYx7NSu4jVN2b3m&zxykK>D%Wxl}tI$a&^w|&clDNl881FMqysWcK}9TVUO^I%)axWzE$JUVeW61Bke!uPh3V0@K{ zQoKo5Dcyv8uRNraW-Y`TZgVjlt^9&w9V2Br0ms#rsxF6K+S4lLeZEe8K>-#KkFx>w zm}K1yuRNB+zt~cv`KSgQNK3C-U85CC+=8`o_NPoxBLU}8hEAzEZRkCLCoX{Y_=&Sh zbpnY?;YFnP(HJu8SnJ_2lES>7BYW4PL%mbk|Iu~2drQ$wi-)qNmL(-yuvk8PLpZYeVc9JglXj;|UWb$95 z5fD;JV`gP!2Z8kzO)6;xMo5|Me+cDmZ_G~jy|yx~YrtkU>pD{qNyWAsrnVuuqPwr} zqoGXizZLmI8y?cwu7@m5`)!m;JudrLw^iO~@j(SgEGndL0|ccab@b|yo8=Xjx(Id< z6%{&xcTb8|5HwC{nm4h`C0L<&$uL8*)cvtEQKL+cxv@z?D92dx{!Ooj9gwGeis`KF zTLHMrbHBKnp;=NHLvLC6ps8q7Y+|f}L>k-IS7=goVa2w_=X5&o2Czsb0-?Xu2f1#j zdlRK6Gp$#)*)rxa@-}$;PJlP#ZKB)0yIGG}L4X%&s1(Kc*ldXYmws-5rHlzO=vS!= zsxQUD;8SK#rC`22*C34EUCYpuU3p;;F6@enGIH%GJ|>xm4RFJp~05 zQySw>woAWr&{>u|XuC61{1&c=EQ)yi)0NYN%EJBa^B_ zqN`3{e_{qJGbnWKJAji-g~rC#_x|2ByYZFBDQR|5ru7dTlN5soE((~4Yh)+wZ`C(T y=t&rl(xYgf+aEy6{tr<9Z}I<6A>ANB<6Xqgjc+6VtE8V4WcoUHA?09OI%l diff --git a/images/breakout-tut-6.png b/images/breakout-tut-6.png deleted file mode 100644 index 365879faa38b50baca1683b0ba7a51dce16e8f13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4030 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 diff --git a/images/breakout-tut-7.png b/images/breakout-tut-7.png deleted file mode 100644 index 1c2d0c2c812ee6ae6490aa5f043035586cfad26d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4662 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 diff --git a/images/breakout-tut-8.png b/images/breakout-tut-8.png deleted file mode 100644 index 8600dd7509aa1873d90a3c3ed1c8cf6acf5d159c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2677 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 diff --git a/images/breakout-tut_analog-input-graph.svg b/images/breakout-tut_analog-input-graph.svg new file mode 100644 index 00000000..9e26e4dc --- /dev/null +++ b/images/breakout-tut_analog-input-graph.svg @@ -0,0 +1,3 @@ + +]>MatrixWriterButterworthClockMatrixWriterAnalogDataBreakoutAnalogInput \ No newline at end of file diff --git a/images/breakout-tut_analog-output-graph.svg b/images/breakout-tut_analog-output-graph.svg new file mode 100644 index 00000000..b659b8cf --- /dev/null +++ b/images/breakout-tut_analog-output-graph.svg @@ -0,0 +1,3 @@ + +]>BreakoutAnalogOutputRamp Generator \ No newline at end of file diff --git a/images/breakout-tut_config-chain.svg b/images/breakout-tut_config-chain.svg new file mode 100644 index 00000000..6f379f65 --- /dev/null +++ b/images/breakout-tut_config-chain.svg @@ -0,0 +1,3 @@ + +]>StartAcquisitionCsvWriterTimestampBreakoutBoardCreateContext \ No newline at end of file diff --git a/images/breakout-tut-1.png b/images/breakout-tut_device-options.png similarity index 100% rename from images/breakout-tut-1.png rename to images/breakout-tut_device-options.png diff --git a/images/breakout-tut_digital-input-graph.svg b/images/breakout-tut_digital-input-graph.svg new file mode 100644 index 00000000..1e09c2f8 --- /dev/null +++ b/images/breakout-tut_digital-input-graph.svg @@ -0,0 +1,3 @@ + +]>HasFlagHasFlagDigitalInputsButtonsCsvWriterBreakoutDigitalInput \ No newline at end of file diff --git a/images/breakout-tut_digital-output-graph.svg b/images/breakout-tut_digital-output-graph.svg new file mode 100644 index 00000000..0ed8a246 --- /dev/null +++ b/images/breakout-tut_digital-output-graph.svg @@ -0,0 +1,3 @@ + +]>BreakoutDigitalOutputAccumulateIntTimer \ No newline at end of file diff --git a/images/breakout-tut_heartbeat-graph.svg b/images/breakout-tut_heartbeat-graph.svg new file mode 100644 index 00000000..1882fa80 --- /dev/null +++ b/images/breakout-tut_heartbeat-graph.svg @@ -0,0 +1,3 @@ + +]>ClockHeartbeatData \ No newline at end of file diff --git a/images/breakout-tut_mem-monitor-graph.svg b/images/breakout-tut_mem-monitor-graph.svg new file mode 100644 index 00000000..89c19ad2 --- /dev/null +++ b/images/breakout-tut_mem-monitor-graph.svg @@ -0,0 +1,3 @@ + +]>PercentUsedCsvWriterMemoryMonitorData \ No newline at end of file diff --git a/images/breakout-tut_ramp-gen.svg b/images/breakout-tut_ramp-gen.svg new file mode 100644 index 00000000..933da924 --- /dev/null +++ b/images/breakout-tut_ramp-gen.svg @@ -0,0 +1,3 @@ + +]>WorkflowOutputConvertToArrayBufferCountAddModAccumulateFloatTimer \ No newline at end of file diff --git a/tutorials/breakoutboard-tut.md b/tutorials/breakoutboard-tut.md index 05a5879e..8141a58f 100644 --- a/tutorials/breakoutboard-tut.md +++ b/tutorials/breakoutboard-tut.md @@ -4,7 +4,14 @@ title: Breakout Board Tutorial --- # Breakout Board Tutorial -In this example, we will explore the breakout board's functionality by demoing its capabilities. The workflow below can by copy/pasted into the Bonsai editor using the clipboard icon in the top right. This workflow captures data from the analog and digital inputs on the breakout board and streams them to disk. Additionally, the analog and digital outputs are driven using signals generated in the workflow and the hardware memory use is monitored and saved. In the following sections, we break this workflow into components and provide an explanation for each. +In this example, we will explore the breakout board's functionality by demoing its capabilities. The workflow below can by copy/pasted into the Bonsai editor using the clipboard icon in the top right. This workflow: + +- Captures data from the analog and digital inputs on the breakout board and streams them to disk +- Generates signals to drive the breakout boards analog and digital outputs +- Monitors and saves hardware memory buffer use information. +- Monitors the breakout board's heartbeat signal + +In the following sections, we break this workflow into components and provide an explanation for each. :::workflow ![BreakoutBoard](../workflows/examples/BreakoutBoard.bonsai) @@ -14,71 +21,75 @@ In this example, we will explore the breakout board's functionality by demoing i > If you want a less busy starting point for using the breakout board then have a look at the in the user guide. ## Configuring the breakout board -We start by configuring the hardware using a configuration chain. This chain creates a hardware context using , adds a breakout board configuration using , and then starts acquisition using . Here we break down each of these operators. +We start by configuring the hardware using a configuration chain. This chain creates a ONIX acquisition context using , configures a breakout board using , and then starts acquisition using . Here we break down each of these operators. -![Breakout board configuration chain](../images/breakout-tut-0.png) +![Breakout board configuration chain](../images/breakout-tut_config-chain.svg) ### CreateContext -The operator determines the device driver and host-computer index that the system communicates through. The `Driver` property is set to "riffa", which is the name of the the PCIe device used by ONIX. In our case, because we are using a single ONIX system, the the `Index` property is set to 0. If second system was used on the same computer, a second operator would be required and its `Index` property set to 1. +The operator determines creates a "context" that determines the device driver, physical interface type, and host-computer index that the system communicates through. The `Driver` property is set to "riffa", which is the name of the PCIe device used by ONIX. In our case, because we are using a single ONIX system, the `Index` property is set to 0. If second system was used on the same computer, a second operator would be required and its `Index` property set to 1. ### ConfigureBreakoutBoard -The operator is used to configure the breakout board. Configuration settings for the breakout board can be examined and edited by clicking on the operator to highlight it and open its property pane to the right of the editor. Expanding of the members of the property pane allows you to configure each of the devices within the breakout board. In this demo, the breakout board properties are set to their default values with two exceptions: +The operator is used to configure the breakout board. Configuration settings for the breakout board can be examined and edited by clicking on the node to highlight it and open its property pane to the right of the editor. Expanding the members of the property pane allows you to configure each of the devices within the breakout board. In this demo, the breakout board properties are set to their default values with two exceptions: - `AnalogIO` channel 0 is configured as an output by setting its `Direction0` property to `Output` - The `MemoryMonitor` is enabled by setting its `Enable` property to `True` -![Breakout board configuration settings](../images/breakout-tut-1.png){width=650px} +![Breakout board configuration settings](../images/breakout-tut_device-options.png){width=650px} Aside from the configuration operations, the output of the operator is timestamped and then saved to a CSV file. This file will contain the wall-clock time that data collection start along with metadata concerning important system configuration settings, such as the `BlockReadSize`, `BlockWriteSize`, `AcquisitionClockHz` (rate of clock that produces all `Clock` values in the workflow), etc. ### StartAcquisition The operator begins acquisition after the hardware has been configured. In this example, we are going to be capturing data from the breakout board only, so the rate of data being produced by the hardware will be relatively modest (~2.5 MB/s), and dominated by the analog inputs. We are using a `BlockReadSize` of 2048 bytes. This means that the data reading thread will block until 2048 bytes of data have been produced by the hardware. At 2.5 MB/s the hardware will produce 2048 bytes every 800 microseconds or so. This is a hard bound on the latency of the system. If lower latencies were required, the hardware would need to produce data more quickly or the `BlockReadSize` would need to be reduced. The `BlockWriteSize` is also set to 2048 bytes. This determines the amount of memory that is preallocated for temporarily holding data before it is sent to hardware. It is less critical to performance unless the rate that data be written to the hardware is comparable to the rate that the hardware produces data, which is not a common scenario. -## Streaming breakout board data -Following the configuration chain, the the remaining processing graphs of the workflow are used to capture data from, or send data to, the breakout board. We will step through each of these. +## Streaming data +Following the configuration chain, the remaining processing graphs of the workflow are used to capture data from, or send data to, the breakout board. We will step through each of these. > [!TIP] -> When trying to understand a workflow's operation, its very useful to visualize the data that being generated by each operator. You can open an operator's visualizer by double clicking the operator while the workflow is running. The type of visualizer that opens well depend on the type of data handled by the operator and whether or not the appropriate Design library has been installed. +> When trying to understand a workflow's operation, its very useful to visualize the data that being generated by each operator. You can open an operator's visualizer by double clicking the node while the workflow is running. The type of visualizer that opens will depend on the type of data handled by the operator and whether or not the appropriate Design library has been installed. ### Analog inputs -![Breakout board analog input processing graph](../images/breakout-tut-2.png) +![Breakout board analog input processing graph](../images/breakout-tut_analog-input-graph.svg) The first processing graph captures data from the breakout board's analog inputs using a operator which is configured as follows: - The `DeviceName` is set to `BreakoutBoard/AnalogIO`. In our system, this is the only selection available in the drop down menu since only a single breakout board was configured in the configuration chain. -- The `BufferSize` is set to 50. This means that 50 samples will be collected from each of the the 12 analog inputs and packed into a that is propagated downstream (each frames will contain a 50-element `Clock` vector and a 12-channel x 50-sample `AnalogData` matrix). The analog inputs are sampled at 100 kHz per channel so this corresponds to 500 microseconds of data. That's lower than the minimal latency introduced by the `BlockReadSize` setting. Therefore, our chosen `BufferSize` will not impose a significant effect on processing latency: the buffer will be filled essentially every time hardware is accessed and propagated instantly. +- The `BufferSize` is set to 50. This means that 50 samples will be collected from each of the 12 analog inputs and packed into a that is propagated downstream (each frame will contain a 50-element `Clock` vector and a 12-channel x 50-sample `AnalogData` matrix). The analog inputs are sampled at 100 kHz per channel so this corresponds to 500 microseconds of data. That's lower than the minimal latency introduced by the `BlockReadSize` setting. Therefore, our chosen `BufferSize` will not impose a significant effect on processing latency: the buffer will be filled essentially every time hardware is accessed and propagated instantly. - The `DataType` is set to `Volts`. This means that samples will be represented as single-precision floating point voltages. -The sequence is split into `Clock` and `AnalogData` sequences (right-click the operator and hovering over `Output` in the context menu to examine and expand output types), which contain the acquisition clock sample times and sample values, respectively . Both of these streams are saved to disk using a `MatrixWriter`. The `AnalogData` is passed through is passed through a 1 kHz low-pass Butterworth filter, after the raw data is saved, for demonstration purposes. Note that although analog channel 0 is set to an output, its voltage is looped back and recorded. This provides a automatic and hardware-synchronized measurement of the output voltage being sent to channel 0. +The sequence is split into `Clock` and `AnalogData` sequences (right-click the node and hover over `Output` in the resulting context menu to examine and expand output types), which contain the -based sample times and sample values, respectively. Both of these streams are saved to disk using a `MatrixWriter`. For demonstration purposes, the `AnalogData` is passed through is passed through a 1 kHz low-pass Butterworth filter after the raw data is saved. Note that although analog channel 0 is set to an output, its voltage is looped back and recorded. This provides an automatic and hardware-synchronized measurement of the output voltage being sent to channel 0. ### Analog outputs -![Breakout board analog output processing graph](../images/breakout-tut-3.png) +![Breakout board analog output processing graph](../images/breakout-tut_analog-output-graph.svg) + +This portion of the workflow generates a ramping analog signal and sends it to each of the analog outputs using a operator. The `RampGenerator` is a [`GroupWorkflow`](https://bonsai-rx.org/docs/articles/editor.html#workflow) that contains a number of Bonsai operators. You can look at how it works hitting Ctrl + Enter when the node is highlighted to expand the internal workflow in a new tab: + +![The RampGenerator GroupWorkflow](../images/breakout-tut_ramp-gen.svg) -This portion of the workflow generates an ramping analog signal and sends it to each of the analog outputs using a operator. The `RampGenerator` is a [`GroupWorkflow`](https://bonsai-rx.org/docs/articles/editor.html#workflow) that contains an number of Bonsai operators. You can look at how it works hitting Ctrl + Enter when the operator is highlighted to expand the internal workflow in a new tab. The `RampGenerator` contains a ~100 Hz timer that is used to create an array of 12 ramping voltage values, one for each channel. Although a voltage ramp is sent to all the channels, only channel 0 was selected to be a output, so this is the only channel that will be affected. If other channels are configured as outputs (see [ConfigureBreakoutBoard](#configurebreakoutboard)), then they will also ramp their voltage. +The `RampGenerator` contains a ~100 Hz timer that is used to create an array of 12 ramping voltage values, one for each channel. Although a voltage ramp is sent to all the channels, only channel 0 was selected to be a output, so this is the only channel that will be affected. If other channels are configured as outputs (see [ConfigureBreakoutBoard](#configurebreakoutboard)), then they will also ramp their voltage. ### Digital inputs -![Breakout board digital input processing graph](../images/breakout-tut-5.png) +![Breakout board digital input processing graph](../images/breakout-tut_digital-input-graph.svg) -The 8-bit, 5-V tolerant digital input port along with the breakout board's button and switch states are captured using a operator. The digital inputs are sampled at 5 MHz. However, they will only produce data when a change in state occurs (e.g. a digital input pin toggles from logic low to logic high or a button is pressed). Whenever a change in digital state occurs data will be propagated and saved by the `CsvWriter`. Because the `CsvWriter` is a [Sink](https://bonsai-rx.org/docs/articles/operators.html#sink), the produced by the operator will pass right through it and can be expanded by right-click the operator and hovering over `Output` in the context menu. In this case we have exposed `DigitalInputs` and `Buttons`, which represent the 8-bit digital input port state and the button/switch state, respectively. Each of these outputs is followed by a `HasFlag` filter that is used to determine if a certain digital input pin is logic-high (Pins 0, 1, and 7 in this example) or to check if a certain button (☾ or □ in this example) has been depressed. +The 8-bit, 5-V tolerant digital input port along with the breakout board's button and switch states are captured using a operator. The digital inputs are sampled at 5 MHz. However, they will only produce data when a change in state occurs (e.g. a digital input pin toggles from logic low to logic high or a button is pressed). Whenever a change in digital state occurs data will be propagated and saved by the `CsvWriter`. Because the `CsvWriter` is a [Sink](https://bonsai-rx.org/docs/articles/operators.html#sink), the produced by the operator will pass right through it and can be expanded by right-clicking the node and hovering over `Output` in the resulting context menu. In this case we have exposed `DigitalInputs` and `Buttons`, which represent the 8-bit digital input port state and the button/switch state, respectively. Each of these outputs is followed by a `HasFlag` filter that is used to determine if a certain digital input pin is logic-high (Pins 0, 1, and 7 in this example) or to check if a certain button (☾ or □ in this example) has been depressed. ### Digital outputs -![Breakout board digital output processing graph](../images/breakout-tut-6.png) +![Breakout board digital output processing graph](../images/breakout-tut_digital-output-graph.svg) -The 8-bit digital output port is updated using a operator. A ~10 Hz timer is used to drive a counter. Although this produced a 32-bit integer that counts from 1 to 2147483647, operator will only use the lower 8-bits to update the digital output state. This can be seen reflected on the LEDs on the breakout board will show a binary count for 0 to 255 before the pattern repeats. +The 8-bit digital output port is updated using a operator. A ~10 Hz timer is used to drive a counter. Although this produced a 32-bit integer that counts from 1 to 2147483647, operator will only use the lower 8-bits to update the digital output state. This can be seen reflected on the LEDs on the breakout board will show a binary count from 0 to 255 before the pattern repeats. ### Memory monitor -![Breakout board memory monitor processing graph](../images/breakout-tut-7.png) +![Breakout board memory monitor processing graph](../images/breakout-tut_mem-monitor-graph.svg) -The hardware first-in-first-out (FIFO) memory use is monitored using 8-bit digital output port is updated using a operator. A snapshot of the hardware FIFO's use is taken at regular intervals at a rate determined in the configuration [breakout board configuration](#configurebreakoutboard). The s are saved and re-emitted by a produced by a `CsvWriter`. They can then be expanded by right-click the operator and hovering over `Output` in the context menu, in this case to access the `PercentUsed`, which shows the amount of the percent of hardware FIFO that occupied by data. This is a diagnostic data stream that is most useful in the context of closed-loop performance. It tells the user if data is being consumed rapidly enough by the host PC to keep up with data production by the hardware. The hardware FIFO is a buffer that is required to deal with the fact that computers with normal operating systems cannot perform operations with strict regularity. When there are hiccups in acquisition, the hardware FIFO picks up the slack, but should then be cleared immediately. To get the lowest latencies, the `BlockReadSize` should be as small as possible *while the memory use percentage remains around 0%*. +The hardware first-in-first-out (FIFO) memory use is monitored using 8-bit digital output port is updated using a operator. A snapshot of the hardware FIFO's use is taken at regular intervals at a rate determined in the configuration [breakout board configuration](#configurebreakoutboard). The s are saved and re-emitted by a `CsvWriter`. They can then be expanded by right-clicking the node and hovering over `Output` in the resulting context menu, in this case to access the `PercentUsed`, which shows the amount of the percent of hardware FIFO that occupied by data. This is a diagnostic data stream that is most useful in the context of closed-loop performance. It tells the user if data is being consumed rapidly enough by the host PC to keep up with data production by the hardware. The hardware FIFO is a buffer that is required to deal with the fact that computers with normal operating systems cannot perform operations with strict regularity. When there are hiccups in acquisition, the hardware FIFO picks up the slack, but should then be cleared immediately. To get the lowest latencies, the `BlockReadSize` should be as small as possible *while the memory use percentage remains around 0%*. > [!WARNING] -> If the hardware FIFO's `PercentUsed` is non-zero for long time periods, or is increasing, the `BlockReadSize` is setting is too small (see [StartAcquisition](#startacquisition)). A small `BlockReadSize` will mean that the host computer does not have to wait long for enough data to become available to propagate it forward, but will reduce overall bandwidt by increasing the frquency at which the host computer checks if data is available and performs hardware reads. +> If the hardware FIFO's `PercentUsed` is non-zero for long time periods, or is increasing, the `BlockReadSize` setting is too small (see [StartAcquisition](#startacquisition)). A small `BlockReadSize` will mean that the host computer does not have to wait long for enough data to become available to propagate it forward, but will reduce overall bandwidth by increasing the frequency at which the host computer checks if data is available and performs hardware reads. ### Heartbeat -![Breakout board heartbeat](../images/breakout-tut-8.png) +![Breakout board heartbeat](../images/breakout-tut_heartbeat-graph.svg) Finally, heartbeat data is monitored using a operator, which produces xref:OpenEphys.Onix1.HeartbeatDataFrames> at a regular interval defined in [breakout board configuration](#configurebreakoutboard). diff --git a/workflows/examples/BreakoutBoard.bonsai b/workflows/examples/BreakoutBoard.bonsai index 717dfad3..a3fbe681 100644 --- a/workflows/examples/BreakoutBoard.bonsai +++ b/workflows/examples/BreakoutBoard.bonsai @@ -67,7 +67,7 @@ - 4096 + 2048 2048 From c8919133b712fa2f31a690e993b449520bbd58e3 Mon Sep 17 00:00:00 2001 From: jonnew Date: Wed, 21 Aug 2024 16:09:34 -0400 Subject: [PATCH 4/6] Fix typos and text in breakout tutorial - This tutorial is still missing a data loadin script --- tutorials/breakoutboard-tut.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/breakoutboard-tut.md b/tutorials/breakoutboard-tut.md index 8141a58f..5f84a215 100644 --- a/tutorials/breakoutboard-tut.md +++ b/tutorials/breakoutboard-tut.md @@ -41,7 +41,7 @@ Aside from the configuration operations, the output of the operator begins acquisition after the hardware has been configured. In this example, we are going to be capturing data from the breakout board only, so the rate of data being produced by the hardware will be relatively modest (~2.5 MB/s), and dominated by the analog inputs. We are using a `BlockReadSize` of 2048 bytes. This means that the data reading thread will block until 2048 bytes of data have been produced by the hardware. At 2.5 MB/s the hardware will produce 2048 bytes every 800 microseconds or so. This is a hard bound on the latency of the system. If lower latencies were required, the hardware would need to produce data more quickly or the `BlockReadSize` would need to be reduced. The `BlockWriteSize` is also set to 2048 bytes. This determines the amount of memory that is preallocated for temporarily holding data before it is sent to hardware. It is less critical to performance unless the rate that data be written to the hardware is comparable to the rate that the hardware produces data, which is not a common scenario. ## Streaming data -Following the configuration chain, the remaining processing graphs of the workflow are used to capture data from, or send data to, the breakout board. We will step through each of these. +The rest of the workflow concerns capturing data from and sending to the breakout board, using a set of discrete "processing graphs" that either produce data from hardware (inputs/sources) or accept data produced by software (outputs/sinks). We describe these graphs in the following sections. > [!TIP] > When trying to understand a workflow's operation, its very useful to visualize the data that being generated by each operator. You can open an operator's visualizer by double clicking the node while the workflow is running. The type of visualizer that opens will depend on the type of data handled by the operator and whether or not the appropriate Design library has been installed. @@ -70,7 +70,7 @@ The `RampGenerator` contains a ~100 Hz timer that is used to create an array of ![Breakout board digital input processing graph](../images/breakout-tut_digital-input-graph.svg) -The 8-bit, 5-V tolerant digital input port along with the breakout board's button and switch states are captured using a operator. The digital inputs are sampled at 5 MHz. However, they will only produce data when a change in state occurs (e.g. a digital input pin toggles from logic low to logic high or a button is pressed). Whenever a change in digital state occurs data will be propagated and saved by the `CsvWriter`. Because the `CsvWriter` is a [Sink](https://bonsai-rx.org/docs/articles/operators.html#sink), the produced by the operator will pass right through it and can be expanded by right-clicking the node and hovering over `Output` in the resulting context menu. In this case we have exposed `DigitalInputs` and `Buttons`, which represent the 8-bit digital input port state and the button/switch state, respectively. Each of these outputs is followed by a `HasFlag` filter that is used to determine if a certain digital input pin is logic-high (Pins 0, 1, and 7 in this example) or to check if a certain button (☾ or □ in this example) has been depressed. +The 8-bit, 5-V tolerant digital input port along with the breakout board's button and switch states are captured using a operator. The digital inputs are sampled at 5 MHz. However, they will only produce data when a change in state occurs (e.g. a digital input pin toggles from logic low to logic high or a button is pressed). Whenever a change in digital state occurs data will be propagated and saved by the `CsvWriter`. Because the `CsvWriter` is a [Sink](https://bonsai-rx.org/docs/articles/operators.html#sink), the produced by the operator will passes through it. Therefore the frame and can be expanded by right-clicking the `CsvWriter` node and hovering over `Output` in the resulting context menu. In this case, we have exposed `DigitalInputs` and `Buttons`, which represent the 8-bit digital input port state and the button/switch state, respectively. Each of these outputs is followed by a `HasFlag` filter that is used to determine if a certain digital input pin is logic-high (Pins 0, 1, and 7 in this example) or to check if a certain button (☾ or □ in this example) has been depressed. ### Digital outputs From 87bcdc6f1a478cba47b45d12647a45efddb6a6e7 Mon Sep 17 00:00:00 2001 From: jonnew Date: Thu, 22 Aug 2024 15:33:41 -0400 Subject: [PATCH 5/6] Add data loading script to breakout tutorial --- tutorials/breakoutboard-tut.md | 9 ++++--- workflows/examples/BreakoutBoard.bonsai | 20 ++++++-------- workflows/examples/load-breakoutboard.py | 34 ++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 workflows/examples/load-breakoutboard.py diff --git a/tutorials/breakoutboard-tut.md b/tutorials/breakoutboard-tut.md index 5f84a215..4ec6e061 100644 --- a/tutorials/breakoutboard-tut.md +++ b/tutorials/breakoutboard-tut.md @@ -94,8 +94,11 @@ The hardware first-in-first-out (FIFO) memory use is monitored using 8-bit digit Finally, heartbeat data is monitored using a operator, which produces xref:OpenEphys.Onix1.HeartbeatDataFrames> at a regular interval defined in [breakout board configuration](#configurebreakoutboard). ## Loading data +The following python script can be used to load and plot the data produced by the workflow described in this tutorial. -> [!TODO] -> Python script for loading the data produced by this workflow - +[!code-python[](../workflows/examples/load-breakoutboard.py)] +> [!NOTE] +> This script will attempt to load entire files into arrays. For long recordings, data will need to be split into more manageable chunks by: +> - Modifying this script to partially load files +> - Modifying the workflow to cyclically creating new files after a certain duration diff --git a/workflows/examples/BreakoutBoard.bonsai b/workflows/examples/BreakoutBoard.bonsai index a3fbe681..e8c86a24 100644 --- a/workflows/examples/BreakoutBoard.bonsai +++ b/workflows/examples/BreakoutBoard.bonsai @@ -80,7 +80,7 @@ false Timestamp false - Timestamp,Value + Timestamp,Value.AcquisitionClockHz,Value.BlockReadSize,Value.BlockWriteSize @@ -181,6 +181,8 @@ digital-data_.csv + ; + false false Timestamp @@ -190,11 +192,6 @@ DigitalInputs - - - Pin0 Pin1 Pin7 - - Buttons @@ -258,15 +255,14 @@ - - - + + + - + - - + \ No newline at end of file diff --git a/workflows/examples/load-breakoutboard.py b/workflows/examples/load-breakoutboard.py new file mode 100644 index 00000000..df6de70a --- /dev/null +++ b/workflows/examples/load-breakoutboard.py @@ -0,0 +1,34 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Load data from breakout board tutorial workflow +suffix = '2024-08-22T14_16_06'; # Change to match file names' suffix +plt.close('all') + +#%% Metadata +dt = {'names': ('time', 'acq_clk_hz', 'block_read_sz', 'block_write_sz'), + 'formats': ('datetime64[us]', 'u4', 'u4', 'u4')} +meta = np.genfromtxt('start-time_' + suffix + '.csv', delimiter=',', dtype=dt) +print(f"Recording was started at {meta['time']} GMT") + +#%% Analog Inputs +analog_input = {} +analog_input['time'] = np.fromfile('analog-clock_' + suffix + '.raw', dtype=np.uint64) / meta['acq_clk_hz'] +analog_input['data'] = np.reshape(np.fromfile('analog-data_' + suffix + '.raw', dtype=np.float32), (-1, 12)) + +plt.figure() +plt.plot(analog_input['time'], analog_input['data']) +plt.xlabel("time (sec)") +plt.ylabel("volts") +plt.legend(['Ch. 0', 'Ch. 1', 'Ch. 2', 'Ch. 3', 'Ch. 4', 'Ch. 5', + 'Ch. 6', 'Ch. 7', 'Ch. 8', 'Ch. 9', 'Ch. 10', 'Ch. 11']) + +#%% Hardware FIFO buffer use +dt = {'names': ('clock', 'bytes', 'percent'), + 'formats': ('u8', 'u4', 'f8')} +memory_use = np.genfromtxt('memory-use_' + suffix + '.csv', delimiter=',', dtype=dt) + +plt.figure() +plt.plot(memory_use['clock'] / meta['acq_clk_hz'], memory_use['percent']) +plt.xlabel("time (sec)") +plt.ylabel("FIFO used (%)") From 7a9ec0e7b0553e538b9fc0cba2c27bca84d0298f Mon Sep 17 00:00:00 2001 From: cjsha Date: Fri, 23 Aug 2024 16:59:44 -0400 Subject: [PATCH 6/6] Fix some typos --- src/onix-bonsai-onix1 | 2 +- tutorials/breakoutboard-tut.md | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/onix-bonsai-onix1 b/src/onix-bonsai-onix1 index 7cb45a2a..ee68e23c 160000 --- a/src/onix-bonsai-onix1 +++ b/src/onix-bonsai-onix1 @@ -1 +1 @@ -Subproject commit 7cb45a2af4fc387fcfbf0a2028c09b78ccb41c06 +Subproject commit ee68e23c19e2195052c5423cc257fca00d2f2210 diff --git a/tutorials/breakoutboard-tut.md b/tutorials/breakoutboard-tut.md index 4ec6e061..ffdad3d6 100644 --- a/tutorials/breakoutboard-tut.md +++ b/tutorials/breakoutboard-tut.md @@ -6,10 +6,10 @@ title: Breakout Board Tutorial # Breakout Board Tutorial In this example, we will explore the breakout board's functionality by demoing its capabilities. The workflow below can by copy/pasted into the Bonsai editor using the clipboard icon in the top right. This workflow: -- Captures data from the analog and digital inputs on the breakout board and streams them to disk -- Generates signals to drive the breakout boards analog and digital outputs +- Captures data from the analog and digital inputs on the breakout board and streams them to disk. +- Generates signals to drive the breakout boards analog and digital outputs. - Monitors and saves hardware memory buffer use information. -- Monitors the breakout board's heartbeat signal +- Monitors the breakout board's heartbeat signal. In the following sections, we break this workflow into components and provide an explanation for each. @@ -26,12 +26,12 @@ We start by configuring the hardware using a configuration chain. This chain cre ![Breakout board configuration chain](../images/breakout-tut_config-chain.svg) ### CreateContext -The operator determines creates a "context" that determines the device driver, physical interface type, and host-computer index that the system communicates through. The `Driver` property is set to "riffa", which is the name of the PCIe device used by ONIX. In our case, because we are using a single ONIX system, the `Index` property is set to 0. If second system was used on the same computer, a second operator would be required and its `Index` property set to 1. +The operator creates a "context" that determines the device driver, physical interface type, and host-computer index that the system communicates through. The `Driver` property is set to "riffa", which is the name of the PCIe device used by ONIX. In our case, because we are using a single ONIX system, the `Index` property is set to 0. If a second system is used on the same computer, a second operator would be required and its `Index` property set to 1. ### ConfigureBreakoutBoard -The operator is used to configure the breakout board. Configuration settings for the breakout board can be examined and edited by clicking on the node to highlight it and open its property pane to the right of the editor. Expanding the members of the property pane allows you to configure each of the devices within the breakout board. In this demo, the breakout board properties are set to their default values with two exceptions: +The operator is used to configure the breakout board. Configuration settings for the breakout board can be examined and edited by clicking on the node to select it and open its property pane to the right of the editor. Expanding the members of the property pane allows you to configure each of the devices within the breakout board. In this demo, the breakout board properties are set to their default values with two exceptions: - `AnalogIO` channel 0 is configured as an output by setting its `Direction0` property to `Output` -- The `MemoryMonitor` is enabled by setting its `Enable` property to `True` +- `MemoryMonitor` is enabled by setting its `Enable` property to `True` ![Breakout board configuration settings](../images/breakout-tut_device-options.png){width=650px} @@ -44,7 +44,7 @@ The operator begins acquisition after th The rest of the workflow concerns capturing data from and sending to the breakout board, using a set of discrete "processing graphs" that either produce data from hardware (inputs/sources) or accept data produced by software (outputs/sinks). We describe these graphs in the following sections. > [!TIP] -> When trying to understand a workflow's operation, its very useful to visualize the data that being generated by each operator. You can open an operator's visualizer by double clicking the node while the workflow is running. The type of visualizer that opens will depend on the type of data handled by the operator and whether or not the appropriate Design library has been installed. +> When trying to understand a workflow's operation, its very useful to visualize the data generated by each operator. You can open an operator's visualizer by double clicking the node while the workflow is running. The type of visualizer that opens will depend on the type of data handled by the operator and whether or not the appropriate Design library has been installed. ### Analog inputs @@ -60,7 +60,7 @@ The sequence is split into ` ![Breakout board analog output processing graph](../images/breakout-tut_analog-output-graph.svg) -This portion of the workflow generates a ramping analog signal and sends it to each of the analog outputs using a operator. The `RampGenerator` is a [`GroupWorkflow`](https://bonsai-rx.org/docs/articles/editor.html#workflow) that contains a number of Bonsai operators. You can look at how it works hitting Ctrl + Enter when the node is highlighted to expand the internal workflow in a new tab: +This portion of the workflow generates a ramping analog signal and sends it to each of the analog outputs using a operator. The `RampGenerator` is a [`GroupWorkflow`](https://bonsai-rx.org/docs/articles/editor.html#workflow) that contains a number of Bonsai operators. You can look at how it works hitting Ctrl + Enter when the node is selected to expand the internal workflow in a new tab: ![The RampGenerator GroupWorkflow](../images/breakout-tut_ramp-gen.svg) @@ -70,7 +70,7 @@ The `RampGenerator` contains a ~100 Hz timer that is used to create an array of ![Breakout board digital input processing graph](../images/breakout-tut_digital-input-graph.svg) -The 8-bit, 5-V tolerant digital input port along with the breakout board's button and switch states are captured using a operator. The digital inputs are sampled at 5 MHz. However, they will only produce data when a change in state occurs (e.g. a digital input pin toggles from logic low to logic high or a button is pressed). Whenever a change in digital state occurs data will be propagated and saved by the `CsvWriter`. Because the `CsvWriter` is a [Sink](https://bonsai-rx.org/docs/articles/operators.html#sink), the produced by the operator will passes through it. Therefore the frame and can be expanded by right-clicking the `CsvWriter` node and hovering over `Output` in the resulting context menu. In this case, we have exposed `DigitalInputs` and `Buttons`, which represent the 8-bit digital input port state and the button/switch state, respectively. Each of these outputs is followed by a `HasFlag` filter that is used to determine if a certain digital input pin is logic-high (Pins 0, 1, and 7 in this example) or to check if a certain button (☾ or □ in this example) has been depressed. +The 8-bit, 5-V tolerant digital input port along with the breakout board's button and switch states are captured using a operator. The digital inputs are sampled at 5 MHz. However, they will only produce data when a change in state occurs (e.g. a digital input pin toggles from logic low to logic high or a button is pressed). Whenever a change in digital state occurs, data will be propagated and saved by the `CsvWriter`. Because the `CsvWriter` is a [Sink](https://bonsai-rx.org/docs/articles/operators.html#sink), the produced by the operator will pass through it. Therefore, the frame can be expanded by right-clicking the `CsvWriter` node and hovering over `Output` in the resulting context menu. In this case, we have exposed `DigitalInputs` and `Buttons`, which represent the 8-bit digital input port state and the button/switch state, respectively. Each of these outputs is followed by a `HasFlag` filter that is used to determine if a certain digital input pin is logic-high (Pins 0, 1, and 7 in this example) or to check if a certain button (☾ or □ in this example) has been depressed. ### Digital outputs