Сегодня сделаем необычный музыкальный инструмент, у которого вместо клавиш будут использоваться съедобные продукты.
Тут у нас цукат, хлеб, яблоко, пастила, огурец, сыр, колбаса и капуста и их мы превратим в кнопки.
За основу взята вот эта статья с сайта instructables. В ней описывается, как превратить надпись карандашом в емкостный датчик. Мы сделаем то же самое, только из продуктов и будем управлять звуком.
Для проекта понадобятся:
- 8 резисторов сопротивлением 1Мом;
- динамик;
- провода.
Схема довольно простая:
К синим проводам подсоедините то, что вы хотите превратить в кнопки.
Код программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
int speakerPin = 12; int capSensePin1 = 2; int capSensePin2 = 3; int capSensePin3 = 4; int capSensePin4 = 5; int capSensePin5 = 6; int capSensePin6 = 7; int capSensePin7 = 8; int capSensePin8 = 9; int tones[] = { 956, 1014, 1136, 1275, 1432, 1519, 1700, 1915 }; int touchedCutoff = 60; void playTone(int tone, int duration) { for (long i = 0; i < duration * 1000L; i += tone * 2) { digitalWrite(speakerPin, HIGH); delayMicroseconds(tone); digitalWrite(speakerPin, LOW); delayMicroseconds(tone); } } void setup() { Serial.begin(9600); pinMode(speakerPin, OUTPUT); } void loop() { if (readCapacitivePin(capSensePin1) > touchedCutoff) { playTone(tones[0], 200); } if (readCapacitivePin(capSensePin2) > touchedCutoff) { playTone(tones[1], 200); } if (readCapacitivePin(capSensePin3) > touchedCutoff) { playTone(tones[2], 200); } if (readCapacitivePin(capSensePin4) > touchedCutoff) { playTone(tones[3], 200); } if (readCapacitivePin(capSensePin5) > touchedCutoff) { playTone(tones[4], 200); } if (readCapacitivePin(capSensePin6) > touchedCutoff) { playTone(tones[5], 200); } if (readCapacitivePin(capSensePin7) > touchedCutoff) { playTone(tones[6], 200); } if (readCapacitivePin(capSensePin8) > touchedCutoff) { playTone(tones[7], 200); } } // readCapacitivePin // Input: Arduino pin number // Output: A number, from 0 to 17 expressing // how much capacitance is on the pin // When you touch the pin, or whatever you have // attached to it, the number will get higher // In order for this to work now, // The pin should have a 1+Megaohm resistor pulling // it up to +5v. uint8_t readCapacitivePin(int pinToMeasure) { // This is how you declare a variable which // will hold the PORT, PIN, and DDR registers // on an AVR volatile uint8_t* port; volatile uint8_t* ddr; volatile uint8_t* pin; // Here we translate the input pin number from // Arduino pin number to the AVR PORT, PIN, DDR, // and which bit of those registers we care about. byte bitmask; if ((pinToMeasure >= 0) && (pinToMeasure <= 7)) { port = &PORTD; ddr = &DDRD; bitmask = 1 << pinToMeasure; pin = &PIND; } if ((pinToMeasure > 7) && (pinToMeasure <= 13)) { port = &PORTB; ddr = &DDRB; bitmask = 1 << (pinToMeasure - 8); pin = &PINB; } if ((pinToMeasure > 13) && (pinToMeasure <= 19)) { port = &PORTC; ddr = &DDRC; bitmask = 1 << (pinToMeasure - 13); pin = &PINC; } // Discharge the pin first by setting it low and output *port &= ~(bitmask); *ddr |= bitmask; delay(1); // Make the pin an input WITHOUT the internal pull-up on *ddr &= ~(bitmask); // Now see how long the pin to get pulled up int cycles = 16000; for (int i = 0; i < cycles; i++) { if (*pin & bitmask) { cycles = i; break; } } // Discharge the pin again by setting it low and output // It's important to leave the pins low if you want to // be able to touch more than 1 sensor at a time - if // the sensor is left pulled high, when you touch // two sensors, your body will transfer the charge between // sensors. *port &= ~(bitmask); *ddr |= bitmask; return cycles; } |