Remote I/O Switchx4 LEDx4 AINx2(Battery,Potentiometer) OUTx8 INx8 nRFUARTの改造版 ライブラリアップデートに注意 BLE_API,nRF51822,mbed

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_LoopbackUART by Bluetooth Low Energy

main.cpp

Committer:
noboruk
Date:
2016-12-28
Revision:
16:5df99e9291af
Parent:
15:828ad860628f
Child:
17:663243430dc2

File content as of revision 16:5df99e9291af:

/* 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 "mbed.h"
#include "ble/BLE.h"
#include "ble/services/UARTService.h"
//
////////////////////////////////////////
//
#define LED_ON          1
#define LED_OFF         0
//
////////////////////////////////////////
// I/O pin define
#define LED_PIN1        P0_25
#define LED_PIN2        P0_28
#define LED_PIN3        P0_29
#define LED_PIN4        P0_30

#define SWITCH_PIN1     P0_4
#define SWITCH_PIN2     P0_5
#define SWITCH_PIN3     P0_6
#define SWITCH_PIN4     P0_7

#define OUT_PORT_PIN1   P0_18
#define OUT_PORT_PIN2   P0_17
#define OUT_PORT_PIN3   P0_16
#define OUT_PORT_PIN4   P0_20
#define OUT_PORT_PIN5   P0_21
#define OUT_PORT_PIN6   P0_22
#define OUT_PORT_PIN7   P0_23
#define OUT_PORT_PIN8   P0_24

#define IN_PORT_PIN1    P0_0
#define IN_PORT_PIN2    P0_1
#define IN_PORT_PIN3    P0_10
#define IN_PORT_PIN4    P0_12
#define IN_PORT_PIN5    P0_13
#define IN_PORT_PIN6    P0_14
#define IN_PORT_PIN7    P0_15
#define IN_PORT_PIN8    P0_19

#define ANALOG_IN_PIN1  P0_2
#define ANALOG_IN_PIN2  P0_3

//#define PWM_PIN         P0_8

#define DEBUG_TX_PIN    P0_9
#define DEBUG_RX_PIN    P0_11
//
////////////////////////////////////////
//
#define cmd_LED 'L' // "Lxx"
#define cmd_OUT 'O' // "Oxx"
//
////////////////////////////////////////
//
DigitalOut      LED_1(LED_PIN1);
DigitalOut      LED_2(LED_PIN2);
DigitalOut      LED_3(LED_PIN3);
DigitalOut      LED_4(LED_PIN4);

DigitalIn       SW_1(SWITCH_PIN1);
DigitalIn       SW_2(SWITCH_PIN2);
DigitalIn       SW_3(SWITCH_PIN3);
DigitalIn       SW_4(SWITCH_PIN4);

DigitalOut      DO_1(OUT_PORT_PIN1);
DigitalOut      DO_2(OUT_PORT_PIN2);
DigitalOut      DO_3(OUT_PORT_PIN3);
DigitalOut      DO_4(OUT_PORT_PIN4);
DigitalOut      DO_5(OUT_PORT_PIN5);
DigitalOut      DO_6(OUT_PORT_PIN6);
DigitalOut      DO_7(OUT_PORT_PIN7);
DigitalOut      DO_8(OUT_PORT_PIN8);

DigitalIn       DI_1(IN_PORT_PIN1);
DigitalIn       DI_2(IN_PORT_PIN2);
DigitalIn       DI_3(IN_PORT_PIN3);
DigitalIn       DI_4(IN_PORT_PIN4);
DigitalIn       DI_5(IN_PORT_PIN5);
DigitalIn       DI_6(IN_PORT_PIN6);
DigitalIn       DI_7(IN_PORT_PIN7);
DigitalIn       DI_8(IN_PORT_PIN8);

//
Serial          DEBUG(DEBUG_TX_PIN, DEBUG_RX_PIN);
AnalogIn        AIN_1(ANALOG_IN_PIN1);
AnalogIn        AIN_2(ANALOG_IN_PIN2);
//
////////////////////////////////////////
//
BLEDevice  ble;
UARTService *uartServicePtr;
Ticker ticker;
//
////////////////////////////////////////
uint16_t input_now;
uint16_t input_old;
uint16_t ain1_now;
uint16_t ain2_now;
uint16_t ain1_old;
uint16_t ain2_old;
uint16_t output_buf;

////////////////////////////////////////
void periodicCallback_led_blink( void );
void periodicCallback_sw_read( void );
void set_LED( int num, int val );
void set_OUT( int num, int val );
void read_IN( void );
void port_clear( void );
void cmd_check( uint8_t* s );
void board_test( void );
//
////////////////////////////////////////
uint16_t board_test_fg = 0;
uint16_t uart_cmd_check( void );
uint16_t cmd_c_wp;
uint8_t cmd_str[8];
bool update_characteristic_fg;
bool change_input_fg;
bool first_update_fg;
uint16_t adc_update_cnt;
//
////////////////////////////////////////
// BLEイベント接続時
void connectionCallback(const Gap::ConnectionCallbackParams_t * params)
{
    ticker.detach();
    DEBUG.printf("Connection handle:%u \r\n",params->handle);
    // stop blinking when we connect
    LED_1 = LED_OFF;
    read_IN();
    ticker.attach(periodicCallback_sw_read, 0.05);
    update_characteristic_fg = true;
    first_update_fg = true;
    adc_update_cnt = 0;
}

//
////////////////////////////////////////
// BLEイベント切断時
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    int i;
    update_characteristic_fg = false;
    ticker.detach();
    DEBUG.printf("Disconnected!\n\r");
    DEBUG.printf("Restarting the advertising process\n\r");
    ble.startAdvertising();
    ticker.attach(periodicCallback_led_blink, 1);
    for( i=1; i < 4+1 ; i++ ){ set_LED(i,0); }
    for( i=1; i < 8+1 ; i++ ){ set_OUT(i,0); }
}
//
////////////////////////////////////////
// BLE-UART受信時
void onDataWritten(const GattWriteCallbackParams *params)
{
    uint8_t* s;
    if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
        uint16_t bytesRead = params->len;
        DEBUG.printf("received %u bytes\n\r", bytesRead);
        s = (uint8_t*)(&(params->data[0]));
        cmd_check(s);
        // BLE-UART送信
//        ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
    }
}
//
////////////////////////////////////////
// 未接続時周期割り込み
void periodicCallback_led_blink(void)
{
    LED_1 = !LED_1;
}
//
////////////////////////////////////////
// 接続時周期割り込み
void periodicCallback_sw_read( void  )
{
    char send_str[20];
    uint16_t slen;

    read_IN();
    sprintf(send_str,"%04X,%04X,%04X \r",input_now,ain1_now,ain2_now);
    slen = strlen(send_str);

    if( first_update_fg == true )
    {
        first_update_fg = false;
        change_input_fg = true;
    }
    else
    {
        change_input_fg = false;
    }

    if( input_now != input_old )
    {
        change_input_fg = true;
    }
    adc_update_cnt++;
    if( adc_update_cnt > 5  )
    {
        adc_update_cnt = 0;
        change_input_fg = true;
    }
    if(( update_characteristic_fg == true )&&( change_input_fg == true ))
    {
        DEBUG.printf("len=%d,data=%s",slen,send_str);
        ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),(uint8_t*)(&send_str[0]),slen);
    }
}
//
////////////////////////////////////////
// メイン
int main(void)
{
    DEBUG.baud(9600);
    port_clear();
    read_IN();
    read_IN();
    DEBUG.printf("\r\n");
    DEBUG.printf("BLE remote I/O \r\n");
    DEBUG.printf(" nRFUART version\r\n");
    DEBUG.printf("   2019/12/24\r\n");
    read_IN();
    DEBUG.printf("\r\n");
    if( ( input_now & 0x0003 ) == 0x0003 ){ board_test(); } //SW1,2 ON?
//
    DEBUG.printf("Start program\r\n");
    ticker.attach(periodicCallback_led_blink, 1);

    ble.init();
    ble.onConnection(connectionCallback);
    ble.onDisconnection(disconnectionCallback);
    ble.onDataWritten(onDataWritten);

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

    ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */
    ble.startAdvertising();

    UARTService uartService(ble);
    uartServicePtr = &uartService;

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

