Testing and modifying the Hubsan H501S quadcopter

This project is released under the GPL license



load dropping system activated when LED is switched on

HUD circuit diagram and software now available

sky text in color!

Auto pilot with latitude, longitude, and altitude working

gpss auto pilot code for Microchip PIC18F14K22:
And for those who cannot assemble it, here the hex file:

See below for circuit diagram.

This version does not support negative altitudes,
so if you start on top of a mountain and want to fly down into the valley, it wont work.
Uses one wire from the AFC_RX test point, one to the throttle, and one to the LED switch (with local transistor on remote board).

Seems to work 100% so far, there is a very slight movement when a next waypoint is found.
I made the code so it will first fly to the requested altitude for a waypoint, and only then move towards that waypoint.
This to avoid obstacles.
In the code is a also a vertical speed limit, but I deactivated that for now as it had the tendency to do a really soft landing,
it is difficult to write this code because it is not a normal PID loop, but sort of overriding the normal drone control in follow me mode.
So I wrote it a bit like I would fly, move the throttle for altitude it is an 'I' (integral) controller so it slowly starts to nullify altitude errors.
The main thing with V speed speed limit is that if you go down from say 100 meters to 1 meter will it be so fast that it digs a hole?
There are a number of defines at the start of the asm code you can use to set this maximum speed too, so....
And use at your own risk.
Great, apart from the V speed limit, cool it worked for the first time.
Wrote it last week but had to wait for a bit if decent weather, only no-rain for some hours was today, great, almost forgot the code... :-)
I added a NPN-PNP buffer (2 transistors), and some resistors to limit the effect on the throttle,
the 3k3 is the limit, the 680 Ohm mainly short circuit protection.
With all those wires dangling from the remote, the resistors _in_ the remote protect that, and the 680 Ohm in the control board protects that.
So, anyways decoding the AFC_RX testpoint altitude now works in asm ...
This all needs more testing but cannot hope for a better altitude control, this _is_ perfect.

Auto pilot flight test 100 % successful

did some programming and hardware design using a PIC 18F14K22 and a CMOS switch


Thoughts about next version
I think I solved how to also control the altitude from the SDcard.
Some scoping of the motor speed control (left stick up down) of the remote shows it is just a simple potmeter outputting a DC voltage of 0 to 3.3 V.
As there is real altitude feedback of the drone on the remote AFC_RX test point,
we can set up a loop to compare drone altitude to the altitude for each waypoint specified on the SDcard, so control the altitude it flies to each waypoint.
This would be cool, the serial input of this PIC is free to be used for AFC_RX, and it has a DAC output that can do 0- 3.3 V and can be fed via some attenuator to the left stick.
Only 4 more wires to this board? inputs: AFC_RX, AFC_TX, outputs: left stick up / down, LED switch (drop control).
Gotta try this! (and that code can be used for HUD anyways).
I now will reserve 2 bytes for altitude and 1 byte for 'commands' as the last 3 bytes of each SDcard sector, altitude in dm, so max 6553.5 meters should be enough...
This allows the drone to land at a specified longitude and latitude too, fly a stealth pattern below radar, etc etc.. deliver things, pick up things..
In the end why not get rid of the radio link altogether, and replace the 2.4 GHz transceiver module in the drone with this circuit, and emulate its i2c communication, its already been hacked by others.
That way no radio link issues... :-) hard to jam, OK you can still jam GPS, how about inertial OK... ;-)

So :-), just wrote some C test code to extract the altitude info from the remote AFC_RX testpoint into a variable, it does a checksum check too (cracked that), seems to work fine even without using the AFC_TX testpoint,
so maybe only need 3 wires....
Instructions are in the file, this is proto test code, and will be used by me to write the PIC asm, but should work on Raspi too, works even on my 64 bit Linux laptop..
The same coding method can be used to get all other info, say for HUD, from AFC_RX, see this remote_testpoint_AFC_RX_decode_key.txt AFC_RX data analysis from a binary dump.
I decided to use a 'mode' variable, a 'state machine' and not a whole lot of buffer space, as the PIC I use has little memory space.

Also wrote fly_waypoints-0.4.tgz
This is a program written in C for the Linux operating system to write to an old SDcard from a text file waypoints.dat that has lines with latitude and longitude for each point you want the drone to go,
you can also specify the speed towards that point in km/h.

Need not be a huge card, a very old one of 32 MB (yes Mega Byte, not Giga Byte) will do.
Note that I use no file system, just one sector per GPS data blob, one sector every 200 ms (5 Hz), so ALL other data on that card will be DESTROYED, back it up first!.
And make sure you do NOT write to an existing hard-disk, sda or hda for example, or if you have more than one disk sdb .. etc etc

Edit the provided waypoints.dat in the tgz archive for YOUR longitude and latitude and what you want the drone to do, and fill the card, see instructions in README.
You can get latitude and longitude from google maps, right click 'what is here'.

To read the card and then send the data to the Hubsan H501S remote,

I designed a small Microchip PIC based card reader for this project with an electronic switch that can automatically select between normal GPS from the remote and GPS data from the SDcard:

Build it, top view:

bottom view: gpss_PCB_bottom_IMG_5869.JPG

Mounted with Scotch double sided tape for a test run, pressing the white button for one second activates flying the pattern recorded on the SD card:

