football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include <list>
00002 #include <DebounceIn.h>
00003 #include "configs.h"
00004 
00005 using namespace std;
00006 
00007 ///////////////////////////////////  PINS   ///////////////////////////////////
00008 
00009 DebounceIn buttonTeam(BUT_TEAM);
00010 DebounceIn buttonSpace(BUT_SPACE);
00011 DebounceIn buttonVolMore(BUT_VOL_MORE);
00012 DebounceIn buttonVolLess(BUT_VOL_LESS);
00013 
00014 DigitalOut ledTeamA(LED_TEAM_A);
00015 DigitalOut ledTeamB(LED_TEAM_B);
00016 DigitalOut ledSpace5(LED_SPACE5);
00017 DigitalOut ledSpace10(LED_SPACE10);
00018 DigitalOut ledSpace15(LED_SPACE15);
00019 DigitalOut ledSpace20(LED_SPACE20);
00020 DigitalOut ledBuzzer(LED_BUZZER_ON);
00021 
00022 AnalogIn ain(ANALOG_IN);    // used for randomizing  
00023 #ifdef NORDIC
00024 DigitalOut buzzer(BUZZER);
00025 #ifndef HARD_V2
00026 DigitalOut buzzLow(BUZZ_LOW);
00027 #endif
00028 DigitalOut buzzMed(BUZZ_MED);
00029 DigitalOut buzzHigh(BUZZ_HIGH);
00030 #else
00031 PwmOut speaker(BUZZER);     // passive buzzer
00032 #endif
00033 
00034 /////////////////////////////////// FUNCTIONS ///////////////////////////////////
00035 
00036 void beep(float period, float time, uint8_t vol) { 
00037 #ifdef ENABLE_SOUND
00038     if(!vol) return;
00039 #ifdef NORDIC
00040     if(vol>=3) {
00041 #ifndef HARD_V2
00042         buzzLow = LOW_ON; 
00043 #endif 
00044         buzzMed = MED_OFF; buzzHigh = HIGH_OFF;
00045     } else if(vol>=2) {
00046 #ifndef HARD_V2
00047         buzzLow = LOW_OFF; 
00048 #endif 
00049         buzzMed = MED_ON; buzzHigh = HIGH_OFF;
00050     } else {
00051 #ifndef HARD_V2
00052         buzzLow = LOW_OFF; 
00053 #endif 
00054         buzzMed = MED_OFF; buzzHigh = HIGH_ON;
00055     }
00056     buzzer = 0;     // P-MOSFET
00057     wait(time);
00058     buzzer = 1;
00059 #else
00060     speaker.period(period);
00061     if(vol>=3) 
00062         speaker = 0.5; //50% duty cycle - max volume
00063     else if(vol>=2) 
00064         speaker = 0.33;
00065     else
00066         speaker = 0.2;
00067     wait(time);
00068     speaker=0.0; // turn off audio
00069 #endif
00070 #endif
00071 }
00072 
00073 void binary_sound(int z) {
00074     // Beeps numbers according to their binary form
00075     // (used for debugging in display-less and serial-less environments)
00076 #ifdef ENABLE_SOUND
00077 #ifndef NORDIC
00078     speaker.period(0.004);
00079     while(z) {
00080         speaker = 0.5;
00081         if(z&1) wait(0.5);
00082         else wait(0.25);
00083         speaker = 0.0;
00084         wait(1.0);
00085         z >>= 1;
00086     }
00087     beep(NOTE_A4, 1.0, 2);
00088 #endif
00089 #endif
00090 }
00091 
00092 void generate_name(char rand_name[], uint8_t size) {
00093     // Generate random name on the 62 character alphabet
00094     memset(rand_name, 0x00, size);
00095     char alph[63] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
00096     uint32_t seed = ((ain.read_u16()+3)/17)*((ain.read_u16()+5)/13);
00097     srand(seed);
00098     for(int i=0;i<size-1;i++) {
00099         rand_name[i] = alph[abs(rand()) % 62];
00100     }
00101 }
00102 
00103 void spaceLEDs(int level) {
00104     if(level<=0) {
00105         ledSpace5 = 1; ledSpace10 = 0; ledSpace15 = 0; ledSpace20 = 0;
00106     } else if(level<=1) {
00107         ledSpace5 = 0; ledSpace10 = 1; ledSpace15 = 0; ledSpace20 = 0;
00108     } else if(level<=2) {
00109         ledSpace5 = 0; ledSpace10 = 0; ledSpace15 = 1; ledSpace20 = 0;
00110     } else {
00111         ledSpace5 = 0; ledSpace10 = 0; ledSpace15 = 0; ledSpace20 = 1;
00112     }
00113 }
00114 
00115 
00116 /////////////////////////////////// CLASSES ///////////////////////////////////
00117 
00118 struct Contact {
00119     int16_t rssi;
00120     uint32_t time_ms;
00121 };
00122 
00123 class Player {
00124   public:
00125     char name[NAME_LEN+1];
00126     int8_t team;
00127     Player(const char rand_name[]) {
00128         memset(name, 0x00, NAME_LEN+1);
00129         memcpy(name, rand_name, NAME_LEN);
00130     }
00131     void update(int8_t _team, int rssi, uint32_t time=NULL) {
00132         // Remember this contact
00133         team = _team;
00134         Contact c;
00135         c.rssi = rssi;
00136         c.time_ms = (time!=NULL) ? time : 0; //tmr.read_ms();
00137         contacts.push_front(c);
00138         
00139         // Cleanup
00140         while(contacts.size() > MAX_RECORDS) contacts.pop_back();
00141         while(!contacts.empty() && c.time_ms - contacts.back().time_ms > MAX_HISTORY_MS) contacts.pop_back();
00142     }
00143     int16_t get_distance(int &cnt) {
00144         // Find max RSSI
00145         uint32_t cur_time = 0; //tmr.read_ms();
00146         int16_t max_rssi=-128;
00147         cnt=0;
00148         for (list<Contact>::iterator it=contacts.begin(); it != contacts.end(); ++it) {
00149             if(cur_time - it->time_ms > SIGNALS_VALID_MS) break;
00150             if(it->rssi > max_rssi) max_rssi = it->rssi;
00151             cnt++;
00152         }
00153         return max_rssi;
00154     }
00155     inline bool operator==(const char rhs[]){ return memcmp(name, rhs, NAME_LEN)==0; }
00156     inline bool operator==(const Player& rhs){ return *this==rhs.name; }
00157     //inline bool operator!=(const char rhs[]){ return !(*this == rhs); }
00158   private:
00159     list<Contact> contacts;
00160 };
00161 
00162 class Players {
00163   public:
00164     list<Player> players;
00165     
00166     void update(const char name[], int8_t team, int16_t rssi, uint32_t time_ms=NULL) {
00167         list<Player>::iterator it;
00168         for (it=players.begin(); it != players.end(); ++it) {
00169             if(*it==name) break;
00170         }
00171         if(it!=players.end()) {
00172             it->update(team, rssi, time_ms);
00173         } else {
00174             Player p(name);
00175             p.update(team, rssi, time_ms);
00176             players.push_front(p);
00177         }
00178     }
00179     
00180     void showAll(int8_t team, uint8_t level, uint8_t volume) {
00181         // Output the current state to the user:
00182         //   - show the current information table and/or
00183         //   - beep if the user is too close to another one
00184         int i=0, nContacts, signal, maxTeamSignal = -128;
00185         list<Player>::iterator it;
00186         //out.clear();
00187         for (it=players.begin(); it != players.end(); ++it) {
00188             signal = it->get_distance(nContacts);
00189             if(signal>-128) {
00190                 /*
00191                 out.printf("%d ", ++i);
00192                 out.printf((team==it->team) ? "+" : "-");       // teammate or opponent?
00193                 out.printf("%s ", it->name);
00194                 out.printf("%d/%d", -signal, nContacts);
00195                 out.printf((-signal<SPACE[level]) ? "!" : " ");
00196                 out.printf("\r\n");
00197                 */
00198             }
00199             if(team==it->team && signal>maxTeamSignal) {
00200                 maxTeamSignal = signal;
00201             }
00202         } 
00203         //if(!i) {
00204         //    out.printf("Nobody around\r\n");
00205         //    beep(NOTE_A5,0.5,volume);
00206         //}
00207         if(-maxTeamSignal<SPACE[level]) {
00208             beep(NOTE_A4, 0.33, volume);
00209         }
00210     }
00211 };
00212 
00213 /////////////////////////////////// MAIN CODE ///////////////////////////////////
00214 
00215 int main()
00216 {    
00217     char tx_buff[100] = {0};
00218     char rx_buff[100] = {0};
00219     char rand_name[NAME_LEN+1] = {0};
00220     char other_name[NAME_LEN+1] = {0};
00221     int8_t myTeam = 1, otherTeam;
00222     uint8_t level = 1, volume = 1;      // SPACE10, VOL_LOW
00223     int bTeamNew, bTeamOld, bSpaceOld, bSpaceNew, bVMNew, bVLNew, bVMOld, bVLOld;
00224     
00225     // Blink all the LEDs at startup
00226     spaceLEDs(0); wait(0.2); spaceLEDs(1); wait(0.2); spaceLEDs(2); wait(0.2);  spaceLEDs(3); wait(0.2); ledSpace20 = 0;
00227 #ifdef TEST_LED_SOUND
00228     // Test LEDs and sound simultaneously to save time
00229     buzzMed = MED_OFF; buzzHigh = HIGH_OFF; 
00230     ledBuzzer = 1; buzzer=0; wait(0.2); buzzer=1; ledBuzzer = 0;
00231     buzzMed = MED_ON;
00232     ledTeamA = 1; buzzer=0; wait(0.2); buzzer=1; ledTeamA = 0;  
00233     buzzMed = MED_OFF; buzzHigh = HIGH_ON; 
00234     ledTeamB = 1; buzzer=0; wait(0.2); buzzer=1; ledTeamB = 0; 
00235     buzzHigh = HIGH_OFF;
00236 #else
00237     ledBuzzer = 1; wait(0.2); ledBuzzer = 0;
00238     ledTeamA = 1; wait(0.2); ledTeamA = 0;  
00239     ledTeamB = 1; wait(0.2); ledTeamB = 0; 
00240     
00241     // Beep all the levels on startup
00242     beep(NOTE_A5, 0.2, 1);
00243     beep(NOTE_A5, 0.2, 2);
00244     beep(NOTE_A5, 0.2, 3);
00245 #endif
00246     
00247     // ...and go to a informative LEDs
00248     spaceLEDs(level);
00249     ledBuzzer = volume ? 1 : 0;
00250     if(myTeam & 1) ledTeamA = 1;
00251     else ledTeamB = 1;
00252 
00253     // Buttons initialization
00254     buttonSpace.mode(PullDown);
00255     buttonVolMore.mode(PullDown);
00256     buttonVolLess.mode(PullDown);
00257 #ifdef NORDIC
00258     buttonTeam.mode(PullDown);
00259     bTeamOld = 0;
00260 #else
00261     buttonTeam.mode(PullUp);
00262     bTeamOld = 1;
00263 #endif
00264     bSpaceOld = 0;
00265     bVMOld = 0;
00266     bVLOld = 0;
00267         
00268     // Pick node number
00269     char this_node = int(ain.read()*255+17)*int(ain.read()*255+11); // random node value
00270     //out.printf("Node: %d\r\n", this_node);
00271 
00272     // Pick node name
00273     generate_name(rand_name, sizeof(rand_name));
00274     /*
00275     out.printf("Name: %s\r\n", rand_name);
00276     out.sleep(2.0);
00277     */
00278         
00279     //tmr.start();
00280     
00281     Players players;
00282     
00283     uint32_t last_send = 0; //tmr.read_ms();
00284     uint32_t last_shown = 0; // tmr.read_ms();
00285     //uint32_t min_wait = SEND_RATE_MS - 0.5*SEND_RATE_MS*SEND_DESYNC;
00286     //uint32_t send_wait = min_wait;
00287 
00288     while (true)
00289     {
00290         // Read team button
00291         bTeamNew = buttonTeam;
00292         if(bTeamNew==PRESSED && bTeamOld==RELEASED) {
00293             myTeam = (myTeam==1) ? 2 : 1;
00294             ledTeamA = myTeam & 1;
00295             ledTeamB = ~myTeam & 1;
00296             /*
00297             out.clear();
00298             out.printf("New team: %d\r\n", myTeam);
00299             out.sleep(2);
00300             */
00301         }
00302         bTeamOld = bTeamNew;
00303         
00304         // Read space button
00305         bSpaceNew = buttonSpace;
00306         if(bSpaceNew && !bSpaceOld) {
00307             level = (level+1) & 0b11;   // four states
00308             spaceLEDs(level);
00309             /*
00310             out.clear();
00311             out.printf("New level: %d\r\n", level);
00312             out.sleep(2);
00313             */
00314         }
00315         bSpaceOld = bSpaceNew;
00316 
00317         // Read volume buttons
00318         bVMNew = buttonVolMore.read();
00319         bVLNew = buttonVolLess.read();
00320         if(bVMNew && !bVMOld) {
00321             volume++;
00322             if(volume>3) volume=3;
00323             ledBuzzer = 1;
00324             /*
00325             out.clear();
00326             out.printf("New volume: %d\r\n", volume);
00327             out.sleep(2);
00328             */
00329         }
00330         if(bVLNew && !bVLOld) {
00331             if(volume>0) volume--;
00332             if(!volume) ledBuzzer = 0;
00333             /*
00334             out.clear();
00335             out.printf("New volume: %d\r\n", volume);
00336             out.sleep(2);
00337             */
00338         }
00339         bVMOld = bVMNew;
00340         bVLOld = bVLNew;
00341 
00342         // Output
00343         unsigned long current_time = 0; //tmr.read_ms();
00344         
00345         if (current_time - last_shown > CYCLE_MS)
00346         {
00347             players.showAll(myTeam, level, volume);
00348             last_shown = current_time;
00349         }
00350         
00351     }
00352 }