Skip to content

Commit 5593ab9

Browse files
committed
Add animations
1 parent 0847496 commit 5593ab9

5 files changed

Lines changed: 214 additions & 6 deletions

File tree

animations/ei_animations.aep

589 KB
Binary file not shown.

book/_toc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ parts:
1919
sections:
2020
- file: manuals/intros/alpaca2/programming.ipynb
2121
- file: manuals/intros/alpaca2/signals.ipynb
22+
- file: manuals/intros/alpaca2/extras.ipynb
2223
- file: manuals/intros/breadboard.ipynb
2324

2425
- caption: Lab manuals
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "3d88442e",
6+
"metadata": {},
7+
"source": [
8+
"# Dig Deeper\n",
9+
"\n",
10+
"This page includes concepts that are bit more advanced but might come in handy when dealing with ALPACA.\n",
11+
"\n",
12+
"\n",
13+
"## Live Plotting\n",
14+
"\n",
15+
":::{admonition} Background: 'yield'\n",
16+
":class: note, dropdown\n",
17+
"\n",
18+
"The `yield` keyword is a new concept. It is simillar to the `return` keyword but it doesn't stop the function. Instead it **yields (adds) the value to the output and continues**. This can be compared to lists.\n",
19+
"\n",
20+
"```python\n",
21+
"def foo():\n",
22+
" l = []\n",
23+
" for i in range(5):\n",
24+
" l.append(i + 1)\n",
25+
" \n",
26+
" return l\n",
27+
"\n",
28+
"output = foo()\n",
29+
"```\n",
30+
"\n",
31+
"gives the exact same result as\n",
32+
"\n",
33+
"```python\n",
34+
"def foo():\n",
35+
" for i in range(5):\n",
36+
" yield i + 1\n",
37+
"\n",
38+
"# foo() returns a 'generator' which is essentially\n",
39+
"# something that can be used to generate a list\n",
40+
"output = list(foo())\n",
41+
"```\n",
42+
"\n",
43+
"Where they start to differ is when you start to use them in loops:\n",
44+
"\n",
45+
"```python\n",
46+
"def foo():\n",
47+
" for i in range(5):\n",
48+
" print(\"Here \", i)\n",
49+
" yield i + 1\n",
50+
"\n",
51+
"for j in foo():\n",
52+
" print(\"There \", j)\n",
53+
"\n",
54+
"### OUTPUT\n",
55+
"# Here 1\n",
56+
"# There 2\n",
57+
"# Here 2\n",
58+
"# There 3\n",
59+
"# ...\n",
60+
"```\n",
61+
"\n",
62+
"```python\n",
63+
"def foo():\n",
64+
" l = []\n",
65+
" for i in range(5):\n",
66+
" print(\"Here \", i)\n",
67+
" l.append(i + 1)\n",
68+
" \n",
69+
" return l\n",
70+
"\n",
71+
"for j in foo():\n",
72+
" print(\"There \", j)\n",
73+
"\n",
74+
"### OUTPUT\n",
75+
"# Here 1\n",
76+
"# Here 2\n",
77+
"# Here ..\n",
78+
"# There 1\n",
79+
"# There 2\n",
80+
"# There 3\n",
81+
"# ...\n",
82+
"```\n",
83+
"\n",
84+
"As you can see the main difference is with `yield` the function doesn't stop it continues. Where as returning needs the whole function the be finished.\n",
85+
":::\n",
86+
"\n",
87+
"\n",
88+
"When acquiring data, standard plots fall short as they show you the results at the very end. With **live plotting**, you can update an active graph. From the below example you can see how to \"animate\" matplotlib graphs to match your output.\n",
89+
"\n",
90+
"```python\n",
91+
"import matplotlib.pyplot as plt\n",
92+
"\n",
93+
"@pico.task\n",
94+
"def measure_samples(N, dur):\n",
95+
" '''\n",
96+
" Take measurements for dur seconds and N samples for each measurement\n",
97+
" '''\n",
98+
" from utime import ticks_add, ticks\n",
99+
"\n",
100+
" deadline = ticks_add(ticks(), dur) # dur in the future\n",
101+
"\n",
102+
" while ticks_diff(deadline, ticks()) =< 0:\n",
103+
" total = 0\n",
104+
" for i in range(N):\n",
105+
" total += adc0.read_u16()\n",
106+
" \n",
107+
" yield total * 3 / 2**16 / N # Add average to the list\n",
108+
"\n",
109+
" return # Stop\n",
110+
"\n",
111+
"plt.ion() # Enable matplotlib\n",
112+
"fig, ax = plt.subplots() # Create figure and an axis\n",
113+
"\n",
114+
"t = [] # Time\n",
115+
"y = [] # Values\n",
116+
"# Initialize an empty line object\n",
117+
"(line,) = ax.plot([], [])\n",
118+
"\n",
119+
"# This for loop will run as long as 'yield' is 'ran'\n",
120+
"for val in measure_samples(50, 5):\n",
121+
" t.append(time.time()) # Add current time\n",
122+
" y.append(val) # Add measurement\n",
123+
"\n",
124+
" ax.relim() # Adjust the x-axis and y-axis\n",
125+
" ax.autoscale_view()\n",
126+
"\n",
127+
" # Update the line with current data\n",
128+
" line.set_ydata(y)\n",
129+
" line.set_xdata(t)\n",
130+
"\n",
131+
"plt.ioff()\n",
132+
"plt.show()\n",
133+
"```"
134+
]
135+
}
136+
],
137+
"metadata": {
138+
"language_info": {
139+
"name": "python"
140+
}
141+
},
142+
"nbformat": 4,
143+
"nbformat_minor": 5
144+
}

