Skip to content

Commit 67aa134

Browse files
committed
CatsPlay Experience implemented
Removed NimBLE-Arduino as it is no longer going to be supported on ESP32 CPUs. See h2zero/NimBLE-Arduino#685. Implemented BLE device-to-device communication using JSON encoded data. Later I will put the message handling code into BLEMessaging.cpp and .h. Inveigle starts a CatsPlay experience based on RSSI distance values from BLE.cpp. BLE now runs a server and client on the device - same for a nearby device. Inveigle uses BLE to see if it received a Pounce from another cat. CatsPlay experience SetUp determines the heading to the other device and plays 1 of 8 videos where the cat looks to the other cat. Run will let the user make a TOF gesture to send a Pounce method to the other device, and making no gestures after 10 seconds runs TearDown to show the cat video ending the play. In a future update BLE shares the local RTC time between devices. If one device has valid time them the other one uses the same. I'm doing this just in case the device is not tracking GPS satellites, nor using NTP over Wifi, so the watch wearer doesn't have to set the time.
1 parent 1ce2fc4 commit 67aa134

15 files changed

+626
-1157
lines changed

src/BLE.cpp

Lines changed: 184 additions & 880 deletions
Large diffs are not rendered by default.

src/BLE.h

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,80 @@
22
#define _BLE_
33

44
#include "Arduino.h"
5-
#include <WiFi.h>
6-
#include <SPI.h>
7-
#include <SD.h>
8-
9-
#include <NimBLEDevice.h>
105

116
#include "config.h"
127
#include "secrets.h"
138

9+
#include <BLEDevice.h>
10+
#include <BLEUtils.h>
11+
#include <BLEServer.h>
12+
#include <BLE2902.h>
13+
#include <ArduinoJson.h>
14+
1415
#include "Logger.h"
15-
#include "Accelerometer.h"
16-
#include <Arduino_GFX_Library.h>
17-
#include <JPEGDEC.h>
16+
#include "TOF.h"
1817
#include "Compass.h"
1918

20-
#define maxDistanceReadings 3
19+
// Define BLEServerClass
20+
class BLEServerClass
21+
{
22+
public:
23+
BLEServerClass();
24+
25+
void begin();
26+
void handleClientData();
27+
void sendJsonData(String jsonData);
28+
29+
int getLatestHeading();
30+
void setLatestHeading( int myh );
31+
bool isPounced();
32+
33+
BLEServer* pServer;
34+
BLEService* pService;
35+
BLECharacteristic* pCharacteristic;
36+
BLEClient* pClient;
37+
BLERemoteCharacteristic* pRemoteCharacteristic;
38+
BLEAdvertising* pAdvertising;
39+
40+
class MyServerCallbacks : public BLEServerCallbacks {
41+
void onConnect(BLEServer* pServer) override;
42+
void onDisconnect(BLEServer* pServer) override;
43+
};
44+
45+
class MyCharacteristicCallbacks : public BLECharacteristicCallbacks {
46+
void onWrite(BLECharacteristic* pCharacteristic) override;
47+
};
2148

22-
class BLE
49+
private:
50+
bool bleStarted;
51+
};
52+
53+
54+
// Define BLEClientClass
55+
class BLEClientClass
2356
{
2457
public:
25-
BLE();
58+
BLEClientClass();
2659
void begin();
2760
void loop();
28-
String getMessage();
29-
void setMessage( String heading );
30-
bool connectToServer();
31-
bool getServerValue();
32-
bool lookingTowardsEachOther( float avgDistance );
33-
void setRemoteHeading( float myh );
34-
float getRemoteHeading();
35-
void setLocalHeading( float myd );
36-
float getLocalHeading();
37-
bool matchHeading( float measured_angle );
38-
bool isStarted();
61+
void handleClientData();
62+
void sendJsonData(String jsonData);
63+
int getDistance();
64+
void sendPounce();
3965

40-
private:
41-
TaskHandle_t bleInitTaskHandle;
42-
static void bleInitTaskWrapper(void * parameter);
43-
void bleInitTask();
66+
BLEClient* pClient;
67+
BLERemoteCharacteristic* pRemoteCharacteristic;
4468

45-
void areDevicesPointedToEachOther();
46-
void showCatFaceDirection( int pose );
47-
uint8_t* loadFileToBuffer( String filePath );
69+
class MyClientCallbacks : public BLEClientCallbacks {
70+
void onConnect(BLEClient* pClient) override;
71+
void onDisconnect(BLEClient* pClient) override;
72+
};
4873

49-
bool bleStarted;
74+
private:
75+
int latestrssi;
76+
unsigned long sendHeadingTimer;
77+
unsigned long checkRSSItimer;
5078

51-
std::string devname;
52-
int msgCounter;
53-
unsigned long serverWaitTime;
54-
unsigned long clientWaitTime;
55-
String message;
56-
57-
NimBLECharacteristic* pHeadingCharacteristic;
58-
NimBLEServer* pServer;
59-
NimBLEClient* pClient;
60-
61-
int runningDistance [ maxDistanceReadings ];
62-
float localHeading;
63-
float remoteHeading;
64-
String hottercolder;
65-
float oldAverageDistance;
66-
long showWaitTime;
67-
long fileSize;
68-
69-
JPEGDEC jpeg;
7079
};
7180

