#include "bluetooth.h" #include #include // Initialize UART for Bluetooth communication #define UART_ID uart1 #define AT_EN_PIN 15 //Initialize UART for bluetooth module void initBluetooth(uint baudrate, uint tx_pin, uint rx_pin, int master) { uart_init(UART_ID, baudrate); gpio_set_function(tx_pin, GPIO_FUNC_UART); gpio_set_function(rx_pin, GPIO_FUNC_UART); if(master) { //Initialise AT_EN gpio gpio_init(AT_EN_PIN); gpio_set_dir(AT_EN_PIN, GPIO_OUT); gpio_put(AT_EN_PIN, true); sleep_ms(1000); } } // Send data over Bluetooth using UART int sendBluetoothData(const char* data) { if(uart_is_writable(UART_ID)) { uart_puts(UART_ID, data); return 1; } else return 0; } //Simple function that sends a series of setup commands to the bluetooth master void configMaster() { //Initialization of Master HC-05 (really only needs to be done once, but is done on init just in case) sendATCommand("AT+NAME=Master"); sleep_ms(1000); sendATCommand("AT+ROLE=1"); sleep_ms(1000); sendATCommand("AT+CMODE=0"); sleep_ms(1000); sendATCommand("AT+BIND=5856,00,004C1B"); sleep_ms(1000); sendATCommand("AT+RESET"); sleep_ms(1000); gpio_put(AT_EN_PIN, 0); } //Simple function that sends a command to the bluetooth module, similar to send bluetooth data void sendATCommand(const char* cmd) { if(uart_is_writable(UART_ID)) uart_puts(UART_ID, cmd); // uart_puts(UART_ID, "\r\n"); // Send AT command // Newline characters for end of command } //Reads from the uart buffer and populates the inputted buffer bool readBluetoothResponse(char* buffer) { int i = 0; while(uart_is_readable(UART_ID) && i < 50) { buffer[i] = uart_getc(UART_ID); i++; } //buffer[i] = '\0'; // Ensure buffer is terminated return true; // Return false if no data was read } //Parsing Algorithm to Parse Bluetooth Message of form POS:X-Y|CALIBRATE:<0/1>|CLICK:<0/1>| int parseBluetoothResponse(const char* btMessage, int*x, int*y, volatile bool* calibrate, volatile bool* userClicked) { // Copy the message to a temporary buffer because strtok modifies the string char tempBuffer[100]; strncpy(tempBuffer, btMessage, sizeof(tempBuffer) - 1); tempBuffer[sizeof(tempBuffer) - 1] = '\0'; // Ensure null-termination char *token; char *delimiter = "|"; char *save_ptr; // Get the first token token = strtok_r(tempBuffer, delimiter, &save_ptr); int count = 0; *calibrate = false; *userClicked = false; // Walk through other tokens while (token != NULL && count < 3) { if (strncmp(token, "POS:", 4) == 0) { // Parse position data sscanf(token, "POS:%d-%d", x, y); } else if (strncmp(token, "CALIBRATE:1", 11) == 0) { *calibrate = true; } else if (strncmp(token, "CLICK:1", 7) == 0) { *userClicked = true; printf("CLICKED\r\n"); return 2; } //Get next token token = strtok_r(NULL, delimiter, &save_ptr); count++; if(count == 3) break; } if(count == 3) return 2; } /* COMMENTED, UNUSED CODE FROM A PREVIOUS IMPLEMENTATION KEPT HERE FOR REFERENCE */ /*for some reason, the pico does not use the standard strchr so a custom one was made*/ // const char* pico_strchr(const char* str, int c) // { // while(*str != '\0') // { // if(*str == c) return str; // str++; // } // return NULL; // } // int parseResponse(char* bt_response, int* x, int*y) // { // /* // This function outputs x&y values passed into function, // returns 2 on successful parse and population of x/y // returns 1 on reception of calibrate // returns 0 on reception of useclicked // returns -1 if message could not be successfully parses // BLUETOOTH MESSAGING FOR EASY DATA TRANSFER // POS:X-Y|CALIBRATE:|USERCLICKED: // (Last two have empty data portions as sending these messages assumes you would like to calibrate or initiate a click) // */ // const char* delimiter = pico_strchr(bt_response, ':'); // if(delimiter != NULL) // { // //Should give the length of the keyword, i.e., of POS, CALIBRATE, or USERCLICKED // size_t keywordLen = delimiter - bt_response; // //Create a temporary char array to hold the keyword for later comparison // char keyword[keywordLen + 1]; // //Populate char array with keyword // strncpy(keyword, bt_response, keywordLen); // //One position past delimiter should be data // const char* data = delimiter + 1; // if(strcmp(keyword, "POS") == 0) // { // sscanf(bt_response, "POS:%d-%d",x, y); // return 2; // } // if(strcmp(keyword, "CALIBRATE") == 0) // { // return 1; // } // if(strcmp(keyword, "USERCLICKED") == 0) // { // return 0; // } // } // else return -1; // }