SerialOscuinoGemmaM0.ino 7.6 KB

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