Design

Sähkötöistä serverille eli miten valo syttyi API-IPA-nappiin

March 4, 2015

Read time 4 min

Kaupunkikulttuurin kukkea uutuus, Reaktorin rakentelema API-IPA-olutnappi valaisee oluenystävien iltoja BrewDogissa Viiskulmassa. Olutnapin saavuttaman mediahuomion innoittamana päätin hieman valottaa sen syntyä myös teknisestä näkökulmasta.

API-IPA-napin rakentelu oli ensimmäinen elektroniikkaprojektini. Sen aikana paitsi opin juottamaan myös vihkiydyin kaikin puolin syvemmälle sähkörakentelun saloihin. On se kivaa, kun ympärillä on osaavia ja auttavia tyyppejä!

Rautapuolella käytin perustana Electric Impiä. Imp on ohjelmoitava elektroniikka-alusta, joka tarjoaa pikkuruisessa paketissa tietokoneen ja langattoman nettiyhteyden. Lisäksi päälle tulee valmistajan oma pilvi. Breakout boardilla sain tarvittavat liitäntäkohdat näppärästi silmien eteen muiden komponenttien lisäämiseksi. Protoilu on tällä setillä nopeaa, mikä on näissä hommissa arvokasta.

Imp kiinnittyi breakout boardiin SD-kortin tavoin. Asetin Impin ottamaan virtansa mini-USB-virtalähteestä yhdistämällä tarvittavat liittimet breakout boardissa. Protovaiheessa juotin Impiin kiinni piikkirimaa ja käytin komponenttien yhdistelyyn breadboardia sekä jumpereita. Varsinaisiin tuotantoversioihin puolestaan juottelin herrasmiesmäiseen tapaan omat piirilevyt.

Electric Impin tööttääminen wifiin on hauskaa, koska se tehdään kännykän näyttöä hyväksikäyttämällä. Nollat ja ykköset viuhuvat kännykän näytön sammuessa ja käynnistyessä tiuhaan tahtiin. Kannattaa käydä kurkkaamassa: Electric Imp Blink-up guide.

Ohjelmointi puolestaan tapahtuu Impin omassa online-IDE:ssä selaimen kautta.

Tiivistetysti siis tällä eväskattauksella hoitui elektroniikkapuoli:

Electric Imp
Electric Imp breakout board
Iso punainen nappi, jossa on myös LED esivastuksella
Kondensaattori
Pieni kaiutin

Nappi on kiinni pinnissä 1, jossa on Impin puolelta käytössä sisäinen pulldown-resistori. Kondensaattori välissä tasaa virran, jotta saadaan yksi signaali per napinpainallus.

Imp lähettää tiedon painalluksesta omaan pilveensä, josta se ammutaan suoraan läpi Herokussa pyörivälle node-serverille. Node-serverillä on Socket.io:n avulla yhteys Instagram-televisioon sekä tarjoilijan näkymään iPadilla. Sockettien avulla toimii myös palaava yhteys. Sen tehtävänä on puolestaan lopettaa ledin välkkyminen, kun tarjoilija on kuitannut omassa näkymässään tilauksen toimitetuksi.

Kaiutin on hyvin yksinkertaisesti kiinni pinnissä 8 ja maassa. Sitä kontrolloidaan omatekoisella kevyellä MIDI-kirjastolla. Reaktorin Jari Aarniala loihti tätä varten monofonisten MIDIen konvertterin haluamaamme muotoon.

Kaiutinta ohjataan näin:

speaker <- hardware.pin8;

function playNote(hz, duration) {
  speaker.write(0.0);
  imp.sleep(0.02);
  speaker.configure(PWM_OUT, 1.0/hz, 0.1);
  imp.sleep(duration);
}

function rest(duration) {
  speaker.write(0.0);
  imp.sleep(duration);
}

function speakerOff() {
  speaker.write(0.0);
}

function playMidiMario() {
  playNote(659.2551138257398, 0.095238);
  rest(0.047619);
  playNote(659.2551138257398, 0.095238);
  rest(0.190476);
  playNote(659.2551138257398, 0.095238);
  rest(0.190476);
  playNote(523.2511306011972, 0.095238);
  rest(0.047619);
  playNote(659.2551138257398, 0.095238);
  rest(0.190476);
  playNote(783.9908719634985, 0.095238);
  speakerOff();
}

Led asuu pinnissä 9. Isossa punaisessa napissa on mukana ledi, jossa on suoraan jalkaan juotettuna tarvittava etuvastus. Kun nappia painetaan, valo alkaa vilkkua. Vilkkuminen loppuu, kun olut on onnellisesti viety janoiselle asiakkaalle ja tarjoilija on painanut omasta iPad-näkymästään kuittausnappia.

