Intermittent Bluetooth - change to XOR for LED toggle?

Post Reply
dustnnotes
Posts: 1
Joined: Thu Mar 02, 2017 2:31 am

Intermittent Bluetooth - change to XOR for LED toggle?

Post by dustnnotes »

I ran into, and resolved, an issue with my Bluetooth communication, the result of which I wanted to put out there in case others are having the same issue, and for a possible change in the main code line.

I am building a quad based on the NanoWii, which uses the ATmega32u4. To allow wireless telemetry during flight, I included a Bluetooth module (KEDSUM Arduino HC-06 Serial Bluetooth) in the quad. Having used this BT module before, I was aware it requires a pull-up on the NanoWii RX signal, so I added a command to the setup section of Multiwii.cpp to instruct the ATmega32u4 to enable the internal pull-up on the RxD pin (PORTD |= 1<<2;). The BT module worked fine, with the exception of occasional intermittent/erratic behavior. When it failed, the updates to the GUI (either on the PC or an android tablet) would stop, and GUI EZ would give you some annoying verbal warning that the bluetooth connection was lost. After some experimentation (read days of debug and several rebuilds of the BT connecting cable), I noticed that the failures were happening when the drone was tilted more than 25 degrees off of level. I found in the Multiwii code where the >25 degree inclination was detected, and used to blink the LED in response. To blink the LED, it was using the PIN command to toggle the bit controlling the LED pin (through the LEDPIN_TOGGLE #define). It turns out the LED pin and the BT RxD pin are in the same 8-bit register (PORTD).

Poking around with the oscilloscope, I found that the RxD signal was experiencing what appeared to be contention (multiple drivers on one signal), or at the very list some defeat of the pull-up, if the LED was being toggled due to the off level condition - it went from a full signal swing when working, to a 1/2 swing when failing. Reading through the ATmega32u4 documentation, the PIN command seems to do some unique things to the entire 8-bit register if pull-ups are used. So I changed from using the PIN command to a PORT XOR operation in config.h (using the OVERRIDE_LEDPIN_TOGGLE set of #defines). The net effect for the LED toggle action was the following change:
PIND |= 1<<5; --> PORTD ^= 1<<5;

Since the change, BT has worked perfectly, and the oscope confirms full signal swing even if the LED is blinking!

So if you have been having intermittent issues with BT, you may be having a similar issue. To avoid this in the future, the question is, could the MultiWii code change from using the PIN |= (OR) command to using PORT ^= (XOR) for the LED Toggle function, so that pins using pull-ups in that same port don't get stomped on when the LED is toggled? I haven't done an exhaustive search, but I think it would just be changing PINx |= commands to PORTx ^= commands in the #define statements. Just a thought.

Post Reply