book/manuals/intros/alpaca2/programming.ipynb

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@
2424
"After connecting the ALPACA to your computer via USB you can access the device:\n",
2525
"\n",
2626
"```python\n",
27-
"from belay import Device, list_devices\n",
27+
"from belay import Device\n",
28+
"from alpaca import list_boards\n",
2829
"\n",
29-
"# 'list_devices()' gets all connected boards to your computer\n",
30+
"# 'list_boards()' gets all connected boards to your computer\n",
3031
"# and the first element is most likely the ALPACA. \n",
31-
"pico = Device(list_devices()[0].to_port())\n",
32+
"pico = Device(list_boards()[0].to_port())\n",
3233
"```\n",
3334
"\n",
3435
"To identify which code part needs to be seen by the ALPACA and which code part needs to be seen by your computer, you can 'tag' functions (`def`) that will be executed in ALPACA using `@pico.task`.\n",
@@ -109,14 +110,76 @@
109110
"\n",
110111
"## Dealing with data\n",
111112
"\n",
112-
"ALPACA has a very small memory, therefore storing a lot of things in variables can sometimes be exhaustive.\n",
113+
"<font color=\"#ea9943\">**Each communication**</font> between your ALPACA and your computer <font color=\"#ea9943\">**takes time!**</font> So some conventions that keep sending instructions to ALPACA are often bad practice for timely acquiring data.\n",
113114
"\n",
114115
"```python\n",
116+
"# BAD\n",
115117
"@pico.task\n",
116-
"def measurement():\n",
117-
" while \n",
118+
"def measure():\n",
119+
" adc0.read_u16() * 3 / 2**16\n",
120+
"\n",
121+
"for i in range(3):\n",
122+
" print(measure())\n",
123+
"\n",
124+
"# GOOD\n",
125+
"@pico.task\n",
126+
"def measure_n(N):\n",
127+
" val = []\n",
128+
"\n",
129+
" for i in range(N):\n",
130+
" val.append(adc0.read_u16() * 3 / 2**16)\n",
131+
"\n",
132+
" return val\n",
133+
"\n",
134+
"print(measure_n(3))\n",
135+
"```\n",
136+
"\n",
137+
"```{figure} ../images/alpaca/alpaca_time.avif\n",
138+
"---\n",
139+
"max-height: 300px\n",
140+
"name: Connect USB-C to energy hub and Micro USB to Student Pico\n",
141+
"class: no-invert\n",
142+
"---\n",
118143
"```\n",
119144
"\n",
145+
"\n",
146+
":::{caution}\n",
147+
"ALPACA has a **very small memory**, therefore storing a lot of things in variables can sometimes be exhaustive. So either when sending the data paritition it or calculate your result on the go.\n",
148+
"\n",
149+
"For instance when taking 300 samples\n",
150+
"\n",
151+
"```python\n",
152+
"@pico.task\n",
153+
"def measure_n(N):\n",
154+
" val = []\n",
155+
"\n",
156+
" for i in range(N):\n",
157+
" val.append(adc0.read_u16() * 3 / 2**16)\n",
158+
"\n",
159+
" return val\n",
160+
"\n",
161+
"vals = []\n",
162+
"\n",
163+
"for i in range(30):\n",
164+
" vals += measure_n(100)\n",
165+
"\n",
166+
"print(\"Voltage AVG (n=3000): \", sum(vals) / 300)\n",
167+
"\n",
168+
"# ==== OR ====\n",
169+
"\n",
170+
"@pico.task\n",
171+
"def measure_n(N):\n",
172+
" val = 0 # Just stores one number\n",
173+
"\n",
174+
" for i in range(N):\n",
175+
" val += adc0.read_u16()\n",
176+
"\n",
177+
" return val * 3 / 2**16 / N\n",
178+
"\n",
179+
"print(\"Voltage AVG (n=3000): \", measure_n(3000))\n",
180+
"```\n",
181+
":::\n",
182+
"\n",
120183
"# Modules\n",
121184
"\n",
122185
"Some modules aren't available in ALPACA and some modules aren't available in the computer. These are the **modules that are available on ALPACA only** you have to import them inside the functions.\n",
192 KB
Binary file not shown.

0 commit comments

Comments
 (0)