Tässä Electric Impin device-koodi kokonaisuudessaan, s’il vous plait:

sendOrderSwitch <- hardware.pin1;
speaker <- hardware.pin8;
led <- hardware.pin9;

led.configure(DIGITAL_OUT);

ledState <- 0;
shouldPulse <- 0;
wakeupTimerHandle <- null;

function playNote(hz, duration) {
  speaker.write(0.0);
  imp.sleep(0.02);
  speaker.configure(PWM_OUT, 1.0/hz, 0.1);
  imp.sleep(duration);
}

function rest(duration) {
  speaker.write(0.0);
  imp.sleep(duration);
}

function speakerOff() {
  speaker.write(0.0);
}

function playMidiMario() {
  playNote(659.2551138257398, 0.095238);
  rest(0.047619);
  playNote(659.2551138257398, 0.095238);
  rest(0.190476);
  playNote(659.2551138257398, 0.095238);
  rest(0.190476);
  playNote(523.2511306011972, 0.095238);
  rest(0.047619);
  playNote(659.2551138257398, 0.095238);
  rest(0.190476);
  playNote(783.9908719634985, 0.095238);
  speakerOff();
}

function cancelWakeupIfExists() {
  if (wakeupTimerHandle) {
    imp.cancelwakeup(wakeupTimerHandle);
  }
}

function stopPulsing(unUsedState) {
  cancelWakeupIfExists();
  shouldPulse = 0;
  led.write(1);
}

function pulse() {
  cancelWakeupIfExists();

  if (shouldPulse == 1) {
    ledState = 1-ledState;
    led.write(ledState);
    wakeupTimerHandle = imp.wakeup(0.5, pulse);
  }
}

function sendOrder() {
  local body = {
    table = 1
    place = "BrewDog"
  }

  agent.send("order-from-table", body);
}

function emitClick() {
  if(sendOrderSwitch.read() == 1){
    shouldPulse = 1;
    sendOrder();
    pulse();
    playMidiMario();
  }
}

agent.on("stopPulsing", stopPulsing);

sendOrderSwitch.configure(DIGITAL_IN_PULLDOWN, emitClick);

led.write(1);

Tässä siemailtavaksi myös Electric Impin agent-koodi. Se tarjoaa mahdollisuuden POST-kutsuille, kun laitteelta tulee pyyntö order-from-table:

function HttpPostWrapper (url, headers, string) {
  local request = http.post(url, headers, string);
  local response = request.sendsync();
  return response;
}

function requestHandler(request, response) {
  if ("stopPulsing" in request.query && request.query.stopPulsing == "1") {
    local stopPulsing = request.query.stopPulsing.tointeger();
 
    device.send("stopPulsing", stopPulsing);
  }
  
  response.send(200, "OK");
}

device.on("order-from-table", function(body) {
  server.log("Got an order from table");
  HttpPostWrapper("http://endpoint", { "Content-Type" : "application/json" }, http.jsonencode(body));
})

http.onrequest(requestHandler);

server.log("Stop pulsing: " + http.agenturl() + "?stopPulsing=1");

Napin tuotantoversion ilmiasusta vastasi Maker3D:n Svante Knuus, joka suunnitteli kotelon ja hoiti 3D-tulostuksen. Olutnappi on suunniteltu Blenderillä mittatilaustyönä. Designissa tyylilähtökohtana oli retropelihenkisyys, ja inspiraation lähteena toimi vanhojen pelien low-polygon-modelit. Lisäksi koteloinnista piti tietysti saada kestävä mahdollisesti kovakouraisiinkin ravintolaolosuhteisiin.

Kotelot tulostettiin 3DFactories-lafkan Easy3DMaker -tulostimella FDM-tekniikkaa hyödyntäen. Tulosteet pyöräyteltiin mustasta PLA PrintPlus -materiaalista. Kappaleeseen mallinnettiin tueksi ohut sisäkehä, jonka avulla oli mahdollista tulostaa ikään kuin tyhjän päälle. Näin kotelon päällimmäisestä pinnasta saatiin mukavan tasalaatuinen. Tulostuksen jälkeen tukirakenne oli helppo poistaa.

Kotelon 3D-mallit ovat vapaasti kaikkien nikkareiden käytettävissä, ja ne voi ladata allaolevista kuvista.

Hedelmäisiä API-IPA-hetkiä!

Never miss a post