100KM

U4eake's showleds, arming and low battery warning leds

Following up on the success of my relay low battery warning leds I have expanded that code to include a complete lightshow and to be compatible with the newest ACM codes (2.1.1) and the APM1 hardware.  APM2 hardware MAY work, but I don't have APM2 at this time, so no guarantees.

Credits to Bill Sanford and Max Levine whose work has been an inspiration and a basis for these leds.

 

1) Software side :

By using the agmatthews userhooks it is now much simpler to upgrade to a new firmware without having to change the code each time.  You just have to copy 2 files and change setting in the APM_config.h.  The needed files AND my config.h file (for version 2.1.1r5) are in the following file : U4eake_showleds.zip 

Updated files for ArduCopter 2.5 (compile with arduino1.0 relax patch) : u4-showleds.zip  These still work for ArduCopter 2.5.3.

Update files for ArduCopter 2.6 : Showleds_ACM2.6.zip  Because motors were put in a library, every motor_armed in the showleds code had to be modified to motors.armed().  Also you have to put

#define COPTER_LEDS 0

into your APM_Config.h file to disable the new copterleds, which are enabled by default.


You need to copy the usercode.pde and the usercode.h files into your arducopter directory (overwriting the files already there) and add the settings below to your APM_config.h.  DO NOT just copy my APM_config.h, it is only included as an example to clarify the settings.

#define MOTOR_LEDS 0                                   // 0 = off, 1 = on
#define SHOW_LEDS 1                                    // set to 1 to enable AN7-AN15 controlled led lightshow
#define RELAY_LEDS 0                                    // set to 1 to use the old relay led low battery warning

#define COPTER_LEDS 0

#define BATTERY_EVENT ENABLED

#define LOW_VOLTAGE 9.9
#define MID_VOLTAGE 10.6
#define VOLT_DIV_RATIO 3.33

#define INPUT_VOLTAGE 5.26

Also uncomment the 50hz agmatthews userhook and the mediumloop userhook (remove the // in front of it) so it looks like this :

#define USERHOOK_50HZLOOP userhook_50Hz();

#define USERHOOK_MEDIUMLOOP userhook_MediumLoop();

 

The voltages can be adjusted to match your desires.  If you have a 4S battery for example, you should put higher values, like 13.2V for the LOW_VOLTAGE.  INPUT_VOLTAGE is the voltage that goes into the APM (usually the voltage from you ubec).  VOLT_DIV_RATIO is an calibration value that you can adjust so that your reported battery voltage corresponds to the real battery voltage.

 

After compiling the code with arduino and uploading it to the APM board, you also need to set battery monitoring to option 3 : battery volts

3689416774?profile=original

 

That's it for the software modifications if you have a hexa or are happy with the patterns as they are !  On a quad or octo you may want to adjust the patterns a bit, but I'll explain that further down this blog (see Adjusting Patterns).

 

The code and blink patterns are optimised for use on my hexa (6 leds strips on the arms + 2 spare ones).  

The leds will go on when motors are armed and out when disarmed.  During flight, different flashing patterns can be selected with Ch7. The other use of Ch7 is not affected, so you can still use it for simple or recording waypoints. The leds will flash with the last pattern in this file when ch7 is high (recording waypoint or simple)
When battery gets below the first threshold (MID_VOLTAGE = 10.6V), the ledshow is overridden and the leds will flash with following pattern : led 1,3,5 on/off and led 2,4,6 off/on. So if the first ones are off, the others are on and vice versa.
When second threshold (LOW_VOLTAGE)is reached (9.9V) the leds will flash quicker.

 

2) Hardware :

The code uses the AN8 tot AN15 analog ports (portK) on the oilpan of APM1.  In the picture you can see them labelled  AN0-AN15.  AN8 to AN15 are the ones on the right (4x2 pins)

3689439386?profile=original

 

You can either connect 1 led directly to each port (the ports can supply 40mA current) or you can use a ULN2803 darlington transistor chip to drive the leds according to the following shedule (thx to Max Levine for this schematic) :

3689414934?profile=original

