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 |
| 17 ## Blinky ## |
| 18 |
| 19 Embedded devices are most commonly used to collect data and perform some kind of |
| 20 control task via attached sensors and output devices such as LEDs. Take a look |
| 21 at the ```blinky.dart``` program located in the ```/samples/basic/``` folder. |
| 22 This blinks the Raspberry Pi on-board LED. |
| 23 |
| 24 First the program initializes the RaspberryPi helper object: |
| 25 |
| 26 ~~~ |
| 27 RaspberryPi pi = new RaspberryPi(); |
| 28 pi.leds.activityLED.setMode(OnboardLEDMode.gpio); |
| 29 ~~~ |
| 30 |
| 31 Next, it simply loops and alternates between turning the led on and off: |
| 32 |
| 33 ~~~ |
| 34 while (true) { |
| 35 pi.leds.activityLED.on(); |
| 36 sleep(500); |
| 37 pi.leds.activityLED.off(); |
| 38 sleep(500); |
| 39 } |
| 40 ~~~ |
| 41 |
| 42 Pretty easy, right!? |
| 43 |
| 44 ## Buzzer |
| 45 |
| 46 Let's expand on the previous sample by wiring up a small custom circuit. We will |
| 47 use a [breadboard](http://www.instructables.com/id/How-to-use-a-breadboard/) for |
| 48 fast iteration. |
| 49 |
| 50 Start by building a circuit resembling [this schematic](https://storage.googleap
is.com/fletch-archive/images/buzzer-schematic.png). |
| 51 |
| 52 We will be communicating with the components on the breadboard using a |
| 53 [GPIO](https://en.wikipedia.org/wiki/General-purpose_input/output) (general |
| 54 purpose input/output) interface. First we need to configure the GPIO pins for |
| 55 the components we wired up (full runnable code located in |
| 56 ```/samples/basic/buzzer.dart```): |
| 57 |
| 58 ~~~ |
| 59 import 'package:gpio/gpio.dart'; |
| 60 |
| 61 main() { |
| 62 // GPIO pin constants. |
| 63 const int button = 16; |
| 64 const int speaker = 21; |
| 65 ~~~ |
| 66 |
| 67 Notice how we are using pins 16 and 21. Those pin numbers are based on the |
| 68 connection points shown in the schematic, and the [pinout for the Raspberry Pi |
| 69 2](http://www.raspberry-projects.com/pi/pi-hardware/raspberry-pi-2-model-b/rpi2-
model-b-io-pins). |
| 70 |
| 71 Next, we need to tell GPIO which pins we intend to write to (i.e., use as |
| 72 output), and which we intend to read from (i.e., use as input): |
| 73 |
| 74 ~~~ |
| 75 RaspberryPi pi = new RaspberryPi(); |
| 76 PiMemoryMappedGPIO gpio = pi.memoryMappedGPIO; |
| 77 gpio.setMode(button, Mode.input); |
| 78 gpio.setMode(speaker, Mode.output); |
| 79 ~~~ |
| 80 |
| 81 Finally, we simply spin in an internal loop and map the state of the button to |
| 82 the speaker, i.e. when we see a high signal on the button we set a high signal |
| 83 on the speaker and vice versa. |
| 84 |
| 85 ~~~ |
| 86 while (true) { |
| 87 bool buttonState = gpio.getPin(button); |
| 88 gpio.setPin(speaker, buttonState); |
| 89 } |
| 90 ~~~ |
| 91 |
| 92 ## Door bell |
| 93 |
| 94 In the buzzer sample we spun in an eternal loop to sound out speaker. Often it |
| 95 can be more convenient to wait for a certain state to occur. This is supported |
| 96 via GPIO events. Let try to build a small door bell. |
| 97 |
| 98 First we need to configure GPIO for events. We configure the pins as before, and |
| 99 then enable a trigger on the button: |
| 100 |
| 101 ~~~ |
| 102 // Initialize Raspberry Pi and configure the pins. |
| 103 RaspberryPi pi = new RaspberryPi(); |
| 104 SysfsGPIO gpio = pi.sysfsGPIO; |
| 105 |
| 106 // Initialize pins. |
| 107 gpio.exportPin(speaker); |
| 108 gpio.setMode(speaker, Mode.output); |
| 109 gpio.exportPin(button); |
| 110 gpio.setMode(button, Mode.input); |
| 111 gpio.setTrigger(button, Trigger.both); |
| 112 ~~~ |
| 113 |
| 114 Next, we simply wait for the button to be pressed (i.e., for the GPIO pin of the |
| 115 button to go to 'true'): |
| 116 |
| 117 ~~~ |
| 118 while (true) { |
| 119 // Wait for button press. |
| 120 gpio.waitFor(button, true, -1); |
| 121 |
| 122 .... |
| 123 } |
| 124 } |
| 125 ~~~ |
| 126 |
| 127 And then we sound the bell: |
| 128 |
| 129 ~~~ |
| 130 // Sound bell |
| 131 for (var i = 1; i <= 3; i++) { |
| 132 gpio.setPin(speaker, true); |
| 133 sleep(100); |
| 134 gpio.setPin(speaker, false); |
| 135 sleep(500); |
| 136 } |
| 137 ~~~ |
| 138 |
| 139 ## Knight rider |
| 140 |
| 141 In all the previous samples we relied on a very simple program structure: A few |
| 142 lines of initialization code, and then a small eternal loop in which we had a |
| 143 few more lines of code. For our next sample we are going to explore a slightly |
| 144 larger program to illustrate how the Dart programming language allows us to |
| 145 structure our program using classes and encapsulation. |
| 146 |
| 147 We are going to build a small running light. Remember |
| 148 [KITT](https://www.youtube.com/watch?v=Mo8Qls0HnWo), the car from the Knight |
| 149 Rider show? Let's try to [replicate those |
| 150 lights](https://storage.googleapis.com/fletch-archive/images/knight-rider.mp4). |
| 151 |
| 152 The full program is available in ```/samples/basic/knight-rider.dart```. Let's |
| 153 step through how it's built. |
| 154 |
| 155 First we will create a ```Lights``` helper class. This class will contain all |
| 156 the core functionality required for managing the LEDs on the breadboard that we |
| 157 will be animating. Initially let's define a variable containing a list of |
| 158 integers containing the GPIO pins of all the connected LEDs, and a variable |
| 159 containing a GPIO manager. Note that the GPIO variable starts with an |
| 160 underscore; this is the Dart syntax for declaring a private variable that is |
| 161 encapsulated to the implementation of the class.) |
| 162 |
| 163 ~~~ |
| 164 class Lights { |
| 165 final GPIO _gpio; |
| 166 final List<int> leds; |
| 167 |
| 168 Lights(this._gpio, this.leds); |
| 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 to hold the GPIO pins, to |
| 215 initialize our Lights helper class, and to call the lights methods, and we are |
| 216 done! |
| 217 |
| 218 ~~~ |
| 219 main() { |
| 220 // Initialize Raspberry Pi |
| 221 RaspberryPi pi = new RaspberryPi(); |
| 222 |
| 223 // Array constant containing the GPIO pins of the connected LEDs. |
| 224 // You can add more LEDs simply by extending the list. Make sure |
| 225 // the pins are listed in the order the LEDs are connected. |
| 226 List<int> leds = [26, 19, 13, 6]; |
| 227 |
| 228 // Initialize the lights controller class. |
| 229 Lights lights = new Lights(pi.memoryMappedGPIO, leds); |
| 230 lights.init(); |
| 231 |
| 232 // Alternate between running left and right in a continuous loop. |
| 233 const int waitTime = 100; |
| 234 while (true) { |
| 235 lights.runLightLeft(waitTime); |
| 236 lights.runLightRight(waitTime); |
| 237 } |
| 238 } |
| 239 ~~~ |
OLD | NEW |