Lasersnijden met Java ME

Het begon allemaal met de volgende vraag: “Is het mogelijk om zelf een lasersnijder te maken?”. “Natuurlijk”, zei Richard Ginus, software developer bij Ordina, optimistisch. Het lukte hem inderdaad om met een beperkt budget een door Java-aangestuurde lasersnijder te maken. In dit artikel is te lezen hoe.

Introductie

Een lasersnijder bestaat uit een laser die via twee assen over een werkgebied kan bewegen. Op deze manier kun je selectief materiaal weggebranden. Door de laser iets minder hard te laten branden, kun je ook graveren. Lasergraveren wordt veel gebruikt om bijvoorbeeld logo’s op producten te zetten of deze op een andere manier te personaliseren.

Eigenlijk heeft bijna iedereen een lasergrafeermachine in huis, namelijk de DVD-brander in je computer! Het eerste idee was om een laser uit een oude DVD-speler te halen. Dit is lastig, want daarvoor heb je allerlei speciale tools nodig. Daarom ben ik op zoek gegaan naar een goedkope kit. Uiteindelijk is de keuze gevallen op een microslice. Deze gebruikt een krachtigere diode dan een DVD-brander en komt tevens met een frame, motoren, motor drivers, laseraansturing, knoppen en schakelaars.

Voor de aansturing gebruik ik een Raspberry Pi 2. De GPIO-header (Die rij metalen pinnetjes) van de Raspberry komt goed van pas om alles aan te sturen. Hierdoor hebben we geen aparte microcontroller nodig. De software zal gebruik maken van Java ME embedded. Dit is niet alleen omdat het kan, maar meer omdat het moet. In Java ME zit immers een API om de GPIO-pinnen direct aan te sturen.


Shopping list
Wil je ook je eigen lasersnijder? Dan dien je de volgende benodigdheden aan te schaffen:

  • Microslice 2.5 kit;
  • Raspberry Pi 2;
  • Experimenteerprint;
  • BSS138;
  • 7 weerstanden 10K;
  • 5v BEC regulator;
  • Anti stress bal ;)
  • Lijm;
  • 12 volt 3 Ampère voeding;
  • 2.1mm DC jack;
  • Soldeerbenodigdheden;
  • 2x20 female header.

 

Aan de slag

Ik ben begonnen met de kit. Na het lijmen van de verschillende framedelen zijn de sensoren en motoren geplaatst en de draden op maat gemaakt. Vervolgens heb ik alles verbonden met de Raspberry Pi. Hiervoor is een protobordje gemaakt om alles overzichtelijk te houden. Onderstaand is daar een schema van te vinden.

afbeelding 1: Dit is het schema van de aansluitingen. Linksonder bevinden zich de weerstanden die nodig zijn om de stroom door de schakelaars te beperken. Rechtsboven bevindt zich de level converter.

 

Een stukje elektrotechniek

Al de elektronica van de kit is ontworpen voor een communicatiespanning van 5 volt. De Raspberry communiceert met een communicatiespanning van 3.3 volt. Dit kan natuurlijk niet samen en zal resulteren in rook en tranen. Er moest dus het nodige aangepast worden. Voor alle schakelaars is gewoon 3.3 volt voedingsspanning gebruikt. Bij de drivers van de motoren is het nodig een jumper te solderen. De aansturing van de lasermodule is moeilijker. Hiervoor moet je een eigen oplossing vinden om 3.3 naar 5 volt om te zetten. Dit noem je een level converter. Hier zijn speciale chips voor, maar ik heb gekozen voor een simpele transistor.

Afbeelding 2: Het protoboard op de Raspberry Pi. Het lijkt een wirwar van draden, maar er zit logica achter.

Nu is het tijd voor de software. Eerst heb ik, volgens de Oracle-tutorial, de softwareomgeving opgezet. Daarvoor moet je een Java ME runtime op de Raspberry zetten en plaats je de Java ME SDK op de ontwikkelings-PC. De runtime op de Raspberry Pi kan IMlets uitvoeren, de opvolger van de MIDlet. Daarnaast verzorgt de runtime een verbinding over het netwerk met de IDE. Voor ontwikkeling met Java ME is Netbeans zeer aan te raden. Dit is voor de support en de integratie met de Java ME SDK. Op de desktop van de ontwikkelings-PC staat ook de Device Connection Manager. Deze tool slaat een verbinding tussen de runtime op de Pi en de IDE.

Vervolgens is het zaak om de stand van de schakelaars te printen op het scherm in Java ME. Om de I/O-pinnen van de Raspberry aan te kunnen spreken, biedt Java ME de Device I/O API. Hiermee kun je elke pin een object geven. Het object biedt methoden om de betreffende pin als input of als output in te stellen. Als een schakelaar contact maakt, verandert de spanning op een van de pinnen. Wanneer dit is gebeurd, wordt een event gegenereerd waarnaar je kunt luisteren. Na een worsteling met pinnummers is het uiteindelijk gelukt om de status van de schakelaars te printen. De moeilijkheid is dat er meerdere namen zijn voor dezelfde pinnen. Ik heb een tool (Zie referenties) gebruikt waarin de nummers van de pinnen zijn op te zoeken.

