Projekt Pepper Bell: Porovnání verzí

m
 
(Není zobrazeno 11 mezilehlých verzí od stejného uživatele.)
Řádek 20: Řádek 20:
  
 
== Odkazy na knihovnu arduina a vlastní zdrojový kód ==
 
== Odkazy na knihovnu arduina a vlastní zdrojový kód ==
 +
'''Upozornění! Vzhledem k omezení syntaxe wikisofia kopírujte prosím zdrojový kód přímo z editace zdroje stránky, nikoliv z podoby, do jaké je intepretována při zobrazení na stránce. Přislušný úsek je v souladu se syntaxí české wikipedie umístěn mezi značkou <nowiki><tt> a </tt></nowiki>.'''
  
 
=== Původní kód pro měření odporu u mkrve a papriky ===
 
=== Původní kód pro měření odporu u mkrve a papriky ===
 +
<tt>
 
void setup() {
 
void setup() {
 
  // initialize serial communications (for debugging only):
 
  // initialize serial communications (for debugging only):
Řádek 46: Řádek 48:
 
   delay(1);        // delay in between reads for stability
 
   delay(1);        // delay in between reads for stability
 
}
 
}
 +
</tt>
 +
=== 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;}
  
=== Finální kód Pepper Bellu ===
+
// 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>
 +
 
 +
== Popis vývoje a konečné verze vlastního produktu ==
 +
