Pulsating LEDs

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_BADGE by David Adkins

main.cpp

Committer:
davidadkins1
Date:
2017-01-16
Revision:
10:fdf87f019389
Parent:
9:5f0732aa3008

File content as of revision 10:fdf87f019389:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string.h>
#include "mbed.h"
#include "BLE.h"

#include "UARTService.h"

#define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
                               * it will have an impact on code-size and power consumption. */
                               
#define TXRX_BUF_LEN                     20

// sinetable is loaded with a progressive tick time
// designed to continuesly vary the PWM period
// for a 5 secound time frame.
extern float sinetable[256];
                               
// LED defines and variables
#define GREEN_LED_PIN                   P0_7
#define RED_LED_PIN                     P0_3

#define LED_ON                          0x00
#define LED_OFF                         0x01
#define MAX_LED_LEVEL                   0x0A

// Command set
#define CMD_GREEN                       0x01
#define CMD_RED                         0x02
#define CMD_OFF                         0x03

#define TICK_FRAME          0.02

DigitalOut      LED_SET_GREEN(GREEN_LED_PIN);
DigitalOut      LED_SET_RED(RED_LED_PIN);
Ticker led_pwm_tick;    // for LED PWM

uint8_t next_angle = 0;         // Counter for 5 secound pulsating
float next_tick;                // Current PWM pulse width
uint8_t led_brightness = 0;     // Used to scale the PWM period
                                // 0 is off, 10 is always on

#if NEED_CONSOLE_OUTPUT
#define DEBUG(STR) { if (uart) uart->write(STR, strlen(STR)); }
#else
#define DEBUG(...) /* nothing */
#endif /* #if NEED_CONSOLE_OUTPUT */

BLEDevice  ble;
UARTService *uart;
uint8_t txPayload[TXRX_BUF_LEN] = {0,};
//static const uint8_t uart_tx_uuid[]   = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};

//GattCharacteristic  txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);

// Local prototypes
void green_pwm_tick_off(void);
void green_pwm_tick_on(void);
void red_pwm_tick_off(void);
void red_pwm_tick_on(void);
void pwm_tick_min(void);


void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    //DEBUG("Disconnected!\n\r");
    //DEBUG("Restarting the advertising process\n\r");
    ble.startAdvertising();
}

void WrittenHandler(const GattWriteCallbackParams *Handler)
{   
    uint8_t buf[TXRX_BUF_LEN];
    //uint16_t bytesRead;
    //uint16_t index;
    //if (Handler->handle == txCharacteristic.getValueAttribute().getHandle()) 
    {
        //ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), buf, &bytesRead);
        //memset(txPayload, 0, TXRX_BUF_LEN);
        //memcpy(txPayload, buf, TXRX_BUF_LEN);  
        buf[0] = uart->_getc();
        
        
        if(CMD_GREEN == buf[0])
        {
            led_brightness = uart->_getc();
            
            if(led_brightness > MAX_LED_LEVEL)
            {
                led_brightness = MAX_LED_LEVEL;
            }
            
            if(MAX_LED_LEVEL == led_brightness)
            {
                LED_SET_GREEN = LED_ON;
                led_pwm_tick.attach(pwm_tick_min, 5.0);
            }
            else if(0 == led_brightness)
            {
                LED_SET_GREEN = LED_OFF;
                led_pwm_tick.attach(pwm_tick_min, 5.0);
            }
            else
            {
                led_pwm_tick.attach(green_pwm_tick_on, .001);
                next_angle = 0;
            }

            LED_SET_RED = LED_OFF;
        }
        else if(CMD_RED == buf[0])
        {
            led_brightness = uart->_getc();
            
            if(led_brightness > MAX_LED_LEVEL)
            {
                led_brightness = MAX_LED_LEVEL;
            }
            
            if(MAX_LED_LEVEL == led_brightness)
            {
                LED_SET_RED = LED_ON;
                led_pwm_tick.attach(pwm_tick_min, 5.0);
            }
            else if(0 == led_brightness)
            {
                LED_SET_RED = LED_OFF;
                led_pwm_tick.attach(pwm_tick_min, 5.0);
           }
            else
            {
                LED_SET_RED = LED_ON;
                led_pwm_tick.attach(red_pwm_tick_on, .001);
            }

            LED_SET_GREEN = LED_OFF;
        }
        else if(CMD_OFF == buf[0])
        {
            LED_SET_GREEN = LED_OFF;
            LED_SET_RED = LED_OFF;
            led_pwm_tick.attach(pwm_tick_min, 5.0);
        }
    }
}

void pwm_tick_min()
{
    // do nothing in this tick while LED's are off
    // 5 second tick to allow processor max sleep time
}

void green_pwm_tick_on(void)
{
    next_tick = sinetable[next_angle] * ((float)led_brightness / (MAX_LED_LEVEL - 1));
    
    LED_SET_GREEN = LED_ON;
    led_pwm_tick.attach(green_pwm_tick_off, next_tick);     
}

void green_pwm_tick_off()
{
    next_tick = TICK_FRAME - next_tick;
    
    LED_SET_GREEN = LED_OFF;
    led_pwm_tick.attach(green_pwm_tick_on, next_tick);
    
    ++next_angle;    
}

void red_pwm_tick_on(void)
{
    next_tick = sinetable[next_angle] * ((float)led_brightness / (MAX_LED_LEVEL - 1));
    
    LED_SET_RED = LED_ON;
    led_pwm_tick.attach(red_pwm_tick_off, next_tick);     
}

void red_pwm_tick_off()
{
    next_tick = TICK_FRAME - next_tick;
    
    LED_SET_RED = LED_OFF;
    led_pwm_tick.attach(red_pwm_tick_on, next_tick);
    
    ++next_angle;    
}

int main(void)
{
    LED_SET_GREEN = LED_OFF;
    LED_SET_RED = LED_OFF;
    
    ble.init();
    ble.onDisconnection(disconnectionCallback);
    ble.onDataWritten(WrittenHandler);

    //led_brightness = 5;
    led_pwm_tick.attach(pwm_tick_min, 5.0);  // 
    
    uart = new UARTService(ble);

    /* setup advertising */
    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                     (const uint8_t *)"Smart Badge", sizeof("Smart Badge") - 1);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                    (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));

    ble.gap().setAdvertisingInterval(2000); /* in multiples of 1 ms. */
    ble.gap().setTxPower(-40);

    ble.gap().startAdvertising();

    while (true)
    {
        ble.waitForEvent();
    }
}