1

Now I am Running Arduino code for Bluefruit LE on bare ATMega328 with 8MHz internal clock, with Bluefruit connected, pin 0 and 1 RX/TX unused, and AT42QT1011-based capsense circuits (logical input to pins 1, 2, 3).

There appeared one problem: when I try to switch the device ON (with 4.5 V batteries, but the same with 5 V USB power), it happens only after three or more attempts. Each time "loop" stops after a second of what appears to be correct operation. For example, if I touch one of the capsensors on the first second of operation, and LED is on, it stays ON, which means, the "loop" is not run.

I have tried to put back the Serial (it was in use in the original echoDemo example), tried to put pollACI after digitalWrite to LED pins. See pin assignments defined in the sketch, those were re-checked with actual circuit.

Measured power supply current and voltage - there were no significant changes in it, even if both LEDs were on. BLE module at startup or while transmitting, was not causing any brownouts. In addition, checked input current and voltage with oscilloscope, and there were no anomalies as well.

NB, this is atmega328, without "p", so for the record I am using 0x07 efuse, 0xE2 lfuse and 0xD9 hfuse.

Also, if the device starts up, it will work fine for at least an hour.

What could be other reasons for such random early failure? (in average, about four attempts to switch on, sometimes starts even on first, second time)

The sketch in question:

/*********************************************************************
This is an example for our nRF8001 Bluetooth Low Energy Breakout

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/1697

Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!

Written by Kevin Townsend/KTOWN  for Adafruit Industries.
MIT license, check LICENSE for more information
All text above, and the splash screen below must be included in any redistribution
*********************************************************************/

//#define F_CPU 8000000

#include <SPI.h>
#include "Adafruit_BLE_UART.h"

// Connect CLK/MISO/MOSI to hardware SPI
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 2     // This should be an interrupt pin, on Uno thats #2 or #3
#define ADAFRUITBLE_RST 7

#define REDLED 8
#define BLUELED 9
#define LEFTPAD A2
#define RIGHTPAD A3
#define BADPAD A1

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);

unsigned int leftcnt, rightcnt;

void setup(void)
{ 
  pinMode(REDLED, OUTPUT);
  pinMode(BLUELED, OUTPUT);
  pinMode(LEFTPAD, INPUT_PULLUP);
  pinMode(RIGHTPAD, INPUT_PULLUP);
  pinMode(BADPAD, INPUT_PULLUP);
  digitalWrite(BLUELED, LOW);
  digitalWrite(REDLED, LOW);        
  delay(300);
  BTLEserial.setDeviceName("MYUART"); /* 7 characters max! */
  BTLEserial.begin();
  digitalWrite(REDLED, HIGH);        
  delay(300);
  digitalWrite(BLUELED, HIGH);
  leftcnt = 0;
  rightcnt = 0;
}

aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;

void loop()
{
  BTLEserial.pollACI();

  if (digitalRead(LEFTPAD)) {
    leftcnt++;
    digitalWrite(BLUELED, LOW);
  } else {
    leftcnt = 0;
    digitalWrite(BLUELED, HIGH);
  }
  if (digitalRead(RIGHTPAD)) {
    rightcnt++;
    digitalWrite(REDLED, LOW);
  } else {
    rightcnt = 0;
    digitalWrite(REDLED, HIGH);        
  }

  aci_evt_opcode_t status = BTLEserial.getState();

  if (status == ACI_EVT_CONNECTED) {
    boolean inp = false;
    while (BTLEserial.available()) {
      char c = BTLEserial.read();
      inp = true;
    }
    if (inp) {
      if (leftcnt > 5) {
        BTLEserial.print("LEFT");
      }
      if (rightcnt > 5) {
        BTLEserial.print("RIGHT");
      }
      if (digitalRead(BADPAD)) {
        BTLEserial.print("CENTRAL");
      }     
    }
  }
}

UPDATE: MCU's reset pin is pulled-up by a resistor. Bluefruit's RST connected to PD7 on atmega328 (also known as arduino digital pin 7). Also, 3.3 uF capacitor on the power lines near MCU's IC. (there are more near capsense circuits).

When I disconnect Bluefruit's power, the rest of the circuit (LEDs showing cap sensors state) works without failures after startup. So it looks like under some circumstances, control never leaves BLE code to return to the loop?

UPDATE 2: Found long list of reset causes (not sure yet whether relevant here): Arduino/AVR ATmega microcontroller, random resets, jumps or variable/data corruption ...

UPDATE 3: Added two 100nF bypass capacitors near GND / VCC pins on both sides. The problem is still there.

UPDATE 4: Performed all kinds of experiments, placing BLE module's power lines in different places, with different capacitors. Only in the case of separate power (common ground) the problems were different (but may be due to different times of turning module and MCU on).

UPDATE 5: May be relevant or not, but when I run MCU on 1MHz (8 MHz internal clock, divided by 8 - lfuse 0x62), success rate is better than 70%. The speed seem to be enough for my application, but of course near 100% turn-on success should be achieved.

MAY BE IMPORTANT: I have added watchdog to sketch (thanks to the "Make: Sensors" book by Karvinen & Karvinen, Valtokari):

  WDTCSR |= (1<<WDCE) | (1<<WDE);
  WDTCSR = 1<<WDP0 | 1<<WDP3;
  WDTCSR |= _BV(WDIE);
  MCUSR &= ~( 1 << WDRF);

And in the respective ISR red led is turned on or off once in about 8 seconds or so. And ISR code works (thus, MCU works all the time too, right?), even though the "loop" runs no longer.

Can this still be attributed to trouble with power or is it more likely control flow is stuck somewhere in the BLE library?

UPDATE: Well... As advised here, while trying out Serial (via microbot USB adapter), I understood, that it does not work reliably (if at all, sometimes eats characters, prints garbage, ...). Not sure whether SPI is sensitive to clock accuracy, but if it is, it may be the problem. Also, the circuit turns on always when powered from USB3 port 5V.

  • What is the wiring of your reset pin? Do you have bypass caps on the power pins? Write a sketch which outputs a running count on the serial port, temporarily connect a logic level serial port (USB converter cable or whatever) to the transmit pin, and monitor that to see if it keeps running or also experiences unexplained failure. – Chris Stratton Oct 4 '15 at 17:51
  • Updated. Do you mean a sketch, where I do not do any Bluetooth? As for connecting serial port, I will try. – Roman Susi Oct 4 '15 at 18:08
  • Yes, one with no bluetooth only to test the hardware of the MCU portion of your board. The capacitor you have described is more of a filter than a bypass. Don't remove it, but you should also have a smaller (and hence lower inductance) capacitor connected as directly across the power pins as you can manage. – Chris Stratton Oct 4 '15 at 18:11
  • Updated: the rest of circuit works without failures, when power disconnected from Bluefruit (or if all control wires disconnected - I have two separate cables). – Roman Susi Oct 4 '15 at 18:30
  • You should still try it connected, but with a program that doesn't use it, and only outputs on the serial. One thing to keep in mind is that BLE chips, especially first generation ones, can draw a lot of pulse current when transmitting. – Chris Stratton Oct 4 '15 at 18:31
0

The main problem cause was inaccurate internal clock. As soon, as external 8MHz crystal has been attached to XTAL pins (with a pair of 22pF capacitors to GND), problems with turning the board on disappeared.

Also, I found

while(1);

loop in the Adafruit's nRF8001 library, which runs whenever problems with the Bluefruit LE board are encountered. That is possibly why interrupts worked fine, but the whole MCU never returned to the main loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.