Unable to trigger action via BlueTooth

Hi. I’m trying to create a dawn-simulating alarm clock that is triggered when my phone sends a specified character to the Linksprite BlueTooth shield.

Using the attached sketch I am able to initiate and configure BlueTooth between a set of specified ‘listening hours’. While the BlueTooth buffer is empty, the sketch updates the OLED time display every second. When the buffer is not empty I would like to test for receipt of a ‘*’ and, if found, trigger a LED to brighten.

Using my phone and PC, I can see the BT device, but am unable to send any data to it. Using bluetoothctl in Linux I am able to connect to the BT shield, but the connection is rapidly dropped as the shield becomes ‘unavailable’.

I suspect my loop (lines 71-117) is responsible, and have tried different configurations of if-else and while loops to update clock while listening for incoming BT. Grateful for any pointers.

/*
   Blutooth-triggered, dawn-simulating alarm clock
   v0.3
*/

// LIBRARIES
#include <LiquidCrystal.h>
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <SoftwareSerial.h>

// CONSTANTS
// LEDPWM pin
const byte pulsepin = 9;
// Bluetooth pins
const byte BTrxD = 7;
const byte BTtxD = 6;
// BT listen hours
const byte listenFrom = 00;
const byte listenTo = 23;


// VARIABLES
// LEDPWM
byte i = 0;
byte ledState;
unsigned long previousMicros = 0;
unsigned long previousMillis = 0;

int lookup[64] = {1, 2, 4, 6, 9, 12, 16, 20, 25, 30, 36,
                  42, 49, 56, 64, 72, 81, 90, 100, 110, 121, 132,
                  144, 156, 169, 182, 196, 210, 225, 240, 256, 272, 289,
                  306, 324, 342, 361, 380, 400, 420, 441, 462, 484, 506,
                  529, 552, 576, 600, 625, 650, 676, 702, 729, 756, 784,
                  812, 841, 870, 900, 930, 961, 992, 992, 992
                 };

unsigned long lampOnMinutes = 10;        //length of time the lamp will be on since sunrise ended
unsigned long lampOnMilliSeconds = (lampOnMinutes * 60 * 1000);

int duty;                       //high time in microseconds
long sunriseMin = 1;           //length of sunrise in minutes
long stepMillis = sunriseMin * 60 * 1000 / 64;
long pulsePeriodMicros = 5000; //pulse period in microseconds

// Bluetooth
boolean btRunning = false;
boolean btListening = false;
byte dotcnt = 0;  // counting '.'s sent to serial display for debugging

// INITIALIZE HARDWARE    // Check which pin BT shield uses to communicate w. Board !!!!
//                (rs, rw, enable, data4,5,6,7)
LiquidCrystal oled(12, 11, 10, 5, 4, 3, 2);
SoftwareSerial bluetooth(6, 7); // Bluetooth shield

void setup()
{
  Serial.begin(38400);
  while (!Serial)
  {} // delay for serial port to connect. Needed for USB serial monitor
  // set up the LCD columns & rows
  oled.begin(16, 2);
  oled.clear();
  // sync clock with from RTC
  setSyncProvider(RTC.get);
  pinMode(pulsepin, OUTPUT);
  Serial.println("void setup run OK");
}

void loop()
{
  btListenhrs();  // set btListening to 'true' between specified hours
  while (btListening)
  {
    printtime();  // update OLED
    if ( ! btRunning )  // if bluetooth is not running
    {
      setupBlueTooth();
    }
    while ( ! bluetooth.available() )  // if nothing in bluetooth buffer
    {  // print dots to serial monitor to show loop is running
      if ( dotcnt < 50 )
      {
        Serial.print(".");
        dotcnt++;
      }
      else
      {
        Serial.println(".");
        dotcnt = 0;
      }
      btListenhrs();
      printtime();
      delay(1000);
    }
    Serial.println("BT received");  // when bluetooth buffer not empty
    char receivedChar;
    receivedChar = bluetooth.read();
    if ( receivedChar == '*' )
    {
      LEDPWM(); // start LED PWM
      Serial.println("BT received = '*'");
      bluetooth.end();   // kill bluetooth
      btRunning = false;
    }

  }
  //  following code runs when we're outwith specified hours
  if ( btRunning );  // following lines to be run 
  {
    bluetooth.end();
    btRunning = false;
  }
  printtime();
  delay(1000);
}

void btListenhrs()
{
  if ( hour() >= listenFrom && hour() <= listenTo )
  {
    btListening = true;
  }
  else
  {
    btListening = false;
  }
}

void printtime()
{
  oled.setCursor(3, 0);
  if ( hour() < 10 )
  {
    oled.print("0");
  }
  oled.print(hour());
  oled.print(":");
  if ( minute() < 10 )
  {
    oled.print("0");
  }
  oled.print(minute());
  oled.print(":");
  if ( second() < 10 )
  {
    oled.print("0");
  }
  oled.print(second());
}

void LEDPWM()
{
  Serial.println("LEDPWM called");
  unsigned long currentMicros = micros();
  unsigned long currentMillis = millis();
  duty = lookup[i] * 5;
  if (i < 64)
  {
    if ( currentMicros - previousMicros > pulsePeriodMicros )
    {
      previousMicros = currentMicros;
    }
    if ( currentMicros - previousMicros < duty )
    {
      ledState = HIGH;
    }
    if ( currentMicros - previousMicros > duty )
    {
      ledState = LOW;
    }
    if ( currentMillis - previousMillis > stepMillis )
    {
      previousMillis = currentMillis;
      i++;
      //      Serial.print("i=");
      //      Serial.println(i);
    }
  }
  if (i == 64)
  {
    if ( currentMillis - previousMillis  < lampOnMilliSeconds )
    {
      ledState = HIGH;
      Serial.print("Time elapsed since sunrise=");
      Serial.println(currentMillis - previousMillis);
      delay(10000);
    }
    if ( currentMillis - previousMillis > lampOnMilliSeconds )
    {
      ledState = LOW;
      Serial.print(lampOnMinutes);
      Serial.println(" minutes is up! Lamp is off.");
      delay(10000);
    }
  }
  digitalWrite(pulsepin, ledState);
}

void sendBlueToothCommand(char *Command)
{
  bluetooth.print(Command);
  Serial.print(Command);
  delay(100);
  if ( bluetooth.available() )
  {
    Serial.print(char(bluetooth.read()));
  }
}

void setupBlueTooth()
{
  Serial.println("setupBlueTooth called");
  bluetooth.begin(38400);
  sendBlueToothCommand("AT+NAME=arduinoBT\r\n");
  sendBlueToothCommand("AT+ROLE=0\r\n");
  sendBlueToothCommand("AT+CMODE=0\r\n");
  sendBlueToothCommand("AT+PSWD=7531\r\n");
  sendBlueToothCommand("AT+UART=38400,0,0\r\n");
  delay(1000);
  Serial.println(btRunning);
  Serial.print("enableBlueTooth called");
  bluetooth.begin(38400);
  delay(1000);
  btRunning = true;
  Serial.println();
  Serial.println("setupBlueTooth completed");
}

Combined0.3.ino (5.34 KB)

  if ( btRunning );  // following lines to be run

Nonsense. What is executed if the statement is true is the ; (a no-operation). The following lines are unconditionally executed.

Thanks for noticing that, Paul. Best, Joe.