Developing the ornithopter

This page follows the development of an ornithopter, i.e. a drone flying by flapping its wings.

Related work

As mentioned a few times in class, there are several attempted drones projects within the class, fabacademy and beyond. Here follow a table of related projects to my ornithopter.

Source Relation Keywords
Ingrassia Daniele Flying quadcopters MultiWii, Flight controller, Sonar sensing
Ciurnelli Mattia Flying quadcopters Power distribution
Lambert Rulindana Winged copter Styrofoam wings
Rangholia Chirag Flying quadcopters Assembly, legs, multi-wii flight controller board
Zachary John Jackowski (mirror) Master Thesis on ornithopters Mechanical design, electrical design, control experiments, PD controller
Bionic bird Commercial ornithopter Design preview, shaper mechanism, wing motion and main gears


W1 - Design brainstorming

The wing flapping will be generated by a rotating axis which gets transformed into a reciprocating linear motion. The two main Variants of the mechanism are

W3 - Scrap motor + base shaft attempt

I found a piece of an old printer mechanism in my lab which had a rotating motor which I dismounted to check out.

I laser-cut a base plate in wood and 3d printed a shaft to connect and allow gears to be mounted on the axis as shown in the video below. Unfortunately, I found out that the specifications of the motors do not match what a flying bird would require.

The motor had the identifier KM-16A030-100-06150 which I found a reference from Adafruit imported from Shenzhen Kinmore Motor. I connected it to 6 volts to check whether it was working. The good news is that it works. The bad news is that as shown in the reference, the rotation speed is quite slow: around 2 Hz at the rated voltage (6V). I can technically increase the voltage to get higher speed, but the reference shows a maximum of 150 rpm. When increasing the voltage, I reached around 4 Hz at 8 volts, but this is not enough, and the motor would already start to get damaged. I will need to find another motor for the final prototype. However I might well just use that one for my initial attempts.

W7 - Working assembly for wing mechanism

I finished a first version of the assembly design with OnShape. This time, I did the whole mechanism within a sketch and iterated only on the sketch first, until I got it correct.

The fixed variable settings include:

The main constraint to make the system work is to ensure that the bar linking the reciprocating linear axis and the wings keeps a constant size. The reason for the horizontal distance between the pins is to avoid having to put the linkages on different planes. In this design, the values are D=1", H=1", W=L=0.6" and α=40°, β=20°.

W7 - First physical prototype

I also tried to create a 3d printed prototype to check the fabrication part. I exported all parts as-is (I know, who would do that? what about clearance?). I used the Objet printer in the CSAIL shop, and unfortunately this came with the issue that our waterjet cleaning station is currently broken. This meant doing the cleaning manually in a bucket of water for a while.

At this stage, the assembly, although super-light, showed a few problems:

  1. 3D-printed rods are not solid enough! Most of them would easily break during operation, and I could not assemble some without breaking them such as the long ones going through the shoulder.
  2. 3D-printed pins are as bad as 3D-printed rods.
  3. Clearance is needed for the wholes to allow rods through them, and let them rotate. A machinist friend suggested 1 to 2 thousands of an inch in diameter would be sufficient. After measuring the rod diameters, they were mostly exactly as expected 1/4 and 1/8 inch, so this seems great.
  4. The thin rib-cage may need to be thickened a big. One side actually had a defect from printing which I had never seen (a part seemed to have mis-fired, or maybe something mechanical happened there?)

My next attempt will thus be to reprint the main body parts with extra hole clearance, while increasing the strength of the rib cage. Instead of printing the rods, I will cut steel or aluminum ones since these exist in default 1/4 and 1/8 inch diameter. Instead of printing the pins, I will convert these as rods going through the rest of their base shape, and using metal for strength.

W9 - Second prototype and considerations

The objet printer is back on wheels and so I am printing a new version of the prototype. Because this week is Output Device week, I am also going to start integrating the motors into my frame, which requires extending the frame to the tail with its two servo motors and having a body for holding the brushless motor, the control / communication board and some battery.

While discussing about the rods with a colleague, we considered threaded standoffs which I could end with small screws and washers for clamping the standoff itself. A simpler version would be pure rods which would need some ending such as a shaft collar. Unfortunately, these tend to be expensive. Standoffs are also somewhat expensive (although much less), but they seem also limited in length. Thus, for now I will use 1/8 aluminum rods and tape/glue some washers onto their ends.