01. Původním cílem projektu bylo získat zvuk z biologických materiálů, jako je zelenina či květiny. Inspirací nám byl projekt zpívající květiny (http://www.instructables.com/id/Singing-plant-Make-your-plant-sing-with-Arduino-/), nakonec jsme se však shodly, že měření kapacity je příliš technicky složité, a jaly jsme se měřit odpor. Prvními experimentálními objekty byla paprika a mrkev.
 +
 
 +
02. Základním hardwarem bylo Arduino Uno, na které jsme připojily TinkerKit Sensor Shield.
 +
 
 +
03. Poté jsme vytvořily za použití příkladu tonePitchFollower (původní kód výše).
 +
 
 +
04. Dále následovalo připojení mrkve a papriky na Sensor Shield (konektory A0 a A3) pomocí propojovacích kabelů.
 +
 
 +
05. Poté jsme upravily kód: nastavení délky a frekvence tónů, aby tvořily stupnici C-dur, podmínky zaznění tónů atd.
 +
 
 +
06. Snaha o použití knihovny zvuků, aby zelenina vydávala zvuk klavíru - nakonec zavrhnuto.
 +
 
 +
07. Měření odporu zeleniny nakonec pro nehezké zvuky a malou zajímavost zavrhnuto.
 +
 
 +
08. Příprava nové verze - odpojení Sensor Shieldu a práce pouze s Arduinem; zvolen jiný druh zeleniny: chilli papričky.
 +
 
 +
09. S pomocí návodu k obdobnému projektu od Stiana Eikelanda ([https://blog.eikeland.se/2015/04/24/banana-piano/ https://blog.eikeland.se/2015/04/24/banana-piano/]) upraven kód v Arduino softwaru - v nové verzi zelenina vydává tón při dotyku (Arduino již není nastaveno na měření odporu, nýbrž kapacity; kompletní kód finálního nastavení výše).
 +
 
 +
10. Nastavení délky tónu (300 ms) a frekvence (každý výstup = tón na stupnici C-Dur; např. C1: 262, D1: 294 atp.) pro každou chilli papričku.
 +
 
 +
11. Zavěšení chilli papriček na improvizované bidýlko.
 +
 
 +
12. Zapojení jednoho konce drátových propojek do každé chilli papričky (z vrchu) a druhého konce do portů 2-9 na Arduinu. Pro vytvoření co nejdelšího “kabelu” použity vždy dvě drátové propojky spojené jedním ”krokodýlkem”.
 +
 
 +
13. Seřazení chilli papriček podle pořadí ve stupnici C-Dur.
 +
 
 +
14. K uzemnění využit alobal, kterým se obalil jeden konec drátové propojky, její druhý konec byl zapojen do jednoho z GND portů na Arduinu.
 +
 
 +
15. Do Arduina zapojen reproduktor (porty: GND a 10), pro zvýšení hlasitosti reproduktor umístěn do plastového kelímku.
 +
 
 +
16. Místo laptopu připojena pomocí USB baterie Noontec Giant A10000 pro větší mobilitu.
 +
 
 +
17. Alobal na uzemnění umístěn na zem, slouží v zásadě jako “pedál” pro zaznění zvuku.
 +
 
 +
Konečná podoba projektu: “Zvonkohra” z osmi chilli papriček, které tvoří stupnici C-Dur (od C1 do C2). Tóny vycházejí při zvýšení napětí po zmáčknutí chilli papričky. Papričky reagují rychle a přesně, reproduktor je dostatečně hlasitý. Projekt může být potenciálně vylepšen vyřešením možnosti polyfonie.
 +
 
 +
== Fotodokumentace ==
 +
 
 +
<gallery widths="200" mode=nolines>
 +
Soubor:PepperBell01.jpg|Zapojování drátků spojujících mrkev a Arduino UNO
 +
Soubor:PepperBell02.jpg|Zapojená mrkev a paprika, při dotyku lidské ruky se zeleninou je možno měřit odpor
 +
Soubor:PepperBell03.jpg|Kód v Arduino pro měření odporu papriky a mrkve
 +
Soubor:PepperBell04.jpg|Zapojování chilli papriček do Arduina
 +
Soubor:PepperBell05.jpg|Připojování drátků k chilli papričkám
 +
Soubor:PepperBell06.jpg|Detail drátků, krokodýlků a reproduktoru, zapojených do Arduina
 +
Soubor:PepperBell07.jpg|Úprava papriček, řazení dle C-dur stupnice
 +
Soubor:PepperBell08.jpg|První pokusy o hru na Pepper Bell
 +
Soubor:PepperBell09.jpg|Detail zapojení a reproduktoru
 +
Soubor:PepperBell10.jpg|Detail papriček, které jsou popsány písmeny, označující jejich tón ve stupnici C-dur
 +
Soubor:PepperBell11.jpg|Detail dekorovaného kelímku, který zajišťuje větší hlasitost reproduktoru (po sundání čepičky)
 +
Soubor:PepperBell12.jpg|Detail loga Pepper Bell
 +
Soubor:PepperBell13.jpg|Detail dekorace
 +
Soubor:PepperBell14.jpg|Celý Pepper Bell
 +
</gallery>
 +
 
 +
== Videodokumentace ==
 +
[https://youtu.be/9ru56ihFYIg https://youtu.be/9ru56ihFYIg]

Aktuální verze z 18. 12. 2015, 13:00

Č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

Upozornění! Vzhledem k omezení syntaxe wikisofia kopírujte prosím zdrojový kód přímo z editace zdroje stránky, nikoliv z podoby, do jaké je intepretována při zobrazení na stránce. Přislušný úsek je v souladu se syntaxí české wikipedie umístěn mezi značkou <tt> a </tt>.

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); 

}

Popis vývoje a konečné verze vlastního produktu

01. Původním cílem projektu bylo získat zvuk z biologických materiálů, jako je zelenina či květiny. Inspirací nám byl projekt zpívající květiny (http://www.instructables.com/id/Singing-plant-Make-your-plant-sing-with-Arduino-/), nakonec jsme se však shodly, že měření kapacity je příliš technicky složité, a jaly jsme se měřit odpor. Prvními experimentálními objekty byla paprika a mrkev.

02. Základním hardwarem bylo Arduino Uno, na které jsme připojily TinkerKit Sensor Shield.

03. Poté jsme vytvořily za použití příkladu tonePitchFollower (původní kód výše).

04. Dále následovalo připojení mrkve a papriky na Sensor Shield (konektory A0 a A3) pomocí propojovacích kabelů.

05. Poté jsme upravily kód: nastavení délky a frekvence tónů, aby tvořily stupnici C-dur, podmínky zaznění tónů atd.

06. Snaha o použití knihovny zvuků, aby zelenina vydávala zvuk klavíru - nakonec zavrhnuto.

07. Měření odporu zeleniny nakonec pro nehezké zvuky a malou zajímavost zavrhnuto.

08. Příprava nové verze - odpojení Sensor Shieldu a práce pouze s Arduinem; zvolen jiný druh zeleniny: chilli papričky.

09. S pomocí návodu k obdobnému projektu od Stiana Eikelanda (https://blog.eikeland.se/2015/04/24/banana-piano/) upraven kód v Arduino softwaru - v nové verzi zelenina vydává tón při dotyku (Arduino již není nastaveno na měření odporu, nýbrž kapacity; kompletní kód finálního nastavení výše).

10. Nastavení délky tónu (300 ms) a frekvence (každý výstup = tón na stupnici C-Dur; např. C1: 262, D1: 294 atp.) pro každou chilli papričku.

11. Zavěšení chilli papriček na improvizované bidýlko.

12. Zapojení jednoho konce drátových propojek do každé chilli papričky (z vrchu) a druhého konce do portů 2-9 na Arduinu. Pro vytvoření co nejdelšího “kabelu” použity vždy dvě drátové propojky spojené jedním ”krokodýlkem”.

13. Seřazení chilli papriček podle pořadí ve stupnici C-Dur.

14. K uzemnění využit alobal, kterým se obalil jeden konec drátové propojky, její druhý konec byl zapojen do jednoho z GND portů na Arduinu.

15. Do Arduina zapojen reproduktor (porty: GND a 10), pro zvýšení hlasitosti reproduktor umístěn do plastového kelímku.

16. Místo laptopu připojena pomocí USB baterie Noontec Giant A10000 pro větší mobilitu.

17. Alobal na uzemnění umístěn na zem, slouží v zásadě jako “pedál” pro zaznění zvuku.

Konečná podoba projektu: “Zvonkohra” z osmi chilli papriček, které tvoří stupnici C-Dur (od C1 do C2). Tóny vycházejí při zvýšení napětí po zmáčknutí chilli papričky. Papričky reagují rychle a přesně, reproduktor je dostatečně hlasitý. Projekt může být potenciálně vylepšen vyřešením možnosti polyfonie.

Fotodokumentace

Videodokumentace

https://youtu.be/9ru56ihFYIg