Tag-Archive: video

In klein fliegt der Quadcopter (NanoQuad) endlich – und wie!

Da ich bisher wenig Glück mit meinen bisherigen Quadcoptern hatte und bisher nur wenig Motivation aufbringen konnte, das wieder gerade zu rücken, habe ich mich im Zuge meiner Zwischenbeschäftigung mit Mikrohelikoptern auch mit Quadcoptern im kleinen Maßstab beschäftigt. Ich habe mir einen auf Basis des Flyduino NanoQuad-Rahmens mit NanoWii-Controller (MultiWii Software 2.2) zusammengebaut. Seit ich die Firmware der Drehzahlregler durch die BLHeli Multirotor-Firmware ausgetauscht habe (es gibt dazu übrigens eine super Anleitung bei OlliW), fliegt das kleine Biest extrem stabil und liefert Schub satt.

Please specify a Flickr ID for this gallery

Wo sich jetzt das Grundproblem mit der Flugtauglichkeit überhaupt nicht mehr stellt, konnte ich etwas übermütiger werden und habe eine kleine Kamera in Form eines Schlüsselanhängers unter den Quad gehängt. Sieht man davon ab, dass das Video „wobbelt“ weil noch eine brauchbare Dämpfung fehlt, sind die ersten Bilder schon ganz gut geworden:

Quadcopter-Update

So, es ist inzwischen einiges an der Quadcopter-Front passiert – nur sauber fliegen tut er immer noch nicht. Aber der Reihe nach: dieses Video ist jetzt schon etwas älter, zeigt aber schon etwas bessere Flugversuche mit meinem Selbstbaurahmen:

Nach diesem und weiteren Flugversuche habe ich den Rahmen aus Kohlefaserteilen nachgebaut um ihn leichter zu machen. Dieser Neubau wiegt gute 170 Gramm weniger als das vorherige Modell aus Platinenmaterial und Alurohren und der Copter kommt somit auf ein Abfluggewicht von etwa 1060 Gramm. Von diesem Modell gibt es leider keine Flugaufnahmen bisher, aber er hat auch schon mehr als eine Design-Iteration hinter sich.

“Raw“ materials for the carbon version of my frame Carbon version of my DIY quadcopter frame

Erster Entwurf

Grundsätzlich besteht der Kohlefaserrahmen aus den gleichen Teilen wie der bisherige Rahmen, 16 mm Rohren und 1mm starkem Plattenmaterial. Bei der Art Belastung, wie sie beim Reindrücken der Rohre in die Halterungen auftritt, erwiesen sich die Rohre als brüchig und mussten daher an jedem Ende mit einem passenden Holzstopfen versehen werden, der ihnen die nötige Stabilität gibt. Weil ich die Rohre nicht lackieren wollte, habe ich mich entschieden von einer Plus-Konfiguration auf eine X-Konfiguration umzusteigen und die Orientierung durch LED-Streifen kenntlich zu machen.

Für den ersten Anlauf habe ich ausschließlich Kunststoffschrauben für alle Schraubverbindungen verwendet und zudem lange Schrauben aus Kunststoff durch das hintere Ende der Arme an der Mittelplatte und durch das vordere an der Motorhalterung geführt, um ein Verdrehen in den Halterungen zu verhindern. Dieses Verdrehen der Arme war eine der großen Schwachstellen des ersten Rahmens (neben seinem Gewicht). Leider stellte sich nach einigen Flugversuchen schnell heraus, dass Schraubverbindungen aus Kunststoff nicht stark genug angezogen werden können, um wirklich fest zu sein. Dies äußerte sich dann recht schnell in losen Halterungen und einem Gewackel der ganzen Konstruktion. Die langen Schrauben in den Armen erwiesen sich zudem also zu flexibel um wirklich ernsthaft einem Verdrehen der Arme vorzubeugen.

Zweiter Entwurf

Der Rahmen musste also verbessert werden. Trotz des höheren Gewichts habe ich alle Plastikschrauben durch Metallschrauben und Muttern mit Sicherungsring ersetzt. Unterlegscheiben mit einem größeren Außenrand als üblich halten dabei die Halteklemmen der Rohre genau mittig über den Bohrlöchern. Die lange Schraube durch den Arm auf der Seite der Motorträger wurde ebenfalls durch eine Metallschraube ersetzt und die Schrauben auf der Seite der Mittelplatte wurden zugunsten eines Splints für jeden Arm komplett entfernt.

