football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Committer:
andriym
Date:
Thu Jun 16 05:06:24 2016 +0000
Revision:
95:3cc3ae2e5e7f
Parent:
94:831a7fc2d69a
Child:
97:2894fbc2d4f8
Removed output lib.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elmbed 76:6638d83939d5 1 #include <RFM69.h>
andriym 78:43a6b54f0372 2 #include <list>
andriym 82:1e552cc1a615 3 #include <DebounceIn.h>
andriym 89:425369a595c4 4 #ifdef BLE_ENABLE
andriym 92:a9ebe6d0a0fa 5 #include "ble/BLE.h"
andriym 90:b4d53a870147 6 #include "ble/services/DFUService.h"
andriym 89:425369a595c4 7 #endif
AntonLS 0:28ca4562fe1a 8
andriym 78:43a6b54f0372 9 using namespace std;
andriym 78:43a6b54f0372 10
andriym 89:425369a595c4 11 Timer tmr;
andriym 95:3cc3ae2e5e7f 12 //Output out;
elmbed 17:d8b901d791fd 13
andriym 89:425369a595c4 14 #ifdef BLE_ENABLE
andriym 90:b4d53a870147 15 BLEDevice ble;
andriym 91:0fc897cccc06 16
andriym 91:0fc897cccc06 17 // Optional: Device Name, add for human read-ability
andriym 92:a9ebe6d0a0fa 18 //const static char DEVICE_NAME[] = "PassiveCoach";
andriym 90:b4d53a870147 19
andriym 91:0fc897cccc06 20 // You have up to 26 bytes of advertising data to use.
andriym 89:425369a595c4 21 //const static uint8_t AdvData[] = {0x01,0x02,0x03,0x04,0x05}; /* Example of hex data */
andriym 92:a9ebe6d0a0fa 22 //const static uint8_t AdvData[] = {"Keep the Space!"}; /* Example of character data */
andriym 89:425369a595c4 23 #endif // BLE_ENABLE
andriym 89:425369a595c4 24
andriym 78:43a6b54f0372 25 /////////////////////////////////// PINS ///////////////////////////////////
andriym 79:9db29f41dc9d 26
andriym 82:1e552cc1a615 27 DebounceIn buttonTeam(BUT_TEAM);
andriym 82:1e552cc1a615 28 DebounceIn buttonSpace(BUT_SPACE);
andriym 82:1e552cc1a615 29 DebounceIn buttonVolMore(BUT_VOL_MORE);
andriym 82:1e552cc1a615 30 DebounceIn buttonVolLess(BUT_VOL_LESS);
andriym 81:3cd7de5d01ef 31
andriym 79:9db29f41dc9d 32 DigitalOut ledTeamA(LED_TEAM_A);
andriym 79:9db29f41dc9d 33 DigitalOut ledTeamB(LED_TEAM_B);
andriym 79:9db29f41dc9d 34 DigitalOut ledSpace5(LED_SPACE5);
andriym 79:9db29f41dc9d 35 DigitalOut ledSpace10(LED_SPACE10);
andriym 79:9db29f41dc9d 36 DigitalOut ledSpace15(LED_SPACE15);
andriym 79:9db29f41dc9d 37 DigitalOut ledSpace20(LED_SPACE20);
andriym 81:3cd7de5d01ef 38 DigitalOut ledBuzzer(LED_BUZZER_ON);
andriym 81:3cd7de5d01ef 39
andriym 79:9db29f41dc9d 40 AnalogIn ain(ANALOG_IN); // used for randomizing
andriym 78:43a6b54f0372 41 #ifdef NORDIC
andriym 79:9db29f41dc9d 42 DigitalOut buzzer(BUZZER);
andriym 88:d3f0394da5aa 43 #ifndef HARD_V2
andriym 79:9db29f41dc9d 44 DigitalOut buzzLow(BUZZ_LOW);
andriym 88:d3f0394da5aa 45 #endif
andriym 79:9db29f41dc9d 46 DigitalOut buzzMed(BUZZ_MED);
andriym 79:9db29f41dc9d 47 DigitalOut buzzHigh(BUZZ_HIGH);
andriym 79:9db29f41dc9d 48 #else
andriym 79:9db29f41dc9d 49 PwmOut speaker(BUZZER); // passive buzzer
andriym 79:9db29f41dc9d 50 #endif
AntonLS 30:c60b0d52b067 51
andriym 78:43a6b54f0372 52 /////////////////////////////////// RADIO ///////////////////////////////////
andriym 83:79cb2ba44b66 53 #ifdef ENABLE_PIN
andriym 83:79cb2ba44b66 54 static RFM69 radio(RFM_MOSI, RFM_MISO, RFM_SCK, RFM_SS, RFM_IRQ, RFM_ISM_EN);
andriym 83:79cb2ba44b66 55 #else
andriym 79:9db29f41dc9d 56 static RFM69 radio(RFM_MOSI, RFM_MISO, RFM_SCK, RFM_SS, RFM_IRQ);
andriym 83:79cb2ba44b66 57 #endif
AntonLS 12:6d313d575f84 58
elmbed 76:6638d83939d5 59 static bool promiscuousMode = true; // set 'true' to sniff all packets on the same network
AntonLS 0:28ca4562fe1a 60
andriym 78:43a6b54f0372 61 /////////////////////////////////// FUNCTIONS ///////////////////////////////////
andriym 78:43a6b54f0372 62
andriym 81:3cd7de5d01ef 63 void beep(float period, float time, uint8_t vol) {
andriym 78:43a6b54f0372 64 #ifdef ENABLE_SOUND
andriym 81:3cd7de5d01ef 65 if(!vol) return;
andriym 79:9db29f41dc9d 66 #ifdef NORDIC
andriym 81:3cd7de5d01ef 67 if(vol>=3) {
andriym 88:d3f0394da5aa 68 #ifndef HARD_V2
andriym 88:d3f0394da5aa 69 buzzLow = LOW_ON;
andriym 88:d3f0394da5aa 70 #endif
andriym 88:d3f0394da5aa 71 buzzMed = MED_OFF; buzzHigh = HIGH_OFF;
andriym 81:3cd7de5d01ef 72 } else if(vol>=2) {
andriym 88:d3f0394da5aa 73 #ifndef HARD_V2
andriym 88:d3f0394da5aa 74 buzzLow = LOW_OFF;
andriym 88:d3f0394da5aa 75 #endif
andriym 88:d3f0394da5aa 76 buzzMed = MED_ON; buzzHigh = HIGH_OFF;
andriym 79:9db29f41dc9d 77 } else {
andriym 88:d3f0394da5aa 78 #ifndef HARD_V2
andriym 88:d3f0394da5aa 79 buzzLow = LOW_OFF;
andriym 88:d3f0394da5aa 80 #endif
andriym 88:d3f0394da5aa 81 buzzMed = MED_OFF; buzzHigh = HIGH_ON;
andriym 79:9db29f41dc9d 82 }
andriym 80:8d4f190bd253 83 buzzer = 0; // P-MOSFET
andriym 80:8d4f190bd253 84 wait(time);
andriym 79:9db29f41dc9d 85 buzzer = 1;
andriym 79:9db29f41dc9d 86 #else
andriym 78:43a6b54f0372 87 speaker.period(period);
andriym 81:3cd7de5d01ef 88 if(vol>=3)
andriym 81:3cd7de5d01ef 89 speaker = 0.5; //50% duty cycle - max volume
andriym 81:3cd7de5d01ef 90 else if(vol>=2)
andriym 81:3cd7de5d01ef 91 speaker = 0.33;
andriym 81:3cd7de5d01ef 92 else
andriym 81:3cd7de5d01ef 93 speaker = 0.2;
andriym 78:43a6b54f0372 94 wait(time);
andriym 78:43a6b54f0372 95 speaker=0.0; // turn off audio
andriym 78:43a6b54f0372 96 #endif
andriym 79:9db29f41dc9d 97 #endif
andriym 78:43a6b54f0372 98 }
andriym 78:43a6b54f0372 99
andriym 78:43a6b54f0372 100 void binary_sound(int z) {
andriym 78:43a6b54f0372 101 // Beeps numbers according to their binary form
andriym 78:43a6b54f0372 102 // (used for debugging in display-less and serial-less environments)
andriym 78:43a6b54f0372 103 #ifdef ENABLE_SOUND
andriym 79:9db29f41dc9d 104 #ifndef NORDIC
andriym 78:43a6b54f0372 105 speaker.period(0.004);
andriym 78:43a6b54f0372 106 while(z) {
andriym 78:43a6b54f0372 107 speaker = 0.5;
andriym 78:43a6b54f0372 108 if(z&1) wait(0.5);
andriym 78:43a6b54f0372 109 else wait(0.25);
andriym 78:43a6b54f0372 110 speaker = 0.0;
andriym 78:43a6b54f0372 111 wait(1.0);
andriym 78:43a6b54f0372 112 z >>= 1;
andriym 78:43a6b54f0372 113 }
andriym 81:3cd7de5d01ef 114 beep(NOTE_A4, 1.0, 2);
andriym 79:9db29f41dc9d 115 #endif
andriym 78:43a6b54f0372 116 #endif
andriym 78:43a6b54f0372 117 }
andriym 78:43a6b54f0372 118
andriym 78:43a6b54f0372 119 void generate_name(char rand_name[], uint8_t size) {
andriym 78:43a6b54f0372 120 // Generate random name on the 62 character alphabet
andriym 78:43a6b54f0372 121 memset(rand_name, 0x00, size);
andriym 78:43a6b54f0372 122 char alph[63] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
andriym 78:43a6b54f0372 123 uint32_t seed = ((ain.read_u16()+3)/17)*(radio.readTemperature(-1)+37)*((ain.read_u16()+5)/13);
andriym 78:43a6b54f0372 124 srand(seed);
andriym 78:43a6b54f0372 125 for(int i=0;i<size-1;i++) {
andriym 78:43a6b54f0372 126 rand_name[i] = alph[abs(rand()) % 62];
andriym 78:43a6b54f0372 127 }
andriym 78:43a6b54f0372 128 }
andriym 78:43a6b54f0372 129
andriym 86:2a569d9e67f5 130 void spaceLEDs(int level) {
andriym 85:4692a1790cfa 131 if(level<=0) {
andriym 85:4692a1790cfa 132 ledSpace5 = 1; ledSpace10 = 0; ledSpace15 = 0; ledSpace20 = 0;
andriym 85:4692a1790cfa 133 } else if(level<=1) {
andriym 85:4692a1790cfa 134 ledSpace5 = 0; ledSpace10 = 1; ledSpace15 = 0; ledSpace20 = 0;
andriym 85:4692a1790cfa 135 } else if(level<=2) {
andriym 85:4692a1790cfa 136 ledSpace5 = 0; ledSpace10 = 0; ledSpace15 = 1; ledSpace20 = 0;
andriym 85:4692a1790cfa 137 } else {
andriym 85:4692a1790cfa 138 ledSpace5 = 0; ledSpace10 = 0; ledSpace15 = 0; ledSpace20 = 1;
andriym 85:4692a1790cfa 139 }
andriym 85:4692a1790cfa 140 }
andriym 85:4692a1790cfa 141
andriym 89:425369a595c4 142 #ifdef BLE_ENABLE
andriym 92:a9ebe6d0a0fa 143 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
andriym 92:a9ebe6d0a0fa 144 {
andriym 92:a9ebe6d0a0fa 145 //pc.printf("Disconnected \r\n");
andriym 92:a9ebe6d0a0fa 146 //pc.printf("Restart advertising \r\n");
andriym 92:a9ebe6d0a0fa 147 ble.startAdvertising();
andriym 92:a9ebe6d0a0fa 148 }
andriym 92:a9ebe6d0a0fa 149
andriym 90:b4d53a870147 150 // Optional: Restart advertising when peer disconnects
andriym 92:a9ebe6d0a0fa 151 /*
andriym 89:425369a595c4 152 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
andriym 89:425369a595c4 153 {
andriym 89:425369a595c4 154 BLE::Instance().gap().startAdvertising();
andriym 89:425369a595c4 155 }
andriym 92:a9ebe6d0a0fa 156 */
andriym 90:b4d53a870147 157 // This function is called when the ble initialization process has failed
andriym 89:425369a595c4 158 void onBleInitError(BLE &ble, ble_error_t error)
andriym 89:425369a595c4 159 {
andriym 90:b4d53a870147 160 // Avoid compiler warnings
andriym 89:425369a595c4 161 (void) ble;
andriym 89:425369a595c4 162 (void) error;
andriym 89:425369a595c4 163
andriym 90:b4d53a870147 164 // Initialization error handling should go here
andriym 89:425369a595c4 165 }
andriym 89:425369a595c4 166
andriym 90:b4d53a870147 167 // Callback triggered when the ble initialization process has finished
andriym 93:620dd0a7ddc7 168 /*
andriym 89:425369a595c4 169 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
andriym 89:425369a595c4 170 {
andriym 89:425369a595c4 171 BLE& ble = params->ble;
andriym 89:425369a595c4 172 ble_error_t error = params->error;
andriym 89:425369a595c4 173
andriym 89:425369a595c4 174 if (error != BLE_ERROR_NONE) {
andriym 90:b4d53a870147 175 // In case of error, forward the error handling to onBleInitError
andriym 89:425369a595c4 176 onBleInitError(ble, error);
andriym 89:425369a595c4 177 return;
andriym 89:425369a595c4 178 }
andriym 89:425369a595c4 179
andriym 90:b4d53a870147 180 // Ensure that it is the default instance of BLE
andriym 89:425369a595c4 181 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
andriym 89:425369a595c4 182 return;
andriym 89:425369a595c4 183 }
andriym 89:425369a595c4 184
andriym 90:b4d53a870147 185 // Set device name characteristic data
andriym 89:425369a595c4 186 ble.gap().setDeviceName((const uint8_t *) DEVICE_NAME);
andriym 89:425369a595c4 187
andriym 90:b4d53a870147 188 // Optional: add callback for disconnection
andriym 89:425369a595c4 189 ble.gap().onDisconnection(disconnectionCallback);
andriym 89:425369a595c4 190
andriym 90:b4d53a870147 191 // Sacrifice 3B of 31B to Advertising Flags
andriym 89:425369a595c4 192 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE );
andriym 89:425369a595c4 193 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
andriym 89:425369a595c4 194
andriym 90:b4d53a870147 195 // Sacrifice 2B of 31B to AdvType overhead, rest goes to AdvData array you define
andriym 89:425369a595c4 196 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, AdvData, sizeof(AdvData));
andriym 89:425369a595c4 197
andriym 90:b4d53a870147 198 // Optional: Add name to device
andriym 89:425369a595c4 199 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
andriym 89:425369a595c4 200
andriym 90:b4d53a870147 201 // Set advertising interval. Longer interval == longer battery life
andriym 90:b4d53a870147 202 ble.gap().setAdvertisingInterval(100); // 100ms
andriym 89:425369a595c4 203
andriym 90:b4d53a870147 204 // Start advertising
andriym 89:425369a595c4 205 ble.gap().startAdvertising();
andriym 89:425369a595c4 206 }
andriym 93:620dd0a7ddc7 207 */
andriym 89:425369a595c4 208 #endif // BLE_ENABLE
andriym 89:425369a595c4 209
andriym 78:43a6b54f0372 210 /////////////////////////////////// CLASSES ///////////////////////////////////
andriym 78:43a6b54f0372 211
andriym 78:43a6b54f0372 212 struct Contact {
andriym 78:43a6b54f0372 213 int16_t rssi;
andriym 78:43a6b54f0372 214 uint32_t time_ms;
andriym 78:43a6b54f0372 215 };
andriym 78:43a6b54f0372 216
andriym 78:43a6b54f0372 217 class Player {
andriym 78:43a6b54f0372 218 public:
andriym 78:43a6b54f0372 219 char name[NAME_LEN+1];
andriym 78:43a6b54f0372 220 int8_t team;
andriym 78:43a6b54f0372 221 Player(const char rand_name[]) {
andriym 78:43a6b54f0372 222 memset(name, 0x00, NAME_LEN+1);
andriym 78:43a6b54f0372 223 memcpy(name, rand_name, NAME_LEN);
andriym 78:43a6b54f0372 224 }
andriym 78:43a6b54f0372 225 void update(int8_t _team, int rssi, uint32_t time=NULL) {
andriym 78:43a6b54f0372 226 // Remember this contact
andriym 78:43a6b54f0372 227 team = _team;
andriym 78:43a6b54f0372 228 Contact c;
andriym 78:43a6b54f0372 229 c.rssi = rssi;
andriym 89:425369a595c4 230 c.time_ms = (time!=NULL) ? time : tmr.read_ms();
andriym 78:43a6b54f0372 231 contacts.push_front(c);
andriym 78:43a6b54f0372 232
andriym 78:43a6b54f0372 233 // Cleanup
andriym 78:43a6b54f0372 234 while(contacts.size() > MAX_RECORDS) contacts.pop_back();
andriym 78:43a6b54f0372 235 while(!contacts.empty() && c.time_ms - contacts.back().time_ms > MAX_HISTORY_MS) contacts.pop_back();
andriym 78:43a6b54f0372 236 }
andriym 78:43a6b54f0372 237 int16_t get_distance(int &cnt) {
andriym 78:43a6b54f0372 238 // Find max RSSI
andriym 89:425369a595c4 239 uint32_t cur_time = tmr.read_ms();
andriym 78:43a6b54f0372 240 int16_t max_rssi=-128;
andriym 78:43a6b54f0372 241 cnt=0;
andriym 78:43a6b54f0372 242 for (list<Contact>::iterator it=contacts.begin(); it != contacts.end(); ++it) {
andriym 78:43a6b54f0372 243 if(cur_time - it->time_ms > SIGNALS_VALID_MS) break;
andriym 78:43a6b54f0372 244 if(it->rssi > max_rssi) max_rssi = it->rssi;
andriym 78:43a6b54f0372 245 cnt++;
andriym 78:43a6b54f0372 246 }
andriym 78:43a6b54f0372 247 return max_rssi;
andriym 78:43a6b54f0372 248 }
andriym 78:43a6b54f0372 249 inline bool operator==(const char rhs[]){ return memcmp(name, rhs, NAME_LEN)==0; }
andriym 78:43a6b54f0372 250 inline bool operator==(const Player& rhs){ return *this==rhs.name; }
andriym 78:43a6b54f0372 251 //inline bool operator!=(const char rhs[]){ return !(*this == rhs); }
andriym 78:43a6b54f0372 252 private:
andriym 78:43a6b54f0372 253 list<Contact> contacts;
andriym 78:43a6b54f0372 254 };
andriym 78:43a6b54f0372 255
andriym 78:43a6b54f0372 256 class Players {
andriym 78:43a6b54f0372 257 public:
andriym 78:43a6b54f0372 258 list<Player> players;
andriym 78:43a6b54f0372 259
andriym 78:43a6b54f0372 260 void update(const char name[], int8_t team, int16_t rssi, uint32_t time_ms=NULL) {
andriym 78:43a6b54f0372 261 list<Player>::iterator it;
andriym 78:43a6b54f0372 262 for (it=players.begin(); it != players.end(); ++it) {
andriym 78:43a6b54f0372 263 if(*it==name) break;
andriym 78:43a6b54f0372 264 }
andriym 78:43a6b54f0372 265 if(it!=players.end()) {
andriym 78:43a6b54f0372 266 it->update(team, rssi, time_ms);
andriym 78:43a6b54f0372 267 } else {
andriym 78:43a6b54f0372 268 Player p(name);
andriym 78:43a6b54f0372 269 p.update(team, rssi, time_ms);
andriym 78:43a6b54f0372 270 players.push_front(p);
andriym 78:43a6b54f0372 271 }
andriym 78:43a6b54f0372 272 }
andriym 78:43a6b54f0372 273
andriym 81:3cd7de5d01ef 274 void showAll(int8_t team, uint8_t level, uint8_t volume) {
andriym 79:9db29f41dc9d 275 // Output the current state to the user:
andriym 79:9db29f41dc9d 276 // - show the current information table and/or
andriym 79:9db29f41dc9d 277 // - beep if the user is too close to another one
andriym 79:9db29f41dc9d 278 int i=0, nContacts, signal, maxTeamSignal = -128;
andriym 78:43a6b54f0372 279 list<Player>::iterator it;
andriym 95:3cc3ae2e5e7f 280 //out.clear();
andriym 78:43a6b54f0372 281 for (it=players.begin(); it != players.end(); ++it) {
andriym 79:9db29f41dc9d 282 signal = it->get_distance(nContacts);
andriym 79:9db29f41dc9d 283 if(signal>-128) {
andriym 95:3cc3ae2e5e7f 284 /*
andriym 78:43a6b54f0372 285 out.printf("%d ", ++i);
andriym 78:43a6b54f0372 286 out.printf((team==it->team) ? "+" : "-"); // teammate or opponent?
andriym 78:43a6b54f0372 287 out.printf("%s ", it->name);
andriym 79:9db29f41dc9d 288 out.printf("%d/%d", -signal, nContacts);
andriym 79:9db29f41dc9d 289 out.printf((-signal<SPACE[level]) ? "!" : " ");
andriym 79:9db29f41dc9d 290 out.printf("\r\n");
andriym 95:3cc3ae2e5e7f 291 */
andriym 79:9db29f41dc9d 292 }
andriym 79:9db29f41dc9d 293 if(team==it->team && signal>maxTeamSignal) {
andriym 79:9db29f41dc9d 294 maxTeamSignal = signal;
andriym 78:43a6b54f0372 295 }
andriym 78:43a6b54f0372 296 }
andriym 79:9db29f41dc9d 297 //if(!i) {
andriym 79:9db29f41dc9d 298 // out.printf("Nobody around\r\n");
andriym 81:3cd7de5d01ef 299 // beep(NOTE_A5,0.5,volume);
andriym 79:9db29f41dc9d 300 //}
andriym 79:9db29f41dc9d 301 if(-maxTeamSignal<SPACE[level]) {
andriym 81:3cd7de5d01ef 302 beep(NOTE_A4, 0.33, volume);
andriym 78:43a6b54f0372 303 }
andriym 78:43a6b54f0372 304 }
andriym 78:43a6b54f0372 305 };
andriym 78:43a6b54f0372 306
andriym 78:43a6b54f0372 307 /////////////////////////////////// MAIN CODE ///////////////////////////////////
andriym 78:43a6b54f0372 308
elmbed 76:6638d83939d5 309 int main()
andriym 78:43a6b54f0372 310 {
andriym 92:a9ebe6d0a0fa 311 #ifdef BLE_ENABLE
andriym 92:a9ebe6d0a0fa 312 // BLE initialization
andriym 92:a9ebe6d0a0fa 313 ble.init();
andriym 92:a9ebe6d0a0fa 314 ble.onDisconnection(disconnectionCallback);
andriym 92:a9ebe6d0a0fa 315 #endif // BLE_ENABLE
andriym 92:a9ebe6d0a0fa 316
elmbed 76:6638d83939d5 317 char tx_buff[100] = {0};
elmbed 76:6638d83939d5 318 char rx_buff[100] = {0};
andriym 78:43a6b54f0372 319 char rand_name[NAME_LEN+1] = {0};
andriym 78:43a6b54f0372 320 char other_name[NAME_LEN+1] = {0};
andriym 79:9db29f41dc9d 321 int8_t myTeam = 1, otherTeam;
andriym 87:a9870d513fcf 322 uint8_t level = 1, volume = 1; // SPACE10, VOL_LOW
andriym 89:425369a595c4 323 int bTeamNew, bTeamOld, bSpaceOld, bSpaceNew, bVMNew, bVLNew, bVMOld, bVLOld;
elmbed 76:6638d83939d5 324
andriym 94:831a7fc2d69a 325 // Blink all the LEDs at startup
andriym 94:831a7fc2d69a 326 spaceLEDs(0); wait(0.2); spaceLEDs(1); wait(0.2); spaceLEDs(2); wait(0.2); spaceLEDs(3); wait(0.2); ledSpace20 = 0;
andriym 94:831a7fc2d69a 327 #ifdef TEST_LED_SOUND
andriym 94:831a7fc2d69a 328 // Test LEDs and sound simultaneously to save time
andriym 94:831a7fc2d69a 329 buzzMed = MED_OFF; buzzHigh = HIGH_OFF;
andriym 94:831a7fc2d69a 330 ledBuzzer = 1; buzzer=0; wait(0.2); buzzer=1; ledBuzzer = 0;
andriym 94:831a7fc2d69a 331 buzzMed = MED_ON;
andriym 94:831a7fc2d69a 332 ledTeamA = 1; buzzer=0; wait(0.2); buzzer=1; ledTeamA = 0;
andriym 94:831a7fc2d69a 333 buzzMed = MED_OFF; buzzHigh = HIGH_ON;
andriym 94:831a7fc2d69a 334 ledTeamB = 1; buzzer=0; wait(0.2); buzzer=1; ledTeamB = 0;
andriym 94:831a7fc2d69a 335 buzzHigh = HIGH_OFF;
andriym 94:831a7fc2d69a 336 #else
andriym 94:831a7fc2d69a 337 ledBuzzer = 1; wait(0.2); ledBuzzer = 0;
andriym 94:831a7fc2d69a 338 ledTeamA = 1; wait(0.2); ledTeamA = 0;
andriym 94:831a7fc2d69a 339 ledTeamB = 1; wait(0.2); ledTeamB = 0;
andriym 89:425369a595c4 340
andriym 94:831a7fc2d69a 341 // Beep all the levels on startup
andriym 94:831a7fc2d69a 342 beep(NOTE_A5, 0.2, 1);
andriym 94:831a7fc2d69a 343 beep(NOTE_A5, 0.2, 2);
andriym 94:831a7fc2d69a 344 beep(NOTE_A5, 0.2, 3);
andriym 94:831a7fc2d69a 345 #endif
andriym 94:831a7fc2d69a 346
andriym 94:831a7fc2d69a 347 // ...and go to a informative LEDs
andriym 94:831a7fc2d69a 348 spaceLEDs(level);
andriym 81:3cd7de5d01ef 349 ledBuzzer = volume ? 1 : 0;
andriym 94:831a7fc2d69a 350 if(myTeam & 1) ledTeamA = 1;
andriym 94:831a7fc2d69a 351 else ledTeamB = 1;
andriym 89:425369a595c4 352
andriym 89:425369a595c4 353 // Buttons initialization
andriym 79:9db29f41dc9d 354 buttonSpace.mode(PullDown);
andriym 81:3cd7de5d01ef 355 buttonVolMore.mode(PullDown);
andriym 81:3cd7de5d01ef 356 buttonVolLess.mode(PullDown);
andriym 79:9db29f41dc9d 357 #ifdef NORDIC
andriym 79:9db29f41dc9d 358 buttonTeam.mode(PullDown);
andriym 89:425369a595c4 359 bTeamOld = 0;
andriym 79:9db29f41dc9d 360 #else
andriym 79:9db29f41dc9d 361 buttonTeam.mode(PullUp);
andriym 89:425369a595c4 362 bTeamOld = 1;
andriym 79:9db29f41dc9d 363 #endif
andriym 89:425369a595c4 364 bSpaceOld = 0;
andriym 89:425369a595c4 365 bVMOld = 0;
andriym 89:425369a595c4 366 bVLOld = 0;
elmbed 76:6638d83939d5 367
andriym 89:425369a595c4 368 #ifdef BLE_ENABLE
andriym 92:a9ebe6d0a0fa 369 // setup advertising
andriym 92:a9ebe6d0a0fa 370 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
andriym 92:a9ebe6d0a0fa 371 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
andriym 92:a9ebe6d0a0fa 372 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
andriym 92:a9ebe6d0a0fa 373 (const uint8_t *)"KeepTheSpace", sizeof("KeepTheSpace") - 1);
andriym 92:a9ebe6d0a0fa 374 //ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
andriym 92:a9ebe6d0a0fa 375 // (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
andriym 92:a9ebe6d0a0fa 376
andriym 92:a9ebe6d0a0fa 377 // 100ms; in multiples of 0.625ms.
andriym 92:a9ebe6d0a0fa 378 ble.setAdvertisingInterval(160);
andriym 92:a9ebe6d0a0fa 379
andriym 93:620dd0a7ddc7 380 //ble.addService(uartService);
andriym 92:a9ebe6d0a0fa 381
andriym 92:a9ebe6d0a0fa 382 DFUService dfu(ble);
andriym 92:a9ebe6d0a0fa 383
andriym 92:a9ebe6d0a0fa 384 ble.startAdvertising();
andriym 92:a9ebe6d0a0fa 385 //pc.printf("Advertising Start \r\n");
andriym 92:a9ebe6d0a0fa 386
andriym 92:a9ebe6d0a0fa 387 /*
andriym 92:a9ebe6d0a0fa 388 // GAP version
andriym 89:425369a595c4 389 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
andriym 89:425369a595c4 390 ble.init(bleInitComplete); // Initialize BLE baselayer
andriym 91:0fc897cccc06 391 DFUService dfu( ble );
andriym 92:a9ebe6d0a0fa 392 */
andriym 89:425369a595c4 393 #endif // BLE_ENABLE
andriym 89:425369a595c4 394
andriym 89:425369a595c4 395 // Pick node number
andriym 78:43a6b54f0372 396 char this_node = int(ain.read()*255+17)*int(ain.read()*255+11); // random node value
andriym 95:3cc3ae2e5e7f 397 //out.printf("Node: %d\r\n", this_node);
andriym 78:43a6b54f0372 398
andriym 89:425369a595c4 399 // Initialize the radio
andriym 78:43a6b54f0372 400 radio.initialize(FREQUENCY, this_node, NETWORKID);
andriym 78:43a6b54f0372 401 #ifdef HIGH_POWER
andriym 78:43a6b54f0372 402 radio.setHighPower(true);
andriym 78:43a6b54f0372 403 #endif
elmbed 76:6638d83939d5 404 radio.encrypt(0);
elmbed 76:6638d83939d5 405 radio.promiscuous(promiscuousMode);
andriym 85:4692a1790cfa 406 if(FREQUENCY == RF69_868MHZ)
andriym 85:4692a1790cfa 407 radio.setFrequency(868000000);
andriym 85:4692a1790cfa 408 else if(FREQUENCY == RF69_915MHZ)
andriym 85:4692a1790cfa 409 radio.setFrequency(915000000);
AntonLS 11:d3aa5fca2330 410
andriym 89:425369a595c4 411 // Pick node name
andriym 78:43a6b54f0372 412 generate_name(rand_name, sizeof(rand_name));
andriym 95:3cc3ae2e5e7f 413 /*
andriym 78:43a6b54f0372 414 out.printf("Name: %s\r\n", rand_name);
andriym 78:43a6b54f0372 415 out.sleep(2.0);
andriym 95:3cc3ae2e5e7f 416 */
andriym 78:43a6b54f0372 417
andriym 89:425369a595c4 418 tmr.start();
andriym 78:43a6b54f0372 419
andriym 78:43a6b54f0372 420 Players players;
andriym 78:43a6b54f0372 421
andriym 89:425369a595c4 422 uint32_t last_send = tmr.read_ms();
andriym 89:425369a595c4 423 uint32_t last_shown = tmr.read_ms();
andriym 78:43a6b54f0372 424 //uint32_t min_wait = SEND_RATE_MS - 0.5*SEND_RATE_MS*SEND_DESYNC;
andriym 78:43a6b54f0372 425 //uint32_t send_wait = min_wait;
AntonLS 49:626e84ce5e52 426
elmbed 76:6638d83939d5 427 while (true)
AntonLS 19:afcbb425b3cf 428 {
andriym 79:9db29f41dc9d 429 // Read team button
andriym 79:9db29f41dc9d 430 bTeamNew = buttonTeam;
andriym 79:9db29f41dc9d 431 if(bTeamNew==PRESSED && bTeamOld==RELEASED) {
andriym 79:9db29f41dc9d 432 myTeam = (myTeam==1) ? 2 : 1;
andriym 79:9db29f41dc9d 433 ledTeamA = myTeam & 1;
andriym 79:9db29f41dc9d 434 ledTeamB = ~myTeam & 1;
andriym 95:3cc3ae2e5e7f 435 /*
andriym 78:43a6b54f0372 436 out.clear();
andriym 79:9db29f41dc9d 437 out.printf("New team: %d\r\n", myTeam);
andriym 78:43a6b54f0372 438 out.sleep(2);
andriym 95:3cc3ae2e5e7f 439 */
andriym 78:43a6b54f0372 440 }
andriym 79:9db29f41dc9d 441 bTeamOld = bTeamNew;
andriym 79:9db29f41dc9d 442
andriym 79:9db29f41dc9d 443 // Read space button
andriym 79:9db29f41dc9d 444 bSpaceNew = buttonSpace;
andriym 79:9db29f41dc9d 445 if(bSpaceNew && !bSpaceOld) {
andriym 79:9db29f41dc9d 446 level = (level+1) & 0b11; // four states
andriym 85:4692a1790cfa 447 spaceLEDs(level);
andriym 95:3cc3ae2e5e7f 448 /*
andriym 79:9db29f41dc9d 449 out.clear();
andriym 79:9db29f41dc9d 450 out.printf("New level: %d\r\n", level);
andriym 79:9db29f41dc9d 451 out.sleep(2);
andriym 95:3cc3ae2e5e7f 452 */
andriym 79:9db29f41dc9d 453 }
andriym 79:9db29f41dc9d 454 bSpaceOld = bSpaceNew;
andriym 81:3cd7de5d01ef 455
andriym 81:3cd7de5d01ef 456 // Read volume buttons
andriym 82:1e552cc1a615 457 bVMNew = buttonVolMore.read();
andriym 82:1e552cc1a615 458 bVLNew = buttonVolLess.read();
andriym 81:3cd7de5d01ef 459 if(bVMNew && !bVMOld) {
andriym 81:3cd7de5d01ef 460 volume++;
andriym 81:3cd7de5d01ef 461 if(volume>3) volume=3;
andriym 81:3cd7de5d01ef 462 ledBuzzer = 1;
andriym 95:3cc3ae2e5e7f 463 /*
andriym 81:3cd7de5d01ef 464 out.clear();
andriym 81:3cd7de5d01ef 465 out.printf("New volume: %d\r\n", volume);
andriym 81:3cd7de5d01ef 466 out.sleep(2);
andriym 95:3cc3ae2e5e7f 467 */
andriym 81:3cd7de5d01ef 468 }
andriym 81:3cd7de5d01ef 469 if(bVLNew && !bVLOld) {
andriym 81:3cd7de5d01ef 470 if(volume>0) volume--;
andriym 81:3cd7de5d01ef 471 if(!volume) ledBuzzer = 0;
andriym 95:3cc3ae2e5e7f 472 /*
andriym 81:3cd7de5d01ef 473 out.clear();
andriym 81:3cd7de5d01ef 474 out.printf("New volume: %d\r\n", volume);
andriym 81:3cd7de5d01ef 475 out.sleep(2);
andriym 95:3cc3ae2e5e7f 476 */
andriym 81:3cd7de5d01ef 477 }
andriym 81:3cd7de5d01ef 478 bVMOld = bVMNew;
andriym 81:3cd7de5d01ef 479 bVLOld = bVLNew;
andriym 81:3cd7de5d01ef 480
andriym 81:3cd7de5d01ef 481 // Output
andriym 89:425369a595c4 482 unsigned long current_time = tmr.read_ms();
elmbed 76:6638d83939d5 483
andriym 79:9db29f41dc9d 484 if (current_time - last_shown > CYCLE_MS)
andriym 78:43a6b54f0372 485 {
andriym 81:3cd7de5d01ef 486 players.showAll(myTeam, level, volume);
andriym 78:43a6b54f0372 487 last_shown = current_time;
andriym 78:43a6b54f0372 488 }
andriym 78:43a6b54f0372 489
andriym 81:3cd7de5d01ef 490 // Radios
andriym 78:43a6b54f0372 491 if (current_time - last_send > SEND_RATE_MS)
AntonLS 19:afcbb425b3cf 492 {
elmbed 76:6638d83939d5 493 // Send message
andriym 79:9db29f41dc9d 494 snprintf(tx_buff, sizeof(tx_buff), "N=%s,%d", rand_name, myTeam);
andriym 78:43a6b54f0372 495 radio.send(EVERY_NODE, tx_buff, strlen(tx_buff));
andriym 78:43a6b54f0372 496 last_send = current_time;
andriym 78:43a6b54f0372 497 //send_wait = min_wait + (rand() % SEND_RATE_MS)*SEND_DESYNC;
andriym 78:43a6b54f0372 498
andriym 89:425369a595c4 499 //// Some debugging info I used to display
andriym 78:43a6b54f0372 500 //out.clear();
andriym 78:43a6b54f0372 501 //out.printf("Sent: %s\r\n", tx_buff);
andriym 78:43a6b54f0372 502 //uint8_t tempC = radio.readTemperature(-1); // -1 = user cal factor, adjust for correct ambient
andriym 78:43a6b54f0372 503 //uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain
andriym 78:43a6b54f0372 504 //uint32_t freq = radio.getFrequency();
andriym 78:43a6b54f0372 505 //out.printf("T: %d, G: %d\r\n", tempC, gain);
andriym 78:43a6b54f0372 506 //if(freq!=868000000) out.printf("Freq: %d\r\n", freq);
elmbed 76:6638d83939d5 507
andriym 81:3cd7de5d01ef 508 //beep(NOTE_A3, 0.05, volume);
elmbed 76:6638d83939d5 509 }
andriym 78:43a6b54f0372 510
elmbed 76:6638d83939d5 511 if (radio.receiveDone())
AntonLS 11:d3aa5fca2330 512 {
elmbed 76:6638d83939d5 513 memset(rx_buff, 0x00, sizeof(rx_buff));
elmbed 76:6638d83939d5 514 memcpy(rx_buff, (char*)radio.DATA, radio.DATALEN > sizeof(rx_buff)-1 ? sizeof(rx_buff)-1 : radio.DATALEN);
elmbed 76:6638d83939d5 515
andriym 78:43a6b54f0372 516 if(rx_buff[0]=='N' && rx_buff[1]=='=') {
andriym 78:43a6b54f0372 517 memcpy(other_name, rx_buff+2, NAME_LEN);
andriym 78:43a6b54f0372 518 other_name[5] = 0x00;
andriym 78:43a6b54f0372 519 if(sizeof(rx_buff)>8 && rx_buff[7]==',') {
andriym 79:9db29f41dc9d 520 otherTeam = rx_buff[8]-'0';
andriym 79:9db29f41dc9d 521 } else otherTeam = 1;
andriym 89:425369a595c4 522 players.update(other_name, otherTeam, radio.RSSI, tmr.read_ms());
andriym 78:43a6b54f0372 523
andriym 78:43a6b54f0372 524 //uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain
andriym 78:43a6b54f0372 525 //out.clear();
andriym 78:43a6b54f0372 526 //out.printf("Other: %s\r\n", other_name);
andriym 78:43a6b54f0372 527 //out.printf("RSSI: %d, G: %d\r\n", radio.RSSI, gain);
andriym 78:43a6b54f0372 528
andriym 81:3cd7de5d01ef 529 //beep(NOTE_A5, 0.5, volume);
andriym 78:43a6b54f0372 530 } else { // received unknown signal
andriym 78:43a6b54f0372 531 uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain
andriym 95:3cc3ae2e5e7f 532 /*
andriym 78:43a6b54f0372 533 out.clear();
andriym 78:43a6b54f0372 534 out.printf("Got: %s\r\n", rx_buff);
andriym 78:43a6b54f0372 535 out.printf("RSSI: %d, G: %d\r\n", radio.RSSI, gain);
andriym 78:43a6b54f0372 536 out.sleep(2.0);
andriym 95:3cc3ae2e5e7f 537 */
andriym 78:43a6b54f0372 538 }
AntonLS 11:d3aa5fca2330 539 }
andriym 89:425369a595c4 540
andriym 89:425369a595c4 541 #ifdef BLE_ENABLE
andriym 92:a9ebe6d0a0fa 542 // ble.waitForEvent();
andriym 91:0fc897cccc06 543 #endif // BLE_ENABLE
AntonLS 0:28ca4562fe1a 544 }
elmbed 76:6638d83939d5 545 }