Joseph Ellsworth / Mbed 2 deprecated xj-data-log-test-and-example

Dependencies:   data_log mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* xj-data-log-test-and-exmple.c
00002   Shows basic usage of dat_log library and
00003   performs some basic tests. 
00004   
00005   By Joseph Ellsworth CTO of A2WH
00006   Take a look at A2WH.com Producing Water from Air using Solar Energy
00007   March-2016 License: https://developer.mbed.org/handbook/MIT-Licence 
00008   Please contact us http://a2wh.com for help with custom design projects.
00009   
00010   When using F303K8 and I2C 
00011     SB16 and SB18 must be removed because
00012     they link D4 to A4 and D5 to A5
00013     PG #12 http://www.st.com/content/ccc/resource/technical/document/user_manual/e3/0e/88/05/e8/74/43/a0/DM00231744.pdf/files/DM00231744.pdf/jcr:content/translations/en.DM00231744.pdf    
00014    
00015     FRAM Chip Interface MB85RS2MTPH-G-JNE1 
00016         3 MBit FRAM.  Also works with WinBond W25Q80BV and Windbond 8MB chips.
00017         
00018     #1 - Chip Select 
00019     #2 - DO - Data Out hook to MISO
00020     #3 - WP - Write  Protect - connect GND
00021     #4 - GND
00022     #5 - DI - Data In - hook to MOSI
00023     #6 - CLk- Clock - Hook to SPI_SCLK
00024     #7 - HD - Hold - connect VCC 3.3V
00025     #8 - VCC - Connect VCC 3.3V
00026     
00027     See Also: http://www.instructables.com/id/How-to-Design-with-Discrete-SPI-Flash-Memory/step2/The-WinBond-Device-Interface/
00028     
00029     If system seems to return garbage after writting test data 
00030     then one or more pins are most likely linked with a solder bridge
00031     check the users guide for the board you are using. 
00032 */
00033     
00034 #include "mbed.h"
00035 #include "dataLog.h"  
00036 
00037 const float adc_ref = 3.3f;
00038 // SPI PINS 
00039 #define SPI1_SCK PA_5
00040 #define SPI1_MISO PA_6
00041 #define SPI1_MOSI PA_7
00042 
00043 // SPI PINS for Data Log chip
00044 #define dataLogMISOPin  SPI1_MISO
00045 #define dataLogMOSIPin  SPI1_MOSI
00046 #define dataLogCLKPin   SPI1_SCK
00047 #define dataLogSelectPin PA_4
00048 
00049 //#define DO_LOG_ERASE  // uncomment to erase the existing log.
00050 //#define DO_SEND_MANUAL  // uncomment to send first 1000 bytes to pc on startup
00051 //#define DO_SEND_ALL // uncomment to send entire log to PC on startup
00052 //#define DO_SEND_LAST // uncomment to send last 900 bytes to pc on startup
00053 //#define TEST_BASIC_READ_WRITE // uncomment to erase chip and test basic read write interface
00054 
00055 AnalogIn waterTempSense(A0);
00056 AnalogIn oxygenLevelSense(A1);
00057 AnalogIn solarStrengthSense(A2);
00058 
00059 // imagine for sake of example that we have
00060 // circuitry that actually convert these Volt
00061 // readings to useful readings.
00062  
00063 DigitalOut led(LED1);
00064 Serial pc(USBTX, USBRX);
00065 
00066 // simulated process generating log entries
00067 // based on ADC readings. 
00068 void generateSimulatedLog(struct DLOG *lgr,  int numCycles, float sleepBetween) {
00069     char stateHappy[] = "happy";
00070     char stateSad[] = "sad";
00071     char stateDead[] = "dead fish";
00072     char *currState = stateHappy;
00073     char *lastState = 0;
00074     int cycleCnt;
00075    
00076 
00077     for(cycleCnt=0; cycleCnt < numCycles; cycleCnt++) {
00078         float waterTemp = waterTempSense.read() * adc_ref;
00079         float oxygenLevel = oxygenLevelSense.read() * adc_ref;
00080         float solarStrength = solarStrengthSense.read() * adc_ref;
00081         //float waterSpeed = waterSpeedSense.read() * adc_ref;
00082     
00083         char tbuff[256];
00084         sprintf(tbuff, "%0.2f,%0.2f,%0.2f", waterTemp, oxygenLevel, solarStrength);
00085         dlLog(lgr, "sensors",tbuff);
00086         // date and time are automatically recorded with the call.
00087         // time is only recorded to the second granularity and dates
00088         // are actually recorded as separate records when the date changes.
00089 
00090         pc.printf("cycleCnt=%d logged %s\r\n", cycleCnt, tbuff);
00091         
00092         currState = stateHappy;
00093         if (oxygenLevel < 20)
00094           currState = stateSad;
00095         if (oxygenLevel < 12)
00096           currState = stateDead;
00097           
00098         if (currState != lastState) {
00099           // Only generate a new log if the current state has changed
00100           lastState = currState;
00101           sprintf(tbuff,"%s,%0.2f", currState, oxygenLevel);
00102           dlLog(lgr,"state", tbuff);  
00103           pc.printf("cycleCnt=%d logged stateChange %s\r\n", cycleCnt, tbuff);  
00104         }
00105         // lgr will internally log time.  Whenever the date changes
00106         // it will log a new date records.     
00107         led = !led;    
00108         wait(sleepBetween);
00109     }
00110 }
00111 
00112 // documentaion on supporting Serial Interupts 
00113 // https://developer.mbed.org/cookbook/Serial-Interrupts
00114 
00115 
00116 int main() {
00117     pc.baud(9600);
00118     pc.printf("\nData Logger Example example\n");
00119     set_time(1459380179);
00120     
00121     // NOTE: You need to initialize the clock to some meaningful value
00122     //  I use a clock chip but here is a manual setting 
00123     time_t seconds = time(NULL);
00124     pc.printf("time set to %s\r\n", ctime(&seconds));
00125     
00126     char dlbuff[81]; // buffer used internally by this instance of data log
00127     DataLogChipType dlchip(dataLogMOSIPin, dataLogMISOPin, dataLogCLKPin, dataLogSelectPin);
00128     pc.printf("\r\nInitialized Data Log Chip");
00129     
00130     
00131     #ifdef TEST_BASIC_READ_WRITE  
00132     printf("start basic write test\r\n");
00133     printf("chipErase\r\n");
00134     dlchip.chipErase(); 
00135     memset(dlbuff,0,30);   
00136     memcpy(dlbuff, "I am a test\r\n\r\n\r\n",17);
00137     dlchip.writeStream(100,dlbuff, 17);
00138     memset(dlbuff,0,30);
00139     dlchip.readStream(100, dlbuff, 17);
00140     printf("read buffer =%s\r\n", dlbuff);
00141     #endif
00142 
00143     struct DLOG *lgr = dlMake(&dlchip, dlbuff, 80, &pc);    
00144     pc.printf("\r\nInitialized Logger\r\n");    
00145     pc.printf("logger nextWritePos=%ld", lgr->nextWritePos);    
00146     
00147     dlHelp(lgr); // send data log command help to pc. 
00148     #ifdef DO_LOG_ERASE
00149       //Erase the log But only if you really want to loose the
00150       // data
00151       pc.printf("ERASE LOG");
00152       dlEraseLog(lgr);
00153       pc.printf("afer erase logger nextWritePos=%ld", lgr->nextWritePos);
00154     #endif 
00155     
00156     #ifdef DO_SEND_MANUAL
00157       // Manually Read first 1,000 bytes from the log
00158       // could contain some garbage since it does not
00159       // pay attention to current log length.
00160       char rbuff[1001];
00161       memset(rbuff,1001,0);
00162       dlchip.readStream(dlFirstLogEntry, rbuff, 1000);
00163       pc.printf("first 1000 characters from log\r\n%s\r\n", rbuff);
00164     #endif
00165     
00166     #ifdef DO_SEND_ALL
00167       // Send Log Contents to Serial port
00168       // sends from byte zero of the log
00169       // to byte 100,000 or end of log which ever comes 
00170       // first. 
00171       pc.printf("\r\nSend the contents of log to PC automated way\r\n");
00172       dlReadSendAll(lgr, &pc);
00173       pc.printf("\r\nDONE SEND ALL\r\n");
00174     #endif
00175     
00176     #ifdef DO_SEND_LAST
00177       pc.printf("\r\nSend the last 900 bytes\r\n");
00178       dlReadSendLast(lgr, &pc, 50000);
00179       pc.printf("\r\nDONE Send Last\r\n");
00180     #endif
00181     
00182     
00183     // Record our record headers.  These need to match the records we will
00184     // write later.  It is OK to change the defintion of the headers as the 
00185     // parser will use the correct defenition provided you always record the
00186     // defenition before writing the log entries.
00187     dlLog(lgr, "HEAD\tsensors", "waterTemp.f,oxygenLevel.f,solarStrength.f,waterSpeed.f");
00188     dlLog(lgr, "HEAD\ttstate", "currState.s,oxygenLevel.f");
00189     pc.printf("\r\nWrote record type headers\n");
00190     // by convention I record the record header every time the system starts.
00191     // in future will have a fast way to retrieve active header for each record
00192     // type so you can determine if new header is differnt that exisitng header and
00193     // only record if they chanaged. 
00194     // The .f suffix is a hint to down stream parser to parse as a float.
00195     //  .f - float,  .i - int or long, .s-string,  .d - ISO date, .b - byte
00196     // at the very least you should record a new HEAD record the first time 
00197     // a given record type is used and every time you add or change the fields or field ordering.
00198     
00199     generateSimulatedLog(lgr, 20, 10.0);
00200     
00201     while(1) {
00202         
00203         
00204     }
00205   
00206   
00207     
00208 }