Table of Contents Introduction
1.1
Dankwoord
1.2
Abstract
1.3
Intation
1.4
Opdracht
1.5
Programmeer technologieen
1.6
Arduino
1.6.1
Read-functies
1.6.1.1
Write-functies
1.6.1.2
Visual Studio
1.6.2
Winform
1.6.2.1
Codering Winforms
1.6.2.2
Driver Template
1.6.2.3
Keuze-hardware
1.7
Robot Arm
1.7.1
Inleiding
1.7.1.1
Keuzes Arm
1.7.1.2
Start Building
1.7.1.3
Aansluiting
1.7.1.4
Aansturing motoren
1.7.2
H-brug
1.7.2.1
L293D
1.7.2.2
L293D connections
1.7.2.3
Waarheidstabel L293D
1.7.2.4
Microcontroller
1.7.3
Servomotoren
1.7.4
Wat is een servomotor
1.7.4.1
Opbouw van de servomotor
1.7.4.2
Werking van een servomotor
1.7.4.3
Sturen van een servomotor
1.7.4.4
Gebruikte servomotoren
1.7.4.5
LED-matrix
1.8
Onderdelen
1.8.1
LED
1.8.1.1
ULN2003A
1.8.1.2
PCB
1.8.1.3
Arduino
1.8.1.4
2
Software
1.8.2
Multiplexen
1.8.2.1
Code
1.8.2.2
Bibliografie
1.9
Conclusie
1.10
3
Dankwoord Ik zou graag het bedrijf Intation bedanken dat ze mij deze kans gegeven hebben om dit project te mogen maken. In het specifiek wil ik Glen Vanroelen daarbij bedanken omdat hij gedurende deze periode mij vooral heeft gesteund en geholpen waar nodig. Ook heeft hij de kleine foutjes eruit gehaald en me veel bijgeleerd. Niet alleen over het project zelf maar ook over hoe het in het bedrijfsleven eraan toegaat. Ook wil ik graag de leerkrachten bedanken die mij gedurende dit project hebben geholpen met de vragen die ik had.
Abstract Het doel van deze bachelorproef bestond uit het onderzoeken en het ontwikkelen van een werkend prototype voor een beursdemo. Het doel van deze demo was dat via de Kinect een hardware product kon aangestuurd worden. Dus dat er voor de Kinect gestaan wordt en een bepaalde beweging uitgevoerd kan worden zodat er dan ook iets in hardware zal gebeuren. Wij dachten hierbij snel aan een robot arm. Zodat we deze kunnen besturen via de Kinect. Via Unity Game Engine kunnen we dan een 3D weergave geven van de robot arm die ook zal bewegen. Wanneer de gebruiker voor de Kinect plaats neemt zal dit worden weergegeven op een scherm en kan hij de 3D robot arm in Unity bewegen. Intern worden dan waarden doorgestuurd naar de Arduino code die dan vervolgens de robot arm zal aansturen. Afhankelijk van welke beweging er gebeurt in Unity zal er ook een overeenkomstige beweging gebeuren met de robot arm. Dit laatste wordt in werkelijkheid gebracht door een Driver template die de functies zal verwerken en doorsturen naar de Arduino IDE, die op zijn beurt alles zal uitlezen en de motoren zal aansturen via de H-bruggen.
Intation Intation is een bedrijf dat zich profileert in de procesautomatisatie en de regeltechniek. Zij houden zich bezig met het ontwikkelen en programmatie van een bepaald industrieel proces. Het proces waar zij aan werken doet zich vaak voor in havenbedrijven. Bijgevolg werken zij dus zo goed als altijd aan een proces dat wordt beheerd door middel van vaten, buizen en kleppen.
4
Opdracht Inleiding Bestaand project afwerken i.v.m. hardware en software. Het project moet een autonoom project worden met behulp van een Kinect. We moeten met de Kinect werken om zo, als er een beweging gedaan word voor de Kinect, dat er in de hardware ook een verandering plaatsneemt. Bijvoorbeeld: Als we voor de Kinect gaan staan en we beelden uit dat we een kraantje opendraaien, dat dit ook werkelijk gebeurt. Dus we kunnen dan een emmer water vullen of dergelijke. Of als we een arm beweging doen dat er iets beweegt/verplaatst. Dus we zijn gaan samen zitten en beginnen brainstormen. We zijn samen tot de conclusie gekomen dat we met een robot arm gaan werken. De robot arm kunnen we dan besturen aan de hand van de Kinect. Afhankelijk van de beweging zal de Kinect mee veranderen. Met deze robot arm en die bewegingen kunnen we dan een soort van puzzel oplossen. Ook zouden we dan een Led-matrix bouwen om de gegevens van het bedrijf te laten opkomen. Dit oogt veel mooier voor het project dan aangezien het de bedoeling is dat dit op een beurs zal komen te staan.
Opdrachtverloop Dus dankzij het brainstormen kon er deze manier rustig samengezeten worden en opzoekingswerk doen om een goede visuele kant voor de opdracht te maken. Daarbij dachten we dus bij het gebruiken van een robot arm. Hardware matig dacht ik ook aan een LED-matrix om dan de gegevens van de opdracht en de gegevens van het bedrijf te laten zien op de beursstand. Dan zijn we begonnen met het aankopen van de verschillende componenten om dit allemaal te kunnen bouwen. Eens we deze componenten hadden konden we beginnen bouwen aan de robot arm. Ondertussen heb ik dan ook schema’s gemaakt voor de matrix en ook voor de motorsturing. Deze schema’s zijn ook nodig om de PCB’s hiervoor te kunnen printen. Dan kan het bouwen van de arm starten en het uitzoeken van de aansluiting van de servo motoren. Zodra er geweten was hoe de servo motoren werden aangesloten kon de softwareontwikkeling hiervoor beginnen. We gaan dan van een winform gebruik maken om de juiste waarde en de juiste motor aan te sturen. Vanaf we weten dat we meedere motoren konden aansturen tegelijk en dit werkte konden we beginnen met de template driver te schrijven. Dit om makkelijker te kunnen gebruiken met de Software. Ook om nadien sneller te kunnen inpikken voor mensen die nieuw zijn met het project maar hier toch in moeten werken. Dan is dit gemakkelijker om snel in te pikken. Dus rest er ons enkel nog de communicatie tussen hardware en software wat dan via deze driver zal gebeuren.
Software Deze opdracht zal zowel Hardware als software bevatten. Natuurlijk is het officieel opgesplitst voor Tim en Kristof, zodat Kristof de Hardware doet en Tim zich bezig zou houden met alle software. Maar aangezien er bij de hardware ook software nodig is. Deze software zal dan bestaan uit de code van de Arduino, de code van de winforms maar ook de code van de Driver template. Uiteraard zal deze code niet altijd geheel complex zijn maar code is code. De code moet uiteraard ook werken vooraleer de hardware kan werken. Op het einde zal het aantal code niet verassend hoog liggen, maar om hardware te kunnen doen werken moet er vooral heel veel getest worden. Dus zal er heel veel testcode bestaan waardoor er uiteindelijk niet veel gedaan lijkt te zijn maar er is dan vooral veel getest. Maar als het puntje bij het paaltje komt zal er altijd software nodig zijn om hardware met een Arduino te willen laten werken.
5
Hardware De opdracht aan de kant van de Hardware is noodzakelijk om de robot arm te laten bewegen. Dus moet er een robot arm in elkaar gestoken worden om deze daarna vlot te kunnen aansturen via een Arduino. We moeten via de Kinect gestures kunnen zien en dan iets laten doen met de Arm. Hiervoor zullen we dan iets gaan voorzien zodat de juiste motor en de juiste waarde meegeeft naar de Arduino (Write). De functie die naar de Arduino over de seriele poort schrijft, moet worden voorbereid om als driver commando te werken. Als extra kan er een LED-matrix gemaakt worden die dan de gegevens van het bedrijf kan tonen op de beursstand. Aangezien de Robot Arm een Eye Catcher op een beurs wordt kan deze LED-matrix zeer mooi komen te staan.
6
Programmeer technologien Arduino Read-functies De Read-functies zijn de methodes die steeds de Seriele poort zullen lezen of er iets aanwezig is, en als er dan iets aanwezig is zal hij via een algoritme de data lezen en verwerken. Natuurlijk vooraleer dit algoritme geschreven kon worden moest er eerst nagedacht/uitgezocht worden hoe de data via de Seri?le poort doorgestuurd wordt en in welk formaat. De data wordt op de Seriele poort in het formaat van ASCII karakters geschreven en doorgestuurd. Dus eender wat er geschreven zal worden, er zal een ASCII karakter van gemaakt worden en deze wordt dan doorgestuurd. Dit wil natuurlijk niet zeggen dat als je bijvoorbeeld ‘80’ schrijft op de poort dat hij ‘80’ als een karakter ziet. De ‘80’ wordt opgesplitst in de 8 en de 0. En dan afhankelijk van welk teken zal hij dit omzetten naar het overeenkomstige ASCII karakter. Dit wil dus zeggen dat het algoritme ook deze ASCII karakter zal moeten omzetten en de berekeningen moet uitvoeren. Om verder te gaan op het schrijven van de waarden, het schrijven gebeurt niet in Arduino IDE maar in Visual Studio. In de Arduino IDE wordt er enkel gelezen van de Seriele poort. Er moet natuurlijk beslist worden of we twee keer gaan readen tegelijk, of dat er met delimiters gebruikt gaan worden. Aangezien we een waarde aan de motoren moeten meegeven, en er ook een bepaalde motor moeten kunnen geselecteerd worden vanuit Visual Studio. Het twee keer Writen in Visual Studio en twee keer readen kort na elkaar is niet mogelijk, dus zal er gebruik worden gemaakt van de delimiteres. Dit zijnde de komma. Dus moeten we in het algoritme ook de komma mee voorzien dat deze de waarde voor de komma opslaat en ook de waarde na de komma. if (Serial.available())
{
ByteData = Serial.read(); if (ByteData >= 48 && ByteData <= 57) {
if (tmp == -1) {
tmp = ByteData � 48; }
else {
tmp = tmp * 10; tmp = tmp + ByteData - 48;
}
}
Eerst zal er dus gecontroleerd worden of er data op de Seriele poort aanwezig is. Als dit het geval is dan zal er verder gegaan worden. Eerst wordt de data in een variabele gestoken zodat we hier gemakkelijker kunnen werken. Als eerste wordt er dan gecontroleerd of het eerste karakter tussen 48 en 57 ligt. Dit wil zeggen dat er eerst gecontroleerd zal worden of het een getal is dat er aanwezig is. Als het nu een getal is dan zal er gekeken worden of de variabele tmp nog leeg is en als dit het geval is zal er 48 van de data afgetrokken worden aangezien 48 het eerste getal is en als het getal 49 bijvoorbeeld is dan zal het getal 1 zijn, op deze manier kunnen we snel zien welk getal het is. Daarna zal de if terug doorgelopen worden en kan het volgende karakater gelezen worden. En als dit terug een getal is dan komen we in de else functie omdat tmp niet meer leeg is in dit geval. Het getal wordt dan vermenigvuldigt met 10 aangezien ons decimaal stelsel met stappen van 10 werkt. En dan worden ze opgeslagen met elkaar.
7
else if (ByteData == 44) {
data1 = tmp; tmp = -1;
}
else if (ByteData == 32) {
data2 = tmp; tmp = -1; Serial.println(data1); Serial.println(data2);
}
else {
data2 = tmp; tmp = -1;
}
Maar als het volgende karakter nu niet tussen 48-57 ligt dan is dit geen getal en zal er gecontroleerd worden of het een komma of een spatie is. De komma is onze delimiter en de spatie is het eindkarakter. Als we nu een komma tegenkomen zal de eerste opgeslagen waarde opgeslagen worden in een andere variabele en wordt tmp terug leeggemaakt. Wanneer er nu een spatie gedetecteerd wordt dan is dit het einde en zal de laatst opgeslagen waarde in een variabele opgeslagen worden en tmp opnieuw leeggemaakt worden. if (data2 == 9) {
if (data1 == 9)
{
StartPos();
else
if (data2 == 1)
{
if (data1 <= 180 && data1 >= 5)
else if (data2 == 2)
}
{
} ArmTurn(data1);
}
}
{
if (data1 <= 180 && data1 >= 10)
{
Shoulder(data1);
}
}
else if (data2 == 3) {
if (data1 <= 150 && data1 > 0)
{
Elbow(data1);
}
}
else if (data2 == 4) {
if (data1 <= 120 && data1 >= 5 )
{
Wrist(data1);
}
}
else if (data2 == 5) {
if (data1 <= 155 && data1 > 0)
{
Twist(data1);
}
}
else if (data2 == 6) {
if (data1 <= 30 && data1 > 0)
{
Grab(data1);
}
}
We hebben nu de twee waarden opgeslagen. Dan kunnen we er mee werken. Eerst gaan we controleren welke motor er aangestuurd moet worden en daarna controleren we het andere getal voor te kijken welke waarde er naar deze motor gestuurd moet worden.
8
Write-functie De Write functie in de Arduino IDE heeft niets met de Seriele poort te maken. De write functie heeft te maken met het schrijven naar de servo motoren. We maken hierbij ook gebruik van de Servo.h library van Arduino zelf om de motoren aan te sturen. In deze library zit de mogelijkheid dat we een waarde tussen 0-180 kunnen ingeven en dat de servo motoren dan verplaatsen naar de juiste waarde. Eerst moeten we een servo object aanmaken vooraleer we naar die bepaalde servo kunnen schrijven. Dit object kunnen we dan attachen aan de juiste pin waarop we deze hebben aangesloten op de Arduino Due. De write functie ziet er dus als volgt uit. Vb: Grab.Write(50); Om het mij persoonlijk gemakkelijker te maken heb ik kleine methodes geschreven zodat we niet telkens opnieuw write moeten typen maar dat we gewoon de waarde kunnen meegeven als een parameter in de methode. void Grab(int grabpos) {
GrabServo.write(grabpos); }
Dit is nu enkel het voorbeeld van de GrabServo maar dit is voor elke servo motor hetzelfde.
9
Visual Studio Waarom Visual Studio Visual Studio is een gekend platform voor ons. Ook omdat we hier al in gewerkt hebben en hierin in c# kunnen schrijven. Met de winforms kunnen we een mooie interface maken waarin we tekstvakken kunnen plaatsen om de verschillende waarden in te geven. Deze waarden zullen dan gelezen worden en klaargezet om dan in de Write functie te schrijven. Een goede interface is ook veel mooier.
Winform In de winforms is het de bedoeling dat we via invoer velden de juiste motor en waarde ingeven en zo dan doorsturen naar de Arduino. In de winform zullen tekstvakken uitgelezen worden. We hebben sowieso 6 rijen, en 2 kolommen. Dit omdat we 6 motoren hebben, we moeten een bepaalde motor en een bepaalde waarde geven. Dus bij deze een tabel van 6x2. Ook zijn er knoppen aanwezig die dan ofwel de start positie gaan weergeven ofwel de ingegeven positie gaan weergeven.
Aan de linkerkant zien we zes Comboboxes met alle verschillende motoren in die dan gekozen kunnen worden en aan de rechterkant zien we dan zes textboxen waarin we de waarde van die bepaalde motor kunnen ingeven. Als we dan op ‘Set Position’ klikken dan wordt er eerst gecontrolleerd of er iets ingevuld is in de textboxen en of er iets aangeduid is bij de comboxen, als dit het geval is dan zullen die bepaalde waarden opgeslagen worden. Naar het einde toe zijn er dan voor elke gesture knoppen toegevoegd. Dit om deze gestures voor te stellen. Naar het einde toe als de Software van de robot arm en de Software van Unity en de Kinect volledig klaar is kunnen we dit samen voegen en hoeven we enkel de code achter de knoppen te gebruiken en achter de gestures in Unity te stoppen.
Codering winforms Als we nu eerst kijken in het geval dat we alles nog moeten invoeren in de winforms qua waarden en motoren. Dus nog voor het geval dat we de gestures voor stellen. Ten eerste worden de waarden natuurlijk uitgelezen in de textboxen en comboboxen met deze waarden kunnen we dan de juist write functie aanvullen. De write functie bestaat dan uit een functie die de driver template zal aanroepen en dan parameters zal meegeven in de vorm van KeyValuePairs. Deze KeyValuePairs maken het gemakkelijker om deze waarden nadien uit te lezen in de template zelf. Ook is de manier van werken met KeyValuePairs veel gemakkelijker en eenvoudiger om goed op te slaan in een duidelijkere lijst. De KeyValuePair constructor bevat twee properties. Key waarin de naam van de parameter komt, en Value de de waarde van diezelfde parameter (key). Dus in het geval van de robot arm is dit dan als voorbeeld;
10
KeyValuePair<string,string>(�motor�,1). KeyValuePair<string,string>(�motorvalue�,150).
In beide gevallen is het twee keer een string dat in de KeyValuePair wordt opgeslagen. Technisch gezien zijn de value’s int waarden maar omdat deze uit de textboxen wordt uitgelezen is dit een string dit zou omgezet kunnen worden maar dat vergroot de kans op onnodige bugs. Dus de Key is de eerste waarde die tussen de haakjes staat en de value is de tweede waarde. Dus als key kunnen we dan schrijven dat we een motor willen en daarbij kunnen we als value dan zeggen welke motor. Hetzelfde voor het tweede puntje en dit is hetzelfde voorbeeld. Maar bij dit voorbeeld wordt er enkel getoond hoe de values worden opgeslagen in de KeyValuePair. Hierbij kunnen we dan eerst schrijven dat het om een motorvalue gaat en dan de juiste waarde erachter kunnen plaatsen. In dit geval hebben we 2 KeyValuePair constructors nodig. Maar omdat we altijd meerdere motoren gaan moeten aansturen steken we al deze KeyValuePair’s in een list van KeyValuePair’s. List
> Parameters = new List>();
Dit is dan de lijst waaraan we de verschillende waarden aan gaan toevoegen. Dus moeten er nieuwe KeyValuePair’s aangemaakt worden. KeyValuePair<string, string> Motor1 = new KeyValuePair<string, string>("motor1", numberFirstMotor.ToString()); KeyValuePair<string, string> Position1 = new KeyValuePair<string, string>("position1", FirstTB.Text); KeyValuePair<string, string> Motor2 = new KeyValuePair<string, string>("motor2", numberSecondMotor.ToString()); KeyValuePair<string, string> Position2 = new KeyValuePair<string, string>("position2", SecondTB.Text); KeyValuePair<string, string> Motor3 = new KeyValuePair<string, string>("motor3", numberThirdMotor.ToString()); KeyValuePair<string, string> Position3 = new KeyValuePair<string, string>("position3", ThirdTB.Text); KeyValuePair<string, string> Motor4 = new KeyValuePair<string, string>("motor4", numberFourthMotor.ToString()); KeyValuePair<string, string> Position4 = new KeyValuePair<string, string>("position4", FourthTB.Text); Parameters.Add(Motor1); Parameters.Add(Position1); Parameters.Add(Motor2); Parameters.Add(Position2); Parameters.Add(Motor3); Parameters.Add(Position3); Parameters.Add(Motor4); Parameters.Add(Position4); MoreWriteFunction(Parameters);
Bovenstaande code vertelt ons dat er 4 motoren aangestuurd moeten worden met hun bepaalde waarde. Al deze waarden worden dan toegevoegd aan de lijst die we makkelijk kunnen meegeven naar de Write functie. De Values die achter de Keys staan zijn de waarden die uit de textboxen en de comboboxen komen. Op het einde van deze
11
code zien we dat de Lijst van parameters wordt meegegeven bij het aanroepen van de schrijf-functie. Dat was nu het voorbeeld van wanneer manueel alles is ingevoerd in de comboboxen en in de textboxen. Nu kunnen we kijken naar het voorbeeld van de Gesture knoppen.
Dit zijn 8 verschillende knoppen. 8 knoppen omdat er afgesproken is dat we met 8 gestures gingen werken dus is er voor elke gesture een bepaalde knop voorzien, maar ook voor elke knop is er een bepaalde beweging voorzien van de Robot arm. Voor 8 bewegingen hebben we dus twee start en twee eindposities. Dit omdat we ook de voorwerpen op elke positie willen kunnen plaatsen.
12
private void TakeStartPositionB(object sender, EventArgs e) { List> Parameters = new List> (); Parameters.Add(new KeyValuePair<string, string>("Motor", "1")); Parameters.Add(new KeyValuePair<string, string>("MotorValue", "40")); Parameters.Add(new KeyValuePair<string, string>("COM", compoort)); Driver.MotorDriver.SetParameterList(Parameters); Driver.MotorDriver.RunCommand("SwipeRight"); Thread.Sleep(2000); Parameters.Add(new KeyValuePair<string, string>("Motor", "2")); Parameters.Add(new KeyValuePair<string, string>("MotorValue", "122")); Parameters.Add(new KeyValuePair<string, string>("Motor", "3")); Parameters.Add(new KeyValuePair<string, string>("MotorValue", "130")); Parameters.Add(new KeyValuePair<string, string>("COM", compoort)); Driver.MotorDriver.SetParameterList(Parameters); Driver.MotorDriver.RunCommand("SwipeRight"); Thread.Sleep(2000); Parameters.Add(new KeyValuePair<string, string>("Motor", "4")); Parameters.Add(new KeyValuePair<string, string>("MotorValue", "30")); Parameters.Add(new KeyValuePair<string, string>("Motor", "5")); Parameters.Add(new KeyValuePair<string, string>("MotorValue", "66")); Parameters.Add(new KeyValuePair<string, string>("COM", compoort)); Driver.MotorDriver.SetParameterList(Parameters); Driver.MotorDriver.RunCommand("SwipeRight"); Thread.Sleep(2000); Parameters.Add(new KeyValuePair<string, string>("Motor", "6")); Parameters.Add(new KeyValuePair<string, string>("MotorValue", "15")); Parameters.Add(new KeyValuePair<string, string>("COM", compoort)); Driver.MotorDriver.SetParameterList(Parameters); Driver.MotorDriver.RunCommand("SwipeRight"); Thread.Sleep(2000); Parameters.Add(new KeyValuePair<string, string>("Motor", "2")); Parameters.Add(new KeyValuePair<string, string>("MotorValue", "100")); Parameters.Add(new KeyValuePair<string, string>("Motor", "3")); Parameters.Add(new KeyValuePair<string, string>("MotorValue", "100")); Parameters.Add(new KeyValuePair<string, string>("COM", compoort)); Driver.MotorDriver.SetParameterList(Parameters); Driver.MotorDriver.RunCommand("SwipeRight"); Thread.Sleep(2000); }
De bovenstaande code is de code achter de knop ‘Take Start Position B’ . Achter deze knop zit dus de beweging die de robot arm naar de B positie zal leiden om daar een voorwerp te gaan opnemen. Eerst en vooral wordt er in deze methode een lijst aangemaakt die we aan het einde gaan meesturen naar de Driver maar waar eerst alle juiste waarden aan toegevoegd moeten worden. Voor de eerste Thread.sleep wordt de ArmTurn motor gedraait naar zijn positie. Dit omdat deze lijst dan naar de driver gestuurd wordt, en via SetParameterList worden de waarde daar omgezet in een nieuwe lijst en kan via het commando de functie uitgevoerd worden. Maar dit wordt later in de Driver Template beter uitgelegd. Dus nadat deze beweging is uitgevoerd wordt er 2000 miliseconden gewacht dus wat werkelijk twee seconden is. Nadat er gewacht is geweest kan de volgende beweging van start gaan. Hierbij wordt 13
dan de robot arm naar voor gezet, nadat opnieuw gewacht is wordt de robot arm zijn grijper naar beneden geplaatst om zo naar het voorwerp te gaan en wordt er weer even gewacht tot deze beweging gedaan is. Hierna wordt dan de grijper gesloten en zal op het einde de arm terug een klein beetje omhoog gaan. Dit om het feit voor het verduidelijken voor de kijkers dat deze reeks van bewegingen, dus eigenlijk alles achter de Gestures voor ‘Take Start Position B’ afgerond is.
Driver template Eerst en vooral is er gewerkt met een driver template die met de winform gekoppeld is. De driver template zal gebruikt worden als omzetting van de gestures naar de Arduino code, dus eigenlijk zullen hier de nodige omzettingen gedaan worden om juist weg te schrijven naar de Arduino code. Dus als er nu naar de code gekeken wordt kan er gezien worden dat er voor elke methode, een aparte klasse is gemaakt. Deze klassen moeten eerst en vooral toegevoegd worden aan de Commando-list. Deze lijst moet dan uiteindelijk alle verschillende commando’s bevatten die er uiteindelijk uitgevoerd kunnen worden. Als we deze lijst eens gaan bekijken zien we dit. public static List> RegisterCommands() { List> commandList = new List>(); commandList.Add(new KeyValuePair<string, Command>("StartPosition", new StartPosition())); commandList.Add(new KeyValuePair<string, Command>("ArmTurn", new ArmTurn())); commandList.Add(new KeyValuePair<string, Command>("Shoulder", new Shoulder())); commandList.Add(new KeyValuePair<string, Command>("Elbow", new Elbow())); commandList.Add(new KeyValuePair<string, Command>("Wrist", new Wrist())); commandList.Add(new KeyValuePair<string, Command>("Twist", new Twist())); commandList.Add(new KeyValuePair<string, Command>("Grab", new Grab())); commandList.Add(new KeyValuePair<string, Command>("SwipeLeft", new SwipeLeft())); commandList.Add(new KeyValuePair<string, Command>("SwipeRight",new SwipeRight())); commandList.Add(new KeyValuePair<string, Command>("SwipeUp" , new SwipeUp())); commandList.Add(new KeyValuePair<string, Command>("SwipeDown", new SwipeDown())); commandList.Add(new KeyValuePair<string, Command>("RaiseLeftHand", new RaiseLeftHand())); commandList.Add(new KeyValuePair<string, Command>("RaiseRightHand", new RaiseRightHand())); commandList.Add(new KeyValuePair<string, Command>("Tpose", new Tpose())); commandList.Add(new KeyValuePair<string, Command>("Psi", new Psi())); return commandList; }
Eerst en vooral wordt er dus een Command list aangemaakt. Er is te zien dat deze methode een List-methode is genaamd RegisterCommands. Deze bepaalde lijst bevat een KeyValuePair van een string en een commando. Met deze string wordt dan bedoelt, de bepaalde string die aangeroepen moet worden vanuit de Winforms of elders. En met de commando wordt dan bedoelt de commando die de Driver zal moeten uitvoeren. voor elk commando zal er een nieuwe klasse aangemaakt moeten worden maar dit wordt later uitgelegd. Dus er wordt dan een lijst aangemaakt van commando’s waarbij er commandlist.add bij moet gedaan worden omdat er commando’s moeten worden toegevoegd. Bij elke toegevoegd commando wordt er dan de naam geschreven die moet worden aangeroepen, en erna wordt dan de naam van die bepaalde klasse meegegeven. Eerst zien we de 6 commando’s voor de 6 verschillende motoren appart en erna zien we dan de bepaalde gestures die Tim in zijn project uitgezocht heeft. Deze gestures kunnen worden gedetecteerd door de Kinect. 14
Als er dan naar die commando’s hun klasse gaan kijken krijgen we het volgende.
class Shoulder : Command {
public override List>
Run(List> parameters) { SerialPort Poort = new SerialPort(); Poort.BaudRate = 9600; //Poort.PortName = "COM4"; Poort.StopBits = StopBits.One; Poort.ReadBufferSize = 4096; Poort.WriteBufferSize = 2048; string MotorValue = ""; foreach (var par in parameters) { if (par.Key == "MotorValue") { MotorValue = par.Value; } else if (par.Key == "COM") { Poort.PortName = par.Value;
}
} Poort.Open(); Poort.Write(MotorValue + ",2 "); Poort.Close(); }
}
Deze klasse erft over van de Command klasse. Deze klasse is een abstracte klasse die in de code-behind staat en die een list bevat, genaamd Run die een andere list meekrijgt op zijn beurt genaamd parameters. Deze lijst wordt dan override om er nieuwe dingen aan toe te voegen. Als we de bepaalde commando’s willen aanroepen vanuit de Winforms dan moeten we allereerst alle paramters in een lijst steken zoals eerder verteld, maar dan moet die lijst ook meegegeven worden in de SetParameter list van de Driver. Dit omdat dan alle waarden ook in een lijst in de Driver worden gestoken. Deze is dan de methode die dit in de core code van de Driver zal doen. Het zal de Parameter lijst die meegegeven wordt uitlezen en in de nieuwe lijst alles aan toevoegen. Zodat we er in de Driver ook mee kunnen werken. Daarna worden de instellingen gedaan voor de Seriele poort waarover geschreven wordt. Deze instelling moeten telkens gedaan worden vooraleer de poort open wordt gezet om te kunnen schrijven. De poort naam staat hier in commentaar. Dit met als reden dat op elke laptop/pc, als je de Arduino insteekt, de poort anders zal zijn. De compoort naam kan dan meegegeven worden in de Winforms samen met de motoren en de motorwaarden zoals eerder uitgelegd. Dit omdat we in de Driver nooit meer aanpassingen hoeven te doen als deze volledig op punt is. De bedoeling van de Driver is dat deze op de achtergrond in werking treed en dat we deze eigenlijk niet meer moeten open doen tenzij er ergens iets moet verandert worden. Nadat de instellingen voor de compoort gedaan zijn kunnen we verder gaan in de code. De foreach staat er om de hele lijst te overlopen. Want omdat er geweten is dat er altijd meerdere waarden in gaan zitten zoals eerder vermeld, dat de lijst wordt aangevuld met verschillende parameters van de motoren en de motorwaarden. In deze foreach wordt dan nagekeken of het een motorwaarde is en zal de KeyValue hier dan van opslaan. Als deze waarde opgeslagen is zal er gekeken worden welke compoort er ingesteld is. En tot slot kan de opgeslagen waarde van die bepaalde motor dan via Poort.Write geschreven worden naar de Arduino. Dit was nu een voorbeeld voor 1 bepaalde motor aan te sturen. Stel we willen nu zien wat de gestures doen want deze gestures moeten meerdere motoren aansturen.
15
class SwipeRight : Command { public override List> Run(List> parameters) { SerialPort Poort = new SerialPort(); Poort.BaudRate = 9600; // Poort.PortName = "COM4"; Poort.StopBits = StopBits.One; Poort.ReadBufferSize = 4096; Poort.WriteBufferSize = 2048; List<string> Motors = new List<string>(); List<string> Values = new List<string>(); foreach (var par in parameters) {
if (par.Key == "MotorValue") {
Values.Add(par.Value);
}
else if (par.Key == "Motor") { Motors.Add(par.Value);
}
else if (par.Key == "COM") {
Poort.PortName = par.Value;
}
} Poort.Open();
De bovenstaande code is juist hetzelfde dan als we 1 motor willen aansturen. Als enige verandering is het duidelijk te zien nu dat er een extra lijst is aangemaakt voor de verschillende motoren en de verschillende motorwaarden. for (int i = 0; i < Motors.Count; i++) {
if (Motors[i] == "1") {
Poort.Write(Values[i] + ",1 \n"); }
else if (Motors[i] == "2") {
Poort.Write(Values[i] + ",2 \n"); }
else if (Motors[i] == "3") {
Poort.Write(Values[i] + ",3 \n"); }
else if (Motors[i] == "4") { Poort.Write(Values[i] + ",4 \n"); } else if (Motors[i] == "5") {
Poort.Write(Values[i] + ",5 \n"); }
else if (Motors[i] == "6") { Poort.Write(Values[i] + ",6 \n"); } } Poort.Close();
Maar bij deze klasse worden er nadat de Poort open wordt gezet, komt er nog een for loop die de hele opgeslagen lijst zal doorlopen met de verschillende motoren. En dan afhankelijk welke motor erin staat in de lijst zal deze de juiste waarde schrijven naar de Arduino. Merk ook op dat er een ‘\n’ op het einde van elke Write functie geschreven wordt. Dit was een oplossing voor het probleem dat bij het schrijven van meerdere waarden tegelijk dat het algorithme niet alles in de juiste volgorde ontving waardoor er soms rare toestanden gebeurde met de robot arm. Bij nader inzien leek dit de goede oplossinge te zijn, want als we met de Arduino IDE gaan testen kunnen we ook waarden gaan ingeven in het console venster maar dan drukken we ook steeds op enter als we een waarde hebben ingegeven. En aangezien het algorithme ook de enters zal lezen is er tot deze oplossing gekomen.
16
Op het einde zijn we tot de conclusie gekomen dat er eigenlijk maar 1 nieuwe klasse aangemaakt moet worden voor alle gestures. Dit omdat er bij elke klasse hetzelfde kan gedaan worden en dat is gewoon het inlezen van de parameters die in de lijst zijn meegegeven. Dus bij deze kan deze ene klasse voor elke gesture gebruikt worden en wordt ook de Command list veel kleiner die aan het begin van de Driver staat.
17
Keuze Hardware Robot Arm Inleiding We hadden het idee om met een robot arm te werken, dus moesten we op zoek naar een voordelige robot arm die zowel goed was om ermee te werken als prijs/kwaliteit ook zeer goed was. Dus we hadden al snel een lijstje samengesteld met de drie mogelijke robot armen.
Keuzes Arm 1. Velleman KSR10 ? 60 euro Link; http://www.conrad.be/ce/nl/product/079655/Velleman-KSR10-Robotarm-bouwpakket? ref=searchDetail Specificaties; Max. hefvermogen: 100 g Max. reikhoogte bij volledig gestrekte arm: 38 cm. Arm hoogte: Max. 38 cm Draagkracht: Max. 100 g Beschrijving; Maak kennis met de wereld van de robotica met deze robotarm met vijf motors en vijf gewrichten. De arm wordt aangestuurd met een bedieningspaneel met vijf knoppen en bestaat uit een draaiende sokkel, een scharnierende elle boog en pols en een functionele hand. De praktische projector maakt gebruik in het donker mogelijk 2. Arexx RA2-CH2 robotarm ? 99 euro Link; http://www.conrad.be/ce/nl/product/1395728/Arexx-RA2-CH2-RA2-CH2-robotarm-bouwpakket? ref=searchDetail Specificaties; Plastic mini robotarm Metalen onderstel 6 servomotoren Zonder besturingselektronica Hefcapaciteit: ongeveer 80 gram Beschrijving; Deze robotarm mechanica kit is perfect geschikt voor zowel beginners als hobbyisten, maar ook voor studenten en schoolprojecten. Deze kit is ideaal om uw eigen elektronica bv ARDUINO Shields uw eigen robotarm te bouwen. De robotarm vormt een mechanisch complete eenheid met plastic arm, metalen basis en 6 servomotoren. 3. Robotic arm with 7 servos ? 40 euro voor Servo’s plus kosten van laseren nog {wachten op prijs, een mail gestuurd naar een laser print bedrijf met de vraag voor prijzen maar de prijs was afhankelijk van het project en het materiaal dat er gewenst wordt } Link; http://www.thingiverse.com/thing:2433 Specificaties; Beschrijving; Zelf laten laseren Aankopen van Servo’s Aankopen aansturing motoren
18
Conclusie; We kwamen met overleg tot de conclusie dat voor ons de tweede keuze de beste is aangezien deze kop afzonderlijk ook kan draaien. De laatste keuze neemt redelijk veel tijd in omdat alles apart besteld moet worden en ook de arm zelf moet gelaserd worden. En ook de prijs was afhankelijk van het materiaal dat we dan zouden nemen en ook de grootte van het project. Het zou natuurlijk veel mooier en cooler ogen moesten we alles zelf kunnen maken maar helaas is dit niet altijd mogelijk. Nu zitten we een beetje vast aan de vorm en de maten van een voorgemaakte arm. Maar prijs/kwaliteit zitten we zeker goed met de Arexx RA2-CH2 robotarm.
Start building Voor de robot arm in elkaar te steken zat er een gids bij. Dus ben ik deze gaan volgen om de Arm correct in elkaar te steken. Zodat ik er zeker van was dat de juiste vijzen op de juiste plaats zitten als ook de juiste Servo’s op de juiste plaats.
Aansluiting Nergens in de manual stond beschreven wat de juiste aansluiting is voor de Servo motoren. Er moeten 3 kabeltjes aangesloten worden maar welke is juist wat. In verschillende voorbeelden online wordt er dan gebruikt gemaakt van de aansluiting links rechts en ground maar ook wordt er gebruikt gemaakt van de aansluiting 5volt ground en data. Ik heb ze uiteraard allebei getest. Maar aangezien we een Arduino als microcontroller gebruiken kunnen we gebruik maken van de Servo library van Arduino zelf. Bij deze maakt het ons gemakkelijker om de Servo’s aan te sturen. In die library staat beschreven hoe we ze juist moeten aansturen. Dit is dus de 5volt, ground en Data methode. Dit wetende kunnen we ook 4 motoren aansluiten op 1 L293D chip. Normaal gezien maar 2, maar door deze methode te gebruiken moet er gewoon meegeven worden op welke graden de Servo moeten komen te staan dus we hoeven een waarde tussen 0-180 meegeven. En niet dat de motor links of rechts moet kunnen gaan. Vandaar kunnen we er 4 aansluiten op 1 chip.
Aansturing motoren Aansturing van de motoren zal gebeuren via H-bruggen. De H-bruggen die in dit project gebruikt werden zijn L293D chips. Die bevatten 2 complete H-bruggen die een motor zowel links als rechts kunnen laten draaien. Maar in dit geval zullen we geen motoren links of rechts laten draaien maar hebben we enkel 1 output nodig per servo motor.
H-brug Zelf de simpelste robot heeft een motor nodig om een wieltje te kunnen draaien of om een bepaalde beweging uit te voeren. De motoren hebben meer stroom nodig dan de meeste microcontroller pinnen kunne leveren. Daarom hebben we een soort van schakelaar nodig die een kleine stroom kan ontvangen om vervolgens deze te versterken en uiteindelijk een grootte stroom te leveren die de motor zal nodig hebben om te kunnen werken. Dit hele proces kan gedaan worden door wat ze noemen een Motor Driver. Motor drivers zijn meestal stroom versterkende IC’s die een laag stroom signaal kunnen ontvangen van de bepaalde microcontroller en vervolgens een grotere stroom uitleveren voor de motor. In de meeste gevallen, zal een transistor gebruikt worden als schakelaar en tegelijk de stroom versterken om de motor aan of uit te kunnen schakelen. Maar de transistoren zitten dan verwerkt in de IC. Het aan en/of uit schakelen van een motor heeft enkel 1 schakelaar nodig om de motor te bedienen in 1 richting. Wanneer we nu de motor in de andere richting willen laten draaien kunnen we gewoon de polariteit van de motor omdraaien. Deze oplossing kan gemaakt worden met een opstelling van vier schakelaars. De schakelaars worden dan zo opgesteld dat het de motor kan sturen maar ook dat het ook de motor in de twee richtingen kan laten werken. Een van de meest gebruikte opstellingen is de H-bridge opstelling waarbij transistoren opgesteld zijn in de vorm van de letter ‘H’ .
19
Zoals we kunnen zien op de bovenstaande figuur, de schakeling heeft dus de opstelling van de vier schakelaars. Het schakelen van deze schakelaars kan de motor schakelen in beide richtingen. 1. Het schakelen van schakelaar A en D zal de motor met de klok mee laten draaien. 2. Het schakelen van schakelaar B en C zal de motor tegen de klok in laten draaien. 3. Het schakelen van schakelaar A en B zal de motor doen remmen (stoppen) 4. Het uit schakelen van alle schakelaars zal de motor een vrije loop geven 5. Het schakelen van A en C tegelijk of B en D tegelijk zal kortsluiting geven dus is deze modus niet aangeraden. De H-brug kan gebouwd worden uit verschillende materialen, gebruik makend van relays, mosfets, Field effect transistor (FET), bi-polar junction transistoren (BJT), etc. Maar als de nodige stroom niet te hoog is, kunnen we al genoegen nemen met de L293D IC. Deze kleine IC kan niet een maar twee motoren bedienen.
L293D L293D IC is in de meeste gevallen een standaard 16-pin DIP (dual-in line package). Deze motordriver IC kan twee kleine motoren gelijktijdig in elke richting bedienen. En dit allemaal met enkel 4 microcontroller pins (als er geen gebruik gemaakt wordt van de enable pinnen). De output stroom is gelimiteerd tot 600mA per kanaal met piek stromen die gelimiteerd zijn tot 1.2A. dit betekent dat de motoren die stroom tot 600mA nodig hebben, kunnen gebruikt worden. Alhoewel dat de meeste motoren in de hobby robotics zullen werken aangezien dit meestal kleinere projecten zijn. Net zoals het project waaraan ik heb gewerkt. De voedingsspanning kan oplopen tot en met 36V. dit betekent dat er geen rekening moet gehouden worden met de spanningsregeling. L293D heeft een enable functie wat erbij kan helpen dat je de output pinnen aan of uit kan zetten. Als de enable pinnen een logische ‘1’ hebben, dan zal de stand aan de ingang de stand zijn van de uitgang. Als de enable pin naar een logische ‘0’ wordt gezet zal de output uit gaan onafhankelijk van de ingangs stand. De datasheet van de L293D chip verteld ons ook dat er een temperatuur protection aanwezig is. Dit wil zeggen dat een interne sensor de temperatuur van de IC zal meten en dat deze de IC zal uitschakelen wanneer een bepaalde temperatuur wordt bereikt. De L293D IC heeft een terugkoppeldiode die de transistoren tegen piekspanningen zal beschermen wanneer de motorspoel afstaat. De logische stand ‘0’ is in de IC ingesteld op 1,5V. Dus als we de pin op ‘1’ willen zetten moeten we een spannning aanbrengen die hoger is dan de 1,5V.
20
L293D connections Op de volgende figuur is de meest basis voorstelling van de L293D IC. Elke pin heeft zijn eigen betekenis.
1. Pin 1 en Pin 9 zijn ‘Enable’ pins, ze zouden verbonden moeten zijn met +5V voor de werking van de motoren. Wanneer deze met de ground (low) worden verboden dan zullen de uitgangen uitgeschakeld zijn onafhankelijk van de ingangen. 2. Pin 4, Pin 5, Pin 12 en Pin 13 zijn ground pinnen. Deze pinnen moeten logischer wijze met de ground van de microcontroller verbonden worden voor de juiste werking van de IC. 3. Pin 2, Pin 7, Pin 10 en Pin 15 zijn ingangen. Deze moeten verbonden worden met de microcontroller. Pin 2 en Pin 7 bedienen de eerste motor, Pin 10 en Pin 15 bedienen de tweede motor. 4. Pin 3, Pin 6, Pin 11 en Pin 14 zijn uitgangen. Deze pinnen moeten met de motoren verbonden worden. Pin 3 en Pin 6 zijn de pinnen die verbonden zijn met de ingang aan Pin 2 en Pin 7, Pin 11 en Pin 14 uiteraard dan met de andere 2 ingangen. 5. Pin 16 is de voeding van de IC en zou met +5V verbonden moeten zijn om te kunnen werken. 6. Pin 8 powers de twee motoren en zal verbonden moeten zijn met de positieve pin van een extra batterij. Zoals eerder vermeld kan deze spanning oplopen tot 36V.
21
Waarheidstabel Pin 1
Pin 2
Pin 7
Function
High
High
Low
Draait tegen de klok in (Reverse)
High
Low
High
Draait met de klok mee (Forward)
High
High
High
Stop
High
Low
Low
Stop
Low
x
x
Stop
High = ~+5V Low = ~0V X= ofwel high ofwel low dit maakt niet uit.
Microcontroller Als microcontroller maken we gebruik van de Arduino. Via de Arduino kunnen we dan via de L293D de servo motoren aansturen. In de Microcontroller (Arduino) zit standaard een library voor servo-motoren. Dit maakt het gemakkelijker aangezien we gewoon een servo object moeten aanmaken en dan zeggen, Servo.Write(50);. Met de 50 is de waarde die de servo motor moet hebben. Dus als we hem naar 90 graden willen zeggen we gewoon Servo.Write(90);.
Servomotoren Wat is een servomotor Een servomotor is een motor die deel uitmaakt van een servosysteem. Het woord servo komt van het Latijnse ‘servus’ wat slaaf betekend. Dit verwijst naar het opvolgen van een opgegeven taak. Een servomotor wordt gebruikt om in mechanische systemen, door middel van een draaibeweging, een zeer precieze regeling te krijgen van de hoekpositie. Servosystemen noemt men soms ook volgsystemen omdat een bepaalde grootheid altijd een andere grootheid volgt in waarde.
Opbouw van de servomotor
22
De servomotor bestaat uit deze onderdelen: 1. DC-motor; 2. Tandwielen en as; 3. Potentiometer: positioneringsensor; 4. Regelcircuit. De rode draad is de-plus klem van de voeding. De zwarte draad is de massa. De gele (of witte) draad is de stuurlijn. Een servomotor bestaat uit een motor die gekoppeld is aan een potentiometer (sensor) om een terugkoppeling (feedback) te krijgen over de huidige positie van de motor. Dit gebeurd via tandwielen die zorgen voor reductie.
Werking van een servomotor servosysteem Een servosysteem werkt via het concept van terugkoppeling uit de regeltechniek. De uitgang van dit systeem is een functie van het verschil tussen de gewenste waarde en de proceswaarde (gemeten stand) op een zodanige manier dat de fout of de afwijking bijgewerkt wordt. Met andere woorden, een servosysteem is een geautomatiseerd systeem dat door middel van foutdetectie negatief teruggekoppeld wordt, om de werking van het systeem bij te sturen.
Bij de servomotor wordt de hoekstand van de as (huidige positie van de motor) teruggekoppeld om de beweging en eindstand van de as (eindpositie van de motor) te regelen.
Principewerking Het systeem om de huidige hoekstand van de as te bepalen noemt men de encoder. De encoder zet gegevens, zoals bij de servomotor: de hoekstand van de as (positie van de motor), om in een signaal. De potentiometer (encoder) is gekoppeld aan de motor. De encoder genereert een signaal aan de hand van de positie van de motor. Dit signaal (proceswaarde of het teruggekoppeld signaal) wordt teruggekoppeld en vergeleken met de gevraagde positie van de motor (gewenste waarde of het gestuurde signaal). Als de huidige stand van de motor niet overeen komt met de gevraagde positie van de motor, zal er een correctiesignaal naar de motor worden gestuurd om deze naar de juiste richting te laten draaien tot de afwijking is weggewerkt. Wanneer er geen verschil is tussen de gewenste waarde en de proceswaarde, zal het correctiesignaal nul zijn en zal de motor stoppen met draaien.
Optische encoders De encoder kan een potentiometer zijn die gekoppeld is aan een motor of een optische encoder. De optische encoder bepaalt de positie van de motor door middel van een encoderschijf. Een encoderschijf is een schijf met gaatjes in. Loodrecht op de encoderschijf wordt een lichtbundel geschenen met daarachter een lichtdetector. Telkens wanneer er een gaatje de lichtbundel passeert, krijgt de lichtdetector een lichtpuls en zo ziet men hoever de schijf gedraaid is.
23
Toepassing Servomotoren worden zeer veel gebruikt in de automatisering en robotica omdat de hoekstand van de as zeer nauwkeurig geregeld kan worden.
Sturen van een servomotor PWM Pulse Width Modulation of kortweg PWM is een modulatietechniek waarbij informatie omgezet wordt naar een puls met een bepaalde breedte. De duty cycle of relatieve inschakeltijd (tijd dat de puls hoog is ten opzichte van de totale lengte van de puls) geeft de waarde van de informatie weer. De duty cycle wordt berekend met de formule: d = thoog / T d = duty cycle; thoog = de tijd dat de puls hoog is; T = de periode Het voornaamste doel van PWM is het controleren van het geleverde vermogen aan elektrische apparaten. PWM wordt bijvoorbeeld gebruikt bij het regelen van de helderheid van een LED. Wanneer de puls hoog is, brandt de LED met een vermogen van U x I . Als de puls laag is, brandt de LED niet en het vermogen is nul. Dus de LED krijgt maar een deel van het vermogen over de periode. Het gemiddelde vermogen zal dan kleiner zijn dan het vermogen wanneer de puls hoog is. Hierdoor kan men dus de helderheid van een LED regelen.
PWM als sturing van een servomotor De sturing van een servomotor berust ook op het principe van PWM maar dit werkt net iets anders. Bij de servomotor bepaalt niet de duty cycle de hoek die ingesteld wordt maar enkel de tijd dat de puls hoog is. Om de 20ms (50Hz) wordt er een puls naar de servomotor gestuurd. De lengte van de puls gaat de hoekstand van de as bepalen.
24
Wanneer de lengte van de puls gelijk is aan 1.5ms, zal de motor de hoekstand van de as naar 90° brengen (middenpositie). 90° is de neutrale stand (middenpositie) van de servomotor. Als de lengte van de puls minder is dan 1.5ms, dan zal hoekstand kleiner zijn dan 90° . Wanneer de lengte van de puls groter is dan 1.5ms, dan zal de hoekstand groter zijn dan 90° . Bij sommige servomotoren blijft de motor naar links draaien als de lengte van de puls kleiner is dan een bepaalde waarde, en de motor blijft naar rechts draaien wanneer de lengte van de puls groter is dan een bepaalde waarde. Deze waarden kunnen varieren afhankelijk van het type motor of fabrikant.
Servomotoren tegenover een stappenmotor De positie van een stappenmotor wordt geregeld door het draaien van een aantal stappen in een bepaalde richting. In tegenstelling tot de servomotor heeft de stappenmotor geen terugkoppeling over de bereikte positie. Aldus wordt de motor niet bijgestuurd wanneer deze niet in de juiste positie geraakt. Stel dat de stappenmotor een iets te zware last moet aansturen, dan is het mogelijk dat de motor een paar keer doorspint waardoor er een paar stappen niet uitgevoerd worden. Door het ontbreken van de terugkoppeling staat de motor op het einde van zijn beweging niet in de juiste positie en wordt dit niet gecorrigeerd.
Gebruikte servomotoren Het type servomotor dat in dit project gebruikt wordt zijn de motoren die bij de Arrex robot arm meegeleverd werden. Dit zijn namelijk 4 mini DGservo 12g en 2 maxi DGservo S07NF STD. Specificaties; Gewicht : 56g. Speed : 6V ; 0.18/60° ...: 7v ; 0.16/60° Torque : 6V ; 16 kg-cm ... : 7V ; 13.5 kg-cm
25
Led matrix Onderdelen LED Een led is letterlijk vertaald een diode die licht geeft. Een led kan alleen maar branden als er de juiste spanning over staat. Met andere woorden als de diode in doorlaat staat dan zal de led branden. Een led heeft een kort en een lang pinnetje. De lange pin is de anode of de plus. De plus moet, de drempelspanning, groter zijn dan de min-klem om te branden. De min-klem of de kathode is de korte pin. Soorten Leds Er zijn verschillende soorten leds. Door de samenstelling van de halfgeleider aan te passen kunnen we verschillende kleuren verkrijgen. Halfgeleider materiaal
Kleur
Gallium-aluminiumarsenide (AlGaAs)
Rood, infrarood
Aluminiumindiumgalliumfosfide (AllnGaP2)
Diep rood, Rood, Rood-oranje, Amber
Galliumarseenfosfide (GaAsP)
Rood, Oranje, Geel
Galliumnitride (GaN)
Groen
Galliumfosfide (GaP)
Groen
Zinkselenide (ZnSe)
Blauw
Siliciumcarbide (SiC)
Blauw
Indiumgalliumnitride (InGaN)
Groen, Blauw, Ultra-violet
Diamant (C)
Ultraviolet
Eenkleurige leds We hebben leds die maar een enkele kleur kunnen produceren. Dit noemen we monochromatische leds. We kunnen deze leds overal gebruiken. Zowel in mijn eindwerk als in andere schakelingen. Deze leds worden het meeste gebruikt. Meerkleurige leds Dit zijn leds die meerdere kleuren kunnen geven. Meestal worden ze RGB-leds genoemd ofwel trichromatische leds. De drie hoofdkleuren zijn rood, groen en blauw. Deze bevinden zich allemaal in een behuizing. Door bij elke kleur de lichtintensiteit afzonderlijk af te regelen krijgen we de gewenste kleuren. Deze leds worden meestal gebruikt voor sfeerverlichting. Drempelspanningen De drempelspanning is de spanning waarbij een led maximaal brandt. De drempelspanning verschilt van kleur tot kleur. Zo zien we dat wit de hoogste spanning nodig heeft om maximaal te gaan branden.
26
Berekenen van de voorschakelweerstand De voorschakelweerstand dient om de stroom door de led voldoende klein te houden waardoor de levensduur van de led veel groter wordt. Want als de stroom te klein is, gaat de led zwakker branden. Er moet dus balans gezocht worden tussen een lange levensduur en voldoende licht. We nemen nu bijvoorbeeld de rode led. Dit omdat deze ook in mijn eindwerk aanwezig is. Deze heeft een drempelspanning van 1,6 volt. De bronspanning van de mijn eindwerk bedraagt 5 volt. De spanning over deze weerstand berekenen we door de drempelspanning af te trekken van de ingangsspanning. Ur = Uin - Udrempel Ur = 5V - 1,6V = 3,4V De stroom door de weerstand is gelijk aan de stroom door de led (20mA). R = U/I R = 3,4V/20mA = 170ohm Ik heb 150ohm genomen omdat dit de dichtstbijzijnde waarde is tegen 170ohm. 180ohm ligt natuurlijk dichter bij 170 maar we gebruiken 150ohm omdat er nog een spanning over de darlington-schakeling in de ULN2003 staat.
ULN2003A De ULN2003 wordt gebruikt om de kolommen aan te sturen. In de ULN2003 zitten zeven darlingtontransistoren met gemeenschappelijke emitters. De ULN2003 werkt inverterend omdat de schakeling zo is opgebouwd, en enkel en alleen als de rij 5V krijgt. Deze ULN’s zijn nuttig voor het besturen van een brede waaier van ladingen, waaronder elektromagneten, relais DC-motoren, leddisplays en een hoog vermogen buffers. Elke uitgang kan 500mA leveren en kan piekstromen weerstaan van 600mA. Darlington: De stroomversterkingsfactor β (hfe) van een darlingtontransistor is bij benadering het product van de stroomversterkingsfactoren van de twee afzonderlijke transistoren, zodat een darlington een zeer grote stroomversterkingsfactor heeft. Soms is het nodig om met een kleine stroom een veel grotere stroom te sturen.
27
Laagvermogentransistoren hebben een grote versterkingsfactor, maar kunnen geen grote stroom sturen. Hoogvermogentransistoren hebben doorgaans een lage stroomversterkingsfactor, en moeten dientengevolge met een niet al te kleine stroom aangestuurd worden. Door twee zulke transistoren in een schakeling te gebruiken, kunnen beide kenmerken samengevoegd worden en daarmee de goede eigenschappen gecombineerd. De gemeenschappelijke behuizing bespaart bovendien ruimte. De stroom door de collector van een transistor is β (hFE) keer groter dan de stroom door de basis, de emitterstroom is nagenoeg even groot als de collectorstroom. Stel dat beide transistoren een hFE hebben van 200 en 100. Dit wil zeggen dat de basisstroom van de tweede transistor 100 keer kleiner is dan collectorstroom van deze transistor. Deze basisstroom is ook de emitterstroom van de eerste transistor, dus ook nagenoeg gelijk aan de collectorstroom van de eerste transistor. De basisstroom van de eerste transistor is dus 200 keer kleiner dan deze stroom. De basisstroom van de eerste transistor is dus 20.000 keer kleiner dan de collectorstroom van de tweede transistor. IC is ongeveer IE IE2 = IE1 hFE = IB2 hFE IB1 = IE1/hFE IB2 = IB1 * hFE = IE1
28
Zoals je kan zien op in de onderstaande figuur werkt de Darlington dus inverterend in deze schakeling (wanneer de rij actief is). Wanneer aan de ingang van de Darlington 5V geplaatst word zakt de uitgang van de Darlington (uitlezing multimeter) bijna naar 0V. Zoals je kan zien aan de kleuren van de pijltjes brandt de LED alleen maar wanneer er zowel op rij en kolom een logische 1 geplaatst wordt (5V).
Wanneer de ingang van de Darlington in dit geval 0V is, wordt de uitgang nagenoeg 5V. De led is gedoofd omdat er geen spanningsval aanwezig is om de led te doen branden. Aan de anode staat 5V maar aan de kathode ook. Hier staat nu wel 4V. Dit is nooit exact 5V.
29
Op de onderstaande schakeling is ook weer te zien dat de led niet zal branden, dit omdat ook hier weer geen spanningsval aanwezig is. Er is nog mogelijkheid die er bestaat om aan te tonen dat de Darlington-schakeling inverterend werkt en dat is door bij elke bron 0V aan te sluiten. Hierbij zullen we dan zien dat er aan de anode van de led 0V staat en aan de kathode ongeveer 5V.
De weerstanden van 1k in deze simulaties dienen om de spanningen van de bronnen om te zetten naar de stroom die nodig is om in de basis van de eerste Darlington-transistor te vloeien (transistors werken met en versterken stromen, geen spanningen). Pinbezetting
30
Zoals eerder verteld zijn er zeven Darlington-schakelingen met elke een in- en uitgang. Aan elke component is een ‘ground’ massa en ook hier. Aan de ULN2003A is een speciale pin aanwezig. Deze noemt men de ‘Common Free Wheeling Diodes’. Een ‘vrijloopdiode’ of ‘Common Free Wheeling Diode’ is een circuit om de schakelinrichting te beschermen tegen beschadiging door de tegenstroom van inductieve belasting. Zonder de ‘vrijloopdiode’ kan de spanning zo hoog oplopen dat hij beschadigingen in de schakelinrichting kan veroorzaken.
PCB Voor de LED-matrix hebben we een PCB nodig om alles mooi naast elkaar te kunnen zetten. Dit gaat natuurlijk ook op andere manieren maar dan is dit zeker niet zo mooi als wanneer er een PCB wordt voorzien. Hierbij is er de hulp gekomen van mijn oude school. Ze hebben daar een CNC-machine voor PCB te printen. Dus mocht ik mijn bestanden doorsturen en is dit dan geprint. Het resultaat was zeer mooi zoals te zien op de onderstaande foto. Het is dus een koperen plaat met harde kunststof in tussenin. Dus technisch gezien zijn het 2 koperen platen met de harde kunststof er tussen. De banen en/of eilanden zijn van elkaar gescheiden doordat het koper op de juiste plaatsen is weg gefreesd. Doordat het kunststof geen geleidende stof is zullen de banen en/of eilanden van elkaar gescheiden zijn. Tussen de rijen en de kolommen zijn er ook Via’s voorzien. Een Via is simpelweg een gat doorheen de printplaat zoals de gaten die voorzien zijn voor de componenten door te steken. Maar bij een Via wordt dan gewoon aan de boven- en onderkant een eiland voorzien waarop we kunnen solderen. Dus het verbind de onder- met de bovenzijde. Er is wel nog steeds een draadje dat er doorheen moet gestoken worden om zo dan beide kanten te kunnen solderen en te voorzien van een goede verbinding tussen onder- en bovenzijde.
Vooraleer we deze mooie plaat kunnen verkrijgen moeten er eerst schema’s voorzien worden om dit te kunnen printen. Deze schema’s kunnen gemaakt worden, allereerst in Multisim om deze dan te transferen naar Ultiboard. Eerst en vooral moet er bekeken worden welke componenten die nodig zijn om de led-matrix werkend te krijgen en op een goeie manier rond elkaar gezet worden om zo weinig mogelijk gekruiste banen te verkrijgen later. Als componenten hebben we dus LEDs nodig met hun bijhorende voorschakelweerstanden, daarnaast ook
31
ULN2003A Darlingtontransistoren die de kolommen. Dus in multisim worden alle banen met elkaar verbonden zoals je dit zelf wil en zodat het uiteindelijk nodig is. Want deze ‘Nets’ worden ook de officiele banen op de printplaat. Hierbij moet er dus goed gekeken worden of alles juist verbonden is. Als er in de printplaat nu een foute baan zit dan moet heel het process herdaan worden, en moet er terug gestart worden vanuit Multisim.
Elke component moet zeker ook een footprint hebben om naar Ultiboard gelinkt te kunnen worden. Afhankelijk van de component zullen deze met een footprint meestal blauw worden. Maar connectoren daarentegen die zien altijd groen. Printontwerp (Ultiboard);
32
De bovenstaande foto vergeleken met de opstelling van op multisim lijkt volledig dezelfde. Dit omdat we weten dat er in multisim zo weinig mogelijk kruisingen waren met de banen dus word deze opstelling gewoon herhaald om het minst gekruiste banen te verkrijgen. Natuurlijk bij kleinere PCBs kan er zodanig voor gezorgd worden dat er weinig tot geen gekruiste verbindingen zijn waardoor er maar 1 laag geprint moet worden voor de banen. Maar spijtig genoeg bij iets grotere projecten is het soms helemaal niet mogelijk om kruisingen te voorkomen en moeten er Via’s gemaakt worden. Zoals eerder uitgelegd is een Via een kleine verbindingen van de bottom layer naar de top layer. De bottom layer daar worden de rode verbindingen gefreesd, en uiteraard worden dan de groene banen aan de top layer gefreesd. Ook is op de bovenstaande foto duidelijk te zien dat er verbindingen zijn die de rode banen met de groene verbinden.
Arduino Als microcontroller wordt ook hierbij gebruik gemaakt van een Arduino DUE. De allergrootste reden hiervoor is dat de Arduino DUE 54 digitale i/o pinnen heeft. Dit aantal maakt het vrij duidelijk waarom we deze gaan gebruiken aangezien we zelf 28 digitale i/o zeker nodig hebben. En wel degelijk 28 omdat we 8 rijen hebben maar ook 20 kolommen.
Software Code Multiplexen Om een led te doen branden moeten we de led voorzien van een spanningsverschil. Aan de anode van de led moet 1.8V (hangt af van led tot led) meer staan dan aan de kathode van de led. In de onderstaande figuur is duidelijk te zien dat de led brandt. Ik heb hierbij 5V aan de rij aangesloten en de massa (0V) aan de kolom. 5V is een digitale ‘1’ en 0V is een digitale ‘0’. Als we nu de led willen doen branden moeten we op de juiste rij 5V aansluiten en op de juiste kolom 0V. Als we nu 5V op de eerste kolom zetten, zal de kolom doven omdat er nu geen spanningsverschil meer aanwezig is. Een LED aan; 33
Op bovenstaande schakeling toon ik hoe het praktisch in zijn werking gaat. Er komt een spanningsval over de LED te staan waardoor deze zal branden. De weerstand staat er natuurlijk zodat de LED niet te hoog wordt aangestuurd. Alle leds aan
Meerdere leds op een rij
34
Hier toon ik eens wat meer leds op een rij. Het werkingsprincipe blijft hetzelfde als met een led. Een spanningsval wordt veroorzaakt en de led zal branden.
35
Meerdere leds in een kolom
Bij de leds in kolommen bestaat net dezelfde uitleg, maar in plaats van verschillende massa’s die worden aangesloten, worden er nu verschillende bronnen aangesloten met weerstanden. Verschillende LEDs aansturen in een rij of een kolom
36
Dit is een voorbeeld van het fout programmeren of het fout aansturen van twee leds. In dit geval is de bedoeling dat LED1 en LED9 zullen branden. Maar het is duidelijk te zien dat dit niet klopt. Dit komt omdat LED7 op dezelfde kolom zit als LED1 en LED 2 op dezelfde kolom als LED9. LED7 zit op zijn beurt op dezelfde rij als LED 9 en LED 2 op dezelfde rij als LED1. Over LED7 en LED2 verkrijgen we dus ook een spanningsval waardoor deze leds zullen branden. Tegen de wil in van de programmeur. Hierdoor zullen we moeten multiplexen. Dit wil zeggen kolom per kolom of rij per rij activeren om zo ervoor te zorgen dat verschillende leds in rijen/kolommen kunnen branden. Wanneer deze rijen/kolommen zo snel worden afgewisseld dat het onmenselijk is om dit met ons oog te kunnen volgen lijkt het of alle leds stilstaan. En zien we een mooie figuur. Als we nu een figuur willen tonen doen we dit dus met multiplexen. Als voorbeeld gebruik ik een eenvoudig kruis. We nemen dus de eerste kolom waarbij we, door de juiste spanningen over de juiste leds aansluiten, de juiste leds laten branden.
Voor de volgende kolom doen we net hetzelfde en zetten nu de 5V op de tweede rij. Doordat we kolom 2 op de massa hebben aangesloten zal de middelste led branden.
37
Nu hetzelfde voor de laatste kolom. We zetten de 5V op rij 1 en rij 3 en 0V op de laatste kolom. Hierdoor zal de laatste kolom van het kruis branden.
Als we dit nu snel na elkaar laten lopen (multiplexen) zal je zien dat het een mooi kruis is. Met snel wordt hier bedoeld dat we de programma’s zo snel achter elkaar laten lopen zodat men niet kan zien dat het meerdere programma’s zijn.
38
Code Voor het coderen van de verschillende teksten/letters/figuren, moet eerst alle pinnen gedefinieerd worden. Zowel de rijen als de kolommen worden in een Array gestoken. Dit maakt het later gemakkelijker om de juiste pinnen aan te roepen en ook te gaan gebruiken. const int Row[8] = {22,23,24,25,26,27,28,29}; const int Column[66] = {30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49};
Zoals we al duidelijk zien dat er achter de Column een groter getal staat dan 20 kunnen we misschien gaan denken dat dit een fout is maar helaas is dit niet het geval. Die 66 staat er omdat we dan veel gemakkelijker een langere tekst erop kunnen laten verschuiven. Maar dit word later nog duidelijker uitgelegd. Daarna moeten de alle gedefinieerde pinnen ingesteld worden als uitgang. Omdat deze uiteraard nooit als ingang gebruikt zullen worden en enkel waarden gaan uitsturen naar de matrix moeten de pinnen ingesteld worden als output, zodat deze de juiste waarden kunnen doorgeven en de juiste spanning. Alle pinnen moeten ook eerst ingesteld worden dat deze LOW zijn dus dat er zeker nog niets brand bij de start van de Arduino. for (int pin = 0; pin < 8; pin ++) {
pinMode (Row[pin], OUTPUT );
}
for(int pin = 0; pin <20; pin++) {
pinMode (Column[pin], OUTPUT );
}
for (int pin = 0; pin < 8; pin ++) {
digitalWrite (Row[pin], LOW );
}
for(int pin = 0; pin <20; pin ++) {
digitalWrite (Column[pin], LOW );
}
Wanneer er nu een tekst op moet verschijnen ben ik persoonlijk alle letters 1 voor 1 gaan programmeren om deze nadien dan op de juiste plaats te kunnen zetten en na mekaar te laten inschuiven. Op de onderstaande code is te zien hoe de letter A wordt geprogrammeerd. Deze letter wordt in stukken verdeeld om dan deze stukken te multiplexen zodat deze letter mooi lijkt stil te staan.
39
void A(int a, int StartPosition ){ if(( StartPosition � a ) < 20) { if(( StartPosition - a) > 0 ) { for(int i =1 ; i <8 ; i++) {
digitalWrite(Row[i], HIGH ); }
digitalWrite(Column[ StartPosition � a ], HIGH ); digitalWrite(Column[( StartPosition + 4 )-a], HIGH ); delay(1); for(int i =1 ; i <8 ; i++)
{
digitalWrite(Row[i], LOW );
}
digitalWrite(Row[0], HIGH ); digitalWrite(Row[4], HIGH ); digitalWrite(Column[StartPosition-a], LOW ); digitalWrite(Column[(StartPosition+4)-a],LOW ); digitalWrite(Column[(StartPosition+1)-a],HIGH ); digitalWrite(Column[(StartPosition+2)-a], HIGH ); digitalWrite(Column[(StartPosition+3)-a], HIGH ); delay(1); digitalWrite(Row[0], LOW ); digitalWrite(Row[4], LOW ); digitalWrite(Column[(StartPosition+1)-a], LOW ); digitalWrite(Column[(StartPosition+2)-a], LOW ); digitalWrite(Column[(StartPosition+3)-a], LOW ); delay(1); }
}
}
Eerst en vooral zien we op de bovenstaande code dat er 2 parameters worden meegegeven. Een parameter die de verschuiving zal meegeven en dit is de parameter a, en een andere parameter genaamd StartPosition die zal vertellen waar de letter moet starten. Dit om de letter goed achter elkaar te kunnen plaatsen in de matrix. Als we dan eens in de methode gaan kijken zien we dat we starten met 2 if functies. De eerste if functies zal controleren of de waarde van de verschuiving niet kleiner word dan 20. En de tweede if zal ervoor zorgen dat de waarde van de verschuiving niet kleiner dan nul mag worden. Dit twee if functies gaan er dus voor zorgen dat de letter enkel getekend worden als ze zichtbaar zijn binnen de led matrix. Hiermee bedoel ik dat ze werkelijk zichtbaar gaan zijn op de matrix, omdat er gewerkt wordt in theorie met een veel grotere matrix maar in de werkelijkheid zien we maar 20 kolommen maar in theorie staan er 66 geprogrammeerd. Namelijk 66 omdat hierbij alle letters achter elkaar passen voor de woorden die ik zal gebruiken en tonen op de matrix. Eenmaal alles gecontroleerd is door de if functies worden de juiste rijen en de juiste kolommen op de juiste momenten op HIGH gezet en ook weer op LOW gezet. Bijvoorbeeld bij de letter A zoals hierboven te zien is, worden eerst de verticale lijnen in de letter op HIGH gezet en daarna weer op LOW en fractie van seconden later worden ook de horizontale lijnen op HIGH gezet en daarna weer op LOW. Als we dit dan allemaal snel na elkaar laten lopen dan zien we een mooie stilstaande letter A. Dit omdat de delays zo laag staan dat de flikkering van de led nooit zichtbaar is voor het mensen oog. Er wordt nu het voorbeeld genomen van de letter A maar dit is voor elke letter of nummer hetzelfde. Dat de letter/nummer opgesplitst wordt en zo gemultiplext zodat deze mooi stil staat en goed zichtbaar is. Dus ook bij elke letter moeten de juiste rijen en de juiste kolommen op de juiste momenten HIGH en weer LOW gezet worden. Het verschuiven van de letters; Het verschuiven van de letters of anders gezegd het laten inlopen van de letter en zo weer verdwijnen wordt zoals eerder gezegd meegegeven met de parameter ‘a’. Deze parameter zal (zoals gezien in de voorbeeld code hierboven.) gebruikt worden bij het aanduiden van de Row waarde. Hierin staat | Startposition - a | waardoor hij telkens de a waarde zal opschuiven. De a waarde zal steeds verhogen in een andere methode genaamd Intation.
40
void IntationIneens() {
for(int i = 0; i< 60;i++) {
for(int k = 0;k < 50 ; k++) {
N(i,58);
I(i,15); N(i,21); T(i,28); A(i,34); T(i,40); I(i,46); O(i,52); }
delay(2);
}
}
Bij dit stuk code zien we dat we ‘i’ meegeven bij het aanroepen van de letters. Dit is enkel een naamgeving dus we zien dat in de for loop de ‘i’ oploopt waardoor de letter zal verschuiven naar links. De letter zal zeker naar links verschuiven want als i groter wordt, word ook a groter dus wordt het verschil met de StartPosition kleiner waardoor hij dichter naar 0 zal gaan. En de led matrix kolom 0 ligt helemaal links. De tweede for loop waarin werkelijk alle methodes worden aangeroepen zorgt ervoor dat de letters eerst even blijven staan vooraleer hij kan verschuiven. Anders verkrijgen we een geflikker aan leds en dat is niet wat we willen. Excel; Voor de letters duidelijk zichtbaar en leesbaar te maken en om alles goed op zijn plaats te krijgen ook in de theoretische kolommen heb ik gebruik gemaakt van een excel template. In excel is het gemakkelijk om kolommen en rijen bij elkaar te plaatsen dus dit maakte het gemakkelijker voor het programmeren van de letters.
De donkere zone beschrijft dan het zichtbare en de lichtere zone beschrijft de theoretische kolommen. Zo kunnen we gemakkelijker hun startpositie meegeven. Ook maakt dit het gemakkelijk om de letters op te splitsen en zodanig te kunnen kijken voor de juiste rijen en kolommen op de juiste tijden te activeren en deactiveren.
41
Bibliografie Robot Arm; http://www.conrad.be/ce/nl/product/1395728/Arexx-RA2-CH2-RA2-CH2-robotarm-bouwpakket/? ref=category&rt=category&rb=1 LED’s; http://www.conrad.be/ce/nl/product/184350/Vishay-TLHK-5800-LED-bedraad-Rood-Rond-5-mm-5500mcd-4-20-mA-19-V?ref=searchDetail PCB; GTI Beveren (Met dank aan leerkracht E. Van Dyck.) Servomotoren; Oude cursus uit mijn vorige studies. L293D (h-bruggen); http://www.ti.com/lit/ds/symlink/l293.pdf Arduino DUE; https://www.arduino.cc/en/Main/ArduinoBoardDue ULN2003A; http://www.ti.com/lit/ds/symlink/uln2003a.pdf
42
Conclusie Project Het uiteindelijk te bereiken doel voor mij is bereikt. Er is een mooie robot arm opstelling met een goed werkende led matrix. Langs de kant van de hardware is dus alles gelopen volgens plan. Het was in het begin een helse zoektocht om alles goed en perfect uit te zoeken zodat alles op de juiste manier kan werken. Er moesten datasheets gelezen worden tot ze langs ons oren uitkwamen, maar een goede voorbereiding is belangrijk om het project goed verder te kunnen zetten. Ook was ik zeer blij met alle steun die Glen ons geboden heeft. Ook omdat hij elke week de tijd zocht tussen zijn drukke agenda om elke donderdag naar school te komen en samen bij ons te komen werken zodat we snel al onze vragen konden stellen en hulp konden krijgen waar nodig. Uiteraard waren er af en toe bugs die voor problemen zorgde, maar mits wat zoek werk en debug werk konden deze al snel verdwijnen uit ons project. De grootste problemen waren er omdat ik alles nog moest leren over de driver en de KeyValuePair methoden, maar dankzij goede steun en uitleg van Glen was ik hier vrij goed mee weg. Bij de Hardware was denk ik het grootste probleem de servo motoren. Hoe deze juist moesten aangesloten worden en de codering ervan. Vooral de codering hiervan was soms lastig omdat er soms snel na elkaar geschreven moest worden over de COM-poort en dit zorgde vaak voor problemen. Stage zelf Eerlijk gezegd was de stageplaats niet altijd even optimaal. We moesten daarbij telkens alles opruimen en in een kluisje gaan steken die ik bovendien zelf heb betaald. Er vloeide ook niet echt een werksfeer aangezien we tussen de studenten zaten. Maar denk ondanks dit minpuntje was er wel een goeie communicatie met Glen omdat hij veel langskwam om ons bij te staan. Dus al bij al was het een zeer leerrijke stage. Ben ook zeer blij dat we voor dit leuke bedrijf Intation mochten werken. Voor de personeelsvergaderingen die we mochten meevolgen werden we telkens heel goed ontvangen. Ik vond het ook zeer vriendelijk dat we zo een personeelsvergaderingen mochten meemaken dit was een leuke ervaring om ook eens te zien hoe het dan in het bedrijf daar aan toegaat. Ook de verschillende activiteiten die we met het bedrijf gaan doen zijn was zeer leuk dus ben vrij blij over deze leerrijke periode en hopelijk zijn ze van mij ook zo blij.
43