////////////////////////////////////////
void board_test( void )
{
//  I/O port debug
    cmd_c_wp = 0;

    DEBUG.printf("board I/O debug \r\n");
    output_buf = 0;
    read_IN();
    read_IN();
    while( 1 )
    {
        wait_ms(200);
        read_IN();
        DEBUG.printf("%04X,%04X,%04X \r",input_now,ain1_now,ain2_now);
        //
        if( input_now & 0x0001 ){ set_LED(1,1); } else { set_LED(1,0); }
        if( input_now & 0x0002 ){ set_LED(2,1); } else { set_LED(2,0); }
        if( input_now & 0x0004 ){ set_LED(3,1); } else { set_LED(3,0); }
        if( input_now & 0x0008 ){ set_LED(4,1); } else { set_LED(4,0); }
        //
        if( output_buf & 0x0001 ){ set_OUT(1,1); } else { set_OUT(1,0); }
        if( output_buf & 0x0002 ){ set_OUT(2,1); } else { set_OUT(2,0); }
        if( output_buf & 0x0004 ){ set_OUT(3,1); } else { set_OUT(3,0); }
        if( output_buf & 0x0008 ){ set_OUT(4,1); } else { set_OUT(4,0); }
        if( output_buf & 0x0010 ){ set_OUT(5,1); } else { set_OUT(5,0); }
        if( output_buf & 0x0020 ){ set_OUT(6,1); } else { set_OUT(6,0); }
        if( output_buf & 0x0040 ){ set_OUT(7,1); } else { set_OUT(7,0); }
        if( output_buf & 0x0080 ){ set_OUT(8,1); } else { set_OUT(8,0); }
        output_buf++;
        if( uart_cmd_check() != 0 )
        {
            cmd_check( cmd_str );
        }
    }
}