Ausrichten des Auslegers mit Hilfe eines Linienlasers

Zum Fixieren der Arme habe ich diese zunächst mit Hilfe eines selbstnivellierenden Linienlasers passend ausgerichtet (der Laserstrahl muss das Armrohr genau mittig schneiden, mittig auf der Schraube liegen und komplett mittig über den Motor bis hoch zum Propellermitnehmer verlaufen). Danach habe ich durch die inneren Klemmen und die Arme ein horizontales Loch gebohrt, durch das ein genau passender Splint gesteckt wurde. Da dieser Splint die Klemme mit dem Arm in einer festen Position ohne Spiel verbindet, ist damit effektiv ein Verändern der Position des Auslegers nicht mehr möglich.

Der so veränderte Rahmen erwies sich dann als sehr robust und verwindungssteif. Durch die starren Verbindungen, insbesondere die mit dem Splint, besteht allerdings auch ein erhöhtes Risiko, bei einem Crash einen Bruchschaden zu verursachen. Das ist natürlich dann auch passiert als ich das Ding in einer Panikreaktion wieder mal unangespitzt in der Acker gejagt habe. Zur Zeit ist der Rahmen in Reparatur, einen neuen Ausleger habe ich schon gefertigt. Der Rahmen muss jetzt wieder zusammengebaut und die LEDs neu verdrahtet werden.

Neuer Flightcontroller

Nach den bisherigen Flugversuchen bin ich recht enttäuscht von meinem bisherigen, sehr einfachen Flight Controller Board. Auch wenn ich glaube, dass viele der Probleme, die ich hatte, auf meine geringe Übung mit Quadcoptern zurückzuführen sind, bin ich genauso überzeugt davon, dass der bisherige Flight Controller auch für einen Teil der Probleme verantwortlich ist. Ich werde daher auf ein Board auf MultiWii-Basis umsteigen, das digtiale Sensoren hat (Gyroskop und Beschleunigungsmesser) und dessen Software ich auch lesen und verstehen kann. Mehr dazu in Kürze…

Quadcopter-Testflug #2: Auf, auf, und … ab in den Acker

Alter und neuer Motor im Vergleich

Alter und neuer Motor im Vergleich

Nach dem Reinfall mit dem ersten Flugversuch habe ich den Copter am Wochenende mit stärkeren Motoren (Turnigy Aerodrive SK3 2830-1020kv) und einem 3S-LiPo ausgerüstet, denn schließlich brauchte das Ding mehr Power, har, har, har.

Flugtag … äh, -stunde … äh, -minuten

Ich hatte Sonntag zwar einen engen Terminplan, habe aber doch eine halbe Stunde gefunden, in der ich den Quadcopter auf einem Acker in der Nähe ausprobieren konnte. Was soll ich sagen: er fliegt. Die Leistung ist jetzt ausreichend, vielleicht nicht für Akrobatikflug, aber zumindest um vom Boden in brauchbare Höhen aufzusteigen.

Und da beginnt das Problem: ich bin ziemlich unkoordiniert an die ganze Sache rangegangen und war unterm Strich mit der Situation leicht überfordert. Diesem Umstand sind dann die Crashs aus dem Video von diesem Tag geschuldet:

Der richtig spektakuläre Crash ist da aber gar nicht drauf: ich kam kaum vom Boden hoch und gab deshalb mehr Schub. Das war dann aber zuviel Schub und der Quadcopter schoss auf 4-5 Meter Höhe. Und mir fiel in Panik aber nichts besseres ein, als den Schub auf null zu reduzieren, woraufhin der Quadcopter natürlich wie ein Stein aus dem Himmel fiel. Glücklicherweise ging bei den Crashs nur ein Propeller zu Bruch. Dass der Copter aber beinahe in Flammen aufgegangen wäre, erläutere ich aber erst weiter unten 😉

Erkenntnisse

Der Quadcopter nach dem Crash

Der Quadcopter nach dem Crash

