football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Committer:
andriym
Date:
Mon May 09 01:08:01 2016 +0000
Revision:
78:43a6b54f0372
Parent:
76:6638d83939d5
Child:
79:9db29f41dc9d
Changed radio configs, Player tracking table, Switch team button, Output class (for different displays and Serial), different boards support.

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"
AntonLS 0:28ca4562fe1a 4
andriym 78:43a6b54f0372 5 using namespace std;
andriym 78:43a6b54f0372 6
andriym 78:43a6b54f0372 7 Timer t;
andriym 78:43a6b54f0372 8 Output out;
elmbed 17:d8b901d791fd 9
andriym 78:43a6b54f0372 10 /////////////////////////////////// PINS ///////////////////////////////////
andriym 78:43a6b54f0372 11 #ifdef NORDIC
andriym 78:43a6b54f0372 12 //PwmOut speaker(PB_8); // TODO: add sound for Nordic
andriym 78:43a6b54f0372 13 DigitalIn din(BTN1);
andriym 78:43a6b54f0372 14 AnalogIn ain(P0_1); // used for randomizing
andriym 78:43a6b54f0372 15 #else // not NORDIC
andriym 78:43a6b54f0372 16 #ifdef NUCLEO
andriym 78:43a6b54f0372 17 PwmOut speaker(PB_8);
andriym 78:43a6b54f0372 18 DigitalIn din(USER_BUTTON);
andriym 78:43a6b54f0372 19 AnalogIn ain(A5); // used for randomizing
andriym 78:43a6b54f0372 20 #else // LPC assumed
andriym 78:43a6b54f0372 21 PwmOut speaker(p21);
andriym 78:43a6b54f0372 22 DigitalIn din(p5);
andriym 78:43a6b54f0372 23 AnalogIn ain(p15); // used for randomizing
andriym 78:43a6b54f0372 24 #endif // NUCLEO
andriym 78:43a6b54f0372 25 #endif // NORDIC
AntonLS 30:c60b0d52b067 26
andriym 78:43a6b54f0372 27 /////////////////////////////////// RADIO ///////////////////////////////////
andriym 78:43a6b54f0372 28 #ifdef NORDIC
andriym 78:43a6b54f0372 29 static RFM69 radio(P0_20,P0_22,P0_25,P0_24,P0_23); // Update according to your setup
andriym 78:43a6b54f0372 30 #else // not NORDIC
andriym 78:43a6b54f0372 31 #ifdef NUCLEO
andriym 78:43a6b54f0372 32 static RFM69 radio(D11,D12,D13,D10,D9);
andriym 78:43a6b54f0372 33 #else // LPC assumed
andriym 78:43a6b54f0372 34 static RFM69 radio(p11,p12,p13,p10,p9);
andriym 78:43a6b54f0372 35 #endif // NUCLEO
andriym 78:43a6b54f0372 36 #endif // NORDIC
AntonLS 12:6d313d575f84 37
elmbed 76:6638d83939d5 38 static bool promiscuousMode = true; // set 'true' to sniff all packets on the same network
AntonLS 0:28ca4562fe1a 39
andriym 78:43a6b54f0372 40 /////////////////////////////////// FUNCTIONS ///////////////////////////////////
andriym 78:43a6b54f0372 41
andriym 78:43a6b54f0372 42 void beep(float period, float time) {
andriym 78:43a6b54f0372 43 #ifdef ENABLE_SOUND
andriym 78:43a6b54f0372 44 speaker.period(period);
andriym 78:43a6b54f0372 45 speaker =0.5; //50% duty cycle - max volume
andriym 78:43a6b54f0372 46 wait(time);
andriym 78:43a6b54f0372 47 speaker=0.0; // turn off audio
andriym 78:43a6b54f0372 48 #endif
andriym 78:43a6b54f0372 49 }
andriym 78:43a6b54f0372 50
andriym 78:43a6b54f0372 51 void binary_sound(int z) {
andriym 78:43a6b54f0372 52 // Beeps numbers according to their binary form
andriym 78:43a6b54f0372 53 // (used for debugging in display-less and serial-less environments)
andriym 78:43a6b54f0372 54 #ifdef ENABLE_SOUND
andriym 78:43a6b54f0372 55 speaker.period(0.004);
andriym 78:43a6b54f0372 56 while(z) {
andriym 78:43a6b54f0372 57 speaker = 0.5;
andriym 78:43a6b54f0372 58 if(z&1) wait(0.5);
andriym 78:43a6b54f0372 59 else wait(0.25);
andriym 78:43a6b54f0372 60 speaker = 0.0;
andriym 78:43a6b54f0372 61 wait(1.0);
andriym 78:43a6b54f0372 62 z >>= 1;
andriym 78:43a6b54f0372 63 }
andriym 78:43a6b54f0372 64 beep(0.002, 1.0);
andriym 78:43a6b54f0372 65 #endif
andriym 78:43a6b54f0372 66 }
andriym 78:43a6b54f0372 67
andriym 78:43a6b54f0372 68 void generate_name(char rand_name[], uint8_t size) {
andriym 78:43a6b54f0372 69 // Generate random name on the 62 character alphabet
andriym 78:43a6b54f0372 70 memset(rand_name, 0x00, size);
andriym 78:43a6b54f0372 71 char alph[63] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
andriym 78:43a6b54f0372 72 uint32_t seed = ((ain.read_u16()+3)/17)*(radio.readTemperature(-1)+37)*((ain.read_u16()+5)/13);
andriym 78:43a6b54f0372 73 srand(seed);
andriym 78:43a6b54f0372 74 for(int i=0;i<size-1;i++) {
andriym 78:43a6b54f0372 75 rand_name[i] = alph[abs(rand()) % 62];
andriym 78:43a6b54f0372 76 }
andriym 78:43a6b54f0372 77 }
andriym 78:43a6b54f0372 78
andriym 78:43a6b54f0372 79 /////////////////////////////////// CLASSES ///////////////////////////////////
andriym 78:43a6b54f0372 80
andriym 78:43a6b54f0372 81 struct Contact {
andriym 78:43a6b54f0372 82 int16_t rssi;
andriym 78:43a6b54f0372 83 uint32_t time_ms;
andriym 78:43a6b54f0372 84 };
andriym 78:43a6b54f0372 85
andriym 78:43a6b54f0372 86 class Player {
andriym 78:43a6b54f0372 87 public:
andriym 78:43a6b54f0372 88 char name[NAME_LEN+1];
andriym 78:43a6b54f0372 89 int8_t team;
andriym 78:43a6b54f0372 90 Player(const char rand_name[]) {
andriym 78:43a6b54f0372 91 memset(name, 0x00, NAME_LEN+1);
andriym 78:43a6b54f0372 92 memcpy(name, rand_name, NAME_LEN);
andriym 78:43a6b54f0372 93 }
andriym 78:43a6b54f0372 94 void update(int8_t _team, int rssi, uint32_t time=NULL) {
andriym 78:43a6b54f0372 95 // Remember this contact
andriym 78:43a6b54f0372 96 team = _team;
andriym 78:43a6b54f0372 97 Contact c;
andriym 78:43a6b54f0372 98 c.rssi = rssi;
andriym 78:43a6b54f0372 99 c.time_ms = (time!=NULL) ? time : t.read_ms();
andriym 78:43a6b54f0372 100 contacts.push_front(c);
andriym 78:43a6b54f0372 101
andriym 78:43a6b54f0372 102 // Cleanup
andriym 78:43a6b54f0372 103 while(contacts.size() > MAX_RECORDS) contacts.pop_back();
andriym 78:43a6b54f0372 104 while(!contacts.empty() && c.time_ms - contacts.back().time_ms > MAX_HISTORY_MS) contacts.pop_back();
andriym 78:43a6b54f0372 105 }
andriym 78:43a6b54f0372 106 int16_t get_distance(int &cnt) {
andriym 78:43a6b54f0372 107 // Find max RSSI
andriym 78:43a6b54f0372 108 uint32_t cur_time = t.read_ms();
andriym 78:43a6b54f0372 109 int16_t max_rssi=-128;
andriym 78:43a6b54f0372 110 cnt=0;
andriym 78:43a6b54f0372 111 for (list<Contact>::iterator it=contacts.begin(); it != contacts.end(); ++it) {
andriym 78:43a6b54f0372 112 if(cur_time - it->time_ms > SIGNALS_VALID_MS) break;
andriym 78:43a6b54f0372 113 if(it->rssi > max_rssi) max_rssi = it->rssi;
andriym 78:43a6b54f0372 114 cnt++;
andriym 78:43a6b54f0372 115 }
andriym 78:43a6b54f0372 116 return max_rssi;
andriym 78:43a6b54f0372 117 }
andriym 78:43a6b54f0372 118 inline bool operator==(const char rhs[]){ return memcmp(name, rhs, NAME_LEN)==0; }
andriym 78:43a6b54f0372 119 inline bool operator==(const Player& rhs){ return *this==rhs.name; }
andriym 78:43a6b54f0372 120 //inline bool operator!=(const char rhs[]){ return !(*this == rhs); }
andriym 78:43a6b54f0372 121 private:
andriym 78:43a6b54f0372 122 list<Contact> contacts;
andriym 78:43a6b54f0372 123 };
andriym 78:43a6b54f0372 124
andriym 78:43a6b54f0372 125 class Players {
andriym 78:43a6b54f0372 126 public:
andriym 78:43a6b54f0372 127 list<Player> players;
andriym 78:43a6b54f0372 128
andriym 78:43a6b54f0372 129 void update(const char name[], int8_t team, int16_t rssi, uint32_t time_ms=NULL) {
andriym 78:43a6b54f0372 130 list<Player>::iterator it;
andriym 78:43a6b54f0372 131 for (it=players.begin(); it != players.end(); ++it) {
andriym 78:43a6b54f0372 132 if(*it==name) break;
andriym 78:43a6b54f0372 133 }
andriym 78:43a6b54f0372 134 if(it!=players.end()) {
andriym 78:43a6b54f0372 135 it->update(team, rssi, time_ms);
andriym 78:43a6b54f0372 136 } else {
andriym 78:43a6b54f0372 137 Player p(name);
andriym 78:43a6b54f0372 138 p.update(team, rssi, time_ms);
andriym 78:43a6b54f0372 139 players.push_front(p);
andriym 78:43a6b54f0372 140 }
andriym 78:43a6b54f0372 141 }
andriym 78:43a6b54f0372 142
andriym 78:43a6b54f0372 143 void show_all(int8_t team) {
andriym 78:43a6b54f0372 144 // Show the current information table
andriym 78:43a6b54f0372 145 int i=0, contacts, dist;
andriym 78:43a6b54f0372 146 list<Player>::iterator it;
andriym 78:43a6b54f0372 147 out.clear();
andriym 78:43a6b54f0372 148 for (it=players.begin(); it != players.end(); ++it) {
andriym 78:43a6b54f0372 149 dist = it->get_distance(contacts);
andriym 78:43a6b54f0372 150 if(dist>-128) {
andriym 78:43a6b54f0372 151 out.printf("%d ", ++i);
andriym 78:43a6b54f0372 152 out.printf((team==it->team) ? "+" : "-"); // teammate or opponent?
andriym 78:43a6b54f0372 153 out.printf("%s ", it->name);
andriym 78:43a6b54f0372 154 out.printf("%d/%d\r\n", -dist, contacts);
andriym 78:43a6b54f0372 155 }
andriym 78:43a6b54f0372 156 }
andriym 78:43a6b54f0372 157 if(!i) {
andriym 78:43a6b54f0372 158 out.printf("Nobody around\r\n");
andriym 78:43a6b54f0372 159 beep(0.001,0.5);
andriym 78:43a6b54f0372 160 }
andriym 78:43a6b54f0372 161 }
andriym 78:43a6b54f0372 162 };
andriym 78:43a6b54f0372 163
andriym 78:43a6b54f0372 164 /////////////////////////////////// MAIN CODE ///////////////////////////////////
andriym 78:43a6b54f0372 165
elmbed 76:6638d83939d5 166 int main()
andriym 78:43a6b54f0372 167 {
elmbed 76:6638d83939d5 168 char tx_buff[100] = {0};
elmbed 76:6638d83939d5 169 char rx_buff[100] = {0};
andriym 78:43a6b54f0372 170 char rand_name[NAME_LEN+1] = {0};
andriym 78:43a6b54f0372 171 char other_name[NAME_LEN+1] = {0};
andriym 78:43a6b54f0372 172 int8_t team = 1, other_team;
elmbed 76:6638d83939d5 173
andriym 78:43a6b54f0372 174 beep(0.002, 0.5);
andriym 78:43a6b54f0372 175
andriym 78:43a6b54f0372 176 din.mode(PullUp);
andriym 78:43a6b54f0372 177 int button_old = 1, button_new;
elmbed 76:6638d83939d5 178
andriym 78:43a6b54f0372 179 char this_node = int(ain.read()*255+17)*int(ain.read()*255+11); // random node value
andriym 78:43a6b54f0372 180 out.printf("Node: %d\r\n", this_node);
andriym 78:43a6b54f0372 181
andriym 78:43a6b54f0372 182 // Init radio
andriym 78:43a6b54f0372 183 radio.initialize(FREQUENCY, this_node, NETWORKID);
andriym 78:43a6b54f0372 184 #ifdef HIGH_POWER
andriym 78:43a6b54f0372 185 radio.setHighPower(true);
andriym 78:43a6b54f0372 186 #endif
elmbed 76:6638d83939d5 187 radio.encrypt(0);
elmbed 76:6638d83939d5 188 radio.promiscuous(promiscuousMode);
andriym 78:43a6b54f0372 189 radio.setFrequency(868000000);
AntonLS 11:d3aa5fca2330 190
andriym 78:43a6b54f0372 191 generate_name(rand_name, sizeof(rand_name));
andriym 78:43a6b54f0372 192 out.printf("Name: %s\r\n", rand_name);
andriym 78:43a6b54f0372 193 out.sleep(2.0);
andriym 78:43a6b54f0372 194
elmbed 76:6638d83939d5 195 t.start();
andriym 78:43a6b54f0372 196
andriym 78:43a6b54f0372 197 Players players;
andriym 78:43a6b54f0372 198
andriym 78:43a6b54f0372 199 uint32_t last_send = t.read_ms();
andriym 78:43a6b54f0372 200 uint32_t last_shown = t.read_ms();
andriym 78:43a6b54f0372 201 //uint32_t min_wait = SEND_RATE_MS - 0.5*SEND_RATE_MS*SEND_DESYNC;
andriym 78:43a6b54f0372 202 //uint32_t send_wait = min_wait;
AntonLS 49:626e84ce5e52 203
elmbed 76:6638d83939d5 204 while (true)
AntonLS 19:afcbb425b3cf 205 {
andriym 78:43a6b54f0372 206 button_new = din;
andriym 78:43a6b54f0372 207 if(!button_new && button_old) {
andriym 78:43a6b54f0372 208 team = (team==1) ? 2 : 1;
andriym 78:43a6b54f0372 209 out.clear();
andriym 78:43a6b54f0372 210 out.printf("New team: %d\r\n", team);
andriym 78:43a6b54f0372 211 out.sleep(2);
andriym 78:43a6b54f0372 212 }
andriym 78:43a6b54f0372 213 button_old = button_new;
andriym 78:43a6b54f0372 214
elmbed 76:6638d83939d5 215 unsigned long current_time = t.read_ms();
elmbed 76:6638d83939d5 216
andriym 78:43a6b54f0372 217 if (current_time - last_shown > 2000L)
andriym 78:43a6b54f0372 218 {
andriym 78:43a6b54f0372 219 players.show_all(team);
andriym 78:43a6b54f0372 220 last_shown = current_time;
andriym 78:43a6b54f0372 221 }
andriym 78:43a6b54f0372 222
andriym 78:43a6b54f0372 223 if (current_time - last_send > SEND_RATE_MS)
AntonLS 19:afcbb425b3cf 224 {
elmbed 76:6638d83939d5 225 // Send message
andriym 78:43a6b54f0372 226 snprintf(tx_buff, sizeof(tx_buff), "N=%s,%d", rand_name, team);
andriym 78:43a6b54f0372 227 radio.send(EVERY_NODE, tx_buff, strlen(tx_buff));
andriym 78:43a6b54f0372 228 last_send = current_time;
andriym 78:43a6b54f0372 229 //send_wait = min_wait + (rand() % SEND_RATE_MS)*SEND_DESYNC;
andriym 78:43a6b54f0372 230
andriym 78:43a6b54f0372 231 //out.clear();
andriym 78:43a6b54f0372 232 //out.printf("Sent: %s\r\n", tx_buff);
andriym 78:43a6b54f0372 233 //uint8_t tempC = radio.readTemperature(-1); // -1 = user cal factor, adjust for correct ambient
andriym 78:43a6b54f0372 234 //uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain
andriym 78:43a6b54f0372 235 //uint32_t freq = radio.getFrequency();
andriym 78:43a6b54f0372 236 //out.printf("T: %d, G: %d\r\n", tempC, gain);
andriym 78:43a6b54f0372 237 //if(freq!=868000000) out.printf("Freq: %d\r\n", freq);
elmbed 76:6638d83939d5 238
andriym 78:43a6b54f0372 239 //beep(0.003, 0.05);
elmbed 76:6638d83939d5 240 }
andriym 78:43a6b54f0372 241
elmbed 76:6638d83939d5 242 if (radio.receiveDone())
AntonLS 11:d3aa5fca2330 243 {
elmbed 76:6638d83939d5 244 memset(rx_buff, 0x00, sizeof(rx_buff));
elmbed 76:6638d83939d5 245 memcpy(rx_buff, (char*)radio.DATA, radio.DATALEN > sizeof(rx_buff)-1 ? sizeof(rx_buff)-1 : radio.DATALEN);
elmbed 76:6638d83939d5 246
andriym 78:43a6b54f0372 247 if(rx_buff[0]=='N' && rx_buff[1]=='=') {
andriym 78:43a6b54f0372 248 memcpy(other_name, rx_buff+2, NAME_LEN);
andriym 78:43a6b54f0372 249 other_name[5] = 0x00;
andriym 78:43a6b54f0372 250 if(sizeof(rx_buff)>8 && rx_buff[7]==',') {
andriym 78:43a6b54f0372 251 other_team = rx_buff[8]-'0';
andriym 78:43a6b54f0372 252 } else other_team = 1;
andriym 78:43a6b54f0372 253 players.update(other_name, other_team, radio.RSSI, t.read_ms());
andriym 78:43a6b54f0372 254
andriym 78:43a6b54f0372 255 //uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain
andriym 78:43a6b54f0372 256 //out.clear();
andriym 78:43a6b54f0372 257 //out.printf("Other: %s\r\n", other_name);
andriym 78:43a6b54f0372 258 //out.printf("RSSI: %d, G: %d\r\n", radio.RSSI, gain);
andriym 78:43a6b54f0372 259
andriym 78:43a6b54f0372 260 //beep(0.001, 0.5);
andriym 78:43a6b54f0372 261 } else { // received unknown signal
andriym 78:43a6b54f0372 262 uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain
andriym 78:43a6b54f0372 263 out.clear();
andriym 78:43a6b54f0372 264 out.printf("Got: %s\r\n", rx_buff);
andriym 78:43a6b54f0372 265 out.printf("RSSI: %d, G: %d\r\n", radio.RSSI, gain);
andriym 78:43a6b54f0372 266 out.sleep(2.0);
andriym 78:43a6b54f0372 267 }
AntonLS 11:d3aa5fca2330 268 }
AntonLS 0:28ca4562fe1a 269 }
elmbed 76:6638d83939d5 270 }