Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed 4DGL-uLCD-SE mbed-rtos nRF24L01P
main.cpp
00001 #include "uLCD_4DGL.h" 00002 #include "mbed.h" 00003 #include "rtos.h" 00004 00005 #include "Microphone.h" 00006 #include "Speaker.h" 00007 #include "HUD.h" 00008 #include "nRF24L01P.h" 00009 00010 #include "CircularBuf.h" 00011 #include "CircularBuf.cpp" // Hack to get templates to work 00012 00013 // How many times larger the buffer should be 00014 #define FIFO_BUFFER_SCALE 250 00015 // How maybe bytes to send over RF 00016 #define DATA_PACKET_SIZE 32 00017 // How quickly to sample the mic / play the speaker 00018 #define SAMPLE_PERIOD 1/8000.0 00019 00020 00021 Serial pc(USBTX, USBRX); 00022 DigitalOut myled1(LED1); // Mic data sent over RF 00023 DigitalOut myled2(LED2); // Speaker data recieved over RF 00024 DigitalOut myled3(LED3); // Sampled mic / played the speaker 00025 DigitalOut myled4(LED4); // Heartbeat 00026 00027 Speaker spkr(p18); 00028 Microphone mic(p16); 00029 Mutex u; 00030 00031 uLCD_4DGL uLCD(p28, p27, p29); // serial tx, serial rx, reset pin; 00032 00033 nRF24L01P my_nrf24l01p(p5, p6, p7, p8, p9, p10); // mosi, miso, sck, csn, ce, irq 00034 CircularBuf<uint8_t> txbuff( FIFO_BUFFER_SCALE * DATA_PACKET_SIZE ); 00035 CircularBuf<uint8_t> rxbuff( FIFO_BUFFER_SCALE * DATA_PACKET_SIZE ); 00036 Ticker sampler; //10:41 am 4/20 00037 00038 InterruptIn button(p12); //changed DitialIn to InterruptIn at 5:54 4/18/18 00039 BusIn channel(p21, p22, p23, p24, p25); 00040 00041 int rfFreq; 00042 int dataRate; 00043 unsigned long long rxAddr, txAddr; 00044 int pipe = 0; 00045 int channelNum = -1; 00046 00047 enum operatingMode { 00048 RECEIVE = 0, 00049 TRANSMIT 00050 }; 00051 00052 operatingMode mode; 00053 00054 // Cheap nonbranching min function 00055 int min(int a, int b) 00056 { 00057 return a * (int)(a <= b) + b * (int)(b < a); 00058 } 00059 00060 // Sets the channel of the RF device based on which swtiches are flipped 00061 // by changing RX/TX pipes 00062 // TODO: Make sure we don't have to restart the device or anything to change this 00063 void setChannel() 00064 { 00065 int oldChannel = channelNum; 00066 //int oldPipe = pipe; 00067 //int width = 5; 00068 switch (channel) { 00069 case 0: // Channel 0 00070 //rxAddr = txAddr = 0xC2C2C2C2C0; 00071 //pipe = NRF24L01P_PIPE_P0; 00072 channelNum = 0; 00073 if (channelNum != oldChannel) { 00074 //my_nrf24l01p.setRxAddress(rxAddr, width, pipe); 00075 //my_nrf24l01p.setTxAddress(txAddr, width); 00076 rfFreq = channelNum + NRF24L01P_MIN_RF_FREQUENCY; 00077 my_nrf24l01p.setRfFrequency(rfFreq); 00078 u.lock(); 00079 uLCD.locate(0, 0); 00080 uLCD.printf("Freq: %d MHz", rfFreq); 00081 uLCD.locate(0, 2); 00082 uLCD.printf("Channel: %d ", channelNum); 00083 uLCD.locate(0, 10); 00084 u.unlock(); 00085 } 00086 break; 00087 case 1: // Channel 1 00088 //rxAddr = txAddr = 0xC2C2C2C2C1; 00089 //pipe = NRF24L01P_PIPE_P1; 00090 channelNum = 1; 00091 if (channelNum != oldChannel) { 00092 //my_nrf24l01p.setRxAddress(rxAddr, width, pipe); 00093 //my_nrf24l01p.setTxAddress(txAddr, width); 00094 rfFreq = channelNum + NRF24L01P_MIN_RF_FREQUENCY; 00095 my_nrf24l01p.setRfFrequency(rfFreq); 00096 uLCD.locate(0, 0); 00097 uLCD.printf("Freq: %d MHz", rfFreq); 00098 uLCD.locate(0, 2); 00099 uLCD.printf("Channel: %d ", channelNum); 00100 uLCD.locate(0, 10); 00101 u.unlock(); 00102 } 00103 break; 00104 case 2: // Channel 2 00105 //rxAddr = txAddr = 0xC2C2C2C2C2; 00106 //pipe = NRF24L01P_PIPE_P2; 00107 channelNum = 2; 00108 if (channelNum != oldChannel) { 00109 //my_nrf24l01p.setRxAddress(rxAddr, width, pipe); 00110 //my_nrf24l01p.setTxAddress(txAddr, width); 00111 rfFreq = channelNum + NRF24L01P_MIN_RF_FREQUENCY; 00112 my_nrf24l01p.setRfFrequency(rfFreq); 00113 u.lock(); 00114 uLCD.locate(0, 0); 00115 uLCD.printf("Freq: %d MHz", rfFreq); 00116 uLCD.locate(0, 2); 00117 uLCD.printf("Channel: %d ", channelNum); 00118 uLCD.locate(0, 10); 00119 u.unlock(); 00120 } 00121 break; 00122 case 4: // Channel 3 00123 //rxAddr = txAddr = 0xC2C2C2C2C3; 00124 //pipe = NRF24L01P_PIPE_P3; 00125 channelNum = 3; 00126 if (channelNum != oldChannel) { 00127 //my_nrf24l01p.setRxAddress(rxAddr, width, pipe); 00128 //my_nrf24l01p.setTxAddress(txAddr, width); 00129 rfFreq = channelNum + NRF24L01P_MIN_RF_FREQUENCY; 00130 my_nrf24l01p.setRfFrequency(rfFreq); 00131 u.lock(); 00132 uLCD.locate(0, 0); 00133 uLCD.printf("Freq: %d MHz", rfFreq); 00134 uLCD.locate(0, 2); 00135 uLCD.printf("Channel: %d ", channelNum); 00136 uLCD.locate(0, 10); 00137 u.unlock(); 00138 } 00139 break; 00140 case 8: // Channel 4 00141 //rxAddr = txAddr = 0xC2C2C2C2C4; 00142 //pipe = NRF24L01P_PIPE_P4; 00143 channelNum = 4; 00144 if (channelNum != oldChannel) { 00145 //my_nrf24l01p.setRxAddress(rxAddr, width, pipe); 00146 //my_nrf24l01p.setTxAddress(txAddr, width); 00147 rfFreq = channelNum + NRF24L01P_MIN_RF_FREQUENCY; 00148 my_nrf24l01p.setRfFrequency(rfFreq); 00149 u.lock(); 00150 uLCD.locate(0, 0); 00151 uLCD.printf("Freq: %d MHz", rfFreq); 00152 uLCD.locate(0, 2); 00153 uLCD.printf("Channel: %d ", channelNum); 00154 uLCD.locate(0, 10); 00155 u.unlock(); 00156 } 00157 break; 00158 case 16: // Channel 5 00159 //rxAddr = txAddr = 0xC2C2C2C2C5; 00160 //pipe = NRF24L01P_PIPE_P5; 00161 channelNum = 5; 00162 if (channelNum != oldChannel) { 00163 //my_nrf24l01p.setRxAddress(rxAddr, width, pipe); 00164 //my_nrf24l01p.setTxAddress(txAddr, width); 00165 rfFreq = channelNum + NRF24L01P_MIN_RF_FREQUENCY; 00166 my_nrf24l01p.setRfFrequency(rfFreq); 00167 u.lock(); 00168 uLCD.locate(0, 0); 00169 uLCD.printf("Freq: %d MHz", rfFreq); 00170 uLCD.locate(0, 2); 00171 uLCD.printf("Channel: %d ", channelNum); 00172 uLCD.locate(0, 10); 00173 u.unlock(); 00174 } 00175 break; 00176 default: 00177 break; 00178 } 00179 00180 //pc.printf("Pipe = %d\r\n", pipe); 00181 00182 // TODO: Don't force it to the default RF frequency 00183 //channelNum = 2; 00184 00185 //my_nrf24l01p.setRfFrequency(channelNum + NRF24L01P_MIN_RF_FREQUENCY); 00186 } 00187 00188 // Callback interrupt from the button to shift into transmit mode 00189 void enterTransmitMode() 00190 { 00191 mode = TRANSMIT; 00192 txbuff.clear(); 00193 // u.lock(); 00194 // uLCD.locate(0, 10); 00195 // uLCD.printf("Mode: Transmitting"); 00196 // u.unlock(); 00197 } 00198 00199 // Callback interrupt from the button to shift into receive mode 00200 void enterRecieveMode() 00201 { 00202 mode = RECEIVE; 00203 rxbuff.clear(); 00204 // u.lock(); 00205 // uLCD.locate(0, 10); 00206 // uLCD.printf("Mode: Receiving"); 00207 // u.unlock(); 00208 } 00209 00210 // Called every SAMPLE_PERIOD ms to sample the mic or output data into the speaker 00211 void sampleData() 00212 { 00213 // Depending on the mode, only sample the mic or output data to the speaker 00214 if (mode == RECEIVE) { 00215 // Get speaker sample from buffer 00216 // If there is no data in the buffer, it will just output 0 to the write function 00217 uint8_t speakerSample = 0; 00218 rxbuff.pop(&speakerSample, 1); 00219 00220 // Output into the actual speaker 00221 spkr.write (speakerSample); 00222 } else { 00223 // Get mic sample and place into buffer 00224 uint8_t micSample = mic.getData(); 00225 txbuff.push(&micSample, 1); 00226 00227 // Make sure the speaker is actually off 00228 spkr.turnOff(); 00229 } 00230 00231 // TODO: This will have to be removed later on once we actually crank up the sample rate 00232 myled3 = !myled3; 00233 } 00234 00235 // Communicates to the other MBED using RF 00236 void commThread() 00237 { 00238 // We want this in it's own thread so we don't have to worry about the 00239 // timings screwing anything else up 00240 // It can't be in an interrupt because of that 00241 while (true) { 00242 // Change what we are sending based on what mode we are in 00243 if (mode == RECEIVE) { 00244 // Make sure something is there to read 00245 if (my_nrf24l01p.readable( NRF24L01P_PIPE_P0 )) { 00246 uint8_t spkrPacket[DATA_PACKET_SIZE]; 00247 00248 // Remove entire packet of data from the bus 00249 int numReceived = my_nrf24l01p.read( NRF24L01P_PIPE_P0, (char*) spkrPacket, DATA_PACKET_SIZE ); 00250 00251 // Place into buffer to play speaker in another thread 00252 // Only place into the buffer the number of bytes received 00253 rxbuff.push(spkrPacket, min(DATA_PACKET_SIZE, numReceived)); 00254 00255 //pc.printf("Receiviing....\n\r"); 00256 myled2 = !myled2; 00257 } 00258 } else { // mode == TRANSMIT 00259 if (txbuff.size() >= DATA_PACKET_SIZE) { 00260 uint8_t micPacket[DATA_PACKET_SIZE]; 00261 00262 // Pull an entire packet of data from the mic sample buffer 00263 int numPopped = txbuff.pop(micPacket, DATA_PACKET_SIZE); 00264 // rxbuff.push(micPacket, DATA_PACKET_SIZE); 00265 00266 // Send the entire buffer to the other device 00267 // TODO: We just assume that DATA_PACKET_SIZE bytes were popped, this may 00268 // not be the case 00269 my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char*) micPacket, DATA_PACKET_SIZE ); 00270 00271 myled1 = !myled1; 00272 } 00273 } 00274 00275 //pc.printf("TX Size %d RX Size%d Mode %d\n\r", txbuff.size(), rxbuff.size(), mode); 00276 Thread::yield(); 00277 //Thread::wait(10); 00278 } 00279 } 00280 00281 // Displays the current info to the LCD display 00282 /*void lcdThread() 00283 { 00284 while (1) { 00285 uLCD.locate(0, 0); 00286 uLCD.printf("Freq: %d MHz", rfFreq); 00287 uLCD.locate(0, 2); 00288 uLCD.printf("Rate: %d kbps", dataRate); 00289 uLCD.locate(0, 4); 00290 uLCD.printf("Addr: 0x%010llX", txAddr); 00291 uLCD.locate(0, 6); 00292 //uLCD.printf("RX: 0x%010llX", rxAddr); 00293 uLCD.printf("Channel: %d", channelNum); 00294 uLCD.locate(0, 10); 00295 00296 switch (mode) { 00297 case RECEIVE: 00298 uLCD.printf("Mode: Receiving"); 00299 break; 00300 case TRANSMIT: 00301 uLCD.line(0, 8, 127, 8, BLACK); 00302 uLCD.printf("Mode: Transmitting"); 00303 break; 00304 } 00305 00306 // Maybe add some graphics too idk 00307 Thread::wait(1000); 00308 } 00309 }*/ 00310 00311 int main() 00312 { 00313 //Thread lcd; 00314 Thread comm; 00315 00316 // Set up the nrf24l01p 00317 my_nrf24l01p.setAirDataRate(2000); // 2Mbs 00318 rfFreq = my_nrf24l01p.getRfFrequency(); 00319 dataRate = my_nrf24l01p.getAirDataRate(); 00320 rxAddr = my_nrf24l01p.getRxAddress(); 00321 txAddr = my_nrf24l01p.getTxAddress(); 00322 00323 my_nrf24l01p.setTransferSize(DATA_PACKET_SIZE); 00324 00325 my_nrf24l01p.setReceiveMode(); 00326 my_nrf24l01p.enable(); 00327 00328 pc.printf( "nRF24L01+ Frequency : %d MHz\r\n", rfFreq ); 00329 pc.printf( "nRF24L01+ Output power : %d dBm\r\n", my_nrf24l01p.getRfOutputPower() ); 00330 pc.printf( "nRF24L01+ Data Rate : %d kbps\r\n", my_nrf24l01p.getAirDataRate() ); 00331 pc.printf( "nRF24L01+ TX Address : 0x%010llX\r\n", txAddr ); 00332 pc.printf( "nRF24L01+ RX Address : 0x%010llX\r\n", rxAddr ); 00333 00334 pc.printf("Finished starting up....\n\r"); 00335 00336 mode = RECEIVE; 00337 00338 // Initialize the uLCD 00339 uLCD.baudrate(3000000); 00340 uLCD.background_color(BLACK); 00341 00342 // Spawn threads 00343 //lcd.start(lcdThread); 00344 comm.start(commThread); 00345 00346 // Setup the button to enter transmit mode when pushed down 00347 // and recieve when release 00348 button.mode(PullUp); 00349 button.fall(&enterTransmitMode); 00350 button.rise(&enterRecieveMode); 00351 00352 // Setup sampler to sample at a specific frequency 00353 sampler.attach(&sampleData, SAMPLE_PERIOD); 00354 00355 // Heartbeat thread 00356 u.lock(); 00357 uLCD.locate(0, 0); 00358 uLCD.printf("Freq: %d MHz", rfFreq); 00359 uLCD.locate(0, 2); 00360 uLCD.printf("Channel: %d", channelNum); 00361 uLCD.locate(0, 4); 00362 uLCD.printf("Addr: 0x%010llX", txAddr); 00363 uLCD.locate(0, 6); 00364 uLCD.printf("RX: 0x%010llX", rxAddr); 00365 uLCD.locate(0, 10); 00366 uLCD.printf("Mode: Receiving"); 00367 u.unlock(); 00368 int oldmode = -1; 00369 00370 while (1) { 00371 myled4 = !myled4; 00372 setChannel(); // Poll the DIP switch and change channels accordingly 00373 if (mode == 0 && not(oldmode == mode)) { 00374 uLCD.locate(6, 10); 00375 uLCD.printf("Rx"); 00376 oldmode = mode; 00377 } else if (mode == 1 && not(oldmode == mode)) { 00378 uLCD.locate(6, 10); 00379 uLCD.printf("Tx"); 00380 oldmode = mode; 00381 } 00382 Thread::wait(100); 00383 } 00384 }
Generated on Tue Jul 12 2022 11:14:19 by
1.7.2