record adc values and send them to another uprocessor

Dependencies:   BufferedSerial SDFileSystem mbed

Fork of SDFileSystem_HelloWorld by mbed official

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();
+    }
+}
+
+