SerialOscuinowithBundles.ino 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #include <OSCBundle.h>
  2. #include <OSCBoards.h>
  3. #ifdef BOARD_HAS_USB_SERIAL
  4. #include <SLIPEncodedUSBSerial.h>
  5. SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
  6. #else
  7. #include <SLIPEncodedSerial.h>
  8. SLIPEncodedSerial SLIPSerial(Serial);
  9. #endif
  10. //outgoing messages
  11. OSCBundle bundleOUT;
  12. //converts the pin to an osc address
  13. char * numToOSCAddress( int pin){
  14. static char s[10];
  15. int i = 9;
  16. s[i--]= '\0';
  17. do
  18. {
  19. s[i] = "0123456789"[pin % 10];
  20. --i;
  21. pin /= 10;
  22. }
  23. while(pin && i);
  24. s[i] = '/';
  25. return &s[i];
  26. }
  27. /**
  28. * ROUTES
  29. *
  30. * these are where the routing functions go
  31. *
  32. */
  33. /**
  34. * DIGITAL
  35. *
  36. * called when address matched "/d"
  37. * expected format:
  38. * /d/(pin)
  39. * /u = digitalRead with pullup
  40. * (no value) = digitalRead without pullup
  41. * (value) = digital write on that pin
  42. *
  43. */
  44. void routeDigital(OSCMessage &msg, int addrOffset ){
  45. //match input or output
  46. for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){
  47. //match against the pin number strings
  48. int pinMatched = msg.match(numToOSCAddress(pin), addrOffset);
  49. if(pinMatched){
  50. //if it has an int, then it's a digital write
  51. if (msg.isInt(0)){
  52. pinMode(pin, OUTPUT);
  53. digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW);
  54. }
  55. else if(msg.isFloat(0)){
  56. analogWrite(pin, (int)(msg.getFloat(0)*255.0f));
  57. }
  58. //otherwise it's an digital read
  59. //with a pullup?
  60. else if (msg.fullMatch("/u", pinMatched+addrOffset)){
  61. //set the pullup
  62. pinMode(pin, INPUT_PULLUP);
  63. //setup the output address which should be /d/(pin)/u
  64. char outputAddress[9];
  65. strcpy(outputAddress, "/d");
  66. strcat(outputAddress, numToOSCAddress(pin));
  67. strcat(outputAddress,"/u");
  68. //do the digital read and send the results
  69. bundleOUT.add(outputAddress).add(digitalRead(pin));
  70. } //else without a pullup
  71. else {
  72. //set the pinmode
  73. pinMode(pin, INPUT);
  74. //setup the output address which should be /d/(pin)
  75. char outputAddress[6];
  76. strcpy(outputAddress, "/d");
  77. strcat(outputAddress, numToOSCAddress(pin));
  78. //do the digital read and send the results
  79. bundleOUT.add(outputAddress).add(digitalRead(pin));
  80. }
  81. }
  82. }
  83. }
  84. /**
  85. * ANALOG
  86. *
  87. * called when the address matches "/a"
  88. *
  89. * format:
  90. * /a/(pin)
  91. * /u = analogRead with pullup
  92. * (no value) = analogRead without pullup
  93. * (digital value) = digital write on that pin
  94. * (float value) = analogWrite on that pin
  95. *
  96. **/
  97. void routeAnalog(OSCMessage &msg, int addrOffset ){
  98. //iterate through all the analog pins
  99. for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){
  100. //match against the pin number strings
  101. int pinMatched = msg.match(numToOSCAddress(pin), addrOffset);
  102. if(pinMatched){
  103. //if it has an int, then it's a digital write
  104. if (msg.isInt(0)){
  105. pinMode(analogInputToDigitalPin(pin), OUTPUT);
  106. digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW);
  107. }
  108. else if(msg.isFloat(0)){
  109. analogWrite(pin, (int)(msg.getFloat(0)*255.0f));
  110. }
  111. #ifdef BOARD_HAS_ANALOG_PULLUP
  112. //with a pullup?
  113. else if (msg.fullMatch("/u", pinMatched+addrOffset)){
  114. //set the pullup
  115. pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP);
  116. //setup the output address which should be /a/(pin)/u
  117. char outputAddress[9];
  118. strcpy(outputAddress, "/a");
  119. strcat(outputAddress, numToOSCAddress(pin));
  120. strcat(outputAddress,"/u");
  121. //do the analog read and send the results
  122. bundleOUT.add(outputAddress).add((int32_t)analogRead(pin));
  123. } //else without a pullup
  124. #endif
  125. else {
  126. //otherwise it's an analog read
  127. //set the pinmode
  128. pinMode(analogInputToDigitalPin(pin), INPUT);
  129. //setup the output address which should be /a/(pin)
  130. char outputAddress[6];
  131. strcpy(outputAddress, "/a");
  132. strcat(outputAddress, numToOSCAddress(pin));
  133. //do the analog read and send the results
  134. bundleOUT.add(outputAddress).add((int32_t)analogRead(pin));
  135. }
  136. }
  137. }
  138. }
  139. #ifdef BOARD_HAS_TONE
  140. /**
  141. * TONE
  142. *
  143. * square wave output "/tone"
  144. *
  145. * format:
  146. * /tone/pin
  147. *
  148. * (digital value) (float value) = frequency in Hz
  149. * (no value) disable tone
  150. *
  151. **/
  152. void routeTone(OSCMessage &msg, int addrOffset ){
  153. //iterate through all the analog pins
  154. for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){
  155. //match against the pin number strings
  156. int pinMatched = msg.match(numToOSCAddress(pin), addrOffset);
  157. if(pinMatched){
  158. unsigned int frequency = 0;
  159. //if it has an int, then it's an integers frequency in Hz
  160. if (msg.isInt(0)){
  161. frequency = msg.getInt(0);
  162. } //otherwise it's a floating point frequency in Hz
  163. else if(msg.isFloat(0)){
  164. frequency = msg.getFloat(0);
  165. }
  166. else
  167. noTone(pin);
  168. if(frequency>0)
  169. {
  170. if(msg.isInt(1))
  171. tone(pin, frequency, msg.getInt(1));
  172. else
  173. tone(pin, frequency);
  174. }
  175. }
  176. }
  177. }
  178. #endif
  179. #ifdef BOARD_HAS_CAPACITANCE_SENSING
  180. #if defined(__MKL26Z64__)
  181. #define NTPINS 11
  182. const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,3,4 };
  183. #else
  184. #define NTPINS 12
  185. const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,25,32, 33 };
  186. #endif
  187. void routeTouch(OSCMessage &msg, int addrOffset )
  188. {
  189. for(int i=0;i<NTPINS;++i)
  190. {
  191. const char *name = numToOSCAddress(cpins[i]);
  192. int pinMatched = msg.match(name, addrOffset);
  193. if(pinMatched)
  194. {
  195. char outputAddress[9];
  196. strcpy(outputAddress, "/c");
  197. strcat(outputAddress, name);
  198. bundleOUT.add(outputAddress).add(touchRead(cpins[i]));
  199. }
  200. }
  201. }
  202. #endif
  203. /**
  204. * SYSTEM MESSAGES
  205. *
  206. * expected format:
  207. * /s
  208. * /m = microseconds
  209. * /d = number of digital pins
  210. * /a = number of analog pins
  211. * /l integer = set the led
  212. * /t = temperature
  213. * /s = power supply voltage
  214. */
  215. //
  216. void routeSystem(OSCMessage &msg, int addrOffset ){
  217. #ifdef BOARD_HAS_DIE_TEMPERATURE_SENSOR
  218. if (msg.fullMatch("/t", addrOffset)){
  219. bundleOUT.add("/s/t").add(getTemperature());
  220. }
  221. #endif
  222. #ifdef BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT
  223. if (msg.fullMatch("/s", addrOffset)){
  224. bundleOUT.add("/s/s").add(getSupplyVoltage());
  225. }
  226. #endif
  227. if (msg.fullMatch("/m", addrOffset)){
  228. bundleOUT.add("/s/m").add((int32_t)micros());
  229. }
  230. if (msg.fullMatch("/d", addrOffset)){
  231. bundleOUT.add("/s/d").add(NUM_DIGITAL_PINS);
  232. }
  233. if (msg.fullMatch("/a", addrOffset)){
  234. bundleOUT.add("/s/a").add(NUM_ANALOG_INPUTS);
  235. }
  236. if (msg.fullMatch("/l", addrOffset)){
  237. if (msg.isInt(0)){
  238. pinMode(LED_BUILTIN, OUTPUT);
  239. int i = msg.getInt(0);
  240. pinMode(LED_BUILTIN, OUTPUT);
  241. digitalWrite(LED_BUILTIN, (i > 0)? HIGH: LOW);
  242. bundleOUT.add("/s/l").add(i);
  243. }
  244. }
  245. }
  246. /**
  247. * MAIN METHODS
  248. *
  249. * setup and loop, bundle receiving/sending, initial routing
  250. */
  251. void setup() {
  252. SLIPSerial.begin(115200); // set this as high as you can reliably run on your platform
  253. }
  254. //reads and routes the incoming messages
  255. void loop(){
  256. OSCBundle bundleIN;
  257. int size;
  258. while(!SLIPSerial.endofPacket())
  259. if ((size =SLIPSerial.available()) > 0)
  260. {
  261. while(size--)
  262. bundleIN.fill(SLIPSerial.read());
  263. }
  264. if(!bundleIN.hasError())
  265. {
  266. bundleIN.route("/s", routeSystem);
  267. bundleIN.route("/a", routeAnalog);
  268. bundleIN.route("/d", routeDigital);
  269. #ifdef BOARD_HAS_TONE
  270. bundleIN.route("/tone", routeTone);
  271. #endif
  272. #ifdef BOARD_HAS_CAPACITANCE_SENSING
  273. bundleIN.route("/c", routeTouch);
  274. #endif
  275. }
  276. bundleIN.empty();
  277. //send the outgoing message
  278. SLIPSerial.beginPacket();
  279. bundleOUT.send(SLIPSerial);
  280. SLIPSerial.endPacket();
  281. bundleOUT.empty();
  282. }