rad 0.2.2 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. data/History.txt +34 -0
  2. data/Manifest.txt +113 -7
  3. data/{README.txt → README.rdoc} +17 -5
  4. data/Rakefile +3 -0
  5. data/bin/rad +106 -1
  6. data/lib/examples/add_hysteresis.rb +13 -0
  7. data/lib/examples/basic_blink.rb +10 -0
  8. data/lib/examples/blink_m_address_assignment.rb +104 -0
  9. data/lib/examples/blink_m_hello.rb +14 -0
  10. data/lib/examples/blink_m_multi.rb +61 -0
  11. data/lib/examples/blink_with_serial.rb +16 -0
  12. data/lib/examples/configure_pa_lcd_boot.rb +91 -0
  13. data/lib/examples/debounce_methods.rb +49 -0
  14. data/lib/examples/external_variable_fu.rb +26 -0
  15. data/lib/examples/external_variables.rb +32 -0
  16. data/lib/examples/first_sound.rb +23 -0
  17. data/lib/examples/frequency_generator.rb +30 -0
  18. data/lib/examples/hello_array.rb +48 -0
  19. data/lib/examples/hello_array2.rb +79 -0
  20. data/lib/examples/hello_array_eeprom.rb +59 -0
  21. data/lib/examples/hello_clock.rb +84 -0
  22. data/lib/examples/hello_eeprom.rb +51 -0
  23. data/lib/examples/hello_eeprom_lcdpa.rb +81 -0
  24. data/lib/examples/hello_format_print.rb +94 -0
  25. data/lib/examples/hello_lcd_charset.rb +75 -0
  26. data/lib/examples/hello_pa_lcd.rb +59 -0
  27. data/lib/examples/hello_servos.rb +88 -0
  28. data/lib/examples/hello_spectra_sound.rb +38 -0
  29. data/lib/examples/hello_world.rb +11 -0
  30. data/lib/examples/hello_xbee.rb +12 -0
  31. data/lib/examples/hysteresis_duel.rb +39 -0
  32. data/lib/examples/i2c_with_clock_chip.rb +124 -0
  33. data/lib/examples/midi_beat_box.rb +86 -0
  34. data/lib/examples/midi_scales.rb +94 -0
  35. data/lib/examples/motor_knob.rb +30 -0
  36. data/lib/examples/servo_buttons.rb +23 -0
  37. data/lib/examples/servo_calibrate_continuous.rb +92 -0
  38. data/lib/examples/servo_throttle.rb +40 -0
  39. data/lib/examples/sparkfun_lcd.rb +48 -0
  40. data/lib/examples/spectra_soft_pot.rb +34 -0
  41. data/lib/examples/times_method.rb +8 -0
  42. data/lib/examples/toggle.rb +10 -0
  43. data/lib/examples/twitter.rb +57 -0
  44. data/lib/examples/two_wire.rb +14 -0
  45. data/lib/libraries/AFSoftSerial/AFSoftSerial.cpp +321 -0
  46. data/lib/libraries/AFSoftSerial/AFSoftSerial.h +61 -0
  47. data/lib/libraries/AFSoftSerial/keywords.txt +18 -0
  48. data/lib/libraries/AF_XPort/AF_XPort.cpp +166 -0
  49. data/lib/libraries/AF_XPort/AF_XPort.h +48 -0
  50. data/lib/libraries/DS1307/DS1307.cpp +162 -0
  51. data/lib/libraries/DS1307/DS1307.h +66 -0
  52. data/lib/libraries/{SWSerLCDpa → DS1307}/keywords.txt +1 -1
  53. data/lib/libraries/FrequencyTimer2/FrequencyTimer2.cpp +144 -0
  54. data/lib/libraries/FrequencyTimer2/FrequencyTimer2.h +42 -0
  55. data/lib/libraries/FrequencyTimer2/keywords.txt +22 -0
  56. data/lib/libraries/I2CEEPROM/I2CEEPROM.cpp +120 -0
  57. data/lib/libraries/I2CEEPROM/I2CEEPROM.h +70 -0
  58. data/lib/libraries/I2CEEPROM/keywords.txt +21 -0
  59. data/lib/libraries/LoopTimer/LoopTimer.cpp +35 -0
  60. data/lib/libraries/LoopTimer/LoopTimer.h +34 -0
  61. data/lib/libraries/LoopTimer/keywords.txt +27 -0
  62. data/lib/libraries/OneWire/OneWire.cpp +194 -0
  63. data/lib/libraries/OneWire/OneWire.h +63 -0
  64. data/lib/libraries/OneWire/keywords.txt +35 -0
  65. data/lib/libraries/OneWire/readme.txt +13 -0
  66. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +93 -47
  67. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +16 -9
  68. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +311 -0
  69. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +67 -0
  70. data/lib/libraries/Servo/Servo.cpp +192 -0
  71. data/lib/libraries/Servo/Servo.h +61 -0
  72. data/lib/libraries/Stepper/Stepper.cpp +220 -0
  73. data/lib/libraries/Stepper/Stepper.h +86 -0
  74. data/lib/libraries/Stepper/keywords.txt +28 -0
  75. data/lib/libraries/Wire/Wire.cpp +262 -0
  76. data/lib/libraries/Wire/Wire.h +67 -0
  77. data/lib/libraries/Wire/keywords.txt +31 -0
  78. data/lib/libraries/Wire/twi.h +57 -0
  79. data/lib/libraries/Wire/utility/twi.c +449 -0
  80. data/lib/libraries/Wire/utility/twi.h +57 -0
  81. data/lib/plugins/bitwise_ops.rb +54 -0
  82. data/lib/plugins/blink.rb +25 -0
  83. data/lib/plugins/blink_m.rb +356 -0
  84. data/lib/plugins/debounce.rb +138 -0
  85. data/lib/plugins/debug_output_to_lcd.rb +71 -0
  86. data/lib/plugins/hysteresis.rb +52 -0
  87. data/lib/plugins/input_output_state.rb +84 -0
  88. data/lib/plugins/lcd_padding.rb +58 -0
  89. data/lib/plugins/mem_test.rb +37 -0
  90. data/lib/plugins/midi.rb +60 -0
  91. data/lib/plugins/parallax_ping.rb +50 -0
  92. data/lib/plugins/servo_pulse.rb +31 -0
  93. data/lib/plugins/servo_setup.rb +86 -0
  94. data/lib/plugins/smoother.rb +54 -0
  95. data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
  96. data/lib/plugins/spectra_symbol.rb +79 -0
  97. data/lib/plugins/twitter_connect.rb +145 -0
  98. data/lib/rad/README.rdoc +5 -0
  99. data/lib/rad/arduino_plugin.rb +246 -0
  100. data/lib/rad/arduino_sketch.rb +351 -257
  101. data/lib/rad/generators/makefile/makefile.erb +1 -1
  102. data/lib/rad/generators/makefile/makefile.rb +9 -10
  103. data/lib/rad/hardware_library.rb +813 -0
  104. data/lib/rad/init.rb +3 -1
  105. data/lib/rad/rad_processor.rb +128 -0
  106. data/lib/rad/rad_rewriter.rb +94 -0
  107. data/lib/rad/rad_type_checker.rb +26 -0
  108. data/lib/rad/sim/arduino_sketch.rb +57 -0
  109. data/lib/rad/sketch_compiler.rb +47 -0
  110. data/lib/rad/tasks/build_and_make.rake +146 -24
  111. data/lib/rad/variable_processing.rb +153 -0
  112. data/lib/rad/version.rb +1 -1
  113. data/spec/examples/hello_world.rb +11 -0
  114. data/spec/examples/serial_motor.rb +12 -0
  115. data/spec/models/sketch_compiler_spec.rb +96 -0
  116. data/spec/sim/hello_world_spec.rb +42 -0
  117. data/test/test_array_processing.rb +179 -0
  118. data/test/test_plugin_loading.rb +151 -0
  119. data/test/test_translation_post_processing.rb +185 -0
  120. data/test/test_variable_processing.rb +238 -0
  121. data/website/index.html +22 -7
  122. data/website/stylesheets/screen.css +32 -1
  123. metadata +130 -13
@@ -0,0 +1,138 @@
1
+ class Debounce < ArduinoPlugin
2
+
3
+
4
+ # RAD plugins are c methods, directives, external variables and assignments and calls
5
+ # that may be added to the main setup method
6
+ # function prototypes not needed since we generate them automatically
7
+
8
+ # directives, external variables and setup assignments and calls can be added rails style (not c style)
9
+ # hack from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1209050315
10
+
11
+ # plugin_directives "#undef int", "#include <stdio.h>", "char _str[32];", "#define writeln(...) sprintf(_str, __VA_ARGS__); Serial.println(_str)"
12
+ # add to directives
13
+ #plugin_directives "#define EXAMPLE 10"
14
+
15
+ # add to external variables
16
+ # ok, we need to deal with
17
+ # what about variables
18
+ # need to loose the colon...
19
+ # external_variables "char status_message[40] = \"very cool\"", "char* msg[40]"
20
+
21
+ # add the following to the setup method
22
+ # add_to_setup "foo = 1";, "bar = 1;" "sub_setup();"
23
+
24
+ # one or more methods may be added and prototypes are generated automatically with rake make:upload
25
+
26
+ # call pulse(us) to pulse a servo
27
+
28
+ #####################
29
+
30
+ ## How this works
31
+
32
+ ## The cast:
33
+ ## a normally open push button (circuit is closed when button is depressed)
34
+ ## variables [input].
35
+ ## [input]read: or current read -- what we see from the input pin HIGH (1) untouched or LOW (1) depressed
36
+ ## [input]prev: or previous read – assigned to current reading at the end of the method
37
+ ## [input]state: the stored state HIGH (1) or LOW (0)
38
+ ## [input]time: the time when we last had a true
39
+ ## millis: number of milliseconds since the Arduino began running the current program
40
+
41
+ ## So….
42
+
43
+ ## If HIGH and the [input]read was LOW (button was depressed since the last time we looped) AND If millis() - [input]time > 200
44
+ ## Flip the state
45
+ ## And assign [input]time millis()
46
+ ## Else Set the pin to [input]state
47
+ ## Assign [input]prev to [input]read
48
+
49
+ ## abstract summary:
50
+
51
+ ## So 99%+ of the time, we always see a HIGH (unless the button is pushed)
52
+ ## If the button is pushed, we record this LOW to [input]prev, so the next time we enter the loop and the button is not being pushed we see true as long as millis() minus the [input]time of the last toggle is greater the 200 (adjust, which can be set with an adjust option)
53
+
54
+
55
+ ######################
56
+
57
+
58
+ add_debounce_struct
59
+
60
+ # increase the debounce_setting, increase if the output flickers
61
+ # need docs..
62
+ # and testing
63
+ #
64
+ # remember these are being called from the loop (typically)
65
+ #
66
+ # NOTE: if two buttons are controlling one output, today, strange
67
+ # things will happen since each button tries to assert its own state
68
+ # suggestion: we can fix this with an array of structs for shared outputs
69
+ # ie: output_pin 5, :as => :yellow_led, :shared => :yes # default no
70
+ # this would put the state at the output which could be compared to
71
+ # the inputs_state and override and set it if different
72
+
73
+
74
+
75
+ int toggle(int output)
76
+ {
77
+ return toggle_output(output);
78
+ }
79
+
80
+ int toggle_output(int output)
81
+ {
82
+ if (dbce[output].state == HIGH)
83
+ dbce[output].state = LOW;
84
+ else
85
+ dbce[output].state = HIGH;
86
+ digitalWrite(output, dbce[output].state);
87
+
88
+ return dbce[output].state;
89
+ }
90
+
91
+
92
+ int read_input(int input)
93
+ {
94
+ int state = LOW;
95
+ dbce[input].read = digitalRead(input);
96
+
97
+ if (dbce[input].read == HIGH && dbce[input].prev == LOW && millis() - dbce[input].time > dbce[input].adjust)
98
+ {
99
+ dbce[input].time = millis();
100
+ state = HIGH;
101
+ }
102
+ else
103
+ state = LOW;
104
+
105
+ dbce[input].prev = dbce[input].read;
106
+ return state;
107
+ }
108
+
109
+
110
+ int toggle(int input, int output)
111
+ {
112
+ return read_and_toggle(input, output);
113
+ }
114
+
115
+ int read_and_toggle(int input, int output)
116
+ {
117
+ dbce[input].read = digitalRead(input);
118
+ // did we just release a button which was depressed the last time we checked and over 200 millseconds has passed since this statement was last true?
119
+ if (dbce[input].read == HIGH && dbce[input].prev == LOW && millis() - dbce[input].time > dbce[input].adjust) {
120
+ // ... flip the output
121
+ if (dbce[input].state == HIGH)
122
+ dbce[input].state = LOW;
123
+ else
124
+ dbce[input].state = HIGH;
125
+
126
+ /* save time of last press */
127
+ dbce[input].time = millis();
128
+ }
129
+
130
+ digitalWrite(output, dbce[input].state);
131
+
132
+ dbce[input].prev = dbce[input].read;
133
+
134
+ return dbce[input].state;
135
+ }
136
+
137
+
138
+ end
@@ -0,0 +1,71 @@
1
+ class DebugOutputToLcd < ArduinoPlugin
2
+
3
+ # RAD plugins are c methods, directives, external variables and assignments and calls
4
+ # that may be added to the main setup method
5
+ # function prototypes not needed since we generate them automatically
6
+
7
+ # directives, external variables and setup assignments and calls can be added rails style (not c style)
8
+
9
+ # add to directives
10
+ #plugin_directives "#define ARY_SIZE 10"
11
+
12
+ # add to external variables
13
+ #external_variables "unsigned long start_loop_time = 0;", "unsigned long total_loop_time = 0;"
14
+
15
+ # add the following to the setup method
16
+ #add_to_setup "scan = &sm_ary[0];", "cur = &sm_ary[0];", "start = &sm_ary[0];", "end = &sm_ary[ARY_SIZE-1];"
17
+
18
+ # add an element to the array and return the average
19
+
20
+ # need a nice home for these
21
+
22
+
23
+
24
+
25
+
26
+ void send_servo_debug_to_lcd(int servo)
27
+ {
28
+ lcd_first_line();
29
+ Serial.print("pw ");
30
+ Serial.print( find_servo_pulse_width(servo));
31
+ Serial.print(" lp ");
32
+ Serial.print( find_servo_last_pulse(servo));
33
+ Serial.print("s");
34
+ Serial.print( find_servo_start_pulse(servo));
35
+ // Serial.print(" t");
36
+ // Serial.print( find_debounce_time(servo));
37
+
38
+ lcd_second_line();
39
+ Serial.print("d");
40
+ // Serial.print( millis() - find_debounce_time(servo));
41
+ Serial.print(" m");
42
+ Serial.print(millis());
43
+
44
+ }
45
+
46
+
47
+ void send_button_debug_to_lcd(int button)
48
+ {
49
+
50
+ lcd_first_line();
51
+ Serial.print("r");
52
+ Serial.print( find_debounce_read(button));
53
+ Serial.print("p");
54
+ Serial.print( find_debounce_prev(button));
55
+ Serial.print("s");
56
+ Serial.print( find_debounce_state(button));
57
+ Serial.print(" t");
58
+ Serial.print( find_debounce_time(button));
59
+
60
+ lcd_second_line();
61
+ Serial.print("d");
62
+ Serial.print( millis() - find_debounce_time(button));
63
+ Serial.print(" m");
64
+ Serial.print(millis());
65
+
66
+ }
67
+
68
+
69
+
70
+
71
+ end
@@ -0,0 +1,52 @@
1
+ class Hysteresis < ArduinoPlugin
2
+
3
+ # jdbarnhart
4
+ # 20080728
5
+ #
6
+ #
7
+ # purpose
8
+ #
9
+ # add hysteresis to analog readings, typically sensors or potentiometers
10
+ #
11
+ # use
12
+ # two steps
13
+ #
14
+ # one
15
+ # declare :device => :sensor
16
+ # example:
17
+ # input_pin 1, :as => :sensor_one, :device => :sensor
18
+ #
19
+ # two
20
+ # instead of:
21
+ # my_lcd.print analogRead sensor_two
22
+ # use add_hyst
23
+ # my_lcd.print sensor_one.with_hyst 4
24
+ #
25
+ # # note, 4 is the amount of hysteresis
26
+ #
27
+ #
28
+ void with_hysteresis(int pin, int amt)
29
+ {
30
+ with_hyst(pin, amt);
31
+ }
32
+
33
+ int with_hyst(int pin, int amt)
34
+ {
35
+ int read;
36
+ unsigned int i;
37
+ read = analogRead(pin);
38
+ for (i = 0; i < (int) (sizeof(hyst) / sizeof(hyst[0])); i++) {
39
+ if (pin == hyst[i].pin) {
40
+ if (((read - hyst[i].state) > amt ) || ((hyst[i].state - read) > amt )) {
41
+ hyst[i].state = read;
42
+ return hyst[i].state;
43
+ }
44
+ else
45
+ return hyst[i].state;
46
+ }
47
+ }
48
+ }
49
+
50
+
51
+
52
+ end
@@ -0,0 +1,84 @@
1
+ class InputOutputState < ArduinoPlugin
2
+
3
+ # RAD plugins are c methods, directives, external variables and assignments and calls
4
+ # that may be added to the main setup method
5
+ # function prototypes not needed since we generate them automatically
6
+
7
+ # directives, external variables and setup assignments and calls can be added rails style (not c style)
8
+
9
+ # add to directives
10
+ #plugin_directives "#define ARY_SIZE 10"
11
+
12
+ # add to external variables
13
+ #external_variables "int *cur, *scan, *start, *end;", "int sm_ary[ARY_SIZE];"
14
+
15
+ # add the following to the setup method
16
+ #add_to_setup "scan = &sm_ary[0];", "cur = &sm_ary[0];", "start = &sm_ary[0];", "end = &sm_ary[ARY_SIZE-1];"
17
+
18
+ # return states of button and servo output stored in
19
+ # array structs dbcd (debounce) and serv (servo)
20
+ # need error catch ...
21
+ # how about auto generating documentation from plugins
22
+ # at least showing
23
+
24
+
25
+
26
+ int find_debounce_state(int input)
27
+ {
28
+ return dbce[input].state;
29
+ }
30
+
31
+ int find_debounce_read(int input)
32
+ {
33
+ return dbce[input].read;
34
+ }
35
+
36
+ int find_debounce_prev(int input)
37
+ {
38
+ return dbce[input].prev;
39
+ }
40
+
41
+ unsigned long find_debounce_time(int input)
42
+ {
43
+ return dbce[input].time;
44
+ }
45
+
46
+ int find_debounce_adjust(int input)
47
+ {
48
+ return dbce[input].adjust;
49
+ }
50
+
51
+ long unsigned find_servo_pulse_width(int input)
52
+ {
53
+ return serv[input].pulseWidth;
54
+ }
55
+
56
+ unsigned long find_servo_last_pulse(int input)
57
+ {
58
+ return serv[input].lastPulse;
59
+ }
60
+
61
+ unsigned long find_servo_start_pulse(int input)
62
+ {
63
+ return serv[input].startPulse;
64
+
65
+ }
66
+
67
+ unsigned long find_servo_refresh_time(int input)
68
+ {
69
+ return serv[input].refreshTime;
70
+ }
71
+
72
+ int find_servo_min(int input)
73
+ {
74
+ return serv[input].min;
75
+ }
76
+
77
+ int find_servo_max(int input)
78
+ {
79
+ return serv[input].max;
80
+
81
+ }
82
+
83
+
84
+ end
@@ -0,0 +1,58 @@
1
+ class LCDPadding < ArduinoPlugin
2
+
3
+ # jdbarnhart
4
+ # 20080729
5
+ #
6
+ #
7
+ # purpose
8
+
9
+ # simple integer padding for lcd display pad
10
+ #
11
+ # example
12
+ # my_lcd.print pad_int_to_str 29, 5
13
+ #
14
+ # result
15
+ # " 29"
16
+
17
+
18
+
19
+ static char* pad_int_to_str(int num, int length)
20
+ {
21
+ int i = 0;
22
+ int start;
23
+ char plain[20];
24
+ char space[5] = " ";
25
+ char* pretty = " ";
26
+ itoa(num, plain ,10);
27
+ start = length - strlen(plain);
28
+ while (i <= length) {
29
+ if (i >= start)
30
+ pretty[i] = plain[i - start];
31
+ else
32
+ pretty[i] = space[0];
33
+ i++;
34
+ }
35
+ return pretty;
36
+ }
37
+
38
+ static char* pad_int_to_str_w_zeros(int num, int length)
39
+ {
40
+ int i = 0;
41
+ int start;
42
+ char plain[20];
43
+ char space[5] = "0 ";
44
+ char* pretty = " ";
45
+ itoa(num, plain ,10);
46
+ start = length - strlen(plain);
47
+ while (i <= length) {
48
+ if (i >= start)
49
+ pretty[i] = plain[i - start];
50
+ else
51
+ pretty[i] = space[0];
52
+ i++;
53
+ }
54
+ return pretty;
55
+ }
56
+
57
+
58
+ end
@@ -0,0 +1,37 @@
1
+ class MemTest < ArduinoPlugin
2
+
3
+ # RAD plugins are c methods, directives, external variables and assignments and calls
4
+ # that may be added to the main setup method
5
+ # function prototypes not needed since we generate them automatically
6
+
7
+ # directives, external variables and setup assignments and calls can be added rails style (not c style)
8
+
9
+ # add to directives
10
+ #plugin_directives "#define EXAMPLE 10"
11
+
12
+ # add to external variables
13
+ # external_variables "int foo, bar"
14
+
15
+ # add the following to the setup method
16
+ # add_to_setup "foo = 1";, "bar = 1;" "sub_setup();"
17
+
18
+ # one or more methods may be added and prototypes are generated automatically with rake make:upload
19
+
20
+ # test the memory on your arduino uncommenting the following:
21
+ # add_to_setup "memoryTest();"
22
+ # or adding "memoryTest()" (no semicolon) to your main sketch
23
+
24
+ int memoryTest() {
25
+ int byteCounter = 0; // initialize a counter
26
+ byte *byteArray; // create a pointer to a byte array
27
+ while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) {
28
+ byteCounter++; // if allocation was successful, then up the count for the next try
29
+ free(byteArray); // free memory after allocating it
30
+ }
31
+
32
+ free(byteArray); // also free memory after the function finishes"
33
+ return byteCounter; // send back the highest number of bytes successfully allocated
34
+ }
35
+
36
+
37
+ end
@@ -0,0 +1,60 @@
1
+ class Midi < ArduinoPlugin
2
+
3
+
4
+ # reference
5
+
6
+ # To send MIDI, attach a MIDI out jack (female DIN-5) to Arduino.
7
+ # DIN-5 pinout is: _____
8
+ # pin 2 - Gnd / \
9
+ # pin 4 - 220 ohm resistor to +5V | 3 1 | Female MIDI jack
10
+ # pin 5 - Arduino D1 (TX) | 5 4 |
11
+ # all other pins - unconnected \__2__/
12
+ # Adapted from Tom Igoe's work at:
13
+ # http://itp.nyu.edu/physcomp/Labs/MIDIOutput
14
+ # And Tod E. Kurt <tod@todbot.com
15
+ # http://todbot.com/
16
+ #
17
+ # Created 25 October 2008
18
+ # copyleft 2008 jdbarnhart
19
+ # http://jdbarnhart.com/
20
+
21
+ void note_on(char cmd, int data1, char data2) {
22
+ Serial.print(cmd, BYTE);
23
+ Serial.print(data1, BYTE);
24
+ Serial.print(data2, BYTE);
25
+ }
26
+
27
+ void note_on(int channel, int note, int velocity) {
28
+ midi_msg( (0x90 | (channel)), note, velocity);
29
+ }
30
+
31
+ void note_on(long int& channel, long int& note, long int& velocity) {
32
+ midi_msg( (0x90 | (channel)), note, velocity);
33
+ }
34
+
35
+ void note_off(long int& channel, long int& note, long int& velocity) {
36
+ midi_msg( (0x90 | (channel)), note, velocity);
37
+ }
38
+
39
+ void note_off(byte channel, byte note, byte velocity) {
40
+ midi_msg( (0x90 | (channel)), note, velocity);
41
+ }
42
+
43
+ void play_note(long int& channel, long int& note, long int& velocity) {
44
+ midi_msg( (0x90 | (channel)), note, velocity);
45
+ delay(100);
46
+ midi_msg( (0x90 | (channel)), note, 0);
47
+ }
48
+
49
+
50
+
51
+ void midi_msg(byte cmd, byte data1, byte data2) {
52
+ digitalWrite(led(), 1); // indicate we're sending MIDI data
53
+ Serial.print(cmd, BYTE);
54
+ Serial.print(data1, BYTE);
55
+ Serial.print(data2, BYTE);
56
+ digitalWrite(led(), 0); // indicate we're sending MIDI data
57
+ }
58
+
59
+
60
+ end