Chromium Code Reviews| 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 |