football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Committer:
andriym
Date:
Thu Jun 16 03:55:32 2016 +0000
Revision:
94:831a7fc2d69a
Parent:
93:620dd0a7ddc7
Child:
95:3cc3ae2e5e7f
Testing all the LEDs and sounds at startup.

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