ECE 4180 - Final Project Team / Mbed 2 deprecated WalkieTalkie

Dependencies:   mbed 4DGL-uLCD-SE mbed-rtos nRF24L01P

Committer:
Nurchu
Date:
Mon Apr 23 15:03:21 2018 +0000
Revision:
29:0c6f3c0c992a
Parent:
27:08d34e60b6d0
Child:
30:1c309c020125
Debugging CircularBuf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Nurchu 0:c35b54fb9c3c 1 #include "mbed.h"
Nurchu 7:0ac1f1ca8aa6 2 #include "rtos.h"
Nurchu 20:e068469ffb89 3
Nurchu 2:dc046ff72566 4 #include "Microphone.h"
Nurchu 20:e068469ffb89 5 #include "Speaker.h"
drechtmann3 18:e2a8ea6f55d3 6 #include "HUD.h"
Nurchu 20:e068469ffb89 7 #include "nRF24L01P.h"
jacksacane 21:95009b231c1f 8 #include "uLCD_4DGL.h"
Nurchu 20:e068469ffb89 9
Nurchu 20:e068469ffb89 10 #include "CircularBuf.h"
Nurchu 20:e068469ffb89 11 #include "CircularBuf.cpp" // Hack to get templates to work
Nurchu 20:e068469ffb89 12
Nurchu 27:08d34e60b6d0 13 // How many times larger the buffer should be
Nurchu 27:08d34e60b6d0 14 #define FIFO_BUFFER_SCALE 4
Nurchu 27:08d34e60b6d0 15 // How maybe bytes to send over RF
Nurchu 27:08d34e60b6d0 16 #define DATA_PACKET_SIZE 32
Nurchu 27:08d34e60b6d0 17 // How quickly to sample the mic / play the speaker
Nurchu 27:08d34e60b6d0 18 #define SAMPLE_PERIOD 0.1
Nurchu 20:e068469ffb89 19
Nurchu 20:e068469ffb89 20
Nurchu 27:08d34e60b6d0 21 Serial pc(USBTX, USBRX);
Nurchu 27:08d34e60b6d0 22 DigitalOut myled1(LED1); // Mic data sent over RF
Nurchu 27:08d34e60b6d0 23 DigitalOut myled2(LED2); // Speaker data recieved over RF
Nurchu 27:08d34e60b6d0 24 DigitalOut myled3(LED3); // Sampled mic / played the speaker
Nurchu 27:08d34e60b6d0 25 DigitalOut myled4(LED4); // Heartbeat
Nurchu 20:e068469ffb89 26
Nurchu 20:e068469ffb89 27 Speaker spkr(p18);
Nurchu 27:08d34e60b6d0 28 Microphone mic(p16);
Nurchu 27:08d34e60b6d0 29
Nurchu 29:0c6f3c0c992a 30 //uLCD_4DGL uLCD(p27, p28, p30); // serial tx, serial rx, reset pin;
Nurchu 20:e068469ffb89 31
Nurchu 20:e068469ffb89 32 nRF24L01P my_nrf24l01p(p5, p6, p7, p8, p9, p10); // mosi, miso, sck, csn, ce, irq
Nurchu 27:08d34e60b6d0 33 CircularBuf<uint8_t> txbuff( FIFO_BUFFER_SCALE * DATA_PACKET_SIZE );
Nurchu 27:08d34e60b6d0 34 CircularBuf<uint8_t> rxbuff( FIFO_BUFFER_SCALE * DATA_PACKET_SIZE );
Nurchu 27:08d34e60b6d0 35 Ticker sampler; //10:41 am 4/20
Nurchu 20:e068469ffb89 36
Nurchu 29:0c6f3c0c992a 37 InterruptIn button(p12); //changed DitialIn to InterruptIn at 5:54 4/18/18
Nurchu 27:08d34e60b6d0 38 BusIn channel(p21, p22, p23, p24); // TODO: CHANGE THESE TO THE ACTUAL PINS NEEDED
Nurchu 20:e068469ffb89 39
jacksacane 21:95009b231c1f 40 int rfFreq;
jacksacane 21:95009b231c1f 41 int dataRate;
jacksacane 21:95009b231c1f 42 unsigned long long rxAddr, txAddr;
jacksacane 21:95009b231c1f 43
jacksacane 21:95009b231c1f 44 enum operatingMode {
jacksacane 21:95009b231c1f 45 RECEIVE = 0,
jacksacane 21:95009b231c1f 46 TRANSMIT
jacksacane 21:95009b231c1f 47 };
jacksacane 21:95009b231c1f 48
jacksacane 21:95009b231c1f 49 operatingMode mode;
jacksacane 21:95009b231c1f 50
Nurchu 27:08d34e60b6d0 51 // Cheap nonbranching min function
Nurchu 27:08d34e60b6d0 52 int min(int a, int b) {
Nurchu 27:08d34e60b6d0 53 return a * (int)(a <= b) + b * (int)(b < a);
Nurchu 27:08d34e60b6d0 54 }
drechtmann3 1:fc0a2c17e086 55
Nurchu 27:08d34e60b6d0 56 // Sets the frequency of the RF device based on which swtiches are flipped
Nurchu 27:08d34e60b6d0 57 // TODO: Make sure we don't have to restart the device or anything to change this
Nurchu 27:08d34e60b6d0 58 void setRFFrequency() {
Nurchu 29:0c6f3c0c992a 59 int channelNum = 0;//channel.read();
Nurchu 27:08d34e60b6d0 60
Nurchu 27:08d34e60b6d0 61 // TODO: Don't force it to the default RF frequency
Nurchu 27:08d34e60b6d0 62 channelNum = 2;
Nurchu 27:08d34e60b6d0 63
Nurchu 27:08d34e60b6d0 64 my_nrf24l01p.setRfFrequency(channelNum + NRF24L01P_MIN_RF_FREQUENCY);
Nurchu 27:08d34e60b6d0 65 }
drechtmann3 1:fc0a2c17e086 66
Nurchu 27:08d34e60b6d0 67 // Callback interrupt from the button to shift into transmit mode
Nurchu 27:08d34e60b6d0 68 void enterTransmitMode() {
Nurchu 27:08d34e60b6d0 69 mode = TRANSMIT;
Nurchu 27:08d34e60b6d0 70 }
drechtmann3 1:fc0a2c17e086 71
Nurchu 27:08d34e60b6d0 72 // Callback interrupt from the button to shift into receive mode
Nurchu 27:08d34e60b6d0 73 void enterRecieveMode() {
Nurchu 27:08d34e60b6d0 74 mode = RECEIVE;
drechtmann3 10:a8fcfc869fa5 75 }
drechtmann3 1:fc0a2c17e086 76
Nurchu 27:08d34e60b6d0 77 // Called every SAMPLE_PERIOD ms to sample the mic or output data into the speaker
Nurchu 27:08d34e60b6d0 78 void sampleData()
Nurchu 12:efcfe4c0d9f2 79 {
Nurchu 27:08d34e60b6d0 80 // Depending on the mode, only sample the mic or output data to the speaker
Nurchu 27:08d34e60b6d0 81 if (mode == RECEIVE) {
Nurchu 27:08d34e60b6d0 82 // Get speaker sample from buffer
Nurchu 27:08d34e60b6d0 83 // If there is no data in the buffer, it will just output 0 to the write function
Nurchu 27:08d34e60b6d0 84 uint8_t speakerSample = 0;
Nurchu 27:08d34e60b6d0 85 rxbuff.pop(&speakerSample, 1);
Nurchu 27:08d34e60b6d0 86
Nurchu 27:08d34e60b6d0 87 // Output into the actual speaker
Nurchu 27:08d34e60b6d0 88 spkr.write(speakerSample);
Nurchu 27:08d34e60b6d0 89 } else {
Nurchu 27:08d34e60b6d0 90 // Get mic sample and place into buffer
Nurchu 27:08d34e60b6d0 91 uint8_t micSample = mic.getData();
Nurchu 27:08d34e60b6d0 92 txbuff.push(&micSample, 1);
Nurchu 12:efcfe4c0d9f2 93
Nurchu 27:08d34e60b6d0 94 // Make sure the speaker is actually off
Nurchu 27:08d34e60b6d0 95 spkr.turnOff();
Nurchu 27:08d34e60b6d0 96 }
Nurchu 27:08d34e60b6d0 97
Nurchu 27:08d34e60b6d0 98 // TODO: This will have to be removed later on once we actually crank up the sample rate
Nurchu 27:08d34e60b6d0 99 myled3 = !myled3;
Nurchu 27:08d34e60b6d0 100 }
drechtmann3 1:fc0a2c17e086 101
Nurchu 27:08d34e60b6d0 102 // Communicates to the other MBED using RF
Nurchu 27:08d34e60b6d0 103 void commThread()
Nurchu 27:08d34e60b6d0 104 {
Nurchu 29:0c6f3c0c992a 105 pc.printf("Enter commThread\n\r");
Nurchu 27:08d34e60b6d0 106 // We want this in it's own thread so we don't have to worry about the
Nurchu 27:08d34e60b6d0 107 // timings screwing anything else up
Nurchu 27:08d34e60b6d0 108 // It can't be in an interrupt because of that
Nurchu 27:08d34e60b6d0 109 while (true) {
Nurchu 27:08d34e60b6d0 110 // Change what we are sending based on what mode we are in
Nurchu 27:08d34e60b6d0 111 if (mode == RECEIVE) {
Nurchu 27:08d34e60b6d0 112 // Make sure something is there to read
Nurchu 27:08d34e60b6d0 113 if (my_nrf24l01p.readable( NRF24L01P_PIPE_P0 )) {
Nurchu 27:08d34e60b6d0 114 uint8_t spkrPacket[DATA_PACKET_SIZE];
Nurchu 27:08d34e60b6d0 115
Nurchu 27:08d34e60b6d0 116 // Remove entire packet of data from the bus
Nurchu 27:08d34e60b6d0 117 int numReceived = my_nrf24l01p.read( NRF24L01P_PIPE_P0, (char*) spkrPacket, DATA_PACKET_SIZE );
Nurchu 27:08d34e60b6d0 118
Nurchu 27:08d34e60b6d0 119 // Place into buffer to play speaker in another thread
Nurchu 27:08d34e60b6d0 120 // Only place into the buffer the number of bytes received
Nurchu 27:08d34e60b6d0 121 rxbuff.push(spkrPacket, min(DATA_PACKET_SIZE, numReceived));
Nurchu 27:08d34e60b6d0 122
Nurchu 27:08d34e60b6d0 123 pc.printf("Receiviing....\n\r");
Nurchu 27:08d34e60b6d0 124 myled2 = !myled2;
Nurchu 27:08d34e60b6d0 125 }
Nurchu 27:08d34e60b6d0 126 } else { // mode == TRANSMIT
Nurchu 27:08d34e60b6d0 127 if (txbuff.size() >= DATA_PACKET_SIZE) {
Nurchu 27:08d34e60b6d0 128 uint8_t micPacket[DATA_PACKET_SIZE];
Nurchu 27:08d34e60b6d0 129
Nurchu 27:08d34e60b6d0 130 // Pull an entire packet of data from the mic sample buffer
Nurchu 27:08d34e60b6d0 131 int numPopped = txbuff.pop(micPacket, DATA_PACKET_SIZE);
Nurchu 27:08d34e60b6d0 132
Nurchu 27:08d34e60b6d0 133 // Send the entire buffer to the other device
Nurchu 27:08d34e60b6d0 134 // TODO: We just assume that DATA_PACKET_SIZE bytes were popped, this may
Nurchu 27:08d34e60b6d0 135 // not be the case
Nurchu 27:08d34e60b6d0 136 my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char*) micPacket, DATA_PACKET_SIZE );
Nurchu 27:08d34e60b6d0 137
Nurchu 27:08d34e60b6d0 138 pc.printf("Transmitting....\n\r");
Nurchu 27:08d34e60b6d0 139 myled1 = !myled1;
Nurchu 27:08d34e60b6d0 140 }
drechtmann3 1:fc0a2c17e086 141 }
Nurchu 27:08d34e60b6d0 142
Nurchu 27:08d34e60b6d0 143 Thread::yield();
Nurchu 12:efcfe4c0d9f2 144 }
Nurchu 12:efcfe4c0d9f2 145 }
drechtmann3 1:fc0a2c17e086 146
Nurchu 27:08d34e60b6d0 147 // Displays the current info to the LCD display
jacksacane 21:95009b231c1f 148 void lcdThread()
jacksacane 21:95009b231c1f 149 {
Nurchu 29:0c6f3c0c992a 150 pc.printf("Enter lcdThread\n\r");
jacksacane 21:95009b231c1f 151 while (1) {
Nurchu 29:0c6f3c0c992a 152 /*
jacksacane 21:95009b231c1f 153 uLCD.locate(64, 20);
jacksacane 21:95009b231c1f 154 uLCD.printf("Frequency: %d MHz", rfFreq);
jacksacane 21:95009b231c1f 155 uLCD.locate(64, 40);
jacksacane 21:95009b231c1f 156 uLCD.printf("Data Rate: %d kbps", dataRate);
jacksacane 21:95009b231c1f 157 uLCD.locate(64, 60);
jacksacane 21:95009b231c1f 158 uLCD.printf("TX Address: 0x%010llX", txAddr);
jacksacane 21:95009b231c1f 159 uLCD.locate(64, 80);
jacksacane 21:95009b231c1f 160 uLCD.printf("RX Address: 0x%010llX", rxAddr);
jacksacane 21:95009b231c1f 161 uLCD.locate(64, 100);
Nurchu 27:08d34e60b6d0 162
jacksacane 21:95009b231c1f 163 switch (mode) {
jacksacane 21:95009b231c1f 164 case RECEIVE:
jacksacane 21:95009b231c1f 165 uLCD.printf("Mode: Receiving");
jacksacane 21:95009b231c1f 166 break;
jacksacane 21:95009b231c1f 167 case TRANSMIT:
jacksacane 21:95009b231c1f 168 uLCD.printf("Mode: Transmitting");
jacksacane 21:95009b231c1f 169 break;
jacksacane 21:95009b231c1f 170 }
Nurchu 29:0c6f3c0c992a 171 */
jacksacane 21:95009b231c1f 172 // Maybe add some graphics too idk
Nurchu 27:08d34e60b6d0 173 Thread::wait(50);
jacksacane 21:95009b231c1f 174 }
jacksacane 21:95009b231c1f 175 }
jacksacane 21:95009b231c1f 176
Nurchu 12:efcfe4c0d9f2 177 int main()
Nurchu 12:efcfe4c0d9f2 178 {
Nurchu 27:08d34e60b6d0 179 Thread lcd;
Nurchu 27:08d34e60b6d0 180 Thread comm;
jacksacane 21:95009b231c1f 181
Nurchu 27:08d34e60b6d0 182 // Set up the nrf24l01p
jacksacane 21:95009b231c1f 183 rfFreq = my_nrf24l01p.getRfFrequency();
jacksacane 21:95009b231c1f 184 dataRate = my_nrf24l01p.getAirDataRate();
jacksacane 21:95009b231c1f 185 rxAddr = my_nrf24l01p.getRxAddress();
jacksacane 21:95009b231c1f 186 txAddr = my_nrf24l01p.getTxAddress();
jacksacane 21:95009b231c1f 187
Nurchu 27:08d34e60b6d0 188 my_nrf24l01p.setTransferSize(DATA_PACKET_SIZE);
jacksacane 21:95009b231c1f 189
jacksacane 21:95009b231c1f 190 my_nrf24l01p.setReceiveMode();
jacksacane 21:95009b231c1f 191 my_nrf24l01p.enable();
jacksacane 21:95009b231c1f 192
Nurchu 27:08d34e60b6d0 193 pc.printf("Finished starting up....\n\r");
Nurchu 27:08d34e60b6d0 194
jacksacane 22:e835b3490280 195 mode = RECEIVE;
jacksacane 22:e835b3490280 196
Nurchu 29:0c6f3c0c992a 197 CircularBuf<int> temp(20);
Nurchu 29:0c6f3c0c992a 198 int t[1];
Nurchu 29:0c6f3c0c992a 199 for (int i = 0; i < 5; i++) {
Nurchu 29:0c6f3c0c992a 200 t[0] = i;
Nurchu 29:0c6f3c0c992a 201 pc.printf("%d.", temp.push(&t[0], 1));
Nurchu 29:0c6f3c0c992a 202 }
Nurchu 29:0c6f3c0c992a 203 pc.printf("\n\rBuff size %d\n\r", temp.size());
Nurchu 29:0c6f3c0c992a 204
Nurchu 29:0c6f3c0c992a 205 for (int i = 0; i < 20; i++) {
Nurchu 29:0c6f3c0c992a 206 pc.printf("%d ", temp._data[i]);
Nurchu 29:0c6f3c0c992a 207 }
Nurchu 29:0c6f3c0c992a 208 pc.printf("\n\r%d %d\n\r", temp._head, temp._tail);
Nurchu 29:0c6f3c0c992a 209
Nurchu 29:0c6f3c0c992a 210 for (int i = 0; i < 5; i++) {
Nurchu 29:0c6f3c0c992a 211 t[0] = 0;
Nurchu 29:0c6f3c0c992a 212 pc.printf("%d.", temp.pop(&t[0], 1));
Nurchu 29:0c6f3c0c992a 213 pc.printf("%d ", t);
Nurchu 29:0c6f3c0c992a 214 pc.printf("\n\r%d %d\n\r", temp._head, temp._tail);
Nurchu 29:0c6f3c0c992a 215 }
Nurchu 29:0c6f3c0c992a 216 pc.printf("\n\rBuff size %d\n\r", temp.size());
Nurchu 29:0c6f3c0c992a 217 pc.printf("\n\r%d %d\n\r", temp._head, temp._tail);
Nurchu 29:0c6f3c0c992a 218
jacksacane 21:95009b231c1f 219 // Initialize the uLCD
Nurchu 29:0c6f3c0c992a 220 //uLCD.baudrate(3000000);
Nurchu 29:0c6f3c0c992a 221 //uLCD.background_color(BLACK);
jacksacane 21:95009b231c1f 222
jacksacane 21:95009b231c1f 223 // Spawn threads
jacksacane 21:95009b231c1f 224 lcd.start(lcdThread);
Nurchu 27:08d34e60b6d0 225 comm.start(commThread);
jacksacane 21:95009b231c1f 226
Nurchu 27:08d34e60b6d0 227 // Setup the button to enter transmit mode when pushed down
Nurchu 27:08d34e60b6d0 228 // and recieve when release
Nurchu 29:0c6f3c0c992a 229 button.mode(PullUp);
Nurchu 29:0c6f3c0c992a 230 //button.fall(&enterTransmitMode);
Nurchu 29:0c6f3c0c992a 231 //button.rise(&enterRecieveMode);
Nurchu 27:08d34e60b6d0 232
Nurchu 27:08d34e60b6d0 233 // Setup sampler to sample at a specific frequency
Nurchu 29:0c6f3c0c992a 234 //sampler.attach(&sampleData, SAMPLE_PERIOD);
Nurchu 27:08d34e60b6d0 235
Nurchu 29:0c6f3c0c992a 236 pc.printf("Enter Heartbeat\n\r");
Nurchu 27:08d34e60b6d0 237 // Heartbeat thread
drechtmann3 1:fc0a2c17e086 238 while (1) {
Nurchu 27:08d34e60b6d0 239 myled4 = !myled4;
Nurchu 27:08d34e60b6d0 240 Thread::wait(100);
Nurchu 12:efcfe4c0d9f2 241 }
Nurchu 12:efcfe4c0d9f2 242 }