OSCEsplora.ino 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. Bidirectional Esplora OSC communications using SLIP
  3. Adrian Freed, Jeff Lubow 2013
  4. Includes some examples of common "best practices" for OSC name space and parameter
  5. mapping design.
  6. */
  7. #include <Esplora.h>
  8. #include <OSCBundle.h>
  9. //Teensy and Leonardo variants have special USB serial
  10. #include <SLIPEncodedUSBSerial.h>
  11. #if !defined(__AVR_ATmega32U4__)
  12. #error select Arduino Esplora in board menu
  13. #endif
  14. // temperature
  15. float getTemperature(){
  16. int result;
  17. ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0);
  18. ADCSRB = _BV(MUX5);
  19. delayMicroseconds(200); // wait for Vref to settle
  20. ADCSRA |= _BV(ADSC); // Convert
  21. while (bit_is_set(ADCSRA,ADSC));
  22. result = ADCL;
  23. result |= ADCH<<8;
  24. analogReference(DEFAULT);
  25. return result/1023.0f;
  26. }
  27. float getSupplyVoltage(){
  28. // powersupply
  29. int result;
  30. // Read 1.1V reference against AVcc
  31. ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  32. delayMicroseconds(300); // wait for Vref to settle
  33. ADCSRA |= _BV(ADSC); // Convert
  34. while (bit_is_set(ADCSRA,ADSC));
  35. result = ADCL;
  36. result |= ADCH<<8;
  37. float supplyvoltage = 1.1264f *1023 / result;
  38. return supplyvoltage;
  39. }
  40. // Esplora has a dinky green led at the top left and a big RGB led at the bottom right
  41. void routeLed(OSCMessage &msg, int addrOffset ){
  42. if(msg.match("/red", addrOffset)) {
  43. if (msg.isInt(0)) Esplora.writeRed( (byte)msg.getInt(0));
  44. }
  45. else
  46. if(msg.match("/green", addrOffset)) {
  47. if (msg.isInt(0)) Esplora.writeGreen( (byte)msg.getInt(0));
  48. }
  49. else
  50. if(msg.match("/blue", addrOffset)) {
  51. if (msg.isInt(0)) Esplora.writeBlue( (byte)msg.getInt(0));
  52. }
  53. else
  54. if(msg.match("/rgb", addrOffset)) {
  55. if (msg.isInt(0)&&msg.isInt(1)&&msg.isInt(2))
  56. {
  57. Esplora.writeRGB((byte)msg.getInt(0),(byte)msg.getInt(1),(byte)msg.getInt(2));
  58. }
  59. }
  60. else
  61. {
  62. if (msg.isInt(0))
  63. {
  64. digitalWrite(13, msg.getInt(0)>0?HIGH:LOW);
  65. }
  66. }
  67. }
  68. // Esplora has a dinky green led at the top left and a big RGB led at the bottom right
  69. void routeOut(OSCMessage &msg, int addrOffset ){
  70. if(msg.match("/B", addrOffset) || msg.match("/b", addrOffset)) {
  71. if (msg.isInt(0)) {
  72. pinMode(11,OUTPUT);
  73. digitalWrite(11, msg.getInt(0)>0?HIGH:LOW);
  74. }
  75. else
  76. pinMode(11,INPUT); // add pull up logic some day
  77. }
  78. else
  79. if(msg.match("/A", addrOffset) ||msg.match("/a", addrOffset)) {
  80. if (msg.isInt(0)) {
  81. pinMode(3,OUTPUT);
  82. digitalWrite(3, msg.getInt(0)>0?HIGH:LOW);
  83. }
  84. else
  85. pinMode(3,INPUT); // add pull up logic some day
  86. }
  87. }
  88. /**
  89. * TONE
  90. *
  91. * square wave output "/tone"
  92. *
  93. * format:
  94. * /tone
  95. * (no value) = notome
  96. * float or int = frequency
  97. * optional length of time as an integer in milliseconds afterwards
  98. *
  99. **/
  100. void routeTone(OSCMessage &msg, int addrOffset ){
  101. unsigned int frequency = 0;
  102. if (msg.isInt(0)){
  103. frequency = msg.getInt(0);
  104. }
  105. else if(msg.isFloat(0)){
  106. frequency = msg.getFloat(0); // this doesn't work due to problems with double to float conversion?
  107. }
  108. else
  109. Esplora.noTone();
  110. if(frequency>0)
  111. {
  112. if(msg.isInt(1))
  113. Esplora.tone(frequency, msg.getInt(1));
  114. else
  115. Esplora.tone( frequency);
  116. }
  117. }
  118. const char *released = "released";
  119. const char *pressed = "pressed";
  120. const byte MUX_ADDR_PINS[] = {
  121. A0, A1, A2, A3 };
  122. const byte MUX_COM_PIN = A4;
  123. unsigned int myReadChannel(byte channel) {
  124. digitalWrite(MUX_ADDR_PINS[0], (channel & 1) ? HIGH : LOW);
  125. digitalWrite(MUX_ADDR_PINS[1], (channel & 2) ? HIGH : LOW);
  126. digitalWrite(MUX_ADDR_PINS[2], (channel & 4) ? HIGH : LOW);
  127. digitalWrite(MUX_ADDR_PINS[3], (channel & 8) ? HIGH : LOW);
  128. return analogRead(MUX_COM_PIN);
  129. }
  130. SLIPEncodedUSBSerial SLIPSerial(Serial);
  131. void setup() {
  132. SLIPSerial.begin(115200); // set this as high as you can reliably run on your platform
  133. }
  134. int32_t counter = 0;
  135. int32_t serialnumber = 2; //hard coded; beware
  136. int32_t num_components = 3; //currently break the bundle up into 3 components
  137. void loop(){
  138. OSCBundle bndl;
  139. int32_t manifest_count = 1;
  140. if(!SLIPSerial.available())
  141. {
  142. // The RAW OSC address space and parameter mappngs try to capture
  143. // the data at lowest level without calibration or scaling
  144. // The names are chosen to match what is on the silkscreen of the board where it is found
  145. #define RAW
  146. #ifdef RAW
  147. SLIPSerial.beginPacket();
  148. bndl.add("/mic").add((int32_t)Esplora.readMicrophone());
  149. bndl.add("/temp/sensor/celsius").add((int32_t)Esplora.readTemperature(DEGREES_C));
  150. bndl.add("/temp/sensor/fahrenheit").add((int32_t)Esplora.readTemperature(DEGREES_F));
  151. bndl.add("/linear/potentiometer").add((int32_t)Esplora.readSlider());
  152. bndl.add("/light/sensor").add((int32_t)Esplora.readLightSensor());
  153. bndl.add("/switch/1").add((int32_t)Esplora.readButton(SWITCH_1));
  154. bndl.add("/switch/2").add((int32_t)Esplora.readButton(SWITCH_2));
  155. bndl.add("/switch/3").add((int32_t)Esplora.readButton(SWITCH_3));
  156. bndl.add("/switch/4").add((int32_t)Esplora.readButton(SWITCH_4));
  157. bndl.add("/joystick/X").add((int32_t)Esplora.readJoystickX());
  158. bndl.add("/joystick/Y").add((int32_t)Esplora.readJoystickY());
  159. bndl.add("/joystick/switch").add((int32_t)Esplora.readJoystickSwitch());
  160. bndl.add("/joystick/switch/1").add((int32_t)Esplora.readButton(JOYSTICK_DOWN));
  161. bndl.add("/joystick/switch/2").add((int32_t)Esplora.readButton(JOYSTICK_LEFT));
  162. bndl.add("/joystick/switch/3").add((int32_t)Esplora.readButton(JOYSTICK_UP));
  163. bndl.add("/joystick/switch/4").add((int32_t)Esplora.readButton(JOYSTICK_RIGHT));
  164. bndl.add("/accelerometer/x").add(Esplora.readAccelerometer(X_AXIS));
  165. bndl.add("/accelerometer/y").add(Esplora.readAccelerometer(Y_AXIS));
  166. bndl.add("/accelerometer/z").add(Esplora.readAccelerometer(Z_AXIS));
  167. bndl.send(SLIPSerial); // send the bytes to the SLIP stream
  168. SLIPSerial.endPacket(); // mark the end of the OSC Packet
  169. bndl.empty();
  170. #endif //RAW
  171. // The COOKED OSC address space and parameter mappings
  172. // encode data for ease of use and legibility at the host. Unit intervals replace integers
  173. // The names are chosen to clarify usage rather than adherence to the silkscreen
  174. // also values are acquired as close together as reasonably possible to increase
  175. // their usability in sensor fusion contexts, i.e. in this case with the accelerometer
  176. SLIPSerial.beginPacket(); // mark the beginning of the OSC Packet
  177. //bundle 1
  178. bndl.add("/acceleration/x").add(Esplora.readAccelerometer(X_AXIS)/512.0f);
  179. bndl.add("/acceleration/y").add(Esplora.readAccelerometer(Y_AXIS)/512.0f);
  180. bndl.add("/acceleration/z").add(Esplora.readAccelerometer(Z_AXIS)/512.0f);
  181. bndl.add("/photoresistor").add(Esplora.readLightSensor()/1023.0f);
  182. bndl.add("/joystick/horizontal").add(-1.0 * (int32_t)Esplora.readJoystickX()/512.0f);
  183. bndl.add("/joystick/vertical").add(-1.0 * (int32_t)Esplora.readJoystickY()/512.0f);
  184. bndl.add("/joystick/button").add(Esplora.readJoystickSwitch()>0? released:pressed);
  185. bndl.add("/joystick/backward").add((int32_t)Esplora.readButton(JOYSTICK_DOWN)?released:pressed);
  186. bndl.add("/joystick/left").add((int32_t)Esplora.readButton(JOYSTICK_LEFT)?released:pressed);
  187. bndl.add("/joystick/forward").add((int32_t)Esplora.readButton(JOYSTICK_UP)?released:pressed);
  188. bndl.add("/joystick/right").add((int32_t)Esplora.readButton(JOYSTICK_RIGHT)?released:pressed);
  189. bndl.add("/serialnumber").add(serialnumber);
  190. //bndl.add("/manifest").add(manifest_count++).add(num_components).add(counter);
  191. bndl.send(SLIPSerial); // send the bytes to the SLIP stream
  192. SLIPSerial.endPacket(); // mark the end of the OSC Packet
  193. bndl.empty(); //bundle ending early due to current memory limitations
  194. //bundle 2
  195. bndl.add("/diamond/backward").add((int32_t)Esplora.readButton(SWITCH_1)?released:pressed);
  196. bndl.add("/diamond/left").add((int32_t)Esplora.readButton(SWITCH_2)?released:pressed);
  197. bndl.add("/diamond/forward").add((int32_t)Esplora.readButton(SWITCH_3)?released:pressed);
  198. bndl.add("/diamond/right").add((int32_t)Esplora.readButton(SWITCH_4)?released:pressed);
  199. bndl.add("/microphone/loudness").add(Esplora.readMicrophone()/1023.0f);
  200. bndl.add("/temperature/fahrenheit").add((float)Esplora.readTemperature(DEGREES_F));
  201. bndl.add("/temperature/celsius").add((float)Esplora.readTemperature(DEGREES_C));
  202. bndl.add("/slider/horizontal").add(1.0f - ((float)Esplora.readSlider()/1023.0f));
  203. bndl.add("/serialnumber").add(serialnumber);
  204. //bndl.add("/manifest").add(manifest_count++).add(num_components).add(counter);
  205. bndl.send(SLIPSerial); // send the bytes to the SLIP stream
  206. SLIPSerial.endPacket(); // mark the end of the OSC Packet
  207. bndl.empty(); //bundle ending early due to current memory limitations
  208. //bundle 3
  209. bndl.add("/connector/white/left").add(myReadChannel(CH_MIC +1)/1023.0);
  210. bndl.add("/connector/white/right").add(myReadChannel(CH_MIC +2)/1023.0);
  211. bndl.add("/led/red").add((int32_t)Esplora.readRed());
  212. bndl.add("/led/green").add((int32_t)Esplora.readGreen());
  213. bndl.add("/led/blue").add((int32_t)Esplora.readBlue());
  214. bndl.add("/led/rgb").add((int32_t)Esplora.readRed()).add((int32_t)Esplora.readGreen()).add((int32_t)Esplora.readBlue());
  215. bndl.add("/connector/orange/right").add((digitalRead(3)==HIGH)?1:0);
  216. bndl.add("/connector/orange/left").add((digitalRead(11)==HIGH)?1:0);
  217. bndl.add("/vendor").add("Arduino");
  218. bndl.add("/productname").add("Esplora");
  219. bndl.add("/serialnumber").add(serialnumber);
  220. //bndl.add("/manifest").add(manifest_count++).add(num_components).add(counter);
  221. bndl.send(SLIPSerial); // send the bytes to the SLIP stream
  222. SLIPSerial.endPacket(); // mark the end of the OSC Packet
  223. bndl.empty();
  224. counter += 1;
  225. // bndl.add("/32u4/supplyVoltage").add(getSupplyVoltage());
  226. // bndl.add("/32u4/temperature").add(getTemperature());
  227. }
  228. else
  229. {
  230. OSCBundle bundleIN;
  231. int size;
  232. while(!SLIPSerial.endofPacket())
  233. if ((size =SLIPSerial.available()) > 0)
  234. {
  235. while(size--)
  236. bundleIN.fill(SLIPSerial.read());
  237. }
  238. {
  239. if(!bundleIN.hasError())
  240. {
  241. bundleIN.route("/led", routeLed);
  242. bundleIN.route("/L", routeLed); // this is how it is marked on the silkscreen
  243. bundleIN.route("/out", routeOut); // for the TinkerIt output connectors
  244. bundleIN.route("/tone", routeTone);
  245. bundleIN.route("/squarewave", routeTone);
  246. bundleIN.route("/notone", routeTone);
  247. }
  248. }
  249. }
  250. }