In verband met de winter van 2013/2014 ben ik op zoek gegaan naar een nieuw project. Deze keer wil ik een quadrocopter gaan bouwen. Nu is het bouwen van een quadrocopter niet heel spectaculair en er zijn al voldoende bouwverslagen van.
Echter wil ik mijn eigen controller programmeren op basis van een Arduino Uno inclusief de noodzakelijke sensoren. Dus ZONDER gebruik te maken van reeds bestaande programma’s. En dat zie je volgens mij niet zo vaak. Mede omdat de Arduino Uno een relatief lichte en trage processor is. In dit verslag wil ik de problemen (die ik zeker tegen ga komen) beschrijven.
Het frame wil ik mij niet druk om maken en kies daarom voor een F330 van DJI. Door het formaat past deze goed op het bureau tijdens het programmeren en testen. Een nadeel van een klein frame is dat deze van nature onstabieler is dan een grote.
“Waarom het wiel opnieuw uitvinden?” zullen sommigen zich afvragen. Omdat ik wil weten of ik het kan en omdat ik het leuk vind om probleemoplossend te programmeren.
Er zijn voorlopig vier stappen die ik deze winter wil bereiken:
1) Vliegen op basis van gyro’s;
2) Automatisch stabiliseren op basis van een versnellingssensor;
3) Automatisch hoogteregeling op basis van luchtdruk;
4) Een servo aangedreven gimbal.
De onderdelen die ik ga gebruiken (de meeste had ik nog liggen):
- DJI Flame Wheel 330;
- Arduino Uno;
- ST L3G4200D 3-assige gyro;
- CMPS10 kompasmodule met versnellingssensor;
- Driekleuren led voor signalering;
- druksensor MS5607;
- Futaba R617FS ontvanger;
- 3250mAh / 3S lipo;
De communicatie tussen de Arduino en de sensoren is op basis van I2C. Het inlezen van de ontvangersignalen en de aansturing van de servo en esc’s is op basis van pulsbreedte (1000 – 2000us).
Een avond solderen levert mij een shield op die ik eenvoudig op de Arduino Uno kan plaatsen. Een CD4075 (drievoudige or-poort) gebruikt ik voor het verzamelen van de ontvangersignalen.
De eerste stap is het realiseren van de communicatie tussen de Arduino en de ontvanger. Het probleem wat zich direct voordoet is tijd. Ik streef er naar om een verversingsfrequentie van de esc’s te behalen van 250Hz. Om 250 Hz te halen mag de programmalus niet langer zijn dan 4ms. Hierdoor is het niet mogelijk om het programma te laten wachten tot de pulsen van de diverse kanalen voorbij zijn gekomen.
De Arduino bied de mogelijkheid om gebruikt te maken van een interrupt. De processor stopt (interrupt) bij een wijziging aan de ingang het lopende programma en voert dan een stuk code uit. Dit gebeurt zo snel dat er bijna geen tijd verloren gaat. Echter heeft de Arduino Uno maar 2 beschikbare interrupt ingangen en heeft de Futaba R617FS ontvanger meer dan twee uitgangen.
De processor op bijvoorbeeld een KK controller heeft meer interrupt ingangen waardoor het verzamelen van ontvangeruitgangen makkelijker is. Maar helaas heb ik mijzelf een Arduino Uno opgelegd.
In het onderstaand schema is de volgorde te zien waarop de pulsen door de R617FS ontvanger uitgestuurd worden. De volgorde is vastgesteld met behulp van de Arduino. Door de signalen van kanaal 1, 3 en 5 te combineren ontstaat er een “somsignaal” waarbij de tijd tussen de statusverandering overeenkomt met de tijd. Door middel van een interrupt ingang is de tijd van de eerste 5 kanalen te bepalen.
Voor het combineren van de signalen maak ik gebruik van een CD4075 (drievoudige or-poort).
Door kanaal 6 van de ontvanger te koppelen aan de tweede interrupt is het mogelijk om 6 kanalen “tijdloos” in te lezen. Onderstaand schema laat de koppeling tussen de Arduino en de ontvanger zien.
Een belangrijk onderdeel is een goede statusmelding. Door middel van een driekleurenled. Op basis van kleur en het aantal pulsen is het eenvoudig om een foutmelding , status of waarschuwing te melden.
Zoals al gemeld is het niet mogelijk om de programmalus te stoppen. Om toch de led aan en uit te zetten is het noodzakelijk om na het inschakelen van de led de actuele “tijd” vast te leggen en daar bijvoorbeeld 1 seconden bij op te tellen. Zolang de actuele tijd onder deze waarde blijft mag de led blijven branden. Is de actuele tijd langer dan schakelt de led uit. Op deze manier zijn er zonder tijdverlies diverse statusmeldingen mogelijk.
Door een weerstanddeler aan te sluiten op een analoge ingang is het ook mogelijk om de spanning van de lipo te meten. Met enkele minuten solderen en een aanpassing in het programma hebben we een alarmmelding bij een te lage spanning van de lipo.
Deze spanningsmeting wil ik ook gaan gebruiken om te zorgen dat de signalen naar de esc’s versterkt worden naarmate de spanning van de lipo daalt. Hierdoor blijft het vlieggedrag bij volle en lege lipo gelijk en kan de regelaar optimaal blijven functioneren.
Het uitlezen van de gyro buffers is met behulp van de datasheet redelijk eenvoudig voor elkaar te krijgen. In de buffers staan steeds de meest actuele rotatiewaardes van alle drie de assen in graden per seconden.
De communicatie is op basis van I2C en standaard staat de kloksnelheid op 100kHz. Mits de sensoren dit aan kunnen is het mogelijk om de kloksnelheid te verhogen naar 400kHz. In de wire library staat het bestand twi.h. Door de regel #define TWI_FREQ 100000L te veranderen in #define TWI_FREQ 400000L gaat de kloksnelheid omhoog. Dit verkort behoorlijk de doorlooptijd.
Door de actuele rotatie te vergelijken met de met de stickpositie van de zender ontstaat er een actuele en gewenste waarde voor de regelkring. Deze twee waardes vormen de input van de pid-regelaar. Afhankelijk van het verschil tussen de twee input waardes ontstaat er een output waarmee de motoren aangestuurd zullen worden.
In programmavorm stelt de pid regelaar niet zo veel voor.
Improving the Beginner?s PID: Direction « Project Blog
Voor de Aurduino is er een library beschikbaar waar de noodzakelijke stukken code zijn verwerkt. Op de implementatie van de regelaar ga ik niet in,en ga er van uit dat dit iedereen wel lukt.
In een notendop hebben we nu voor de drie assen van de quadrocopter de aanstuurwaardes voor de motoren. Door de signalen op de juiste manier te mixen ontstaat er een signaal per motor.
Het mixen van de signalen is eigenlijk eenvoudig. Ik programmeer de quad voor een X opstelling waardoor het signaal voor de motor links voor bijvoorbeeld wordt:
Motor_1 = gas + pid_uitgang_pitch – pid_uitgang_roll + pid_uitgang_yaw
Op deze manier zijn eigenlijk alle bekend configuraties eenvoudig te mixen. En zelfs modellen waarbij de symmetrie afwijkt!
Het aansturen van de esc’s gaat door middel van 1000 t/m 2000us pulsen. Omdat ik ook een servo voor de gimbal toe wil passen kom ik op 5 signalen. Als deze pulsen stuk voor stuk worden uitgestuurd gaat er in het ergste geval 10ms verloren (5 x 2000us). En dat is te lang omdat de verversingsfrequentie daardoor onder de 100Hz zakt. Het is dus noodzakelijk om de signalen gelijktijdig uit te sturen.
Dat lijkt eenvoudiger dan dat het is. Enkele microseconden verschil tijdens het uitsturen zijn direct op te merken in het bewegen van de servo en het vlieggedrag. Iedere puls moet dus keer op keer exact dezelfde lengte hebben en zelfs het in en uitschakelen kost al enkele microseconden.
Ik heb er voor gekozen om de signalen op lengte te selecteren. De kortste puls eerst en de langste puls als laatste. Vervolgens stuur ik de betreffende uitgangen in die volgorde “hoog”. Na de betreffende wachttijd van 1000 t/m 2000us kan ik de uitgangen in dezelfde volgorde weer “laag” sturen. Hierdoor ontstaat een zeer solide en constant uitgangssignaal.
De eerste uitdaging schiet al aardig op en binnenkort ga ik de eerste vluchten maken. Dan zal ik ook een film posten van het eerste resultaat.
Maar eerst nog even wat regels erbij programmeren
Echter wil ik mijn eigen controller programmeren op basis van een Arduino Uno inclusief de noodzakelijke sensoren. Dus ZONDER gebruik te maken van reeds bestaande programma’s. En dat zie je volgens mij niet zo vaak. Mede omdat de Arduino Uno een relatief lichte en trage processor is. In dit verslag wil ik de problemen (die ik zeker tegen ga komen) beschrijven.
Het frame wil ik mij niet druk om maken en kies daarom voor een F330 van DJI. Door het formaat past deze goed op het bureau tijdens het programmeren en testen. Een nadeel van een klein frame is dat deze van nature onstabieler is dan een grote.
“Waarom het wiel opnieuw uitvinden?” zullen sommigen zich afvragen. Omdat ik wil weten of ik het kan en omdat ik het leuk vind om probleemoplossend te programmeren.
Er zijn voorlopig vier stappen die ik deze winter wil bereiken:
1) Vliegen op basis van gyro’s;
2) Automatisch stabiliseren op basis van een versnellingssensor;
3) Automatisch hoogteregeling op basis van luchtdruk;
4) Een servo aangedreven gimbal.
De onderdelen die ik ga gebruiken (de meeste had ik nog liggen):
- DJI Flame Wheel 330;
- Arduino Uno;
- ST L3G4200D 3-assige gyro;
- CMPS10 kompasmodule met versnellingssensor;
- Driekleuren led voor signalering;
- druksensor MS5607;
- Futaba R617FS ontvanger;
- 3250mAh / 3S lipo;
De communicatie tussen de Arduino en de sensoren is op basis van I2C. Het inlezen van de ontvangersignalen en de aansturing van de servo en esc’s is op basis van pulsbreedte (1000 – 2000us).
Een avond solderen levert mij een shield op die ik eenvoudig op de Arduino Uno kan plaatsen. Een CD4075 (drievoudige or-poort) gebruikt ik voor het verzamelen van de ontvangersignalen.
De eerste stap is het realiseren van de communicatie tussen de Arduino en de ontvanger. Het probleem wat zich direct voordoet is tijd. Ik streef er naar om een verversingsfrequentie van de esc’s te behalen van 250Hz. Om 250 Hz te halen mag de programmalus niet langer zijn dan 4ms. Hierdoor is het niet mogelijk om het programma te laten wachten tot de pulsen van de diverse kanalen voorbij zijn gekomen.
De Arduino bied de mogelijkheid om gebruikt te maken van een interrupt. De processor stopt (interrupt) bij een wijziging aan de ingang het lopende programma en voert dan een stuk code uit. Dit gebeurt zo snel dat er bijna geen tijd verloren gaat. Echter heeft de Arduino Uno maar 2 beschikbare interrupt ingangen en heeft de Futaba R617FS ontvanger meer dan twee uitgangen.
De processor op bijvoorbeeld een KK controller heeft meer interrupt ingangen waardoor het verzamelen van ontvangeruitgangen makkelijker is. Maar helaas heb ik mijzelf een Arduino Uno opgelegd.
In het onderstaand schema is de volgorde te zien waarop de pulsen door de R617FS ontvanger uitgestuurd worden. De volgorde is vastgesteld met behulp van de Arduino. Door de signalen van kanaal 1, 3 en 5 te combineren ontstaat er een “somsignaal” waarbij de tijd tussen de statusverandering overeenkomt met de tijd. Door middel van een interrupt ingang is de tijd van de eerste 5 kanalen te bepalen.
Voor het combineren van de signalen maak ik gebruik van een CD4075 (drievoudige or-poort).
Door kanaal 6 van de ontvanger te koppelen aan de tweede interrupt is het mogelijk om 6 kanalen “tijdloos” in te lezen. Onderstaand schema laat de koppeling tussen de Arduino en de ontvanger zien.
Een belangrijk onderdeel is een goede statusmelding. Door middel van een driekleurenled. Op basis van kleur en het aantal pulsen is het eenvoudig om een foutmelding , status of waarschuwing te melden.
Zoals al gemeld is het niet mogelijk om de programmalus te stoppen. Om toch de led aan en uit te zetten is het noodzakelijk om na het inschakelen van de led de actuele “tijd” vast te leggen en daar bijvoorbeeld 1 seconden bij op te tellen. Zolang de actuele tijd onder deze waarde blijft mag de led blijven branden. Is de actuele tijd langer dan schakelt de led uit. Op deze manier zijn er zonder tijdverlies diverse statusmeldingen mogelijk.
Door een weerstanddeler aan te sluiten op een analoge ingang is het ook mogelijk om de spanning van de lipo te meten. Met enkele minuten solderen en een aanpassing in het programma hebben we een alarmmelding bij een te lage spanning van de lipo.
Deze spanningsmeting wil ik ook gaan gebruiken om te zorgen dat de signalen naar de esc’s versterkt worden naarmate de spanning van de lipo daalt. Hierdoor blijft het vlieggedrag bij volle en lege lipo gelijk en kan de regelaar optimaal blijven functioneren.
Het uitlezen van de gyro buffers is met behulp van de datasheet redelijk eenvoudig voor elkaar te krijgen. In de buffers staan steeds de meest actuele rotatiewaardes van alle drie de assen in graden per seconden.
De communicatie is op basis van I2C en standaard staat de kloksnelheid op 100kHz. Mits de sensoren dit aan kunnen is het mogelijk om de kloksnelheid te verhogen naar 400kHz. In de wire library staat het bestand twi.h. Door de regel #define TWI_FREQ 100000L te veranderen in #define TWI_FREQ 400000L gaat de kloksnelheid omhoog. Dit verkort behoorlijk de doorlooptijd.
Door de actuele rotatie te vergelijken met de met de stickpositie van de zender ontstaat er een actuele en gewenste waarde voor de regelkring. Deze twee waardes vormen de input van de pid-regelaar. Afhankelijk van het verschil tussen de twee input waardes ontstaat er een output waarmee de motoren aangestuurd zullen worden.
In programmavorm stelt de pid regelaar niet zo veel voor.
Improving the Beginner?s PID: Direction « Project Blog
Voor de Aurduino is er een library beschikbaar waar de noodzakelijke stukken code zijn verwerkt. Op de implementatie van de regelaar ga ik niet in,en ga er van uit dat dit iedereen wel lukt.
In een notendop hebben we nu voor de drie assen van de quadrocopter de aanstuurwaardes voor de motoren. Door de signalen op de juiste manier te mixen ontstaat er een signaal per motor.
Het mixen van de signalen is eigenlijk eenvoudig. Ik programmeer de quad voor een X opstelling waardoor het signaal voor de motor links voor bijvoorbeeld wordt:
Motor_1 = gas + pid_uitgang_pitch – pid_uitgang_roll + pid_uitgang_yaw
Op deze manier zijn eigenlijk alle bekend configuraties eenvoudig te mixen. En zelfs modellen waarbij de symmetrie afwijkt!
Het aansturen van de esc’s gaat door middel van 1000 t/m 2000us pulsen. Omdat ik ook een servo voor de gimbal toe wil passen kom ik op 5 signalen. Als deze pulsen stuk voor stuk worden uitgestuurd gaat er in het ergste geval 10ms verloren (5 x 2000us). En dat is te lang omdat de verversingsfrequentie daardoor onder de 100Hz zakt. Het is dus noodzakelijk om de signalen gelijktijdig uit te sturen.
Dat lijkt eenvoudiger dan dat het is. Enkele microseconden verschil tijdens het uitsturen zijn direct op te merken in het bewegen van de servo en het vlieggedrag. Iedere puls moet dus keer op keer exact dezelfde lengte hebben en zelfs het in en uitschakelen kost al enkele microseconden.
Ik heb er voor gekozen om de signalen op lengte te selecteren. De kortste puls eerst en de langste puls als laatste. Vervolgens stuur ik de betreffende uitgangen in die volgorde “hoog”. Na de betreffende wachttijd van 1000 t/m 2000us kan ik de uitgangen in dezelfde volgorde weer “laag” sturen. Hierdoor ontstaat een zeer solide en constant uitgangssignaal.
De eerste uitdaging schiet al aardig op en binnenkort ga ik de eerste vluchten maken. Dan zal ik ook een film posten van het eerste resultaat.
Maar eerst nog even wat regels erbij programmeren

Laatst bewerkt door een moderator: