![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Attempting to create an open source, very simple (basically bluetooth notification light to start) smartwatch around the nRF51822.
Dependencies: BLE_API mbed nRF51822
The main branch of code for the simpleWatch project
main.cpp@0:3e9f9b3ed7c8, 2016-05-11 (annotated)
- Committer:
- rjpope42
- Date:
- Wed May 11 18:29:00 2016 +0000
- Revision:
- 0:3e9f9b3ed7c8
Committing a PWM attempt as version 1.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rjpope42 | 0:3e9f9b3ed7c8 | 1 | |
rjpope42 | 0:3e9f9b3ed7c8 | 2 | #include "mbed.h" |
rjpope42 | 0:3e9f9b3ed7c8 | 3 | #include "nrf51.h" |
rjpope42 | 0:3e9f9b3ed7c8 | 4 | #include "nrf51_bitfields.h" |
rjpope42 | 0:3e9f9b3ed7c8 | 5 | #include <string> |
rjpope42 | 0:3e9f9b3ed7c8 | 6 | |
rjpope42 | 0:3e9f9b3ed7c8 | 7 | #include "BLE.h" |
rjpope42 | 0:3e9f9b3ed7c8 | 8 | #include "DFUService.h" |
rjpope42 | 0:3e9f9b3ed7c8 | 9 | #include "UARTService.h" |
rjpope42 | 0:3e9f9b3ed7c8 | 10 | |
rjpope42 | 0:3e9f9b3ed7c8 | 11 | #define LED_GREEN p21 |
rjpope42 | 0:3e9f9b3ed7c8 | 12 | #define LED_RED p22 |
rjpope42 | 0:3e9f9b3ed7c8 | 13 | #define LED_BLUE p23 |
rjpope42 | 0:3e9f9b3ed7c8 | 14 | #define BUTTON_PIN p17 |
rjpope42 | 0:3e9f9b3ed7c8 | 15 | #define BATTERY_PIN p1 |
rjpope42 | 0:3e9f9b3ed7c8 | 16 | |
rjpope42 | 0:3e9f9b3ed7c8 | 17 | #define UART_TX p9 |
rjpope42 | 0:3e9f9b3ed7c8 | 18 | #define UART_RX p11 |
rjpope42 | 0:3e9f9b3ed7c8 | 19 | #define UART_CTS p8 |
rjpope42 | 0:3e9f9b3ed7c8 | 20 | #define UART_RTS p10 |
rjpope42 | 0:3e9f9b3ed7c8 | 21 | |
rjpope42 | 0:3e9f9b3ed7c8 | 22 | InterruptIn button(BUTTON_PIN); |
rjpope42 | 0:3e9f9b3ed7c8 | 23 | AnalogIn battery(BATTERY_PIN); |
rjpope42 | 0:3e9f9b3ed7c8 | 24 | |
rjpope42 | 0:3e9f9b3ed7c8 | 25 | |
rjpope42 | 0:3e9f9b3ed7c8 | 26 | |
rjpope42 | 0:3e9f9b3ed7c8 | 27 | int read_none_count = 0; |
rjpope42 | 0:3e9f9b3ed7c8 | 28 | |
rjpope42 | 0:3e9f9b3ed7c8 | 29 | BLEDevice ble; |
rjpope42 | 0:3e9f9b3ed7c8 | 30 | UARTService *uartServicePtr; |
rjpope42 | 0:3e9f9b3ed7c8 | 31 | |
rjpope42 | 0:3e9f9b3ed7c8 | 32 | volatile bool bleIsConnected = false; |
rjpope42 | 0:3e9f9b3ed7c8 | 33 | volatile uint8_t tick_event = 0; |
rjpope42 | 0:3e9f9b3ed7c8 | 34 | |
rjpope42 | 0:3e9f9b3ed7c8 | 35 | |
rjpope42 | 0:3e9f9b3ed7c8 | 36 | |
rjpope42 | 0:3e9f9b3ed7c8 | 37 | void connectionCallback(const Gap::ConnectionCallbackParams_t *params) |
rjpope42 | 0:3e9f9b3ed7c8 | 38 | { |
rjpope42 | 0:3e9f9b3ed7c8 | 39 | bleIsConnected = true; |
rjpope42 | 0:3e9f9b3ed7c8 | 40 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 41 | |
rjpope42 | 0:3e9f9b3ed7c8 | 42 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams) |
rjpope42 | 0:3e9f9b3ed7c8 | 43 | { |
rjpope42 | 0:3e9f9b3ed7c8 | 44 | ble.startAdvertising(); |
rjpope42 | 0:3e9f9b3ed7c8 | 45 | bleIsConnected = false; |
rjpope42 | 0:3e9f9b3ed7c8 | 46 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 47 | |
rjpope42 | 0:3e9f9b3ed7c8 | 48 | void detect(void) |
rjpope42 | 0:3e9f9b3ed7c8 | 49 | { |
rjpope42 | 0:3e9f9b3ed7c8 | 50 | //LOG("Button pressed\n"); |
rjpope42 | 0:3e9f9b3ed7c8 | 51 | //blue = !blue; |
rjpope42 | 0:3e9f9b3ed7c8 | 52 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 53 | |
rjpope42 | 0:3e9f9b3ed7c8 | 54 | void led_init(void) |
rjpope42 | 0:3e9f9b3ed7c8 | 55 | { |
rjpope42 | 0:3e9f9b3ed7c8 | 56 | |
rjpope42 | 0:3e9f9b3ed7c8 | 57 | //set LED pins to digital output |
rjpope42 | 0:3e9f9b3ed7c8 | 58 | NRF_GPIO->PIN_CNF[LED_BLUE] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 59 | | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 60 | | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 61 | | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 62 | | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); |
rjpope42 | 0:3e9f9b3ed7c8 | 63 | |
rjpope42 | 0:3e9f9b3ed7c8 | 64 | NRF_GPIO->PIN_CNF[LED_GREEN] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 65 | | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 66 | | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 67 | | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 68 | | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); |
rjpope42 | 0:3e9f9b3ed7c8 | 69 | |
rjpope42 | 0:3e9f9b3ed7c8 | 70 | NRF_GPIO->PIN_CNF[LED_RED] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 71 | | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 72 | | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 73 | | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) |
rjpope42 | 0:3e9f9b3ed7c8 | 74 | | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); |
rjpope42 | 0:3e9f9b3ed7c8 | 75 | // NRF_GPIO - #define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) |
rjpope42 | 0:3e9f9b3ed7c8 | 76 | // NRF_GPIO_Type - struct containing possible settings (DIR, INPUT, PULL, DRIVE, SENSE, as well as PIN_CNF[] (configuration array for all 32 outputs) |
rjpope42 | 0:3e9f9b3ed7c8 | 77 | // NRF_GPIO_BASE - #define NRF_GPIO_BASE 0x50000000UL //base register address for GPIO settings |
rjpope42 | 0:3e9f9b3ed7c8 | 78 | // -> just a way of accessing PIN_CNF[pin_we_want_to_mess_with], object oriented programming stuff |
rjpope42 | 0:3e9f9b3ed7c8 | 79 | // GPIO_PIN_CNF_SENSE_Disabled //the appropriate binary value to set sense as disabled |
rjpope42 | 0:3e9f9b3ed7c8 | 80 | // << //bit shift |
rjpope42 | 0:3e9f9b3ed7c8 | 81 | // GPIO_PIN_CNF_SENSE_pos //position that the value of GPIO_PIN_CNF_SENSE_Disabled should be placed at |
rjpope42 | 0:3e9f9b3ed7c8 | 82 | // | //OR all of these values together to set the register |
rjpope42 | 0:3e9f9b3ed7c8 | 83 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 84 | |
rjpope42 | 0:3e9f9b3ed7c8 | 85 | |
rjpope42 | 0:3e9f9b3ed7c8 | 86 | int main(void) |
rjpope42 | 0:3e9f9b3ed7c8 | 87 | { |
rjpope42 | 0:3e9f9b3ed7c8 | 88 | |
rjpope42 | 0:3e9f9b3ed7c8 | 89 | led_init(); |
rjpope42 | 0:3e9f9b3ed7c8 | 90 | |
rjpope42 | 0:3e9f9b3ed7c8 | 91 | //Turn all LEDs off |
rjpope42 | 0:3e9f9b3ed7c8 | 92 | NRF_GPIO->OUTSET = (1UL << LED_BLUE); //remember that writing zeros with outset and outclear has no effect |
rjpope42 | 0:3e9f9b3ed7c8 | 93 | NRF_GPIO->OUTSET = (1UL << LED_RED); |
rjpope42 | 0:3e9f9b3ed7c8 | 94 | NRF_GPIO->OUTSET = (1UL << LED_GREEN); |
rjpope42 | 0:3e9f9b3ed7c8 | 95 | |
rjpope42 | 0:3e9f9b3ed7c8 | 96 | wait(1); |
rjpope42 | 0:3e9f9b3ed7c8 | 97 | |
rjpope42 | 0:3e9f9b3ed7c8 | 98 | button.fall(detect); |
rjpope42 | 0:3e9f9b3ed7c8 | 99 | |
rjpope42 | 0:3e9f9b3ed7c8 | 100 | //Initialising the nRF51822 |
rjpope42 | 0:3e9f9b3ed7c8 | 101 | ble.init(); |
rjpope42 | 0:3e9f9b3ed7c8 | 102 | ble.gap().onDisconnection(disconnectionCallback); |
rjpope42 | 0:3e9f9b3ed7c8 | 103 | ble.gap().onConnection(connectionCallback); |
rjpope42 | 0:3e9f9b3ed7c8 | 104 | |
rjpope42 | 0:3e9f9b3ed7c8 | 105 | |
rjpope42 | 0:3e9f9b3ed7c8 | 106 | /* setup advertising */ |
rjpope42 | 0:3e9f9b3ed7c8 | 107 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); |
rjpope42 | 0:3e9f9b3ed7c8 | 108 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
rjpope42 | 0:3e9f9b3ed7c8 | 109 | ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, |
rjpope42 | 0:3e9f9b3ed7c8 | 110 | (const uint8_t *)"PWMtest", sizeof("PWMtest")); |
rjpope42 | 0:3e9f9b3ed7c8 | 111 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, |
rjpope42 | 0:3e9f9b3ed7c8 | 112 | (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); |
rjpope42 | 0:3e9f9b3ed7c8 | 113 | DFUService dfu(ble); |
rjpope42 | 0:3e9f9b3ed7c8 | 114 | UARTService uartService(ble); |
rjpope42 | 0:3e9f9b3ed7c8 | 115 | uartServicePtr = &uartService; |
rjpope42 | 0:3e9f9b3ed7c8 | 116 | //uartService.retargetStdout(); |
rjpope42 | 0:3e9f9b3ed7c8 | 117 | |
rjpope42 | 0:3e9f9b3ed7c8 | 118 | ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ |
rjpope42 | 0:3e9f9b3ed7c8 | 119 | ble.gap().startAdvertising(); |
rjpope42 | 0:3e9f9b3ed7c8 | 120 | char str[8]; |
rjpope42 | 0:3e9f9b3ed7c8 | 121 | str[5]='\r'; |
rjpope42 | 0:3e9f9b3ed7c8 | 122 | str[6]='\n'; |
rjpope42 | 0:3e9f9b3ed7c8 | 123 | str[7]='\0'; |
rjpope42 | 0:3e9f9b3ed7c8 | 124 | |
rjpope42 | 0:3e9f9b3ed7c8 | 125 | //int rgb_res = 8; //RGB resolution, TODO define this as a constant later |
rjpope42 | 0:3e9f9b3ed7c8 | 126 | int vals[3] = {0}; |
rjpope42 | 0:3e9f9b3ed7c8 | 127 | bool pwmvals[3] = {0}; |
rjpope42 | 0:3e9f9b3ed7c8 | 128 | |
rjpope42 | 0:3e9f9b3ed7c8 | 129 | |
rjpope42 | 0:3e9f9b3ed7c8 | 130 | while (true) { |
rjpope42 | 0:3e9f9b3ed7c8 | 131 | ble.waitForEvent(); |
rjpope42 | 0:3e9f9b3ed7c8 | 132 | str[0]=uartService._getc();//set |
rjpope42 | 0:3e9f9b3ed7c8 | 133 | if (str[0]=='S') |
rjpope42 | 0:3e9f9b3ed7c8 | 134 | { |
rjpope42 | 0:3e9f9b3ed7c8 | 135 | |
rjpope42 | 0:3e9f9b3ed7c8 | 136 | str[1]=uartService._getc();//R |
rjpope42 | 0:3e9f9b3ed7c8 | 137 | str[2]=uartService._getc();//G |
rjpope42 | 0:3e9f9b3ed7c8 | 138 | str[3]=uartService._getc();//B |
rjpope42 | 0:3e9f9b3ed7c8 | 139 | str[4]=uartService._getc(); |
rjpope42 | 0:3e9f9b3ed7c8 | 140 | |
rjpope42 | 0:3e9f9b3ed7c8 | 141 | vals[0] = str[1]-0x30;//convert from char to int |
rjpope42 | 0:3e9f9b3ed7c8 | 142 | vals[1] = str[2]-0x30; |
rjpope42 | 0:3e9f9b3ed7c8 | 143 | vals[2] = str[3]-0x30; |
rjpope42 | 0:3e9f9b3ed7c8 | 144 | uartService.writeString(str); |
rjpope42 | 0:3e9f9b3ed7c8 | 145 | |
rjpope42 | 0:3e9f9b3ed7c8 | 146 | str[0] = 0; |
rjpope42 | 0:3e9f9b3ed7c8 | 147 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 148 | |
rjpope42 | 0:3e9f9b3ed7c8 | 149 | for(uint32_t j = 100000; j>0; j--)//display color for a couple seconds |
rjpope42 | 0:3e9f9b3ed7c8 | 150 | { |
rjpope42 | 0:3e9f9b3ed7c8 | 151 | for(int i = 8; i>0; i--)// |
rjpope42 | 0:3e9f9b3ed7c8 | 152 | { |
rjpope42 | 0:3e9f9b3ed7c8 | 153 | pwmvals[0] = (i - vals[0] == 0);//control brightness by turning LED on after x iterations |
rjpope42 | 0:3e9f9b3ed7c8 | 154 | pwmvals[1] = (i - vals[1] == 0);//could compare directly to str and save an array |
rjpope42 | 0:3e9f9b3ed7c8 | 155 | pwmvals[2] = (i - vals[2] == 0); |
rjpope42 | 0:3e9f9b3ed7c8 | 156 | NRF_GPIO->OUTCLR = (pwmvals[0] << LED_RED)|(pwmvals[1] << LED_GREEN)|(pwmvals[2] << LED_BLUE); |
rjpope42 | 0:3e9f9b3ed7c8 | 157 | |
rjpope42 | 0:3e9f9b3ed7c8 | 158 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 159 | NRF_GPIO->OUTSET = (0x7UL << LED_GREEN);//turn all 3 off |
rjpope42 | 0:3e9f9b3ed7c8 | 160 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 161 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 162 | } |
rjpope42 | 0:3e9f9b3ed7c8 | 163 | |
rjpope42 | 0:3e9f9b3ed7c8 | 164 |