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.
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 }
Generated on Wed Jul 13 2022 20:08:01 by
1.7.2