OLD | NEW |
---|---|
(Empty) | |
1 --- | |
2 title: Fletch project samples | |
3 layout: page | |
4 --- | |
5 | |
6 # Fletch project samples | |
7 | |
8 We have a number of sample programs available in the ```/samples/``` folder. | |
9 Let’s take a look at the code, and get familiar with the platform. | |
10 | |
11 | |
12 * [The 'hello world' of embedded: Blink an LED](#blinky) | |
13 * [Controlling GPIO input and output pins](#buzzer) | |
14 * [Using GPIO events](#door-bell) | |
15 * [Structuring larger programs with classes](#knight-rider) | |
16 * [Communicating with a 'shield'](#sense-hat) | |
17 | |
18 ## Blinky ## | |
19 | |
20 Embedded devices are most commonly used to collect data and perform some kind of | |
21 control task via attached sensors and output devices such as LEDs. The | |
22 communication with these happens via the | |
Søren Gjesse
2015/10/05 16:19:51
happens -> typically happens
the -> a
mit
2015/10/05 17:51:39
Done.
| |
23 [GPIO](https://en.wikipedia.org/wiki/General-purpose_input/output) (general | |
24 purpose input/output) protocol. | |
Søren Gjesse
2015/10/05 16:19:51
protocol -> interface
mit
2015/10/05 17:51:39
Done.
| |
25 | |
26 Take a look at the blinky.dart program located in the ```/samples/basic/``` | |
27 folder. This uses GPIO to blink the Raspberry Pi on-board LED. | |
Søren Gjesse
2015/10/05 16:19:51
It doesn't use GPIO any more, but the sysfs interf
mit
2015/10/05 17:51:39
Yes, makes sense. I will move the GPIO comments do
| |
28 | |
29 First the program initializes the GPIO interface: | |
30 ~~~ | |
31 RaspberryPi pi = new RaspberryPi(); | |
32 pi.leds.activityLED.setMode(OnboardLEDMode.gpio); | |
Søren Gjesse
2015/10/05 16:19:51
You askes me to change this to use the other inter
mit
2015/10/05 17:51:39
Don't we still need this line to tell the Raspberr
Søren Gjesse
2015/10/05 18:28:01
Yes we do, sorry.
| |
33 ~~~ | |
34 | |
35 Next, it simply loops and alternates between turning the led on and off: | |
36 | |
37 ~~~ | |
38 while (true) { | |
39 pi.leds.activityLED.on(); | |
40 sleep(500); | |
41 pi.leds.activityLED.off(); | |
42 sleep(500); | |
43 } | |
44 ~~~ | |
45 | |
46 Pretty easy, right!? | |
47 | |
48 ## Buzzer | |
49 | |
50 Let's expand on the previous sample by wiring up a small custom circuit. We will | |
51 use a [breakboard](http://www.instructables.com/id/How-to-use-a-breadboard/) for | |
52 fast iteration. | |
53 | |
54 Start by building a circuit resembling [this schematic](https://storage.googleap is.com/fletch-archive/images/buzzer-schematic.png). | |
55 | |
56 Next, as we are using a custom circuit, we need to configure the GPIO pins for | |
57 the components we wired up (full runnable code located in | |
58 ```/samples/basic/buzzer.dart```): | |
59 | |
60 ~~~ | |
61 import 'package:gpio/gpio.dart'; | |
62 | |
63 main() { | |
64 // GPIO pin constants. | |
65 const int button = 16; | |
66 const int speaker = 21; | |
67 ~~~ | |
68 | |
69 Notice how we are using pins 16 and 21. Those pin numbers are based on the | |
70 connection points shown in the schematic, and the [pinout for the Raspberry Pi | |
71 2](http://www.raspberry-projects.com/pi/pi-hardware/raspberry-pi-2-model-b/rpi2- model-b-io-pins). | |
72 | |
73 Next, we need to tell GPIO which pins we intend to write to (i.e., use as | |
74 output), and which we intend to read from (i.e., use as input): | |
75 | |
76 ~~~ | |
77 RaspberryPi pi = new RaspberryPi(); | |
78 PiMemoryMappedGPIO gpio = pi.memoryMappedGPIO; | |
79 gpio.setMode(button, Mode.input); | |
80 gpio.setMode(speaker, Mode.output); | |
81 ~~~ | |
82 | |
83 Finally, we simply spin in an internal loop and map the state of the button to | |
84 the speaker, i.e. when we see a high signal on the button we set a high signal | |
85 on the speaker and vice versa. | |
86 | |
87 ~~~ | |
88 while (true) { | |
89 bool buttonState = gpio.getPin(button); | |
90 gpio.setPin(speaker, buttonState); | |
91 } | |
92 ~~~ | |
93 | |
94 ## Door bell | |
95 | |
96 In the buzzer sample we spun in an eternal loop to sound out speaker. Often it | |
97 can be more convenient to wait for a certain state to occur. This is supported | |
98 via GPIO events. Let try to build a small door bell. | |
99 | |
100 First we need to configure GPIO for events. We configure the pins as before, and | |
101 then enable a trigger on the button: | |
102 | |
103 ~~~ | |
104 // Initialize GPIO and speaker pin. | |
105 SysfsGPIO gpio = new SysfsGPIO(); | |
Søren Gjesse
2015/10/05 16:19:51
This was changed to:
RaspberryPi pi = new Raspber
mit
2015/10/05 17:51:39
Done.
| |
106 gpio.exportPin(speaker); | |
107 gpio.setMode(speaker, Mode.output); | |
108 | |
109 // Initialize button pin. Enable a button down trigger. | |
wibling
2015/10/05 15:19:59
NIT: Is it a button down trigger when we enable bo
Søren Gjesse
2015/10/05 16:19:51
It seemed that using the raising (or falling trigg
mit
2015/10/05 17:51:39
Acknowledged.
mit
2015/10/05 17:51:39
Acknowledged.
| |
110 gpio.exportPin(button); | |
111 gpio.setMode(button, Mode.input); | |
112 gpio.setTrigger(button, Trigger.both); | |
113 ~~~ | |
114 | |
115 Next, we simply wait for the button to be pressed (i.e., for the GPIO pin of the | |
116 button to go to 'true'): | |
117 | |
118 ~~~ | |
119 while (true) { | |
120 // Wait for button press. | |
121 gpio.waitFor(button, true, -1); | |
122 | |
123 .... | |
124 } | |
125 } | |
126 ~~~ | |
127 | |
128 And then we sound the bell: | |
129 | |
130 ~~~ | |
131 // Sound bell | |
132 for (var i = 1; i <= 3; i++) { | |
133 gpio.setPin(speaker, true); | |
134 sleep(100); | |
135 gpio.setPin(speaker, false); | |
136 sleep(500); | |
137 } | |
138 ~~~ | |
139 | |
140 ## Night rider | |
141 | |
142 In all the previous samples we relied on a very simple program structure: A few | |
143 lines of initialization code, and then a small eternal loop in which we had a fe w | |
Søren Gjesse
2015/10/05 16:19:51
nit: long line
mit
2015/10/05 17:51:39
Done.
| |
144 more lines of code. For our next sample we are going to explore a slightly | |
145 larger program to illustrate how the Dart programming language allows us to | |
146 structure our program using classes and encapsulation. | |
147 | |
148 We are going to build a small running light. Remember | |
149 [KITT](https://www.youtube.com/watch?v=Mo8Qls0HnWo), the car from the Knight | |
150 Rider show? Let's try to [replicate those | |
151 lights](https://storage.googleapis.com/fletch-archive/images/knight-rider.mp4). | |
152 | |
153 The full program is available in ```/samples/basic/knight-rider.dart```. Let's | |
154 step through how it's built. | |
155 | |
156 First we will create a ```Lights``` helper class. This class will contain all | |
157 the core functionality required for managing the LEDs on the breadboard that we | |
158 will be animating. Initially let's define a variable containing a list of | |
159 integers containing the GPIO pins of all the connected LEDs, and a variable | |
160 containing a GPIO manager. Note that the GPIO variable starts with an | |
161 underscore; this is the Dart syntax for declaring a private variable that can | |
162 only be accessed from within the class itself (i.e., that is encapsulated to the | |
wibling
2015/10/05 15:19:59
NIT: It can be accessed from within the Dart libra
mit
2015/10/05 17:51:39
Rewrote this a bit.
| |
163 implementation of the class.) | |
164 | |
165 ~~~ | |
166 class Lights { | |
167 List<int> leds; | |
168 PiMemoryMappedGPIO _gpio = new PiMemoryMappedGPIO(); | |
Søren Gjesse
2015/10/05 16:19:51
This initialization was refactored in https://code
mit
2015/10/05 17:51:39
Done.
| |
169 ... | |
170 } | |
171 ~~~ | |
172 | |
173 Next, let's implement a small helper function that we can call with a LED number | |
174 (e.g., 2), and which then turns LED number 2 in the LED chain on and turns all | |
175 the other LEDs in the chain off: | |
176 | |
177 ~~~ | |
178 // Sets LED [ledToEnable] to true, and all others to false. | |
179 void _setLeds(int ledToEnable) { | |
180 var state; | |
181 | |
182 for (int i = 0; i < leds.length; i++) { | |
183 bool state = (i == ledToEnable); | |
184 _gpio.setPin(leds[i], state); | |
185 } | |
186 } | |
187 ~~~ | |
188 | |
189 Next, we need to have the lights first move from the left to the right, and then | |
190 from the right to the left. We will do this in another two methods that simply | |
191 run in a for loop either from 0 to the number or LEDs, or the opposite, and then | |
192 call the helper function above: | |
193 | |
194 ~~~ | |
195 // Iterates though the lights in increasing order, and sets the LEDs using | |
196 // a helper function. Pauses [waitTime] milliseconds before returning. | |
197 void runLightLeft(int waitTime) { | |
198 for (int counter = 0; counter < leds.length; counter++) { | |
199 _setLeds(counter); | |
200 sleep(waitTime); | |
201 } | |
202 } | |
203 | |
204 // Iterates though the lights in decreasing order, and sets the LEDs using | |
205 // a helper function. Pauses [waitTime] milliseconds before returning. | |
206 void runLightRight(int waitTime) { | |
207 for (int counter = leds.length - 1; counter >= 0; counter--) { | |
208 _setLeds(counter); | |
209 sleep(waitTime); | |
210 } | |
211 } | |
212 ~~~ | |
213 | |
214 Finally, we just need a small Main function to initialize our Lights helper | |
215 class and to call the lights methods, and we are done! | |
216 | |
217 ~~~ | |
218 main() { | |
219 // Array constant containing the GPIO pins of the connected LEDs. | |
220 // You can add more LEDs simply by extending the list. Make sure | |
221 // the pins are listed in the order the LEDs are connected. | |
222 List<int> leds = [26, 19, 13, 6]; | |
223 | |
224 // Initialize the lights controller class. | |
Søren Gjesse
2015/10/05 16:19:51
Again see https://codereview.chromium.org/13895730
| |
225 Lights lights = new Lights(leds); | |
226 lights.init(); | |
227 | |
228 // Alternate between running left and right in a continuous loop. | |
229 const int waitTime = 100; | |
230 while (true) { | |
231 lights.runLightLeft(waitTime); | |
232 lights.runLightRight(waitTime); | |
233 } | |
234 } | |
235 ~~~ | |
236 | |
237 ## Sense hat | |
238 | |
239 ** TODO ** | |
wibling
2015/10/05 15:19:59
Remove this?
| |
OLD | NEW |