Sisällysluettelo:
- Vaihe 1: Componenten Verzamelen
- Vaihe 2: Prototyyppi Bouwen
- Vaihe 3: Koodin prototyyppi
- Vaihe 4: Prototyyppi Uittesten
- Vaihe 5: "Ontmantelen" huijaaminen En Kijken Welke Componenten Gebruikt Gaan Worden
- Vaihe 6: Werking Originele -painikkeet + Dremelen
- Vaihe 7: Bedrading Solderen + Buttons Vastlijmen
- Vaihe 8: Plaats Maken De Behuizingissa
- Vaihe 9: Bedrading Aansluiten Op Protobord
- Vaihe 10: Verstevigen
- Vaihe 11: Code Voor Het Communiceren Met Reaper
- Vaihe 12: Ohjain Uittesten
Video: Guitar Hero Arduino -projekti: 12 vaihetta (kuvilla)
2024 Kirjoittaja: John Day | [email protected]. Viimeksi muokattu: 2024-01-30 09:03
Wij zijn Maarten Vrebos, Justin Cavanas ja Wannes Stroobandt sekä opimme multimedia- ja viestintätekniikkaa. Voor een groepsproject voor het vak Audiovisual & IT Principles hebben wij een Guitar Hero-gitaar gehackt en gebruikt als behuizing voor onze MIDI-controller. Het oli vuodevaatteet om de bestaande knoppen op de gitaar intern te vervangen. Onze -ohjain zal vastgehouden en bespeeld worden als een normale gitaar. Aangezien we iets hebben gehackt hebben we er niet veel extra material in moeten verwerken.
In de afbeelding kan u onze allereerste schets op papier zien van hoe het eindproduct er zou moeten uitzien met daarnaast een photo van de gitaar die als behuizing zal worden gebruikt.
Wij hebben ons voor dit project gebaseerd op volgende bronnen:
slapyak.wordpress.com/guitar-hero-midi-con…
www.instructables.com/id/Converting-a-rescu…
gizmodo.com/391834/turn-your-guitar-hero-g…
Benodigdheden voor dit -projekti
- 6 kleine -painiketta
- 7 1 khm: n vastusta
- 1 LED -valo 1
- sininen LED
- 1 Arduino Uno R3
- 1 groene LED
- 2 LEDiä
- 1 schuifschakelaar
- 1 leipälauta
- 1 potentiometri
- 1 protobord
- 1 Guitar Hero -kitara
- Voldoende -vuodevaatteet
- Materiaal om te solderen/dremelen/
- Schroevendraaier
Vaihe 1: Componenten Verzamelen
Voor ons prototype (op breadboard) hebben we volgende komponentti gebruikt:
6 Painikkeet
7 1 khm: n vastukset
1 Keltainen LED
1 Sininen LED
1 Arduino Uno R3
1 Vihreä LED
2 Punainen LED
1 Schuifschakelaar
1 Leipälevy
1 Potentiometri
Vaihe 2: Prototyyppi Bouwen
Om ons prototype te bouwen hebben we al onze komponenten gebruikt op een breadboard, deze breadboard dient dan als testobject zodat we niet meteen in behuizing te werk moeten gaan. Jos prototyyppi on valmis, me dan ook gedigitaliseerd kautta tinkercad.com, op deze manier hadden we een duidelijk overzicht van ons prototype dat elk groepslid ook kon bewerken.
Er worden 5 kleine pushbuttons gebruikt die fungeren als 5 snaren en een grote pushbutton die in combinatie metén of meerdere 'snaren' moet worden ingedrukt om een auditief effect te krijgen. Vaihtoehtoisia LED-lamppuja, jotka on asennettu eri puolille maailmaa ja joilla voidaan hallita vuorovaikutteisia interaktiivisia toimintoja.
Vaihe 3: Koodin prototyyppi
Globale variabelen
In this eerste deel van de code initialiseer je globale variabelen voor de pins van arduino uno waar alle pushbuttons mee verbonden zijn.
// zet nastanumerot waar mainButton (snaar) fi andere -painikkeet aan verbonden zijn: const int mainButton = A1; // gitaar snaar const int lightSensor = A0; const int -painikePin1 = 2; // nummer van pushbutton1 const int -painikePin2 = 3; // nummer van pushbutton2const int -painikePin3 = 4; // nummer van pushbutton3const int buttonPin4 = 5; // nummer van pushbutton4const int -painikePin5 = 6; // numeron van painike 5
Hierna worden er twee arrays aangemaakt voor de namen van de pushbuttons en hun pinnummer.
const int aantalKnoppen = 5; const String namenKnoppen [aantalKnoppen] = {"knop 1", "knop 2", "knop 3", "knop 4", "knop 5"}; const int knopPinnen [aantalKnoppen] = {2, 3, 4, 5, 6};
En dan variabelen voor de nins van de LED lichtjes.
const int ledPin1 = 13; // LED -nastan numero 13
const int ledPin2 = 12; // LED -nastan lukumäärä 12 const int ledPin3 = 11; // LED -nastan lukumäärä 11 const int ledPin4 = 10; // LED -nastan määrä 10 const int ledPin5 = 9; // LED -nastan lukumäärä 9 const int potPin = A5; // LED -nastan A5 määrä
De laatste globale variabelen dienen als 'state' voor de sensor (zijn de pushbuttons ingedrukt of niet? Potentiometer, lichtsensor).
// alustava painikeStates voor de knoppen (ingedrukt of niet) int mainButtonState = 0; int -painikeTila1 = 0; int -painikeTila2 = 0; int -painikeTila3 = 0; int -painikeTila4 = 0; int -painikeTila5 = 0; int lightSensorState = 0; int potValue = 0; int lightValue = 0;
Perustaa
Tämä on tyhjä asennusohjelma. Deze on van het type void (geeft geen waarde terug) ja ohjeet hierin worden maar 1 keer uitgevoerd.
Bij elke functie on kommentti, joka on annettu, ja se on konkreettinen sana. Extra uitleg over wat een specificieke functie concreet doet is te vinden in de arduino reference
void setup () {// datanopeus sekunnissa (baud) voor seriele data transmissie Serial.begin (9600); // LEDPin -alustus, joka voi olla myös lähtö pinMode (ledPin1, OUTPUT); pinMode (ledPin2, OUTPUT); pinMode (ledPin3, OUTPUT); pinMode (ledPin4, OUTPUT); pinMode (ledPin5, OUTPUT); // alustavat kaikki painikkeet, kuten syöttö: pinMode (mainButton, INPUT); pinMode (buttonPin1, INPUT); pinMode (buttonPin2, INPUT); pinMode (buttonPin3, INPUT); pinMode (buttonPin4, INPUT); pinMode (buttonPin5, INPUT); pinMode (potPin, INPUT); pinMode (lightSensor, INPUT); }
Tyhjä funktio
Na de setup () functie volgt de loop () functie, de instructies die hierin staan gaan herhaald uitgevoerd worden.
void loop () {// lees de staat van de pushbuttons uit (ingedrukt of niet) mainButtonState = digitalRead (mainButton); buttonState1 = digitalRead (buttonPin1); buttonState2 = digitalRead (buttonPin2); buttonState3 = digitalRead (buttonPin3); buttonState4 = digitalRead (buttonPin4); buttonState5 = digitalRead (buttonPin5);
// alle pushbutton statusen in een array
int buttonStates = {buttonState1, buttonState2, buttonState3, buttonState4, buttonState5};
// leest de waarde uit van de potentiometer en de lichtsensor
potValue = analoginenLue (potPin); lightValue = analoginenLue (lightSensor);
// julistaja ja matriisi mainStates en geef die de standaard waarden 0 in.
int mainStates = {0, 0, 0, 0, 0};
// silmukka matriisin yli aantalKnoppen
for (int i = 0; i <aantalKnoppen; i ++) {pinMode (knopPinnen , INPUT); // Initial alle alle knopPinnen als input digitalRead (knopPinnen ); // lees de waarde van alle knoppinnen uit // indian de verkkokytkin (snaar) ingedrukt is, print all knopnamen, all buttonstates if (mainButtonState == HIGH) {Serial.print (namenKnoppen ); Serial.print (","); Serial.println (buttonStates ); }}
Vaihe 4: Prototyyppi Uittesten
Nadat het prototype gebouwd is volgens ons model en de code geschreven is in Processing, is het tijd om het prototype uit te testen. Videon opetus on tieteellistä tietoa kaikista knoppen -reaktioista, jotka ovat peräisin oppeista, jotka on kerrottu biotrendeistä.
Tässä tweede -videossa on potentiaalimittari, joka on asennettu gitaariin, ja käsikirjoituksen käsikirjoitus prosessoinnissa.
Vaihe 5: "Ontmantelen" huijaaminen En Kijken Welke Componenten Gebruikt Gaan Worden
Als de code correct werkte op het prototype zijn we begonnen met het "ontmantelen" van onze Guitar Hero-gitaar. Me käytimme gitaar opengemaaktia ja saimme Schroevendraaier en bekeken welke originele komponenten me eventueel nog zouden kunnen hergebruiken voor onze controller. Voit käyttää tätä painiketta painamalla painikkeita, jotka on painettu painikkeilla (zie volgende stap). We hebben de tremolo ook gebruikt voor ons eindproduct en voor onze hoofdbutton (initiële button om als een combinatie af te spelen) hebben we ook de originele twee button gebruikt (zie vierde photo). De LEDjes zullen verdwijnen (deze waren enkel ter indicatie zodat we zagen dat alle knoppen correct werkten).
Vaihe 6: Werking Originele -painikkeet + Dremelen
Bändin videot on kuvattu alkuperäisessä tweekissä, jotka ovat peräisin kahdesta alkuperäisestä solmusta, kuten myös schakelaarista, joka on hahmoteltu kaikkeen tehosteeseen ja yhdistettyyn yhdistelmään.
Om onze button on te verwerken in de originele knoppen hebben we de binnenkant van de originelen er grotendeels uitgehaald zoals te zien is op de photo.
Vaihe 7: Bedrading Solderen + Buttons Vastlijmen
Omdat we niet meer met een breadboard werken moeten de draden gesoldeerd worden om zo de verschillende komponenten met elkaar te verbinden. Nadat dit gebeurd is kunnen we de buttons hatalmaslijmen zoals te zien is op de photos's. Eens dit gebeurd is kunnen we doorgaan naar de volgende stap.
Vaihe 8: Plaats Maken De Behuizingissa
Omdat dit Guitar Hero-malli redelijk krap was om mee te werken hebben we extra plaats moeten maken d.m.v. surkea. Zo hebben we uit de achterkant van de gitaar een hele strook verwijderd zodat er meer plaats ontstaat voor de bedrading in gitaar. Omdat er overal in de binnenkant obstakels waren, waaronder veel buisjes om de vijzen in te bevestigen, hebben we die ook verbijderd om optimaal van de gegeven ruimte gebruik te kunnen maken. Op de vierde en vijfde photo is te zien dat we in de achterkant van de gitaar and egan doorgang hebben gecreëerd voor de draden die naar de buttons gaan omdat de gitaar anders niet meer te sluiten was. En op de laatste photo is te zien dat we de draden die rechtstreeks verbonden worden met de Arduino door een gat in de onderkant van de gitaar de behuizing verlaten.
Vaihe 9: Bedrading Aansluiten Op Protobord
Om alle komponentit met elkaar te verbinden hebben we gebruik gemaakt van een protobord. Tämä on bordje data ei ominaispiirre op net dezelfde manier werkt als een breadbord, maar dan betrouwbaarder en tehokkuutta. We hebben de bedrading aan het bordje gesoldeerd zoals te zien is op de derde photo. Dit bord is het centralle punt van waaruit al onze verbindingen vertrekken en samenkomen (zie foto 2).
Vaihe 10: Verstevigen
Viimeistely on myös viimeinen kosketus, mutta se on vakaa. Op deze -kuva on te zien hoe we het deel dat we er hebben uitgehaald d.m.v. dremelen achteraan de buttons verstevigen met stukjes karton.
Vaihe 11: Code Voor Het Communiceren Met Reaper
Deze -koodi on määritetty twee delenissä, mutta eerste deel on de arduino IDE (interaktiivinen kehitysympäristö) geschreven. Kuuntele koodisana geüpload naar arduino zelf en dient om all waarden van de sensors van de midi controller uit te lezen en door te sturen naar processing.
Käsittely on het tweede gedeelte. Deze code dient om alles wat arduino doortuurt te ontvangen en door te sturen naar Reaper.
Arduino
/* Tämä koodi on perusluonnos kommunikoidaksesi prosessoinnin kanssa sarjaportin kautta.
Se on suunnitelma, johon voit laittaa oman koodisi
omille painikkeille, potentiometreille tai antureille.
Siinä on kädenpuristus varmistaaksemme, että olemme yhteydessä
ja kommunikointimuoto päätetään
On tärkeää rakentaa viesti samalla tavalla, jotta Processing osaa purkaa sen ja lähettää oikeat OSC-viestit DAW: lle
tehty werkcollege AV&IT: lle
lokakuuta 2017
*
/ baudinopeus
const pitkä baudinopeus = 115200;
// aika odottaa ms: ssa nastojen äänestysten välillä
const int loopPauseTime = 200; // milli sekuntia
// sarjassa lähetetyn viestin alku- ja lopetusarvot
const Merkkijono startString = "*", endString = "#";
const char contactCharacter = '|';
// PIN -tunnukset
// muut globaalimuuttujat
const int aantalKnoppen = 5; const String namenKnoppen [aantalKnoppen] = {"knop 1", "knop 2", "knop 3", "knop 4", "knop 5"}; const int knopPinnen [aantalKnoppen] = {2, 3, 4, 5, 6}; const int mainButton = A1;
int mainButtonState = 0;
int potValue = 0;
// analogiset anturit
const int potPin = A5; // pin voor tremolo
// Tarvitsemme tätä toimintoa yhteyden muodostamiseksi käsittelyluonnokseen
// Pidä se täällä void estabContact () {while (Serial.available () <= 0) {Serial.print (contactCharacter); // lähetä char ja odota vastausta… delay (loopPauseTime); } Sarja.luku (); }
void setup () {
// aseta pinModes kaikille nastoille (int i = 0; i <aantalKnoppen; i ++) {pinMode (knopPinnen , INPUT); } pinMode (mainButton, INPUT); // kommentoi, jos käytät antureita, jotka toimivat 3 V: n sijasta 5 V: n kanssa // joudut myös liittämään 'ulomman' nastan 3.3 V: iin // analogReference (EXTERNAL);
// sarjakommenttien alustaminen
Serial.begin (baudRate); while (! Sarja); // odota kädenpuristusta createContact (); }
void loop () {
// VAIHE 1: LUE PAINIKKEET // kysele kaikki nastat ja yhdistä lukema sopivaan alueeseen int buttonStates [aantalKnoppen]; /* buttonStates [0] = digitalRead (knopPinnen [0]); buttonStates [1] = digitalRead (knopPinnen [1]); buttonStates [2] = digitalRead (knopPinnen [2]); buttonStates [3] = digitalRead (knopPinnen [3]); buttonStates [4] = digitalRead (knopPinnen [4]); */ mainButtonState = digitalRead (mainButton); for (int i = 0; i <aantalKnoppen; i ++) {buttonStates = digitalRead (knopPinnen ); } potValue = analoginenLue (potPin); // esimerkit: // float v0 = map (bpm, 0, 1023, 60, 250); // jos haluat käyttää normalisoitua kelluntaa (esim. äänenvoimakkuudelle) // float v1 = map (analogRead (pin2), fromMin, fromMax, 0, 100) / 100.0;
// VAIHE 2: KIRJOITA VIESTI
Serial.print (startString); // aloittaa viestisarjan kohteelle (int i = 0; i <aantalKnoppen; i ++) {if (mainButtonState == HIGH) {Serial.print (namenKnoppen ); Serial.print (","); Serial.print (buttonStates ); if (i <aantalKnoppen - 1) {Serial.print (","); }} else {buttonStates = 0; Serial.print (namenKnoppen ); Serial.print (","); Serial.print (buttonStates ); if (i <aantalKnoppen - 1) {Serial.print (","); }}} Serial.print (","); Serial.print ("tremolo"); Serial.print (","); Serial.print (kartta (potValue, 0, 1023, 0, 100)); // kirjoita viestin loppu Serial.print (endString);
// odota hetki..
delay (loopPauseTime); }
Käsittely
Vastuuvapauslauseke: Niet alle code van de processing sketch staat hier in geschreven, voor de volledige code zie het bestand: ProcessingSoundControl_handout_v6_1.pde in bijlage
De Volgende -ohjeet moeten aangepast worden (indien nodig):
// Baudrate moet hetzelfde zijn zoals in de arduino luonnos
lopullinen int baudinopeus = 115200;
// Zoek naar het IP -osoite reaperissa (zie -kuvakaappauksia bijlagessa)
// Stuurt naar dit andres en reaper luistert hier naar käsittelyssä //
// lopullinen merkkijono remoteIP = "192.168.1.43"; //esim. "127.0.0.1";
final String remoteIP = "10.3.209.60";
// Merkitse sendPort muistiin ja täytä se Reaperissa.
// Tämä on portti, jonka Processing lähettää ja Reaper kuuntelee.
final int listenPort = 12000, sendPort = 12000;
// Kuunteluportti on aktiivinen virheenkorjaus.
// portNames ovat täällä myös virheenkorjausta varten.
// lopullinen merkkijono portName = "/dev/ttyACM0";
final String portName = "COM5"; // "/dev/ttyUSB0";
////////////////////// KÄYTTÄJÄ PARAMETRIT //////////////////////// ////
tuonti käsittely. sarja.*;
tuo java.util.*;
tuoda oscP5.*;
tuonti netP5.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
Sarja commsPort; // Sarjaportti
boolean messageArrived = false;
Merkkijono saapuva = "", IncomingOSCMessage = "";
final char startChar = '*', endChar = '#'; final char contactCharacter = '|';
// Varmistaaksemme, että lähetämme vain muuttuvat parametrit (arvot)
// nämä globaalit variablit on poistettu täältä, mutta niitä ei pitäisi alustaa täällä! HashMap oldParams, newParams, toSendParams;
// Meidän on jaettava viesti joka pilkulla
void processIncoming () {String resVec = saapuva.jako (","); // saamme nimi+arvoparit // niin jokaiselle nimelle (+2)… yritä {for (int i = 0; i <resVec.length; i+= 2) {float value = Float.parseFloat (resVec [i+ 1]); // laita ne uuteen hashtable newParams.put (resVec , arvo); }} // jos tapahtuu virhe, otamme sen näytölle ja poistumme. catch (Exception ex) {println ("Poikkeusviesti:" + ex); printArray (resVec); exit (); }}
// Viestiemme suodattaminen
/ * Varmistamme, että OSC-out-viesti tulee vain, kun * syöttöviesti (sarja) muuttuu * Toisin sanoen: jos käännämme/painamme painiketta ja se muuttaa arvoa. * Joten suodatamme pois saapuvat arvot, jotka todella muuttuvat * Huomaa: emme vältä hyppääviä arvoja *, jotka tulevat esimerkiksi kiihtyvyysmittarista tai etäisyysanturista * sinun on tasoitettava ne itse Arduinossa */ void filterParams () {toSendParams = new HashMap (); for (String key: newParams.keySet ()) {// jos avain on jo olemassa jos (oldParams.containsKey (key)) {// avain on olemassa ja arvo ei ole sama, päivitä jos (! oldParams.get (key).equals (newParams.get (key))) {toSendParams.put (key, newParams.get (key)); }} else {// avain ei ole vanhoissa parametreissa, joten laita se! toSendParams.put (avain, newParams.get (avain)); } oldParams.put (avain, newParams.get (avain)); }}
void makeOSC () {
for (String key: toSendParams.keySet ()) {OscMessage myMessage = new OscMessage ("/"+ key); myMessage.add (toSendParams.get (avain)); / * lähetä viesti */ oscP5.send (myMessage, myRemoteLocation); }}
void translateMessage () {
processIncoming (); filterParams (); makeOSC (); } // Kun haluamme tulostaa ikkunaan void ShowIncoming () {// nähdäksesi saapuvan viestin HashMap -tekstin mukaisesti ("Incoming from Arduino", 20, 20); int y = 20; for (Merkkiavain: newParams.keySet ()) {y = y+20; teksti (näppäin, 20, y); teksti (newParams.get (avain), 300, y); }}
void showOsc () {
teksti (IncomingOSCMessage, 300, 200); IncomingOSCMessage = ""; }
void setup () {
koko (1000, 800); // Vaiheen koon täyttö (255); tausta (0); oldParams = uusi HashMap (); newParams = uusi HashMap (); // printArray (Serial.list ()); commsPort = uusi sarja (tämä, portin_nimi, baudinopeus);
/ * käynnistä oscP5, kuuntele saapuvia viestejä */
oscP5 = uusi OscP5 (tämä, kuunteluportti);
/* myRemoteLocation on NetAddress. NetAddress ottaa 2 parametria, * IP -osoite ja portin numero.myRemoteLocationia käytetään parametrina * oscP5.send () -kohdassa, kun osc -paketteja lähetetään toiseen tietokoneeseen, laitteeseen tai sovellukseen. käyttö alla. testausta varten kuunteluportti * ja etäsijaintiosoitteen portti ovat samat, joten * lähetät viestejä takaisin tähän luonnokseen. */ myRemoteLocation = uusi NetAddress (remoteIP, sendPort); }
void draw () {
if (messageArrived) {background (0); translateMessage (); ShowIncoming (); messageArrived = false; } showOsc (); }
void serialEvent (Serial commsPort) {
// lukee tavu sarjaportista: char inChar = commsPort.readChar (); switch (inChar) {case contactCharacter: commsPort.write (contactCharacter); // kysy lisää println ("alkaa…"); tauko; tapaus startChar: saapuva = ""; tauko; tapaus endChar: messageArrived = true; // println ("viestin loppu"); tauko; oletus: saapuva += inChar; tauko; }}
/* saapuva osc -viesti välitetään oscEvent -menetelmälle. */
void oscEvent (OscMessage theOscMessage) {float value = theOscMessage.get (0).floatValue (); // hanki 1. osc -argumentti
SaapuvaOSCMessage += "\ n" +
String.format ("### sai osc -viestin:" + "addrpattern:" + theOscMessage.addrPattern () + ": %f", arvo); println (IncomingOSCMessage); }
Vaihe 12: Ohjain Uittesten
Nu alles on aangesloten, kaikki koodi on geschreven en alles on gedubbelcheckt is het eindelijk tijd om de controller z'n werk te latten doen. Zoek een paar leuke effecten Reaper ja genitar van de voltooide Guitar Hero MIDI Controller!
Suositeltava:
Guitar Hero Guitarin käyttäminen zoomauksen ohjaamiseen (vain Windows): 9 vaihetta
Guitar Hero Guitarin käyttäminen zoomauksen ohjaamiseen (vain Windows): Koska olemme keskellä maailmanlaajuista pandemiaa, monet meistä ovat jumissa kotisiivouksessa ja liittyneet Zoomin kokouksiin. Jonkin ajan kuluttua tästä voi tulla hyvin tylsää ja tylsää. Kun siivosin kotiani, löysin vanhan Guitar Hero -kitaran, joka heitettiin t
Helpompi Guitar Hero Clone Controller!: 10 vaihetta (kuvilla)
Helpompi Guitar Hero Clone Controller!: Tämä on saanut inspiraationsa Realitiesin erinomaisesta ideasta, mutta käytin PC -ohjainta näppäimistön piirilevyn sijasta, jolloin ei tarvittu monimutkaista flipper -rakennetta
Guitar Hero Guitar Disconnecting Fix: 5 vaihetta (kuvilla)
Guitar Hero Guitar Disconnecting Fix: Joten, olet juuri ostanut tuon mukavan käytetyn kitarasankarikitaran ebaystä, ja kun se saapui sinulle, se ei vain yhdistyisi kyseiseen USB -sovittimeen, joten luulet vain hukanneesi 30 euroa; alas viemäristä. Mutta korjaus on olemassa, ja tämä korjaus todennäköisesti toimii
Guitar Hero Clone: 7 vaihetta (kuvilla)
Guitar Hero Clone: Oletko koskaan halunnut soittaa Guitar Heroa tietokoneellasi omalla kotitekoisella kitaralla? Valmistaudu pelaamaan alle 10 dollarilla ja kärsivällisyydellä
Eeppinen! Guitar Hero - kaksikaulainen kitara Epäonnistuminen: 7 vaihetta (kuvilla)
Eeppinen! Guitar Hero - Double Neck Guitar … Fail: Vuonna 2015 tulee kuluneeksi 10 vuotta popkulttuurin ilmiöstä Guitar Hero. Muistatko, että videopeli, josta tuli suositumpi kuin soitin, jota se onnistui jäljittelemään vain hämärästi? Mikä olisikaan parempi tapa juhlia sen kymmenvuotisjuhlaa kuin