This is the wiring _in_ the remote to the gpss-0.3 board:

The GPS in the remote does 5 updates per second, so for 30 minutes flight time you need 30 * 60 * 5 = 9000 sectors, or 4.5 MB, any early small card will do,
however this gpss-0.1.asm only supports card sizes up to 1 or 2 GB (bigger ones have a different sector size IIRC).

Connect the unit in the remote between the GPS and the board, the signal from the board to the GPS should be left,
cut the data wire from the GPS to the board then link it via this gpss module, and use the supply +5 V and ground to supply the gpss board.
The gpss board has its own 3.3 V low dropout regulator for the card.

Now insert the card in the unit.
Switch on the remote, it should show normal GPS.
The green LED on the gpss board should light up.
To start sending the fake data, press the button on the gpss board for at least one second.
The green LED will go out and the red LED will flash each time a sector with fake GPS data is transmitted to the remote,
use follow me mode...
Pressing the button on the gpss board again for more than 1 second will halt transmission and switch back to normal GPS.
Both the red LED and the green LED will be on.
Pressing the button again will continue where it was on the card.
If end of data is reached (a sector starting with a zero on the card) then the red LED will go off, and the green LED will be on,
and control is again given to the normal GPS.

This is really for electronics guys and programmers who want to experiment with this sort of thing.
This is NOT a turn key solution, just an idea I am testing (one of many).
You need to be able to program in C, build electronics with SMD components, know about voltages and how to connect things,
else things will for sure be damaged.

I am using the PIC, not a Raspberry Pi for example, because of size, low power consumption, zero boot time,
and because the idea is also to try this in the drone and add something to latitude and longitude.
or just rewrite the whole drone system...
This PIC because I already wrote all that code, it is just old code adapted for this.
And this fake GPS generator may come in handy for other purposes.
Thing still needs to be tested in flight, has to wait because I am modifying the drone itself now, works on the remote though, see youtube video below.


Wrote some code to make a spoof GPS signal, one that moves north then south and then north again, output by default to /dev/ttyUSB0
click here to download the C code (for Linux)

Using an ebay USB to serial adaptor connected to the Hubsan remote controller GPS input:
and running the code on the laptop, has the remote accept the fake GPS signal generated:
signal accepted

when the program runs, the location of the remote changes, although it sits on the table next to the laptop here:

program also outputs to stdout:
program also outputs to stdout


bought a Hubsan 501S from China.
I am in the Netherlands.
Did some flying here:
great quadcopter!
There was a lot of wind (force 4) and even the pictures are great.

Had some trouble reading that display in the sun though.

Now I am in electronics, so have already many plans to mu^Hodify things...

One thing I wanted to add is multiple waypoints.
Now disassembling that ST ARM processor.. well I already wrote a binary to C converter for an other processor once,
you do everything only once in your life or should...
So then I thought how about fooling the on board GPS by adding a PIC microprocessor and simply adding some values
to latitude and longitude.

Curious, needed to know the GPS module baudrate, the NMEA sentences used for that, OK, setup a wiretap:
just using an ebay USB to serial module.


Now there was a surprise:

quadcopter GPS connector pinout:
black blue white red
0 0 0 0
IN? out GND +
The GPS module in the remote control has the colors exactly reversed...

bit time ~18 uS -> 57600 Bd

NMEA sentences logged with 6 or 7 sats reported:

GPS module in quadcopter seems to use GLONASS (the Russian system)?
Multiple sources like GPS plus BEIDOU and or GLONASS is signaled by 'GNRMC' versus 'GPRMC' for GPS only.

GPS module in quadcopter seems to use multiple sources.

$GNRMC,075549.60,A,5311.40200,N,00524.03001,E,0.066,,051016,,,A <- position GLONASS
$GNGGA,075549.60,5311.40200,N,00524.03001,E,1,07,1.59,9.1,M,45.7,M,, <- position GLONASS

OK, repeat procedure for GPS module in remote controller:

GPS module in remote seems to use GPS only:

$GPRMC,101752.60,A,5311.40200,N,00524.03001,E,0.267,,051016,,,D <- position GPS
$GPGGA,101752.60,5311.40200,N,00524.03001,E,2,07,1.28,-6.6,M,45.7,M,,0000 <- position GPS

OK, well sending fake data with for example a Raspberry Pi to the remote's GPS input should be no problem, using follow me mode
it should follow those NMEA sentences like a dog a bone. :-)
Then the drone can be left unmodified.

The other thing I want to do is connect one of my Sony starlight 0.001 Lux night vision cameras to that 5.8 GHz board.
However every freaking connecter is glued, could not even get those of...

Considered cutting the bottom of the drone, but looks too nice,
So one day I will have to gather enough courage to pull those connectors apart
Update...I have now half the connectors disconnected on the main board.

so I can find the analog point on that camera board, and add a video switch controlled perhaps by the LED control..
Hey just had it a few days, just starting ;-)

I did some testing on the lipo charger cell balancing unit (says 12V in 800 mA out).
I think you should not connect that to your car cigarette lighter... (also 12V).
Hubsan should provide a better charger.
Else wheels on fire?
I charge the batteries with it with a lab supply with current limit set to 1 A here,
should not you stop charging Lipos at 4.2 V per cell? Well it did not.

return to main page