#include #include #include #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it #endif #if !defined(CONFIG_BT_SPP_ENABLED) #error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip. #endif BluetoothSerial SerialBT; #define BT_DISCOVER_TIME 10000 esp_spp_sec_t sec_mask=ESP_SPP_SEC_NONE; esp_spp_role_t role=ESP_SPP_ROLE_SLAVE; String stringReceived = ""; bool playing = false; int numberOfChecks = 0; int GAME_BOARD[3][3] = { {NULL, NULL, NULL}, {NULL, NULL, NULL}, {NULL, NULL, NULL} }; void setup() { M5.begin(); createGrid(); if(! SerialBT.begin("Player2", true) ) { Serial.println("========== serialBT failed!"); abort(); } Serial.println("Starting discoverAsync..."); BTScanResults* btDeviceList = SerialBT.getScanResults(); // maybe accessing from different threads! if (SerialBT.discoverAsync([](BTAdvertisedDevice* pDevice) { Serial.printf(">>>>>>>>>>>Found a new device asynchronously: %s\n", pDevice->toString().c_str()); } ) ) { delay(BT_DISCOVER_TIME); Serial.print("Stopping discoverAsync... "); SerialBT.discoverAsyncStop(); Serial.println("discoverAsync stopped"); delay(5000); if(btDeviceList->getCount() > 0) { BTAddress addr; int channel=0; Serial.println("Found devices:"); for (int i=0; i < btDeviceList->getCount(); i++) { BTAdvertisedDevice *device=btDeviceList->getDevice(i); Serial.printf(" ----- %s %s %d\n", device->getAddress().toString().c_str(), device->getName().c_str(), device->getRSSI()); std::map channels=SerialBT.getChannels(device->getAddress()); Serial.printf("scanned for services, found %d\n", channels.size()); for(auto const &entry : channels) { Serial.printf(" channel %d (%s)\n", entry.first, entry.second.c_str()); } if(channels.size() > 0) { addr = device->getAddress(); channel=channels.begin()->first; } } if(addr) { Serial.printf("connecting to %s - %d\n", addr.toString().c_str(), channel); M5.Axp.SetLDOEnable(3, true); delay(500); M5.Axp.SetLDOEnable(3, false); SerialBT.connect(addr, channel, sec_mask, role); } } else { Serial.println("Didn't find any devices"); } } else { Serial.println("Error on discoverAsync f.e. not workin after a \"connect\""); } } void createGrid() { M5.Lcd.drawLine(0, 80, 320, 80, WHITE); M5.Lcd.drawLine(0, 160, 320, 160, WHITE); M5.Lcd.drawLine(106, 0, 106, 320, WHITE); M5.Lcd.drawLine(212, 0, 212, 320, WHITE); } void createCross(int coord_x, int coord_y) { int COORDS[3][3][4] = { {{30, 20, 70, 60}, {136, 20, 176, 60}, {242, 20, 282, 60}}, {{30, 100, 70, 140}, {136, 100, 176, 140}, {242, 100, 282, 140}}, {{30, 180, 70, 220}, {136, 180, 176, 220}, {242, 180, 282, 220}} }; M5.Lcd.drawLine(COORDS[coord_x][coord_y][0],COORDS[coord_x][coord_y][1],COORDS[coord_x][coord_y][2],COORDS[coord_x][coord_y][3], WHITE); M5.Lcd.drawLine(COORDS[coord_x][coord_y][0],COORDS[coord_x][coord_y][3],COORDS[coord_x][coord_y][2],COORDS[coord_x][coord_y][1], WHITE); GAME_BOARD[coord_x][coord_y] = 2; if (checkWin()) { gameEnd(2); } } void createCircle(int coord_x, int coord_y) { int COORDS[3][3][4] = { {{30, 20, 70, 60}, {136, 20, 176, 60}, {242, 20, 282, 60}}, {{30, 100, 70, 140}, {136, 100, 176, 140}, {242, 100, 282, 140}}, {{30, 180, 70, 220}, {136, 180, 176, 220}, {242, 180, 282, 220}} }; M5.Lcd.drawCircle((COORDS[coord_x][coord_y][0] + COORDS[coord_x][coord_y][2]) / 2, (COORDS[coord_x][coord_y][1] + COORDS[coord_x][coord_y][3]) / 2, 20, WHITE); GAME_BOARD[coord_x][coord_y] = 1; if (checkWin()) { gameEnd(1); } } bool checkWin() { int value = GAME_BOARD[0][0]; int x; numberOfChecks++; if (value > 0) { if ((GAME_BOARD[1][1] == value) && (GAME_BOARD[2][2] == value)) { return true; } } value = GAME_BOARD[0][2]; if (value > 0) { if ((GAME_BOARD[1][1] == value) && (GAME_BOARD[2][0] == value)) { return true; } } for (x = 0; x < 3; x++) { value = GAME_BOARD[x][0]; if (value > 0) { if ((GAME_BOARD[x][1] == value) && (GAME_BOARD[x][2] == value)) { return true; } } } int y; for (y = 0; y < 3; y++) { value = GAME_BOARD[0][y]; if (value > 0) { if ((GAME_BOARD[1][y] == value) && (GAME_BOARD[2][y] == value)) { return true; } } } if (numberOfChecks == 9) { delay(1000); int i; for (i = 0; i < 3; i++) { M5.Axp.SetLDOEnable(3, true); delay(500); M5.Axp.SetLDOEnable(3, false); delay(250); } delay(1000); M5.shutdown(3); } return false; } void gameEnd(int playerNumber) { delay(1000); M5.Lcd.clear(); if (playerNumber == 1) { int i; for (i = 0; i < 3; i++) { M5.Lcd.drawCircle(160, 120, 50, WHITE); M5.Axp.SetLDOEnable(3, true); delay(500); M5.Lcd.clear(); M5.Axp.SetLDOEnable(3, false); delay(250); } M5.shutdown(3); } else { int i; for (i = 0; i < 3; i++) { M5.Lcd.drawLine(100, 60, 220, 160, WHITE); M5.Lcd.drawLine(100, 160, 220, 60, WHITE); M5.Axp.SetLDOEnable(3, true); delay(500); M5.Lcd.clear(); M5.Axp.SetLDOEnable(3, false); delay(250); } M5.shutdown(3); } } void loop() { TouchPoint_t coordinate; coordinate = M5.Touch.getPressPoint(); if(SerialBT.available()){ char c = SerialBT.read(); stringReceived += c; if (stringReceived.length() == 3 && (stringReceived.toInt() % 10) != 1) { stringReceived = ""; } Serial.println(stringReceived); if (stringReceived.length() == 3 && ((stringReceived.toInt() % 10) == 1)) { int value = stringReceived.toInt(); Serial.println(stringReceived); createCircle((int)(value / 100) % 10, (int)(value / 10) % 10); stringReceived = ""; playing = true; } } if (coordinate.x != -1){ if ((coordinate.x > 0) && (coordinate.x < 106)) { if ((coordinate.y > 0) && (coordinate.y < 80)) { if (GAME_BOARD[0][0] == 0) { if (playing) { SerialBT.print("002"); createCross(0, 0); playing = false; } } } if ((coordinate.y > 80) && (coordinate.y < 160)) { if (GAME_BOARD[1][0] == 0) { if (playing) { SerialBT.print("102"); createCross(1, 0); playing = false; } } } if ((coordinate.y > 160) && (coordinate.y < 240)) { if (GAME_BOARD[2][0] == 0) { if (playing) { SerialBT.print("202"); createCross(2, 0); playing = false; } } } } if ((coordinate.x > 106) && (coordinate.x < 212)) { if ((coordinate.y > 0) && (coordinate.y < 80)) { if (GAME_BOARD[0][1] == 0) { if (playing) { SerialBT.print("012"); createCross(0, 1); playing = false; } } } if ((coordinate.y > 80) && (coordinate.y < 160)) { if (GAME_BOARD[1][1] == 0) { if (playing) { SerialBT.print("112"); createCross(1, 1); playing = false; } } } if ((coordinate.y > 160) && (coordinate.y < 240)) { if (GAME_BOARD[2][1] == 0) { if (playing) { SerialBT.print("212"); createCross(2, 1); playing = false; } } } } if ((coordinate.x > 212) && (coordinate.x < 320)) { if ((coordinate.y > 0) && (coordinate.y < 80)) { if (GAME_BOARD[0][2] == 0) { if (playing) { SerialBT.print("022"); createCross(0, 2); playing = false; } } } if ((coordinate.y > 80) && (coordinate.y < 160)) { if (GAME_BOARD[1][2] == 0) { if (playing) { createCross(1, 2); playing = false; SerialBT.print("122"); } } } if ((coordinate.y > 160) && (coordinate.y < 240)) { if (GAME_BOARD[2][2] == 0) { if (playing) { SerialBT.print("222"); createCross(2, 2); playing = false; } } } } } }