Projekt Pepper Bell: Porovnání verzí
m |
(Přidána podsekce Finální kód Pepper Bellu) |
||
| Řádek 49: | Řádek 49: | ||
</tt> | </tt> | ||
=== Finální kód Pepper Bellu === | === Finální kód Pepper Bellu === | ||
| + | <tt> | ||
| + | // Schéma zapojení | ||
| + | // porty 0,1 = nezapojovat, sériový port | ||
| + | // porty 2-9 = papričky | ||
| + | // port 10 a GND = reproduktor | ||
| + | // GND = uzemnit (alobal, na kterém se stojí) | ||
| + | // drát = UTP kabel (ne lanko, ale drát) 2m | ||
| + | |||
| + | const int PORTS[8] = { 2, 3, 4, 5, 6, 7, 8, 9 }; | ||
| + | const int REPRO = 10; | ||
| + | const int THRESHOLDS[8] = { 13, 13, 13, 13, 13, 13, 13, 13 }; | ||
| + | |||
| + | bool touched[8]; | ||
| + | |||
| + | uint8_t readCapacitivePin(int pinToMeasure) { | ||
| + | volatile uint8_t* port; | ||
| + | volatile uint8_t* ddr; | ||
| + | volatile uint8_t* pin; | ||
| + | byte bitmask; | ||
| + | |||
| + | port = portOutputRegister(digitalPinToPort(pinToMeasure)); | ||
| + | ddr = portModeRegister(digitalPinToPort(pinToMeasure)); | ||
| + | bitmask = digitalPinToBitMask(pinToMeasure); | ||
| + | pin = portInputRegister(digitalPinToPort(pinToMeasure)); | ||
| + | |||
| + | // Discharge the pin first by setting it low and output | ||
| + | *port &= ~(bitmask); | ||
| + | *ddr |= bitmask; | ||
| + | delay(1); | ||
| + | |||
| + | // Prevent the timer IRQ from disturbing our measurement | ||
| + | noInterrupts(); | ||
| + | |||
| + | // Make the pin an input with the internal pull-up on | ||
| + | *ddr &= ~(bitmask); | ||
| + | *port |= bitmask; | ||
| + | |||
| + | // Now see how long the pin to get pulled up. This manual unrolling of the loop | ||
| + | // decreases the number of hardware cycles between each read of the pin, | ||
| + | // thus increasing sensitivity. | ||
| + | |||
| + | uint8_t cycles = 17; | ||
| + | if (*pin & bitmask) { cycles = 0;} | ||
| + | else if (*pin & bitmask) { cycles = 1;} | ||
| + | else if (*pin & bitmask) { cycles = 2;} | ||
| + | else if (*pin & bitmask) { cycles = 3;} | ||
| + | else if (*pin & bitmask) { cycles = 4;} | ||
| + | else if (*pin & bitmask) { cycles = 5;} | ||
| + | else if (*pin & bitmask) { cycles = 6;} | ||
| + | else if (*pin & bitmask) { cycles = 7;} | ||
| + | else if (*pin & bitmask) { cycles = 8;} | ||
| + | else if (*pin & bitmask) { cycles = 9;} | ||
| + | else if (*pin & bitmask) { cycles = 10;} | ||
| + | else if (*pin & bitmask) { cycles = 11;} | ||
| + | else if (*pin & bitmask) { cycles = 12;} | ||
| + | else if (*pin & bitmask) { cycles = 13;} | ||
| + | else if (*pin & bitmask) { cycles = 14;} | ||
| + | else if (*pin & bitmask) { cycles = 15;} | ||
| + | else if (*pin & bitmask) { cycles = 16;} | ||
| + | |||
| + | // End of timing-critical section | ||
| + | interrupts(); | ||
| + | |||
| + | // Discharge the pin again by setting it low and output | ||
| + | *port &= ~(bitmask); | ||
| + | *ddr |= bitmask; | ||
| + | |||
| + | return cycles; | ||
| + | } | ||
| + | |||
| + | void setup() { | ||
| + | Serial.begin(57600); | ||
| + | } | ||
| + | |||
| + | void handlePort(int index) { | ||
| + | int cycles = readCapacitivePin(PORTS[index]); | ||
| + | |||
| + | if (!touched[index] && cycles >= THRESHOLDS[index]) { | ||
| + | touched[index] = true; | ||
| + | playSound(index); | ||
| + | } | ||
| + | |||
| + | if (touched[index] && cycles < THRESHOLDS[index]) { | ||
| + | touched[index] = false; | ||
| + | } | ||
| + | } | ||
| + | void playSound(int index){ | ||
| + | // tone (10,500,300); // na pinu 10 zahraje tón o frekvenci 500Hz po dobu 300ms | ||
| + | switch (index) { | ||
| + | case 0: | ||
| + | tone(10,262,300); | ||
| + | break; | ||
| + | case 1: | ||
| + | tone(10,294,300); | ||
| + | break; | ||
| + | case 2: | ||
| + | tone(10,330,300); | ||
| + | break; | ||
| + | case 3: | ||
| + | tone(10,349,300); | ||
| + | break; | ||
| + | case 4: | ||
| + | tone(10,392,300); | ||
| + | break; | ||
| + | case 5: | ||
| + | tone(10,440,300); | ||
| + | break; | ||
| + | case 6: | ||
| + | tone(10,494,300); | ||
| + | break; | ||
| + | case 7: | ||
| + | tone(10,523,300); | ||
| + | break; | ||
| + | |||
| + | default: | ||
| + | noTone(REPRO); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | for (int i = 0; i < 8; i++) { | ||
| + | handlePort(i); | ||
| + | } | ||
| + | delay(30); | ||
| + | } | ||
| + | </tt> | ||
Verze z 12. 11. 2015, 16:34
Obsah
Členové projektu
Anna Brixová, Studia nových médií, e-mail: anna.brixova@gmail.com
Lucie Merunková, Studia nových médií, e-mail: merunkova.lucie@seznam.cz
Eliška Morochovičová, Studia nových médií, e-mail: eliska.moro@gmail.com
Motivace vzniku projektu a jeho význam
Projekt vznikl se záměrem vyzkoušet si programování, práci s open hardwarem a kreativní řešení technických problémů. Chtěly jsme vytvořit něco trochu uměleckého, zároveň však postaveného na technice. Proto jsme se inspirovaly u různých hudebních projektů. V průběhu jsme několikrát zavzpomínaly na hodiny fyziky na střední škole a přály si, abychom dávaly větší pozor, racionální myšlení a návod na internetu (jedna z největších výhod práce s open hardwarem) nám nakonec pomohly dostat se zdárně k cíli, kdy jsme měřily kapacitu papriček a spouštěly na základě zvýšeného napětí tóny. V průběhu letní školy jsme pronikly do tajů programování a práce s Arduinem, a zopakovaly si znalosti základních fyzikálních pravidel. Doufáme, že náš projekt povzbudí další, kteří se třeba bojí, že pro práci s open hardwarem a programovacími jazyky nemají dostatečné technické znalosti, aby si něco takového osobně vyzkoušeli a zjistili, kolik se tímto „hračičkováním“ naučí. Možnost hrát si s dostupnou technologií, snažit se najít řešení a uskutečňovat vlastní projekty, je totiž neocenitelná a naučí nás toho víc, než běžné přednášky.
Použitý materiál a software
- Arduino Uno
- USB kabel notebook / baterie Noontec Giant A10000 na USB
- reproduktor
- drátové propojky
- propojky - „krokodýlky“
- alobal na uzemnění
- 8x chilli papričky (lze nahradit např. i banány atd.)
- software Arduino 1.6.5.
Odkazy na knihovnu arduina a vlastní zdrojový kód
Původní kód pro měření odporu u mkrve a papriky
void setup() {
// initialize serial communications (for debugging only): Serial.begin(9600);
} void loop() {
// read the sensor: int sensorReadingmrkev = analogRead(A0); int sensorReadingpaprika = analogRead(A3); // print the sensor reading so you know its range Serial.println(sensorReadingmrkev); // map the analog input range (in this case, 400 - 1000 from the photoresistor) // to the output pitch range (120 - 1500Hz) // change the minimum and maximum input numbers below // depending on the range your sensor's giving: int thisPitchmrkev = map(sensorReadingmrkev, 400, 1000, 800, 1500); int thisPitchpaprika = map(sensorReadingpaprika, 400, 1000, 200, 800); if (sensorReadingmrkev > 150)
{
tone(3, thisPitchmrkev, 10); // do something here
} // play the pitch: tone(3, thisPitchpaprika, 5);
delay(1); // delay in between reads for stability
}
Finální kód Pepper Bellu
// Schéma zapojení // porty 0,1 = nezapojovat, sériový port // porty 2-9 = papričky // port 10 a GND = reproduktor // GND = uzemnit (alobal, na kterém se stojí) // drát = UTP kabel (ne lanko, ale drát) 2m
const int PORTS[8] = { 2, 3, 4, 5, 6, 7, 8, 9 }; const int REPRO = 10; const int THRESHOLDS[8] = { 13, 13, 13, 13, 13, 13, 13, 13 };
bool touched[8];
uint8_t readCapacitivePin(int pinToMeasure) {
volatile uint8_t* port; volatile uint8_t* ddr; volatile uint8_t* pin; byte bitmask;
port = portOutputRegister(digitalPinToPort(pinToMeasure)); ddr = portModeRegister(digitalPinToPort(pinToMeasure)); bitmask = digitalPinToBitMask(pinToMeasure); pin = portInputRegister(digitalPinToPort(pinToMeasure));
// Discharge the pin first by setting it low and output *port &= ~(bitmask); *ddr |= bitmask; delay(1);
// Prevent the timer IRQ from disturbing our measurement noInterrupts();
// Make the pin an input with the internal pull-up on *ddr &= ~(bitmask); *port |= bitmask;
// Now see how long the pin to get pulled up. This manual unrolling of the loop // decreases the number of hardware cycles between each read of the pin, // thus increasing sensitivity.
uint8_t cycles = 17;
if (*pin & bitmask) { cycles = 0;}
else if (*pin & bitmask) { cycles = 1;}
else if (*pin & bitmask) { cycles = 2;}
else if (*pin & bitmask) { cycles = 3;}
else if (*pin & bitmask) { cycles = 4;}
else if (*pin & bitmask) { cycles = 5;}
else if (*pin & bitmask) { cycles = 6;}
else if (*pin & bitmask) { cycles = 7;}
else if (*pin & bitmask) { cycles = 8;}
else if (*pin & bitmask) { cycles = 9;}
else if (*pin & bitmask) { cycles = 10;}
else if (*pin & bitmask) { cycles = 11;}
else if (*pin & bitmask) { cycles = 12;}
else if (*pin & bitmask) { cycles = 13;}
else if (*pin & bitmask) { cycles = 14;}
else if (*pin & bitmask) { cycles = 15;}
else if (*pin & bitmask) { cycles = 16;}
// End of timing-critical section interrupts();
// Discharge the pin again by setting it low and output *port &= ~(bitmask); *ddr |= bitmask;
return cycles;
}
void setup() {
Serial.begin(57600);
}
void handlePort(int index) {
int cycles = readCapacitivePin(PORTS[index]);
if (!touched[index] && cycles >= THRESHOLDS[index]) {
touched[index] = true;
playSound(index);
}
if (touched[index] && cycles < THRESHOLDS[index]) {
touched[index] = false;
}
} void playSound(int index){
// tone (10,500,300); // na pinu 10 zahraje tón o frekvenci 500Hz po dobu 300ms
switch (index) {
case 0:
tone(10,262,300);
break;
case 1:
tone(10,294,300);
break;
case 2:
tone(10,330,300);
break;
case 3:
tone(10,349,300);
break;
case 4:
tone(10,392,300);
break;
case 5:
tone(10,440,300);
break;
case 6:
tone(10,494,300);
break;
case 7:
tone(10,523,300);
break;
default:
noTone(REPRO);
}
}
void loop() {
for (int i = 0; i < 8; i++) {
handlePort(i);
}
delay(30);
}