Marco Hebing, Remko de Jong, en Eelco Meuter van Ordina zijn gek van de Raspberry Pi en wilden wel eens kijken wat er mogelijk is. Zo zochten ze uit hoe je met Java enkele led’s via een website kunt aansturen. Daarnaast hebben ze een eigen mobiele Java enterpriseserver gebouwd.
De Raspberry Pi is een computer ter grootte van een creditcard. Het is een vernuftig apparaatje met een robuust karakter en handige aansluitingen, dat tegen een schappelijke prijs online te bestellen is, waardoor het een uitstekend platform is om mee te experimenteren. De Raspberry Pi is ontwikkeld, nadat werd geconstateerd dat de huidige generatie startende IT-studenten zelden met computers experimenteert. Vaak komt dit omdat de ouders het niet zien zitten dat zoon- of dochterlief uit nieuwsgierigheid hun kostbare bezit uit elkaar schroeft.
Sinds de introductie zijn het niet alleen ouders, kinderen en onderwijsinstellingen die een Raspberry Pi aanschaffen, maar vindt het computertje ook gretig aftrek bij hobbyisten. Dit leidt tot veel grappige, handige en creatieve toepassingen met een Raspberry Pi, met name op het gebied van home automation.
In dit artikel bespreken we twee toepassingen van een Raspberry Pi met Java. In de eerste toepassing sturen we een aantal led’s aan via een website. Dit project staat model voor een softwarematige aansturing van hardware via de pinnen van de General Purpose Input Output (GPIO) met Java; oftewel de ‘hello world’ van de elektronica.
Het tweede project is wat extremer: bouw je eigen mobiele Java enterpriseserver. In dit project installeren we een volwassen applicatieserver op de Raspberry Pi en monteren deze op een robot. Het praktisch nut van deze mobiele applicatieserver is ons nog niet helemaal duidelijk, maar dat mag de pret niet drukken.
De Raspberry Pi die we tijdens de projecten gebruiken, is van het type Model B (versie 2). Er zijn twee types op de markt. Het verschil tussen Model A en B is dat Model B een extra usb- en ethernetaansluiting heeft en 512 MB RAM, in plaats van de 256 MB die in een Model A zit. Verder draait onze Raspberry Pi met de standaard Linux-distributie en is tijdens de initiële configuratie overgeklokt naar 800 Mhz.
Led there be Pi
We beginnen met het aansturen van enkele led’s via de GPIO-aansluiting (P1). Het boodschappenlijstje in het kader vermeldt de onderdelen die je nodig hebt. De GPIO-connector van de Raspberry Pi heeft 26 pinnen. Deze zijn verdeeld in 17 echte input/output-pinnen, een I2C-interface, een SPI- interface, Serial Tx- en Rx-pinnen. Als je goed naar de Raspberry Pi kijkt, dan zie je dat er een rechtstreekse verbinding is tussen de processor en de GPIO-pinnen. Alles wordt dus direct vanuit de processor aangestuurd.
Figuur 1: Schema van een Raspberry Pi Connector met ons ledproject
Kijken we naar het schema (figuur 1), dan zien we dat er per led (D1 t/m D5) ook een weerstand (R1 t/m R5) in serie is geschakeld om de stroom door elke led te beperken. Dit voorkomt beschadigingen aan de Raspberry Pi en de led’s.
Een led werkt prima met 10mA en heeft daarbij zelf maar 0,7V nodig. De GPIO-pinnen leveren 3,3V, waardoor er dus nog 2,6V overblijft die we met een weerstand veilig wegwerken. De weerstandswaarde kunnen we berekenen met de formule R(?) = U(V) / I(A). In dit geval 2,6V / 0,01A = 260?. Die weerstandswaarde is geen standaardwaarde, dus ronden we af naar boven en komen we uit op 270?.
We hebben dit ledprintje op de eenvoudigste manier gemaakt. Daarbij komt de print, met de koperen kant boven, op de Raspberry Pi te liggen. De connector zit nu aan de onderkant. De foto laat zien wat de bedoeling is. Alle andere componenten solderen we op de koperzijde, zodat ze niet de onderdelen van de Raspberry Pi kunnen raken.
Foto 1: Het led-printje met de koperen kant boven
Vanaf P1-pin 7 (figuur 1) solderen we eerst de weerstand R1. Vanaf de andere kant van de weerstand gaan we door naar de lange aansluiting van led D1. De korte aansluiting van de led verbinden we door met pin 6 van P1, dit is de min, ofwel ground. Herhaal dit voor alle weerstanden en led’s in het schema.
Om de GPIO-pinnen vanuit de processor aan te sturen, gebruiken we WiringPi, een library geschreven in C door Gordon Drogon. Let op! WiringPi gebruikt een eigen nummering voor de pinnen. Deze wijkt af van de GPIO- nummers zoals benoemd in figuur 1.
Tabel 1: Mapping van de de Raspberry Pi naar WiringPi
Om vanuit Java met WiringPi te kunnen praten, gebruiken we Pi4J. Met Pi4J kunnen we de benodigde pinnen definiëren als output. Immers, wij schakelen de led’s aan of uit. Het definiëren van een pin kunnen we maar één keer doen. Het is dus belangrijk om na de initialisatie de referentie naar de pin vast te houden. Dit kan heel simpel door gebruik te maken van een singleton die de objectreferenties naar de pinnen beheert.
Nu moeten we alleen nog een client bouwen om de singleton aan te roepen. Wij kozen voor een simpele JSP, maar je kunt natuurlijk ook je eigen front-end bouwen in bijvoorbeeld JavaFX. Vanuit het aansturen van led’s via een JSP is het natuurlijk nog maar een kleine stap naar een mobiele enterprise-applicatie.
Bouw je eigen mobiele Ja-Pi enterprise-server
In dit volgende project richten we onze Raspberry Pi in als een enterprise-server en monteren we hem op een robot. De opbouw van het voertuig is niets meer dan een Raspberry Pi op rupsbanden, uitgerust met een op een servo gemonteerde webcam, wifi, infraroodsensoren en een paar rijregelaars en schakelaars. De beelden van de webcam worden realtime verwerkt via Motion, een Linux-tool voor live video capture.
Figuur 2: Schema voor de bouw van de robot
Links op figuur 2 zie je duidelijk de GPIO-connector. Rechts naast de GPIO bevinden zich de comparatoren voor de infraroodsensoren. Bovenaan het schema bevinden zich de connectoren voor de rijregelaars en servo.
De besturing van de robot is beperkt tot het versnellen en vertragen van de snelheid en het draaien van de robot en camera. Vooruitrijden betekent dat we de snelheid van beide rupsbanden tegelijkertijd veranderen. We kunnen een bocht maken door de snelheid van de ene rupsband te verhogen ten opzichte van de andere band. Het aanpassen van de snelheid van de elektromotoren gebeurt via de rijregelaars.
Figuur 3: Applicatiearchitectuur voor de aansturing van de robot
De opzet van de applicatie is vrij simpel. Er is een eenvoudige HTML5-pagina, waarmee we via AJAX-requests besturingscommando’s uitvoeren. Een aantal controllers vangt deze REST-calls op. We maken hiervoor gebruik van JAX-RS. In deze controllers injecteren we onze Robot-class. Deze class bevat de logica om de robot te besturen en bevat een referentie van de UnitManager. De UnitManager-class stuurt commando’s uit naar de driver die de robot en camera besturen. Daarnaast leest de UnitManager de sensoren uit via WiringPi.
Voor de applicatieserver kozen we in eerste instantie voor de IBM Websphere. Volgens de brochure is het nieuwe Liberty Profile geheel configureerbaar en gebruik je enkel de features die je nodig hebt. De eerste testen waren veelbelovend. Websphere Librerty Profile draaide al snel en gemakkelijk op onze Raspberry Pi. Na de toevoeging van CDI, een singleton bean, enkele asynchrone beans en een timerservice in onze applicatie, ging het echter mis. Dus exit IBM, welkom JBoss.
Tijd voor de volgende uitdaging. Om de motoren en servo aan te sturen, schrijven we een commando vanuit onze applicatie naar ServoBlaster; een driver om servo’s en motoren softwarematig aan te sturen. Dit moet multi-threaded gebeuren, want de twee rupsbanden moeten simultaan draaien. Je eigen threads beheren op een applicatieserver is niet aan te raden. Om dit te simuleren, maken we gebruik van een timerservice. Dit werkt als volgt. Stel, we willen de snelheid van de robot opvoeren. We creëren dan twee getimede events met een kleine time-out voor respectievelijk de linker- en rechterrupsband. Op de time-out van dit event voeren we het commando uit in een aparte thread.
@Singleton
@Startup
public class UnitManager {
@Inject
private UnitCommand command;
@Resource
private TimerService timerService;
@Timeout
public void executeCommand(Timer timer) {
command.execute((RCUnit) timer.getInfo());
}
/**
* Creates a new command.
*
* @param timer interval at which command is executed
* @param info Required data to be passed to command
*/
public void createCommand( int timer, RCUnit info ) {
timerService.createSingleActionTimer( timer, new TimerConfig(info, false );
}
// rest of class
}
@Stateless
public class UnitCommand {
@Asynchronous
public void execute(RCUnit unit) {
writeCommandToServoBlaster(unit);
}
// rest of class
}
Het bovenstaand codevoorbeeld toont ook nog een RCUnit-class. Deze class is een datacontainer voor onder andere de nieuwe positie en de grenswaarden van de betreffende servo of motor.
Nadat het in elkaar zetten van de robot en het testen van de software, was het tijd om alle Linux-libraries, de applicatieserver en onze webapplicatie te installeren. Dit is erg makkelijk en na een paar minuten opstarttijd heb je beeld. Je kunt nu een mobiele applicatieserver aansturen vanaf een website. Als bestuurder word je netjes gewaarschuwd voor een naderend object. Een eventuele botsing zorgt ervoor dat de motoren en servo geen stroom meer krijgen. Een simpele refresh van de webpagina herinitialiseert de robot en je kunt weer op weg. Mocht je nieuwsgierig zijn naar het eindresultaat, bekijk dan het YouTube-filmpje.
Wij hopen dat deze projecten je inspireren en zijn erg benieuwd met welk (wild) idee jij binnenkort aan de slag gaat. Laat het weten aan de redactie van het Java Magazine. Wat het ook zal zijn, je zal er een hoop van leren en veel lol aan beleven. Veel plezier!
Referenties
Pi4J:
Boodschappenlijstje
1 Raspberry Pi, Model B (versie 2)
Project 1
5 led’s, maakt niet uit welke kleur.
5 weerstanden 270?, 0,25W
26-polige (2x13) female printheader
Stuk experimenteerprint 4x5cm (waarbij drie gaatjes steeds verbonden zijn)
Lichte soldeerbout, ongeveer 15W
Soldeertin
Project 2
Onderstel Robot
2 rijregelaars
6V accupack + acculader
Stuk experimenteerprint
4 micoswitches voor de bumpers
1 standaard servo
2 IDC-connectoren voor de rijregelaar
2 infrarood afstandsensoren
1 power switch
1 diode 1N4004
1 condensator 4700uF/10V
1 flatcable 2x13 polig
1 male printheader 2x13 polig voor flatcable
3 male printheader 1x3 polig voor servo en rijregelaars
1 IC LM2902N
4x weerstand 220k
2x weerstand 470k
2x weerstand 1M
1 WI-PI, wifi dongle
1 webcam
1 sinaasappelkistje
Verf en wat plamuur