Andriy Makukha
/
football_project_wo_output
football_project_wo_output
Fork of football_project by
Diff: main.cpp
- Revision:
- 78:43a6b54f0372
- Parent:
- 76:6638d83939d5
- Child:
- 79:9db29f41dc9d
--- a/main.cpp Wed Apr 27 08:41:13 2016 +0000 +++ b/main.cpp Mon May 09 01:08:01 2016 +0000 @@ -1,54 +1,270 @@ #include <RFM69.h> -#include <SPI.h> +#include <list> +#include "output.h" -#define NODE_ID 1 // ID of the current node -#define SEND_TO_ID 2 // ID to send messages to +using namespace std; + +Timer t; +Output out; -#define NETWORKID 101 //the same on all nodes that talk to each other - -#define FREQUENCY RF69_915MHZ +/////////////////////////////////// PINS /////////////////////////////////// +#ifdef NORDIC +//PwmOut speaker(PB_8); // TODO: add sound for Nordic +DigitalIn din(BTN1); +AnalogIn ain(P0_1); // used for randomizing +#else // not NORDIC +#ifdef NUCLEO +PwmOut speaker(PB_8); +DigitalIn din(USER_BUTTON); +AnalogIn ain(A5); // used for randomizing +#else // LPC assumed +PwmOut speaker(p21); +DigitalIn din(p5); +AnalogIn ain(p15); // used for randomizing +#endif // NUCLEO +#endif // NORDIC -Serial pc(USBTX, USBRX); +/////////////////////////////////// RADIO /////////////////////////////////// +#ifdef NORDIC +static RFM69 radio(P0_20,P0_22,P0_25,P0_24,P0_23); // Update according to your setup +#else // not NORDIC +#ifdef NUCLEO +static RFM69 radio(D11,D12,D13,D10,D9); +#else // LPC assumed +static RFM69 radio(p11,p12,p13,p10,p9); +#endif // NUCLEO +#endif // NORDIC -static RFM69 radio(P0_24,P0_23,P0_25,P0_28,P0_7); static bool promiscuousMode = true; // set 'true' to sniff all packets on the same network +/////////////////////////////////// FUNCTIONS /////////////////////////////////// + +void beep(float period, float time) { +#ifdef ENABLE_SOUND + speaker.period(period); + speaker =0.5; //50% duty cycle - max volume + wait(time); + speaker=0.0; // turn off audio +#endif +} + +void binary_sound(int z) { + // Beeps numbers according to their binary form + // (used for debugging in display-less and serial-less environments) +#ifdef ENABLE_SOUND + speaker.period(0.004); + while(z) { + speaker = 0.5; + if(z&1) wait(0.5); + else wait(0.25); + speaker = 0.0; + wait(1.0); + z >>= 1; + } + beep(0.002, 1.0); +#endif +} + +void generate_name(char rand_name[], uint8_t size) { + // Generate random name on the 62 character alphabet + memset(rand_name, 0x00, size); + char alph[63] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + uint32_t seed = ((ain.read_u16()+3)/17)*(radio.readTemperature(-1)+37)*((ain.read_u16()+5)/13); + srand(seed); + for(int i=0;i<size-1;i++) { + rand_name[i] = alph[abs(rand()) % 62]; + } +} + +/////////////////////////////////// CLASSES /////////////////////////////////// + +struct Contact { + int16_t rssi; + uint32_t time_ms; +}; + +class Player { + public: + char name[NAME_LEN+1]; + int8_t team; + Player(const char rand_name[]) { + memset(name, 0x00, NAME_LEN+1); + memcpy(name, rand_name, NAME_LEN); + } + void update(int8_t _team, int rssi, uint32_t time=NULL) { + // Remember this contact + team = _team; + Contact c; + c.rssi = rssi; + c.time_ms = (time!=NULL) ? time : t.read_ms(); + contacts.push_front(c); + + // Cleanup + while(contacts.size() > MAX_RECORDS) contacts.pop_back(); + while(!contacts.empty() && c.time_ms - contacts.back().time_ms > MAX_HISTORY_MS) contacts.pop_back(); + } + int16_t get_distance(int &cnt) { + // Find max RSSI + uint32_t cur_time = t.read_ms(); + int16_t max_rssi=-128; + cnt=0; + for (list<Contact>::iterator it=contacts.begin(); it != contacts.end(); ++it) { + if(cur_time - it->time_ms > SIGNALS_VALID_MS) break; + if(it->rssi > max_rssi) max_rssi = it->rssi; + cnt++; + } + return max_rssi; + } + inline bool operator==(const char rhs[]){ return memcmp(name, rhs, NAME_LEN)==0; } + inline bool operator==(const Player& rhs){ return *this==rhs.name; } + //inline bool operator!=(const char rhs[]){ return !(*this == rhs); } + private: + list<Contact> contacts; +}; + +class Players { + public: + list<Player> players; + + void update(const char name[], int8_t team, int16_t rssi, uint32_t time_ms=NULL) { + list<Player>::iterator it; + for (it=players.begin(); it != players.end(); ++it) { + if(*it==name) break; + } + if(it!=players.end()) { + it->update(team, rssi, time_ms); + } else { + Player p(name); + p.update(team, rssi, time_ms); + players.push_front(p); + } + } + + void show_all(int8_t team) { + // Show the current information table + int i=0, contacts, dist; + list<Player>::iterator it; + out.clear(); + for (it=players.begin(); it != players.end(); ++it) { + dist = it->get_distance(contacts); + if(dist>-128) { + out.printf("%d ", ++i); + out.printf((team==it->team) ? "+" : "-"); // teammate or opponent? + out.printf("%s ", it->name); + out.printf("%d/%d\r\n", -dist, contacts); + } + } + if(!i) { + out.printf("Nobody around\r\n"); + beep(0.001,0.5); + } + } +}; + +/////////////////////////////////// MAIN CODE /////////////////////////////////// + int main() -{ - unsigned long last_send = 0L; +{ char tx_buff[100] = {0}; char rx_buff[100] = {0}; + char rand_name[NAME_LEN+1] = {0}; + char other_name[NAME_LEN+1] = {0}; + int8_t team = 1, other_team; - pc.baud(9600); - pc.printf("RFM69 test starting with ID: %d\r\n", NODE_ID); + beep(0.002, 0.5); + + din.mode(PullUp); + int button_old = 1, button_new; - radio.initialize(FREQUENCY, NODE_ID, NETWORKID); + char this_node = int(ain.read()*255+17)*int(ain.read()*255+11); // random node value + out.printf("Node: %d\r\n", this_node); + + // Init radio + radio.initialize(FREQUENCY, this_node, NETWORKID); +#ifdef HIGH_POWER + radio.setHighPower(true); +#endif radio.encrypt(0); radio.promiscuous(promiscuousMode); + radio.setFrequency(868000000); - Timer t; + generate_name(rand_name, sizeof(rand_name)); + out.printf("Name: %s\r\n", rand_name); + out.sleep(2.0); + t.start(); + + Players players; + + uint32_t last_send = t.read_ms(); + uint32_t last_shown = t.read_ms(); + //uint32_t min_wait = SEND_RATE_MS - 0.5*SEND_RATE_MS*SEND_DESYNC; + //uint32_t send_wait = min_wait; while (true) { + button_new = din; + if(!button_new && button_old) { + team = (team==1) ? 2 : 1; + out.clear(); + out.printf("New team: %d\r\n", team); + out.sleep(2); + } + button_old = button_new; + unsigned long current_time = t.read_ms(); - if (current_time - last_send > 2000L) + if (current_time - last_shown > 2000L) + { + players.show_all(team); + last_shown = current_time; + } + + if (current_time - last_send > SEND_RATE_MS) { // Send message - snprintf(tx_buff, sizeof(tx_buff), "msg frm: %d at %lu", NODE_ID, current_time); - radio.send(SEND_TO_ID, tx_buff, strlen(tx_buff)); - last_send = current_time; + snprintf(tx_buff, sizeof(tx_buff), "N=%s,%d", rand_name, team); + radio.send(EVERY_NODE, tx_buff, strlen(tx_buff)); + last_send = current_time; + //send_wait = min_wait + (rand() % SEND_RATE_MS)*SEND_DESYNC; + + //out.clear(); + //out.printf("Sent: %s\r\n", tx_buff); + //uint8_t tempC = radio.readTemperature(-1); // -1 = user cal factor, adjust for correct ambient + //uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain + //uint32_t freq = radio.getFrequency(); + //out.printf("T: %d, G: %d\r\n", tempC, gain); + //if(freq!=868000000) out.printf("Freq: %d\r\n", freq); - pc.printf("Sent: %s\r\n", tx_buff); + //beep(0.003, 0.05); } - + if (radio.receiveDone()) { memset(rx_buff, 0x00, sizeof(rx_buff)); memcpy(rx_buff, (char*)radio.DATA, radio.DATALEN > sizeof(rx_buff)-1 ? sizeof(rx_buff)-1 : radio.DATALEN); - pc.printf("Got: %s\r\n", rx_buff); + if(rx_buff[0]=='N' && rx_buff[1]=='=') { + memcpy(other_name, rx_buff+2, NAME_LEN); + other_name[5] = 0x00; + if(sizeof(rx_buff)>8 && rx_buff[7]==',') { + other_team = rx_buff[8]-'0'; + } else other_team = 1; + players.update(other_name, other_team, radio.RSSI, t.read_ms()); + + //uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain + //out.clear(); + //out.printf("Other: %s\r\n", other_name); + //out.printf("RSSI: %d, G: %d\r\n", radio.RSSI, gain); + + //beep(0.001, 0.5); + } else { // received unknown signal + uint8_t gain = (radio.readReg(REG_LNA) & 0b111000)>>3; // LNA Current Gain + out.clear(); + out.printf("Got: %s\r\n", rx_buff); + out.printf("RSSI: %d, G: %d\r\n", radio.RSSI, gain); + out.sleep(2.0); + } } } } \ No newline at end of file