Tag Archives: raspberry pi

GPIO ramp up/down

While testing the menu system yesterday I notice a strange problem. Sometimes pressing  a button triggers not only the GPIO associated with that line, but adjacent lines as well.

My first thought was ‘wiring problem’ as everything is crammed inside the RC with 30+ jumper wires, so I started shaking and moving wires around but it didn’t seem to change much.

Then I turned to code – I thought I might have a bug – and after close introspection the code seemed correct:

  • Set the column GPIO as output
  • Set the column GPIO high (+3.3v)
  • Read all 4 line GPIOs, see which button is pressed
  • Set the column GPIO as input to turn it off
  • Repeat

Everything seemed ok so I took out the oscilloscope and probed one of the columns.

Here’s what I got:

screenshot-from-2016-11-21-09-50-26

I probe 2 column GPIOs here and the trigger is on the green trace. The 2 problems become obvious – first of all the pin goes low too slow so by the time the next pin is high, the previous one still has ~2.3V, enough to register as high. And second – the code lops through this without any delay between pins.

On paper, the code works correctly but not so in real life where there is inductance and bandwidth limits for triggering GPIOs high/low.

 

The fix is trivial. I changed the loop like this:

  • Set the column GPIO as output
  • Set the column GPIO high
  • Wait 2 microseconds for the pin to settle
  • Read all 4 line GPIOs
  • Set the column GPIO low <— this causes the voltage to drop way quicker than just setting the gpio as input
  • Set the column GPIO as input
  • Wait 2 microseconds for the pin to settle
  • Repeat

 

Here’s the trace on the oscilloscope after the changes:

screenshot-from-2016-11-21-10-08-42

 

As you can see there is a clear, safe distance between triggering adjacent column GPIOs and (not visible in the trace) the lines are sampled right in the middle of the high interval.

This works perfectly now.

Advertisements

RC – First HW Test

After a few more failed attempts to print the RC case with ABS I finally gave PLA a chance. Ordered some black 1.75 filament from amazon and a few days later I printed the case successfully from the first try. PLA is great, it’s easy to print, it smells like sugar when printing – as opposed to the chemical smell of ABS – and the quality is really good. However it doesn’t like to be sanded. At all! It’s like trying to sand rubber – or more accurately – sugar.

I decided to stop worrying about the finish so much and ordered some plastic primer and white matte paint. In the meantime I finished the RC PCB and made all the connections and did the first real test.

Here it is:

Features:

  • 3 axis gimbal for yaw, pitch and roll. It’s a very high quality one with bearings and hall sensors instead of pots
  • Motorized linear pot for the throttle. I went for motorized because when changing flight modes I want to have the throttle in the correct position to avoid stopping the motors
  • 0.96″ OLED screen for status info, calibration and other things
  • 8 ADC channels – 4 for the sticks, 3 for the individual LiPo cells and another one for the Gimbal Pitch pot
  • a 4×4 button matrix implemented with pigpio for all the buttons and switches
  • 2 rotary encoders for live editing of parameters like PIDS, menu navigation, etc
  • 2x 2.4 GHZ wifi diversity for the video feed
  • 5.8 GHZ wifi for the phone connection – to send the video feed through
  • 433 Mhz 30 dBm link for the RC data
  • 2.2Ah 3S LiPo battery for ~5h of continuous use, with charger/balancer port

The screen is connected through i2c1 at 1Mhz together with 2 ADC sensors (ADS1115).
I’m using this library to talk to the screen but noticed that a full display update takes ~20-30ms during which I cannot talk to the ADC sensors. To fix this, I changed the library and implemented partial screen updates. Now I can call screen->displayIncremental(1000) and the class will send incremental lines to the screen for 1000 microseconds (1 millisecond). The overall FPS is the same as with full updates but I get to do other things while the display is being updated. To avoid tearing I also added double buffering to the class and an explicit swap method.

The end result is a 40-45 screen updates per second but each update is split in 12-13 partial uploads with ADC readings in the middle. So I can sample the ADC at ~600Hz which is more than enough for a RC system.

The RC has 13 buttons and 2 rotary encoders requiring a total of 17 GPIO. Since I didn’t have enough I ended up grouping the 13 buttons in a matrix of 4×4 following this tutorial. This allows me to reduce the number of GPIO to 12 (8 for the matrix and 4 for the rotary encoders). I implemented the matrix reading using PIGPIO and added some debounce code to avoid detecting ghost presses/releases. Seems to work great and it’s very fast.

 

Most of the HW is done and it’s a mess of wires. I’m working now on some videos of potting it together, making the connections and the calibration.

The next step is to work on the phone app to receive the video feed, although I think I will give the quad a test – line of sight.

I really want to fly soon.

RC Almost Finished

Here’s the case after my best attempt:

 

It looks… bad. The paint coat is horrible and full of scratches and the screen is too big.

But worst of all, the screen is not bright enough in direct sunlight. Not even close. I don’t have a photo but after brief testing I’d say it’s unusable.

So I’m pretty disappointing with the result – I ended up with a big, heavy RC system that is too dim to be usable for FPV.

I searched for a week for alternative capacitive touch screens, preferable in the 5-7 inches range but found nothing bright enough under 100 euros.

So after a mild diy depression I got an idea that will solve at lease 3 of the issues – cost, bright screen and the RC size: use my Galaxy Note4 phone as the screen.

The setup will look like this:

  • The quad will send video through 2.4Ghz, packet injection (a.k.a. wifibroadcast method) and RC stream through 433Mhz
  • The RC will receive both video and RC data and relay them to the phone using another 5.8Ghz wifi UDP connection. The phone will decompress the H264 video using OMX (or whatever is available) and display it with telemetry on top.
  • The phone will also act like a touchscreen interface to control the RC/Quad

 