Auch wenn die ganze Aktion ziemlich unkoordiniert war und mich am Ende Nerven und den einen Propeller gekostet hat, so habe ich doch wertvolle Erkenntnisse gewonnen.

  1. Das eine ist die Sache mit der Steuerung. Der Schubregler ist empfindlich und es gehört nicht viel dazu, den Quadcopter in die Stratosphäre zu befördern oder unangespitzt in den Acker stürzen zu lassen.
  2. Da sich die Steuerung des Quadcopters nicht mit dem eigenen Blick auf das Fluggerät ändert, provoziert eine Position, die auf einen selber zeigt, gerne mal falsche Lenkbefehle, da in diesem Moment die Steuerung optisch umgekehrt ist. Will ich also eine Schieflage nach rechts mit einem Aufrichten nach links kompensieren, wenn der Quadcopter auf mich zukommt, muss ich den Stick nach rechts legen und nicht, wie ich versucht war, nach links. Das verstärkt dann nämlich die Schieflage und schon crasht das Ding.
  3. Der Rahmen funktioniert glücklicherweise wie erwartet, allerdings wurde vor allem beim letzten Crash (auf dem Video) eine gefährliche Designschwäche sichtbar.

Designstärken und -schwächen

Have boom, will travel

Have boom, will travel

Das gute Vorweg: die Konstruktion mit Aluminiumrundrohren und Clips für diese Rohre tut genau das, was sie soll: bei einem heftigen Aufprall springen die Rohre aus den Clips, wodurch die meiste Energie des Absturzes kompensiert wird, ohne dass der Rahmen ernsthaft beschädigt wird. Um den Quadcopter dann wieder flugbereit zu machen, reicht es aus, die Arme wieder neu zu positionieren und in die Klemmen zu drücken.

Angeknackstes Kontrollkabel

Angeknackstes Kontrollkabel

Das Problem an dieser Konstruktion ist mir erst nach dem Crash bewusst geworden: stürzt der Quadcopter in einem steilen Winkel ab, springt ein Arm nicht nur aus den Klemmen, sondern schiebt sich u.U. in den Quadcopter hinein. In diesem Fall war das der grüne Ausleger, der sich fast 10 Zentimeter in den Rahmen geschoben hat. In der Mitte der Platten laufen aber die ganzen Kontroll- und Stromkabel und es war eher Glück, dass das Rohr nur ein einziges Kabel leicht beschädigt hat. Hätte er das Stromkabel erwischt, hätte es einen Kurzschluss gegeben und im schlimmsten Fall einen LiPo-Brand.

Glücklicherweise ist mir das erspart geblieben und so kann ich an die Werkbank zurückkehren, um das Problem anzugehen. Stay tuned!

Quadcopter-Testflug #1: Viel Lärm um nichts

Letzten Freitag in der Mittagspause hatte ich zum ersten Mal Gelgenheit, den Quadcopter probezufliegen. Oder zumindest war das der Plan. Aber der Reihe nach.

Propellermassaker

Mein Plan sah 10×4.7 Slowflyer Propeller für den Quadcopter vor und ich hatte drei Sätze APC-Propeller erworben. Mit 3 Euro pro Stück hielt ich die aber für etwas teuer um damit die ersten Flüge (=Crashs) zu bestreiten und habe daher in billige 10×4.5 Propeller von Hobbyking investiert. Mit denen bekam ich dann aber massive Probleme beim Wuchten, denn statt einem zu schweren Blatt wiesen die meisten eine zu schwere Nabe auf, die sich auch durch massives Wegfeilen von Material nicht beheben ließ. Erst dann fiel mir auf, dass bei eben jenen Propellern die Nabenbohrung gar nicht mittig saß, sondern teilweise bis zu einem Millimeter daneben. Dieser Qualitätsmangel war nicht behebbar, also wanderte der China-Kram zu 3/4 direkt in den Müll, womit die übrig gebliebenen am Ende dann genau so teuer waren, wie die von APC.

Houston, we have no liftoff

Für die China-Propeller musste ich auch andere Propellermitnehmer montieren, nämlich deutlich größere. Die Höhe der Propeller war größer als der verfügbare Schraubweg der eigentlich für diese Motoren angedachten Mitnehmer. Letzten Endes half das aber alles auch nichts, denn das Video zeigt deutlich, dass der Quadcopter nicht fliegt. Er stößt sich ein paar Mal für ein, zwei Zentimeter in die Luft und rutscht dann über den Boden.

