├── .gitignore ├── API.md ├── Applications ├── MaxMSP │ └── examples │ │ ├── OSCEsplora.maxpat │ │ ├── SerialCallResponse.maxpat │ │ ├── SerialEcho.maxpat │ │ ├── SerialOscuino.maxpat │ │ ├── SerialReceive.maxpat │ │ ├── SerialReceivewithServo.maxpat │ │ ├── SerialSend.maxpat │ │ ├── UDPCallResponse.maxpat │ │ ├── UDPEcho.maxpat │ │ ├── UDPOscuino.maxpat │ │ ├── UDPReceive.maxpat │ │ └── UDPSend.maxpat ├── PD │ ├── SerialOscuino.pd │ └── o.io.slipserial.pd └── Processing │ ├── SLIPSerialToUDP │ ├── GUI.pde │ ├── SLIPSerialToUDP.pde │ ├── Serial.pde │ └── UDP.pde │ ├── SLIPSerialToUDPp3 │ ├── UDPReceiveBundle │ └── UDPReceiveBundle.pde │ ├── UDPReceiveMessage │ └── UDPReceiveMessage.pde │ └── serialSend │ ├── code │ └── javaosc.jar │ ├── serialSend.pde │ └── sketch.properties ├── LICENSE ├── OSCBoards.cpp ├── OSCBoards.h ├── OSCBundle.cpp ├── OSCBundle.h ├── OSCData.cpp ├── OSCData.h ├── OSCMatch.c ├── OSCMatch.h ├── OSCMessage.cpp ├── OSCMessage.h ├── OSCTiming.cpp ├── OSCTiming.h ├── README.md ├── SLIPEncodedSerial.h ├── SLIPEncodedTCP.cpp ├── SLIPEncodedTCP.h ├── examples ├── ESP8266ReceiveBundle │ └── ESP8266ReceiveBundle.ino ├── ESP8266ReceiveMessage │ └── ESP8266ReceiveMessage.ino ├── ESP8266sendMessage │ └── ESP8266sendMessage.ino ├── ETC_EOS_TCP │ └── ETC_EOS_TCP.ino ├── OSCEsplora │ └── OSCEsplora.ino ├── PatternMatching │ └── PatternMatching.ino ├── SerialCallResponse │ └── SerialCallResponse.ino ├── SerialEcho │ └── SerialEcho.ino ├── SerialOscuinoAdaFruitPlayGroundExpresswithBundles │ └── SerialOscuinoAdaFruitPlayGroundExpresswithBundles.ino ├── SerialOscuinoForFubarino │ └── SerialOscuinoForFubarino.ino ├── SerialOscuinoGemmaM0 │ └── SerialOscuinoGemmaM0.ino ├── SerialOscuinowithBundles │ └── SerialOscuinowithBundles.ino ├── SerialOscuinowithMessages │ └── SerialOscuinowithMessages.ino ├── SerialReceive │ └── SerialReceive.ino ├── SerialReceiveInfiniteLoop │ └── SerialReceiveInfiniteLoop.ino ├── SerialReceivewithServo │ └── SerialReceivewithServo.ino ├── SerialSendBundle │ └── SerialSendBundle.ino ├── SerialSendBundleWithTimeTag │ └── SerialSendBundleWithTimeTag.ino ├── SerialSendMessage │ └── SerialSendMessage.ino ├── SerialSendMessageInfiniteLoop │ └── SerialSendMessageInfiniteLoop.ino ├── UDPCallResponse │ └── UDPCallResponse.ino ├── UDPEcho │ └── UDPEcho.ino ├── UDPOscuino │ └── UDPOscuino.ino ├── UDPReceive │ └── UDPReceive.ino ├── UDPSendBundle │ └── UDPSendBundle.ino ├── UDPSendBundlewithTimeTag │ └── UDPSendBundlewithTimeTag.ino └── UDPSendMessage │ └── UDPSendMessage.ino ├── keywords.txt ├── library.json ├── library.properties └── test ├── OSCBundle_test ├── OSCBundle_test.ino └── TestPrint.h ├── OSCData_test └── OSCData_test.ino ├── OSCMessage_encode_decode_test ├── OSCMessage_encode_decode_test.ino └── TestPrint.h ├── OSCMessage_match_test └── OSCMessage_match_test.ino └── OSCMessage_test └── OSCMessage_test.ino /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | .DS_Store 4 | *.code-workspace 5 | -------------------------------------------------------------------------------- /Applications/MaxMSP/examples/OSCEsplora.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 4, 8 | "architecture" : "x86", 9 | "modernui" : 1 10 | } 11 | , 12 | "rect" : [ 130.0, 174.0, 983.0, 623.0 ], 13 | "bglocked" : 0, 14 | "openinpresentation" : 0, 15 | "default_fontsize" : 12.0, 16 | "default_fontface" : 0, 17 | "default_fontname" : "Arial", 18 | "gridonopen" : 1, 19 | "gridsize" : [ 15.0, 15.0 ], 20 | "gridsnaponopen" : 1, 21 | "objectsnaponopen" : 1, 22 | "statusbarvisible" : 2, 23 | "toolbarvisible" : 1, 24 | "lefttoolbarpinned" : 0, 25 | "toptoolbarpinned" : 0, 26 | "righttoolbarpinned" : 0, 27 | "bottomtoolbarpinned" : 0, 28 | "toolbars_unpinned_last_save" : 0, 29 | "tallnewobj" : 0, 30 | "boxanimatetime" : 200, 31 | "enablehscroll" : 1, 32 | "enablevscroll" : 1, 33 | "devicewidth" : 0.0, 34 | "description" : "", 35 | "digest" : "", 36 | "tags" : "", 37 | "style" : "", 38 | "subpatcher_template" : "", 39 | "boxes" : [ { 40 | "box" : { 41 | "fontface" : 0, 42 | "fontsize" : 12.0, 43 | "id" : "obj-5", 44 | "maxclass" : "o.display", 45 | "numinlets" : 1, 46 | "numoutlets" : 1, 47 | "outlettype" : [ "" ], 48 | "patching_rect" : [ 141.0, 266.0, 150.0, 34.0 ], 49 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 50 | } 51 | 52 | } 53 | , { 54 | "box" : { 55 | "fontface" : 0, 56 | "fontname" : "Arial", 57 | "fontsize" : 12.0, 58 | "id" : "obj-3", 59 | "linecount" : 6, 60 | "maxclass" : "o.display", 61 | "numinlets" : 1, 62 | "numoutlets" : 1, 63 | "outlettype" : [ "" ], 64 | "patching_rect" : [ 422.5, 125.0, 158.0, 101.0 ], 65 | "text" : "/port : \"usbmodemOSCes41\",\n/rate/output : 0,\n/rate/input : 0,\n/mediansize/received : -1,\n/baud", 66 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 67 | } 68 | 69 | } 70 | , { 71 | "box" : { 72 | "fontname" : "Arial", 73 | "fontsize" : 12.0, 74 | "id" : "obj-2", 75 | "linecount" : 2, 76 | "maxclass" : "comment", 77 | "numinlets" : 1, 78 | "numoutlets" : 0, 79 | "patching_rect" : [ 389.5, -32.5, 170.0, 33.0 ], 80 | "style" : "", 81 | "text" : "Look for your device in the menu list of serial USB" 82 | } 83 | 84 | } 85 | , { 86 | "box" : { 87 | "bgmode" : 0, 88 | "border" : 0, 89 | "clickthrough" : 0, 90 | "enablehscroll" : 0, 91 | "enablevscroll" : 0, 92 | "id" : "obj-7", 93 | "lockeddragscroll" : 0, 94 | "maxclass" : "bpatcher", 95 | "name" : "o.io.serial.display.maxpat", 96 | "numinlets" : 1, 97 | "numoutlets" : 1, 98 | "offset" : [ 3.0, 0.0 ], 99 | "outlettype" : [ "FullPacket" ], 100 | "patching_rect" : [ 81.5, 29.0, 340.5, 25.0 ], 101 | "viewvisibility" : 1 102 | } 103 | 104 | } 105 | , { 106 | "box" : { 107 | "fontname" : "Arial", 108 | "fontsize" : 12.0, 109 | "id" : "obj-23", 110 | "maxclass" : "newobj", 111 | "numinlets" : 2, 112 | "numoutlets" : 2, 113 | "outlettype" : [ "FullPacket", "FullPacket" ], 114 | "patching_rect" : [ 20.5, 68.0, 80.0, 22.0 ], 115 | "style" : "", 116 | "text" : "o.io.slipserial" 117 | } 118 | 119 | } 120 | , { 121 | "box" : { 122 | "fontname" : "Andale Mono", 123 | "fontsize" : 14.0, 124 | "id" : "obj-11", 125 | "linecount" : 3, 126 | "maxclass" : "comment", 127 | "numinlets" : 1, 128 | "numoutlets" : 0, 129 | "patching_rect" : [ 471.0, 29.0, 150.0, 54.0 ], 130 | "style" : "", 131 | "text" : "stats on serial OSC communications" 132 | } 133 | 134 | } 135 | , { 136 | "box" : { 137 | "fontface" : 0, 138 | "fontsize" : 12.0, 139 | "id" : "obj-6", 140 | "maxclass" : "o.display", 141 | "numinlets" : 1, 142 | "numoutlets" : 1, 143 | "outlettype" : [ "" ], 144 | "patching_rect" : [ 214.0, 285.0, 150.0, 34.0 ], 145 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 146 | } 147 | 148 | } 149 | , { 150 | "box" : { 151 | "fontface" : 0, 152 | "fontsize" : 12.0, 153 | "id" : "obj-4", 154 | "maxclass" : "o.display", 155 | "numinlets" : 1, 156 | "numoutlets" : 1, 157 | "outlettype" : [ "" ], 158 | "patching_rect" : [ 23.0, 285.0, 150.0, 34.0 ], 159 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 160 | } 161 | 162 | } 163 | , { 164 | "box" : { 165 | "fontname" : "Arial", 166 | "fontsize" : 12.0, 167 | "id" : "obj-1", 168 | "maxclass" : "newobj", 169 | "numinlets" : 1, 170 | "numoutlets" : 3, 171 | "outlettype" : [ "", "", "FullPacket" ], 172 | "patching_rect" : [ 23.0, 176.0, 119.0, 22.0 ], 173 | "style" : "", 174 | "text" : "o.route /raw /cooked" 175 | } 176 | 177 | } 178 | ], 179 | "lines" : [ { 180 | "patchline" : { 181 | "destination" : [ "obj-4", 0 ], 182 | "disabled" : 0, 183 | "hidden" : 0, 184 | "source" : [ "obj-1", 0 ] 185 | } 186 | 187 | } 188 | , { 189 | "patchline" : { 190 | "destination" : [ "obj-6", 0 ], 191 | "disabled" : 0, 192 | "hidden" : 0, 193 | "source" : [ "obj-1", 1 ] 194 | } 195 | 196 | } 197 | , { 198 | "patchline" : { 199 | "destination" : [ "obj-1", 0 ], 200 | "disabled" : 0, 201 | "hidden" : 0, 202 | "source" : [ "obj-23", 0 ] 203 | } 204 | 205 | } 206 | , { 207 | "patchline" : { 208 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 209 | "destination" : [ "obj-3", 0 ], 210 | "disabled" : 0, 211 | "hidden" : 0, 212 | "midpoints" : [ 91.0, 109.0, 432.0, 109.0 ], 213 | "source" : [ "obj-23", 1 ] 214 | } 215 | 216 | } 217 | , { 218 | "patchline" : { 219 | "destination" : [ "obj-5", 0 ], 220 | "disabled" : 0, 221 | "hidden" : 0, 222 | "source" : [ "obj-23", 0 ] 223 | } 224 | 225 | } 226 | , { 227 | "patchline" : { 228 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 229 | "destination" : [ "obj-7", 0 ], 230 | "disabled" : 0, 231 | "hidden" : 0, 232 | "midpoints" : [ 91.0, 95.0, 433.0, 95.0, 433.0, 5.0, 91.0, 5.0 ], 233 | "source" : [ "obj-23", 1 ] 234 | } 235 | 236 | } 237 | , { 238 | "patchline" : { 239 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 240 | "destination" : [ "obj-23", 1 ], 241 | "disabled" : 0, 242 | "hidden" : 0, 243 | "source" : [ "obj-7", 0 ] 244 | } 245 | 246 | } 247 | ], 248 | "dependency_cache" : [ { 249 | "name" : "o.io.slipserial.maxpat", 250 | "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", 251 | "type" : "JSON", 252 | "implicit" : 1 253 | } 254 | , { 255 | "name" : "o.righttoleft.maxpat", 256 | "bootpath" : "~/Documents/Max/Packages/odot/patchers/ordering", 257 | "type" : "JSON", 258 | "implicit" : 1 259 | } 260 | , { 261 | "name" : "o.io.serial.display.maxpat", 262 | "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", 263 | "type" : "JSON", 264 | "implicit" : 1 265 | } 266 | , { 267 | "name" : "o.route.mxo", 268 | "type" : "iLaX" 269 | } 270 | , { 271 | "name" : "o.display.mxo", 272 | "type" : "iLaX" 273 | } 274 | , { 275 | "name" : "o.pack.mxo", 276 | "type" : "iLaX" 277 | } 278 | , { 279 | "name" : "o.union.mxo", 280 | "type" : "iLaX" 281 | } 282 | , { 283 | "name" : "o.validate.mxo", 284 | "type" : "iLaX" 285 | } 286 | , { 287 | "name" : "o.print.mxo", 288 | "type" : "iLaX" 289 | } 290 | , { 291 | "name" : "o.slip.encode.mxo", 292 | "type" : "iLaX" 293 | } 294 | , { 295 | "name" : "o.slip.decode.mxo", 296 | "type" : "iLaX" 297 | } 298 | , { 299 | "name" : "o.if.mxo", 300 | "type" : "iLaX" 301 | } 302 | ], 303 | "embedsnapshot" : 0 304 | } 305 | 306 | } 307 | -------------------------------------------------------------------------------- /Applications/MaxMSP/examples/SerialEcho.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 6, 6 | "minor" : 1, 7 | "revision" : 6, 8 | "architecture" : "x86" 9 | } 10 | , 11 | "rect" : [ 608.0, 81.0, 1202.0, 749.0 ], 12 | "bglocked" : 0, 13 | "openinpresentation" : 0, 14 | "default_fontsize" : 14.0, 15 | "default_fontface" : 0, 16 | "default_fontname" : "Andale Mono", 17 | "gridonopen" : 0, 18 | "gridsize" : [ 5.0, 5.0 ], 19 | "gridsnaponopen" : 0, 20 | "statusbarvisible" : 2, 21 | "toolbarvisible" : 1, 22 | "boxanimatetime" : 200, 23 | "imprint" : 0, 24 | "enablehscroll" : 1, 25 | "enablevscroll" : 1, 26 | "devicewidth" : 0.0, 27 | "description" : "", 28 | "digest" : "", 29 | "tags" : "", 30 | "boxes" : [ { 31 | "box" : { 32 | "fontname" : "Andale Mono", 33 | "fontsize" : 14.0, 34 | "id" : "obj-1", 35 | "maxclass" : "newobj", 36 | "numinlets" : 1, 37 | "numoutlets" : 1, 38 | "outlettype" : [ "FullPacket" ], 39 | "patching_rect" : [ 218.0, 295.0, 95.0, 22.0 ], 40 | "text" : "o.downcast" 41 | } 42 | 43 | } 44 | , { 45 | "box" : { 46 | "fontname" : "Arial", 47 | "fontsize" : 12.0, 48 | "id" : "obj-18", 49 | "linecount" : 10, 50 | "maxclass" : "o.display", 51 | "numinlets" : 1, 52 | "numoutlets" : 1, 53 | "outlettype" : [ "" ], 54 | "patching_rect" : [ 28.5, 425.0, 267.0, 155.0 ], 55 | "text" : "/ping : 100,\n/thing : [2., 3.04, 1242., 23., \"thing\"],\n/stuff : [1, 2, 3, 4, 5],\n/fsakjfskfsdkasfk : [234, 242, 234, 234, 4],\n/decision : 1,\n/notdecision : 0,\n/micros : 616229100,\n/sequencenumber : 20557,\n/digital/5 : false,\n/lsb : false", 56 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 57 | } 58 | 59 | } 60 | , { 61 | "box" : { 62 | "fontname" : "Arial", 63 | "fontsize" : 12.0, 64 | "id" : "obj-3", 65 | "linecount" : 5, 66 | "maxclass" : "o.display", 67 | "numinlets" : 1, 68 | "numoutlets" : 1, 69 | "outlettype" : [ "" ], 70 | "patching_rect" : [ 404.5, 425.0, 158.0, 88.0 ], 71 | "text" : "/port : \"usbmodem12341\",\n/rate/output : 32,\n/rate/input : 39,\n/mediansize/received : -1,\n/baud", 72 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 73 | } 74 | 75 | } 76 | , { 77 | "box" : { 78 | "fontname" : "Arial", 79 | "fontsize" : 12.0, 80 | "frgb" : 0.0, 81 | "id" : "obj-19", 82 | "linecount" : 2, 83 | "maxclass" : "comment", 84 | "numinlets" : 1, 85 | "numoutlets" : 0, 86 | "patching_rect" : [ 424.5, 269.5, 170.0, 33.0 ], 87 | "text" : "Look for your device in the menu list of serial USB" 88 | } 89 | 90 | } 91 | , { 92 | "box" : { 93 | "id" : "obj-20", 94 | "maxclass" : "bpatcher", 95 | "name" : "o.io.serial.display.maxpat", 96 | "numinlets" : 1, 97 | "numoutlets" : 1, 98 | "offset" : [ 3.0, 0.0 ], 99 | "outlettype" : [ "FullPacket" ], 100 | "patching_rect" : [ 404.5, 340.0, 164.0, 24.0 ] 101 | } 102 | 103 | } 104 | , { 105 | "box" : { 106 | "fontname" : "Arial", 107 | "fontsize" : 12.0, 108 | "id" : "obj-23", 109 | "maxclass" : "newobj", 110 | "numinlets" : 2, 111 | "numoutlets" : 2, 112 | "outlettype" : [ "FullPacket", "FullPacket" ], 113 | "patching_rect" : [ 343.5, 379.0, 80.0, 20.0 ], 114 | "text" : "o.io.slipserial" 115 | } 116 | 117 | } 118 | , { 119 | "box" : { 120 | "fontname" : "Andale Mono", 121 | "fontsize" : 14.0, 122 | "id" : "obj-2", 123 | "linecount" : 6, 124 | "maxclass" : "o.compose", 125 | "numinlets" : 2, 126 | "numoutlets" : 1, 127 | "outlettype" : [ "" ], 128 | "patching_rect" : [ 45.0, 90.166656, 964.0, 105.0 ], 129 | "text" : "/ping : 100,\n/thing : [2., 3.04, 1242., 23., \"thing\"],\n/stuff : [1, 2, 3, 4, 5],\n/fsakjfskfsdkasfk : [234, 242, 234, 234, 4],\n/decision : true,\n/notdecision : false", 130 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 131 | } 132 | 133 | } 134 | , { 135 | "box" : { 136 | "fontname" : "Andale Mono", 137 | "fontsize" : 14.0, 138 | "frgb" : 0.0, 139 | "id" : "obj-4", 140 | "linecount" : 3, 141 | "maxclass" : "comment", 142 | "numinlets" : 1, 143 | "numoutlets" : 0, 144 | "patching_rect" : [ 595.0, 415.0, 150.0, 54.0 ], 145 | "text" : "stats on serial OSC communications" 146 | } 147 | 148 | } 149 | , { 150 | "box" : { 151 | "fontname" : "Andale Mono", 152 | "fontsize" : 14.0, 153 | "id" : "obj-61", 154 | "maxclass" : "newobj", 155 | "numinlets" : 2, 156 | "numoutlets" : 1, 157 | "outlettype" : [ "bang" ], 158 | "patching_rect" : [ 45.0, 38.166656, 162.0, 22.0 ], 159 | "text" : "metro 22 @active 1" 160 | } 161 | 162 | } 163 | ], 164 | "lines" : [ { 165 | "patchline" : { 166 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 167 | "destination" : [ "obj-23", 0 ], 168 | "disabled" : 0, 169 | "hidden" : 0, 170 | "source" : [ "obj-1", 0 ] 171 | } 172 | 173 | } 174 | , { 175 | "patchline" : { 176 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 177 | "destination" : [ "obj-1", 0 ], 178 | "disabled" : 0, 179 | "hidden" : 0, 180 | "source" : [ "obj-2", 0 ] 181 | } 182 | 183 | } 184 | , { 185 | "patchline" : { 186 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 187 | "destination" : [ "obj-23", 1 ], 188 | "disabled" : 0, 189 | "hidden" : 0, 190 | "source" : [ "obj-20", 0 ] 191 | } 192 | 193 | } 194 | , { 195 | "patchline" : { 196 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 197 | "destination" : [ "obj-18", 0 ], 198 | "disabled" : 0, 199 | "hidden" : 0, 200 | "source" : [ "obj-23", 0 ] 201 | } 202 | 203 | } 204 | , { 205 | "patchline" : { 206 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 207 | "destination" : [ "obj-20", 0 ], 208 | "disabled" : 0, 209 | "hidden" : 0, 210 | "midpoints" : [ 414.0, 406.0, 583.0, 406.0, 583.0, 316.0, 414.0, 316.0 ], 211 | "source" : [ "obj-23", 1 ] 212 | } 213 | 214 | } 215 | , { 216 | "patchline" : { 217 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 218 | "destination" : [ "obj-3", 0 ], 219 | "disabled" : 0, 220 | "hidden" : 0, 221 | "midpoints" : [ 414.0, 420.0, 414.0, 420.0 ], 222 | "source" : [ "obj-23", 1 ] 223 | } 224 | 225 | } 226 | , { 227 | "patchline" : { 228 | "destination" : [ "obj-2", 0 ], 229 | "disabled" : 0, 230 | "hidden" : 0, 231 | "source" : [ "obj-61", 0 ] 232 | } 233 | 234 | } 235 | ], 236 | "dependency_cache" : [ { 237 | "name" : "o.io.slipserial.maxpat", 238 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-MMJSS/patchers/esplora", 239 | "patcherrelativepath" : "../../../../../Documents/Max/Packages/CNMAT-MMJSS/patchers/esplora", 240 | "type" : "JSON", 241 | "implicit" : 1 242 | } 243 | , { 244 | "name" : "o.righttoleft.maxpat", 245 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/patchers/ordering", 246 | "patcherrelativepath" : "../../../../../Documents/Max/Packages/CNMAT-odot/patchers/ordering", 247 | "type" : "JSON", 248 | "implicit" : 1 249 | } 250 | , { 251 | "name" : "o.io.serial.display.maxpat", 252 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-MMJSS/patchers/esplora", 253 | "patcherrelativepath" : "../../../../../Documents/Max/Packages/CNMAT-MMJSS/patchers/esplora", 254 | "type" : "JSON", 255 | "implicit" : 1 256 | } 257 | , { 258 | "name" : "o.compose.mxo", 259 | "type" : "iLaX" 260 | } 261 | , { 262 | "name" : "o.pack.mxo", 263 | "type" : "iLaX" 264 | } 265 | , { 266 | "name" : "o.route.mxo", 267 | "type" : "iLaX" 268 | } 269 | , { 270 | "name" : "o.union.mxo", 271 | "type" : "iLaX" 272 | } 273 | , { 274 | "name" : "o.validate.mxo", 275 | "type" : "iLaX" 276 | } 277 | , { 278 | "name" : "o.print.mxo", 279 | "type" : "iLaX" 280 | } 281 | , { 282 | "name" : "o.slip.encode.mxo", 283 | "type" : "iLaX" 284 | } 285 | , { 286 | "name" : "o.slip.decode.mxo", 287 | "type" : "iLaX" 288 | } 289 | , { 290 | "name" : "o.if.mxo", 291 | "type" : "iLaX" 292 | } 293 | , { 294 | "name" : "o.display.mxo", 295 | "type" : "iLaX" 296 | } 297 | , { 298 | "name" : "o.downcast.mxo", 299 | "type" : "iLaX" 300 | } 301 | ] 302 | } 303 | 304 | } 305 | -------------------------------------------------------------------------------- /Applications/MaxMSP/examples/SerialReceivewithServo.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 4, 8 | "architecture" : "x86", 9 | "modernui" : 1 10 | } 11 | , 12 | "rect" : [ 125.0, 78.0, 1072.0, 480.0 ], 13 | "bglocked" : 0, 14 | "openinpresentation" : 0, 15 | "default_fontsize" : 12.0, 16 | "default_fontface" : 0, 17 | "default_fontname" : "Arial", 18 | "gridonopen" : 1, 19 | "gridsize" : [ 15.0, 15.0 ], 20 | "gridsnaponopen" : 1, 21 | "objectsnaponopen" : 1, 22 | "statusbarvisible" : 2, 23 | "toolbarvisible" : 1, 24 | "lefttoolbarpinned" : 0, 25 | "toptoolbarpinned" : 0, 26 | "righttoolbarpinned" : 0, 27 | "bottomtoolbarpinned" : 0, 28 | "toolbars_unpinned_last_save" : 0, 29 | "tallnewobj" : 0, 30 | "boxanimatetime" : 200, 31 | "enablehscroll" : 1, 32 | "enablevscroll" : 1, 33 | "devicewidth" : 0.0, 34 | "description" : "", 35 | "digest" : "", 36 | "tags" : "", 37 | "style" : "", 38 | "subpatcher_template" : "", 39 | "boxes" : [ { 40 | "box" : { 41 | "fontface" : 0, 42 | "fontname" : "Arial", 43 | "fontsize" : 12.0, 44 | "id" : "obj-12", 45 | "maxclass" : "o.display", 46 | "numinlets" : 1, 47 | "numoutlets" : 1, 48 | "outlettype" : [ "" ], 49 | "patching_rect" : [ 27.5, 386.0, 158.0, 34.0 ], 50 | "presentation_rect" : [ 534.5, 418.0, 0.0, 0.0 ], 51 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 52 | } 53 | 54 | } 55 | , { 56 | "box" : { 57 | "id" : "obj-6", 58 | "maxclass" : "newobj", 59 | "numinlets" : 1, 60 | "numoutlets" : 1, 61 | "outlettype" : [ "FullPacket" ], 62 | "patching_rect" : [ 137.5, 194.0, 82.0, 22.0 ], 63 | "style" : "", 64 | "text" : "o.pack /servo" 65 | } 66 | 67 | } 68 | , { 69 | "box" : { 70 | "contdata" : 1, 71 | "id" : "obj-11", 72 | "maxclass" : "multislider", 73 | "numinlets" : 1, 74 | "numoutlets" : 2, 75 | "outlettype" : [ "", "" ], 76 | "parameter_enable" : 0, 77 | "patching_rect" : [ 139.0, 27.0, 20.0, 140.0 ], 78 | "setminmax" : [ 0.0, 180.0 ], 79 | "settype" : 0, 80 | "style" : "" 81 | } 82 | 83 | } 84 | , { 85 | "box" : { 86 | "fontface" : 0, 87 | "fontname" : "Arial", 88 | "fontsize" : 12.0, 89 | "id" : "obj-3", 90 | "maxclass" : "o.display", 91 | "numinlets" : 1, 92 | "numoutlets" : 1, 93 | "outlettype" : [ "" ], 94 | "patching_rect" : [ 198.5, 386.0, 158.0, 34.0 ], 95 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 96 | } 97 | 98 | } 99 | , { 100 | "box" : { 101 | "fontname" : "Arial", 102 | "fontsize" : 12.0, 103 | "id" : "obj-1", 104 | "linecount" : 2, 105 | "maxclass" : "comment", 106 | "numinlets" : 1, 107 | "numoutlets" : 0, 108 | "patching_rect" : [ 218.5, 230.5, 170.0, 33.0 ], 109 | "style" : "", 110 | "text" : "Look for your device in the menu list of serial USB" 111 | } 112 | 113 | } 114 | , { 115 | "box" : { 116 | "bgmode" : 0, 117 | "border" : 0, 118 | "clickthrough" : 0, 119 | "enablehscroll" : 0, 120 | "enablevscroll" : 0, 121 | "id" : "obj-20", 122 | "lockeddragscroll" : 0, 123 | "maxclass" : "bpatcher", 124 | "name" : "o.io.serial.display.maxpat", 125 | "numinlets" : 1, 126 | "numoutlets" : 1, 127 | "offset" : [ 3.0, 0.0 ], 128 | "outlettype" : [ "FullPacket" ], 129 | "patching_rect" : [ 198.5, 301.0, 164.0, 24.0 ], 130 | "viewvisibility" : 1 131 | } 132 | 133 | } 134 | , { 135 | "box" : { 136 | "fontname" : "Arial", 137 | "fontsize" : 12.0, 138 | "id" : "obj-23", 139 | "maxclass" : "newobj", 140 | "numinlets" : 2, 141 | "numoutlets" : 2, 142 | "outlettype" : [ "FullPacket", "FullPacket" ], 143 | "patching_rect" : [ 137.5, 337.0, 80.0, 22.0 ], 144 | "style" : "", 145 | "text" : "o.io.slipserial" 146 | } 147 | 148 | } 149 | , { 150 | "box" : { 151 | "fontname" : "Andale Mono", 152 | "fontsize" : 14.0, 153 | "id" : "obj-5", 154 | "linecount" : 3, 155 | "maxclass" : "comment", 156 | "numinlets" : 1, 157 | "numoutlets" : 0, 158 | "patching_rect" : [ 389.0, 376.0, 150.0, 54.0 ], 159 | "style" : "", 160 | "text" : "stats on serial OSC communications" 161 | } 162 | 163 | } 164 | , { 165 | "box" : { 166 | "fontname" : "Arial", 167 | "fontsize" : 12.0, 168 | "id" : "obj-19", 169 | "maxclass" : "comment", 170 | "numinlets" : 1, 171 | "numoutlets" : 0, 172 | "patching_rect" : [ 335.0, 151.0, 156.0, 20.0 ], 173 | "style" : "", 174 | "text" : "Servo control (from 0-180)" 175 | } 176 | 177 | } 178 | ], 179 | "lines" : [ { 180 | "patchline" : { 181 | "destination" : [ "obj-6", 0 ], 182 | "disabled" : 0, 183 | "hidden" : 0, 184 | "source" : [ "obj-11", 0 ] 185 | } 186 | 187 | } 188 | , { 189 | "patchline" : { 190 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 191 | "destination" : [ "obj-23", 1 ], 192 | "disabled" : 0, 193 | "hidden" : 0, 194 | "source" : [ "obj-20", 0 ] 195 | } 196 | 197 | } 198 | , { 199 | "patchline" : { 200 | "destination" : [ "obj-12", 0 ], 201 | "disabled" : 0, 202 | "hidden" : 0, 203 | "source" : [ "obj-23", 0 ] 204 | } 205 | 206 | } 207 | , { 208 | "patchline" : { 209 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 210 | "destination" : [ "obj-20", 0 ], 211 | "disabled" : 0, 212 | "hidden" : 0, 213 | "midpoints" : [ 208.0, 367.0, 377.0, 367.0, 377.0, 277.0, 208.0, 277.0 ], 214 | "source" : [ "obj-23", 1 ] 215 | } 216 | 217 | } 218 | , { 219 | "patchline" : { 220 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 221 | "destination" : [ "obj-3", 0 ], 222 | "disabled" : 0, 223 | "hidden" : 0, 224 | "midpoints" : [ 208.0, 381.0, 208.0, 381.0 ], 225 | "source" : [ "obj-23", 1 ] 226 | } 227 | 228 | } 229 | , { 230 | "patchline" : { 231 | "destination" : [ "obj-23", 0 ], 232 | "disabled" : 0, 233 | "hidden" : 0, 234 | "source" : [ "obj-6", 0 ] 235 | } 236 | 237 | } 238 | ], 239 | "dependency_cache" : [ { 240 | "name" : "o.io.slipserial.maxpat", 241 | "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", 242 | "type" : "JSON", 243 | "implicit" : 1 244 | } 245 | , { 246 | "name" : "o.righttoleft.maxpat", 247 | "bootpath" : "~/Documents/Max/Packages/odot/patchers/ordering", 248 | "type" : "JSON", 249 | "implicit" : 1 250 | } 251 | , { 252 | "name" : "o.io.serial.display.maxpat", 253 | "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", 254 | "type" : "JSON", 255 | "implicit" : 1 256 | } 257 | , { 258 | "name" : "o.pack.mxo", 259 | "type" : "iLaX" 260 | } 261 | , { 262 | "name" : "o.route.mxo", 263 | "type" : "iLaX" 264 | } 265 | , { 266 | "name" : "o.union.mxo", 267 | "type" : "iLaX" 268 | } 269 | , { 270 | "name" : "o.validate.mxo", 271 | "type" : "iLaX" 272 | } 273 | , { 274 | "name" : "o.print.mxo", 275 | "type" : "iLaX" 276 | } 277 | , { 278 | "name" : "o.slip.encode.mxo", 279 | "type" : "iLaX" 280 | } 281 | , { 282 | "name" : "o.slip.decode.mxo", 283 | "type" : "iLaX" 284 | } 285 | , { 286 | "name" : "o.if.mxo", 287 | "type" : "iLaX" 288 | } 289 | , { 290 | "name" : "o.display.mxo", 291 | "type" : "iLaX" 292 | } 293 | ], 294 | "embedsnapshot" : 0 295 | } 296 | 297 | } 298 | -------------------------------------------------------------------------------- /Applications/MaxMSP/examples/SerialSend.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 6, 6 | "minor" : 1, 7 | "revision" : 9, 8 | "architecture" : "x86" 9 | } 10 | , 11 | "rect" : [ 196.0, 152.0, 1072.0, 480.0 ], 12 | "bglocked" : 0, 13 | "openinpresentation" : 0, 14 | "default_fontsize" : 12.0, 15 | "default_fontface" : 0, 16 | "default_fontname" : "Arial", 17 | "gridonopen" : 0, 18 | "gridsize" : [ 15.0, 15.0 ], 19 | "gridsnaponopen" : 0, 20 | "statusbarvisible" : 2, 21 | "toolbarvisible" : 1, 22 | "boxanimatetime" : 200, 23 | "imprint" : 0, 24 | "enablehscroll" : 1, 25 | "enablevscroll" : 1, 26 | "devicewidth" : 0.0, 27 | "description" : "", 28 | "digest" : "", 29 | "tags" : "", 30 | "boxes" : [ { 31 | "box" : { 32 | "fontsize" : 12.0, 33 | "id" : "obj-8", 34 | "maxclass" : "o.display", 35 | "numinlets" : 1, 36 | "numoutlets" : 1, 37 | "outlettype" : [ "" ], 38 | "patching_rect" : [ 572.0, 228.0, 207.0, 34.0 ], 39 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 40 | } 41 | 42 | } 43 | , { 44 | "box" : { 45 | "fontsize" : 12.0, 46 | "id" : "obj-6", 47 | "maxclass" : "o.display", 48 | "numinlets" : 1, 49 | "numoutlets" : 1, 50 | "outlettype" : [ "" ], 51 | "patching_rect" : [ 95.0, 228.0, 394.0, 34.0 ], 52 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 53 | } 54 | 55 | } 56 | , { 57 | "box" : { 58 | "fontsize" : 12.0, 59 | "id" : "obj-9", 60 | "maxclass" : "o.expr.codebox", 61 | "numinlets" : 1, 62 | "numoutlets" : 2, 63 | "outlettype" : [ "FullPacket", "FullPacket" ], 64 | "patching_rect" : [ 95.0, 172.0, 251.0, 37.0 ], 65 | "text" : " /bundle/time = gettimetag()", 66 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 67 | } 68 | 69 | } 70 | , { 71 | "box" : { 72 | "id" : "obj-7", 73 | "maxclass" : "bpatcher", 74 | "name" : "o.io.serial.display.maxpat", 75 | "numinlets" : 1, 76 | "numoutlets" : 1, 77 | "outlettype" : [ "FullPacket" ], 78 | "patching_rect" : [ 271.0, 58.0, 331.0, 28.0 ] 79 | } 80 | 81 | } 82 | , { 83 | "box" : { 84 | "fontname" : "Andale Mono", 85 | "fontsize" : 14.0, 86 | "frgb" : 0.0, 87 | "id" : "obj-4", 88 | "linecount" : 3, 89 | "maxclass" : "comment", 90 | "numinlets" : 1, 91 | "numoutlets" : 0, 92 | "patching_rect" : [ 592.0, 119.0, 150.0, 54.0 ], 93 | "text" : "stats on serial OSC communications" 94 | } 95 | 96 | } 97 | , { 98 | "box" : { 99 | "fontname" : "Andale Mono", 100 | "fontsize" : 14.0, 101 | "id" : "obj-26", 102 | "maxclass" : "newobj", 103 | "numinlets" : 2, 104 | "numoutlets" : 2, 105 | "outlettype" : [ "FullPacket", "FullPacket" ], 106 | "patching_rect" : [ 95.0, 119.0, 195.0, 22.0 ], 107 | "text" : "o.io.slipserial f 9600" 108 | } 109 | 110 | } 111 | ], 112 | "lines" : [ { 113 | "patchline" : { 114 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 115 | "destination" : [ "obj-7", 0 ], 116 | "disabled" : 0, 117 | "hidden" : 0, 118 | "midpoints" : [ 280.5, 141.0, 300.0, 141.0, 300.0, 96.0, 258.0, 96.0, 258.0, 54.0, 280.5, 54.0 ], 119 | "source" : [ "obj-26", 1 ] 120 | } 121 | 122 | } 123 | , { 124 | "patchline" : { 125 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 126 | "destination" : [ "obj-8", 0 ], 127 | "disabled" : 0, 128 | "hidden" : 0, 129 | "source" : [ "obj-26", 1 ] 130 | } 131 | 132 | } 133 | , { 134 | "patchline" : { 135 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 136 | "destination" : [ "obj-9", 0 ], 137 | "disabled" : 0, 138 | "hidden" : 0, 139 | "source" : [ "obj-26", 0 ] 140 | } 141 | 142 | } 143 | , { 144 | "patchline" : { 145 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 146 | "destination" : [ "obj-26", 1 ], 147 | "disabled" : 0, 148 | "hidden" : 0, 149 | "source" : [ "obj-7", 0 ] 150 | } 151 | 152 | } 153 | , { 154 | "patchline" : { 155 | "destination" : [ "obj-6", 0 ], 156 | "disabled" : 0, 157 | "hidden" : 0, 158 | "source" : [ "obj-9", 0 ] 159 | } 160 | 161 | } 162 | ], 163 | "dependency_cache" : [ { 164 | "name" : "o.io.slipserial.maxpat", 165 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/o.io/experimental/Protocols/serial", 166 | "patcherrelativepath" : "../../../../../../Documents/Max/Packages/o.io/experimental/Protocols/serial", 167 | "type" : "JSON", 168 | "implicit" : 1 169 | } 170 | , { 171 | "name" : "o.righttoleft.maxpat", 172 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/patchers/ordering", 173 | "patcherrelativepath" : "../../../../../../Documents/Max/Packages/CNMAT-odot/patchers/ordering", 174 | "type" : "JSON", 175 | "implicit" : 1 176 | } 177 | , { 178 | "name" : "o.io.serial.display.maxpat", 179 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/o.io/experimental/Protocols/serial", 180 | "patcherrelativepath" : "../../../../../../Documents/Max/Packages/o.io/experimental/Protocols/serial", 181 | "type" : "JSON", 182 | "implicit" : 1 183 | } 184 | , { 185 | "name" : "o.pack.mxo", 186 | "type" : "iLaX" 187 | } 188 | , { 189 | "name" : "o.route.mxo", 190 | "type" : "iLaX" 191 | } 192 | , { 193 | "name" : "o.union.mxo", 194 | "type" : "iLaX" 195 | } 196 | , { 197 | "name" : "o.validate.mxo", 198 | "type" : "iLaX" 199 | } 200 | , { 201 | "name" : "o.print.mxo", 202 | "type" : "iLaX" 203 | } 204 | , { 205 | "name" : "o.slip.encode.mxo", 206 | "type" : "iLaX" 207 | } 208 | , { 209 | "name" : "o.slip.decode.mxo", 210 | "type" : "iLaX" 211 | } 212 | , { 213 | "name" : "o.if.mxo", 214 | "type" : "iLaX" 215 | } 216 | , { 217 | "name" : "o.expr.codebox.mxo", 218 | "type" : "iLaX" 219 | } 220 | , { 221 | "name" : "o.display.mxo", 222 | "type" : "iLaX" 223 | } 224 | ] 225 | } 226 | 227 | } 228 | -------------------------------------------------------------------------------- /Applications/MaxMSP/examples/UDPEcho.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 6, 6 | "minor" : 1, 7 | "revision" : 9, 8 | "architecture" : "x86" 9 | } 10 | , 11 | "rect" : [ 153.0, 100.0, 758.0, 531.0 ], 12 | "bglocked" : 0, 13 | "openinpresentation" : 0, 14 | "default_fontsize" : 14.0, 15 | "default_fontface" : 0, 16 | "default_fontname" : "Andale Mono", 17 | "gridonopen" : 0, 18 | "gridsize" : [ 5.0, 5.0 ], 19 | "gridsnaponopen" : 0, 20 | "statusbarvisible" : 2, 21 | "toolbarvisible" : 1, 22 | "boxanimatetime" : 200, 23 | "imprint" : 0, 24 | "enablehscroll" : 1, 25 | "enablevscroll" : 1, 26 | "devicewidth" : 0.0, 27 | "description" : "", 28 | "digest" : "", 29 | "tags" : "", 30 | "boxes" : [ { 31 | "box" : { 32 | "fontname" : "Andale Mono", 33 | "fontsize" : 14.0, 34 | "id" : "obj-8", 35 | "maxclass" : "newobj", 36 | "numinlets" : 1, 37 | "numoutlets" : 1, 38 | "outlettype" : [ "FullPacket" ], 39 | "patching_rect" : [ 20.5, 240.0, 128.0, 22.0 ], 40 | "text" : "o.betweentimes" 41 | } 42 | 43 | } 44 | , { 45 | "box" : { 46 | "fontsize" : 14.0, 47 | "id" : "obj-7", 48 | "linecount" : 2, 49 | "maxclass" : "o.compose", 50 | "numinlets" : 2, 51 | "numoutlets" : 1, 52 | "outlettype" : [ "" ], 53 | "patching_rect" : [ 20.5, 112.0, 510.0, 42.0 ], 54 | "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 112, 105, 110, 103, 0, 0, 0, 44, 105, 0, 0, 0, 0, 0, 100, 0, 0, 0, 76, 47, 116, 104, 105, 110, 103, 0, 0, 44, 100, 105, 105, 105, 105, 105, 105, 105, 105, 115, 0, 64, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 98, 105, 103, 103, 101, 114, 32, 112, 97, 99, 107, 101, 116, 0, 0, 0 ], 55 | "saved_bundle_length" : 116, 56 | "text" : "/ping : 100,\n/thing : [100., 100, 1, 2, 3, 4, 4, 4, 4, \"bigger packet\"]", 57 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 58 | } 59 | 60 | } 61 | , { 62 | "box" : { 63 | "fontsize" : 14.0, 64 | "id" : "obj-5", 65 | "maxclass" : "o.display", 66 | "numinlets" : 1, 67 | "numoutlets" : 1, 68 | "outlettype" : [ "" ], 69 | "patching_rect" : [ 20.5, 296.0, 517.0, 36.0 ], 70 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 71 | } 72 | 73 | } 74 | , { 75 | "box" : { 76 | "fontname" : "Andale Mono", 77 | "fontsize" : 14.0, 78 | "id" : "obj-61", 79 | "maxclass" : "newobj", 80 | "numinlets" : 2, 81 | "numoutlets" : 1, 82 | "outlettype" : [ "bang" ], 83 | "patching_rect" : [ 20.5, 22.0, 153.0, 22.0 ], 84 | "text" : "metro 2 @active 1" 85 | } 86 | 87 | } 88 | , { 89 | "box" : { 90 | "fontname" : "Andale Mono", 91 | "fontsize" : 14.0, 92 | "id" : "obj-26", 93 | "maxclass" : "newobj", 94 | "numinlets" : 1, 95 | "numoutlets" : 1, 96 | "outlettype" : [ "" ], 97 | "patching_rect" : [ 20.5, 191.0, 288.0, 22.0 ], 98 | "text" : "o.io.udp 128.32.122.252 8888 9999" 99 | } 100 | 101 | } 102 | ], 103 | "lines" : [ { 104 | "patchline" : { 105 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 106 | "destination" : [ "obj-8", 0 ], 107 | "disabled" : 0, 108 | "hidden" : 0, 109 | "source" : [ "obj-26", 0 ] 110 | } 111 | 112 | } 113 | , { 114 | "patchline" : { 115 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 116 | "destination" : [ "obj-7", 0 ], 117 | "disabled" : 0, 118 | "hidden" : 0, 119 | "source" : [ "obj-61", 0 ] 120 | } 121 | 122 | } 123 | , { 124 | "patchline" : { 125 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 126 | "destination" : [ "obj-26", 0 ], 127 | "disabled" : 0, 128 | "hidden" : 0, 129 | "source" : [ "obj-7", 0 ] 130 | } 131 | 132 | } 133 | , { 134 | "patchline" : { 135 | "color" : [ 1.0, 0.8, 0.4, 1.0 ], 136 | "destination" : [ "obj-5", 0 ], 137 | "disabled" : 0, 138 | "hidden" : 0, 139 | "source" : [ "obj-8", 0 ] 140 | } 141 | 142 | } 143 | ], 144 | "dependency_cache" : [ { 145 | "name" : "o.io.udp.maxpat", 146 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/o.io/experimental/Protocols/udp", 147 | "patcherrelativepath" : "../../../../../../Documents/Max/Packages/o.io/experimental/Protocols/udp", 148 | "type" : "JSON", 149 | "implicit" : 1 150 | } 151 | , { 152 | "name" : "o.betweentimes.maxpat", 153 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/patchers/time", 154 | "patcherrelativepath" : "../../../../../../Documents/Max/Packages/CNMAT-odot/patchers/time", 155 | "type" : "JSON", 156 | "implicit" : 1 157 | } 158 | , { 159 | "name" : "o.was.maxpat", 160 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/dev", 161 | "patcherrelativepath" : "../../../../../../Documents/Max/Packages/CNMAT-odot/dev", 162 | "type" : "JSON", 163 | "implicit" : 1 164 | } 165 | , { 166 | "name" : "o.righttoleft.maxpat", 167 | "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/patchers/ordering", 168 | "patcherrelativepath" : "../../../../../../Documents/Max/Packages/CNMAT-odot/patchers/ordering", 169 | "type" : "JSON", 170 | "implicit" : 1 171 | } 172 | , { 173 | "name" : "o.display.mxo", 174 | "type" : "iLaX" 175 | } 176 | , { 177 | "name" : "o.compose.mxo", 178 | "type" : "iLaX" 179 | } 180 | , { 181 | "name" : "o.timetag.mxo", 182 | "type" : "iLaX" 183 | } 184 | , { 185 | "name" : "o.prepend.mxo", 186 | "type" : "iLaX" 187 | } 188 | , { 189 | "name" : "o.intersection.mxo", 190 | "type" : "iLaX" 191 | } 192 | , { 193 | "name" : "o.union.mxo", 194 | "type" : "iLaX" 195 | } 196 | , { 197 | "name" : "o.var.mxo", 198 | "type" : "iLaX" 199 | } 200 | , { 201 | "name" : "o.collect.mxo", 202 | "type" : "iLaX" 203 | } 204 | , { 205 | "name" : "o.if.mxo", 206 | "type" : "iLaX" 207 | } 208 | , { 209 | "name" : "o.expr.codebox.mxo", 210 | "type" : "iLaX" 211 | } 212 | ] 213 | } 214 | 215 | } 216 | -------------------------------------------------------------------------------- /Applications/MaxMSP/examples/UDPReceive.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 4, 8 | "architecture" : "x86", 9 | "modernui" : 1 10 | } 11 | , 12 | "rect" : [ 334.0, 78.0, 1072.0, 480.0 ], 13 | "bglocked" : 0, 14 | "openinpresentation" : 0, 15 | "default_fontsize" : 12.0, 16 | "default_fontface" : 0, 17 | "default_fontname" : "Arial", 18 | "gridonopen" : 1, 19 | "gridsize" : [ 15.0, 15.0 ], 20 | "gridsnaponopen" : 1, 21 | "objectsnaponopen" : 1, 22 | "statusbarvisible" : 2, 23 | "toolbarvisible" : 1, 24 | "lefttoolbarpinned" : 0, 25 | "toptoolbarpinned" : 0, 26 | "righttoolbarpinned" : 0, 27 | "bottomtoolbarpinned" : 0, 28 | "toolbars_unpinned_last_save" : 0, 29 | "tallnewobj" : 0, 30 | "boxanimatetime" : 200, 31 | "enablehscroll" : 1, 32 | "enablevscroll" : 1, 33 | "devicewidth" : 0.0, 34 | "description" : "", 35 | "digest" : "", 36 | "tags" : "", 37 | "style" : "", 38 | "subpatcher_template" : "", 39 | "boxes" : [ { 40 | "box" : { 41 | "fontface" : 0, 42 | "fontsize" : 12.0, 43 | "id" : "obj-5", 44 | "maxclass" : "o.display", 45 | "numinlets" : 1, 46 | "numoutlets" : 1, 47 | "outlettype" : [ "" ], 48 | "patching_rect" : [ 183.5, 341.0, 150.0, 34.0 ], 49 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 50 | } 51 | 52 | } 53 | , { 54 | "box" : { 55 | "fontname" : "Arial", 56 | "fontsize" : 12.0, 57 | "id" : "obj-18", 58 | "linecount" : 2, 59 | "maxclass" : "comment", 60 | "numinlets" : 1, 61 | "numoutlets" : 0, 62 | "patching_rect" : [ 498.0, 91.0, 150.0, 33.0 ], 63 | "style" : "", 64 | "text" : "control Arduino square wave tone on pin 3" 65 | } 66 | 67 | } 68 | , { 69 | "box" : { 70 | "fontface" : 0, 71 | "fontname" : "Andale Mono", 72 | "fontsize" : 14.0, 73 | "id" : "obj-15", 74 | "maxclass" : "o.message", 75 | "numinlets" : 2, 76 | "numoutlets" : 1, 77 | "outlettype" : [ "" ], 78 | "patching_rect" : [ 406.0, 168.0, 150.0, 22.0 ], 79 | "text" : "/tone/3", 80 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 81 | } 82 | 83 | } 84 | , { 85 | "box" : { 86 | "fontname" : "Arial", 87 | "fontsize" : 12.0, 88 | "id" : "obj-12", 89 | "maxclass" : "newobj", 90 | "numinlets" : 1, 91 | "numoutlets" : 1, 92 | "outlettype" : [ "" ], 93 | "patching_rect" : [ 134.0, 127.0, 34.0, 22.0 ], 94 | "style" : "", 95 | "text" : "mtof" 96 | } 97 | 98 | } 99 | , { 100 | "box" : { 101 | "id" : "obj-11", 102 | "maxclass" : "kslider", 103 | "numinlets" : 2, 104 | "numoutlets" : 2, 105 | "outlettype" : [ "int", "int" ], 106 | "parameter_enable" : 0, 107 | "patching_rect" : [ 132.0, 65.0, 336.0, 53.0 ], 108 | "presentation_rect" : [ 0.0, 0.0, 336.0, 53.0 ], 109 | "style" : "", 110 | "varname" : "kslider" 111 | } 112 | 113 | } 114 | , { 115 | "box" : { 116 | "fontname" : "Arial", 117 | "fontsize" : 12.0, 118 | "id" : "obj-9", 119 | "maxclass" : "message", 120 | "numinlets" : 2, 121 | "numoutlets" : 1, 122 | "outlettype" : [ "" ], 123 | "patching_rect" : [ 242.0, 140.0, 32.5, 22.0 ], 124 | "style" : "", 125 | "text" : "220" 126 | } 127 | 128 | } 129 | , { 130 | "box" : { 131 | "fontname" : "Arial", 132 | "fontsize" : 12.0, 133 | "id" : "obj-8", 134 | "maxclass" : "message", 135 | "numinlets" : 2, 136 | "numoutlets" : 1, 137 | "outlettype" : [ "" ], 138 | "patching_rect" : [ 184.0, 137.0, 34.0, 22.0 ], 139 | "style" : "", 140 | "text" : "440." 141 | } 142 | 143 | } 144 | , { 145 | "box" : { 146 | "id" : "obj-4", 147 | "maxclass" : "button", 148 | "numinlets" : 1, 149 | "numoutlets" : 1, 150 | "outlettype" : [ "bang" ], 151 | "patching_rect" : [ 402.0, 137.0, 20.0, 20.0 ], 152 | "style" : "" 153 | } 154 | 155 | } 156 | , { 157 | "box" : { 158 | "fontname" : "Arial", 159 | "fontsize" : 12.0, 160 | "id" : "obj-3", 161 | "linecount" : 3, 162 | "maxclass" : "comment", 163 | "numinlets" : 1, 164 | "numoutlets" : 0, 165 | "patching_rect" : [ 489.0, 279.0, 154.0, 47.0 ], 166 | "style" : "", 167 | "text" : "8888 is the port sent to on the Arduino node 128.32.122.252" 168 | } 169 | 170 | } 171 | , { 172 | "box" : { 173 | "fontface" : 0, 174 | "fontname" : "Andale Mono", 175 | "fontsize" : 14.0, 176 | "id" : "obj-20", 177 | "maxclass" : "o.message", 178 | "numinlets" : 2, 179 | "numoutlets" : 1, 180 | "outlettype" : [ "" ], 181 | "patching_rect" : [ 235.0, 234.0, 150.0, 22.0 ], 182 | "text" : "/tone/3 130.813 \n", 183 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 184 | } 185 | 186 | } 187 | , { 188 | "box" : { 189 | "fontface" : 0, 190 | "fontname" : "Andale Mono", 191 | "fontsize" : 14.0, 192 | "id" : "obj-6", 193 | "maxclass" : "o.message", 194 | "numinlets" : 2, 195 | "numoutlets" : 1, 196 | "outlettype" : [ "" ], 197 | "patching_rect" : [ 185.0, 191.0, 150.0, 22.0 ], 198 | "text" : "/tone/3 \"$1\" ", 199 | "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] 200 | } 201 | 202 | } 203 | , { 204 | "box" : { 205 | "fontname" : "Andale Mono", 206 | "fontsize" : 14.0, 207 | "id" : "obj-26", 208 | "maxclass" : "newobj", 209 | "numinlets" : 1, 210 | "numoutlets" : 1, 211 | "outlettype" : [ "" ], 212 | "patching_rect" : [ 183.5, 290.0, 288.0, 24.0 ], 213 | "style" : "", 214 | "text" : "o.io.udp 128.32.122.252 8888 9999" 215 | } 216 | 217 | } 218 | ], 219 | "lines" : [ { 220 | "patchline" : { 221 | "destination" : [ "obj-12", 0 ], 222 | "disabled" : 0, 223 | "hidden" : 0, 224 | "source" : [ "obj-11", 0 ] 225 | } 226 | 227 | } 228 | , { 229 | "patchline" : { 230 | "destination" : [ "obj-6", 0 ], 231 | "disabled" : 0, 232 | "hidden" : 0, 233 | "source" : [ "obj-12", 0 ] 234 | } 235 | 236 | } 237 | , { 238 | "patchline" : { 239 | "destination" : [ "obj-26", 0 ], 240 | "disabled" : 0, 241 | "hidden" : 0, 242 | "source" : [ "obj-15", 0 ] 243 | } 244 | 245 | } 246 | , { 247 | "patchline" : { 248 | "destination" : [ "obj-5", 0 ], 249 | "disabled" : 0, 250 | "hidden" : 0, 251 | "source" : [ "obj-26", 0 ] 252 | } 253 | 254 | } 255 | , { 256 | "patchline" : { 257 | "destination" : [ "obj-15", 0 ], 258 | "disabled" : 0, 259 | "hidden" : 0, 260 | "source" : [ "obj-4", 0 ] 261 | } 262 | 263 | } 264 | , { 265 | "patchline" : { 266 | "destination" : [ "obj-20", 1 ], 267 | "disabled" : 0, 268 | "hidden" : 0, 269 | "source" : [ "obj-6", 0 ] 270 | } 271 | 272 | } 273 | , { 274 | "patchline" : { 275 | "destination" : [ "obj-26", 0 ], 276 | "disabled" : 0, 277 | "hidden" : 0, 278 | "source" : [ "obj-6", 0 ] 279 | } 280 | 281 | } 282 | , { 283 | "patchline" : { 284 | "destination" : [ "obj-6", 0 ], 285 | "disabled" : 0, 286 | "hidden" : 0, 287 | "source" : [ "obj-8", 0 ] 288 | } 289 | 290 | } 291 | , { 292 | "patchline" : { 293 | "destination" : [ "obj-6", 0 ], 294 | "disabled" : 0, 295 | "hidden" : 0, 296 | "source" : [ "obj-9", 0 ] 297 | } 298 | 299 | } 300 | ], 301 | "dependency_cache" : [ { 302 | "name" : "o.io.udp.maxpat", 303 | "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/udp", 304 | "type" : "JSON", 305 | "implicit" : 1 306 | } 307 | , { 308 | "name" : "o.message.mxo", 309 | "type" : "iLaX" 310 | } 311 | , { 312 | "name" : "o.display.mxo", 313 | "type" : "iLaX" 314 | } 315 | ], 316 | "embedsnapshot" : 0 317 | } 318 | 319 | } 320 | -------------------------------------------------------------------------------- /Applications/MaxMSP/examples/UDPSend.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 4, 8 | "architecture" : "x86", 9 | "modernui" : 1 10 | } 11 | , 12 | "rect" : [ 443.0, 218.0, 1072.0, 480.0 ], 13 | "bglocked" : 0, 14 | "openinpresentation" : 0, 15 | "default_fontsize" : 12.0, 16 | "default_fontface" : 0, 17 | "default_fontname" : "Arial", 18 | "gridonopen" : 1, 19 | "gridsize" : [ 15.0, 15.0 ], 20 | "gridsnaponopen" : 1, 21 | "objectsnaponopen" : 1, 22 | "statusbarvisible" : 2, 23 | "toolbarvisible" : 1, 24 | "lefttoolbarpinned" : 0, 25 | "toptoolbarpinned" : 0, 26 | "righttoolbarpinned" : 0, 27 | "bottomtoolbarpinned" : 0, 28 | "toolbars_unpinned_last_save" : 0, 29 | "tallnewobj" : 0, 30 | "boxanimatetime" : 200, 31 | "enablehscroll" : 1, 32 | "enablevscroll" : 1, 33 | "devicewidth" : 0.0, 34 | "description" : "", 35 | "digest" : "", 36 | "tags" : "", 37 | "style" : "", 38 | "subpatcher_template" : "", 39 | "boxes" : [ { 40 | "box" : { 41 | "fontface" : 0, 42 | "fontsize" : 12.0, 43 | "id" : "obj-8", 44 | "maxclass" : "o.display", 45 | "numinlets" : 1, 46 | "numoutlets" : 1, 47 | "outlettype" : [ "" ], 48 | "patching_rect" : [ 277.0, 243.0, 150.0, 34.0 ], 49 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 50 | } 51 | 52 | } 53 | , { 54 | "box" : { 55 | "fontface" : 0, 56 | "fontsize" : 12.0, 57 | "id" : "obj-6", 58 | "maxclass" : "o.display", 59 | "numinlets" : 1, 60 | "numoutlets" : 1, 61 | "outlettype" : [ "" ], 62 | "patching_rect" : [ 91.0, 243.0, 150.0, 34.0 ], 63 | "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] 64 | } 65 | 66 | } 67 | , { 68 | "box" : { 69 | "fontname" : "Arial", 70 | "fontsize" : 12.0, 71 | "id" : "obj-2", 72 | "maxclass" : "newobj", 73 | "numinlets" : 1, 74 | "numoutlets" : 2, 75 | "outlettype" : [ "FullPacket", "FullPacket" ], 76 | "patching_rect" : [ 91.0, 149.0, 97.0, 22.0 ], 77 | "style" : "", 78 | "text" : "o.if exists(/units)" 79 | } 80 | 81 | } 82 | , { 83 | "box" : { 84 | "fontname" : "Arial", 85 | "fontsize" : 12.0, 86 | "id" : "obj-4", 87 | "linecount" : 2, 88 | "maxclass" : "comment", 89 | "numinlets" : 1, 90 | "numoutlets" : 0, 91 | "patching_rect" : [ 95.0, 62.0, 150.0, 33.0 ], 92 | "style" : "", 93 | "text" : "Set udp port, send and receive port respectively" 94 | } 95 | 96 | } 97 | , { 98 | "box" : { 99 | "fontname" : "Andale Mono", 100 | "fontsize" : 14.0, 101 | "id" : "obj-26", 102 | "maxclass" : "newobj", 103 | "numinlets" : 1, 104 | "numoutlets" : 1, 105 | "outlettype" : [ "" ], 106 | "patching_rect" : [ 91.0, 107.0, 288.0, 24.0 ], 107 | "style" : "", 108 | "text" : "o.io.udp 128.32.122.26 8888 9999" 109 | } 110 | 111 | } 112 | ], 113 | "lines" : [ { 114 | "patchline" : { 115 | "destination" : [ "obj-6", 0 ], 116 | "disabled" : 0, 117 | "hidden" : 0, 118 | "source" : [ "obj-2", 0 ] 119 | } 120 | 121 | } 122 | , { 123 | "patchline" : { 124 | "destination" : [ "obj-8", 0 ], 125 | "disabled" : 0, 126 | "hidden" : 0, 127 | "source" : [ "obj-2", 1 ] 128 | } 129 | 130 | } 131 | , { 132 | "patchline" : { 133 | "destination" : [ "obj-2", 0 ], 134 | "disabled" : 0, 135 | "hidden" : 0, 136 | "source" : [ "obj-26", 0 ] 137 | } 138 | 139 | } 140 | ], 141 | "dependency_cache" : [ { 142 | "name" : "o.io.udp.maxpat", 143 | "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/udp", 144 | "type" : "JSON", 145 | "implicit" : 1 146 | } 147 | , { 148 | "name" : "o.if.mxo", 149 | "type" : "iLaX" 150 | } 151 | , { 152 | "name" : "o.display.mxo", 153 | "type" : "iLaX" 154 | } 155 | ], 156 | "embedsnapshot" : 0 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /Applications/PD/o.io.slipserial.pd: -------------------------------------------------------------------------------- 1 | #N canvas 618 358 756 268 10; 2 | #X obj 95 179 mrpeach/slipdec 65536; 3 | #X obj 95 47 mrpeach/slipenc 65536; 4 | #X obj 359 20 loadbang; 5 | #X obj 95 22 inlet; 6 | #X obj 95 206 outlet; 7 | #X msg 359 83 baud 115200; 8 | #X obj 261 46 inlet; 9 | #X msg 318 46 devicename /dev/tty.usbserial-A5002rKU \, pollintervall 10 | 1; 11 | #X obj 95 135 comport; 12 | #X obj 134 157 print errors; 13 | #X connect 0 0 4 0; 14 | #X connect 1 0 8 0; 15 | #X connect 2 0 7 0; 16 | #X connect 2 0 5 0; 17 | #X connect 3 0 1 0; 18 | #X connect 5 0 8 0; 19 | #X connect 6 0 8 0; 20 | #X connect 7 0 8 0; 21 | #X connect 8 0 0 0; 22 | #X connect 8 1 9 0; 23 | -------------------------------------------------------------------------------- /Applications/Processing/SLIPSerialToUDP/GUI.pde: -------------------------------------------------------------------------------- 1 | 2 | ControlP5 cp5; 3 | 4 | void setupGUI() { 5 | //the ControlP5 object 6 | cp5 = new ControlP5(this); 7 | 8 | //start button 9 | cp5.addButton("START") 10 | .setPosition(width/2 - 100, height-30) 11 | .setSize(200, 20); 12 | 13 | //stop button 14 | cp5.addButton("STOP") 15 | .setPosition(width/2 - 100, height-30) 16 | .setSize(200, 20) 17 | .hide(); 18 | 19 | //setup the baud list 20 | DropdownList baudRate = cp5.addDropdownList("BaudRate") 21 | .setPosition(50, 130) 22 | .setSize(200, 90) 23 | .setItemHeight(20) 24 | .setBarHeight(20) 25 | .setId(4).close(); 26 | ControllerStyle baudRateStyle = baudRate.getCaptionLabel().getStyle(); 27 | baudRate.getCaptionLabel().set("SELECT THE BAUD RATE"); 28 | baudRateStyle.marginTop = baudRateStyle.marginLeft = baudRateStyle.marginTop = 3; 29 | //the baud options 30 | for (int i=0; i serialBuffer = new ArrayList(); 13 | 14 | void setupSerial() { 15 | serial = new Serial(this, Serial.list()[serialListNumber], baud); 16 | } 17 | 18 | void stopSerial() { 19 | serial.stop(); 20 | } 21 | 22 | void serialEvent(Serial serial) { 23 | //decode the message 24 | while (serial.available () > 0) { 25 | slipDecode(byte(serial.read())); 26 | } 27 | } 28 | 29 | void SerialSendToUDP() { 30 | byte [] buffer = new byte[serialBuffer.size()]; 31 | //copy the buffer over 32 | for (int i = 0; i < serialBuffer.size(); i++) { 33 | buffer[i] = serialBuffer.get(i); 34 | } 35 | //send it off 36 | UDPSendBuffer(buffer); 37 | //clear the buffer 38 | serialBuffer.clear(); 39 | //light up the indicator 40 | drawIncomingSerial(); 41 | } 42 | 43 | void serialSend(byte[] data) { 44 | 45 | //encode the message and send it 46 | for (int i = 0; i < data.length; i++){ 47 | slipEncode(data[i]); 48 | } 49 | //write the eot 50 | serial.write(eot); 51 | println(""); 52 | } 53 | 54 | /************************************************************************************ 55 | SLIP ENCODING 56 | ************************************************************************************/ 57 | 58 | byte eot = byte(192); 59 | byte slipesc = byte(219); 60 | byte slipescend = byte(220); 61 | byte slipescesc = byte(221); 62 | 63 | byte previousByte; 64 | 65 | void slipDecode(byte incoming) { 66 | byte previous = previousByte; 67 | previousByte = incoming; 68 | //if the previous was the escape char 69 | if (previous == slipesc) { 70 | //if this one is the esc eot 71 | if (incoming==slipescend) { 72 | serialBuffer.add(eot); 73 | } 74 | else if (incoming==slipescesc) { 75 | serialBuffer.add(slipesc); 76 | } 77 | } 78 | else if (incoming==eot) { 79 | //if it's the eot 80 | //send off the packet 81 | SerialSendToUDP(); 82 | } 83 | else if (incoming != slipesc) { 84 | serialBuffer.add(incoming); 85 | } 86 | } 87 | 88 | void slipEncode(byte incoming) { 89 | if(incoming == eot){ 90 | serial.write(slipesc); 91 | serial.write(slipescend); 92 | } else if(incoming==slipesc) { 93 | serial.write(slipesc); 94 | serial.write(slipescesc); 95 | } else { 96 | serial.write(incoming); 97 | } 98 | print((char)incoming); 99 | print(" "); 100 | println(incoming); 101 | } 102 | -------------------------------------------------------------------------------- /Applications/Processing/SLIPSerialToUDP/UDP.pde: -------------------------------------------------------------------------------- 1 | //UDP communication 2 | UDP udp; 3 | 4 | int inPort = 9000; 5 | int outPort = 9001; 6 | String ipAddress = "127.0.0.1"; 7 | 8 | void setupUDP() { 9 | udp = new UDP( this, inPort ); 10 | //udp.log( true ); // <-- printout the connection activity 11 | udp.listen( true ); 12 | } 13 | 14 | void stopUDP() { 15 | udp.close(); 16 | } 17 | 18 | void UDPSendBuffer(byte[] data) { 19 | udp.send( data, ipAddress, outPort ); 20 | } 21 | 22 | //called when UDP receives some data 23 | void receive( byte[] data) { 24 | drawIncomingUDP(); 25 | //send it over to serial 26 | serialSend(data); 27 | } 28 | -------------------------------------------------------------------------------- /Applications/Processing/UDPReceiveBundle/UDPReceiveBundle.pde: -------------------------------------------------------------------------------- 1 | /* 2 | Receives and visualizes OSCBundles sent over UDP 3 | 4 | Use with /examples/UDPSendBundle 5 | 6 | or with /examples/SerialSendBundle in conjunction 7 | with /Applications/Processing/SLIPSerialToUDP 8 | */ 9 | 10 | import oscP5.*; 11 | import netP5.*; 12 | 13 | OscP5 oscP5; 14 | 15 | void setup() { 16 | size(600,300); 17 | frameRate(30); 18 | //set this to the receiving port 19 | oscP5 = new OscP5(this,9001); 20 | } 21 | 22 | 23 | void draw() { 24 | background(0); 25 | //draw the analog values 26 | float analog0Height = map(analogValue0, 0, 1024, 0, 200); 27 | float analog1Height = map(analogValue1, 0, 1024, 0, 200); 28 | fill(255); 29 | rect(50, 250, 50, -analog0Height); 30 | rect(150, 250, 50, -analog1Height); 31 | //and the labels 32 | textSize(12); 33 | text("/analog/0", 50, 270); 34 | text("/analog/1", 150, 270); 35 | //and the digital pin label 36 | text("/digital/5", 250, 270); 37 | textSize(25); 38 | text(digitalValue5, 250, 250); 39 | //now do the mouse part 40 | //add the label 41 | textSize(12); 42 | text("/mouse/step", 350, 270); 43 | //make a box where it should go 44 | noFill(); 45 | stroke(255); 46 | rect(350, 50, 200, 200); 47 | //and a square where the mouse is 48 | fill(255); 49 | float mouseXPos = map(mouseStepX, 0, 1024, 350, 530); 50 | float mouseYPos = map(mouseStepY, 0, 1024, 50, 230); 51 | rect(mouseXPos, mouseYPos, 20, 20); 52 | } 53 | 54 | int analogValue0 = 50; 55 | int analogValue1 = 50; 56 | String digitalValue5 = "LOW"; 57 | 58 | int mouseStepX = 0; 59 | int mouseStepY = 0; 60 | 61 | // incoming osc message are forwarded to the oscEvent method. 62 | void oscEvent(OscMessage theOscMessage) { 63 | //println(theOscMessage.addrPattern()); 64 | if (theOscMessage.addrPattern().equals("/analog/0")){ 65 | analogValue0 = theOscMessage.get(0).intValue(); 66 | } else if(theOscMessage.addrPattern().equals("/analog/1")){ 67 | analogValue1 = theOscMessage.get(0).intValue(); 68 | } else if(theOscMessage.addrPattern().equals("/digital/5")){ 69 | digitalValue5 = theOscMessage.get(0).stringValue(); 70 | } else if(theOscMessage.addrPattern().equals("/mouse/step")){ 71 | mouseStepX = theOscMessage.get(0).intValue(); 72 | mouseStepY = theOscMessage.get(1).intValue(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Applications/Processing/UDPReceiveMessage/UDPReceiveMessage.pde: -------------------------------------------------------------------------------- 1 | /* 2 | Receives and visualizes OSCBundles sent over UDP 3 | 4 | Use with /examples/UDPSendMessage 5 | 6 | or with /examples/SerialSendMessage in conjunction 7 | with /Applications/Processing/SLIPSerialToUDP 8 | */ 9 | 10 | import oscP5.*; 11 | import netP5.*; 12 | 13 | OscP5 oscP5; 14 | 15 | void setup() { 16 | size(150,300); 17 | frameRate(30); 18 | //set this to the receiving port 19 | oscP5 = new OscP5(this,9001); 20 | } 21 | 22 | 23 | void draw() { 24 | background(0); 25 | //draw the analog values 26 | float analog0Height = map(analogValue0, 0, 1024, 0, 200); 27 | fill(255); 28 | rect(50, 250, 50, -analog0Height); 29 | //and the labels 30 | textSize(12); 31 | text("/analog/0", 50, 270); 32 | } 33 | 34 | int analogValue0 = 50; 35 | 36 | // incoming osc message are forwarded to the oscEvent method. 37 | void oscEvent(OscMessage theOscMessage) { 38 | //println(theOscMessage.addrPattern()); 39 | if (theOscMessage.addrPattern().equals("/analog/0")){ 40 | analogValue0 = theOscMessage.get(0).intValue(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Applications/Processing/serialSend/code/javaosc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CNMAT/OSC/6cea10833c1c0caa3afc419002533b50c5f613c5/Applications/Processing/serialSend/code/javaosc.jar -------------------------------------------------------------------------------- /Applications/Processing/serialSend/serialSend.pde: -------------------------------------------------------------------------------- 1 | import oscP5.*; 2 | import netP5.*; 3 | 4 | OscP5 oscP5; 5 | NetAddress arduinoAddress; 6 | //the number of analog pins on this controller 7 | int analogPins = 16; 8 | //an array of all of the pin values 9 | int[] pinVals = new int[analogPins]; 10 | 11 | void setup() { 12 | frameRate(60); 13 | size(320, 100); 14 | background(0); 15 | //initialize the listening port 16 | oscP5 = new OscP5(this, 9999); 17 | //the outgoing communication to the arduino 18 | arduinoAddress = new NetAddress("128,32.122.252", 8888); 19 | } 20 | 21 | 22 | void draw() { 23 | //clear the previous bars 24 | fill(0); 25 | rect(0, 0, width, height); 26 | //draw each of the bars showing the pin value 27 | for (int i = 0; i < analogPins; i++) { 28 | int value = pinVals[i]; 29 | int barWidth = width/analogPins; 30 | float barHeight = (value/1024.)*height; 31 | //draws the new bar in white 32 | fill(255); 33 | rect(barWidth*i, height - barHeight, barWidth, barHeight); 34 | } 35 | } 36 | 37 | // incoming osc message are forwarded to the oscEvent method. 38 | void oscEvent(OscMessage msg) { 39 | String address = msg.addrPattern(); 40 | if (address.startsWith("/analog/")) { 41 | //then it's an analog reading 42 | //split the address 43 | String[] splitAddr = address.split("/"); 44 | //the third element should be the number 45 | int pinNum = Integer.parseInt(splitAddr[2]); 46 | int val = msg.get(0).intValue(); 47 | pinVals[pinNum] = val; 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Applications/Processing/serialSend/sketch.properties: -------------------------------------------------------------------------------- 1 | mode=Android 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Written by Yotam Mann and Adrian Freed, The Center for New Music and Audio Technologies, 2 | University of California, Berkeley. Copyright (c) 2013, The Regents of 3 | the University of California (Regents). 4 | 5 | Permission to use, copy, modify, distribute, and distribute modified versions 6 | of this software and its documentation without fee and without a signed 7 | licensing agreement, is hereby granted, provided that the above copyright 8 | notice, this paragraph and the following two paragraphs appear in all copies, 9 | modifications, and distributions. 10 | 11 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 12 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 13 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 14 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 | 16 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 19 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 20 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 21 | -------------------------------------------------------------------------------- /OSCBoards.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Written by Adrian Freed, The Center for New Music and Audio Technologies, 3 | University of California, Berkeley. Copyright (c) 2013, The Regents of 4 | the University of California (Regents). 5 | 6 | Permission to use, copy, modify, distribute, and distribute modified versions 7 | of this software and its documentation without fee and without a signed 8 | licensing agreement, is hereby granted, provided that the above copyright 9 | notice, this paragraph and the following two paragraphs appear in all copies, 10 | modifications, and distributions. 11 | 12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 | 17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 21 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 22 | 23 | For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu 24 | */ 25 | 26 | 27 | #include 28 | #include "OSCBoards.h" 29 | 30 | #ifndef analogInputToDigitalPin 31 | int analogInputToDigitalPin(int i) 32 | { 33 | switch(i) 34 | { 35 | #ifdef A0 36 | case 0: return A0; 37 | #endif 38 | #ifdef A1 39 | case 1: return A1; 40 | #endif 41 | #ifdef A2 42 | case 2: return A2; 43 | #endif 44 | #ifdef A3 45 | case 3: return A3; 46 | #endif 47 | #ifdef A4 48 | case 4: return A4; 49 | #endif 50 | #ifdef A5 51 | case 5: return A5; 52 | #endif 53 | #ifdef A6 54 | case 6: return A6; 55 | #endif 56 | #ifdef A7 57 | case 7: return A7; 58 | #endif 59 | #ifdef A8 60 | case 8: return A8; 61 | #endif 62 | #ifdef A9 63 | case 9: return A9; 64 | #endif 65 | #ifdef A10 66 | case 10: return A10; 67 | #endif 68 | #ifdef A11 69 | case 11: return A11; 70 | #endif 71 | #ifdef A12 72 | case 12: return A12; 73 | #endif 74 | #ifdef A13 75 | case 13: return A13; 76 | #endif 77 | #ifdef A14 78 | case 14: return A14; 79 | #endif 80 | #ifdef A15 81 | case 15: return A15; 82 | #endif 83 | #ifdef A16 84 | case 16: return A16; 85 | #endif 86 | } 87 | return -1; 88 | } 89 | #endif 90 | 91 | 92 | #ifdef BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT 93 | #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || defined(__MK64FX512V__) || defined(__MK66FX1M0__) 94 | float getSupplyVoltage() 95 | { 96 | analogReference(DEFAULT); 97 | analogReadResolution(12); 98 | analogReadAveraging(32); 99 | PMC_REGSC |= PMC_REGSC_BGBE; // 39=bandgap ref (PMC_REGSC |= PMC_REGSC_BGBE); 100 | delay(1); 101 | 102 | #if defined(__MKL26Z64__) 103 | // Teensy 3 LC 104 | int val = analogRead(39); 105 | return val>0? (1.0f*4095/val):0.0f; 106 | #elif defined(__MK64FX512V__) || defined(__MK66FX1M0__) 107 | int val = analogRead(71); 108 | return val>0? (1.195f*4095/val):0.0f; 109 | #else 110 | int val = analogRead(39); 111 | return val>0? (1.195f*4095/val):0.0f; 112 | #endif 113 | } 114 | 115 | #else 116 | // power supply measurement on some Arduinos 117 | float getSupplyVoltage(){ 118 | // powersupply 119 | int result; 120 | // Read 1.1V reference against AVcc 121 | #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 122 | ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 123 | #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) 124 | ADMUX = _BV(MUX5) | _BV(MUX0); 125 | #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 126 | ADMUX = _BV(MUX3) | _BV(MUX2); 127 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega1280__) 128 | ADMUX = 0x40| _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) ; 129 | ADCSRB = 0; 130 | #else 131 | ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 132 | #endif 133 | delayMicroseconds(300); // wait for Vref to settle 134 | ADCSRA |= _BV(ADSC); // Convert 135 | while (bit_is_set(ADCSRA,ADSC)); 136 | result = ADCL; 137 | result |= ADCH<<8; 138 | 139 | float supplyvoltage = 1.1264f *1023 / result; 140 | return supplyvoltage; 141 | } 142 | #endif 143 | 144 | #endif 145 | 146 | #ifdef BOARD_HAS_DIE_TEMPERATURE_SENSOR 147 | 148 | #if defined(__MK20DX128__) || defined(__MK20DX256__)|| defined(__MKL26Z64__) || defined(__MK66FX1M0__) || defined(__MK64FX512V__) 149 | float getTemperature() 150 | { 151 | #if defined(__MK64FX512V__) || defined(__MK66FX1M0__) 152 | const int temppin = 70 ; 153 | #else 154 | const int temppin = 38; 155 | #endif 156 | // untested on all teensy 3.x 157 | analogReference(INTERNAL); 158 | analogReadResolution(12); 159 | analogReadAveraging(32); 160 | delay(2); 161 | 162 | float val = 25.0 + 0.17083 * (2454.19 - analogRead(temppin)); 163 | 164 | analogReference(DEFAULT); 165 | 166 | return val; 167 | } 168 | #else 169 | // temperature 170 | float getTemperature(){ 171 | int result; 172 | 173 | #if defined(__AVR_ATmega32U4__) 174 | ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0); 175 | ADCSRB = _BV(MUX5); 176 | #else 177 | ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); 178 | #endif 179 | delayMicroseconds(200); // wait for Vref to settle 180 | ADCSRA |= _BV(ADSC); // Convert 181 | while (bit_is_set(ADCSRA,ADSC)); 182 | result = ADCL; 183 | result |= ADCH<<8; 184 | 185 | analogReference(DEFAULT); 186 | 187 | return result/1023.0f; 188 | } 189 | #endif 190 | 191 | #endif 192 | -------------------------------------------------------------------------------- /OSCBoards.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSCBoards.h 3 | // 4 | // 5 | // Created by AdrianFreed on 5/26/13. 6 | // 7 | // 8 | 9 | #ifndef _OSCBoards_h 10 | #define _OSCBoards_h 11 | 12 | 13 | #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || defined(__MK66FX1M0__) 14 | // Teensy 3.0 3.1 3.1LC 3.2 3.6 15 | #define BOARD_HAS_CAPACITANCE_SENSING 16 | #endif 17 | 18 | #if defined(__AVR_ATmega32U4__) || defined(__MKL26Z64__) || defined(__MK20DX128__)|| defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__AVR_ATmega328_) || defined(__AVR_ATmega128__) 19 | 20 | #define BOARD_HAS_DIE_TEMPERATURE_SENSOR 21 | #endif 22 | 23 | #if defined(__AVR_ATmega32U4__) || defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega328_) || defined(__AVR_ATmega128__) 24 | 25 | 26 | #define BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT 27 | #endif 28 | 29 | 30 | #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega328_) || defined(__AVR_ATmega128__) 31 | #define BOARD_HAS_ANALOG_PULLUP 32 | #endif 33 | 34 | // missing specs for PIC32 35 | 36 | #if (defined(__PIC32MX__) || defined(__PIC32MZ__)) 37 | #define NUM_ANALOG_INPUTS NUM_ANALOG_PINS 38 | #define NUM_DIGITAL_INPUTS NUM_DIGITAL_PINS 39 | #define LED_BUILTIN PIN_LED1 40 | 41 | #endif 42 | 43 | 44 | #ifndef analogInputToDigitalPin 45 | int analogInputToDigitalPin(int i); 46 | #endif 47 | 48 | #ifdef BOARD_HAS_DIE_TEMPERATURE_SENSOR 49 | float getTemperature(); 50 | #endif 51 | 52 | #ifdef BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT 53 | float getSupplyVoltage(); 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /OSCBundle.h: -------------------------------------------------------------------------------- 1 | /* 2 | Written by Yotam Mann, The Center for New Music and Audio Technologies, 3 | University of California, Berkeley. Copyright (c) 2012, 2013, The Regents of 4 | the University of California (Regents). 5 | 6 | Permission to use, copy, modify, distribute, and distribute modified versions 7 | of this software and its documentation without fee and without a signed 8 | licensing agreement, is hereby granted, provided that the above copyright 9 | notice, this paragraph and the following two paragraphs appear in all copies, 10 | modifications, and distributions. 11 | 12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 | 17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 21 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 22 | 23 | 24 | */ 25 | 26 | #ifndef OSCBUNDLE_h 27 | #define OSCBUNDLE_h 28 | 29 | #include "OSCMessage.h" 30 | 31 | extern osctime_t zerotime; 32 | class OSCBundle 33 | { 34 | 35 | private: 36 | 37 | /*============================================================================= 38 | PRIVATE VARIABLES 39 | =============================================================================*/ 40 | 41 | //the array of messages contained in the bundle 42 | OSCMessage ** messages; 43 | 44 | //the number of messages in the array 45 | int numMessages; 46 | 47 | osctime_t timetag; 48 | 49 | //error codes 50 | OSCErrorCode error; 51 | 52 | /*============================================================================= 53 | DECODING INCOMING BYTES 54 | =============================================================================*/ 55 | 56 | //the decoding states for incoming bytes 57 | enum DecodeState { 58 | STANDBY, 59 | HEADER, 60 | TIMETAG, 61 | MESSAGE_SIZE, 62 | MESSAGE, 63 | } decodeState; 64 | 65 | //stores incoming bytes until they can be decoded 66 | uint8_t * incomingBuffer; 67 | int incomingBufferSize; 68 | 69 | //the size of the incoming message 70 | int incomingMessageSize; 71 | 72 | //adds a byte to the buffer 73 | void addToIncomingBuffer(uint8_t); 74 | //clears the incoming buffer 75 | void clearIncomingBuffer(); 76 | 77 | //decoding functions 78 | void decode(uint8_t); 79 | void decodeTimetag(); 80 | void decodeHeader(); 81 | void decodeMessage(uint8_t); 82 | 83 | //just a placeholder while filling 84 | OSCMessage & add(); 85 | 86 | 87 | public: 88 | 89 | /*============================================================================= 90 | CONSTRUCTORS / DESTRUCTOR 91 | =============================================================================*/ 92 | 93 | //default timetag of 94 | OSCBundle(osctime_t = zerotime); 95 | 96 | //DESTRUCTOR 97 | ~OSCBundle(); 98 | 99 | //clears all of the OSCMessages inside 100 | OSCBundle& empty(); 101 | 102 | /*============================================================================= 103 | SETTERS 104 | =============================================================================*/ 105 | 106 | //start a new OSC Message in the bundle 107 | OSCMessage & add(const char * address); 108 | //add with nothing in it produces an invalid osc message 109 | //copies an existing message into the bundle 110 | OSCMessage & add(OSCMessage & msg); 111 | 112 | template 113 | OSCBundle& setTimetag(T t){ 114 | timetag = (osctime_t) t; 115 | return *this; 116 | } 117 | //sets the timetag from a buffer 118 | OSCBundle& setTimetag(uint8_t * buff){ 119 | memcpy(&timetag, buff, 8); 120 | return *this; 121 | } 122 | 123 | /*============================================================================= 124 | GETTERS 125 | =============================================================================*/ 126 | 127 | //gets the message the matches the address string 128 | //will do regex matching 129 | OSCMessage * getOSCMessage(char * addr); 130 | 131 | //get message by position 132 | OSCMessage * getOSCMessage(int position); 133 | 134 | /*============================================================================= 135 | MATCHING 136 | =============================================================================*/ 137 | 138 | //if the bundle contains a message that matches the pattern, 139 | //call the function callback on that message 140 | bool dispatch(const char * pattern, void (*callback)(OSCMessage&), int = 0); 141 | 142 | //like dispatch, but allows for partial matches 143 | //the address match offset is sent as an argument to the callback 144 | bool route(const char * pattern, void (*callback)(OSCMessage&, int), int = 0); 145 | 146 | /*============================================================================= 147 | SIZE 148 | =============================================================================*/ 149 | //returns the number of messages in the bundle; 150 | int size(); 151 | 152 | /*============================================================================= 153 | ERROR 154 | =============================================================================*/ 155 | 156 | bool hasError(); 157 | 158 | OSCErrorCode getError(); 159 | 160 | /*============================================================================= 161 | SENDING 162 | =============================================================================*/ 163 | 164 | OSCBundle& send(Print &p); 165 | 166 | /*============================================================================= 167 | FILLING 168 | =============================================================================*/ 169 | 170 | OSCBundle& fill(uint8_t incomingByte); 171 | 172 | OSCBundle& fill(const uint8_t * incomingBytes, int length); 173 | }; 174 | 175 | #endif 176 | -------------------------------------------------------------------------------- /OSCData.h: -------------------------------------------------------------------------------- 1 | /* 2 | Written by Yotam Mann, The Center for New Music and Audio Technologies, 3 | University of California, Berkeley. Copyright (c) 2013, The Regents of 4 | the University of California (Regents). 5 | 6 | Permission to use, copy, modify, distribute, and distribute modified versions 7 | of this software and its documentation without fee and without a signed 8 | licensing agreement, is hereby granted, provided that the above copyright 9 | notice, this paragraph and the following two paragraphs appear in all copies, 10 | modifications, and distributions. 11 | 12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 | 17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 21 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 22 | 23 | For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu 24 | */ 25 | 26 | #ifndef OSCDATA_h 27 | #define OSCDATA_h 28 | 29 | #include "Arduino.h" 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "OSCTiming.h" 37 | 38 | #if (defined(TEENSYDUINO) && defined(USB_SERIAL)) || (!defined(TEENSYDUINO) && defined(__AVR_ATmega32U4__)) || defined(__SAM3X8E__) || (defined(_USB) && defined(_USE_USB_FOR_SERIAL_)) || defined(BOARD_maple_mini) 39 | 40 | #define BOARD_HAS_USB_SERIAL 41 | #if defined(__SAM3X8E__) 42 | #define thisBoardsSerialUSB SerialUSB 43 | #else 44 | #define thisBoardsSerialUSB Serial 45 | #endif 46 | #endif 47 | 48 | #if defined(ESP8266) || defined(ESP32) 49 | #define ESPxx 50 | #endif 51 | #if INT_MAX!=2147483647 52 | typedef int32_t intOSC_t; 53 | #else 54 | typedef int intOSC_t; 55 | #endif 56 | 57 | //ERRORS///////////////////////////////////////////////// 58 | typedef enum { OSC_OK = 0, 59 | BUFFER_FULL, INVALID_OSC, ALLOCFAILED, INDEX_OUT_OF_BOUNDS 60 | } OSCErrorCode; 61 | typedef struct { 62 | uint8_t r,g,b,a; 63 | } oscrgba_t; 64 | 65 | typedef struct { 66 | uint8_t port, status, channel, data1, data2; 67 | } oscmidi_t; 68 | extern osctime_t zerotime; 69 | extern oscrgba_t zeroRgba; 70 | extern oscmidi_t zeroMidi; 71 | 72 | typedef enum { 73 | OSC_NULL, OSC_IMPULSE 74 | } oscevent_t; 75 | 76 | 77 | class OSCData 78 | { 79 | 80 | private: 81 | 82 | //friends 83 | friend class OSCMessage; 84 | 85 | //should only be used while decoding 86 | //leaves an invalid OSCMessage with a type, but no data 87 | OSCData(char t); 88 | 89 | public: 90 | 91 | //an error flag 92 | OSCErrorCode error; 93 | 94 | //the size (in bytes) of the data 95 | int bytes; 96 | 97 | //the type of the data 98 | int type; 99 | 100 | //the data 101 | union { 102 | char * s; //string 103 | int32_t i; //int 104 | float f; //float 105 | double d; //double 106 | int64_t l; //long 107 | uint8_t * b; //blob 108 | oscrgba_t rgba; 109 | oscmidi_t midi; 110 | osctime_t time; 111 | oscevent_t event; 112 | } data; 113 | 114 | //overload the constructor to account for all the types and sizes 115 | OSCData(const char * s); 116 | #if defined(__SAM3X8E__) 117 | OSCData (int16_t); 118 | OSCData (uint16_t); 119 | #endif 120 | 121 | OSCData (intOSC_t); 122 | OSCData (int64_t); 123 | #if INT_MAX!=2147483647 124 | OSCData (int); 125 | #endif 126 | OSCData (unsigned int); 127 | OSCData (float); 128 | OSCData (double); 129 | OSCData (uint8_t *, int); 130 | //accepts another OSCData objects and clones it 131 | OSCData (OSCData *); 132 | OSCData (boolean); 133 | OSCData (oscrgba_t); 134 | OSCData (oscmidi_t); 135 | OSCData (oscevent_t); 136 | OSCData (osctime_t); 137 | 138 | //destructor 139 | ~OSCData(); 140 | 141 | //GETTERS 142 | int32_t getInt(); 143 | int64_t getInt64(); 144 | 145 | float getFloat(); 146 | double getDouble(); 147 | int getString(char *); 148 | int getString(char *, int); 149 | int getString(char *, int, int, int); 150 | int getBlob(uint8_t *); 151 | int getBlob(uint8_t *, int); 152 | int getBlob(uint8_t *, int, int, int); 153 | const uint8_t* getBlob(); 154 | int getBlobLength(); 155 | bool getBoolean(); 156 | oscrgba_t getRgba(); 157 | oscmidi_t getMidi(); 158 | oscevent_t getEvent(); 159 | 160 | osctime_t getTime(); 161 | 162 | //constructor from byte array with type and length 163 | OSCData(char, uint8_t *, int); 164 | //fill the passed in buffer with the data 165 | //uint8_t * asByteArray(); 166 | 167 | }; 168 | 169 | /* 170 | based on http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c 171 | 172 | if the system is little endian, it will flip the bits 173 | if the system is big endian, it'll do nothing 174 | */ 175 | template 176 | static inline T BigEndian(const T& x) 177 | { 178 | const int one = 1; 179 | const char sig = *(char*)&one; 180 | if (sig == 0) return x; // for big endian machine just return the input 181 | T ret; 182 | int size = sizeof(T); 183 | char* src = (char*)&x + sizeof(T) - 1; 184 | char* dst = (char*)&ret; 185 | while (size-- > 0){ 186 | *dst++ = *src--; 187 | } 188 | return ret; 189 | } 190 | 191 | #endif 192 | -------------------------------------------------------------------------------- /OSCMatch.c: -------------------------------------------------------------------------------- 1 | #define OSC_MATCH_ENABLE_2STARS 1 2 | #define OSC_MATCH_ENABLE_NSTARS 1 3 | /* 4 | Written by John MacCallum, The Center for New Music and Audio Technologies, 5 | University of California, Berkeley. Copyright (c) 2009, The Regents of 6 | the University of California (Regents). 7 | Permission to use, copy, modify, distribute, and distribute modified versions 8 | of this software and its documentation without fee and without a signed 9 | licensing agreement, is hereby granted, provided that the above copyright 10 | notice, this paragraph and the following two paragraphs appear in all copies, 11 | modifications, and distributions. 12 | 13 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 14 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 15 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 16 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 | 18 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 19 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 21 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 22 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | */ 24 | #include 25 | #include "OSCMatch.h" 26 | 27 | static int osc_match_star(const char *pattern, const char *address); 28 | static int osc_match_star_r(const char *pattern, const char *address); 29 | static int osc_match_single_char(const char *pattern, const char *address); 30 | static int osc_match_bracket(const char *pattern, const char *address); 31 | static int osc_match_curly_brace(const char *pattern, const char *address); 32 | 33 | int osc_match(const char *pattern, const char *address, int *pattern_offset, int *address_offset) 34 | { 35 | if(!strcmp(pattern, address)){ 36 | *pattern_offset = strlen(pattern); 37 | *address_offset = strlen(address); 38 | return OSC_MATCH_ADDRESS_COMPLETE | OSC_MATCH_PATTERN_COMPLETE; 39 | } 40 | 41 | const char *pattern_start; 42 | const char *address_start; 43 | 44 | pattern_start = pattern; 45 | address_start = address; 46 | 47 | *pattern_offset = 0; 48 | *address_offset = 0; 49 | 50 | while(*address != '\0' && *pattern != '\0'){ 51 | if(*pattern == '*'){ 52 | if(!osc_match_star(pattern, address)){ 53 | return 0; 54 | } 55 | while(*pattern != '/' && *pattern != '\0'){ 56 | pattern++; 57 | } 58 | while(*address != '/' && *address != '\0'){ 59 | address++; 60 | } 61 | }else if(*address == '*'){ 62 | while(*pattern != '/' && *pattern != '\0'){ 63 | pattern++; 64 | } 65 | while(*address != '/' && *address != '\0'){ 66 | address++; 67 | } 68 | }else{ 69 | int n = 0; 70 | if(!(n = osc_match_single_char(pattern, address))){ 71 | return 0; 72 | } 73 | if(*pattern == '['){ 74 | while(*pattern != ']'){ 75 | pattern++; 76 | } 77 | pattern++; 78 | address++; 79 | }else if(*pattern == '{'){ 80 | while(*pattern != '}'){ 81 | pattern++; 82 | } 83 | pattern++; 84 | address += n; 85 | }else{ 86 | pattern++; 87 | address++; 88 | } 89 | } 90 | } 91 | 92 | *pattern_offset = pattern - pattern_start; 93 | *address_offset = address - address_start; 94 | 95 | int r = 0; 96 | 97 | if(*address == '\0') { 98 | r |= OSC_MATCH_ADDRESS_COMPLETE; 99 | } 100 | 101 | if(*pattern == '\0') { 102 | r |= OSC_MATCH_PATTERN_COMPLETE; 103 | } 104 | 105 | return r; 106 | } 107 | 108 | static int osc_match_star(const char *pattern, const char *address) 109 | { 110 | const char *address_start = address; 111 | const char *pattern_start = pattern; 112 | int num_stars = 0; 113 | if(*address == '\0') { return 0; } 114 | while(*address != '/' && *address != '\0'){ 115 | address++; 116 | } 117 | while(*pattern != '/' && *pattern != '\0'){ 118 | if(*pattern == '*'){ 119 | num_stars++; 120 | } 121 | pattern++; 122 | } 123 | pattern--; 124 | address--; 125 | switch(num_stars){ 126 | case 1: 127 | { 128 | const char *pp = pattern, *aa = address; 129 | while(*pp != '*'){ 130 | if(!(osc_match_single_char(pp, aa))){ 131 | return 0; 132 | } 133 | if(*pp == ']' || *pp == '}'){ 134 | while(*pp != '[' && *pp != '{'){ 135 | pp--; 136 | } 137 | } 138 | pp--; 139 | aa--; 140 | } 141 | } 142 | break; 143 | case 2: 144 | #if (OSC_MATCH_ENABLE_2STARS == 1) 145 | { 146 | const char *pp = pattern, *aa = address; 147 | while(*pp != '*'){ 148 | if(!(osc_match_single_char(pp, aa))){ 149 | return 0; 150 | } 151 | if(*pp == ']' || *pp == '}'){ 152 | while(*pp != '[' && *pp != '{'){ 153 | pp--; 154 | } 155 | } 156 | pp--; 157 | aa--; 158 | } 159 | aa++; // we want to start one character forward to allow the star to match nothing 160 | const char *star2 = pp; 161 | const char *test = aa; 162 | int i = 0; 163 | while(test > address_start){ 164 | pp = star2 - 1; 165 | aa = test - 1; 166 | i++; 167 | while(*pp != '*'){ 168 | if(!osc_match_single_char(pp, aa)){ 169 | break; 170 | } 171 | if(*pp == ']' || *pp == '}'){ 172 | while(*pp != '[' && *pp != '{'){ 173 | pp--; 174 | } 175 | } 176 | pp--; 177 | aa--; 178 | } 179 | if(pp == pattern_start){ 180 | return 1; 181 | } 182 | test--; 183 | } 184 | return 0; 185 | } 186 | break; 187 | #else 188 | return 0; 189 | #endif 190 | default: 191 | #if (OSC_MATCH_ENABLE_NSTARS == 1) 192 | return osc_match_star_r(pattern_start, address_start); 193 | break; 194 | #else 195 | return 0; 196 | #endif 197 | } 198 | return 1; 199 | } 200 | 201 | #if (OSC_MATCH_ENABLE_NSTARS == 1) 202 | static int osc_match_star_r(const char *pattern, const char *address) 203 | { 204 | if(*address == '/' || *address == '\0'){ 205 | if(*pattern == '/' || *pattern == '\0' || (*pattern == '*' && ((*(pattern + 1) == '/') || *(pattern + 1) == '\0'))){ 206 | return 1; 207 | }else{ 208 | return 0; 209 | } 210 | } 211 | if(*pattern == '*'){ 212 | if(osc_match_star_r(pattern + 1, address)){ 213 | return 1; 214 | }else{ 215 | return osc_match_star_r(pattern, address + 1); 216 | } 217 | }else{ 218 | if(!osc_match_single_char(pattern, address)){ 219 | return 0; 220 | } 221 | if(*pattern == '[' || *pattern == '{'){ 222 | while(*pattern != ']' && *pattern != '}'){ 223 | pattern++; 224 | } 225 | } 226 | return osc_match_star_r(pattern + 1, address + 1); 227 | } 228 | } 229 | #endif 230 | 231 | static int osc_match_single_char(const char *pattern, const char *address) 232 | { 233 | switch(*pattern){ 234 | case '[': 235 | return osc_match_bracket(pattern, address); 236 | case ']': 237 | while(*pattern != '['){ 238 | pattern--; 239 | } 240 | return osc_match_bracket(pattern, address); 241 | case '{': 242 | return osc_match_curly_brace(pattern, address); 243 | case '}': 244 | while(*pattern != '{'){ 245 | pattern--; 246 | } 247 | return osc_match_curly_brace(pattern, address); 248 | case '?': 249 | return 1; 250 | default: 251 | if(*pattern == *address){ 252 | return 1; 253 | }else{ 254 | return 0; 255 | } 256 | } 257 | return 0; 258 | } 259 | 260 | static int osc_match_bracket(const char *pattern, const char *address) 261 | { 262 | pattern++; 263 | int val = 1; 264 | if(*pattern == '!'){ 265 | pattern++; 266 | val = 0; 267 | } 268 | int matched = !val; 269 | while(*pattern != ']' && *pattern != '\0'){ 270 | // the character we're on now is the beginning of a range 271 | if(*(pattern + 1) == '-'){ 272 | if(*address >= *pattern && *address <= *(pattern + 2)){ 273 | matched = val; 274 | break; 275 | }else{ 276 | pattern += 3; 277 | } 278 | }else{ 279 | // just test the character 280 | if(*pattern == *address){ 281 | matched = val; 282 | break; 283 | } 284 | pattern++; 285 | } 286 | } 287 | return matched; 288 | } 289 | 290 | static int osc_match_curly_brace(const char *pattern, const char *address) 291 | { 292 | pattern++; 293 | const char *ptr = pattern; 294 | while(*ptr != '}' && *ptr != '\0' && *ptr != '/'){ 295 | while(*ptr != '}' && *ptr != '\0' && *ptr != '/' && *ptr != ','){ 296 | ptr++; 297 | } 298 | int n = ptr - pattern; 299 | if(!strncmp(pattern, address, n)){ 300 | return n; 301 | }else{ 302 | ptr++; 303 | pattern = ptr; 304 | } 305 | } 306 | return 0; 307 | } -------------------------------------------------------------------------------- /OSCMatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | Written by John MacCallum, The Center for New Music and Audio Technologies, 3 | University of California, Berkeley. Copyright (c) 2009, The Regents of 4 | the University of California (Regents). 5 | Permission to use, copy, modify, distribute, and distribute modified versions 6 | of this software and its documentation without fee and without a signed 7 | licensing agreement, is hereby granted, provided that the above copyright 8 | notice, this paragraph and the following two paragraphs appear in all copies, 9 | modifications, and distributions. 10 | 11 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 12 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 13 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 14 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 | 16 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 19 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 20 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 21 | */ 22 | 23 | #ifndef __OSC_MATCH_H__ 24 | #define __OSC_MATCH_H__ 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /** 31 | * Switch this off to disable matching against a pattern with 2 stars 32 | */ 33 | //#define OSC_MATCH_ENABLE_2STARS 1 34 | /** 35 | * Switch this off to disable matching against a pattern with more than 2 stars which will 36 | * be done recursively. 37 | */ 38 | //#define OSC_MATCH_ENABLE_NSTARS 1 39 | 40 | /** 41 | * Return code for osc_match() that indicates that the entire address was successfully matched 42 | */ 43 | #define OSC_MATCH_ADDRESS_COMPLETE 1 44 | 45 | /** 46 | * Return code for osc_match() that indicates that the entire pattern was successfully matched 47 | */ 48 | #define OSC_MATCH_PATTERN_COMPLETE 2 49 | /* 50 | typedef struct _osc_callback { 51 | const char* address; // Address 52 | struct _osc_callback *child; // RAM 53 | struct _osc_callback *sibling; // RAM 54 | struct _osc_callback *parent; // RAM 55 | int callback; // ROM 56 | } osc_callback; 57 | */ 58 | 59 | /** 60 | * Match a pattern against an address. In the case of a partial match, pattern_offset 61 | * and address_offset will contain the number of bytes into their respective strings 62 | * where the match failed. 63 | * 64 | * @param pattern The pattern to match 65 | * @param address The address to match 66 | * @param pattern_offset The number of bytes into the pattern that were matched successfully 67 | * @param address_offset The number of bytes into the address that were matched successfully 68 | * @return 0 if the match failed altogether, or an or'd combination of OSC_MATCH_ADDRESS_COMPLETE and 69 | * OSC_MATCH_PATTERN_COMPLETE. 70 | */ 71 | int osc_match(const char *pattern, const char *address, int *pattern_offset, int *address_offset); 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif // __OSC_MATCH_H__ 78 | 79 | -------------------------------------------------------------------------------- /OSCTiming.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Written by Adrian Freed, The Center for New Music and Audio Technologies, 3 | University of California, Berkeley. Copyright (c) 2013, The Regents of 4 | the University of California (Regents). 5 | 6 | Permission to use, copy, modify, distribute, and distribute modified versions 7 | of this software and its documentation without fee and without a signed 8 | licensing agreement, is hereby granted, provided that the above copyright 9 | notice, this paragraph and the following two paragraphs appear in all copies, 10 | modifications, and distributions. 11 | 12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 | 17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 21 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 22 | 23 | For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu 24 | */ 25 | 26 | 27 | #include "OSCTiming.h" 28 | 29 | #if defined(TEENSYDUINO) && defined(__arm__) 30 | extern volatile uint32_t systick_millis_count; 31 | static uint32_t savedcount, savedcurrent; 32 | 33 | static void latchOscTime() 34 | { 35 | 36 | uint32_t istatus; 37 | uint32_t count, current; 38 | 39 | __disable_irq(); 40 | current = SYST_CVR; 41 | count = systick_millis_count; 42 | istatus = SCB_ICSR; // bit 26 indicates if systick exception pending 43 | __enable_irq(); 44 | //systick_current = current; 45 | //systick_count = count; 46 | //systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0; 47 | if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++; 48 | current = ((F_CPU / 1000) - 1) - current; 49 | savedcount=count; savedcurrent=current; 50 | } 51 | static osctime_t computeOscTime() 52 | { //4,294,967,296 53 | 54 | 55 | osctime_t t; 56 | 57 | 58 | t.seconds = (( uint64_t)(savedcount/1000)) ; 59 | 60 | 61 | t.fractionofseconds = ( (uint64_t)(4294967295) * ( (savedcount * 1000 + (uint64_t)savedcurrent / (F_CPU / 1000000UL)) % 1000000) ) /1000000; 62 | return t; 63 | } 64 | 65 | osctime_t oscTime() 66 | { 67 | latchOscTime(); 68 | return computeOscTime(); 69 | } 70 | 71 | #elif defined(CORE_TEENSY) 72 | extern volatile uint32_t timer0_millis_count; 73 | static uint32_t savedcount, savedmicros; 74 | 75 | static void latchOscTime() 76 | { 77 | noInterrupts(); 78 | savedcount = timer0_millis_count; 79 | savedmicros = micros(); 80 | interrupts(); 81 | } 82 | 83 | static osctime_t computeOscTime() 84 | { //4,294,967,296 85 | osctime_t t; 86 | savedmicros %= 1000000; 87 | t.fractionofseconds= (67108864ULL * savedmicros) / 15625 ; // 2^32/1000000 88 | t.seconds = savedcount/1000; 89 | return t; 90 | #ifdef ddfgsdfgsdfgsdfg 91 | return ((savedcount/1000)<<32) + ( (4294967295ULL) * ( (savedcount * 1000ULL + savedmicros) % 1000000ULL) ) /1000000ULL 92 | 93 | ; 94 | #endif 95 | 96 | 97 | } 98 | osctime_t oscTime() 99 | { 100 | latchOscTime(); 101 | return computeOscTime(); 102 | 103 | } 104 | #elif defined(AVR) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__) || defined(_SAMD21_) || defined(__ARM__) 105 | static uint32_t savedcount, savedmicros; 106 | 107 | 108 | static void latchOscTime() 109 | { 110 | noInterrupts(); 111 | //cli(); 112 | savedcount = millis(); 113 | savedmicros = micros(); 114 | interrupts(); 115 | //sei(); 116 | } 117 | 118 | osctime_t computeOscTime() 119 | { //4,294,967,296 120 | osctime_t t; 121 | savedmicros %= 1000000UL; 122 | // t.fractionofseconds = (67108864ULL * (uint64_t)savedmicros) / 15625ULL ; // 2^32/1000000 123 | t.fractionofseconds= (67108864UL * savedmicros)/ 15625ULL ; // 2^32/1000000 124 | t.seconds = savedcount/1000; 125 | return t; 126 | 127 | 128 | 129 | } 130 | osctime_t oscTime() 131 | { 132 | latchOscTime(); 133 | return computeOscTime(); 134 | } 135 | 136 | #else 137 | 138 | 139 | 140 | static void latchOscTime() 141 | { 142 | } 143 | 144 | osctime_t oscTime() 145 | { 146 | osctime_t t; 147 | t.fractionofseconds = 1; 148 | return t; 149 | 150 | } 151 | #endif 152 | 153 | int adcRead(int pin, osctime_t *t) 154 | { 155 | latchOscTime(); 156 | 157 | int v =analogRead(pin); 158 | *t = oscTime(); 159 | return v; 160 | } 161 | #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || defined(__MK66FX1M0__) 162 | int capacitanceRead(int pin, osctime_t *t) 163 | { 164 | latchOscTime(); 165 | int v = touchRead(pin); 166 | 167 | *t = oscTime(); 168 | return v; 169 | } 170 | #endif 171 | int inputRead(int pin, osctime_t *t) 172 | { 173 | 174 | int v =digitalRead(pin); 175 | *t = oscTime(); 176 | 177 | return v; 178 | } 179 | -------------------------------------------------------------------------------- /OSCTiming.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSCTiming.h 3 | // 4 | // 5 | // Created by AdrianFreed on 11/10/13. 6 | // 7 | // 8 | 9 | #ifndef ____OSCTiming__ 10 | #define ____OSCTiming__ 11 | 12 | 13 | #include "Arduino.h" 14 | #include 15 | #include 16 | #include 17 | typedef struct 18 | { 19 | uint32_t seconds; 20 | uint32_t fractionofseconds; 21 | } osctime_t; 22 | 23 | osctime_t oscTime(); 24 | int adcRead(int pin, osctime_t *t); 25 | int capacitanceRead(int pin, osctime_t *t); 26 | 27 | int inputRead(int pin, uint64_t *t); 28 | 29 | 30 | #endif /* defined(____OSCTiming__) */ 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OSC for Arduino 2 | 3 | This is an Arduino and Teensy library implementation of the [OSC](http://opensoundcontrol.org) (Open Sound Control) encoding.It was developed primarily by Yotam Mann and Adrian Freed at CNMAT where OSC was invented. It benefits from contributions from John MacCallum, Matt Wright, Jeff Lubow and Andy Schmeder and many beta testers. 4 | 5 | Features: 6 | 7 | * Supports the four basic OSC data types (32-bit integers, 32-bit floats, strings, and blobs - arbitrary length byte sequences) 8 | * Supports the optional 64-bit timetag data type and Booleans 9 | * Address pattern matching 10 | * Dynamic memory allocation 11 | * Sends and receives OSC packets over transport layers that implements the Arduino Stream Class such as Serial and Ethernet UDP 12 | 13 | # Installation 14 | 15 | We recommend Arduino 1.8.5 and a compatible Teensyduino overlay if you use the Teensy. Install using the library manager. 16 | 17 | Additional information about installing libraries on [Arduino's website](https://www.arduino.cc/en/Guide/Libraries). 18 | 19 | # Examples 20 | 21 | The `Applications` folder contains examples for Max/MSP and PD and Processing that work with the example sketches. This will be expanded to include other applications like TouchOSC and Processing. For the Max/MSP examples you will need to download the CNMAT max externals package that includes the "o." objects available [here](http://cnmat.berkeley.edu/downloads). 22 | 23 | # API 24 | 25 | OSC for Arduino supports creating, sending and receiving OSCMessages individually and wrapped into OSCBundles. 26 | 27 | The full API is available [here](./API.md). 28 | 29 | ### Sending Data 30 | 31 | Create a new `OSCMessage` with an address in the constructor: 32 | 33 | ```C++ 34 | OSCMessage msg("/address"); 35 | ``` 36 | 37 | add some data to it: 38 | 39 | ```C++ 40 | msg.add(1); 41 | msg.add(2.0); 42 | msg.add("three"); 43 | ``` 44 | 45 | `add` will infer the type of the data and encode it correctly. The API also supports chaining, so multiple calls to `add` can be strung together: 46 | 47 | ```C++ 48 | msg.add(1).add(2.0f).add("three"); 49 | ``` 50 | 51 | Then send it over any transport layer that extends Arduino's [Print class](http://playground.arduino.cc/Code/Printclass) like the `Serial` out. 52 | 53 | ```C++ 54 | msg.send(Serial); 55 | ``` 56 | 57 | ### Receiving Data 58 | 59 | In a typical Serial stream, there is no way to know where one message ends and another begins. That's why we recommend using `SLIPSerial` (which also comes in the OSC for Arduino Package). Read more about the lightweight [SLIP encoding](https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol). 60 | 61 | To receive an OSCMessage, wait for the end of SLIP Stream, and fill an empty OSCMessage with the available bytes: 62 | 63 | ```C++ 64 | //make an empty message to fill with the incoming data 65 | OSCMessage msg; 66 | //wait for the end of the packet to be received 67 | while(!SLIPSerial.endofPacket()){ 68 | int size = SLIPSerial.available(); 69 | if (size > 0){ 70 | //fill the msg with all of the available bytes 71 | while(size--){ 72 | msg.fill(SLIPSerial.read()); 73 | } 74 | } 75 | } 76 | ``` 77 | 78 | Now you can query and use the data you received: 79 | 80 | ```C++ 81 | //returns true if the data in the first position is an integer 82 | if (msg.isInt(0)){ 83 | //get that integer 84 | int data = msg.getInt(0); 85 | } 86 | ``` 87 | 88 | ### Routing / Dispatching 89 | 90 | OSCMessages can be routed to a specific function by matching their address exactly or with an OSC pattern. 91 | 92 | `dispatch` will do a full match on the OSCMessage's address or patterned address. 93 | 94 | ```C++ 95 | OSCMessage msg("/a/1"); 96 | msg.dispatch("/a/1", dispatchAddress); 97 | ``` 98 | 99 | And the function definition of `dispatchAddress` could be as follows: 100 | 101 | ```C++ 102 | //called whenever an OSCMessage's address matches "/a/1" 103 | void dispatchAddress(OSCMessage &msg){ 104 | //do something with the OSCMessage... 105 | if (msg.isFloat(0)){ 106 | float val = msg.getFloat(0); 107 | } 108 | } 109 | ``` 110 | 111 | `route` does the same thing as `dispatch` but allows for partial address matching as long as they are aligned to a `/` character. 112 | 113 | ```C++ 114 | OSCMessage msg("/b/2"); 115 | msg.route("/b", routeAddress); 116 | ``` 117 | 118 | ```C++ 119 | //called whenever an OSCMessage's address matches "/b" 120 | void routeAddress(OSCMessage &msg, int addressOffset){ 121 | //do something with the OSCMessage... 122 | if (msg.isBoolean(0)){ 123 | bool val = msg.getBoolean(0); 124 | } 125 | } 126 | ``` 127 | 128 | ### OSCBundles 129 | 130 | An OSCBundle is a group of OSCMessage that can be sent and received together. 131 | 132 | ```C++ 133 | OSCBundle bundle; 134 | //add a new OSCMessage to the bundle with the address "/a" 135 | OSCMessage msgA = bundle.add("/a"); 136 | //add some data to that message 137 | msgA.add("some data"); 138 | //append another OSCMessage, this time chaining 'add' calls 139 | bundle.add("/b").add("some more data").add("even more data"); 140 | ``` 141 | 142 | Now send the OSCBundle over SLIPSerial 143 | 144 | ```C++ 145 | //start a new SLIP Packet 146 | SLIPSerial.beginPacket(); 147 | //send the data 148 | bundle.send(SLIPSerial); 149 | //end the packet 150 | SLIPSerial.endPacket(); 151 | ``` 152 | 153 | ### SLIP Serial 154 | 155 | The OSC for Arduino library includes extensions of the USB serial and Hardware serial functions of the Arduino core that sends and receives data using the SLIP encoding. This makes Max/MSP and PD integration very simple using CNMAT's o.io.slipserial. The SLIPSerial library implements the same methods as the Serial object with additional `beginPacket` and `endPacket` methods to mark the boundaries of each packet in a serial stream. 156 | 157 | When sending data, begin each packet with `SLIPSerial.beginPacket()`, then write any data to the SLIPSerial and signify the end of the packet using `SLIPSerial.endPacket()`. 158 | 159 | On the receiving side, in addition to the normal `read` and `available` methods of the Serial object, SLIPSerial includes `SLIPSerial.endofPacket()` which returns true when the EOT (End Of Transmission) character is received, marking the end of the data packet. 160 | 161 | # Oscuino 162 | 163 | As well as many small examples illustrating the API, there is a larger application called "oscuino" that illustrates how to use OSC to simplify situations Firmata and Maxuino are typically used in. 164 | 165 | # Support 166 | 167 | ### IDEs 168 | 169 | Arduino 1.8.5 170 | 171 | Best Supported Board: 172 | ARM boards such M0, Zero, Teensy 3.0 and 3.1 and LC have the performance and memory that afford rich OSC implementations. 173 | Our primary test platform for new development is the Teensy 3.x series which currently offers the best performance 174 | of any of the Arduinos and variants. We greatly appreciate Paul Stoffregen's ongoing work 175 | with "best practice" engineering of high performance micro-controllers. 176 | 177 | ### Unsupported boards 178 | 179 | Arduino Yun and related openwrt/arduino hybrids (e.g. Draguino): 180 | 181 | Marco Brianza is exploring these interesting approaches to running this OSC library on the Atmel 32u4 in the Yun: 182 | https://github.com/cylinderlight/udp2serial 183 | https://github.com/cylinderlight/udp2serialSPI 184 | 185 | The Yun still lacks the Linux-side support to reliably move data between the 32u4 and the router's cpu. We recommend that you add a Teensy to the USB port of an OpenWrt router to get good performance and reliability with our library. 186 | 187 | # Testing 188 | 189 | OSC for Arduino comes with a small suite of tests to validate its functionality and test compatibility when new platforms come out. The tests are broken into a number of individual `.ino` files located in the `test` folder. 190 | 191 | The tests require [ArduinoUnit](https://github.com/mmurdoch/arduinounit) to be installed in the `libraries` folder. The results of the test are printed to the Serial console. 192 | 193 | Tested on: 194 | 195 | * Esplora 196 | * Leonardo 197 | * Teensy 3.x 198 | * Mega 2560 199 | 200 | # Performance 201 | 202 | Currently best performance is achieved with Arduinos with built-in USB Serial, i.e. Teensy 3.0, Teensy 2.0 and 2.0++ and Leanardo variants (12Mbps max). 203 | 204 | This is because the Wiznet 5100 used in the Ethernet Arduino and shields uses really slow SPI (0.3Mbps). This will change as people retool to use the much faster Wiznet 5200 which has been measured with the Due at 6Mbps. 205 | 206 | References: 207 | * http://forum.pjrc.com/threads/17951-WIZ820io-Ethernet-and-2nd-power-supply-with-teensy-3-0 208 | * http://arduino.cc/forum/index.php?topic=139147.0 209 | 210 | The serial examples use a 9600 baud rate which is reliable on most of the FTDI based Arduinos. The slow rate is required for Arduino's without clock chips such as the TinyLili. Once you have established that things work at 9600 baud you will find it very beneficial to increase the rate. e.g. `Serial.begin(345600); // !! 115200, 230400, 345600, 460800 X` 211 | 212 | # Future development ideas 213 | 214 | * WIFI examples 215 | * STM32 support 216 | * Intel Galileo support 217 | * HiFive Support 218 | * Photon Support 219 | * support for special OSC types in CNMAT's "o." especially subbundles 220 | * examples for recent OSC support in node.js and Node Red 221 | * nested bundles 222 | * performance tuning 223 | * Photon spark core examples 224 | * Better Time Tags that avoid the overflow limitation of Arduino timer code 225 | * Time Tag synchronization 226 | * Bluetooth LE 227 | * TCP/IP Examples 228 | * examples for more applications (i.e. TouchOSC, Processing with SLIP) 229 | * deadline scheduling of OSC 64-bit timetags 230 | * ADK support 231 | 232 | We welcome and appreciate your contributions and feedback. 233 | 234 | # New in this release 235 | ESPxx, M0, PIC32 -------------------------------------------------------------------------------- /SLIPEncodedSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | Extends the Serial class to encode SLIP over serial 3 | */ 4 | #include "Arduino.h" 5 | 6 | #ifndef SLIPEncodedSerial_h 7 | #define SLIPEncodedSerial_h 8 | 9 | #include 10 | #ifdef ARDUINO_API_VERSION 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | 17 | 18 | #if (defined(TEENSYDUINO) && (defined(USB_SERIAL) || defined(USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL) || defined(USB_SERIAL_HID) || defined(USB_MIDI_SERIAL) || defined(USB_MIDI_AUDIO_DUAL_SERIAL) || defined(USB_MIDI4_SERIAL) || defined(USB_MIDI16_SERIAL) || defined(USB_MIDI_AUDIO_SERIAL) || defined(USB_MIDI16_AUDIO_SERIAL))) || (!defined(TEENSYDUINO) && defined(__AVR_ATmega32U4__)) || defined(ARDUINO_SAMD_ADAFRUIT)|| defined(__SAM3X8E__) || (defined(_USB) && defined(_USE_USB_FOR_SERIAL_)) || defined(_SAMD21_) || defined(__PIC32MX__) || defined(__PIC32MZ__) || defined(ARDUINO_USB_CDC_ON_BOOT) || defined(ARDUINO_ARCH_RP2040) 19 | #define BOARD_HAS_USB_SERIAL 20 | 21 | 22 | //import the serial USB object 23 | #if defined(TEENSYDUINO) && defined (__arm__) 24 | #if !defined(USB_HOST_TEENSY36_) 25 | #include 26 | #endif 27 | #elif defined(TEENSYDUINO) && defined (__AVR__) 28 | #include 29 | #elif defined(__SAM3X8E__) || defined(_SAMD21_) 30 | #include 31 | #elif (defined(__PIC32MX__) || defined(__PIC32MZ__) || defined(ARDUINO_USB_CDC_ON_BOOT)) 32 | #include 33 | #elif defined(__AVR_ATmega32U4__) 34 | #include "USBAPI.h" 35 | #include 36 | #elif defined(ARDUINO_ARCH_RP2040) 37 | #include 38 | #elif defined(ARDUINO_SAMD_ADAFRUIT) 39 | #include "USB/USBAPI.h" 40 | #else 41 | #error Unknown USB port 42 | #endif 43 | 44 | #endif 45 | 46 | template 47 | class _SLIPSerial: public Stream{ 48 | 49 | private: 50 | // state machine for SLIP escape characters 51 | enum erstate {CHAR, FIRSTEOT, SECONDEOT, SLIPESC } rstate; 52 | 53 | //the serial port used 54 | T * serial; 55 | 56 | public: 57 | _SLIPSerial(T &s) 58 | { 59 | serial = &s; 60 | rstate = CHAR; 61 | } 62 | 63 | static const uint8_t eot = 0300; 64 | static const uint8_t slipesc = 0333; 65 | static const uint8_t slipescend = 0334; 66 | static const uint8_t slipescesc = 0335; 67 | /* 68 | SERIAL METHODS 69 | */ 70 | bool endofPacket() 71 | { 72 | if(rstate == SECONDEOT) 73 | { 74 | rstate = CHAR; 75 | return true; 76 | } 77 | if (rstate==FIRSTEOT) 78 | { 79 | if(serial->available() || (serial->peek() != -1)) 80 | { 81 | uint8_t c =serial->peek(); 82 | if(c==eot) 83 | { 84 | serial->read(); // throw it on the floor 85 | } 86 | } 87 | rstate = CHAR; 88 | return true; 89 | } 90 | return false; 91 | } 92 | int available(){ 93 | back: 94 | uint8_t cnt = serial->available(); 95 | 96 | if((cnt==0) && (serial->peek()==-1)) 97 | return 0; 98 | if(rstate==CHAR) 99 | { 100 | uint8_t c =serial->peek(); 101 | if(c==slipesc) 102 | { 103 | rstate = SLIPESC; 104 | serial->read(); // throw it on the floor 105 | goto back; 106 | } 107 | else if( c==eot) 108 | { 109 | rstate = FIRSTEOT; 110 | serial->read(); // throw it on the floor 111 | goto back; 112 | } 113 | return 1; // we may have more but this is the only sure bet 114 | } 115 | else if(rstate==SLIPESC) 116 | return 1; 117 | else if(rstate==FIRSTEOT) 118 | { 119 | if(serial->peek()==eot) 120 | { 121 | rstate = SECONDEOT; 122 | serial->read(); // throw it on the floor 123 | return 0; 124 | } 125 | rstate = CHAR; 126 | }else if (rstate==SECONDEOT) { 127 | rstate = CHAR; 128 | } 129 | 130 | return 0; 131 | 132 | } 133 | 134 | //reads a byte from the buffer 135 | int read(){ 136 | back: 137 | uint8_t c = serial->read(); 138 | if(rstate==CHAR) 139 | { 140 | if(c==slipesc) 141 | { 142 | rstate=SLIPESC; 143 | goto back; 144 | } 145 | else if(c==eot){ 146 | 147 | return -1; // xxx this is an error 148 | } 149 | return c; 150 | } 151 | else 152 | if(rstate==SLIPESC) 153 | { 154 | rstate=CHAR; 155 | if(c==slipescend) 156 | return eot; 157 | else if(c==slipescesc) 158 | return slipesc; 159 | else { 160 | // insert some error code here 161 | return -1; 162 | } 163 | 164 | } 165 | else 166 | return -1; 167 | } 168 | size_t readBytes( uint8_t *buffer, size_t size) 169 | { 170 | size_t count = 0; 171 | while(!endofPacket() && available() && (size>0)) 172 | { 173 | int c = read(); 174 | if(c>=0) 175 | { 176 | *buffer++ = c; 177 | ++count; 178 | --size; 179 | 180 | } 181 | else 182 | break; 183 | } 184 | return count; 185 | } 186 | // as close as we can get to correct behavior 187 | int peek(){ 188 | int c = serial->peek(); 189 | if(rstate==SLIPESC) 190 | { 191 | if(c==slipescend) 192 | return eot; 193 | else if(c==slipescesc) 194 | return slipesc; 195 | } 196 | return c; 197 | } 198 | 199 | //encode SLIP 200 | size_t write(uint8_t b){ 201 | if(b == eot){ 202 | serial->write(slipesc); 203 | return serial->write(slipescend); 204 | } else if(b==slipesc) { 205 | serial->write(slipesc); 206 | return serial->write(slipescesc); 207 | } else { 208 | return serial->write(b); 209 | } 210 | } 211 | size_t write(const uint8_t *buffer, size_t size) 212 | { 213 | size_t result=0; 214 | while(size--) 215 | { 216 | result = write(*buffer++); 217 | } 218 | return result; 219 | } 220 | 221 | 222 | void begin(unsigned long baudrate){ 223 | serial->begin(baudrate); 224 | } 225 | // for bluetooth 226 | void begin(char *name){ 227 | serial->begin(name); 228 | } 229 | //SLIP specific method which begins a transmitted packet 230 | void beginPacket() { serial->write(eot); } 231 | 232 | //signify the end of the packet with an EOT 233 | void endPacket(){ 234 | serial->write(eot); 235 | } 236 | 237 | void flush(){ 238 | serial->flush(); 239 | } 240 | 241 | }; 242 | 243 | using SLIPEncodedSerial = _SLIPSerial ; 244 | // template <> void _SLIPSerial::endPacket(){ 245 | // serial->write(eot); 246 | 247 | // } 248 | 249 | #ifdef BOARD_HAS_USB_SERIAL 250 | #if defined(_SAMD21_) 251 | // Required for Serial on Zero based boards 252 | #if defined(ARDUINO_SAMD_ZERO) 253 | // Adafruit breaks with tradition here 254 | #define thisBoardsSerialUSB Serial 255 | typedef decltype(Serial) actualUSBtype; 256 | #else 257 | #define thisBoardsSerialUSB SerialUSB 258 | typedef decltype(SerialUSB) actualUSBtype; 259 | #endif 260 | 261 | #elif defined(__SAM3X8E__) 262 | // Required for Serial on Zero based boards 263 | #define thisBoardsSerialUSB SerialUSB 264 | typedef decltype(SerialUSB) actualUSBtype; 265 | 266 | // defined(__SAM3X8E__) 267 | #elif defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_SAMD_ADAFRUIT) || defined(ARDUINO_USB_CDC_ON_BOOT) || defined(CORE_TEENSY) || defined(__AVR_ATmega32U4__) || (defined(__PIC32MX__) || defined(__PIC32MZ__)) 268 | #define thisBoardsSerialUSB Serial 269 | typedef decltype(Serial) actualUSBtype; 270 | #endif 271 | using SLIPEncodedUSBSerial = _SLIPSerial; 272 | #if defined(CORE_TEENSY) 273 | template <> void _SLIPSerial::endPacket(){ 274 | serial->write(eot); 275 | serial->send_now(); 276 | } 277 | #endif 278 | 279 | #endif // BOARD_HAS_USB_SERIAL 280 | 281 | // Bluetooth Example 282 | 283 | // #if BOARD_HAS_BLUETOOTH_SERIAL 284 | // #include "BluetoothSerial.h" 285 | // BluetoothSerial bluetoothserialinstance; 286 | // SLIPEncodedBluetoothSerial SLIPSerial(bluetoothserialinstance); 287 | 288 | #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32S2) 289 | #include "BluetoothSerial.h" 290 | using SLIPEncodedBluetoothSerial = _SLIPSerial; 291 | #define BOARD_HAS_BLUETOOTH_SERIAL 292 | 293 | #endif 294 | #endif 295 | -------------------------------------------------------------------------------- /SLIPEncodedTCP.cpp: -------------------------------------------------------------------------------- 1 | #include "SLIPEncodedTCP.h" 2 | #include 3 | /* 4 | CONSTRUCTOR 5 | */ 6 | //instantiate with the tranmission layer 7 | 8 | SLIPEncodedTCP::SLIPEncodedTCP(Client &s){ 9 | tcpClient = &s; 10 | rstate = CHAR; 11 | } 12 | 13 | static const uint8_t eot = 0300; 14 | static const uint8_t slipesc = 0333; 15 | static const uint8_t slipescend = 0334; 16 | static const uint8_t slipescesc = 0335; 17 | /* 18 | tcpClient METHODS 19 | */ 20 | bool SLIPEncodedTCP::endofPacket() 21 | { 22 | if(rstate == SECONDEOT) 23 | { 24 | rstate = CHAR; 25 | return true; 26 | } 27 | if (rstate==FIRSTEOT) 28 | { 29 | if(tcpClient->available()) 30 | { 31 | uint8_t c =tcpClient->peek(); 32 | if(c==eot) 33 | { 34 | tcpClient->read(); // throw it on the floor 35 | } 36 | } 37 | rstate = CHAR; 38 | return true; 39 | } 40 | return false; 41 | } 42 | int SLIPEncodedTCP::available(){ 43 | back: 44 | int cnt = tcpClient->available(); 45 | 46 | if(cnt==0) 47 | return 0; 48 | if(rstate==CHAR) 49 | { 50 | uint8_t c =tcpClient->peek(); 51 | if(c==slipesc) 52 | { 53 | rstate = SLIPESC; 54 | tcpClient->read(); // throw it on the floor 55 | goto back; 56 | } 57 | else if( c==eot) 58 | { 59 | rstate = FIRSTEOT; 60 | tcpClient->read(); // throw it on the floor 61 | goto back; 62 | } 63 | return 1; // we may have more but this is the only sure bet 64 | } 65 | else if(rstate==SLIPESC) 66 | return 1; 67 | else if(rstate==FIRSTEOT) 68 | { 69 | if(tcpClient->peek()==eot) 70 | { 71 | rstate = SECONDEOT; 72 | tcpClient->read(); // throw it on the floor 73 | return 0; 74 | } 75 | rstate = CHAR; 76 | }else if (rstate==SECONDEOT) { 77 | rstate = CHAR; 78 | } 79 | 80 | return 0; 81 | 82 | } 83 | 84 | //reads a byte from the buffer 85 | int SLIPEncodedTCP::read(){ 86 | back: 87 | uint8_t c = tcpClient->read(); 88 | if(rstate==CHAR) 89 | { 90 | if(c==slipesc) 91 | { 92 | rstate=SLIPESC; 93 | goto back; 94 | } 95 | else if(c==eot){ 96 | 97 | return -1; // xxx this is an error 98 | } 99 | return c; 100 | } 101 | else 102 | if(rstate==SLIPESC) 103 | { 104 | rstate=CHAR; 105 | if(c==slipescend) 106 | return eot; 107 | else if(c==slipescesc) 108 | return slipesc; 109 | else { 110 | // insert some error code here 111 | return -1; 112 | } 113 | 114 | } 115 | else 116 | return -1; 117 | } 118 | 119 | // as close as we can get to correct behavior 120 | int SLIPEncodedTCP::peek(){ 121 | uint8_t c = tcpClient->peek(); 122 | if(rstate==SLIPESC) 123 | { 124 | if(c==slipescend) 125 | return eot; 126 | else if(c==slipescesc) 127 | return slipesc; 128 | } 129 | return c; 130 | } 131 | 132 | //the arduino and wiring libraries have different return types for the write function 133 | #if defined(WIRING) || defined(BOARD_DEFS_H) 134 | 135 | //encode SLIP 136 | void SLIPEncodedTCP::write(uint8_t b){ 137 | if(b == eot){ 138 | tcpClient->write(slipesc); 139 | return tcpClient->write(slipescend); 140 | } else if(b==slipesc) { 141 | tcpClient->write(slipesc); 142 | return tcpClient->write(slipescesc); 143 | } else { 144 | return tcpClient->write(b); 145 | } 146 | } 147 | void SLIPEncodedTCP::write(const uint8_t *buffer, size_t size) { while(size--) write(*buffer++); } 148 | #else 149 | //encode SLIP 150 | size_t SLIPEncodedTCP::write(uint8_t b){ 151 | if(b == eot){ 152 | tcpClient->write(slipesc); 153 | return tcpClient->write(slipescend); 154 | } else if(b==slipesc) { 155 | tcpClient->write(slipesc); 156 | return tcpClient->write(slipescesc); 157 | } else { 158 | return tcpClient->write(b); 159 | } 160 | } 161 | size_t SLIPEncodedTCP::write(const uint8_t *buffer, size_t size) { size_t result=0; while(size--) result = write(*buffer++); return result; } 162 | 163 | #endif 164 | 165 | //SLIP specific method which begins a transmitted packet 166 | void SLIPEncodedTCP::beginPacket() { tcpClient->write(eot); } 167 | 168 | //signify the end of the packet with an EOT 169 | void SLIPEncodedTCP::endPacket(){ 170 | tcpClient->write(eot); 171 | } 172 | 173 | void SLIPEncodedTCP::flush(){ 174 | tcpClient->flush(); 175 | } 176 | -------------------------------------------------------------------------------- /SLIPEncodedTCP.h: -------------------------------------------------------------------------------- 1 | /* 2 | Extends the TCP client class to encode SLIP over TCP 3 | */ 4 | 5 | #ifndef SLIPEncodedTCP_H 6 | #define SLIPEncodedTCP_H 7 | 8 | #include "Arduino.h" 9 | #include 10 | #include 11 | 12 | 13 | class SLIPEncodedTCP: public Stream{ 14 | 15 | private: 16 | enum erstate {CHAR, FIRSTEOT, SECONDEOT, SLIPESC } rstate; 17 | 18 | //the TCP client used 19 | Client * tcpClient; 20 | 21 | public: 22 | SLIPEncodedTCP(Client & ); 23 | 24 | int available(); 25 | int read(); 26 | int peek(); 27 | void flush(); 28 | void beginPacket(); // SLIP specific method which begins a transmitted packet 29 | void endPacket(); // SLIP specific method which ends a transmittedpacket 30 | bool endofPacket(); // SLIP specific method which indicates that an EOT was received 31 | 32 | //the arduino and wiring libraries have different return types for the write function 33 | #if defined(WIRING) || defined(BOARD_DEFS_H) 34 | void write(uint8_t b); 35 | void write(const uint8_t *buffer, size_t size); 36 | 37 | #else 38 | //overrides the Stream's write function to encode SLIP 39 | size_t write(uint8_t b); 40 | size_t write(const uint8_t *buffer, size_t size); 41 | 42 | //using Print::write; 43 | #endif 44 | 45 | }; 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /examples/ESP8266ReceiveBundle/ESP8266ReceiveBundle.ino: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | 3 | Open Sound Control (OSC) library for the ESP8266/ESP32 4 | 5 | Example for receiving open sound control (OSC) bundles on the ESP8266/ESP32 6 | Send integers '0' or '1' to the address "/led" to turn on/off the built-in LED of the esp8266. 7 | 8 | This example code is in the public domain. 9 | 10 | --------------------------------------------------------------------------------------------- */ 11 | #ifdef ESP8266 12 | #include 13 | #else 14 | #include 15 | #endif 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | char ssid[] = "*****************"; // your network SSID (name) 22 | char pass[] = "*******"; // your network password 23 | 24 | // A UDP instance to let us send and receive packets over UDP 25 | WiFiUDP Udp; 26 | const IPAddress outIp(10,40,10,105); // remote IP (not needed for receive) 27 | const unsigned int outPort = 9999; // remote port (not needed for receive) 28 | const unsigned int localPort = 8888; // local port to listen for UDP packets (here's where we send the packets) 29 | 30 | 31 | OSCErrorCode error; 32 | unsigned int ledState = LOW; // LOW means led is *on* 33 | 34 | #ifndef BUILTIN_LED 35 | #ifdef LED_BUILTIN 36 | #define BUILTIN_LED LED_BUILTIN 37 | #else 38 | #define BUILTIN_LED 13 39 | #endif 40 | #endif 41 | 42 | void setup() { 43 | pinMode(BUILTIN_LED, OUTPUT); 44 | digitalWrite(BUILTIN_LED, ledState); // turn *on* led 45 | 46 | Serial.begin(115200); 47 | 48 | // Connect to WiFi network 49 | Serial.println(); 50 | Serial.println(); 51 | Serial.print("Connecting to "); 52 | Serial.println(ssid); 53 | WiFi.begin(ssid, pass); 54 | 55 | while (WiFi.status() != WL_CONNECTED) { 56 | delay(500); 57 | Serial.print("."); 58 | } 59 | Serial.println(""); 60 | 61 | Serial.println("WiFi connected"); 62 | Serial.println("IP address: "); 63 | Serial.println(WiFi.localIP()); 64 | 65 | Serial.println("Starting UDP"); 66 | Udp.begin(localPort); 67 | Serial.print("Local port: "); 68 | #ifdef ESP32 69 | Serial.println(localPort); 70 | #else 71 | Serial.println(Udp.localPort()); 72 | #endif 73 | 74 | } 75 | 76 | 77 | void led(OSCMessage &msg) { 78 | ledState = msg.getInt(0); 79 | digitalWrite(BUILTIN_LED, ledState); 80 | Serial.print("/led: "); 81 | Serial.println(ledState); 82 | } 83 | 84 | void loop() { 85 | OSCBundle bundle; 86 | int size = Udp.parsePacket(); 87 | 88 | if (size > 0) { 89 | while (size--) { 90 | bundle.fill(Udp.read()); 91 | } 92 | if (!bundle.hasError()) { 93 | bundle.dispatch("/led", led); 94 | } else { 95 | error = bundle.getError(); 96 | Serial.print("error: "); 97 | Serial.println(error); 98 | } 99 | } 100 | } 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /examples/ESP8266ReceiveMessage/ESP8266ReceiveMessage.ino: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | 3 | Open Sound Control (OSC) library for the ESP8266/ESP32 4 | 5 | Example for receiving open sound control (OSC) messages on the ESP8266/ESP32 6 | Send integers '0' or '1' to the address "/led" to turn on/off the built-in LED of the esp8266. 7 | 8 | This example code is in the public domain. 9 | 10 | --------------------------------------------------------------------------------------------- */ 11 | #ifdef ESP8266 12 | #include 13 | #else 14 | #include 15 | #endif 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | char ssid[] = "*****************"; // your network SSID (name) 22 | char pass[] = "*******"; // your network password 23 | 24 | // A UDP instance to let us send and receive packets over UDP 25 | WiFiUDP Udp; 26 | const IPAddress outIp(10,40,10,105); // remote IP (not needed for receive) 27 | const unsigned int outPort = 9999; // remote port (not needed for receive) 28 | const unsigned int localPort = 8888; // local port to listen for UDP packets (here's where we send the packets) 29 | 30 | 31 | OSCErrorCode error; 32 | unsigned int ledState = LOW; // LOW means led is *on* 33 | 34 | #ifndef BUILTIN_LED 35 | #ifdef LED_BUILTIN 36 | #define BUILTIN_LED LED_BUILTIN 37 | #else 38 | #define BUILTIN_LED 13 39 | #endif 40 | #endif 41 | 42 | void setup() { 43 | pinMode(BUILTIN_LED, OUTPUT); 44 | digitalWrite(BUILTIN_LED, ledState); // turn *on* led 45 | 46 | Serial.begin(115200); 47 | 48 | // Connect to WiFi network 49 | Serial.println(); 50 | Serial.println(); 51 | Serial.print("Connecting to "); 52 | Serial.println(ssid); 53 | WiFi.begin(ssid, pass); 54 | 55 | while (WiFi.status() != WL_CONNECTED) { 56 | delay(500); 57 | Serial.print("."); 58 | } 59 | Serial.println(""); 60 | 61 | Serial.println("WiFi connected"); 62 | Serial.println("IP address: "); 63 | Serial.println(WiFi.localIP()); 64 | 65 | Serial.println("Starting UDP"); 66 | Udp.begin(localPort); 67 | Serial.print("Local port: "); 68 | #ifdef ESP32 69 | Serial.println(localPort); 70 | #else 71 | Serial.println(Udp.localPort()); 72 | #endif 73 | 74 | } 75 | 76 | 77 | void led(OSCMessage &msg) { 78 | ledState = msg.getInt(0); 79 | digitalWrite(BUILTIN_LED, ledState); 80 | Serial.print("/led: "); 81 | Serial.println(ledState); 82 | } 83 | 84 | void loop() { 85 | OSCMessage msg; 86 | int size = Udp.parsePacket(); 87 | 88 | if (size > 0) { 89 | while (size--) { 90 | msg.fill(Udp.read()); 91 | } 92 | if (!msg.hasError()) { 93 | msg.dispatch("/led", led); 94 | } else { 95 | error = msg.getError(); 96 | Serial.print("error: "); 97 | Serial.println(error); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /examples/ESP8266sendMessage/ESP8266sendMessage.ino: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | 3 | Open Sound Control (OSC) library for the ESP8266/ESP32 4 | 5 | Example for sending messages from the ESP8266/ESP32 to a remote computer 6 | The example is sending "hello, osc." to the address "/test". 7 | 8 | This example code is in the public domain. 9 | 10 | --------------------------------------------------------------------------------------------- */ 11 | #if defined(ESP8266) 12 | #include 13 | #else 14 | #include 15 | #endif 16 | #include 17 | #include 18 | 19 | char ssid[] = "*****************"; // your network SSID (name) 20 | char pass[] = "*******"; // your network password 21 | 22 | WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP 23 | const IPAddress outIp(10,40,10,105); // remote IP of your computer 24 | const unsigned int outPort = 9999; // remote port to receive OSC 25 | const unsigned int localPort = 8888; // local port to listen for OSC packets (actually not used for sending) 26 | 27 | void setup() { 28 | Serial.begin(115200); 29 | 30 | // Connect to WiFi network 31 | Serial.println(); 32 | Serial.println(); 33 | Serial.print("Connecting to "); 34 | Serial.println(ssid); 35 | WiFi.begin(ssid, pass); 36 | 37 | while (WiFi.status() != WL_CONNECTED) { 38 | delay(500); 39 | Serial.print("."); 40 | } 41 | Serial.println(""); 42 | 43 | Serial.println("WiFi connected"); 44 | Serial.println("IP address: "); 45 | Serial.println(WiFi.localIP()); 46 | 47 | Serial.println("Starting UDP"); 48 | Udp.begin(localPort); 49 | Serial.print("Local port: "); 50 | #ifdef ESP32 51 | Serial.println(localPort); 52 | #else 53 | Serial.println(Udp.localPort()); 54 | #endif 55 | 56 | } 57 | 58 | void loop() { 59 | OSCMessage msg("/test"); 60 | msg.add("hello, osc."); 61 | Udp.beginPacket(outIp, outPort); 62 | msg.send(Udp); 63 | Udp.endPacket(); 64 | msg.empty(); 65 | delay(500); 66 | } 67 | -------------------------------------------------------------------------------- /examples/ETC_EOS_TCP/ETC_EOS_TCP.ino: -------------------------------------------------------------------------------- 1 | // Example for ETC EOS Conasoles, sending und receiving pings 2 | #include "Ethernet.h" 3 | #include "OSCMessage.h" 4 | #include "SLIPEncodedTCP.h" 5 | 6 | uint8_t mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x14, 0x48}; 7 | IPAddress localIP(10, 101, 1, 201); // IP of your Arduino 8 | IPAddress dns(10, 101, 1, 201); // IP of your DNS server 9 | IPAddress subnet(255, 255, 0, 0); // your subnet 10 | IPAddress eosIP(10, 101, 1, 100); // IP of your console 11 | uint16_t eosTcpPort = 3037; // use default EOS Slip port 12 | 13 | EthernetClient tcp; 14 | SLIPEncodedTCP slip (tcp); 15 | 16 | void setup() { 17 | Serial.begin(9600); 18 | Ethernet.begin(mac, localIP, dns ,subnet); 19 | if (!tcp.connected()) { 20 | tcp.stop(); 21 | tcp.connect(eosIP, eosTcpPort); 22 | } 23 | } 24 | 25 | void loop() { 26 | OSCMessage msg; 27 | static unsigned long lastTimeSent; 28 | static int32_t pingNum; 29 | unsigned long curTime; 30 | 31 | // look if there is a new meassage, if yes print ping data 32 | if (slip.available()) { 33 | while (!slip.endofPacket()) { 34 | while (slip.available()) { 35 | msg.fill(slip.read()); 36 | } 37 | } 38 | if (msg.fullMatch("/eos/out/ping")) { 39 | Serial.print("Ping Number "); 40 | Serial.print(msg.getInt(0)); 41 | Serial.println(" received"); 42 | } 43 | } 44 | 45 | // send a ping every second 46 | curTime = millis(); 47 | if (curTime - lastTimeSent > 1000) { 48 | OSCMessage ping("/eos/ping"); 49 | ping.add(pingNum++); 50 | if (!tcp.connected()) { 51 | tcp.stop(); 52 | tcp.connect(eosIP, eosTcpPort); 53 | } 54 | slip.beginPacket(); 55 | ping.send(slip); 56 | slip.endPacket(); 57 | lastTimeSent = curTime; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /examples/PatternMatching/PatternMatching.ino: -------------------------------------------------------------------------------- 1 | /* 2 | The library has four methods for doing pattern matching on address. 3 | 'match' and 'fullMatch' are specific to OSCMessages while route and dispatch work on both messages and bundles. 4 | 5 | OSCMessage: 6 | match - matches the message's address pattern against an address. returns the number of characters matched from the address passed in. 7 | fullMatch - returns true if the pattern was a complete match against the address 8 | 9 | OSCMessage && OSCBundle: 10 | route - calls a function with the matched OSCMessage(s) and the number of matched characters in the address as the parameters 11 | dispatch - calls a function with each OSCMessage which was fully matched by the pattern 12 | 13 | /////////////////////////////////////////////////////////////////////////////////////////////////// 14 | OSC Regular expression pattern matching rules from http://opensoundcontrol.org/spec-1_0 15 | 16 | 1. '?' in the OSC Address Pattern matches any single character 17 | 2. '*' in the OSC Address Pattern matches any sequence of zero or more characters 18 | 3. A string of characters in square brackets (e.g., "[string]") in the OSC Address Pattern matches any character in the string. 19 | Inside square brackets, the minus sign (-) and exclamation point (!) have special meanings: 20 | two characters separated by a minus sign indicates the range of characters between the given two in ASCII collating sequence. 21 | An exclamation point at the beginning of a bracketed string negates the sense of the list, meaning that the list matches any character not in the list. 22 | 4. A comma-separated list of strings enclosed in curly braces (e.g., "{foo,bar}") in the OSC Address Pattern matches any of the strings in the list. 23 | 5. Any other character in an OSC Address Pattern can match only the same character. 24 | /////////////////////////////////////////////////////////////////////////////////////////////////// 25 | */ 26 | 27 | #include 28 | 29 | void setup() { 30 | Serial.begin(38400); 31 | } 32 | 33 | void loop(){ 34 | //a heavily patterned message address 35 | OSCMessage msg0("/{input,output}/[0-2]/[!ab]/*"); 36 | //match will traverse as far as it can in the pattern 37 | //it returns the number of characters matched from the pattern 38 | int patternOffset = msg0.match("/input/1"); 39 | if (patternOffset>0){ 40 | //string multiple 'match' methods together using the pattern offset parameter to continue matching where it left off 41 | //use 'fullMatch' to test if the entire pattern was matched. 42 | if(msg0.fullMatch("/c/anything", patternOffset)){ 43 | Serial.println("Match: '/input/1/c/anything' against the pattern '/{input,output}/[0-2]/[abc]/*'"); 44 | } 45 | } 46 | //write over the other message address 47 | OSCMessage msg1("/partialMatch"); 48 | //match will return 0 if it did not reach the end or a '/' 49 | if(!msg1.match("/partial")){ 50 | Serial.println("No Match: '/partial' against the pattern '/partialMatch'"); 51 | } 52 | OSCMessage msg2("/output/[0-2]"); 53 | //'route' is uses 'match' to allow for partial matches 54 | //it invokes the callback with the matched message and the pattern offset as parameters to the callback 55 | msg2.route("/output", routeOutput); 56 | //'dispatch' uses 'fullMatch' so it does not allow for partial matches 57 | //invokes the callback with only one argument which is the matched message 58 | msg2.dispatch("/output/1", routeOutputOne); 59 | delay(1000); 60 | } 61 | 62 | //called after matching '/output' 63 | //the matched message and the number of matched characters as the parameters 64 | void routeOutput(OSCMessage &msg, int patternOffset){ 65 | Serial.println("Match: '/output'"); 66 | //string multiple 'route' methods together using the pattern offset parameter. 67 | msg.route("/0", routeZero, patternOffset); 68 | } 69 | 70 | //called after matching '/0' 71 | void routeZero(OSCMessage &msg, int addressOffset){ 72 | Serial.println("Match: '/output/0'"); 73 | } 74 | 75 | //called after matching '/output/1' 76 | void routeOutputOne(OSCMessage &msg){ 77 | Serial.println("Match: '/output/1'"); 78 | } 79 | 80 | 81 | // 82 | // TROUBLESHOOTING: 83 | // Because of a bug in the Arduino IDE, it sometimes thinks that the '*' in combination with '/' is the opening or closing of a multiline comment 84 | // This can be fixed by escaping the '/' with '\' or using the octal value of '*' which is '\052' 85 | // for example: 86 | // "/*" == "/\052" == "\/*" 87 | // 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /examples/SerialCallResponse/SerialCallResponse.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Serial Call Response 3 | Send responses to calls for information from a remote host 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #ifdef BOARD_HAS_USB_SERIAL 12 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 13 | #else 14 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 15 | #endif 16 | 17 | OSCBundle bundleOUT; 18 | 19 | /** 20 | * ANALOG 21 | * 22 | * called when the address matches "/a" 23 | * 24 | * format: 25 | * /analog/(pin) 26 | * /u = analogRead with pullup 27 | * 28 | **/ 29 | 30 | void routeAnalog(OSCMessage &msg, int addrOffset ){ 31 | int pinMatched; 32 | pinMatched = msg.match("/0", addrOffset); 33 | if(pinMatched){ 34 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(0), INPUT_PULLUP); //set the pullup 35 | //do the analog read and send the results 36 | bundleOUT.add("/analog/0").add((intOSC_t)analogRead(0)); 37 | } 38 | pinMatched = msg.match("/1", addrOffset); 39 | if(pinMatched){ 40 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(1), INPUT_PULLUP); //set the pullup 41 | //do the analog read and send the results 42 | bundleOUT.add("/analog/1").add((intOSC_t)analogRead(1)); 43 | } 44 | pinMatched = msg.match("/2", addrOffset); 45 | if(pinMatched){ 46 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(2), INPUT_PULLUP); //set the pullup 47 | //do the analog read and send the results 48 | bundleOUT.add("/analog/2").add((intOSC_t)analogRead(2)); 49 | } 50 | pinMatched = msg.match("/3", addrOffset); 51 | if(pinMatched){ 52 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(3), INPUT_PULLUP); //set the pullup 53 | //do the analog read and send the results 54 | bundleOUT.add("/analog/3").add((intOSC_t)analogRead(3)); 55 | } 56 | pinMatched = msg.match("/4", addrOffset); 57 | if(pinMatched){ 58 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(4), INPUT_PULLUP); //set the pullup 59 | //do the analog read and send the results 60 | bundleOUT.add("/analog/4").add((intOSC_t)analogRead(4)); 61 | } 62 | pinMatched = msg.match("/5", addrOffset); 63 | if(pinMatched){ 64 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(5), INPUT_PULLUP); //set the pullup 65 | //do the analog read and send the results 66 | bundleOUT.add("/analog/5").add((intOSC_t)analogRead(5)); 67 | } 68 | } 69 | 70 | /** 71 | * MAIN METHODS 72 | * 73 | * setup and loop, bundle receiving/sending, initial routing 74 | */ 75 | void setup() { 76 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 77 | } 78 | 79 | //reads and routes the incoming messages 80 | void loop(){ 81 | OSCBundle bundleIN; 82 | 83 | int size; 84 | 85 | while(!SLIPSerial.endofPacket()) 86 | if ((size =SLIPSerial.available()) > 0) 87 | { 88 | while(size--) 89 | bundleIN.fill(SLIPSerial.read()); 90 | } 91 | if(!bundleIN.hasError()) 92 | { 93 | bundleIN.route("/analog", routeAnalog); 94 | //send the outgoing response message 95 | SLIPSerial.beginPacket(); 96 | bundleOUT.send(SLIPSerial); 97 | SLIPSerial.endPacket(); 98 | bundleOUT.empty(); // empty the bundle ready to use for new messages 99 | } 100 | } 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /examples/SerialEcho/SerialEcho.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Serial USB ports are bidirectional. 4 | 5 | This example can be extended to build routers and forwarders of OSC packets 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #ifdef BOARD_HAS_USB_SERIAL 13 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 14 | #else 15 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 16 | #endif 17 | 18 | void setup() { 19 | //begin SLIPSerial just like Serial 20 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 21 | } 22 | 23 | void loop(){ 24 | OSCBundle bndl; 25 | int size; 26 | //receive a bundle 27 | 28 | while(!SLIPSerial.endofPacket()) 29 | if( (size =SLIPSerial.available()) > 0) 30 | { 31 | while(size--) 32 | bndl.fill(SLIPSerial.read()); 33 | } 34 | 35 | if(!bndl.hasError()) 36 | { 37 | static intOSC_t sequencenumber=0; 38 | // we can sneak an addition onto the end of the bundle 39 | bndl.add("/micros").add((intOSC_t)micros()); // (int32_t) is the type of OSC Integers 40 | bndl.add("/sequencenumber").add(sequencenumber++); 41 | bndl.add("/digital/5").add(digitalRead(5)==HIGH); 42 | bndl.add("/lsb").add((sequencenumber &1)==1); 43 | SLIPSerial.beginPacket(); // mark the beginning of the OSC Packet 44 | bndl.send(SLIPSerial); 45 | SLIPSerial.endPacket(); 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /examples/SerialOscuinoForFubarino/SerialOscuinoForFubarino.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Fubarino MINI 5 | 6 | #include 7 | 8 | #ifdef BOARD_HAS_USB_SERIAL 9 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 10 | #else 11 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 12 | #endif 13 | OSCBundle bundleOUT; 14 | 15 | //converts the pin to an osc address 16 | char * numToOSCAddress( int pin){ 17 | static char s[10]; 18 | int i = 9; 19 | s[i--]= '\0'; 20 | do 21 | { 22 | s[i] = "0123456789"[pin % 10]; 23 | --i; 24 | pin /= 10; 25 | } 26 | while(pin && i); 27 | s[i] = '/'; 28 | return &s[i]; 29 | } 30 | 31 | /** 32 | * ROUTES 33 | * 34 | * these are where the routing functions go 35 | * 36 | */ 37 | /** 38 | * DIGITAL 39 | * 40 | * called when address matched "/d" 41 | * expected format: 42 | * /d/(pin) 43 | * /u = digitalRead with pullup 44 | * (no value) = digitalRead without pullup 45 | * (value) = digital write on that pin 46 | * 47 | */ 48 | 49 | void routeDigital(OSCMessage &msg, int addrOffset ){ 50 | //match input or output 51 | for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ 52 | //match against the pin number strings 53 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 54 | if(pinMatched){ 55 | switch(pin) 56 | { 57 | // fubarino MINI 58 | // these are used for clocks and USB and Program switch and shouldn't be written to 59 | // unless you know what you are doing 60 | case 3: case 14: case 15: case 23: case 16: case 31:case 32: goto out; 61 | } 62 | //if it has an int, then it's a digital write 63 | if (msg.isInt(0)){ 64 | pinMode(pin, OUTPUT); 65 | digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); 66 | } //otherwise it's an digital read 67 | //with a pullup? 68 | else if (msg.fullMatch("/u", pinMatched+addrOffset)){ 69 | //set the pullup 70 | pinMode(pin, INPUT_PULLUP); 71 | //setup the output address which should be /d/(pin)/u 72 | char outputAddress[9]; 73 | strcpy(outputAddress, "/d"); 74 | strcat(outputAddress, numToOSCAddress(pin)); 75 | strcat(outputAddress,"/u"); 76 | //do the digital read and send the results 77 | { 78 | OSCMessage msgOut(outputAddress); msgOut.add(digitalRead(pin)); 79 | SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); 80 | } 81 | } //else without a pullup 82 | else { 83 | //set the pinmode 84 | pinMode(pin, INPUT); 85 | //setup the output address which should be /d/(pin) 86 | char outputAddress[6]; 87 | strcpy(outputAddress, "/d"); 88 | strcat(outputAddress, numToOSCAddress(pin)); 89 | //do the digital read and send the results 90 | { 91 | OSCMessage msgOut(outputAddress); msgOut.add(digitalRead(pin)); 92 | SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); 93 | } 94 | } 95 | } 96 | out: ; 97 | } 98 | } 99 | 100 | /** 101 | * ANALOG 102 | * 103 | * called when the address matches "/a" 104 | * 105 | * format: 106 | * /a/(pin) 107 | * /u = analogRead with pullup 108 | * (no value) = analogRead without pullup 109 | * (digital value) = digital write on that pin 110 | * (float value) = analogWrite on that pin 111 | * 112 | **/ 113 | 114 | void routeAnalog(OSCMessage &msg, int addrOffset ){ 115 | //iterate through all the analog pins 116 | for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ 117 | //match against the pin number strings 118 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 119 | if(pinMatched){ 120 | //if it has an int, then it's a digital write 121 | if (msg.isInt(0)){ 122 | pinMode(analogInputToDigitalPin(pin), OUTPUT); 123 | digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); 124 | } //otherwise it's an analog read 125 | else if(msg.isFloat(0)){ 126 | analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); 127 | } 128 | #ifdef BOARD_HAS_ANALOG_PULLUP 129 | //with a pullup? 130 | else if (msg.fullMatch("/u", pinMatched+addrOffset)){ 131 | //set the pullup 132 | 133 | pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); 134 | 135 | //setup the output address which should be /a/(pin)/u 136 | char outputAddress[9]; 137 | strcpy(outputAddress, "/a"); 138 | strcat(outputAddress, numToOSCAddress(pin)); 139 | strcat(outputAddress,"/u"); 140 | //do the analog read and send the results 141 | { 142 | OSCMessage msgOut(outputAddress); msgOut.add((intOSC_t)analogRead(pin)); 143 | SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); 144 | } 145 | } //else without a pullup 146 | #endif 147 | else { 148 | //set the pinmode 149 | // This fails on Arduino 1.04 on Leanardo, I added this to fix it: #define analogInputToDigitalPin(p) (p+18) 150 | 151 | pinMode(analogInputToDigitalPin(pin), INPUT); 152 | //setup the output address which should be /a/(pin) 153 | char outputAddress[6]; 154 | strcpy(outputAddress, "/a"); 155 | strcat(outputAddress, numToOSCAddress(pin)); 156 | //do the analog read and send the results 157 | { 158 | OSCMessage msgOut(outputAddress); msgOut.add((intOSC_t)analogRead(pin)); 159 | SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); 160 | } 161 | } 162 | } 163 | } 164 | } 165 | 166 | #ifdef BOARD_HAS_TONE 167 | 168 | /** 169 | * TONE 170 | * 171 | * square wave output "/tone" 172 | * 173 | * format: 174 | * /tone/pin 175 | * 176 | * (digital value) (float value) = frequency in Hz 177 | * (no value) disable tone 178 | * 179 | **/ 180 | 181 | void routeTone(OSCMessage &msg, int addrOffset ){ 182 | //iterate through all the analog pins 183 | for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ 184 | //match against the pin number strings 185 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 186 | if(pinMatched){ 187 | unsigned int frequency = 0; 188 | //if it has an int, then it's an integers frequency in Hz 189 | if (msg.isInt(0)){ 190 | frequency = msg.getInt(0); 191 | } //otherwise it's a floating point frequency in Hz 192 | else if(msg.isFloat(0)){ 193 | frequency = msg.getFloat(0); 194 | } 195 | else 196 | noTone(pin); 197 | if(frequency>0) 198 | { 199 | if(msg.isInt(1)) 200 | tone(pin, frequency, msg.getInt(1)); 201 | else 202 | tone(pin, frequency); 203 | } 204 | } 205 | } 206 | } 207 | #endif 208 | 209 | 210 | 211 | /** 212 | * SYSTEM MESSAGES 213 | * 214 | * expected format: 215 | * /s 216 | * /m = microseconds 217 | * /d = number of digital pins 218 | * /a = number of analog pins 219 | * /l integer = set the led 220 | * /t = temperature 221 | * /s = power supply voltage 222 | */ 223 | // 224 | void routeSystem(OSCMessage &msg, int addrOffset ){ 225 | 226 | #ifdef BOARD_HAS_DIE_TEMPERATURE_SENSOR 227 | if (msg.fullMatch("/t", addrOffset)){ 228 | { OSCMessage msgOut("/s/t"); msgOut.add(getTemperature()); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } 229 | } 230 | #endif 231 | #ifdef BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT 232 | if (msg.fullMatch("/s", addrOffset)){ 233 | { OSCMessage msgOut("/s/s"); msgOut.add(getSupplyVoltage()); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } 234 | } 235 | #endif 236 | if (msg.fullMatch("/m", addrOffset)){ 237 | { OSCMessage msgOut("/s/m"); msgOut.add((intOSC_t)micros()); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } 238 | } 239 | if (msg.fullMatch("/d", addrOffset)){ 240 | { OSCMessage msgOut("/s/d"); msgOut.add(NUM_DIGITAL_PINS); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } 241 | } 242 | if (msg.fullMatch("/a", addrOffset)){ 243 | { OSCMessage msgOut("/s/a"); msgOut.add(NUM_ANALOG_INPUTS); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } 244 | } 245 | if (msg.fullMatch("/l", addrOffset)){ 246 | 247 | if (msg.isInt(0)){ 248 | pinMode(LED_BUILTIN, OUTPUT); 249 | int i = msg.getInt(0); 250 | pinMode(LED_BUILTIN, OUTPUT); 251 | digitalWrite(LED_BUILTIN, (i > 0)? HIGH: LOW); 252 | { OSCMessage msgOut("/s/l"); msgOut.add(i); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } 253 | } 254 | } 255 | } 256 | 257 | /** 258 | * MAIN METHODS 259 | * 260 | * setup and loop, bundle receiving/sending, initial routing 261 | */ 262 | 263 | void setup() { 264 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 265 | } 266 | 267 | //reads and routes the incoming messages 268 | void loop(){ 269 | OSCBundle bundleIN; 270 | int size; 271 | while(!SLIPSerial.endofPacket()) 272 | if ((size =SLIPSerial.available()) > 0) 273 | { 274 | while(size--) 275 | bundleIN.fill(SLIPSerial.read()); 276 | } 277 | 278 | if(!bundleIN.hasError()) 279 | { 280 | bundleIN.route("/s", routeSystem); 281 | bundleIN.route("/a", routeAnalog); 282 | bundleIN.route("/d", routeDigital); 283 | #ifdef BOARD_HAS_TONE 284 | bundleIN.route("/tone", routeTone); 285 | #endif 286 | #ifdef BOARD_HAS_CAPACITANCE_SENSING 287 | bundleIN.route("/c", routeTouch); 288 | #endif 289 | } 290 | 291 | } 292 | 293 | -------------------------------------------------------------------------------- /examples/SerialOscuinoGemmaM0/SerialOscuinoGemmaM0.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "Adafruit_FreeTouch.h" 5 | #include 6 | 7 | Adafruit_FreeTouch qt_0 = Adafruit_FreeTouch(A0, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE); 8 | Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(A1, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE); 9 | Adafruit_FreeTouch qt_2 = Adafruit_FreeTouch(A2, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE); 10 | Adafruit_FreeTouch *p[3] = { &qt_0, &qt_1, &qt_2 }; 11 | 12 | #undef NUM_DIGITAL_PINS 13 | #define NUM_DIGITAL_PINS 3 14 | #undef NUM_ANALOG_PINS 15 | #define NUM_ANALOG_PINS 3 16 | 17 | SLIPEncodedUSBSerial SLIPSerial( Serial ); 18 | 19 | 20 | 21 | //outgoing messages 22 | 23 | OSCBundle bundleOUT; 24 | 25 | //converts the pin to an osc address 26 | char * numToOSCAddress( int pin){ 27 | static char s[10]; 28 | int i = 9; 29 | 30 | s[i--]= '\0'; 31 | do 32 | { 33 | s[i] = "0123456789"[pin % 10]; 34 | --i; 35 | pin /= 10; 36 | } 37 | while(pin && i); 38 | s[i] = '/'; 39 | return &s[i]; 40 | } 41 | 42 | /** 43 | * ROUTES 44 | * 45 | * these are where the routing functions go 46 | * 47 | */ 48 | 49 | /** 50 | * DIGITAL 51 | * 52 | * called when address matched "/d" 53 | * expected format: 54 | * /d/(pin) 55 | * /u = digitalRead with pullup 56 | * (no value) = digitalRead without pullup 57 | * (value) = digital write on that pin 58 | * 59 | */ 60 | 61 | void routeDigital(OSCMessage &msg, int addrOffset ){ 62 | //match input or output 63 | for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ 64 | //match against the pin number strings 65 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 66 | if(pinMatched){ 67 | //if it has an int, then it's a digital write 68 | if (msg.isInt(0)){ 69 | pinMode(pin, OUTPUT); 70 | digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); 71 | } 72 | else if(msg.isFloat(0)){ 73 | analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); 74 | } 75 | 76 | //otherwise it's an digital read 77 | //with a pullup? 78 | else if (msg.fullMatch("/u", pinMatched+addrOffset)){ 79 | //set the pullup 80 | pinMode(pin, INPUT_PULLUP); 81 | //setup the output address which should be /d/(pin)/u 82 | char outputAddress[9]; 83 | strcpy(outputAddress, "/d"); 84 | strcat(outputAddress, numToOSCAddress(pin)); 85 | strcat(outputAddress,"/u"); 86 | //do the digital read and send the results 87 | bundleOUT.add(outputAddress).add(digitalRead(pin)); 88 | } //else without a pullup 89 | else { 90 | //set the pinmode 91 | pinMode(pin, INPUT); 92 | //setup the output address which should be /d/(pin) 93 | char outputAddress[6]; 94 | strcpy(outputAddress, "/d"); 95 | strcat(outputAddress, numToOSCAddress(pin)); 96 | //do the digital read and send the results 97 | bundleOUT.add(outputAddress).add(digitalRead(pin)); 98 | } 99 | } 100 | } 101 | } 102 | 103 | /** 104 | * ANALOG 105 | * 106 | * called when the address matches "/a" 107 | * 108 | * format: 109 | * /a/(pin) 110 | * /u = analogRead with pullup 111 | * (no value) = analogRead without pullup 112 | * (digital value) = digital write on that pin 113 | * (float value) = analogWrite on that pin 114 | * 115 | **/ 116 | 117 | void routeAnalog(OSCMessage &msg, int addrOffset ){ 118 | //iterate through all the analog pins 119 | for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ 120 | //match against the pin number strings 121 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 122 | if(pinMatched){ 123 | //if it has an int, then it's a digital write 124 | if (msg.isInt(0)){ 125 | pinMode(analogInputToDigitalPin(pin), OUTPUT); 126 | digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); 127 | } 128 | else if(msg.isFloat(0)){ 129 | analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); 130 | } 131 | #ifdef BOARD_HAS_ANALOG_PULLUP 132 | //with a pullup? 133 | else if (msg.fullMatch("/u", pinMatched+addrOffset)){ 134 | //set the pullup 135 | 136 | pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); 137 | 138 | //setup the output address which should be /a/(pin)/u 139 | char outputAddress[9]; 140 | strcpy(outputAddress, "/a"); 141 | strcat(outputAddress, numToOSCAddress(pin)); 142 | strcat(outputAddress,"/u"); 143 | //do the analog read and send the results 144 | bundleOUT.add(outputAddress).add((intOSC_t)analogRead(pin)); 145 | } //else without a pullup 146 | #endif 147 | 148 | else { 149 | //otherwise it's an analog read 150 | //set the pinmode 151 | 152 | pinMode(analogInputToDigitalPin(pin), INPUT); 153 | //setup the output address which should be /a/(pin) 154 | char outputAddress[6]; 155 | strcpy(outputAddress, "/a"); 156 | strcat(outputAddress, numToOSCAddress(pin)); 157 | //do the analog read and send the results 158 | bundleOUT.add(outputAddress).add((intOSC_t)analogRead(pin)); 159 | } 160 | } 161 | } 162 | } 163 | 164 | #if 1 165 | /** 166 | * TONE 167 | * 168 | * square wave output "/tone" 169 | * 170 | * format: 171 | * /tone/pin 172 | * 173 | * (digital value) (float value) = frequency in Hz 174 | * (no value) disable tone 175 | * 176 | **/ 177 | 178 | void routeTone(OSCMessage &msg, int addrOffset ){ 179 | //iterate through all the analog pins 180 | for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ 181 | //match against the pin number strings 182 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 183 | if(pinMatched){ 184 | unsigned int frequency = 0; 185 | //if it has an int, then it's an integers frequency in Hz 186 | if (msg.isInt(0)){ 187 | frequency = msg.getInt(0); 188 | } //otherwise it's a floating point frequency in Hz 189 | else if(msg.isFloat(0)){ 190 | frequency = msg.getFloat(0); 191 | } 192 | else 193 | noTone(pin); 194 | if(frequency>0) 195 | { 196 | if(msg.isInt(1)) 197 | tone(pin, frequency, msg.getInt(1)); 198 | else 199 | tone(pin, frequency); 200 | } 201 | } 202 | } 203 | } 204 | #endif 205 | 206 | 207 | 208 | 209 | void routeTouch(OSCMessage &msg, int addrOffset ) 210 | { 211 | for(int i=0;i<3;++i) 212 | { 213 | const char *name = numToOSCAddress(i); 214 | int pinMatched = msg.match(name, addrOffset); 215 | if(pinMatched && p[i]) 216 | { 217 | 218 | char outputAddress[9]; 219 | strcpy(outputAddress, "/c"); 220 | strcat(outputAddress, name); 221 | bundleOUT.add(outputAddress).add(p[i]->measure()); 222 | } 223 | } 224 | } 225 | 226 | /** 227 | * SYSTEM MESSAGES 228 | * 229 | * expected format: 230 | * /s 231 | * /m = microseconds 232 | * /d = number of digital pins 233 | * /a = number of analog pins 234 | * /l integer = set the led 235 | * /t = temperature 236 | * /s = power supply voltage 237 | */ 238 | // 239 | void routeSystem(OSCMessage &msg, int addrOffset ){ 240 | 241 | if (msg.fullMatch("/m", addrOffset)){ 242 | bundleOUT.add("/s/m").add((intOSC_t)micros()); 243 | } 244 | if (msg.fullMatch("/d", addrOffset)){ 245 | bundleOUT.add("/s/d").add(NUM_DIGITAL_PINS); 246 | } 247 | if (msg.fullMatch("/a", addrOffset)){ 248 | bundleOUT.add("/s/a").add(NUM_ANALOG_INPUTS); 249 | } 250 | if (msg.fullMatch("/l", addrOffset)){ 251 | if (msg.isInt(0)){ 252 | pinMode(LED_BUILTIN, OUTPUT); 253 | int i = msg.getInt(0); 254 | pinMode(LED_BUILTIN, OUTPUT); 255 | digitalWrite(LED_BUILTIN, (i > 0)? HIGH: LOW); 256 | bundleOUT.add("/s/l").add(i); 257 | } 258 | } 259 | } 260 | 261 | /** 262 | * MAIN METHODS 263 | * 264 | * setup and loop, bundle receiving/sending, initial routing 265 | */ 266 | 267 | 268 | void setup() { 269 | SLIPSerial.begin(115200); // set this as high as you can reliably run on your platform 270 | for(int i=0; i<3; ++i) 271 | if(!p[i]->begin()) 272 | p[i] =0; 273 | } 274 | 275 | //reads and routes the incoming messages 276 | void loop(){ 277 | OSCBundle bundleIN; 278 | int size; 279 | 280 | while(!SLIPSerial.endofPacket()) 281 | if ((size =SLIPSerial.available()) > 0) 282 | { 283 | while(size--) 284 | bundleIN.fill(SLIPSerial.read()); 285 | } 286 | 287 | if(!bundleIN.hasError()) 288 | { 289 | bundleIN.route("/s", routeSystem); 290 | bundleIN.route("/a", routeAnalog); 291 | bundleIN.route("/d", routeDigital); 292 | bundleIN.route("/tone", routeTone); 293 | bundleIN.route("/c", routeTouch); 294 | } 295 | bundleIN.empty(); 296 | 297 | 298 | //send the outgoing message 299 | SLIPSerial.beginPacket(); 300 | bundleOUT.send(SLIPSerial); 301 | SLIPSerial.endPacket(); 302 | bundleOUT.empty(); 303 | 304 | } 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | -------------------------------------------------------------------------------- /examples/SerialOscuinowithBundles/SerialOscuinowithBundles.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #ifdef BOARD_HAS_USB_SERIAL 8 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 9 | #else 10 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 11 | #endif 12 | 13 | 14 | //outgoing messages 15 | 16 | OSCBundle bundleOUT; 17 | 18 | //converts the pin to an osc address 19 | char * numToOSCAddress( int pin){ 20 | static char s[10]; 21 | int i = 9; 22 | 23 | s[i--]= '\0'; 24 | do 25 | { 26 | s[i] = "0123456789"[pin % 10]; 27 | --i; 28 | pin /= 10; 29 | } 30 | while(pin && i); 31 | s[i] = '/'; 32 | return &s[i]; 33 | } 34 | 35 | /** 36 | * ROUTES 37 | * 38 | * these are where the routing functions go 39 | * 40 | */ 41 | 42 | /** 43 | * DIGITAL 44 | * 45 | * called when address matched "/d" 46 | * expected format: 47 | * /d/(pin) 48 | * /u = digitalRead with pullup 49 | * (no value) = digitalRead without pullup 50 | * (value) = digital write on that pin 51 | * 52 | */ 53 | 54 | void routeDigital(OSCMessage &msg, int addrOffset ){ 55 | //match input or output 56 | for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ 57 | //match against the pin number strings 58 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 59 | if(pinMatched){ 60 | //if it has an int, then it's a digital write 61 | if (msg.isInt(0)){ 62 | pinMode(pin, OUTPUT); 63 | digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); 64 | } 65 | else if(msg.isFloat(0)){ 66 | analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); 67 | } 68 | 69 | //otherwise it's an digital read 70 | //with a pullup? 71 | else if (msg.fullMatch("/u", pinMatched+addrOffset)){ 72 | //set the pullup 73 | pinMode(pin, INPUT_PULLUP); 74 | //setup the output address which should be /d/(pin)/u 75 | char outputAddress[9]; 76 | strcpy(outputAddress, "/d"); 77 | strcat(outputAddress, numToOSCAddress(pin)); 78 | strcat(outputAddress,"/u"); 79 | //do the digital read and send the results 80 | bundleOUT.add(outputAddress).add(digitalRead(pin)); 81 | } //else without a pullup 82 | else { 83 | //set the pinmode 84 | pinMode(pin, INPUT); 85 | //setup the output address which should be /d/(pin) 86 | char outputAddress[6]; 87 | strcpy(outputAddress, "/d"); 88 | strcat(outputAddress, numToOSCAddress(pin)); 89 | //do the digital read and send the results 90 | bundleOUT.add(outputAddress).add(digitalRead(pin)); 91 | } 92 | } 93 | } 94 | } 95 | 96 | /** 97 | * ANALOG 98 | * 99 | * called when the address matches "/a" 100 | * 101 | * format: 102 | * /a/(pin) 103 | * /u = analogRead with pullup 104 | * (no value) = analogRead without pullup 105 | * (digital value) = digital write on that pin 106 | * (float value) = analogWrite on that pin 107 | * 108 | **/ 109 | 110 | void routeAnalog(OSCMessage &msg, int addrOffset ){ 111 | //iterate through all the analog pins 112 | for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ 113 | //match against the pin number strings 114 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 115 | if(pinMatched){ 116 | //if it has an int, then it's a digital write 117 | if (msg.isInt(0)){ 118 | pinMode(analogInputToDigitalPin(pin), OUTPUT); 119 | digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); 120 | } 121 | else if(msg.isFloat(0)){ 122 | analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); 123 | } 124 | #ifdef BOARD_HAS_ANALOG_PULLUP 125 | //with a pullup? 126 | else if (msg.fullMatch("/u", pinMatched+addrOffset)){ 127 | //set the pullup 128 | 129 | pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); 130 | 131 | //setup the output address which should be /a/(pin)/u 132 | char outputAddress[9]; 133 | strcpy(outputAddress, "/a"); 134 | strcat(outputAddress, numToOSCAddress(pin)); 135 | strcat(outputAddress,"/u"); 136 | //do the analog read and send the results 137 | bundleOUT.add(outputAddress).add((intOSC_t)analogRead(pin)); 138 | } //else without a pullup 139 | #endif 140 | 141 | else { 142 | //otherwise it's an analog read 143 | //set the pinmode 144 | 145 | pinMode(analogInputToDigitalPin(pin), INPUT); 146 | //setup the output address which should be /a/(pin) 147 | char outputAddress[6]; 148 | strcpy(outputAddress, "/a"); 149 | strcat(outputAddress, numToOSCAddress(pin)); 150 | //do the analog read and send the results 151 | bundleOUT.add(outputAddress).add((intOSC_t)analogRead(pin)); 152 | } 153 | } 154 | } 155 | } 156 | 157 | #ifdef BOARD_HAS_TONE 158 | /** 159 | * TONE 160 | * 161 | * square wave output "/tone" 162 | * 163 | * format: 164 | * /tone/pin 165 | * 166 | * (digital value) (float value) = frequency in Hz 167 | * (no value) disable tone 168 | * 169 | **/ 170 | 171 | void routeTone(OSCMessage &msg, int addrOffset ){ 172 | //iterate through all the analog pins 173 | for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ 174 | //match against the pin number strings 175 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 176 | if(pinMatched){ 177 | unsigned int frequency = 0; 178 | //if it has an int, then it's an integers frequency in Hz 179 | if (msg.isInt(0)){ 180 | frequency = msg.getInt(0); 181 | } //otherwise it's a floating point frequency in Hz 182 | else if(msg.isFloat(0)){ 183 | frequency = msg.getFloat(0); 184 | } 185 | else 186 | noTone(pin); 187 | if(frequency>0) 188 | { 189 | if(msg.isInt(1)) 190 | tone(pin, frequency, msg.getInt(1)); 191 | else 192 | tone(pin, frequency); 193 | } 194 | } 195 | } 196 | } 197 | #endif 198 | 199 | 200 | #ifdef BOARD_HAS_CAPACITANCE_SENSING 201 | #if defined(__MKL26Z64__) 202 | #define NTPINS 11 203 | const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,3,4 }; 204 | #else 205 | #define NTPINS 12 206 | const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,25,32, 33 }; 207 | #endif 208 | 209 | void routeTouch(OSCMessage &msg, int addrOffset ) 210 | { 211 | for(int i=0;i 0)? HIGH: LOW); 268 | bundleOUT.add("/s/l").add(i); 269 | } 270 | } 271 | #endif 272 | } 273 | 274 | /** 275 | * MAIN METHODS 276 | * 277 | * setup and loop, bundle receiving/sending, initial routing 278 | */ 279 | 280 | 281 | void setup() { 282 | SLIPSerial.begin(115200); // set this as high as you can reliably run on your platform 283 | } 284 | 285 | //reads and routes the incoming messages 286 | void loop(){ 287 | OSCBundle bundleIN; 288 | int size; 289 | 290 | while(!SLIPSerial.endofPacket()) 291 | if ((size =SLIPSerial.available()) > 0) 292 | { 293 | while(size--) 294 | bundleIN.fill(SLIPSerial.read()); 295 | } 296 | 297 | if(!bundleIN.hasError()) 298 | { 299 | bundleIN.route("/s", routeSystem); 300 | bundleIN.route("/a", routeAnalog); 301 | bundleIN.route("/d", routeDigital); 302 | #ifdef BOARD_HAS_TONE 303 | bundleIN.route("/tone", routeTone); 304 | #endif 305 | #ifdef BOARD_HAS_CAPACITANCE_SENSING 306 | bundleIN.route("/c", routeTouch); 307 | #endif 308 | } 309 | bundleIN.empty(); 310 | 311 | 312 | //send the outgoing message 313 | SLIPSerial.beginPacket(); 314 | bundleOUT.send(SLIPSerial); 315 | SLIPSerial.endPacket(); 316 | bundleOUT.empty(); 317 | 318 | } 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | -------------------------------------------------------------------------------- /examples/SerialReceive/SerialReceive.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Set the LED according to incoming OSC control 3 | */ 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #ifdef BOARD_HAS_USB_SERIAL 10 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 11 | #else 12 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 13 | #endif 14 | 15 | 16 | void LEDcontrol(OSCMessage &msg) 17 | { 18 | if (msg.isInt(0)) 19 | { 20 | pinMode(LED_BUILTIN, OUTPUT); 21 | digitalWrite(LED_BUILTIN, (msg.getInt(0) > 0)? HIGH: LOW); 22 | } 23 | else if(msg.isString(0)) 24 | { 25 | int length=msg.getDataLength(0); 26 | if(length<5) 27 | { 28 | char str[length]; 29 | msg.getString(0,str,length); 30 | if((strcmp("on", str)==0)|| (strcmp("On",str)==0)) 31 | { 32 | pinMode(LED_BUILTIN, OUTPUT); 33 | digitalWrite(LED_BUILTIN, HIGH); 34 | } 35 | else if((strcmp("Of", str)==0)|| (strcmp("off",str)==0)) 36 | { 37 | pinMode(LED_BUILTIN, OUTPUT); 38 | digitalWrite(LED_BUILTIN, LOW); 39 | } 40 | } 41 | } 42 | 43 | } 44 | 45 | 46 | void setup() { 47 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 48 | } 49 | //reads and dispatches the incoming message 50 | void loop(){ 51 | OSCBundle bundleIN; 52 | int size; 53 | 54 | while(!SLIPSerial.endofPacket()) 55 | if( (size =SLIPSerial.available()) > 0) 56 | { 57 | while(size--) 58 | bundleIN.fill(SLIPSerial.read()); 59 | } 60 | 61 | if(!bundleIN.hasError()) 62 | bundleIN.dispatch("/led", LEDcontrol); 63 | 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /examples/SerialReceiveInfiniteLoop/SerialReceiveInfiniteLoop.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Blink the LED according to incoming OSC on/off rates in quasi-asynchronous way 3 | */ 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #ifdef BOARD_HAS_USB_SERIAL 10 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 11 | #else 12 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 13 | #endif 14 | 15 | 16 | constexpr unsigned long blinkInterval = 2500; 17 | unsigned long blinkNow; 18 | 19 | unsigned long blinkRateOn = 50; 20 | unsigned long blinkRateOff = 50; 21 | 22 | void LEDcontrol(OSCMessage& msg) 23 | { 24 | if (msg.isInt(0)) { 25 | blinkRateOn = msg.getInt(0); 26 | } 27 | 28 | if (msg.isInt(1)) { 29 | blinkRateOff = msg.getInt(1); 30 | } 31 | } 32 | 33 | void setup() 34 | { 35 | Serial.begin(9600); 36 | 37 | const unsigned long startNow = millis() + 5000; 38 | while(!Serial && millis() < startNow); 39 | 40 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 41 | 42 | blinkNow = millis() + blinkInterval; 43 | } 44 | 45 | //reads and dispatches the incoming message 46 | void loop() 47 | { 48 | OSCBundle bundleIN; 49 | int size; 50 | 51 | if (SLIPSerial.available()) 52 | while (!SLIPSerial.endofPacket()) 53 | while (SLIPSerial.available()) 54 | bundleIN.fill(SLIPSerial.read()); 55 | 56 | if (!bundleIN.hasError()) 57 | bundleIN.dispatch("/led", LEDcontrol); 58 | 59 | if (millis() >= blinkNow) { 60 | pinMode(LED_BUILTIN, OUTPUT); 61 | 62 | Serial.print("Blinking at "); 63 | Serial.print(blinkRateOn); 64 | Serial.print("/"); 65 | Serial.print(blinkRateOff); 66 | Serial.println(); 67 | 68 | for (auto i = 0; i <= 5; i ++) { 69 | digitalWrite(LED_BUILTIN, HIGH); 70 | delay(blinkRateOn); 71 | digitalWrite(LED_BUILTIN, LOW); 72 | delay(blinkRateOff); 73 | } 74 | // blinkNow = millis() + blinkInterval; 75 | blinkNow = millis() + blinkInterval - 5 * (blinkRateOn + blinkRateOff); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /examples/SerialReceivewithServo/SerialReceivewithServo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Control a servo according to incoming OSC control 3 | * 4 | */ 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #ifdef BOARD_HAS_USB_SERIAL 12 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 13 | #else 14 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 15 | #endif 16 | 17 | 18 | Servo myservo; 19 | 20 | void servoControl(OSCMessage &msg) 21 | { 22 | if (msg.isInt(0)) 23 | { 24 | myservo.write(msg.getInt(0)); 25 | } 26 | #ifdef TEMPoraray 27 | else if (msg.isFloat(0)) 28 | { 29 | //test if that pin is a PWM 30 | if (digitalPinHasPWM(LED_BUILTIN)) 31 | { 32 | pinMode(LED_BUILTIN, OUTPUT); 33 | analogWrite(LED_BUILTIN, (int)(msg.getFloat(0)*127.0f)); 34 | } 35 | else 36 | SoftPWMSet(LED_BUILTIN, (int)(msg.getFloat(0)*127.0f)); 37 | } 38 | #endif 39 | 40 | } 41 | 42 | void setup() { 43 | SLIPSerial.begin(9600); 44 | 45 | myservo.attach(13); 46 | myservo.write(90); 47 | 48 | 49 | } 50 | //reads and dispatches the incoming message 51 | void loop(){ 52 | OSCBundle bundleIN; 53 | int size; 54 | 55 | while(!SLIPSerial.endofPacket()) 56 | if( (size =SLIPSerial.available()) > 0) 57 | { 58 | while(size--) 59 | bundleIN.fill(SLIPSerial.read()); 60 | } 61 | 62 | if(!bundleIN.hasError()) 63 | bundleIN.dispatch("/servo", servoControl); 64 | 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /examples/SerialSendBundle/SerialSendBundle.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Make an OSC bundle and send it over SLIP serial 4 | 5 | OSCBundles allow OSCMessages to be grouped together to preserve the order and completeness of related messages. 6 | They also allow for timetags to be carried to represent the presentation time of the messages. 7 | */ 8 | #include 9 | #include 10 | 11 | #ifdef BOARD_HAS_USB_SERIAL 12 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 13 | #else 14 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 15 | #endif 16 | 17 | 18 | void setup() { 19 | //begin SLIPSerial just like Serial 20 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 21 | 22 | 23 | } 24 | 25 | void loop(){ 26 | //declare the bundle 27 | OSCBundle bndl; 28 | //BOSCBundle's add' returns the OSCMessage so the message's 'add' can be composed together 29 | bndl.add("/analog/0").add((intOSC_t)analogRead(0)); 30 | bndl.add("/analog/1").add((intOSC_t)analogRead(1)); 31 | bndl.add("/digital/5").add((digitalRead(5)==HIGH)); 32 | 33 | 34 | SLIPSerial.beginPacket(); 35 | bndl.send(SLIPSerial); // send the bytes to the SLIP stream 36 | SLIPSerial.endPacket(); // mark the end of the OSC Packet 37 | bndl.empty(); // empty the bundle to free room for a new one 38 | 39 | bndl.add("/mouse/step").add((intOSC_t)analogRead(0)).add((intOSC_t)analogRead(1)); 40 | bndl.add("/units").add("pixels"); 41 | SLIPSerial.beginPacket(); 42 | bndl.send(SLIPSerial); // send the bytes to the SLIP stream 43 | SLIPSerial.endPacket(); // mark the end of the OSC Packet 44 | bndl.empty(); // empty the bundle to free room for a new one 45 | 46 | delay(100); 47 | } 48 | -------------------------------------------------------------------------------- /examples/SerialSendBundleWithTimeTag/SerialSendBundleWithTimeTag.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Make an OSC bundle and send it over SLIP serial 4 | 5 | OSCBundles allow OSCMessages to be grouped together to preserve the order and completeness of related messages. 6 | They also allow for timetags to be carried to represent the presentation time of the messages. 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifdef BOARD_HAS_USB_SERIAL 14 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 15 | #else 16 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 17 | #endif 18 | 19 | 20 | void setup() { 21 | //begin SLIPSerial just like Serial 22 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 23 | 24 | } 25 | 26 | void loop(){ 27 | //declare the bundle 28 | OSCBundle bndl; 29 | osctime_t timetag; 30 | 31 | //OSCBundle's add' returns the OSCMessage so the message's 'add' can be composed together 32 | bndl.add("/analog/0").add((intOSC_t)adcRead(0, &timetag)); 33 | bndl.add("/analog/0/time").add(timetag); 34 | 35 | bndl.add("/analog/1").add((intOSC_t)adcRead(1, &timetag)); 36 | bndl.add("/analog/1/time").add(timetag); 37 | 38 | bndl.add("/digital/5").add((digitalRead(5)==HIGH)?"HIGH":"LOW"); 39 | 40 | SLIPSerial.beginPacket(); 41 | bndl.setTimetag(oscTime()); 42 | bndl.send(SLIPSerial); // send the bytes to the SLIP stream 43 | SLIPSerial.endPacket(); // mark the end of the OSC Packet 44 | bndl.empty(); // empty the bundle to free room for a new one 45 | 46 | delay(100); 47 | } 48 | -------------------------------------------------------------------------------- /examples/SerialSendMessage/SerialSendMessage.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | /* 4 | Make an OSC message and send it over serial 5 | */ 6 | 7 | #ifdef BOARD_HAS_USB_SERIAL 8 | #include 9 | SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); 10 | #else 11 | #include 12 | SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 13 | #endif 14 | 15 | 16 | void setup() { 17 | //begin SLIPSerial just like Serial 18 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 19 | } 20 | 21 | 22 | void loop(){ 23 | //the message wants an OSC address as first argument 24 | OSCMessage msg("/analog/0"); 25 | msg.add((intOSC_t)analogRead(0)); 26 | 27 | SLIPSerial.beginPacket(); 28 | msg.send(SLIPSerial); // send the bytes to the SLIP stream 29 | SLIPSerial.endPacket(); // mark the end of the OSC Packet 30 | msg.empty(); // free space occupied by message 31 | 32 | delay(20); 33 | } 34 | -------------------------------------------------------------------------------- /examples/SerialSendMessageInfiniteLoop/SerialSendMessageInfiniteLoop.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Make an OSC message for controlling a remote LED blinking rates. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #ifdef BOARD_HAS_USB_SERIAL 9 | #include 10 | SLIPEncodedUSBSerial SLIPSerial(thisBoardsSerialUSB); 11 | #else 12 | #include 13 | SLIPEncodedSerial SLIPSerial(Serial1); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial 14 | #endif 15 | 16 | constexpr auto blinkRatesSize = 8; 17 | int blinkRates[blinkRatesSize] = { 25, 50, 100, 125, 150, 175, 200, 225 }; 18 | 19 | void setup() 20 | { 21 | //begin SLIPSerial just like Serial 22 | SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform 23 | } 24 | 25 | void loop() 26 | { 27 | //the message wants an OSC address as first argument 28 | OSCMessage msg("/led"); 29 | 30 | auto i = rand() % (blinkRatesSize - 1); 31 | auto blinkRateOn = blinkRates[i]; 32 | 33 | auto j = rand() % (blinkRatesSize - 1); 34 | auto blinkRateOff = blinkRates[j]; 35 | 36 | msg.add(blinkRateOn).add(blinkRateOff); 37 | 38 | SLIPSerial.beginPacket(); 39 | msg.send(SLIPSerial); // send the bytes to the SLIP stream 40 | SLIPSerial.endPacket(); // mark the end of the OSC Packet 41 | msg.empty(); // free space occupied by message 42 | 43 | delay(20); 44 | } 45 | -------------------------------------------------------------------------------- /examples/UDPCallResponse/UDPCallResponse.ino: -------------------------------------------------------------------------------- 1 | /* 2 | UDP Call Response 3 | 4 | Send responses to calls for information from a remote host 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | //UDP communication 14 | EthernetUDP Udp; 15 | 16 | //the Arduino's IP 17 | IPAddress ip(128, 32, 122, 252); 18 | 19 | //port numbers 20 | const unsigned int inPort = 8888; 21 | const unsigned int outPort = 9999; 22 | 23 | 24 | //everything on the network needs a unique MAC 25 | #if defined(__MK20DX128__) 26 | // Teensy 3 has MAC burned in 27 | static byte mac[6]; 28 | void read(uint8_t word, uint8_t *mac, uint8_t offset) { 29 | FTFL_FCCOB0 = 0x41; // Selects the READONCE command 30 | FTFL_FCCOB1 = word; // read the given word of read once area 31 | 32 | // launch command and wait until complete 33 | FTFL_FSTAT = FTFL_FSTAT_CCIF; 34 | while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)); 35 | 36 | *(mac+offset) = FTFL_FCCOB5; // collect only the top three bytes, 37 | *(mac+offset+1) = FTFL_FCCOB6; // in the right orientation (big endian). 38 | *(mac+offset+2) = FTFL_FCCOB7; // Skip FTFL_FCCOB4 as it's always 0. 39 | } 40 | void read_mac() { 41 | read(0xe,mac,0); 42 | read(0xf,mac,3); 43 | } 44 | #else 45 | void read_mac() {} 46 | byte mac[] = { 47 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields 48 | #endif 49 | 50 | //outgoing messages 51 | 52 | OSCBundle bundleOUT; 53 | 54 | //converts the pin to an osc address 55 | char * numToOSCAddress( int pin){ 56 | static char s[10]; 57 | int i = 9; 58 | 59 | s[i--]= '\0'; 60 | do 61 | { 62 | s[i] = "0123456789"[pin % 10]; 63 | --i; 64 | pin /= 10; 65 | } 66 | while(pin && i); 67 | s[i] = '/'; 68 | return &s[i]; 69 | } 70 | 71 | /** 72 | * ANALOG 73 | * 74 | * called when the address matches "/a" 75 | * 76 | * format: 77 | * /analog/(pin) 78 | * /u = analogRead with pullup 79 | * 80 | **/ 81 | 82 | void routeAnalog(OSCMessage &msg, int addrOffset ){ 83 | int pinMatched; 84 | pinMatched = msg.match("/0", addrOffset); 85 | if(pinMatched){ 86 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(0), INPUT_PULLUP); //set the pullup 87 | //do the analog read and send the results 88 | bundleOUT.add("/analog/0").add((intOSC_t)analogRead(0)); 89 | } 90 | pinMatched = msg.match("/1", addrOffset); 91 | if(pinMatched){ 92 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(1), INPUT_PULLUP); //set the pullup 93 | //do the analog read and send the results 94 | bundleOUT.add("/analog/1").add((intOSC_t)analogRead(1)); 95 | } 96 | pinMatched = msg.match("/2", addrOffset); 97 | if(pinMatched){ 98 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(2), INPUT_PULLUP); //set the pullup 99 | //do the analog read and send the results 100 | bundleOUT.add("/analog/2").add((intOSC_t)analogRead(2)); 101 | } 102 | pinMatched = msg.match("/3", addrOffset); 103 | if(pinMatched){ 104 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(3), INPUT_PULLUP); //set the pullup 105 | //do the analog read and send the results 106 | bundleOUT.add("/analog/3").add((intOSC_t)analogRead(3)); 107 | } 108 | pinMatched = msg.match("/4", addrOffset); 109 | if(pinMatched){ 110 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(4), INPUT_PULLUP); //set the pullup 111 | //do the analog read and send the results 112 | bundleOUT.add("/analog/4").add((intOSC_t)analogRead(4)); 113 | } 114 | pinMatched = msg.match("/5", addrOffset); 115 | if(pinMatched){ 116 | if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(5), INPUT_PULLUP); //set the pullup 117 | //do the analog read and send the results 118 | bundleOUT.add("/analog/5").add((intOSC_t)analogRead(5)); 119 | } 120 | } 121 | 122 | /** 123 | * MAIN METHODS 124 | * 125 | * setup and loop, bundle receiving/sending, initial routing 126 | */ 127 | void setup() { 128 | //setup ethernet part 129 | read_mac(); 130 | Ethernet.begin(mac,ip); 131 | Udp.begin(inPort); 132 | 133 | } 134 | 135 | //reads and routes the incoming messages 136 | void loop(){ 137 | OSCBundle bundleIN; 138 | int size; 139 | 140 | if( (size = Udp.parsePacket())>0) 141 | { 142 | // unsigned int outPort = Udp.remotePort(); 143 | 144 | while(size--) 145 | bundleIN.fill(Udp.read()); 146 | 147 | if(!bundleIN.hasError()) 148 | bundleIN.route("/analog", routeAnalog); 149 | 150 | // send the response bundle back to where the request came from 151 | Udp.beginPacket(Udp.remoteIP(), outPort); 152 | bundleOUT.send(Udp); 153 | Udp.endPacket(); 154 | bundleOUT.empty(); // empty the bundle ready to use for new messages 155 | } 156 | } 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /examples/UDPEcho/UDPEcho.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Leverage the UDP source IP and port calls to 4 | return OSC information back 5 | 6 | This example can be extended to build routers and forwarders of OSC packets 7 | 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | EthernetUDP Udp; 15 | 16 | //the Arduino's IP 17 | IPAddress ip(128, 32, 122, 252); 18 | 19 | //port numbers 20 | const unsigned int inPort = 8888; 21 | const unsigned int outPort = 9999; 22 | 23 | //everything on the network needs a unique MAC 24 | #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) 25 | // Teensy 3.x has MAC burned in 26 | static byte mac[6]; 27 | void read(uint8_t word, uint8_t *mac, uint8_t offset) { 28 |   FTFL_FCCOB0 = 0x41;             // Selects the READONCE command 29 |   FTFL_FCCOB1 = word;             // read the given word of read once area 30 | 31 |   // launch command and wait until complete 32 |   FTFL_FSTAT = FTFL_FSTAT_CCIF; 33 |   while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)); 34 | 35 |   *(mac+offset) =   FTFL_FCCOB5;       // collect only the top three bytes, 36 |   *(mac+offset+1) = FTFL_FCCOB6;       // in the right orientation (big endian). 37 |   *(mac+offset+2) = FTFL_FCCOB7;       // Skip FTFL_FCCOB4 as it's always 0. 38 | } 39 | void read_mac() { 40 |   read(0xe,mac,0); 41 |   read(0xf,mac,3); 42 | } 43 | #else 44 | void read_mac() {} 45 | byte mac[] = { 46 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields 47 | #endif 48 | 49 | void setup() { 50 | Ethernet.begin(mac,ip); 51 | Udp.begin(inPort); 52 | } 53 | 54 | void loop(){ 55 | OSCBundle bndl; 56 | int size; 57 | 58 | //receive a bundle 59 | if( (size = Udp.parsePacket())>0) 60 | { 61 | // unsigned int outPort = Udp.remotePort(); 62 | 63 | while(size--) 64 | bndl.fill(Udp.read()); 65 | 66 | if(!bndl.hasError()) 67 | { 68 | //and echo it back 69 | if(bndl.size() > 0) 70 | { 71 | static intOSC_t sequencenumber=0; 72 | 73 | // we can sneak an addition onto the end of the bundle 74 | bndl.add("/micros").add((intOSC_t)micros()); // (intOSC_t) is the type of OSC Integers 75 | bndl.add("/sequencenumber").add(sequencenumber++); 76 | 77 | Udp.beginPacket(Udp.remoteIP(), outPort); 78 | bndl.send(Udp); 79 | Udp.endPacket(); 80 | } 81 | } 82 | } 83 | } 84 | 85 | -------------------------------------------------------------------------------- /examples/UDPReceive/UDPReceive.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | /* 10 | * UDPReceiveOSC 11 | * Set a tone according to incoming OSC control 12 | * Adrian Freed 13 | */ 14 | 15 | //UDP communication 16 | 17 | 18 | EthernetUDP Udp; 19 | byte mac[] = { 20 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields 21 | 22 | //the Arduino's IP 23 | IPAddress ip(128, 32, 122, 252); 24 | 25 | //port numbers 26 | const unsigned int inPort = 8888; 27 | 28 | //converts the pin to an osc address 29 | char * numToOSCAddress( int pin){ 30 | static char s[10]; 31 | int i = 9; 32 | 33 | s[i--]= '\0'; 34 | do 35 | { 36 | s[i] = "0123456789"[pin % 10]; 37 | --i; 38 | pin /= 10; 39 | } 40 | while(pin && i); 41 | s[i] = '/'; 42 | return &s[i]; 43 | } 44 | 45 | /** 46 | * TONE 47 | * 48 | * square wave output "/tone" 49 | * 50 | * format: 51 | * /tone/pin 52 | * 53 | * (digital value) (float value) = frequency in Hz 54 | * (no value) disable tone 55 | * 56 | **/ 57 | 58 | void routeTone(OSCMessage &msg, int addrOffset ){ 59 | //iterate through all the analog pins 60 | for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ 61 | //match against the pin number strings 62 | int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); 63 | if(pinMatched){ 64 | unsigned int frequency = 0; 65 | //if it has an int, then it's an integers frequency in Hz 66 | if (msg.isInt(0)){ 67 | frequency = msg.getInt(0); 68 | } //otherwise it's a floating point frequency in Hz 69 | else if(msg.isFloat(0)){ 70 | frequency = msg.getFloat(0); 71 | } 72 | else 73 | noTone(pin); 74 | if(frequency>0) 75 | { 76 | if(msg.isInt(1)) 77 | tone(pin, frequency, msg.getInt(1)); 78 | else 79 | tone(pin, frequency); 80 | } 81 | } 82 | } 83 | } 84 | 85 | void setup() { 86 | //setup ethernet part 87 | Ethernet.begin(mac,ip); 88 | Udp.begin(inPort); 89 | 90 | } 91 | //reads and dispatches the incoming message 92 | void loop(){ 93 | OSCBundle bundleIN; 94 | int size; 95 | 96 | if( (size = Udp.parsePacket())>0) 97 | { 98 | while(size--) 99 | bundleIN.fill(Udp.read()); 100 | 101 | if(!bundleIN.hasError()) 102 | bundleIN.route("/tone", routeTone); 103 | } 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /examples/UDPSendBundle/UDPSendBundle.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Make an OSC bundle and send it over UDP 4 | 5 | OSCBundles allow OSCMessages to be grouped together 6 | to preserve the order and completeness of related messages. 7 | They also allow for timetags to be carried to represent the presentation time 8 | of the messages. 9 | */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | EthernetUDP Udp; 16 | 17 | //the Arduino's IP 18 | IPAddress ip(128, 32, 122, 252); 19 | //destination IP 20 | IPAddress outIp(128, 32, 122, 125); 21 | const unsigned int outPort = 9999; 22 | 23 | byte mac[] = { 24 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields 25 | void setup() { 26 | Ethernet.begin(mac,ip); 27 | Udp.begin(8888); 28 | } 29 | 30 | 31 | 32 | void loop(){ 33 | //declare the bundle 34 | OSCBundle bndl; 35 | 36 | //BOSCBundle's add' returns the OSCMessage so the message's 'add' can be composed together 37 | bndl.add("/analog/0").add((intOSC_t)analogRead(0)); 38 | bndl.add("/analog/1").add((intOSC_t)analogRead(1)); 39 | bndl.add("/digital/5").add((digitalRead(5)==HIGH)?"HIGH":"LOW"); 40 | 41 | Udp.beginPacket(outIp, outPort); 42 | bndl.send(Udp); // send the bytes to the SLIP stream 43 | Udp.endPacket(); // mark the end of the OSC Packet 44 | bndl.empty(); // empty the bundle to free room for a new one 45 | 46 | bndl.add("/mouse/step").add((intOSC_t)analogRead(0)).add((intOSC_t)analogRead(1)); 47 | bndl.add("/units").add("pixels"); 48 | 49 | Udp.beginPacket(outIp, outPort); 50 | bndl.send(Udp); // send the bytes to the SLIP stream 51 | Udp.endPacket(); // mark the end of the OSC Packet 52 | bndl.empty(); // empty the bundle to free room for a new one 53 | 54 | delay(1000); 55 | } 56 | -------------------------------------------------------------------------------- /examples/UDPSendBundlewithTimeTag/UDPSendBundlewithTimeTag.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Make an OSC bundle and send it over UDP 4 | 5 | OSCBundles allow OSCMessages to be grouped together 6 | to preserve the order and completeness of related messages. 7 | They also allow for timetags to be carried to represent the presentation time 8 | of the messages. 9 | */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | EthernetUDP Udp; 18 | 19 | //the Arduino's IP 20 | IPAddress ip(128, 32, 122, 26); 21 | //destination IP 22 | IPAddress outIp(128, 32, 122, 25); 23 | const unsigned int outPort = 9999; 24 | 25 | byte mac[] = { 26 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields 27 | void setup() { 28 | Ethernet.begin(mac,ip); 29 | Udp.begin(8888); 30 | } 31 | 32 | 33 | 34 | void loop(){ 35 | //declare the bundle 36 | OSCBundle bndl; 37 | osctime_t timetag; 38 | 39 | //OSCBundle's add' returns the OSCMessage so the message's 'add' can be composed together 40 | bndl.add("/analog/0").add((intOSC_t)adcRead(0, &timetag)); 41 | bndl.add("/analog/0/time").add(timetag); 42 | 43 | bndl.add("/analog/1").add((intOSC_t)adcRead(1, &timetag)); 44 | bndl.add("/analog/1/time").add(timetag); 45 | 46 | Udp.beginPacket(outIp, outPort); 47 | bndl.setTimetag(oscTime()); 48 | bndl.send(Udp); // send the bytes to the SLIP stream 49 | Udp.endPacket(); // mark the end of the OSC Packet 50 | bndl.empty(); // empty the bundle to free room for a new one 51 | 52 | bndl.add("/mouse/step").add((intOSC_t)analogRead(0)).add((intOSC_t)analogRead(1)); 53 | bndl.add("/units").add("pixels"); 54 | 55 | Udp.beginPacket(outIp, outPort); 56 | bndl.setTimetag(oscTime()); 57 | bndl.send(Udp); // send the bytes to the SLIP stream 58 | Udp.endPacket(); // mark the end of the OSC Packet 59 | bndl.empty(); // empty the bundle to free room for a new one 60 | 61 | delay(100); 62 | } 63 | -------------------------------------------------------------------------------- /examples/UDPSendMessage/UDPSendMessage.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Make an OSC message and send it over UDP 3 | 4 | Adrian Freed 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | EthernetUDP Udp; 12 | 13 | //the Arduino's IP 14 | IPAddress ip(128, 32, 122, 252); 15 | //destination IP 16 | IPAddress outIp(128, 32, 122, 125); 17 | const unsigned int outPort = 9999; 18 | 19 | byte mac[] = { 20 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields 21 | void setup() { 22 | Ethernet.begin(mac,ip); 23 | Udp.begin(8888); 24 | 25 | } 26 | 27 | 28 | void loop(){ 29 | //the message wants an OSC address as first argument 30 | OSCMessage msg("/analog/0"); 31 | msg.add((intOSC_t)analogRead(0)); 32 | 33 | Udp.beginPacket(outIp, outPort); 34 | msg.send(Udp); // send the bytes to the SLIP stream 35 | Udp.endPacket(); // mark the end of the OSC Packet 36 | msg.empty(); // free space occupied by message 37 | 38 | delay(20); 39 | } 40 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | getOSCMessage KEYWORD2 2 | fill KEYWORD2 3 | send KEYWORD2 4 | dispatch KEYWORD2 5 | route KEYWORD2 6 | setTimetag KEYWORD2 7 | getTimetag KEYWORD2 8 | hasError KEYWORD2 9 | add KEYWORD2 10 | set KEYWORD2 11 | match KEYWORD2 12 | fullMatch KEYWORD2 13 | getInt KEYWORD2 14 | getFloat KEYWORD2 15 | getBoolean KEYWORD2 16 | getTime KEYWORD2 17 | getDouble KEYWORD2 18 | getBlob KEYWORD2 19 | getString KEYWORD2 20 | getAddress KEYWORD2 21 | getDataLength KEYWORD2 22 | getBlobLength KEYWORD2 23 | getType KEYWORD2 24 | isInt KEYWORD2 25 | isFloat KEYWORD2 26 | isBlob KEYWORD2 27 | isString KEYWORD2 28 | isBoolean KEYWORD2 29 | isDouble KEYWORD2 30 | isTime KEYWORD2 31 | size KEYWORD2 32 | bytes KEYWORD2 33 | empty KEYWORD2 34 | OSCBundle KEYWORD1 35 | OSCMessage KEYWORD1 36 | OSCMatch KEYWORD1 37 | OSCData KEYWORD1 38 | endTransmission KEYWORD1 39 | endofTransmission KEYWORD1 40 | SLIPEncodedSerial KEYWORD3 41 | SLIPEncodedUSBSerial KEYWORD3 42 | SLIPEncodedSPISerial KEYWORD3 43 | SLIPEncodedTCP KEYWORD3 44 | oscTime KEYWORD1 45 | adcRead KEYWORD1 46 | capacitanceRead KEYWORD1 47 | inputRead KEYWORD1 48 | ####################################### 49 | # Syntax Coloring Map SPI 50 | ####################################### 51 | ####################################### 52 | # Class 53 | ####################################### 54 | StreamSPI0 KEYWORD3 55 | 56 | ####################################### 57 | # Datatypes (KEYWORD1) 58 | ####################################### 59 | 60 | SPI KEYWORD1 61 | StreamSPI KEYWORD1 62 | 63 | ####################################### 64 | # Methods and Functions (KEYWORD2) 65 | ####################################### 66 | begin KEYWORD2 67 | end KEYWORD2 68 | transfer KEYWORD2 69 | setBitOrder KEYWORD2 70 | setDataMode KEYWORD2 71 | setClockDivider KEYWORD2 72 | 73 | 74 | ####################################### 75 | # Constants (LITERAL1) 76 | ####################################### 77 | SPI_CLOCK_DIV4 LITERAL1 78 | SPI_CLOCK_DIV16 LITERAL1 79 | SPI_CLOCK_DIV64 LITERAL1 80 | SPI_CLOCK_DIV128 LITERAL1 81 | SPI_CLOCK_DIV2 LITERAL1 82 | SPI_CLOCK_DIV8 LITERAL1 83 | SPI_CLOCK_DIV32 LITERAL1 84 | SPI_CLOCK_DIV64 LITERAL1 85 | SPI_MODE0 LITERAL1 86 | SPI_MODE1 LITERAL1 87 | SPI_MODE2 LITERAL1 88 | SPI_MODE3 LITERAL1 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OSC", 3 | "version": "3.5.8", 4 | "keywords": "sound, encoding, OSC", 5 | "description": "Open Sound Control (OSC) is an open, transport-independent, message-based encidubg developed for communication among computers, sound synthesizers, and other multimedia devices.", 6 | "authors": [ 7 | { 8 | "name": "Adrian Freed", 9 | "email": "adrian@adrianfreed.com", 10 | "url": "http://www.adrianfreed.com" 11 | }, 12 | { 13 | "name": "Yotam Mann", 14 | "url": "http://yotammann.info" 15 | } 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/CNMAT/OSC.git" 20 | }, 21 | "frameworks": "arduino", 22 | "platforms": "*" 23 | } 24 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=OSC 2 | version=3.5.8 3 | author=Adrian Freed , Yotam Mann 4 | maintainer=Adrian Freed 5 | sentence=Open Sound Control (OSC) 6 | paragraph=Open Sound Control (OSC) is an open, transport-independent, message-based encoding developed for communication among computers, sound synthesizers, and other multimedia devices. 7 | category=Device Control 8 | url=https://github.com/CNMAT/OSC 9 | architectures=* 10 | -------------------------------------------------------------------------------- /test/OSCBundle_test/OSCBundle_test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "TestPrint.h" 4 | 5 | #define HAS_DOUBLE sizeof(double) == 8 6 | 7 | test(bundle_address){ 8 | OSCBundle bundle; 9 | bundle.add("/address").add(1); 10 | assertEqual(bundle.size(), 1); 11 | OSCMessage msg = bundle.getOSCMessage("/address"); 12 | assertTrue(msg.isInt(0)); 13 | assertEqual(msg.getInt(0), 1); 14 | } 15 | 16 | test(bundle_message_position){ 17 | OSCBundle bundle; 18 | bundle.add("/one").add(1); 19 | bundle.add("/two").add(2); 20 | assertEqual(bundle.size(), 2); 21 | OSCMessage msg0 = bundle.getOSCMessage(0); 22 | assertTrue(msg0.isInt(0)); 23 | assertEqual(msg0.getInt(0), 1); 24 | OSCMessage msg1 = bundle.getOSCMessage(1); 25 | assertTrue(msg1.isInt(0)); 26 | assertEqual(msg1.getInt(0), 2); 27 | } 28 | 29 | test(bundle_add_message){ 30 | OSCMessage msg("/msg"); 31 | OSCBundle bundle; 32 | bundle.add(msg).add(1); 33 | assertEqual(bundle.size(), 1); 34 | OSCMessage test_msg = bundle.getOSCMessage(0); 35 | assertTrue(test_msg.isInt(0)); 36 | assertEqual(test_msg.getInt(0), 1); 37 | } 38 | 39 | void routeA(OSCMessage & msg, int offset){ 40 | assertTrue(msg.isInt(0)); 41 | assertEqual(msg.getInt(0), 1); 42 | } 43 | 44 | void routeB(OSCMessage & msg, int offset){ 45 | assertTrue(msg.isInt(0)); 46 | assertEqual(msg.getInt(0), 2); 47 | } 48 | 49 | test(bundle_route){ 50 | OSCMessage msg("/msg"); 51 | OSCBundle bundle; 52 | bundle.add("/a").add(1); 53 | bundle.add("/b/1").add(2); 54 | assertEqual(bundle.size(), 2); 55 | assertTrue(bundle.route("/a", routeA)); 56 | assertTrue(bundle.route("/b", routeB)); 57 | } 58 | 59 | void dispatchA(OSCMessage & msg){ 60 | assertTrue(msg.isInt(0)); 61 | assertEqual(msg.getInt(0), 1); 62 | } 63 | 64 | void dispatchB(OSCMessage & msg){ 65 | assertTrue(msg.isInt(0)); 66 | assertEqual(msg.getInt(0), 2); 67 | } 68 | 69 | test(bundle_dispatch){ 70 | OSCMessage msg("/msg"); 71 | OSCBundle bundle; 72 | bundle.add("/a").add(1); 73 | bundle.add("/b").add(2); 74 | assertEqual(bundle.size(), 2); 75 | assertTrue(bundle.route("/a", routeA)); 76 | assertTrue(bundle.route("/b", routeB)); 77 | } 78 | 79 | test(bundle_encode){ 80 | TestPrint printer; 81 | //this is the desired output 82 | uint8_t testBuffer[] = {35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 97, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 47, 98, 0, 0, 44, 105, 0, 0, 0, 0, 0, 2}; 83 | OSCBundle bundle; 84 | bundle.add("/a").add(1); 85 | bundle.add("/b").add(2); 86 | bundle.send(printer); 87 | assertEqual(printer.size(), sizeof(testBuffer)); 88 | for (int i = 0; i < sizeof(testBuffer); i++){ 89 | assertEqual(testBuffer[i], printer.at(i)); 90 | } 91 | } 92 | 93 | test(bundle_decode){ 94 | uint8_t testBuffer[] = {35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 97, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 47, 98, 0, 0, 44, 105, 0, 0, 0, 0, 0, 2}; 95 | OSCBundle bundle; 96 | bundle.fill(testBuffer, sizeof(testBuffer)); 97 | assertEqual(bundle.size(), 2); 98 | OSCMessage msgA = bundle.getOSCMessage("/a"); 99 | assertTrue(msgA.isInt(0)); 100 | assertEqual(msgA.getInt(0), 1); 101 | OSCMessage msgB = bundle.getOSCMessage("/b"); 102 | assertTrue(msgB.isInt(0)); 103 | assertEqual(msgB.getInt(0), 2); 104 | } 105 | 106 | test(bundle_decode_invalid){ 107 | uint8_t testBuffer[] = {35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 97, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 47, 98, 0, 0, 44, 105, 0, 0, 0, 0, 2}; 108 | OSCBundle bundle; 109 | bundle.fill(testBuffer, sizeof(testBuffer)); 110 | assertTrue(bundle.hasError()); 111 | } 112 | 113 | 114 | void setup() 115 | { 116 | Serial.begin(9600); 117 | while(!Serial); // for the Arduino Leonardo/Micro only 118 | } 119 | 120 | void loop() 121 | { 122 | Test::run(); 123 | } 124 | -------------------------------------------------------------------------------- /test/OSCBundle_test/TestPrint.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * A print class for testing the encoder 4 | */ 5 | class TestPrint : public Print { 6 | 7 | private: 8 | //a small test buffer 9 | uint8_t buffer[64]; 10 | 11 | //pointer to the current write spot 12 | int bufferPointer; 13 | 14 | public: 15 | 16 | TestPrint(){ 17 | bufferPointer = 0; 18 | } 19 | 20 | size_t write(uint8_t character) { 21 | buffer[bufferPointer++] = character; 22 | return character; 23 | } 24 | 25 | int size(){ 26 | return bufferPointer; 27 | } 28 | 29 | uint8_t at(int index){ 30 | return buffer[index]; 31 | } 32 | 33 | void clear(){ 34 | bufferPointer = 0; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /test/OSCData_test/OSCData_test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define HAS_DOUBLE sizeof(double) == 8 5 | 6 | test(data_int){ 7 | int i = 1; 8 | OSCData datum(i); 9 | assertEqual(datum.getInt(), i); 10 | assertEqual(datum.type, 'i'); 11 | } 12 | 13 | test(data_float){ 14 | float f = 1.1; 15 | OSCData datum(f); 16 | assertEqual(datum.getFloat(), f); 17 | assertEqual(datum.type, 'f'); 18 | } 19 | 20 | test(data_string){ 21 | const char * testStr = "data"; 22 | int testStrLen = strlen(testStr) + 1; 23 | OSCData datum(testStr); 24 | char str[testStrLen]; 25 | datum.getString(str, testStrLen); 26 | assertEqual(strcmp(str, testStr), 0); 27 | assertEqual(datum.type, 's'); 28 | } 29 | 30 | test(data_string_partial_copy){ 31 | const char * testStr = "data"; 32 | int testStrLen = strlen(testStr) + 1; 33 | OSCData datum(testStr); 34 | char str[testStrLen]; 35 | assertEqual(datum.getString(str, 2), 2); 36 | assertEqual(strncmp(str, testStr, 2), 0); 37 | } 38 | 39 | test(data_bool){ 40 | bool f = false; 41 | OSCData datum(f); 42 | assertFalse(datum.getBoolean()); 43 | } 44 | 45 | test(has_double){ 46 | assertEqual(sizeof(double), 8U); 47 | } 48 | 49 | test(data_double){ 50 | if (HAS_DOUBLE){ 51 | double d = 1.1; 52 | OSCData datum = OSCData(d); 53 | assertEqual(datum.getDouble(), d); 54 | assertEqual(datum.type, 'd'); 55 | } 56 | } 57 | 58 | test(data_blob){ 59 | uint8_t b[] = {0, 1, 2, 3}; 60 | OSCData datum(b, 4); 61 | uint8_t blob[4]; 62 | datum.getBlob(blob, 4); 63 | for (int i = 0; i < 4; i++){ 64 | assertEqual(blob[i], b[i]); 65 | } 66 | assertEqual(datum.type, 'b'); 67 | } 68 | 69 | test(data_blob_partial_copy){ 70 | uint8_t b[] = {0, 1, 2, 3}; 71 | OSCData datum(b, 4); 72 | uint8_t blob[4]; 73 | assertEqual(datum.getBlob(blob, 2), 2); 74 | for (int i = 0; i < 2; i++){ 75 | assertEqual(blob[i], b[i]); 76 | } 77 | } 78 | 79 | test(data_copy){ 80 | OSCData datum = OSCData(1); 81 | OSCData cpy(datum); 82 | assertEqual(cpy.getInt(), 1); 83 | assertEqual(cpy.type, 'i'); 84 | } 85 | 86 | 87 | void setup() 88 | { 89 | Serial.begin(9600); 90 | while(!Serial); // for the Arduino Leonardo/Micro only 91 | } 92 | 93 | void loop() 94 | { 95 | Test::run(); 96 | } 97 | -------------------------------------------------------------------------------- /test/OSCMessage_encode_decode_test/OSCMessage_encode_decode_test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "TestPrint.h" 4 | 5 | #define HAS_DOUBLE sizeof(double) == 8 6 | 7 | test(message_encode_int){ 8 | TestPrint printer; 9 | //this is the desired output 10 | uint8_t testBuffer[] = {47, 102, 111, 111, 0, 0, 0, 0, 44, 105, 105, 105, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 255, 255, 255, 236}; 11 | OSCMessage msg("/foo"); 12 | msg.add(1); 13 | msg.add(2); 14 | msg.add(-20); 15 | msg.send(printer); 16 | assertEqual(printer.size(), sizeof(testBuffer)); 17 | for (unsigned int i = 0; i < sizeof(testBuffer); i++){ 18 | assertEqual(testBuffer[i], printer.at(i)); 19 | } 20 | } 21 | 22 | test(message_encode_string){ 23 | TestPrint printer; 24 | //this is the desired output 25 | uint8_t testBuffer[] = {47, 116, 101, 115, 116, 0, 0, 0, 44, 115, 115, 0, 104, 105, 0, 0, 104, 111, 119, 100, 121, 0, 0, 0}; 26 | OSCMessage msg("/test"); 27 | msg.add("hi"); 28 | msg.add("howdy"); 29 | msg.send(printer); 30 | assertEqual(printer.size(), sizeof(testBuffer)); 31 | for (unsigned int i = 0; i < sizeof(testBuffer); i++){ 32 | assertEqual(testBuffer[i], printer.at(i)); 33 | } 34 | } 35 | 36 | test(message_encode_float){ 37 | TestPrint printer; 38 | //this is the desired output 39 | uint8_t testBuffer[] = {47, 97, 100, 100, 114, 101, 115, 115, 0, 0, 0, 0, 44, 102, 102, 0, 63, 128, 0, 0, 192, 6, 102, 102}; 40 | OSCMessage msg("/address"); 41 | msg.add(1.0f); 42 | msg.add(-2.1f); 43 | msg.send(printer); 44 | assertEqual(printer.size(), sizeof(testBuffer)); 45 | for (unsigned int i = 0; i < sizeof(testBuffer); i++){ 46 | assertEqual(testBuffer[i], printer.at(i)); 47 | } 48 | } 49 | 50 | test(message_encode_double){ 51 | if (HAS_DOUBLE){ 52 | TestPrint printer; 53 | //this is the desired output 54 | uint8_t testBuffer[] = {47, 97, 0, 0, 44, 100, 100, 0, 64, 89, 0, 0, 0, 0, 0, 0, 63, 80, 98, 77, 210, 241, 169, 252}; 55 | OSCMessage msg("/a"); 56 | double d0 = 100; 57 | double d1 = 0.001; 58 | msg.add(d0); 59 | msg.add(d1); 60 | msg.send(printer); 61 | assertEqual(printer.size(), sizeof(testBuffer)); 62 | for (unsigned int i = 0; i < sizeof(testBuffer); i++){ 63 | assertEqual(testBuffer[i], printer.at(i)); 64 | } 65 | } 66 | } 67 | 68 | test(message_encode_blob){ 69 | TestPrint printer; 70 | //this is the desired output 71 | uint8_t testBuffer[] = {47, 98, 0, 0, 44, 98, 0, 0, 0, 0, 0, 5, 1, 2, 3, 4, 5, 0, 0, 0}; 72 | OSCMessage msg("/b"); 73 | uint8_t blob[] = {1, 2, 3, 4, 5}; 74 | msg.add(blob, 5); 75 | msg.send(printer); 76 | assertEqual(printer.size(), sizeof(testBuffer)); 77 | for (unsigned int i = 0; i < sizeof(testBuffer); i++){ 78 | assertEqual(testBuffer[i], printer.at(i)); 79 | } 80 | } 81 | 82 | test(message_encode_mixed){ 83 | TestPrint printer; 84 | //this is the desired output 85 | uint8_t testBuffer[] = {47, 109, 105, 120, 101, 100, 0, 0, 44, 115, 105, 102, 0, 0, 0, 0, 111, 110, 101, 0, 0, 0, 0, 1, 63, 128, 0, 0}; 86 | OSCMessage msg("/mixed"); 87 | msg.add("one"); 88 | msg.add(1); 89 | msg.add(1.0f); 90 | msg.send(printer); 91 | assertEqual(printer.size(), sizeof(testBuffer)); 92 | for (unsigned int i = 0; i < sizeof(testBuffer); i++){ 93 | assertEqual(testBuffer[i], printer.at(i)); 94 | } 95 | } 96 | 97 | test(message_decode_int){ 98 | uint8_t testBuffer[] = {47, 105, 110, 116, 115, 0, 0, 0, 44, 105, 105, 105, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 200, 255, 255, 255, 231}; 99 | OSCMessage msg; 100 | msg.fill(testBuffer, sizeof(testBuffer)); 101 | assertEqual(msg.size(), 3); 102 | assertTrue(msg.isInt(0)); 103 | assertTrue(msg.isInt(1)); 104 | assertTrue(msg.isInt(2)); 105 | assertEqual(msg.getInt(0), 1); 106 | assertEqual(msg.getInt(1), 200); 107 | assertEqual(msg.getInt(2), -25); 108 | } 109 | 110 | test(message_decode_float){ 111 | uint8_t testBuffer[] = {47, 102, 108, 111, 97, 116, 115, 0, 44, 102, 102, 0, 191, 128, 0, 0, 67, 72, 2, 143}; 112 | OSCMessage msg; 113 | msg.fill(testBuffer, sizeof(testBuffer)); 114 | assertEqual(msg.size(), 2); 115 | assertFalse(msg.isInt(0)); 116 | assertTrue(msg.isFloat(0)); 117 | assertTrue(msg.isFloat(1)); 118 | assertEqual(msg.getFloat(0), -1.0f); 119 | assertEqual(msg.getFloat(1), 200.01f); 120 | } 121 | 122 | test(message_decode_double){ 123 | if (HAS_DOUBLE){ 124 | uint8_t testBuffer[] = {47, 100, 0, 0, 44, 100, 0, 0, 64, 36, 5, 30, 184, 81, 235, 133}; 125 | OSCMessage msg; 126 | msg.fill(testBuffer, sizeof(testBuffer)); 127 | double d = 10.01; 128 | assertEqual(msg.size(), 1); 129 | assertTrue(msg.isDouble(0)); 130 | assertEqual(msg.getDouble(0), d); 131 | } 132 | } 133 | 134 | test(message_decode_string){ 135 | uint8_t testBuffer[] = {47, 115, 116, 114, 105, 110, 103, 115, 0, 0, 0, 0, 44, 115, 115, 0, 104, 101, 121, 0, 104, 105, 0, 0}; 136 | OSCMessage msg; 137 | msg.fill(testBuffer, sizeof(testBuffer)); 138 | assertEqual(msg.size(), 2); 139 | assertTrue(msg.isString(0)); 140 | assertTrue(msg.isString(1)); 141 | char str[4]; 142 | msg.getString(0, str, 5); 143 | assertEqual(strcmp(str, "hey"), 0); 144 | msg.getString(1, str, 3); 145 | assertEqual(strcmp(str, "hi"), 0); 146 | } 147 | 148 | test(message_decode_blob){ 149 | uint8_t testBuffer[] = {47, 98, 0, 0, 44, 98, 0, 0, 0, 0, 0, 4, 0, 1, 2, 3}; 150 | OSCMessage msg; 151 | msg.fill(testBuffer, sizeof(testBuffer)); 152 | assertEqual(msg.size(), 1); 153 | assertTrue(msg.isBlob(0)); 154 | uint8_t blob[4]; 155 | msg.getBlob(0, blob, 4); 156 | for (int i = 0; i < 4; i++){ 157 | assertEqual(i, blob[i]); 158 | } 159 | } 160 | 161 | test(message_decode_mixed){ 162 | uint8_t testBuffer[] = {47, 109, 105, 120, 101, 100, 0, 0, 44, 115, 105, 102, 0, 0, 0, 0, 111, 110, 101, 0, 0, 0, 0, 1, 63, 128, 0, 0}; 163 | OSCMessage msg; 164 | msg.fill(testBuffer, sizeof(testBuffer)); 165 | assertEqual(msg.size(), 3); 166 | assertTrue(msg.isString(0)); 167 | assertTrue(msg.isInt(1)); 168 | assertTrue(msg.isFloat(2)); 169 | assertEqual(msg.getInt(1), 1); 170 | assertEqual(msg.getFloat(2), 1.0f); 171 | } 172 | 173 | void setup() 174 | { 175 | Serial.begin(9600); 176 | while(!Serial); // for the Arduino Leonardo/Micro only 177 | } 178 | 179 | void loop() 180 | { 181 | Test::run(); 182 | } 183 | -------------------------------------------------------------------------------- /test/OSCMessage_encode_decode_test/TestPrint.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * A print class for testing the encoder 4 | */ 5 | class TestPrint : public Print { 6 | 7 | private: 8 | //a small test buffer 9 | uint8_t buffer[64]; 10 | 11 | //pointer to the current write spot 12 | unsigned int bufferPointer; 13 | 14 | public: 15 | 16 | TestPrint(){ 17 | bufferPointer = 0; 18 | } 19 | 20 | size_t write(uint8_t character) { 21 | buffer[bufferPointer++] = character; 22 | return character; 23 | } 24 | 25 | unsigned int size(){ 26 | return bufferPointer; 27 | } 28 | 29 | uint8_t at(int index){ 30 | return buffer[index]; 31 | } 32 | 33 | void clear(){ 34 | bufferPointer = 0; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /test/OSCMessage_match_test/OSCMessage_match_test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | test(message_address_match){ 6 | OSCMessage msg("/a/0"); 7 | assertEqual(msg.match("/a"), 2); 8 | assertEqual(msg.match("/a/0"), 4); 9 | } 10 | 11 | test(message_address_match_offset){ 12 | OSCMessage msg("/a/0"); 13 | assertEqual(msg.match("/0", 2), 2); 14 | assertEqual(msg.match("/1", 2), 0); 15 | } 16 | 17 | test(message_address_match_range){ 18 | OSCMessage msg("/[a-z]/0"); 19 | assertEqual(msg.match("/a"), 6); 20 | assertEqual(msg.match("/b/0"), 8); 21 | } 22 | 23 | test(message_address_match_or){ 24 | OSCMessage msg("/{a,b}/0"); 25 | assertEqual(msg.match("/a/0"), 8); 26 | assertEqual(msg.match("/b/0"), 8); 27 | assertEqual(msg.match("/c/0"), 0); 28 | } 29 | 30 | test(message_address_match_char){ 31 | OSCMessage msg("/a/?"); 32 | assertEqual(msg.match("/a/0"), 4); 33 | assertEqual(msg.match("/a/1"), 4); 34 | assertEqual(msg.match("/a/10"), 0); 35 | } 36 | 37 | test(message_address_match_star){ 38 | OSCMessage msg("/a/*"); 39 | assertEqual(msg.match("/a/0"), 4); 40 | assertEqual(msg.match("/a/10"), 4); 41 | assertEqual(msg.match("/a/100"), 4); 42 | } 43 | 44 | test(message_address_fullMatch){ 45 | OSCMessage msg("/a/0"); 46 | assertTrue(msg.fullMatch("/a/0")); 47 | assertFalse(msg.fullMatch("/a/1")); 48 | assertTrue(msg.fullMatch("/0", 2)); 49 | } 50 | 51 | void dispatchMsg(OSCMessage &m){ 52 | assertTrue(m.isInt(0)); 53 | assertEqual(m.getInt(0), 1); 54 | } 55 | 56 | test(message_address_dispatch){ 57 | OSCMessage msg("/a/[0-9]"); 58 | msg.add(1); 59 | assertTrue(msg.dispatch("/a/0", dispatchMsg)); 60 | assertTrue(msg.dispatch("/1", dispatchMsg, 2)); 61 | } 62 | 63 | 64 | void routeMsg(OSCMessage &m, int offset){ 65 | assertTrue(m.isInt(0)); 66 | assertEqual(m.getInt(0), 2); 67 | assertEqual(offset, 2); 68 | } 69 | 70 | test(message_address_route){ 71 | OSCMessage msg("/?/[0-9]"); 72 | msg.add(2); 73 | assertTrue(msg.route("/a", routeMsg)); 74 | assertTrue(msg.route("/b", routeMsg)); 75 | } 76 | 77 | void setup() 78 | { 79 | Serial.begin(9600); 80 | while(!Serial); // for the Arduino Leonardo/Micro only 81 | } 82 | 83 | void loop() 84 | { 85 | Test::run(); 86 | } 87 | -------------------------------------------------------------------------------- /test/OSCMessage_test/OSCMessage_test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define HAS_DOUBLE sizeof(double) == 8 5 | 6 | 7 | test(message_address){ 8 | OSCMessage msg("/hihi"); 9 | char addr[6]; 10 | msg.getAddress(addr); 11 | assertEqual(strcmp(addr, "/hihi"), 0); 12 | } 13 | 14 | test(message_address_offset){ 15 | OSCMessage msg("/foo/bar"); 16 | char addr[5]; 17 | msg.getAddress(addr, 4); 18 | assertEqual(strcmp(addr, "/bar"), 0); 19 | } 20 | 21 | test(message_copy){ 22 | OSCMessage msg("/hihi"); 23 | msg.add(1); 24 | OSCMessage cpy(&msg); 25 | assertEqual(cpy.size(), 1); 26 | assertTrue(cpy.isInt(0)); 27 | assertEqual(cpy.getInt(0), 1); 28 | } 29 | 30 | test(message_int){ 31 | OSCMessage msg("/foo"); 32 | msg.add(1); 33 | assertTrue(msg.isInt(0)); 34 | assertEqual(msg.getInt(0), 1); 35 | assertEqual(msg.getDataLength(0), 4); 36 | } 37 | 38 | test(message_float){ 39 | OSCMessage msg("/foo"); 40 | msg.add(1.0f); 41 | assertTrue(msg.isFloat(0)); 42 | assertEqual(msg.getFloat(0), 1.0f); 43 | assertEqual(msg.getDataLength(0), 4); 44 | } 45 | 46 | test(message_string){ 47 | OSCMessage msg("/foo"); 48 | msg.add("oh hi"); 49 | assertTrue(msg.isString(0)); 50 | char str[6]; 51 | msg.getString(0, str, 6); 52 | assertEqual(strcmp(str, "oh hi"), 0); 53 | assertEqual(msg.getDataLength(0), 6); 54 | } 55 | 56 | test(message_blob){ 57 | OSCMessage msg("/foo"); 58 | uint8_t b[] = {0, 1, 2, 3, 4}; 59 | msg.add(b, 5); 60 | assertTrue(msg.isBlob(0)); 61 | uint8_t blob[5]; 62 | msg.getBlob(0, blob, 5); 63 | for (int i = 0; i < 5; i++){ 64 | assertEqual(blob[i], b[i]); 65 | } 66 | //9 because it includes the 4 byte length 67 | assertEqual(msg.getDataLength(0), 9); 68 | } 69 | 70 | test(message_boolean){ 71 | OSCMessage msg("/foo"); 72 | msg.add(true); 73 | assertTrue(msg.isBoolean(0)); 74 | assertEqual(msg.getBoolean(0), true); 75 | assertEqual(msg.getDataLength(0), 0); 76 | } 77 | 78 | test(mixed_message_type){ 79 | OSCMessage msg("/foo"); 80 | msg.add(true); 81 | msg.add(1.0f); 82 | msg.add(2); 83 | msg.add("test"); 84 | assertEqual(msg.size(), 4); 85 | assertEqual(msg.getType(0), 'T'); 86 | assertTrue(msg.isBoolean(0)); 87 | assertFalse(msg.isBoolean(1)); 88 | assertTrue(msg.isFloat(1)); 89 | assertTrue(msg.isInt(2)); 90 | assertTrue(msg.isString(3)); 91 | assertEqual(msg.getInt(2), 2); 92 | assertEqual(msg.getInt(3), (int)NULL); 93 | } 94 | 95 | void setup() 96 | { 97 | Serial.begin(9600); 98 | while(!Serial); // for the Arduino Leonardo/Micro only 99 | } 100 | 101 | void loop() 102 | { 103 | Test::run(); 104 | } 105 | --------------------------------------------------------------------------------