This page follows the development of an ornithopter, i.e. a drone flying by flapping its wings.
As mentioned a few times in class, there are several attempted drones projects within the class, fabacademy and beyond. I compiled a small table of related work and resources there that is of interest for people diving into ornithopters. A major MIT-related work on ornithopter is the master thesis of Zachary John Jackowski (mirror).
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
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.
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°.
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:
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.
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.
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.
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.
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.
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!
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.
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:
0x18
when address in writing mode has been transmitted and acked.0x28
when data in writing mode has been transmitted and acked.0x40
when address in reading mode has been transmitted and acked.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!
I decided to not create a different board for the serial one, but instead change the bird board slightly. The changes include:
RESET
instead of single dangling pin.T0
.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!
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.
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!
For the first prototype, I am focusing on making a ground vehicle. I found a nice looking press-fit car from Vaasa Hacklab. This will be my inspiration.
My design is on OnShape. I didn't put anything in the body of the car since this will contain the motors, battery and electronics. I am also not creating a bendy surface for the top arches, because I'll do that manually with a plastic film.
First version was way too big, so I measured the dc motors and created a new version that would enclose each motor on each side. That version is much more compact.
Lots of wiring done with female pins and heat shrink. Currently the cables are too long because I was very careful not to cut too much given my lack of wiring expertise. I will trim them down if needed at the end.
Connected to the power supply, it works. Connected to a 9V battery, it works for ~5 seconds, and then dies. I debugged and figured out that the power should not be regulated for these dc motors because the regulator, although tolerating 1.7A, does a poor job at transmitting current when the input is higher than 5V. I checked incrementing the voltage on the power supply from 3.7V where it goes very well, up to 5V, and then past 5V, the motors break down if they are pulling power from the regulated servo lines at 5V. However, they go perfectly fine if I pull power directly from the batteries.
I laser cut wheels.
I tested the 9V battery, but it's far from 5V, so I went with the Lithium-ion 2400mAh batteries I got that have maximum 3.7A discharge. On the power supply, at full throttle, it takes around 1.3A, so I may need such high current discharge. The batteries I use are 3.7V, so I am putting two in series, for 7.4V. I created a case for it (laser cutting again), and put wires through each sides (attached and soldered around the case, not the batteries, so we can easily change the batteries).
At this stage, it rolls in the air, but not on the ground. I need front wheels!
Today is the first working prototype!
I created front wheels by using threaded nylon shafts with wafers and blockers. These are consumable, so I don't expect them to survive very long since there'll be a strong torque on the front holes. The hope is that the nylon will break before the acrylic.
Attaching the wheels, moving the battery to the center (and the board to the front, freeing space for the front wheels, as well as the nRF24 being nicely in the front!
Plugging the power and it moves! But it's impossible to stop it, so I'm working on the serial board to control it.
I have the code for both the communication between the two boards and the motion (speed and direction). I try to plug everything together and run. I increase the speed (or in fact, really the "torque"), and it does not move from the ground. I increase beyond 30%, and smoke comes out. Now, it moves, but at full throttle and crashes against the furniture. I check the dc board, all components look fine, but after examination with the multimeter, the mosfet is dead and lets current go through. I resoldered the mosfet and changed the power settings a bit, explosion again.
I went on several times with different batteries (9V, 7.4V), it always ended up with the mosfet dying. From the oscilloscope, the voltage seems fine beyond some big spikes when the mosfet switches.
I decide to try to use a beefier mosfet since the current one explodes. New board, new tracing, new testing. It now works!
Meanwhile, I learned from the TAs that those voltage spikes need a solution and it is called Flyback diode. I thus redesign the board to add that diode with the beefier mosfet. New board, new tracing, and final testing. Everything seems fine.
This is just a prototype and I am going on further with the bird tomorrow. This prototype has two issues:
The following two videos show the wheel issue and a longer run (on the right, 2x real speed).
Harvesting more designs, I find this great review of ornithopter designs. I am interested mostly with servo-based flapping because it will be easier to manufacture. Fortunately, most of the servos I own have similar footprints (except for one larger one analog servo on the right below). They can do 60 degrees per 0.1sec, which may hopefully be enough for my bird to fly (top angle 40deg, bottom -20deg, total 60deg).
I created a basic wing arm design to be laser cut in three pieces of 0.11in acrylic.
The first version was way too big. I made a second smaller version.
I also designed a lock feature, but realized after cutting that the lock was only locking one layer, so it was basically useless. It would work with 5 layers, but then it becomes too thick. Since I tested the 3 layers version, I don't think the locking feature will be important. The screw already does most of the locking by itself. I'll just use tape to lock the extra two layers from rotating.
I implemented time measurement (easy with counter overflow every 20ms from PWM).
The code is based on the timer1 overflow interrupt updating a counter, which is read (atomically, use ATOMIC_BLOCK()
), and complemented by the timer1 counter for the remaining fraction of 20ms.
// assumes
// * /1 prescaler, 20MHz clock
// * timer1 /8 prescaler
// * timer1 freq+phase correct pwm at 50Hz
// * using ICR1 top at ICR1=25000
volatile unsigned long timer1_overflow_count = 0;
ISR(TIMER1_OVF_vect) {
timer1_overflow_count++;
}
unsigned long overflows() {
unsigned long o;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
o = timer1_overflow_count;
}
return o;
}
unsigned long seconds() {
return overflows() / 50UL;
}
unsigned long millis() {
unsigned long o;
uint16_t t;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
o = timer1_overflow_count;
t = TCNT1;
}
unsigned long T = t;
return 20UL * o + T * 2UL / 5000UL;
}
unsigned long micros() {
unsigned long o;
uint16_t t;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
o = timer1_overflow_count;
t = TCNT1;
}
return 20000UL * o + t * 2L / 5L;
}
void time_init(){
// this needs to be called before setup() or some functions won't
// work there
sei();
// enable timer 1 overflow interrupt
TIMSK1 |= (1 << TOIE1);
}
I can read time correctly, but when doing operations with it, there seems to be a bug somewhere. Values become randomly big from time to time. When I try to pin the problem down by stripping calls, the problem goes away.
I could not figure out what was the problem. I call it a day after debugging for 6 hours.
I went on debugging the bugs with the flapping code and decided to extract the code into functions for each problem at hand.
I'm also keeping state locally (within the function) with static unsigned long
for the time data that was going crazy.
This seems to have fixed the problem.
I still have no idea what happened the day before.
Maybe AVRs don't manage larger-than-16-bits words very well.
Maybe there was an alignment issue.
Maybe an interrupt issue.
Now is time to create the bird main structure as well as the tail! One key component I don't know yet is where the center of mass should be. I am putting the main board near behind the shoulders with the wings, but should I put the (heavy) battery next to the wings, or near the tail? And should I put the two batteries in a long series or next to each other (but then taking more width)? This may change the design considerably. The only way to figure it out is by trying with the battery at different locations.
Or not! My colleague who flies suggested to have an adjustable center of gravity using a weight on a slider. I'm going to use a 1/8in aluminum rod below, and have shaft collars to change the center of mass.
Element | Weight |
Each arm (servo + wing rod) | 29g |
Full Li-ion battery (two cells) | 33g |
Tail servo | 15g |
Aluminum rod | 12g |
Each shaft collar | 5g |
My design is again in Onshape (BetterBody). I cut a first version then added the rod key closer, then recut the shoulders to let the back of the servo (power cables) enter otherwise the servo wouldn't pass through. Finally, I compensated for the kerf using 1/100in offset for the shoulder holes. This is very tight. A bit too tight in fact. I broke the front shoulders.
Then I added the same key lock system as I had attempted before (but failed because the intention was wrong). Here it worked and the intention is also correct.
This lock piece connects to an 1/8in aluminum rod going along the body which I will use to redistribute the weight. By moving shaft collars along it, I can change the center of mass of my bird.
We put things together, and we have the base of the bird! There are a few things to add / change:
We when go towards putting wings. I lay the ripstop cloth on the ground, put the bird structure on top and draw the wings with a pen.
For the connection at the back, I use insulation tape to at the end points and cut (with scissors) a small hole through the wing end (that is reinforced with tape). I then connect that to the holes on the frame with a thread.
For the front, I attached the wings using the same insulation tape after folding the wings around the arms at the horizontal position (where it has the most tension).
And then, we can try to see what happens when it flaps.
At this point, it flaps, but I found out there are major issues:
I also discovered that the ripstop cloth I have feels a lot like paper. I have another one that is much smoother and may work better. Will try that one next.
At this point, the first problem needs to be diagnosed. I weigh each of the components (since there are new ones I laser cut and added) and figure out that the acrylic body is 53g! The acrylic shoulders are 16g. The board is 18g. The weight rod with three collars sum to 27g. The arms are 18g total. The wing is negligible.
I then go over each of the servos I have and the weight vary a lot. Of course, I chose the heaviest ones (19g each)
A valid question is whether I really need those servos. They have the highest speed: 60deg in 0.05sec with a torque of 3.7kg cm. The larger ones (analog servos) do 60deg in 0.12sec with a torque of 3kg cm. The blue ones do 60deg in 0.10sec with a torque of 1.8kg cm. I could not get a datasheet for the HK 15350A servo. Found in EDS, but not on the fab inventory. These are a mistery! They do perform fast, but they are not as precise and tend to vibrate a lot.
Given the weight difference and stats, the only other servos that would have been a good value for weight would be the blue one, but I only have one, so I can forget about that. I will keep the metal servos.
Reducing weight.
I won't do that by changing the servos.
However, it's clear that the main body can be hollowed out a lot!
The top plate is 2/3 of the weight of the bottom one. Meaning the board hole takes a third of the weight.
For the bottom plate, I'll just use a sparse grid instead.
And I will hollow the rest with a sparse grid too for both the top and bottom since they don't need to be full.
By having different grids on top and on bottom, I can get better structural properties.
The other components are not fruitful for weight reduction.
Increasing tension.
First, I will use aluminum rods (or carbon fiber?) for the arms so that they bend less.
Following this tutorial, I am going to stitch the wing more carefully along the whole body of the bird.
I will also stitch rods on the wing (probably in cardboard) to create a better structure.
Increasing lift.
Beyond increasing tension, I will also increase the area of the wings.
There are two dimensions here: the arm length, and the tail length.
Having rods will also enable having a wing that is not triangular but more rectangular.
One day to go!
New wing arms.
Discussing with a friend mechanical engineer about the shoulder design, I learn that the most likely failure point, as expected is the connection between the rod and the servo clamping layer.
To minimize failure, I should be maximizing the contact surface area.
The shape of the servo connection doesn't matter, the area does.
To maximize it, I will have the rode slightly off centered parallel to the servo connector so that it can go as far as possible.
I cut it, and realize that the distance between the rod enpoint and the boundary is too small. The piece might break!
I change the design to include more space between. The shoulder looks nice, but it doesn't fit with the body's neck. I sand it down to fit.
And then we put the rod and realize that the clearance was not very good and the rod moves slightly inside while in motion.
To fix that, I decided to include fine silica sand inside the hole (0.3mm grains). This does help a lot! Now the movement directly transmit to the rod.
We have now much larger potential wings! They need a better lighter body.
New body.
On this thread, I realize that my wing design should probably be a single wing instead of two.
I can do that by clamping the wing between the two sheets of the body.
This will create much better tension!
I also need to reduce the body's weight.
I modify my two-layers design with a longer, thinner tail, and I hollow most areas.
On the good side, the body weight dropped from 53g to 27g (26g less) On the bad side, the new arms sum to 54g total, whereas the previous ones were only 18g (36g more).
I dropped the metal rod to change the center of mass, so we have 27g less, but this will be taken back by the batteries. The total weight has not changed much. The hope is that the new wing attachment and their larger area will help for flying.
New (single) wing.
Measuring the full size to model the (single) wing.
Wing arm span is around 95cm.
From arms to tail is around 29cm.
I need to clamp the back of the tail, so I won't be able to use the whole tail.
I first attempted to laser cut it, and then realized from the material interface that Nylon requires air assist. The laser cutter in CSAIL doesn't have air assist surprisingly. The one in EDS does, but then it seems hazardous, so instead I'm going with manual cutting. Laying out flat on the ground with heavy objects to put the sheet in tension.
I mark it for one side of the wing, then fold it over and transfer the marks. Scissors cutting, and we have a large wing! I got some help to fold the wings on the arms and tape them.
Now is time for the rods. I created two sets of rods: one from the arm center to the tail back (as all online designs I've seen have that one), and then a few spreading from the arms to the back of the wing.
I used a lot of tape today!
In the resting unpowered position, the wings fall straight vertical. It's a bit heavy...
We power it, and it does stay flat (or with the wings up when pressing the start button with speed 0). The initial awakening was painful.
We then try to flap, and the result is pretty bad. The motors are currently pulling from regulated power. One motor pulls much less current because it's second in the power line. I hope that when using the battery, they will not have that issue.
At this point, the last test shows that it's likely that our motors are not sufficient for the bird to fly. It's based on regulated power, so maybe battery power will help, but it cannot do full movement beyond the 10% speed (1 cycle per second). Two cycles per second are already slightly too much. We may have a bird that flaps but does not fly. We will see.
Adding the battery.
For the power, I'm using the same set of two Streamlight CR123A batteries in series.
They pack lots of power (2500mAh) with high current discharge (max > 3V).
Because of space issues, I'm just using tape around the two batteries tight together, and soldering wires for the ground (-) and power (+) lines.
The car has a case, but it has lots of space available.
Now it can stand on its own without any wire intervening from outside!
This page gives more details about those following questions. Here we only answer the question regarding the final bird itself. This does not answer the questions fully because the rest of the prototypes also contributed somewhat to these questions. The remaining answer lies within this document.
See there for the detailed bill of material.