ImPrinter: elektriska Imp trådlös, internet-ansluten termoskrivaren (6 / 7 steg)
Steg 6: imPrinter: Vad är koden?
Vår enhet firmware startar med en klassdefinition för klassen "skrivare". Klasserna är lite mer användbar i situationer där du vill skapa flera instanser av något, men detta ger ett trevligt sätt att strukturera vår kod. De flesta saker enhet firmware måste göra här skapas som metoder i klassen skrivare. Skrivaren också håller reda på sina egna aktuella inställningar.
Inuti skrivaren klassens konstruktor se vi en cool one-liner konfigurera UART (Universal Asynchronous ta emot och sända) hårdvara i den integrerade havspolitiken:
Hardware.uart57.configure (19200, 8, PARITY_NONE, 1, NO_CTSRTS);
Detta sätter upp UART maskinvaran på stift 5 och 7, konfigurerar överföringshastigheten till 19200 (bitar per sekund), 8 databitar per ord, ingen paritetsbitar, en stoppbit och ingen flödeskontroll; bara om de enklaste UART inställningar du kan använda.
Nedan klassdefinitionen för skrivaren registrerar enheten några callbacks för agenten. Vi kan tänka på dessa som krokar, var och en att ge agenten ett sätt att berätta att enheten ska göra något. Agent callbacks registreras med "agent.on()", som tar två argument: en sträng, som ska skickas av agenten att berätta enheten som motringning ska användas; och en funktion som anropas när agenten skickar strängen:
agent.on ("Skriv ut", function(buffer) {< br > server.log ("enhet: skriva ut ny buffert från agent:" + buffert); < br > myPrinter.print(buffer); < br >});
Titta på firmware, kan vi se att vi har registrerat callbacks för alla möjliga saker; togglande fet eller understruken text, berättar om försöksläkemedlet att börja hämta en bild från agent med "pull" callback (som du hittar som en metod i klassen skrivare), mata ett visst antal rader, etc.
När agent callbacks registreras alla, och klasserna definieras, vi instansiera klassen skrivare för att skapa en skrivare objekt, och vi är redo att gå. Enhetens firmware är främst händelsestyrd; bitar av det kallas till handling när agenten signaler är det dags att göra något.
initiera Skrivarobjektet på globalt definitionsområde
minskrivare <-skrivare (hardware.uart57, 19200); < br >
Agent firmware är ungefär samma, men även kortare, med några intressanta bitar kastas i för HTTP interaktioner. Låt oss ta en titt:
Vi köra hela igång med en definition av funktionen printLogo - vi får se detta registrerad som en callback för händelsen "logotyp" lite längre ner. En mycket användbar bit här är bilden av hur man gör en HTTP GET-begäran från din agent:
lokala reqURL = "http://electricimp.com/docs/attachments/images/examples/resources/ei_logo_tinyprinter.bmp"; < br > lokala req = http.get(reqURL); < br > imageData = req.sendsync () .body;
Vi gör en request-objektet med "http.get(reqURL), skicka sedan den, som returnerar ett http svar objekt. Kroppen av svar objektet innehåller bilddata - det är så enkelt är det!
Efter lite arbete med bilddata, ser vi agenten skickar en händelse till enheten. Här måste vi skicka flera parametrar till enheten, så vi packa dem i en array och sedan skicka arrayen med händelsen:
lokala imageParams = [imageSize, imageWidth, imageHeight];
Device.send ("downloadImage", imageParams);
Ner ser vi ytterligare callbacks registreras för händelserna "pull" och "imageDone" från enheten, sedan en callback registrerade med "http.onrequest". Detta är en mycket användbar bit av agent API: funktionen registrerat här kommer att kallas när en HTTP-begäran (av någon metod) görs i den agent URL i Enhetsinställningar. Detta är hur agenten hanterar nya data från skrivaren demo webbplats:
http.OnRequest(function(Request,res) {
En mycket viktig del här, för att skicka inlägg till agent: när webbläsaren skickar ett inlägg, skickar den en preflight-kontroll först för att se vilka metoder de mottagande stöder. Mottagaren ger denna information med dess svarshuvuden. Om dessa inte visar att agenten stöder POST, sidan kommer inte att skicka meddelandet och begäran att agenten är tom! Här är där vi satt dessa huvuden för att vår sida ska fungera:
Res.header ("Access-kontroll-tillåta-ursprung", "*"); < br > res.header ("Access-kontroll-tillåta-Headers","ursprung, X-efterfrågades-med, innehållstyp, acceptera");
Res.header ("Access-kontroll-tillåta-metoder", "POST, få, alternativ");
Agenten gör en annan användbar sak efter rubrikerna är inställda, men innan svar skickas: den bestämmer om du vill använda text meddelande eller bild meddelande föraren baserat på URL-sökvägen som begäran gjordes:
om (request.path == "/ text") {
Senast i agent koden ser vi återuppringning registrerade för händelsen "logotyp" från enheten:
Device.on ("logotyp", function(value) {< br > printLogo(); < br >});
Det är skytte hela matchen! Hela internet-anslutna skrivaren, mindre än 600 linjer!