Tag Archives: mpu9250

Silkopter FC

Finally, after some DHL delivery trouble the boards arrived:

pcb

After watching a few tutorials I immediately tried soldering the most difficult part – the MPU9250 chip. Turns out – if you don’t have the right flux type it’s impossible. I managed to ruin 2 boards in the process and broken 1 chip…

broken pcb

Notice the PCB changing color next to the IMU I2C pins and the ‘dry’ look. The pin header holes are also darker than the others due to the heat.

 

2 days later my new flux came: Chip Quick SMD291 ordered from farnell. This time it went much better as I was able to solder 2 chips in 5 minutes, from the first try. The trick is that tacky solder flux doesn’t evaporate from the hot air and keeps the chip floating while the solder melts (and prevents oxidation). When the solder flows, the chip kinda snaps into place and that’s it. In my first tries I used a flux pen that dried immediately and the friction between the chip and the PCB was greater than the solder surface tension – preventing the chip from snapping into place.

So this is the board almost complete, except for the ADS1115 ADC that didn’t arrive still:

final pcb

 

The last few days I spent trying to get the RF4463 chip to respond on SPI1. I expected surprises and I got them:

  • first of all, activating SPI1 on a RPI3B results in boot times of 2 minutes due to an interrupt issue with the UART driver. Solution: disable the bluetooth and use ttyAMA0 instead of ttyS0
  • next I simply couldn’t get the chip to respond at all. 2 days I spent on this until I went back to the schematic thinking the wiring is not ok. Then I realized that the chip select is connected to CS2 which is GPIO 16 but the SPI1 overlay I used uses GPIO 18 as CS. Duh! Solved by adding dtoverlay=spi1-1cs,cs0_pin=16 in /boot/config.txt
  • that’s it – it works now 🙂

 

In the last moment I added 3 WS2812B RGB LEDs thinking that I will be able to drive them with PIGPIO. I didn’t check the datasheet closely enough to see that they need PWM impulses in the order of 0.5ns whichare way below the resolution of the library.

So today after soldering the LEDs I realized that I cannot drive them. Desperate, I turned to the schematic and saw that by sheer luck I connected the LEDs to GPIO 13 – which happens to be the hardware PWM channel 1. Yaay – exactly what this library needs.

So I downloaded the lib, configured it on DMA channel 4 and PWM channel 1 and ran it and voila! It works with <1% CPU usage:

final pcb2

 

So now I have almost all the hardware working – the dual IMUs, the Baros, the RF chip and most importantly – vital for a 2016 multirotor – the LEDs.

 

I have 6 unpopulated left to give away (for free of course, shipping covered by you) if someone is interested!

boards

 

So now – back to software. The RC is coming along nicely.

Schematic & PCB #2

I finally finished the schematic and PCB and will send them to DirtyPCB today.

It is in HAT format ready to be used with the new (when it’s released) Raspberry PI A3.

It supports either a RF4463F30 or a RFM22B (on the back side) connected to SPI2, a MPU9250 IMU and MS5611 baro connected to SPI1 and/or another set of MPU9250 & MS5611 connected to I2C.

On the same I2C there is an ADS1115 for current/voltage sensing and 2 extra ADC pins broken out on a separate controller.

PIGPIO is connected to 6 PWM pins – 4 for motors and 2 for a gimbal.

In the end I also had sufficient space to include 3 NeoPixels (or WS2812b) RGB LEDs to show various status info. They are all driven by only one GPIO using a serial-like protocol and I think I can make this work with the PIGPIO wave functions.

 

In a future revision I might add a buzzer for alerting comm errors – like link lost – and expose 2 more PWM outputs.

 

First I have to check if the PCB will be manufactured ok.

 

Some screenshots:

 Update July 14th: 

I made some tweaks to the SCH and PCB to include a diode for the leds, according to Adafruit.

In the previous version I was powering the LEDs from 3.3V which is below their minimum voltage. Datasheet here.

To fix this I routed the led VCC to 5V but through a diode.
The WS2812b leds expect the high input voltage to be within 0.7 VCC. With a 5V VCC this results in a 3.5V high level. The raspberry pi provides a reliable 3.3V on the GPIO and there was the risk of the leds failing to understand the PI. There are 2 solutions – a level converter to increase the high level of the PI to 5v or lowering the VCC of the leds a bit. I choose the second ’cause it’s way simpler. A diode drops the voltage from 5V to ~4.3V which in turn drops the expected high level to a convenient ~3V.

Two other changes that I did are:

  • Fixed some signal traces that were running parallel on the top and bottom sides – like the I2C and some PWM outputs. Not sure how important it is but just to avoid any nasty coupling
  • Broken out the I2C to a pin header to eventually connect a PX4Flow.

The board is in production now and I really hope it gets here by Friday.

 

In the meantime I’m investigating a PPM input solution in case I want to use a standard RC system with this board.

 

Schematic & PCB

The Silk FC schematic is finished and the PCB is 70% done.

Here are some screenshots:

 

There is a bit of wiring acrobatics with the PWM connector as I couldn’t find an eagle 6×3 header so I improvised one from 3 2×3 headers… Ugly but it works.

As soon as they are done I will put them on github.

The board is 2 layers only and has the specs from my last post.

I intend to add a footprint for a RFM22B as well as the RF4463F30 so I can choose which to use, in case one of them has issues.

The board should work in both single-imu-baro more and also in dual-imu-baro.

I got 2 MPU9250 and MS5611 from my previous Drotek 10 DOF boards with a bit of hot air.

 

I’m really curious how it will end up as this is my first SMD board and especially my first QFN package. The MPU is really really tiny – like 2 square millimeters.

 

 

UAV Editor

The signal processing view of a quadcopter has one obvious result – a node editor.

Still WIP but here’s the first screenshot:

Screenshot from 2015-03-02 00:16:43

The left top part has some nodes that compute a Reference Frame, a Location and a Battery State from a MPU9250 imu, a MS5611 baro, a Ublox GPS and a RC5T619 ADC.

There are some processors there that do some resampling or convert streams (like an ADC_Voltmeter that converts from ADC to Voltage).

The nodes are read from the brain running on the Raspberry Pi. Each node has:

– a unique name
– a type (class_id)
– a list of inputs
– a list of outputs
– an init_params json which represents fixed configuration that is applied when the node is created. Stuff like IMU sample rate or gyro range.
– a config json that has things that can be changed at any moment – like where the inputs/outputs are connected or calibration data, or cutoff frequency for LPFs.

Each input/output has a name and a stream type that determines where it can be connected. There’s also a sample rate that has to be matched.

Next is to allow uploading of the json configs to the brain and more editing features.

The node editing is done with this library.

Signal processing

While thinking about ways to implement multiple sensor support – for several GPS or gyroscopes – I realized that an UAV can be modeled as a signal processing device.

It can be split like this:

  • sources – like the MPU9250 which generates 4 signal streams: acceleration, angular velocity, magnetic field and temperature, the SRF02 sonar which generates a stream of distances
  • streams – like the acceleration from the imu, or the location stream from the GPS. Each stream has a sample rate
  • sink – like the pigpio PWM. Sinks accept streams of a certain sample rate only
  • and processors – like low pass filters (LPF) or the PIDs, or the AHRS. Processors don’t have an inherent sample rate. They adopt the rate of the input usually.

All of these are implemented as nodes with several inputs and outputs. All nodes are added to the HAL layer and both their properties and connections are configured from a json file.

The important aspect is that – like all signal processing – signal rate is very important and has to be properly matched between nodes to satisfy the nyquist frequency. For example the PWM has a max sample rate of 490Hz so any signal higher than ~240Hz will be seen as noise. Higher frequency signals have to be resampled and low-pass-filtered before fed in the PWM node.

I started implementation last week and – after many rewrites – I have a model that ‘feels right’.

Here are some drawings:

Ahrs_0

Here the MPU9250 node exposes 4 sub-nodes (not shown) – an accelerometer, a gyroscope, a magnetometer and a thermometer. Each of these outputs a stream: acceleration stream, angular velocity, magnetic field and temperature.

The frequency of these streams is determined by the sensor. Acceleration and Angular Velocity are at 1Khz while magnetic field is at 100Hz. Temperature (not shown in the pic) is at 10Hz.

The Magnetic Field stream is fed into a Resampler node that takes it from 100Hz to 1000Hz, ready to be fed into the AHRS procesor node. The reason for this is that upsampling the stream needs a low-pass flter to avoid parasitic frequencies. A sample rate of 100Hz can carry at most a 50Hz signal so when going to 1000Hz sample rate this max frequency has to be maintained. Simply cloning each sample 10 times is not enough as this adds a lot of high frequency harmonics.

So now all signals at 1Khz sample rate are fed into the AHRS which outputs a Reference Frame stream, also at 1Khz. This reference frame represents the rotation of the UAV relative to earths frame of reference.

Right now I have a complimentary filter for the AHRS node but in the ear future I will write an extended kalman filter (EKF) for it – as soon as this tutorial is complete.

Note200215_0

This diagram uses the AHRS output – the reference frame stream – plus the acceleration stream again to output 2 new streams – gravity vector and linear acceleration. These 2 streams will be further used for dead reckoning and stability pids.

Note200215_1_0

Here I have the basic rate PIDs diagram. The angular velocity stream is first resampled from 1KHz to 50Hz (the pic says LPF but it’s actually a resampler node). The reason for this is that the usable bandwidth of the quadcopter is ~20-30Hz. Anything higher than this is noise.

The stream is further passed to the Rate PID processor node which outputs a torque stream (also at 50Hz). Torque is converted to thrust using a model of the motors+propellers (configurable of course), which is fed to the motor mixer and then in the PWM sink.

The advantage of this system is that new processors can be easily added to accommodate new hardware. For example if I want to use 2 GPS sensors I will add a redundancy processor that takes 2 location streams and outputs the healthiest one. Or I can merge them together to get better accuracy – while the rest of the nodes don’t even know nor care about this.

Basically I have minimal coupling between the elements of the system which talk through very well defined (and type safe) interfaces.

The ground station is also simplified. It can enumerate ll the nodes, read their configuration as a json value, change it and push it back to the nodes. Changing a filter cutoff will become trivial.

So far I still working to match the old functionality but in 1-2 weeks I believe this system will be ready for a test.