De volgende stap is het laten bewegen van de motoren. Voor een constante snelheid is het nodig om pulsen met een constante interval naar de motordrivers te sturen. De timing hierbij is zeer belangrijk. In de embedded wereld is het gebruikelijk om het programma voor een korte tijd vast te houden. Op deze manier kun je beter bepalen wanneer het programma verder zal gaan. Thread.sleep() is veel te langzaam voor deze toepassingen. Daarom heb ik gewoon een lege while loop gebruikt die loopt tot een bepaalde systeemtijd is bereikt. Het is een hack, maar het werkt. De garbage collector zou bij de timing roet in het eten kunnen gooien. Het is namelijk niet te voorspellen wanneer hij langskomt. De hold-functie helpt hier ook bij door te wachten op een absolute tijd. Uiteindelijk bleek dat de garbage collector geen probleem veroorzaakt.

 

G-code

De software gebruikt G-code als input. G-code is een set commando’s dat gebruikt wordt voor Computer Numerical Control (CNC). Het beschrijft een reeks instructies die de machine één voor één uitvoert. Voorbeelden hiervan zijn het in een rechte lijn bewegen naar een bepaald punt of het aan- en uitzetten van de laser.

afbeelding 3: G-code van een vierkant

 

De Java-code van dit project is opgedeeld in twee delen: het aansturingsdeel en het besturingsdeel. Het aansturingsdeel zorgt dat de instructies uitgevoerd worden en het besturingsdeel zorgt voor een interface waarin je de instructies kunt invoeren en de instellingen kunt opgeven. De flow van de code van het aansturingsdeel is gebaseerd op een pipeline. Eerst worden de G-code-instructies geïnterpreteerd, waarbij voor elke instructie een object wordt gemaakt. Deze objecten worden in een queue geplaatst. Als alle instructies klaar staan, start het programma de executor. Dit is een deel van de code die zo snel mogelijk de instructies uitvoert in een aparte thread. Dit is gedaan om ervoor te zorgen dat zo min mogelijk afwijking in de timing komt te zitten.

Het blijkt in Java ME embedded niet mogelijk om een webserver op te zetten. Daarom heb ik ervoor gekozen het besturingsdeel in Java SE te maken. Het besturingsdeel en het aansturingsdeel communiceren via een socket. Een bijkomstigheid hiervan is dat je het besturingsdeel ook in andere talen kunt maken. Het besturingsdeel een Java SE- applicatie die met Spring boot een webinterface biedt om de laser te besturen.

 

Ervaringen met Java ME

De bedoeling van Oracle is om met CLDC 8 Java ME op één lijn te krijgen met Java SE. Voor een groot deel is dit gelukt. Tijdens het ontwikkelen heb je niet in de gaten dat je op een ander platform werkt, omdat de meeste functionaliteit gewoon aanwezig is. Pas toen ik String.split wilde gebruiken, kwam ik voor het eerst een verschil tegen.

Het is in Java ME mogelijk om zeer diep in de hardware door te dringen. De meeste chips hebben een aantal hardware-accessoires ingebouwd. Hierbij kun je denken aan timers en controllers. Het is voor embedded applicaties een absolute eis dat deze hardware volledig benut kan worden.

Het is duidelijk dat Java ME 8 een jonge techniek is. Hier en daar zijn grote gaten in de functionaliteit te vinden. De mogelijkheden van de meeste chips zijn via de Device I/O API maar gedeeltelijk beschikbaar gesteld. Je kunt met de hand registers bereiken, maar dit is omslachtig. Voor een groot deel ben je overgeleverd aan chipfabrikanten en aan Oracle voor ondersteuning. Op dit moment wordt, tot mijn grote verdriet, alleen ontwikkelen voor Java ME 8 op Windows ondersteund.

 

Resultaat en toekomst

Het is nu mogelijk om rechte lijnen te graveren in verschillende materialen. Hiermee is de laser niet het snelst of het meest efficiënt, maar alle figuren zijn te benaderen met rechte lijnen, dus je kunt alle figuren maken. Een project als dit kun je eindeloos optimaliseren door bijvoorbeeld de implementatie van precieze curves of dynamische snelheidsregeling, maar ergens moet je een grens trekken. Graag zou ik de bewegingen van de laser in de toekomst willen ‘voorkoken’. Hierbij worden de instructies gereduceerd tot de simpelste vorm. Op deze manier kun je vooraf optimalisaties doen. Helaas is op het moment van schrijven de laserdiode kapot. Vandaar geen foto van het eindresultaat. Wat ik wel kan zeggen, is dat het project gelukt is. Met beperkt budget, beperkte tijd en met puur Java kun je zelf een lasersnijder maken.


Referenties
Getting started guide van Oracle
Tool om pinnummers op te zoeken