Der Grund dafür ist auch klar: Wenn ich bei Vollgas mit diesen Motoren (Turnigy Park 300 1080kv) nicht abheben kann, dann haben sie nicht genug Power oder der Rahmen ist zu schwer. Oder besser: das Verhältnis von Leistung zu Gewicht ist ungünstig. Um dem Abhilfe zu schaffen, gibt es zwei mögliche Lösungen: den Copter leichter machen oder die Motoren stärker. Oder beides. Da ich sowas schon geahnt hatte, habe ich schon vor einiger Zeit stärkere Motoren (Turnigy Aerodrive SK3 2830-1020kv)angeschafft, die ich mit den gleichen Drehreglern fliegen kann. Zudem habe ich das nötige Kohlefasermaterial für die Ausleger und die Mittel- sowie Motorenplatten. Die Umstellung auf Karbonteile dürfte rechnerisch ca. 120 Gramm Ersparnis bringen, also etwa 10% des Gesamtgewichts (ohne Batterie gerechnet).

Ich montiere aber mal zuerst die stärkeren Motoren, vermutlich reicht das schon. Und wie es weitergehts erfährst Du nach der nächsten Maus… vorher habe ich aber als Bonus noch eine Zeitrafferaufnahme von der Testmontage meines Quadcopter-Rahmens:

Presenting the ICMI MAX7219 Arduino library

For my current project, the ICMI Service Status Monitor, I have chosen the Maxim MAX7219 IC to drive the indicator LEDs. This little chip comes with several nice out of the box features such as adjustable LED current, 16 level brightness control, special decode mode for seven segment displays and so on. The main reason I chose it is because it contains a multiplex scan mechanism implemented in hardware. This frees my own code from a lot of additional complexity that I would encounter if I chose to implement multiplex scanning in software (which is not impossible of course and I’ve already done it – check the code samples for my ICMI Seven Segment Board – but it’s nice not having to do it and besides that, the focus of this projects lies more on the PC/Arduino communication).

Control issues

The downside of using the MAX7219 is the more complex communication with the chip required to make things work. The IC uses various registers to store its configuration state and when sending data, you also have to address the proper register and pass the data in a format specified in the data sheet. To make things easier, I chose to implement this communication in form of an Arduino library that makes using the MAX7219 a whole lot easier by hiding the complexity behind a neat API. Others have implemented such a library before more of course and some of them also offer additional functionality such as multi-chip configuration or CODE B digit decoding. I do not intend to compete with them (at least not yet), I merely took the opportunity of extending my skills.

The code for this library along with example code is available on github at https://github.com/hmbusch/ICMI-MAX7219-Arduino

API description

This section describes the methods available to the user when importing this library. Again: don’t get confused by the uint8_t data type – it is the same as byte in Arduino and can hold an integer value between 0 and 255.

Constructor Max7219(uint8_t dataPin, uint8_t clockPin, uint8_t loadPin, uint8_t digitCount)

This constructor is used to create a new „control instance“ for the connected MAX7219 chip. The IC required 3 Arduino pins – the data pin, the clock pin and the load pin (pins 1, 13 and 12 of the MAX7219) that you need to pass to the constructor. In addition, you have to tell it, how many digits (when using seven segment displays) or rows (that’s what we want) are connected to the driver. This value is used internally to verify the parameters of later method calls. Example (Arduino connected with pins 5, 6 and 7):

 

Method void enable(boolean enable)

The whole LED driver can be shutdown by disabling it. All its settings and the current state are preserved, the chip just ceases to operate. After a power reset, the chip is disabled by default so you will need to call max7219.enable(true) (assuming the control instance was constructed with the name  max7219  as in the constructor example above) if you want it to show something. If you omit this call, all your configuration commands will still configure the chip but you simply won’t see it. Enabling and disabling the driver can also be used to flash the whole display.

Methods void setDigitRaw(uint8_t which, uint8_t value) / void setRow(uint8_t which, uint8_t value)