7281
#endif // _BLE_

src/Experience_CatsPlay.cpp

Lines changed: 121 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,24 @@
88
(c) Frank Cohen, All rights reserved. [email protected]
99
Read the license in the license.txt file that comes with this code.
1010
11-
Experience lets the user set the time for the internal RTC
11+
Experience finds nearby devices and lets them pounce on each other
12+
13+
Next up I am incorporating the ble code into the ReflectionsOfFrank project. There will be two classes: BLE.cpp and BLEMessaging.cpp
14+
BLEMessaging will provide the message level tasks
15+
Inveigle will start a CatsPlay experience based on RSSI distance values from BLE.cpp
16+
CatsPlay experience is going to be big. SetUp will determine the heading to the other cat and play 1 of 8 videos where the cat looks to the other cat. Run will let the user make a TOF gesture to send a Pounce method to the other cat, and making no gestures after 10 seconds runs TearDown to show the cat video ending the play
17+
Inveigle will also call BLEmessaging to see if it received a Pounce from another cat
1218
1319
*/
1420

1521
#include "Experience_CatsPlay.h"
1622

1723
extern LOGGER logger; // Defined in ReflectionsOfFrank.ino
1824
extern Video video;
25+
extern BLEServerClass bleServer;
26+
extern BLEClientClass bleClient;
27+
extern TOF tof;
28+
extern Compass compass;
1929

2030
void Experience_CatsPlay::init()
2131
{
@@ -24,23 +34,130 @@ void Experience_CatsPlay::init()
2434
teardownComplete = false;
2535
stopped = false;
2636
idle = false;
37+
38+
setupVidplayed = false;
39+
2740
}
2841

42+
float Experience_CatsPlay::calculateBearing( float headingA, float headingB, float rssi )
43+
{
44+
// RSSI to distance conversion (requires calibration)
45+
float distance = pow(10, (rssi + 40) / (-20)); // Example formula
46+
47+
// Assuming both boards are in the same plane for simplicity
48+
// Calculate relative angle (assume 2D plane)
49+
float angle = atan2(sin(headingB - headingA), cos(headingB - headingA)) * (180 / PI);
50+
51+
// Calculate bearing from A to B
52+
float bearingAB = fmod(angle - headingA + 360, 360);
53+
54+
return bearingAB;
55+
}
56+
2957
void Experience_CatsPlay::setup()
3058
{
31-
video.startVideo( CatsPlay_video );
32-
setSetupComplete(true); // Signal that setup is complete
59+
if ( ! setupVidplayed )
60+
{
61+
setupVidplayed = true;
62+
video.startVideo( CatsPlayFound_video );
63+
}
64+
65+
if ( video.getStatus() == 0 )
66+
{
67+
directionTimer = millis();
68+
overallTimer = millis();
69+
setSetupComplete(true); // Signal that setup is complete
70+
}
3371
}
3472

