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
Diff: main.cpp
- Revision:
- 27:08d34e60b6d0
- Parent:
- 26:57731422b129
- Child:
- 28:9413eb50156d
- Child:
- 29:0c6f3c0c992a
--- a/main.cpp Sat Apr 21 17:55:46 2018 +0000 +++ b/main.cpp Sun Apr 22 00:48:48 2018 +0000 @@ -10,31 +10,32 @@ #include "CircularBuf.h" #include "CircularBuf.cpp" // Hack to get templates to work -#define TRANSFER_SIZE 4 //added 5:54pm 4/18/18 +// How many times larger the buffer should be +#define FIFO_BUFFER_SCALE 4 +// How maybe bytes to send over RF +#define DATA_PACKET_SIZE 32 +// How quickly to sample the mic / play the speaker +#define SAMPLE_PERIOD 0.1 -Serial pc(USBTX, USBRX); // tx, rx -DigitalOut myled1(LED1); -DigitalOut myled2(LED2); -DigitalOut myled3(LED3); +Serial pc(USBTX, USBRX); +DigitalOut myled1(LED1); // Mic data sent over RF +DigitalOut myled2(LED2); // Speaker data recieved over RF +DigitalOut myled3(LED3); // Sampled mic / played the speaker +DigitalOut myled4(LED4); // Heartbeat Speaker spkr(p18); -Microphone mymicrophone(p16); +Microphone mic(p16); + +uLCD_4DGL uLCD(p27, p28, p30); // serial tx, serial rx, reset pin; nRF24L01P my_nrf24l01p(p5, p6, p7, p8, p9, p10); // mosi, miso, sck, csn, ce, irq -uLCD_4DGL uLCD(p27,p28,p30); // serial tx, serial rx, reset pin; -CircularBuf<uint8_t> txbuff(30); -CircularBuf<uint8_t> rxbuff(30); -Ticker t; //10:41 am 4/20 +CircularBuf<uint8_t> txbuff( FIFO_BUFFER_SCALE * DATA_PACKET_SIZE ); +CircularBuf<uint8_t> rxbuff( FIFO_BUFFER_SCALE * DATA_PACKET_SIZE ); +Ticker sampler; //10:41 am 4/20 -InterruptIn Button(p18); //changed DitialIn to InterruptIn at 5:54 4/18/18 -Thread lcd; - -char txData[TRANSFER_SIZE], rxData[TRANSFER_SIZE]; //making these usable by other voids. -int txDataCnt = 0;//and this. -int rxDataCnt = 0;//and this. //David Rechtmann 6.24 pm 4/18/18 -uint8_t micvalue[30]; -int micvalcount = 0; +InterruptIn button(p18); //changed DitialIn to InterruptIn at 5:54 4/18/18 +BusIn channel(p21, p22, p23, p24); // TODO: CHANGE THESE TO THE ACTUAL PINS NEEDED int rfFreq; int dataRate; @@ -47,124 +48,103 @@ operatingMode mode; - -void startup() -{ - -// The nRF24L01+ supports transfers from 1 to 32 bytes, but Sparkfun's -// "Nordic Serial Interface Board" (http://www.sparkfun.com/products/9019) -// only handles 4 byte transfers in the ATMega code. - -// char txData[TRANSFER_SIZE], rxData[TRANSFER_SIZE]; //making these usable by other voids. - // int txDataCnt = 0;//and this. - // int rxDataCnt = 0;//and this. //David Rechtmann 6:24 pm 4/18/18 - - my_nrf24l01p.powerUp(); +// Cheap nonbranching min function +int min(int a, int b) { + return a * (int)(a <= b) + b * (int)(b < a); +} - // Display the (default) setup of the nRF24L01+ chip - pc.printf( "nRF24L01+ Frequency : %d MHz\r\n", my_nrf24l01p.getRfFrequency() ); - pc.printf( "nRF24L01+ Output power : %d dBm\r\n", my_nrf24l01p.getRfOutputPower() ); - pc.printf( "nRF24L01+ Data Rate : %d kbps\r\n", my_nrf24l01p.getAirDataRate() ); - pc.printf( "nRF24L01+ TX Address : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() ); - pc.printf( "nRF24L01+ RX Address : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() ); +// Sets the frequency of the RF device based on which swtiches are flipped +// TODO: Make sure we don't have to restart the device or anything to change this +void setRFFrequency() { + int channelNum = channel.read(); + + // TODO: Don't force it to the default RF frequency + channelNum = 2; + + my_nrf24l01p.setRfFrequency(channelNum + NRF24L01P_MIN_RF_FREQUENCY); +} - pc.printf( "Type keys to test transfers:\r\n (transfers are grouped into %d characters)\r\n", TRANSFER_SIZE ); +// Callback interrupt from the button to shift into transmit mode +void enterTransmitMode() { + mode = TRANSMIT; +} - my_nrf24l01p.setTransferSize( TRANSFER_SIZE ); - - my_nrf24l01p.setReceiveMode(); - my_nrf24l01p.enable(); +// Callback interrupt from the button to shift into receive mode +void enterRecieveMode() { + mode = RECEIVE; } - -void pctransmit() +// Called every SAMPLE_PERIOD ms to sample the mic or output data into the speaker +void sampleData() { - // If we've received anything over the host serial link... - if ( pc.readable() ) { - - // ...add it to the transmit buffer - txData[txDataCnt++] = pc.getc(); + // Depending on the mode, only sample the mic or output data to the speaker + if (mode == RECEIVE) { + // Get speaker sample from buffer + // If there is no data in the buffer, it will just output 0 to the write function + uint8_t speakerSample = 0; + rxbuff.pop(&speakerSample, 1); + + // Output into the actual speaker + spkr.write(speakerSample); + } else { + // Get mic sample and place into buffer + uint8_t micSample = mic.getData(); + txbuff.push(&micSample, 1); - // If the transmit buffer is full - if ( txDataCnt >= sizeof( txData ) ) { - - // Send the transmitbuffer via the nRF24L01+ - my_nrf24l01p.write( NRF24L01P_PIPE_P0, txData, txDataCnt ); - - txDataCnt = 0; - } + // Make sure the speaker is actually off + spkr.turnOff(); + } + + // TODO: This will have to be removed later on once we actually crank up the sample rate + pc.printf("Sampling....\n\r"); + myled3 = !myled3; +} - // Toggle LED1 (to help debug Host -> nRF24L01+ communication) - myled3 = !myled3; - } - - // If we've received anything in the nRF24L01+... - if ( my_nrf24l01p.readable() ) { - - // ...read the data into the receive buffer - rxDataCnt = my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, sizeof( rxData ) ); - - // Display the receive buffer contents via the host serial link - for ( int i = 0; rxDataCnt > 0; rxDataCnt--, i++ ) { - - pc.putc( rxData[i] ); +// Communicates to the other MBED using RF +void commThread() +{ + // We want this in it's own thread so we don't have to worry about the + // timings screwing anything else up + // It can't be in an interrupt because of that + while (true) { + // Change what we are sending based on what mode we are in + if (mode == RECEIVE) { + // Make sure something is there to read + if (my_nrf24l01p.readable( NRF24L01P_PIPE_P0 )) { + uint8_t spkrPacket[DATA_PACKET_SIZE]; + + // Remove entire packet of data from the bus + int numReceived = my_nrf24l01p.read( NRF24L01P_PIPE_P0, (char*) spkrPacket, DATA_PACKET_SIZE ); + + // Place into buffer to play speaker in another thread + // Only place into the buffer the number of bytes received + rxbuff.push(spkrPacket, min(DATA_PACKET_SIZE, numReceived)); + + pc.printf("Receiviing....\n\r"); + myled2 = !myled2; + } + } else { // mode == TRANSMIT + if (txbuff.size() >= DATA_PACKET_SIZE) { + uint8_t micPacket[DATA_PACKET_SIZE]; + + // Pull an entire packet of data from the mic sample buffer + int numPopped = txbuff.pop(micPacket, DATA_PACKET_SIZE); + + // Send the entire buffer to the other device + // TODO: We just assume that DATA_PACKET_SIZE bytes were popped, this may + // not be the case + my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char*) micPacket, DATA_PACKET_SIZE ); + + pc.printf("Transmitting....\n\r"); + myled1 = !myled1; + } } - - // Toggle LED2 (to help debug nRF24L01+ -> Host communication) - myled3 = !myled3; + + Thread::yield(); } } -void receive() //most of this function added by david at 6:02pm 4/18/18 -{ - uint8_t spkrarray[30]; - uint8_t spkrtemp; - while (Button.read() == 0) { - mode = RECEIVE; - if (my_nrf24l01p.readable(0)) { - pc.printf("receiving...."); - my_nrf24l01p.read(0, (char*)spkrarray, 30); - rxbuff.push(spkrarray, 30); - // rxbuff.push(spkrarray, 30); - rxbuff.pop(&spkrtemp, 1); - spkr.write(spkrtemp); - myled2 = !myled2; - } - } -} - -void transmit() -{ - // while (mymycrophone.getData()) { - // txData[txDataCnt++] = mymicrophone.getData(); - // } - // txData[txDataCnt++] = ; - spkr.turnOff(); - - uint8_t txsendary[30]; - txbuff.pop(txsendary, 30); - while (Button.read()) { - // my_nrf24l01p.write(0, (char *)micvalue, 30); - pc.printf("transmitting...."); - my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char*) txsendary, 30); - myled1 = !myled1; - mode = TRANSMIT; - } -} - -void pollmic() -{ - uint8_t txentry = mymicrophone.getData(); - txbuff.push(&txentry, 1); - pc.printf("polling...."); - // micvalcount = micvalcount + 1; - // if (micvalcount > 30); - // { - // micvalcount = 0; - // } - -} - +// Displays the current info to the LCD display void lcdThread() { while (1) { @@ -177,6 +157,7 @@ uLCD.locate(64, 80); uLCD.printf("RX Address: 0x%010llX", rxAddr); uLCD.locate(64, 100); + switch (mode) { case RECEIVE: uLCD.printf("Mode: Receiving"); @@ -185,46 +166,52 @@ uLCD.printf("Mode: Transmitting"); break; } + // Maybe add some graphics too idk - Thread::yield(); + Thread::wait(50); } } int main() { - startup(); - pc.printf("starting up...."); - Button.mode(PullDown);//added 6:23pm 4/18/18 - Button.rise(&transmit); - Button.fall(&receive); - t.attach(&pollmic, 0.1); + Thread lcd; + Thread comm; + // Set up the nrf24l01p rfFreq = my_nrf24l01p.getRfFrequency(); dataRate = my_nrf24l01p.getAirDataRate(); rxAddr = my_nrf24l01p.getRxAddress(); txAddr = my_nrf24l01p.getTxAddress(); - my_nrf24l01p.setTransferSize(TRANSFER_SIZE); + my_nrf24l01p.setTransferSize(DATA_PACKET_SIZE); my_nrf24l01p.setReceiveMode(); my_nrf24l01p.enable(); + pc.printf("Finished starting up....\n\r"); + mode = RECEIVE; // Initialize the uLCD uLCD.baudrate(3000000); uLCD.background_color(BLACK); - // Register interrupts - Button.mode(PullUp);//added 6:23pm 4/18/18 - t.attach(&pollmic, 0.0001); - t.attach(&receive, 0.0001); - // Spawn threads lcd.start(lcdThread); + comm.start(commThread); - // Main thread + // Setup the button to enter transmit mode when pushed down + // and recieve when release + button.mode(PullDown); + button.fall(&enterTransmitMode); + button.rise(&enterRecieveMode); + + // Setup sampler to sample at a specific frequency + sampler.attach(&sampleData, SAMPLE_PERIOD); + + // Heartbeat thread while (1) { - Thread::yield(); + myled4 = !myled4; + Thread::wait(100); } } \ No newline at end of file