Basically this is what most commercial quads (like Mavic) are doing. I’m sure the video link is 2.4GHz due to longer range than 5.8 and better penetration and the connection with the phone is done over a 5.8, low power link.

 

So the next steps are:

  • Redesign a smaller case that will accomodate a Raspberry Pi 3, the RC stick and fader + buttons and wifi cards
  • Write a quick android application that can connect to the RC and decompress the video stream
  • Profit!

RC Case

I finished designing the case that will fit the silkopter RC system.

Here’s how it looks like:

 

Components:

  1. Raspberry Pi3
  2. Official Raspberry Pi 7″ touchscreen
  3. A 3 axis gimbal stick for the yaw/pitch/roll
  4. A ADS1115 ADC to sample the sticks and the throttle fader
  5. A motorized 10K fader for the throttle
  6. A brushed Pololu motor controller. Pololu modules are awesome btw
  7. 2 clickable rotary encoders to tune custom parameters like PIDS
  8. 2 switches to save/restore the custom parameters
  9. 7 push buttons to change flight modes, RTH and other cool things

 

The case is pretty big due to the screen. It’s 22.3 cm tall, 19.5 cm wide and 4.4 cm deep – so I couldn’t print it in one piece on my Prusa I3 printer. So I had to split in in a few pieces, print each one and them glue them together.

After a few failed prints, here’s the end result:

img_0742

 

 

I’m painting it now with matte black paint and tomorrow I will put all the components together.

The only problem I’m having now is that I broke my touchscreen while fitting it in the case so I need to order another one.

 

 

Raspberry Pi Camera V2 & GPS

Last weekend I did some tests with a UBLOX Neo6 GPS running next to the V2 camera to see if it’s better than the V1 camera.

The GPS had a clear view of half of the sky with a building to one side so not necessarily ideal conditions. The GPS was powered from the Pi with the cable wrapped through a small ferrite bead.

Here is a picture of the setup:

IMG_0384.JPG

Here is the graph showing the Satelite number, PDOP, Position accuracy and velocity accuracy reported by the GPS:

Screenshot from 2016-07-17 11-16-49.png

There is a clear jump when turning on the camera where PAcc goes from ~2 to ~3.2. With the V1 camera this jumped to 30-40.

The jamming indicator showed 15-20% regardless if the camera was off or on. With V1 the indicator jumped to 100% when turning the camera on.

The number of satellites is the same, as is the PDOP and VAcc.

 

The spectrum measured with the SDR was crystal clear even when the antenna was almost touching the camera ribbon cable – which btw is unshielded.

 

So my conclusion is that the V2 interferes with the GPS way less than the V1 and with a bit of (optional) ribbon cable shielding it should be ok for a multirotor.

 

 

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.

Classic TX

I thought to give my Flysky TH9x TX a change to use it with silkopter so I made a new node called “CPPM Receiver”. This samples a CPPM stream on a GPIO and outputs the PWM streams that can be fed into the main node.

 

It uses the PIGPIO setAlertFunc which calls a user provided function for all level transitions on a certain gpio pin. The resolution is 5 microseconds which is waay more than needed for a standard CPPM stream. The gap between channels is 400 microseconds so way bigger than the minimum resolution of the library.

 

It started more of a proof of concept but in the end I think it’s perfectly usable.

Here’s a video with it in action, connected to a D8R-II receiver:

 

 

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.

 

New GS

In the past week I started working on the new Ground Station. The problems I’m trying to fix are:

  1. I want a dedicated GS, not a laptop. For this purpose I’m trying a raspberry pi with a 7 inch display (the official RPI touchscreen display), together with a custom case, 2 RC sticks and various buttons. The reason is that a laptop is unwieldy, not bright enough in direct sunlight, tends to get busy with other tasks in the worst moments, doesn’t have a touchscreen (at least my current laptop doesn’t)
  2. I want a nicer interface that focuses on the main purpose of the GS – flying. The current one focuses more on editing the nodes of the quad.

So I started a new project, the GS2 using QT’s QML and a touch driven UI. So far so good, here are some screenshots:

 

The resolution is 800×480, a bit small TBH but enough for now. The display size is 7″.

So far the experience in QML is great, it takes very little time to build a nice, functional UI. It does require to build proxies for anything that has to be exposed from the C++ side to qml but that’s a good thing as it separates the UI from the logic.

The main things that I still have to figure out are:

  1. How to create a property sheet in QML. This is used to show the init params and configuration for nodes. This UI is generated in the current GS so there is no need to write custom UI for every node but just a description of the parameters in a json file.
  2. How to write the node editor in QML. Screen real-estate is limited and the node structure can get complex. One possible solution is to allow node groups. Basically take the IMU and low pass filters ang build a meta-node – a Filtered IMU – and treat that as a new node in the UI. Or group all the Navio sensors together in a new Navio Node and avoid all the current clutter. This is an interesting feature that deserves a few weekends.

 

The physical part of the GS – the case, sticks, buttons are still to be designed but I’m sure I can come up with something in a few weekends. The main parts will be:

  • A raspberry pi to drive the display and run the actual GS
  • An AVR to read the sticks, battery voltage and buttons. Could be replaced with another multichannel ADC and the RPI GPIO
  • A few analog sticks. I’m thinking to salvage the ones in my TH9x remote or buy a few of these or these
  • A RFM22B and 2 TL-WN722 wifi cards for the comms. This will be in a detachable module in the GS, connected by a usb cable so I can mount it higher or on top of my car.
  • LEDs, piezo speaker etc

I already have the rpi + display and the first version of the GS working, check out the video here:


All in all – a few months of work. I hope I don’t get demotivated.