{"id":1722,"date":"2020-10-27T18:57:56","date_gmt":"2020-10-27T22:57:56","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/?p=1722"},"modified":"2020-10-27T20:15:04","modified_gmt":"2020-10-28T00:15:04","slug":"capacitive-%ce%bcpiano-cultivate-an-ear-for-music","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/?p=1722","title":{"rendered":"Capacitive \u03bcPiano: Cultivating an ear for music"},"content":{"rendered":"<p><strong>Problem:<\/strong> Today, many children are taking music lessons. They learn to read notes and play them on different instruments. But is it enough to learn\u00a0notes and scores by heart in order to cultivate an ear for music? Or to recognise notes both auditory and visually to compose them into pleasant melodies that make sense?<\/p>\n<p><strong>Solution:<\/strong> Capacitive \u03bcPiano helps beginners to do exactly that. You can repeat your favourite melody as many times you want, until you finally perceive how to reproduce it. Each capacitive sensor represents a different note. The melody&#8217;s reading becomes an auditory experience for the user, who previously used visual scores. This process helps new practitioners to train an ear for music from the early beginning.<\/p>\n<p><strong><img loading=\"lazy\" class=\"alignnone wp-image-1736 size-large\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/IMG_6343-scaled-e1603839664638-1024x687.jpg\" alt=\"\" width=\"840\" height=\"564\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/IMG_6343-scaled-e1603839664638-1024x687.jpg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/IMG_6343-scaled-e1603839664638-300x201.jpg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/IMG_6343-scaled-e1603839664638-768x515.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/IMG_6343-scaled-e1603839664638-1536x1030.jpg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/IMG_6343-scaled-e1603839664638-2048x1373.jpg 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/IMG_6343-scaled-e1603839664638-1200x805.jpg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/strong><\/p>\n<p>Demo:<\/p>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=L1W8SxbK3Og\">https:\/\/www.youtube.com\/watch?v=L1W8SxbK3Og<\/a><\/p>\n<p>Code:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\"># include &lt;CapacitiveSensor.h&gt;\r\n#include &lt;pitches.h&gt;\r\n\r\n\/\/ Capacitive Sensors\r\nCapacitiveSensor cs1 = CapacitiveSensor(6, 9);\r\nbool cs1Touched = true; long cs1Val;\r\nCapacitiveSensor cs2 = CapacitiveSensor(6, 7);\r\nbool cs2Touched = true; long cs2Val;\r\nCapacitiveSensor cs3 = CapacitiveSensor(6, 5);\r\nbool cs3Touched = true; long cs3Val;\r\nCapacitiveSensor cs4 = CapacitiveSensor(6, 8);\r\nbool cs4Touched = true; long cs4Val;\r\n\r\n\/\/ Speaker + Music\r\n#define speakerPin 4\r\nint melody1[] = {NOTE_E4, NOTE_G3, NOTE_G3, NOTE_C4, NOTE_G3, 0, NOTE_B3, NOTE_C4};\r\nint noteDurations[] = {4, 8, 8, 4, 4, 4, 4, 4};\r\n\r\n\/\/ Switch\r\n#define switchPin 2\r\n\r\ntypedef struct switchTracker {\r\n  int lastReading;       \/\/ last raw value read\r\n  long lastChangeTime;   \/\/ last time the raw value changed\r\n  byte pin;              \/\/ the pin this is tracking changes on\r\n  byte switchState;      \/\/ debounced state of the switch\r\n} switchTrack;\r\n\r\nvoid initSwitchTrack(struct switchTracker &amp;sw, int swPin) {\r\n  pinMode(swPin, INPUT);\r\n  sw.lastReading = digitalRead(swPin);\r\n  sw.lastChangeTime = millis();\r\n  sw.pin = swPin;\r\n  sw.switchState = sw.lastReading;\r\n}\r\n\r\nswitchTrack switchInput;\r\nbool practiseTime = false;\r\n\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n  pinMode(speakerPin, OUTPUT);\r\n  initSwitchTrack(switchInput, switchPin);\r\n  attachInterrupt(digitalPinToInterrupt(switchPin), changeMode, RISING);\r\n}\r\n\r\nvoid loop() {\r\n  Serial.println(practiseTime);\r\n\r\n  if (practiseTime) {\r\n    practise();\r\n  } else {\r\n    playMelody();\r\n    delay(3000);\r\n  }\r\n\r\n}\r\n\r\nvoid changeMode() {\r\n  practiseTime = !practiseTime;\r\n}\r\n\r\nvoid practise() {\r\n  capacitiveSensor1();\r\n  capacitiveSensor2();\r\n  capacitiveSensor3();\r\n  capacitiveSensor4();\r\n\r\n}\r\nvoid capacitiveSensor1() {\r\n\r\n  cs1Val = cs1.capacitiveSensor(80); \/\/ resolution\r\n  if (cs1Touched) {\r\n    if (cs1Val &gt; 1000) {\r\n      Serial.println(cs1Val);\r\n      cs1Touched = false;\r\n      tone(speakerPin, NOTE_E4);\r\n    }\r\n  }\r\n\r\n  if (!cs1Touched) {\r\n    if (cs1Val &lt; 100) {\r\n      Serial.println(cs1Val);\r\n      noTone(speakerPin);\r\n      cs1Touched = true;\r\n    }\r\n  }\r\n}\r\n\r\nvoid capacitiveSensor2() {\r\n\r\n  cs2Val = cs2.capacitiveSensor(80); \/\/ resolution\r\n  if (cs2Touched) {\r\n    if (cs2Val &gt; 1000) {\r\n      Serial.println(cs2Val);\r\n      cs2Touched = false;\r\n      tone(speakerPin, NOTE_G3);\r\n    }\r\n  }\r\n\r\n  if (!cs2Touched) {\r\n    if (cs2Val &lt; 100) {\r\n      Serial.println(cs2Val);\r\n      noTone(speakerPin);\r\n      cs2Touched = true;\r\n    }\r\n  }\r\n}\r\n\r\nvoid capacitiveSensor3() {\r\n\r\n  cs3Val = cs3.capacitiveSensor(80); \/\/ resolution\r\n  if (cs3Touched) {\r\n    if (cs3Val &gt; 1000) {\r\n      Serial.println(cs3Val);\r\n      cs3Touched = false;\r\n      tone(speakerPin, NOTE_C4);\r\n    }\r\n  }\r\n\r\n  if (!cs3Touched) {\r\n    if (cs3Val &lt; 100) {\r\n      Serial.println(cs3Val);\r\n      cs3Touched = true;\r\n      noTone(speakerPin);\r\n    }\r\n  }\r\n}\r\n\r\nvoid capacitiveSensor4() {\r\n\r\n  cs4Val = cs4.capacitiveSensor(80); \/\/ resolution\r\n  if (cs4Touched) {\r\n    if (cs4Val &gt; 1000) {\r\n      Serial.println(cs4Val);\r\n      cs4Touched = false;\r\n      tone(speakerPin, NOTE_B3);\r\n    }\r\n  }\r\n\r\n  if (!cs4Touched) {\r\n    if (cs4Val &lt; 100) {\r\n      Serial.println(cs4Val);\r\n      noTone(speakerPin);\r\n      cs4Touched = true;\r\n    }\r\n  }\r\n}\r\n\r\nvoid playMelody() {\r\n  for (int thisNote = 0; thisNote &lt; 8; thisNote++) {\r\n\r\n    int noteDuration = 1000 \/ noteDurations[thisNote];\r\n\r\n    tone(speakerPin, melody1[thisNote], noteDuration);\r\n\r\n    \/\/ to distinguish the notes, set a minimum time between them.\r\n\r\n    \/\/ the note's duration + 30% seems to work well:\r\n\r\n    int pauseBetweenNotes = noteDuration * 1.30;\r\n\r\n    delay(pauseBetweenNotes);\r\n\r\n    \/\/ stop the tone playing:\r\n\r\n    noTone(1);\r\n  }\r\n}\r\n\r\nboolean switchChange(struct switchTracker &amp; sw) {\r\n  const long debounceTime = 100;\r\n  \/\/ default to no change until we find out otherwise\r\n  boolean result = false;\r\n  int reading = digitalRead(sw.pin);\r\n\r\n  if (reading != sw.lastReading) sw.lastChangeTime = millis();\r\n  sw.lastReading = reading;\r\n  \/\/ if time since the last change is longer than the required dwell\r\n  if ((millis() - sw.lastChangeTime) &gt; debounceTime) {\r\n    result = (reading != sw.switchState);\r\n    \/\/ in any case the value has been stable and so the reported state\r\n    \/\/ should now match the current raw reading\r\n    sw.switchState = reading;\r\n  }\r\n  return result;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Problem: Today, many children are taking music lessons. They learn to read notes and play them on different instruments. But is it enough to learn\u00a0notes and scores by heart in order to cultivate an ear for music? Or to recognise notes both auditory and visually to compose them into pleasant melodies that make sense? Solution: &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/?p=1722\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Capacitive \u03bcPiano: Cultivating an ear for music&#8221;<\/span><\/a><\/p>\n","protected":false},"author":25,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/posts\/1722"}],"collection":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1722"}],"version-history":[{"count":11,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/posts\/1722\/revisions"}],"predecessor-version":[{"id":1749,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/posts\/1722\/revisions\/1749"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1722"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1722"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1722"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}