These two methods are actually only one method with two names. I introduced these names so a user could call whichever method best fits in the context of his program. If your program controls a LED matrix, calls to setDigitRaw() might seem a little strange so you could use setRow() instead.

This is the method that actually tells the driver what to display. You have to specify the index of the row/digit that you want to set (ranging from 0-7, limited by the row/digit count you gave in the constructor) and the value you want to set it to. To make things easier, the method performs a bit level translation of the value from your value to what the MAX7219 expects. This way, the bit order equals the segment or column order. Bit 0 (the rightmost bit, also called the least significant bit) corresponds to segment A (column 1), bit 1 corresponds to segment B (column 2) and so on. To display the number 7 on the fourth digit of a seven segment display, you would pass 3 as the index and  B00000111  (segment A-C lit).

Although the MAX7219 supports it, the library currently does not offer a way to pass a BCD number to the chip. When using BCD mode, you could display a 7 by actually passing a 7 as value and the chip will take care of the decoding to segments. This feature may be included in future releases. The current lack of this feature is the reason why this method is called  setDigitRaw()  and not just setDigit() .

Method void setIntensity(uint8_t level)

The MAX7219 offers a built-in brightness control for the display with a 16 step resolution. This method allows you to set the brightness level for the display and accepts value from 1 (darkest) to 16 (brightest). Any value below 1 will be treated as 1, any value above 16 will be treated as 16. It is not possible to switch off the display, even the darkest setting is still visible and does not stand for „off“. If you want to turn of the display, call  enable(false)  instead. The constructor will set the chip to the highest brightness. This is a sort of safety precaution I created, because the IC’s initial brightness setting defaults to the lowest level. During testing, I wrecked my head trying to figure out why the LEDs were so dim, not realising the brightness settings. For others to avoid this mistake, I reversed the default brightness value in my library implementation.

Method  void testDisplay(boolean testDisplay)

This method can be used to toggle the internal test mode of the MAX7219 on and off. When enabling test mode, the IC switches on all LEDs (regardless of the row/digit count passed to the constructor) and sets brightness to maximum. Enabling the test mode will not overwrite any settings made before entering the test mode, which means when switching back to normal mode, the display will revert to the exact setting that it hade before entering test mode. This method is useful for verifying your LED display and to be able to quickly switch to a fully lit LED panel without having to change each row and saving the state of the display in order to return to that state later.

Method void clearDisplay()

This method does exactly what the name promises: it clears the display by turning all LEDs in all rows off. This operation cannot be undone, that means once you clear the display, you have to reprogram it again, you cannot simply switch back to a previous state.

Method uint8_t version()

In order to provide some hint to a users program regarding the compatibility of the library, this method returns the current version number of the library. This can be used to check programmatically, if the user needs to update to a newer version and it can be used to prevent incompatibility issues.

Using the library

Using this library for your own projects is a two-step process. First, you need to install the library to your Arduino IDE and then you need to import it into you sketch.

Installing the library to the Arduino IDE

Use a file manager to navigate to the directory where your Arduino IDE resides (e.g. D:\Development\Arduino-1.0). Go into the folder called libraries and create a new folder there called ICMIMax7219. Copy the Max7219.cpp and .h files as well as the examples folder into the newly created directory. If your IDE was running at that time, you have to restart it for the changes to take effect. After the restart, go the File => Examples menu. If everything succeeded, you should see and entry called ICMIMax7219 and you can open the BasicFunctionExample from there.

Note: If you have another library for the MAX7219 installed, you may encounter naming clashes when the files of the other library are also named Max7219.*. When encountering this, remove the other MAX7219 library from your Arduino IDE. I will address this problem in the second release of the library.

Using the library in your code

To use the library in your own sketch, you need to import the header file. Do this by placing the line

at the very top of your sketch. This enables you to access the libraries functionality. In order to do so, you need to create an instance of the Max7219 class somewhere in you project. You can do this by calling the constructor as follows

First, the example defines some integer constants to represents the Arduino pins the IC is connected to and the digit/row count. The last line then creates an instance with the name max7219 which can subsequently be used to control the IC with calls like

In order to see a full, working sketch that uses the library, please refer to the BasicFunctionDemo sketch in the examples folder. The video embedded at the start of the post shows you what the output of this sketch will look like on an 8×8 LED matrix.