3573
void Experience_CatsPlay::run()
3674
{
37-
setRunComplete(true); // Signal run complete
75+
// Determine direction
76+
77+
if ( millis() - directionTimer > 2000 )
78+
{
79+
directionTimer = millis();
80+
81+
float headingA = compass.getHeading();
82+
float headingB = bleServer.getLatestHeading();
83+
84+
// Placeholder RSSI value (should be obtained via BLE communication)
85+
float rssi = bleClient.getDistance();
86+
87+
// Calculate bearing from A to B
88+
float bearingAB = calculateBearing(headingA, headingB, rssi);
89+
90+
Serial.print( "Bearing from A to B: " );
91+
Serial.println( bearingAB );
92+
93+
// Show video of cat's face pointing to other cat
94+
95+
if ( ( bearingAB > 0 ) && ( bearingAB < 360 ) )
96+
{
97+
switch ( int ( ( bearingAB / ( 360 / 8 ) ) + 1 ) )
98+
{
99+
case 1:
100+
video.startVideo( CatsPlay1_video );
101+
break;
102+
case 2:
103+
video.startVideo( CatsPlay1_video );
104+
break;
105+
case 3:
106+
video.startVideo( CatsPlay1_video );
107+
break;
108+
case 4:
109+
video.startVideo( CatsPlay1_video );
110+
break;
111+
case 5:
112+
video.startVideo( CatsPlay1_video );
113+
break;
114+
case 6:
115+
video.startVideo( CatsPlay1_video );
116+
break;
117+
case 7:
118+
video.startVideo( CatsPlay1_video );
119+
break;
120+
case 8:
121+
video.startVideo( CatsPlay1_video );
122+
break;
123+
}
124+
}
125+
}
126+
127+
// Pounce gesture made? Send pounce message
128+
129+
if ( bleServer.isPounced() )
130+
{
131+
Serial.println( "CatsPlay pounced" );
132+
133+
// Pounce gesture message received?
134+
video.startVideo( Pounce_video );
135+
}
136+
137+
// Play time done?
138+
139+
if ( millis() - overallTimer > 30000 )
140+
{
141+
setRunComplete(true); // Signal run complete
142+
}
143+
144+
// User gestured a pounce to the connected cat
145+
146+
int mygs = tof.getGesture();
147+
if ( mygs == TOF::None ) return;
148+
149+
Serial.print( "CatsPlay detects TOF gesture " );
150+
Serial.print( mygs );
151+
Serial.println( " sending pounce");
152+
153+
bleClient.sendPounce();
38154
}
39155

40156
void Experience_CatsPlay::teardown()
41157
{
42158
if ( video.getStatus() == 0 )
43159
{
160+
video.startVideo( Sleep_video );
44161
setTeardownComplete( true ); // Signal teardown complete
45162
}
46163
}

src/Experience_CatsPlay.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
#include "Experience.h"
88

9+
#include "BLE.h"
10+
#include "Compass.h"
11+
912
#include "Logger.h"
1013
#include "Video.h"
1114
#include "TimeService.h"
@@ -18,7 +21,11 @@ class Experience_CatsPlay : public Experience {
1821
void init() override;
1922

2023
private:
21-
24+
bool setupVidplayed;
25+
unsigned long directionTimer;
26+
unsigned long overallTimer;
27+
float calculateBearing( float headingA, float headingB, float rssi );
28+
2229
};
2330

2431
#endif // Experience_CatsPlay

src/Experience_Pounce.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
Reflections, mobile connected entertainment device
3+
4+
Repository is at https://github.com/frankcohen/ReflectionsOS
5+
Includes board wiring directions, server side components, examples, support
6+
7+
Licensed under GPL v3 Open Source Software
8+
(c) Frank Cohen, All rights reserved. [email protected]
9+
Read the license in the license.txt file that comes with this code.
10+
11+
Experience lets the user set the time for the internal RTC
12+
13+
*/
14+
15+
#include "Experience_Pounce.h"
16+
17+
extern LOGGER logger; // Defined in ReflectionsOfFrank.ino
18+
extern Video video;
19+
20+
void Experience_Pounce::init()
21+
{
22+
setupComplete = false;
23+
runComplete = false;
24+
teardownComplete = false;
25+
stopped = false;
26+
idle = false;
27+
}
28+
29+
void Experience_Pounce::setup()
30+
{
31+
video.startVideo( Pounce_video );
32+
setSetupComplete(true); // Signal that setup is complete
33+
}
34+
35+
void Experience_Pounce::run()
36+
{
37+
setRunComplete(true); // Signal run complete
38+
}
39+
40+
void Experience_Pounce::teardown() {
41+
// Teardown code for Experience_Awake
42+
if ( video.getStatus() == 0 )
43+
{
44+
setTeardownComplete( true ); // Signal teardown complete
45+
}
46+
}

src/Experience_Pounce.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Experience1.h
2+
#ifndef Experience_Pounce_H
3+
#define Experience_Pounce_H
4+
5+
#include <Arduino.h>
6+
7+
#include "Experience.h"
8+
9+
#include "Logger.h"
10+
#include "Video.h"
11+
#include "TimeService.h"
12+
13+
class Experience_Pounce : public Experience {
14+
public:
15+
void setup() override;
16+
void run() override;
17+
void teardown() override;
18+
void init() override;
19+
20+
private:
21+
22+
};
23+
24+
#endif // Experience_Pounce_H

src/Experience_Sleep.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ void Experience_Sleep::teardown()
5050
Serial.println( "Sleep TEARDOWN" );
5151

5252
// Put cat to deep sleep
53-
// esp_deep_sleep_start();
53+
esp_deep_sleep_start();
5454

55-
Serial.println( "Sleep after sleep start" );
55+
Serial.println( "Sleep after sleep" );
5656

5757
setTeardownComplete( true ); // Signal teardown complete
5858
}

0 commit comments

Comments
 (0)