////////////////////////////////////////
void set_LED( int num, int val )
{
    switch( num )
    {
        case 1:
            LED_1 = val;
            break;
        case 2:
            LED_2 = val;
            break;
        case 3:
            LED_3 = val;
            break;
        case 4:
            LED_4 = val;
            break;
    }
}

void set_OUT( int num, int val )
{
    switch( num )
    {
        case 1:
            DO_1 = val;
            break;
        case 2:
            DO_2 = val;
            break;
        case 3:
            DO_3 = val;
            break;
        case 4:
            DO_4 = val;
            break;
        case 5:
            DO_5 = val;
            break;
        case 6:
            DO_6 = val;
            break;
        case 7:
            DO_7 = val;
            break;
        case 8:
            DO_8 = val;
            break;
    }
}

void read_IN( void )
{
    input_old = input_now;
    input_now = 0;
    if( SW_1 == 0 ){ input_now |= 0x0001; }
    if( SW_2 == 0 ){ input_now |= 0x0002; }
    if( SW_3 == 0 ){ input_now |= 0x0004; }
    if( SW_4 == 0 ){ input_now |= 0x0008; }
    if( DI_1 == 0 ){ input_now |= 0x0100; }
    if( DI_2 == 0 ){ input_now |= 0x0200; }
    if( DI_3 == 0 ){ input_now |= 0x0400; }
    if( DI_4 == 0 ){ input_now |= 0x0800; }
    if( DI_5 == 0 ){ input_now |= 0x1000; }
    if( DI_6 == 0 ){ input_now |= 0x2000; }
    if( DI_7 == 0 ){ input_now |= 0x4000; }
    if( DI_8 == 0 ){ input_now |= 0x8000; }
    ain1_old = ain1_now;
    ain1_now = AIN_1.read_u16();
    ain2_old = ain2_now;
    ain2_now = AIN_2.read_u16();
}

void port_clear( void )
{
    int i;
    for( i=1; i < 4+1 ; i++ ){ set_LED(i,0); }
    for( i=1; i < 8+1 ; i++ ){ set_OUT(i,0); }
//
    LED_1 = 1;
    wait_ms(100);
    LED_2 = 1;
    wait_ms(100);
    LED_3 = 1;
    wait_ms(100);
    LED_4 = 1;
    wait_ms(100);
    LED_1 = 0;
    wait_ms(100);
    LED_2 = 0;
    wait_ms(100);
    LED_3 = 0;
    wait_ms(100);
    LED_4 = 0;
    wait_ms(400);
    LED_1 = 1;
    LED_2 = 1;
    LED_3 = 1;
    LED_4 = 1;
    wait_ms(400);
    LED_1 = 0;
    LED_2 = 0;
    LED_3 = 0;
    LED_4 = 0;
//
}

uint16_t uart_cmd_check( void )
{
    uint16_t res;
    uint8_t c;
    res = 0;
    if( DEBUG.readable() )
    {
        c = DEBUG.getc();
        cmd_str[cmd_c_wp] = c;
        cmd_c_wp++;
        if( cmd_c_wp >= 4 )
        {
            cmd_str[cmd_c_wp] = 0;
            cmd_c_wp = 0;
            res = 1;
        }
    }
    return res;
}

void cmd_check( uint8_t* s )
{
    int val;

    DEBUG.printf("\r\ncmd=%s\r\n",s);
    if( s[2] == '0' )
    {
        val = 0;
    }
    else if( s[2] == '1' )
    {
        val = 1;
    }
    if( s[0] == 'L' )
    {
        switch( s[1] )
        {
            case '1':
                set_LED( 1, val );
                break;
            case '2':
                set_LED( 2, val );
                break;
            case '3':
                set_LED( 3, val );
                break;
            case '4':
                set_LED( 4, val );
                break;
        }
        return;
    }
    if( s[0] == 'O' )
    {
        switch( s[1] )
        {
            case '1':
                set_OUT( 1, val );
                break;
            case '2':
                set_OUT( 2, val );
                break;
            case '3':
                set_OUT( 3, val );
                break;
            case '4':
                set_OUT( 4, val );
                break;
            case '5':
                set_OUT( 5, val );
                break;
            case '6':
                set_OUT( 6, val );
                break;
            case '7':
                set_OUT( 7, val );
                break;
            case '8':
                set_OUT( 8, val );
                break;
        }
        return;
    }
}