This shedule is for a quad and uses a ULN2003.  The ULN2803 has 8 ports instead of 7 and if I remember correctly it can supply a little more currrent (500mA per port).  A typical hobbyking 12V ledstrip of 1m (60 leds) consumes about 300mA, so normally you should be able to hang 1m of ledstrip on each of the 8 ports.  That should be plenty !!

You can get the ULN2803 in your local electronics shop or online here : Canadadrones - ULN2803

The darlington chip lets each input control the output directly across on the other side of the chip.  So nr1 in the picture above, controls output 16,   Nr 2 controls output 15 and so on.  If you look at the pinout picture of the oilpan, you'll see that nr 1 is connected to AN8 and nr2 is connected to AN10, so AN8 in the pictures above controls the red leds, and AN10 controls the green leds.  Get it ? ;-)

 

After the brainsurgery it will look something like this :

ULN2803.jpg

Now you just have to put a heatshrink over the ULN2803 chip and tuck all the wires away nicely.

CAREFULL : in the picture above I had soldered the wires to the wrong ports (side of the compass).  That's what you get when working on your copter till 4 in the morning...  It took me a day to figure out why my leds didn't work as expected.  So you have to solder your wires on the OTHER SIDE (side of the usb connector).  I didn't have a picture of when I soldered it right.

Finally you'll also have to set up your board for battery monitoring (option 3 : total voltage) by soldering the voltage dividers and connecting battery voltage to AN0, which is explained in the wiki here :  Voltage sensors on APM1

 

3) Adjusting the blinking patterns

First you'll have to understand a little about bitmath in arduino : http://www.arduino.cc/playground/Code/BitMath

To save processor cycles I've opted to drive the portK of the atmega1280 using direct portmanipulation. 

If the above all sounds too complicated : here's the simple explanation.

In the usercode you'll often find something like PORTK = B00101010;  This instruction actually turns leds on and off.  0 means off and 1 means on.  Each number turns 1 port off or on, and the first number after B turns port AN15 on. So the ports are B-AN15-AN14-AN13-AN12-AN11-AN10-AN9-AN8 of shorter written : BAN15...AN8

If you would now like to turn the red leds on and the others off in the picture above, this would be PORTK = B00000001; (turns AN8 on, and AN8 is connect to nr1 on the darlington, which turns on red leds)

If you wanna turn the 2 blue ledstrips on and the others off it would be PORTK = B01010000; (ports AN12 and AN14 on, which are connect through the darlington to blue leds)

All 4 strips on would be PortK = B01010101;

Ofcourse for hexa's and octo's this depends on which AN port you have soldered to which nr on the ULN2803.

 

Now we can turn leds on and off, but they still don't blink or "rotate".  For the blinking a counter is used and depending on the counter, leds are switched on and off.  The counter runs in the 10hz or 50hz loop, so you can time the blinking.  If counter =5 when in the 10hz loop will correspond to half a second.  

For "rotating" arms I use the bitmath again, more precisely the bitshift operators << and >>.  These simple shift all bit a few places.  so 00000001 << 1 becomes 00000010.  The 1 shifts 1 place.  By now you understood that this is an easy way to make the leds "rotate".  Just shift the B00000001 1 place each loop cycle and your 'on' leds will shift an arm each cycle, making them look asif they rotate.

 

4) TO DO

On the 8 port ULN2803 there are still 2 ports left unused on my hexa.  I'm planning to use those to replicate the gps status light and maybe a failsafe warning light.  I've also thought about using them to drive leds in the form of a smiley :-)  Other ideas are always welcome !

 

I'm using the relay now to ignite fireworks on the hexa.  But that's a story for another blog ;-)

 

That's about all I can think of telling you, and by now my fingers are tired and my brain is mushy.

I hope you enjoy these leds and don't scare too many people with your new UFO ;-)  Feel free to ask questions in the comments below if something is not clear.

Ow, and ofcourse I assume that you know what you're doing if you solder on your board.  I take NO responsability if something goes wrong and you break it !  Do this at your own risk ! 

 

Regards,

U4

 

E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones

Comments

  • 100KM

    Gustavo, search the forum for Copterleds and you should find some usefull info.  Also you can look in the Leds.pde source file, there is a comment section where the basics are explained.

    Triantafillos, I think the circuit will also work with 5V from a bec and 5V led strips.

  • I have a question too. Will work the same circuit, not power by lipo, but from bec with 5v and 5v led strips?

    Thanks in advance!

  • It is not clear what is the functionality included on the std arducopter code for apm2, and how to use the different led outputs abailable .
    Could somebody clarify please ? It seams to me that some functionality has already been included on the firmware but the manual is not reflecting this changes.

    Many thanks
  • What a nice new option!

    I'm wondering where the equivalent connectors (1,2,3,4) are located on the APM 2.5?

    Another idea........... is there a way to route the signal leds out  from on the (APM2.5)board to external leds?

    Regards :)

  • Robert,
    Sorry for the delayed response. I used the holiday weekend here as an excuse to go heli-free for a few days whilst staying a couple of hours drive from my home at a weekend getaway called La Costa Spa & Resort. The vacation served as dual-purpose since I hope that the short break from this addiction might reinvigorate my preoccupation with all this MR and SRH involvement that has been feeling fatigued lately.

    I am back and just browsed b this thread to see whether there's been muh progress. I was delighted to see your super-informative response and wanted to sa thank you. I kno you are busy around here, so feel honored that you took the time to look up archived information to help me out. Speaking of busy with other topics: I'm assuming you saw my offer to help R&D for those few interested in furthering our capabilities, with specific emphasis on variable-pitch quad rotors? Let's get going on that; I am ready whenever you have t e let mr know how I can help.

    Sincerely,
    Jonathan Lederer
  • Good point.  I'll give it a shot.  I already have a spare anyway.

  • 100KM

    Robert, looking at the schematic of the ULN I don't see why it wouldn't be able to sink current from different voltage sources.  Haven't tried it though.  If you try and you fail, it'll only cost you $1.

  • U4: Question, do you know if the ULN2803 can sink current from different voltage sources?  Can I have some LED's supplied with 12V, and some with 6V?  I don't see why not as it's just providing a ground path?

    Jonathan, I haven't read through everything so I'm not quite sure what I'm doing, but I dug up some old Devlist emails I wrote back in the day, and this may help you?

    This gets more confusing...

    So, I've started to rewrite Motor LEDS, and I took the original code:
    Which if you follow the code through, you see they used pins 62, 64, 66, 68.
    I am now using 62 thru 69.  Otherwise the code isn't significantly changed.  I have uploaded this, and all my pins turn on.  This is good.
    But... pin 62-69 are NOT PortK.  PortK is Pins 82-89.  Pins 63-69 are Port J, and Pin 62 is a ground!

    The traces sure looks like it is pins 82-89 being used.  So how does this code even work?!
    Is there some kind of pin re-mapping going on behind the scenes in Arduino?
    This seems to indicate that there is not:
    This seems to agree with 62-69:
    Another detail: is the APM2 using an Atmega1280?  That's what the schematic says.  I don't believe that's correct?  Where did you get that Schematic from Phil?  It appears to me that  the block with the Atmega1280(2560?) is just a direct copy from the APM1.0 schematic with nothing changed other than the title at the bottom.   
    Anyway, I want to get the LEDs working with APM2, but I have no idea which pins to use.  In fact, I wonder if the situation is a little bit broken.  The existing Motor_led code compiles for APM2, it is not #define restricted to APM1.  So it seems like it's in operation, but I don't know if there is actually anything hooked up to those pins?  
    Which pins are these being used?
    Is it simple AN0 thru AN11?
                                                                                                                                               
     
    Ok, so now looking at this:
    This:
    http://arduino.cc/en/Hacking/PinMapping2560 

    And the APM2 Eagle board layout and just following the traces, it seems like the sonar is on PF0.  Voltage is PF1...
    PF0  Sonar
    PF1  Voltage
    PF2  Current
    PF3  Optical Flow Enable
    PF4  Motor LED 1
    PF5  Motor LED 2
    PF6  Motor LED 3
    PF7  Motor LED 4
    PK0  Motor LED 5/RSSI
    PK1  Motor LED 6/Camera Shutter
    PK2  Camera Roll
    PK3  Camera Pitch
    Now the tricky part is that the pins for PK1, 2 and 3 go through a solder jumper.  I'm not sure what the jumper does.  It appears to make that pin changeable from connection to PortK to some other function, but I have trouble following the trace because it weaves in and out of the board.  I can't find any documentation of this, so it's not clear what this is for, or what the default solder jumper position is.  This picture makes it clear.
    Looks like the SJ slaves that header pin to either PortK, or a PWM output pin. 
    Complicating matters, this image:
    Shows only 3 pins free and clear for LED usage.
    So now I know which pins I *can* use for Copter LEDS, but I don't know which pins I *should* use.  It gets complicated if people want to use those other pins.  If I offer the choice, then it complicates the code even further.  There's a lot of permutations.
    It's too bad because so many PortK pins aren't even used, they're just dry.  I guess they wanted to make the board as small as possible and rationalized IO.
                                                                                                                              
    Then look at these bits of code:

    #if CONFIG_APM_HARDWARE == APM_HARDWARE_APM2
    #define COPTER_LED_1 AN4 // Motor or Aux LED
    #define COPTER_LED_2 AN5 // Motor LED or Beeper
    #define COPTER_LED_3 AN6 // Motor or GPS LED
    #define COPTER_LED_4 AN7 // Motor LED
    #define COPTER_LED_5 AN8 // Motor LED
    #define COPTER_LED_6 AN9 // Motor LED
    #define COPTER_LED_7 AN10 // Motor LED
    #define COPTER_LED_8 AN11 // Motor LED
    #elif CONFIG_APM_HARDWARE == APM_HARDWARE_APM1
    #define COPTER_LED_1 AN8 // Motor or Aux LED
    #define COPTER_LED_2 AN9 // Motor LED
    #define COPTER_LED_3 AN10 // Motor or GPS LED
    #define COPTER_LED_4 AN11 // Motor LED
    #define COPTER_LED_5 AN12 // Motor LED
    #define COPTER_LED_6 AN13 // Motor LED
    #define COPTER_LED_7 AN14 // Motor LED
    #define COPTER_LED_8 AN15 // Motor LED
    #endif

    #define AN0 54 // resistor, vdiv use, divider 1 closest to relay
    #define AN1 55 // resistor, vdiv use, divider 2
    #define AN2 56 // resistor, vdiv use, divider 3
    #define AN3 57 // resistor, vdiv use, divider 4 closest to SW2
    #define AN4 58 // direct GPIO pin, default as analog input, next to SW2 switch
    #define AN5 59 // direct GPIO pin, default as analog input, next to SW2 switch
    #define AN6 60 // direct GPIO pin, default as analog input, close to Pressure sensor, Expansion Ports
    #define AN7 61 // direct GPIO pin, default as analog input, close to Pressure sensor, Expansion Ports

    #define AN8 62 // NC
    #define AN9 63 // NC
    #define AN10 64 // NC
    #define AN11 65 // NC
    #define AN12 66 // NC
    #define AN13 67 // NC
    #define AN14 68 // NC
    #define AN15 69 // NC

  • 100KM

    Hi Jonathan, I know the feeling of thinking you have it, starting on the board and then running into issues.  That's when you have to push through and ask specific questions and/or spend lots of time figuring it out, gambling and testing :-)

    So ready, here goes.

    1) The APM has it's ground from whatever powers it.  It's not shown in the schematic cause it's not really relevant to what we are doing.  The apm is supposed to be powered and have a ground, else nothing will work.  The APM is not even completely shown for that matter.  I guess to be complete you could draw a black line from the APM board to the - of the battery with a bec or esc in between, but it would complicate the drawing without adding much info.

    The APM pins AN8-AN15 put out 0 volts when off and 5V when on and can provide max 40mA current.  Enough for a single 5V led, not good enough for a 20 led strip of 12V leds, so that's why we need the ULN.  It acts as a relay.  When the ULN sees 5V on its pin 1, it will connect pin 16 to pin 8 (ground) thus turning the red leds on.  It might be good to look up the datasheet of the ULN to further understand its working.

    2) This is more complicated and took me a few days to figure out on my APM1 too...  PortK is the name of 8 pins (PK0 - PK7) on the ATmega1280 processor (the large black chip).  I think they are the same on the ATmega2560.  The datasheet of the atmega will show that.  These are the ports the atmega processor knows about, these are his ports.  It doesn't know AN ports, AN is what the ardupilot board designer decided to call them cause they are Analog ports.

    So now you have to find out to which pins on the board these little chip pins are connected.  Or better, you have to find out to which little chip pins the AN ports of the APM2 connect.  Then you look up in the Atmega datasheet which port that is and then you change the instruction accordingly.  So if you find that APM2 ports are connected to chip pins PJ0-PJ7 then you use the instruction PORTJ=B00000000 instead of PORTK.

    I also like nightflying (although forbidden in my country).  I have 2 spare ports on the ULN and was thinking of making one light up a smiley face, and one a sad face :-) and :-( 

    Hope this gets you going a bit !

    Greets, U4

  • I suppose I can thin of two quick inquiries of you:

     First off, is the diagram that shows the older ULN2003 IC and the LED strips connected to each of the first 4 channels a complete diagram?  What I mean is that, to me, I see it as missing a reference to ground for the signal coming from the APM board.  I must be missing something in the logic here that you can help me to digest.  The concept makes sense to me (regarding the physical connections in place as shown) in that you use the LV logic of the arduino to in turn flow much higher voltage through transistors using a separate power source.  I suppose part of it is that I simply do not know what signal is being output from the APMs AN1-8: PWM freq., voltage, ...??

    Secondly, and this I very much related to physical connections, but ventures into the software side at least a bit more than th trivial question above: on the APM 2 boards, AN8-AN15 are no longer the same name nor location as compared with its predecessor.  In the code that I've read and re-read, I don't seem to see definitions for the AN ports of the ApM2.  This is throwing me for a loop when I look at it.  Relatedly, do the PORTK statements remain effective for range of output ports that are numbered differently than for the hardware on which they were intended?  

    All in all, I feel like I have a handle on things when I read your code.  Then, I muster up the courage to go get hands-on with it -- then I get lost all of a sudden and the notion of sending you (and LeFabvre, and whoever the third original dev was who helped cultivate these w8tty bits of code and logic) n ApM2 board "on me" makes more and more sense because I keep stumbling over something here and just am not making the connection (ie. the light bulb just isn't illuminating in the cartoon bubble above my head).

    Recently, I read through all the CopterLED information and code available and, again, thought it was gonna be a breeze.  Then, in turn, when I confidently approached the actual APM2 board to get the project going, the same disconnect occurred and I just am dumbfounded once more!  

    I must be very close to figuring out whatever dumb thing is getting in the way of my success in this subdomain.  You're very welcome, by the way, for my interest in your work; can't really help it, I have always been a night-flying junkie.  To date, my favorite nighttime visual effect was in the form of a set of carbon fibre helicopter blades for my wonderfully acrobatic 450-sized TRex that, when I first caught the R/C bug, I used to literally run 10-15 batteries a day through whilst learning 3D maneuvers.  these blades had, molded into the leading edge of each blade, a number of LEDs (approx 15, if I remember correctly)arranged in a single file; green on one blade visible from above, and red on the other blade visible from below.  Each blade also had built-in single cell rechargeable lipo and embedded CPU of some kind.  What th blades did was exploit  "persistence of vision " and allow the creation of simple text (2 lines @ 24char, 3 sets with a pause between the pages) and archaic graphics (cute though, like smiley face) on the actual surface of the disc created by the spinning of the blade.  It was WAY cool. I prided myself on flying all my circuits inverted back then, so I programmed my blades as follows:

    BoTToM (red, viewable when copter was upright and overhead) would cycle:

    "PRACTICE SAFE SEX!!" and an asterisk for the graphic every 3 seconds back and forth

    ToP (green, viewable when overhead Heli was in inverted flight) would cycle:

    "GO F*^&# YOURSELF!!!" and a smiley face every 3 seconds.

    Thanks again, and hope you liked the memory.

    Jonathan

This reply was deleted.