record adc values and send them to another uprocessor
Dependencies: BufferedSerial SDFileSystem mbed
Fork of SDFileSystem_HelloWorld by
Diff: main.cpp
- Revision:
- 1:b00f060239fe
- Parent:
- 0:bdbd3d6fc5d5
- Child:
- 4:0e2980186bed
--- a/main.cpp Fri Dec 07 11:25:01 2012 +0000 +++ b/main.cpp Wed Jun 15 01:40:10 2016 +0000 @@ -1,19 +1,452 @@ #include "mbed.h" #include "SDFileSystem.h" - -SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board +#include <string> +#include <cstring> +//#include "rtos.h" This seems to cause compile errors and I haven't really structured +// the code to work with rtos ... + +/*======================================================================================== + NOTES + ======================================================================================== +main is at the end of this file + +6/14/2016 - Everything is working! 115200 baud with array sizes of 32 bytes seems to be + what is working reliably. + - Keeping array sizes at 32 seems easy to send and receive over serial. Trying + to figure out why serial receive hangs with more than 32 bytes of data + + +6/1/2016 - test to see if the recieve interrupt is handling the serial transfer and the + read_line() does not need to be called + - set up receive buffer to be stored into an array + ... this will depend on where serial data is being received + + +Board: STM Nucleo f303re +Serial communciation: + uart2 is connected to uart1 = + PC_10 to D2, PC_11 to D8 +SPI communication to SD card: + MOSI, MISO, SCK, CS +******************************************************************************************/ + + + +/*======================================================================================== + PROTOCOL SETUP/INSTANTIATE + ======================================================================================== + +******************************************************************************************/ +SDFileSystem sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, "sd"); // mosi,miso,sclk,cs,name +RawSerial pc(SERIAL_TX, SERIAL_RX); +RawSerial uart1(PC_12, PD_2); // tx, rx +RawSerial uart2(PC_10, PC_11); //tx, rx +AnalogIn squibCLT_ADC(A0); + + + +/*======================================================================================== + GLOBAL VARIABLES + ======================================================================================== + +******************************************************************************************/ + + + +//some global variables to pass data around +int arrayCount = 0; +float squibCLT_array[256]; +float squibCLT_array2[256]; +char squibCLT_array3[256]; +int sendCount, rxInterruptCount = 0; +int ADCReadCount = 32; + + +//serial interrupts transfer variables +const int buffer_size = 255; +char tx_buffer[buffer_size+1]; +char rx_buffer[buffer_size+1]; +volatile int tx_in = 0; +volatile int tx_out = 0; +volatile int rx_in = 0; +volatile int rx_out = 0; +volatile int receiveBuffer = 0; +char tx_line[80]; +char rx_line[80]; + + + + +/*======================================================================================== + FUNCTION DEFINITIONS + ======================================================================================== + +******************************************************************************************/ + + +/************************************************************************ +* clean all the buffers +************************************************************************/ +void cleanBuffers() +{ + memset(tx_buffer, 0, sizeof(tx_buffer)); + memset(rx_buffer, 0, sizeof(rx_buffer)); + tx_in = 0; + tx_out = 0; + rx_in = 0; + rx_out = 0; + receiveBuffer = 0; + memset(tx_line, 0, sizeof(tx_line)); + memset(rx_line, 0, sizeof(rx_line)); + arrayCount = 0; + memset(squibCLT_array, 0, sizeof(squibCLT_array)); + memset(squibCLT_array3, 0, sizeof(squibCLT_array3)); + rxInterruptCount = 0; +} + + +/************************************************************************ +* Copy tx line buffer to large tx buffer for tx interrupt routine * +************************************************************************/ +void send_line() +{ + int i = 0; + char temp_char; + bool empty; + + __disable_irq(); //NVIC_DisableIRQ(UART1_IRQn);// Start Critical Section - don't interrupt while changing global buffer variables + + empty = (tx_in == tx_out); + + while ((i==0) || (tx_line[i-1] != '\n')) + { + + if (((tx_in + 1) % buffer_size) == tx_out) // Wait if buffer full + { + __enable_irq(); //NVIC_EnableIRQ(UART1_IRQn);// End Critical Section - need to let interrupt routine empty buffer by sending + while (((tx_in + 1) % buffer_size) == tx_out) + { + } + + __disable_irq(); //NVIC_DisableIRQ(UART1_IRQn); // Start Critical Section - don't interrupt while changing global buffer variables + } + + tx_buffer[tx_in] = tx_line[i]; +// if (tx_buffer[tx_in] == '\r'){pc.printf("returnline");} + i++; + tx_in = (tx_in + 1) % buffer_size; + } + + if (uart1.writeable() && (empty)) + { + temp_char = tx_buffer[tx_out]; + tx_out = (tx_out + 1) % buffer_size; + + + uart1.putc(temp_char); // Send first character to start tx interrupts, if stopped + +// pc.printf("send command. Value: %c\r\n", temp_char); + } + + __enable_irq(); //NVIC_EnableIRQ(UART1_IRQn); // End Critical Section + return; +} -int main() { - printf("Hello World!\n"); + + +/************************************************************************ +* Read a line from the large rx buffer from rx interrupt routine * +************************************************************************/ +void read_line() +{ + int i = 0; + + __disable_irq(); //NVIC_DisableIRQ(UART1_IRQn); // Start Critical Section - don't interrupt while changing global buffer variables + while ((i==0) || (rx_line[i-1] != '\r')) // Loop reading rx buffer characters until end of line character + { + if (rx_in == rx_out) // Wait if buffer empty + { + __enable_irq(); //NVIC_EnableIRQ(UART1_IRQn); // End Critical Section - need to allow rx interrupt to get new characters for buffer + + while (rx_in == rx_out) + { + } + __disable_irq(); //NVIC_DisableIRQ(UART1_IRQn); // Start Critical Section - don't interrupt while changing global buffer variables + } + + rx_line[i] = rx_buffer[rx_out]; + + i++; + rx_out = (rx_out + 1) % buffer_size; + } + + __enable_irq(); //NVIC_EnableIRQ(UART1_IRQn); // End Critical Section + + strcat(squibCLT_array3,rx_line); + + rx_line[i-1] = 0; + + return; +} + + +/************************************************************************ +* Interupt Routine to read in data from serial port * +************************************************************************/ +void Rx_interrupt() +{ + + while ((uart2.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) // Loop just in case more than one character is in UART's receive FIFO buffer + // Stop if buffer full + { + rx_buffer[rx_in] = uart2.getc(); +// pc.putc(rx_buffer[rx_in]); // Uncomment to Echo to USB serial to watch data flow + rx_in = (rx_in + 1) % buffer_size; + + } + + rxInterruptCount++; + return; +} + + + +/************************************************************************ +* Interupt Routine to write out data to serial port * +************************************************************************/ +void Tx_interrupt() +{ + while ((uart1.writeable()) && (tx_in != tx_out)) // Loop to fill more than one character in UART's transmit FIFO buffer // Stop if buffer empty + { + + uart1.putc(tx_buffer[tx_out]); + tx_out = (tx_out + 1) % buffer_size; + } + + return; +} + + + +/************************************************************************ +* This function will display the array that is being used +* to hold the ADC data collected by the uController +************************************************************************/ +void printArray_debug(float* intArray) +{ + for (int i = 0; i < arrayCount; i++) + { + pc.printf("%.6f\r\n", intArray[i]); + } +} + + + +/************************************************************************ +* handles creating an sd card object, opening the .txt file +* then writes array c and closes file +************************************************************************/ +void writeToSdCard() +{ + pc.printf("Begin write SD Card routine\r\n"); mkdir("/sd/mydir", 0777); - + FILE *fp = fopen("/sd/mydir/sdtest.txt", "w"); - if(fp == NULL) { - error("Could not open file for write\n"); + + while(fp == NULL) + { + error("Could not open file for write\r\n"); + } + + pc.printf("Start writing..."); + + for (int i = 0; i < arrayCount; i++) + { + fprintf(fp, "%f\r\n", squibCLT_array[i]); + } + + fclose(fp); + pc.printf("Done\r\n"); +} + + + +/************************************************************************ +* handles opening the named .txt file and stores everything +* to the char array c and then closes the file. +* +* +************************************************************************/ +void readFromSdCard() +{ + pc.printf("Begin read SD Card routine\r\n"); + + FILE *fp = fopen("/sd/mydir/sdtest.txt", "r"); + + while(fp == NULL) + { + error("Could not open file for read\r\n"); + } + + pc.printf("Starting read..."); + + for (int i = 0; i < arrayCount; i++) + { + fscanf(fp, "%f", &squibCLT_array2[i]); + } + + fclose(fp); + + +#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler //possible sd card library bug. Not sure if this helps + free(fp); +#endif + + pc.printf("Done.\r\n"); + +} + + + +/************************************************************************ +* readADC will recieve an interrupt and store ADC data to an array +* +************************************************************************/ +void readADC() +{ + pc.printf("Start reading ADC..."); + for (int i = 0; i < ADCReadCount; i++) + { + squibCLT_array[i] = squibCLT_ADC.read(); + arrayCount++; + } + pc.printf("Done\r\n"); +} + + +/************************************************************************ +* copies sd card array to serial buffer and sends it over buffer +* +************************************************************************/ +void sendSdCardDataOverSerial() +{ + Timer timer; + int begin, end; + + pc.printf("Sending over serial..."); + + timer.start(); + begin = timer.read_us(); + + for (int i = 0; i < arrayCount; i++) + { + sprintf(tx_line, "%.6f\r\n]", squibCLT_array2[i]); + send_line(); } - fprintf(fp, "Hello fun SD Card World!"); - fclose(fp); - - printf("Goodbye World!\n"); + + end = timer.read_us(); + + pc.printf("Done.\r\n"); + + pc.printf("Transmit took %d microseconds to complete.\r\n", end - begin); +} + + + +/************************************************************************ +* handles receiving data and storing it back into local memory +* +************************************************************************/ +void receiveSdCardDataOverSerial() +{ + Timer timer; + int begin, end; + + pc.printf("Receiving over serial..."); + + timer.start(); + begin = timer.read_us(); + + for (int i = 0; i < arrayCount; i++) + { +// for some reason you have to use this function to read in everything being sent instead of relying on the interrupt service exclusively + read_line(); + //sprintf(squib_test, "%s", rx_line); + } + end = timer.read_us(); + + pc.printf("Done.\r\n"); + + pc.printf("Receive took %d microseconds to complete.\r\n", end - begin); +} + + + + +/**** +* float to char array +****/ +char floatToChar(float f) +{ + char charArray; + + return charArray; } + + +/*======================================================================================== + MAIN + ========================================================================================*/ + + +/************************************************************************ +* main handles: +* setting up serial ports, interrupts +* reading ADC data into char array c +* then store it to an SD card, +* then send it over serial +* +************************************************************************/ +int main() +{ + pc.baud(128000); +// 6/1/2016 sped up baud rate and need to compare with output to see if still the same +// 6/14/2016 any baud rate over 115200 hangs up the serial recieve interrupt :/ + uart1.baud(115200); + uart2.baud(115200); + uart1.attach(&Tx_interrupt, Serial::TxIrq); // Setup a serial interrupt function to transmit data + uart2.attach(&Rx_interrupt, Serial::RxIrq); // Setup a serial interrupt function to receive data + + + for (int j = 0; j < 10; j++) + { + pc.printf("\r\nStarting SD card and serial test.\r\n\r\n"); + + readADC(); + + writeToSdCard(); + readFromSdCard(); + + sendSdCardDataOverSerial(); + receiveSdCardDataOverSerial(); // Rx interrupt interferes with this since it reads from 2 places + + + //debug code + for(int i = 0; i < arrayCount; i++) + { + pc.printf(" %f - %f \r\n", squibCLT_array[i], squibCLT_array2[i]); //, squib_test); + } + + pc.printf("%s", squibCLT_array3); + pc.printf("\r\n\r\n"); + + + pc.printf("%d %d\r\n", rxInterruptCount, sendCount); + + pc.printf("\r\nEND\r\n"); + cleanBuffers(); + } +} + +