{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/pxt-microbit/issues/114","repository_url":"https://api.github.com/repos/Microsoft/pxt-microbit","labels_url":"https://api.github.com/repos/Microsoft/pxt-microbit/issues/114/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/pxt-microbit/issues/114/comments","events_url":"https://api.github.com/repos/Microsoft/pxt-microbit/issues/114/events","html_url":"https://github.com/Microsoft/pxt-microbit/issues/114","id":160160516,"number":114,"title":"Block for inclusion of Bluetooth UART service needed","user":{"login":"bluetooth-mdw","id":8341666,"avatar_url":"https://avatars.githubusercontent.com/u/8341666?v=3","gravatar_id":"","url":"https://api.github.com/users/bluetooth-mdw","html_url":"https://github.com/bluetooth-mdw","followers_url":"https://api.github.com/users/bluetooth-mdw/followers","following_url":"https://api.github.com/users/bluetooth-mdw/following{/other_user}","gists_url":"https://api.github.com/users/bluetooth-mdw/gists{/gist_id}","starred_url":"https://api.github.com/users/bluetooth-mdw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bluetooth-mdw/subscriptions","organizations_url":"https://api.github.com/users/bluetooth-mdw/orgs","repos_url":"https://api.github.com/users/bluetooth-mdw/repos","events_url":"https://api.github.com/users/bluetooth-mdw/events{/privacy}","received_events_url":"https://api.github.com/users/bluetooth-mdw/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/pxt-microbit/labels/BLE","name":"BLE","color":"d4c5f9"},{"url":"https://api.github.com/repos/Microsoft/pxt-microbit/labels/Blocks","name":"Blocks","color":"c5def5"},{"url":"https://api.github.com/repos/Microsoft/pxt-microbit/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/Microsoft/pxt-microbit/milestones/2","html_url":"https://github.com/Microsoft/pxt-microbit/milestones/Bluetooth","labels_url":"https://api.github.com/repos/Microsoft/pxt-microbit/milestones/2/labels","id":1826720,"number":2,"title":"Bluetooth","description":"","creator":{"login":"tballmsft","id":10767146,"avatar_url":"https://avatars.githubusercontent.com/u/10767146?v=3","gravatar_id":"","url":"https://api.github.com/users/tballmsft","html_url":"https://github.com/tballmsft","followers_url":"https://api.github.com/users/tballmsft/followers","following_url":"https://api.github.com/users/tballmsft/following{/other_user}","gists_url":"https://api.github.com/users/tballmsft/gists{/gist_id}","starred_url":"https://api.github.com/users/tballmsft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tballmsft/subscriptions","organizations_url":"https://api.github.com/users/tballmsft/orgs","repos_url":"https://api.github.com/users/tballmsft/repos","events_url":"https://api.github.com/users/tballmsft/events{/privacy}","received_events_url":"https://api.github.com/users/tballmsft/received_events","type":"User","site_admin":false},"open_issues":9,"closed_issues":5,"state":"open","created_at":"2016-06-14T14:44:06Z","updated_at":"2016-06-16T22:23:03Z","due_on":null,"closed_at":null},"comments":5,"created_at":"2016-06-14T11:43:08Z","updated_at":"2016-06-24T07:57:44Z","closed_at":null,"body":"It would be great if there was a tray containing Bluetooth related blocks.\r\n\r\nIn this tray, there should/could be a block per Bluetooth \"service\".\r\n\r\nDragging a Bluetooth service block into a PXT app would result in the corresponding Bluetooth being included in the generated code.\r\n\r\nThis issue requests a block for the micro:bit **Bluetooth UART service**.\r\n\r\nNote that the UART service is a little more complicated than the other services which generally only require a single line of code for them to be included in a build. The UART service needs to be instantiated in the same way but also needs user code for either the production of data to transmit to a connected client and / or user code to receive and process data received from a connected client. At least one of these is required for use of this service to make sense.\r\n\r\nIt would generally make sense to implement producer/consumer code with reference to the state of the Bluetooth connection, for which events are available. i.e. there's no sense trying to transmit data over UART if you're not in a connection.\r\n\r\nNote also that when creating an instance of the UART service, a buffer size must be supplied for the underlying serial data buffer.\r\n\r\nThe Lancaster University documentation covers this well: http://lancaster-university.github.io/microbit-docs/ble/uart-service/ \r\n\r\nI've repeated an example application here to show what the possible structure of an application which creates the UART service and then both receives data from it and transmits data using it might look like.\r\n\r\n```C/C++\r\n#include \"MicroBit.h\"\r\n#include \"MicroBitSamples.h\"\r\n#include \"MicroBitUARTService.h\"\r\nMicroBit uBit;\r\nMicroBitUARTService *uart;\r\n\r\nint connected = 0;\r\n\r\nvoid onConnected(MicroBitEvent e)\r\n{\r\n    uBit.display.scroll(\"C\");\r\n\r\n    connected = 1;\r\n\r\n    // my client will send ASCII strings terminated with the colon character\r\n    ManagedString eom(\":\");\r\n\r\n    while(1) {\r\n        ManagedString msg = uart->readUntil(eom);\r\n        uBit.display.scroll(msg);\r\n    }\r\n\r\n}\r\n\r\nvoid onDisconnected(MicroBitEvent e)\r\n{\r\n    uBit.display.scroll(\"D\");\r\n    connected = 0;\r\n}\r\n\r\nvoid onButtonA(MicroBitEvent e)\r\n{\r\n    if (connected == 0) {\r\n        uBit.display.scroll(\"NC\");\r\n        return;\r\n    }\r\n    uart->send(\"YES\");\r\n    uBit.display.scroll(\"YES\");\r\n}\r\n\r\nvoid onButtonB(MicroBitEvent e)\r\n{\r\n    if (connected == 0) {\r\n        uBit.display.scroll(\"NC\");\r\n        return;\r\n    }\r\n    uart->send(\"NO\");\r\n    uBit.display.scroll(\"NO\");\r\n}\r\n\r\nvoid onButtonAB(MicroBitEvent e)\r\n{\r\n    if (connected == 0) {\r\n        uBit.display.scroll(\"NC\");\r\n        return;\r\n    }\r\n    uart->send(\"GOT IT!!\");\r\n    uBit.display.scroll(\"GOT IT!!\");\r\n}\r\n\r\nint main()\r\n{\r\n    // Initialise the micro:bit runtime.\r\n    uBit.init();\r\n\r\n    // listen for Bluetooth connection state changes\r\n    uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_CONNECTED, onConnected);\r\n    uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, onDisconnected);\r\n\r\n    // listen for user button interactions\r\n    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA);\r\n    uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB);\r\n    uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, onButtonAB);\r\n\r\n    uart = new MicroBitUARTService(*uBit.ble, 32, 32); \r\n    uBit.display.scroll(\"AVM\");\r\n\r\n    release_fiber();\r\n}\r\n\r\n```\r\n\r\nNote that inclusion of Bluetooth services has consequences for memory configuration on the micro:bit, specifically with respect to GATT table size. I've suggested an approach to addressing this to Joe Finney of Lancaster University and we're evaluating. Will update issue once this discussion has progressed further.\r\n"},"comment":{"url":"https://api.github.com/repos/Microsoft/pxt-microbit/issues/comments/228281324","html_url":"https://github.com/Microsoft/pxt-microbit/issues/114#issuecomment-228281324","issue_url":"https://api.github.com/repos/Microsoft/pxt-microbit/issues/114","id":228281324,"user":{"login":"bluetooth-mdw","id":8341666,"avatar_url":"https://avatars.githubusercontent.com/u/8341666?v=3","gravatar_id":"","url":"https://api.github.com/users/bluetooth-mdw","html_url":"https://github.com/bluetooth-mdw","followers_url":"https://api.github.com/users/bluetooth-mdw/followers","following_url":"https://api.github.com/users/bluetooth-mdw/following{/other_user}","gists_url":"https://api.github.com/users/bluetooth-mdw/gists{/gist_id}","starred_url":"https://api.github.com/users/bluetooth-mdw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bluetooth-mdw/subscriptions","organizations_url":"https://api.github.com/users/bluetooth-mdw/orgs","repos_url":"https://api.github.com/users/bluetooth-mdw/repos","events_url":"https://api.github.com/users/bluetooth-mdw/events{/privacy}","received_events_url":"https://api.github.com/users/bluetooth-mdw/received_events","type":"User","site_admin":false},"created_at":"2016-06-24T07:57:44Z","updated_at":"2016-06-24T07:57:44Z","body":"I have added a block for the UART service and a block for writing to it. All good. But I'm finding it difficult to create a block for reading from the UART service buffer until a specified delimiter character is encountered.\r\n\r\nWhat I want is a parameter which accepts a single character. This seems to not be possible which has led me down the path of using an enum, translated into a set of corresponding character values via a function.\r\n\r\nWhat I have now \"works\" but produces a uartRead block which has a string parameter of unlimited length:\r\n\r\n```\r\nusing namespace pxt;\r\n\r\nenum Delimiters {\r\n    //% block=\"new line\"\r\n    NewLine = 1,\r\n    //% block=\",\"\r\n    Comma = 2,\r\n    //% block=\"$\"\r\n    Dollar = 3,\r\n    //% block=\":\"\r\n    Colon = 4,\r\n    //% block=\".\"\r\n    Fullstop = 5,\r\n    //% block=\"#\"\r\n    Hash = 6,\r\n};\r\n\r\n\r\n/**\r\n * Support for additional Bluetooth services.\r\n */\r\n//% color=#0082FB weight=20\r\nnamespace bluetooth {\r\n\r\n```\r\n```\r\n    /**\r\n    *  Starts the Bluetooth UART service\r\n    */\r\n    //% help=bluetooth/start-uart-service\r\n    //% blockId=bluetooth_start_uart_service block=\"bluetooth uart service\" blockGap=8\r\n\r\n    void startUartService() {\r\n        // 61 octet buffer size is 3 x (MTU - 3) + 1\r\n        // MTU on nRF51822 is 23 octets. 3 are used by Attribute Protocol header data leaving 20 octets for payload\r\n        // So we allow a RX buffer that can contain 3 x max length messages plus one octet for a terminator character\r\n        uart = new MicroBitUARTService(*uBit.ble, 61, 60);\r\n    }\r\n    \r\n    /**\r\n    *  Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device.\r\n    */\r\n    //% help=bluetooth/uart-write\r\n    //% blockId=bluetooth_uart_write block=\"bluetooth uart write %data\" blockGap=8\r\n    void uartWrite(StringData *data) {\r\n            uart->send(ManagedString(data));\r\n    }    \r\n\r\n    /**\r\n    *  Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.\r\n    */\r\n    //% help=bluetooth/uart-read\r\n    //% blockId=bluetooth_uart_read block=\"bluetooth uart read %del\" blockGap=8\r\n    StringData* uartRead(StringData *del) {\r\n        return uart->readUntil(ManagedString(del)).leakData();\r\n    }    \r\n```\r\n\r\nTo try using the enum/function mapping approach I created file bluetooth.ts which now contains:\r\n\r\n```\r\n//% blockId=\"delimiter_conv\" block=\"%del\"\r\nexport function delimiters(del : Delimiters) : string {\r\n    switch(del) {\r\n        case Delimiters.NewLine: return \"\\n\";\r\n        case Delimiters.Comma: return \",\";\r\n        case Delimiters.Dollar: return \"$\";\r\n        case Delimiters.Colon: return \":\";\r\n        case Delimiters.Fullstop: return \".\";\r\n        case Delimiters.Hash: return \"#\";\r\n        default: return \"\\n\";\r\n    }\r\n}\r\n```\r\n\r\nand changed my bluetooth..cpp function to look like this:\r\n\r\n```\r\n    /**\r\n    *  Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.\r\n    */\r\n    //% help=bluetooth/uart-read\r\n    //% blockId=bluetooth_uart_read block=\"bluetooth uart read %del=delimiter_conv\" blockGap=8\r\n    StringData* uartRead(StringData *del) {\r\n        return uart->readUntil(ManagedString(del)).leakData();\r\n    }    \r\n```\r\nThis essentially breaks the whole bluetooth category. If I click on the category I get a single block appear:\r\n\r\n![image](https://cloud.githubusercontent.com/assets/8341666/16331607/578da07e-39e9-11e6-8ced-a84e1d44ccee.png)\r\n\r\nThere's clearly something I don't understand about this."}}
{"actor":{"display_login":"bluetooth-mdw"}}