I modeled the gearbox very crudely for now (it may change so I don't know which to put there anyway), and added the main body up to the tail. Because there are multiple ways to model the tail, I decided to not worry about it yet and just create holes for housing the servo motors. To do that, I assumed the 4g servos which I had bought from HobbyExpress (for 4 dollars!), and created a 3d model of it using OnShape and some crudes measurements. I initially thought this would help me, but it didn't really help beyond the crude measurements.

I applied the basic clearance that a friend had suggested of 1/1000 of an inch and printed a new full body. After having done it, I don't think this was a good idea. It ended up being a waste because the clearance was not enough (by quite a lot). I tried to use sand paper to create larger holes for the servo motors in the back region, but eventually decided to just test and empirically get the correct clearance. I tested the clearance for the rod holes, as well as the servo cages using their basic measurement (1/8" rods and size of the servo rectangle), to which I added a clearance ranging from 1/100" to 0.035" (~1mm).

Given this clearances, I will be able to recreate the front mechanism and test it. One issue might happen with the excessive friction between 3d printed material and aluminum. I imagined using ball bearings for that, but these are expensive and complicate the design, so for now I will just go with some greasing. I will also need to add hole exits for the main shoulder shafts so as to enable support material removal more easily.

W10 - Main board for servos and DC motor

While last week was time for doing the servo and dc board, I only really tested the servos back then and while the dc motor was looking fine with an h-bridge, I really don't need one given that my motor won't need to worry about its rotation direction. I thus decided to replace with a transistor, and this took a few trials. When testing the board for the dc motor at the end of last week and for this week before the group project, I did multiple new versions to fix what I found out was a complete flawed design for the dc part and my own misunderstanding. I ended up creating that board 5 times before it finally worked as expected.

The two main issues I encountered were:

A posteriori, this makes full sense, but it took a while and some chance for me to realize the flaw (thank to the board surviving long enough for me to see with the oscilloscope that the heat was only troublesome when the mosfet gate was high (which was creating a short).

The new design finally works with the DC motor and PWMing for setting the speed.

W12 - Different mechanisms, more birds, some battery knowledge, and the wing material

Over the thanksgiving break, I explored the extent to which I don't know about ornithopters but many people do and have created interested birds (not only). I first learned about different types of gears and went over these reference tutorials including about gears, the flapping mechanisms, stability and control.

I also went over many other very interesting crazy drone and ornithopter project videos including an RC plane that floats magically, a dragonfly with four wings, an 18-wings ornithopter that looks more like a giant centipede (or as mentioned in the comments, one of the creatures of Nausicaae.

This last video led me to the work of Toshitatsu Munakata with many such strange creature-like ornithopters. This is very inspiring. I never thought these were possible.

I also found out about the recent bat robot from Caltech and its corresponding publication in science robotics.

Because we're getting near the end of the semester, I looked at the larger picture and learned also about batteries thanks to a great tutorial from Adafruit going into details about capacity and the maximum ratings batteries really draw current at and for how long. I am still not so clear as to how much capacity can really be pulled out of batteries for which I don't find any rated C value and it seems that even with lithium batteries (not Lipo), I may be able to get up to around 2 amps continuously (even CR123a may work). I will have to read more about the details of each individual types that I find (although I'd be happy to avoid Lipo since they can be quite heavy).

I went over my current choices for the wing mechanism and will try either using purely servos (which would simplify a lot of things), or using balljoints because the current friction of my pin/slot system is much too high to allow a bird to fly.

Finally, I received ripstop cloth that will be used for my wings! I got way too much, so I will have some spare to experiment.

W14 - Final boards with ATMega328P and nRF24

Given the success of the nRF24 communication, but the clear need for larger memory sizes and the extra communication needs, I decided to switch the board to a beefier one: the ATMega330P (mirror and datasheet). The wires / components of the main board will be:

The servo PWM requirement and needs for many communication pins confirm the case of the ATMega328P which has 6 PWM pins, two I2C pins as well as SPI and more. Another option from the eds lab would be the ATMega16u4 with 7 PWM pins, and the addition of hardware USB. However, I am going with the 328p version because of the wide support from its usage as Arduino's IC. Fortunately, there are lots of tutorials on how to each new components since this is what Arduino uses (e.g. hardware PWM). There's also the recent work of Renjith from the Fablab Kerala 2017, which details wiring and usage of ATMega328p.

Given the complexity of the board and my interest in having a backup plan and extra pins for merging with Natalie, I decided to use ground planes, and have a few vias to use a ground plane on each side. I found the ways by myself and later read this great tutorial.

When trying to trace the result with Eagle, I am encountering the problem that the thermal pads for ground are too small. I search for a while and find ways to modify the thermal pad width as well as the general isolation between pads and the plane, but not the thermal isolation width. Eventually, I find the answer from the great detailed Eagle demonstration of Gregoire Durrens in Catalonia's fablab. It happens that this setting is to be found in the design rules under Supply > Thermal Isolation. This was not an intuitive layout of the parameters (why not put it per polygon?).

I added the potential for an extra dc motor (e.g. by connecting a PWM pin header to it. I also added pin headers for all the unused pins, and decided to go two-sided with a ground plane on each side including a few vias for connections. This looks much nicer than all the previous boards I've designed so far!

I added the logo and signed it in Gimp. For the font in Gimp, I'm using TeX Gyre Adventor Bold at 143px for 1000dpi. Lowever values led to Mods missing most of it.

Friday 12/08 - Tracing and populating the first bird board.

When cutting the board, there arose a question about what the via size should be. Fortunately, someone had done that in EDS before, and that's Ben. I had seen him install the via rivets and knew where to find them. However the container mentioned 0.6mm inner diameter vias. Would that mean that the via holes had to be 0.6mm? Eventually I realized that this was not the case, and thankfully because 0.6mm is smaller than 1/32 inch, which would make their drilling complicated. Ben suggested to use 0.9mm diameters. He did that with the Othermill, I did it with the Roland, and it worked great too!

Before using the rivets, I asked Elysa to get her unpopulated via board she had made to try and do it myself. That was a GREAT idea. The point is that I broke her board by applying too much pressure. The first punch was not sufficient and the two sides were not connected electrically, so I went stronger the second time, but I went way overboard, and broke the board. Fortunately, Elysa didn't need the board, so I didn't destroy a needed board. Sorry Elysa, thanks for letting me learn!

After having traced the board, I went on with populating first the accelerometer and the ATMega328p. I encountered a problem with the small traces. I used to solder the ICs with the heated pen, but the fact that this chip has many thin traces from its pins led to the traces curling up as soon as I'd touch them with the solder pen. This meant I broke a few of them and although I tried to reconnect them, this was a lost cause.

After talking with my colleague, he suggested that I use solder paste and reflow for that. Thus I traced a new board, and instead of manually soldering each pin, I just dumped solder paste onto the traces, stuck the IC in the solder mud, and used reflow to do the actual connections. Although I had to clean some of the pins that had bridges, this was much easier than preventing traces from breaking, and it goes much faster than soldering manually too! For ICs, I'm going with solder paste + reflow from now on! I also used it for the accelerometer and it was all fine! The rest of the soldering went fine

I then designed a case matching the board holes and laser cut it (happy bird engraving!). The case also help encloses the board to protect it. The first bird board is ready to be tested!

Saturday 12/09 - Bird board testing

I created a code repository on Github for the tests and the rest of the code.

The first test was initially a hello world which would use hardware USART of the board, but there was an issue. It would not communicate. Thus I decided to start with a simpler test: toggling the LED to check that we can program and do the most basic thing. It worked!

Then I went on debugging hardware USART. My processor's clock was seemingly not programmed correctly. I looked quickly at fuses, messed up and decided to use "external clock". It should have been "external crystal oscillator (even though we're using a resonator). As a result, I was not able to communicate with the board nor program it because the fuse was set to using an external clock, which in reality means an external clock signal. This is usually generated by a clock component which has four pins. We don't have that. I was planning on a simple resonator, which corresponded to the external crystal oscillator.

I could not not talk / reprogram directly because a real clock was missing. Thus I decided to find for such clock. I didn't have one, but I though of using the clock signal of another board (chose the servo one) to outsource the clock signal on one of its pins (there's a fuse for that) and then reprogram the correct fuses on my bird board using the clock signal from the other board. This was convoluted, but It worked!

I fixed the fuse to 0x5E and now USART works!. I test 9600 bps, ok. Testing higher 115200, not ok. Checking listings online. 250k should work, but does not (maybe cable issue). I sadly broke my ftdi cable and had issues with the RESET header pin getting disconnected. I learned that free-standing pins are not good. I'll use multiple pins grouped together with pads next time.

Testing lower values. 19200 works, and above too, but only if pausing 1s after sending! In fact even 250k works if pausing data transfers, but then must wait 1s to send new stuff. 9600 bps can send again 1ms later!

Now testing PWMing servos. I looked at this tutorial, but was too generic, I need to go for 20ms periods. Found tutorial targeted at servos. In our case, 20MHz / 50Hz = 400k, which is too high for the counters we are interested in. By using the prescaler dividing by 64, we get 6250, which cannot be divided further, but is sufficient for the 16bit counter. We will need more than two servos, so we need also to use the 8bit timers.

Interestingly, different servos have different orientations. Same timing, but the orientation is inverted between two. It works with two at the same time in hardware!

Let's try with 4 (two for the direction in the back). This means using a 8-bit timer. There's no setting the top value on timer0, the top is just full 8 bits (255), which doesn't let us set the frequency unless the prescaler matches, and sadly it does not on timer0. However, we can use a mode where the frequency is set by OCRA, which disables one output (which becomes 50% duty PWM), but the other output can have any frequency. The details are nicely described in the Arduino's secrets of PWM.

Did the same on PD3, which gets us the 4th servo. Technically, we can also use PB3 for another PWM, but it follows the same logic of being the TOP for the frequency setting of PD3. More problematic would be that we need that pin for SPI communication, and thus cannot use it for that. Fortunately 4 PWM pins are sufficient. We test, and it works! However, the voltage drops considerably. Maybe we want to use stronger capacitors (currently 0.1uF and 10uF on the 5V line). I read online that it was common to have much larger capacitors (~400uF), so will try that if needed. The other issue is that the test power runs from USB at 5V which is not perfect for some of these servos that want 6V. Hopefully the batteries will make it work smoothly.

Briefly, I also tested the mini-circuit for dc-motor using PWM. This worked fine but I had to keep in mind that the frequency cannot be too low, otherwise the motor needs to draw a huge amount of current and basically fails at doing so.

Sunday 12/10 - Accelerometer and nRF24 testing

Read pages 260-298 on the TWI hardware support in the datasheet. Most of the code is provided, but some constants don't exist in my environment, and it only gives generic code that must be taken care of for special cases. I look online and found an I2C library targeting the same board. I inspire myself from it, but then find out that it also doesn't treat failure. An important thing missing in all those examples is what to do when the status register contains something different from expected (i.e. it shows a NACK). Most implementation just return the error and assume it is treated somehow. In practice, you want to send a STOP signal, otherwise the device is likely to block and you cannot go further.

I also struggled with the start sequence w.r.t. the address. The datasheet talks about different constants referring to the address with +W and +R. These correspond to the convention that writing to an address means the 8-bit address code is ADDR,0 whereas reading from it is ADDR,1. Also, starting routines usually tend to check for status TWSR & 0xF8 == 0x18 but that's only for one case scenario. In the accelerator case, there will be three good cases:

Interestingly, there's no acking the read data in our code (or corresponding examples).

I then went with integrating my past example of using nRF24 but using hardware SPI this time. This meant changing most of the configuration and eventually not requiring the DigitalIO library (since no need for software SPI!). It also meant going over the SPI implementation of Arduino and modifying it to reuse most of it. This is currently our only dependency from Arduino. I also changed a bunch of things in the nRF24 library to avoid creating extra dependencies, such as to millis() and delayMicroseconds() that all refer to the usage of a standardized clock / timer 0, which we will eventually have different since we're using it for a servo. I could eventually reimplement the millisecond timing with the newer clock if needed. For now, I just made sure to not need time computations.

I encountered two major issues over this evening.

ADC6 and ADC7
Initially, I thought that all pins have a potential digital output. I was wrong to assume that. My board used pins ADC6 and 7 for the CE and CSN pins used for transmit / receive. Fortunately, I had to use zero ohm resistors to reach the destinatio, and thus I just removed those and created bridges from external pin headers for PC1 and PC2 using jumper cables. In the revised board, I'll just use these directly and provide the ADC pins near the AREF one.

VCC versus GND.
For some reason, I didn't realize when designing the board, but I inverted the location of the power and ground for the nRF24 female headers! This came up as a weird effect when trying to connect to the board while the nRF24 board was on. While not connected, there is no issue, but when connected, it creates a short, and nothing burnt, but I could see the chip on the nRF24 getting warmer with the FLIR camera. Indeed, there was an issue. I cannot nicely fix that with this version of the board, so I decided to connect to the nRF24 using jumper cables from the two sets of new CE/CSN pins and the correctly ordered remaining ones from the female header.

Eventually, it took me a lot of debugging to get the SPI thing working. I am not exactly sure of what was wrong. Maybe timings, maybe settings, maybe the need for transaction setup. Eventually, it got fixed in my messing up with the code of both SPI.h/cpp and NRF24.h/cpp. I connected the receiver from my communication week and the bird board can communicate with it!

Monday 12/11 - Fixing the board, tracing again twice

I decided to not create a different board for the serial one, but instead change the bird board slightly. The changes include:

  1. Correct CE/CSN pins to be on two of PC0,1,2 instead of ADC6,7.
  2. Use pin header to expose RESET instead of single dangling pin.
  3. Add extra blue LED on T0.
  4. Use pin heaer sets to expose SPI pins (MOSI,MISO,SCK).
  5. Fix inverted GND/VCC on nRF24 female pins.

Tracing was no major problem except that I wanted to trace it twice, but there were many people in need of the SRM20. Thus for the second tracing, I decided to give a chance to the Othermill from Bantam Tools. This machine uses Eagle brd files directly, which means it is not as lenient and we cannot be creative in editing the path afterwards as an image as I have been doing frequently with the Roland. This means that for this version, there won't be any bird logo or signature. On the positive side, the tracing went smoothly and the calibration of the tool was automatic. The issues I had to go through included:

Population went fine. I used reflow for both the ATMega328p and the ADXL323. It took me a long time to understand why GND and VCC shorted: the extra solder paste was behind VCC and GND on the west side.

Testing went also quite well (besides a few initial issues). The LED test was directly ok. The communication helloworld / echo was failing until I realized that I had mis-connected the pins and was using the pair RX/RESET instead of TX/RX. The PWM tests were ok signalwise, but the motor would not work. I probed the voltage and realized something was odd because the 5V lines were 3V. I went on with the accelerometer and could not get the communication going. I checked the VCC line and realized it was 5V! I am not sure how this happened, but I seemingly got the wrong voltage regulator for the VCC line. The accelerometer accepts 3V only. In fact, this was not the problem with the accelerometer, but replacing the voltage regulator put the 5V back at correct levels, so the servos were now working. I removed the accelerometer (thinking it might have died from 5V), and resoldered a new one with (reflow again) but it would still not work. I examined the SDA/SCK lines and realized that there were both high without any communication happening. I then probed and realized that the SCL pin was not making contact with its wire! After resoldering it and checking all other pins of the IC, it is working! I tested the radio, and it worked too! I could not solder all the components of the second board because I need the vias (which I don't have tools for in my own lab). The next board is for tomorrow!

Tuesday 12/12 - Many bird boards!

I started by tracing two more boards, one with the Roland, and one with the Othermill. Eventually, there is a consistent problem with traces being irregular on the Othermill and resulting in very thin traces that are jagged and not nice to work with. I populated the previous Othermill board as well the new Roland one and realized that the ones from the Roland were much easier to populate and get working properly. As of now, the Othermill passes most tested but the accelerometer and I am suspecting that the accelerometer is fine electrically, nothing is shorted or badly connected. I can actually see the signals, but it doesn't get an acknowledgement with I2C, so reading X register fails. Maybe the chip is broken, but more likely the traces are too thin and irregular, leading to bad transmission. The nRF24 communication worked on that board, but was having lots of errors. I failed more than half of the time. Either there's a general clock problem, or the traces from the Othermill are bad and I should not use this board.

I populated the second bird board from Roland, and that went much much faster. Nothing shorted. I also decided to solder the large 2x4 female header before doing any of the surrounding work, which helped a lot. I had a lot of issues with that header in the Othermill population because I did it last and the soldering kept creating shorts. Now I know how to avoid that.

I had one single issue with the new Roland board which was the accelerator not responding initially. I checked the lines and realized that SCK was shorted. I could not see where (the pins of the ATMega were all clear), so I assumed it was below the ADXL323. I used flux gel (a variant from a colleague) over the accelerometer, and then used the heatgun to heat the accelerometer uniformly. This did pull a lot of extra solder from below, so it must have been fully shorted. This fixed the communication problem and now the second Roland board is fully functional.

I tried to do the same with the Othermill board, and it did take some extra solder out, but this did not fix the communication. Something else is going on with that board. Probably the trace being too short.

Wednesday 12/13 - Servo boards

During the last class, I looked at related robot projects of interest:

Since I am not sure about the bird being able to fly, I am going to use such vehicles as fallback plan. This should be simple to do given my board. The only trick is having multiple servo motors to simplify the mechanical design. Thus, I created an extension small dc board to connect to similarly to how I have a mini-circuit. I should never have made that mini-circuit in the first place since it is not connected...

I cut 4 of these (fast, easy on the Roland), and also cut a new simpler board. This was a bad decision a posteriori because I don't need it, and it doesn't really add much because even though it's smaller, I can't seem to get its accelerometer working. All other components are fine but the accelerometer. I switched with a new one, but it is still failing. Maybe the clock is not good enough? Maybe the capacitance is too big? I tried using smaller resistors nearby, didn't help. I stopped worrying about it and decided to just use it as serial board if needed.

At this point, I won't touch the boards anymore. I am so tempted to, but I must resist! Electronics was fun. I learned a lot and I like it! But now is time for the mechanical design!