Andriy Makukha
/
football_project_wo_output
football_project_wo_output
Fork of football_project by
main.cpp
- Committer:
- andriym
- Date:
- 2016-05-09
- Revision:
- 78:43a6b54f0372
- Parent:
- 76:6638d83939d5
- Child:
- 79:9db29f41dc9d
File content as of revision 78:43a6b54f0372:
#include <RFM69.h> #include <list> #include "output.h" using namespace std; Timer t; Output out; /////////////////////////////////// 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 /////////////////////////////////// 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 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() { 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; beep(0.002, 0.5); din.mode(PullUp); int button_old = 1, button_new; 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); 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_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), "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); //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); 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); } } } }