' EnvironmentSensingStation.bas ' Created by Chris D. Odom on 8-16-06 ' This application will record environmental data and store the data in the BX-24's ' onboard EEPROM. In this way, we can record data remotely. I used this application to ' record external temperature, internal temperature, ambient light, turbidity ' (direct light and scattered light), and conductivity for a 12-hour period in August, 2006. ' Note that my original code did not measure scattered light. This program, however, does. ' See www.basicxandrobotics.com/apps/ for more information. Option Explicit ' ******************************************************************************* ' *************** Declare Persistent Variables ********************************** ' ******************************************************************************* Private DataWrite As New PersistentBoolean Private NumBytesUsed As New PersistentLong Private Year As New PersistentInteger Private Month As New PersistentByte Private Day As New PersistentByte Public Sub Main() ' ********************************************************************************* ' ******************* Declare Variables and Constants ***************************** ' ********************************************************************************* Dim MemStart as Long, MemLocation as Long, Counter as Long, i as Long, DataBytes as Long Dim DWVoltage as Integer ' Data Write Voltage Dim Hour as Byte Dim Minute as Byte Dim Second as Single ' not Byte as told By NetMedia! Dim Next_Data_Sec as Single ' actual (real) time to take data Dim StrTime as String * 10 ' time as a string Dim Bytes_per_Record as Long Dim Suggested_Elapsed_Time as Single ' Pin numbers: Const LED_pin as Byte = 12 ' RAMB Pin 7 Const IntTemp_pin as Byte = 13 ' RAMB Pin 8 Const ExtTemp_pin as Byte = 14 ' RAMB Pin 9 Const AmbLight_pin as Byte = 15 ' RAMB Pin 10 Const Conduct_pin as Byte = 16 ' RAMB Pin 11 Const TurbidLight_pin as Byte = 17 ' RAMB Pin 12 Const TurbidScatter_pin as Byte = 18 ' RAMB Pin 13 Const StoG_pin as Byte = 20 ' Signal-to-Ground Jumper pin (RAMB Pin 15) ' Sensor Variables: Dim IntTemp as Integer ' BX-24 Pin 13 (RAMB Pin 8) Dim ExtTemp as Integer ' BX-24 Pin 14 (RAMB Pin 9) Dim AmbLight as Integer ' BX-24 Pin 15 (RAMB Pin 10) Dim Conduct as Integer ' BX-24 Pin 16 (RAMB Pin 11) Dim TurbidLight as Integer ' BX-24 Pin 17 (RAMB Pin 12) Dim TurbidScattered as Integer ' BX-24 Pin 18 (RAMB Pin 13) ' ********************************************************************************* ' **************** User-Defined Experimental Variables **************************** ' ********************************************************************************* ' Set the RTC to theses values. The data will begin recording immediately. Year = 2007 ' these lines set the date. the date Month = 1 ' resets after a power restart, Day = 1 ' so without these lines you get zeros Hour = 0 Minute = 0 Second = 0.0 ' Set how many A2D ports are to be used. From 1 to 6. Const Num_of_A2D as Long = 6 ' 1 to 6 ' Set how often to take data in seconds. From 0.0 to 86399.9 (or 24 hours) Const Data_Interval as Single = 120.0 ' Time in seconds. Include decimal point! ' Set how long to collect in hours. Const Elapsed_Time as Single = 18.0 ' Elapsed Time in hours. Include decimal point! ' refer to *.MPP file to determine the number of bytes the program consumes MemStart = 10000 ' start writing to memory after program memory ' ******************************************************************************** ' *********************** Experiment Values Variables **************************** ' ******************************************************************************** Bytes_per_Record = 12 + (Num_of_A2D * 2) ' Calculate the number of Bytes needed to store all of the data: DataBytes = CLng(((Elapsed_Time * 3600.0) / Data_Interval) * CSng(Bytes_per_Record)) ' number of bytes used to store data. Must be less than (32768 - MemStart) ' 5 A2D equals 22 bytes per reading (so 220 = 10 readings, 2200 = 100 readings, etc) ' Say we take data once a second for a total of 60 seconds then DataBytes = 1320 bytes ' Say we take data once a second for a total of 15 minutes then DataBytes = 19800 bytes ' Say we take data every 5 seconds for a total of 30 minutes then DataBytes = 7920 bytes ' Say we take data every 3 seconds for a total of 30 minutes then DataBytes = 13200 bytes ' 60 minutes at 5 seconds per record = 15840 ' 6 hours at 30 seconds per record = 15840 ' 24 hours at 90 seconds per record = 21120 Debug.Print "DataBytes = " & CStr(DataBytes) Debug.Print ' Check to see if the number of Bytes needed is valid: If (DataBytes >= (32768 - MemStart)) Then Debug.Print "You are collecting too much data!" Debug.Print "Reduce Data_Interval, Elapsed_Time, and/or MemStart." Suggested_Elapsed_Time = ((32768.0 - CSng(MemStart)) * Data_Interval) / (CSng(Bytes_per_Record) * 3600.0) Debug.Print "May I suggest that you set Elapsed_Time to " & CStr(Suggested_Elapsed_Time) Do ' loop forever Loop End If ' ********************************************************************************* ' *** If we are conducting a NEW experiment then set DataWrite = TRUE ************* ' ********************************************************************************* ' If the Signal-to-Ground Jumper Pin (BX-24 pin 20, RAMB pin 15) is grounded, a ' toggle is set so data can be recorded once power is again cycled to BX24. ' Improvement notes: ' Add a connector to the walls of the chamber so toggle can be reset without having ' to open the main chamber! Also, add external LEDs to outside of the main chamber ' so we can see the indicator lights without having to open the case. DWVoltage = GetADC(StoG_pin) If (DWVoltage = 0) then ' if Toggle Switch is closed Debug.Print "Setting the DataWrite variable. When" Debug.Print "Green LED blinks, it's OK to power down" Debug.Print "and then remove the short." DataWrite = TRUE Do ' blink GREEN LED: OK to turn off power Call PutPin(25,1) ' turn off Red LED Call PutPin(26,0) Delay(0.05) ' conserve battery power Call PutPin(26,1) Delay(1.0) Loop End If ' ********************************************************************************* ' *** If this is the first time the BX-24 has been powered, RECORD Data *********** ' ********************************************************************************* If (DataWrite = True) Then DataWrite = False 'Makes sure this first data will not be over-written Counter = 0 ' Turn ON the LED (optional if turbidity is not to be measured). Call PutPin(LED_pin, 1) Call PutTimestamp(Year, Month, Day, Hour, Minute, Second) 'put time into memory Debug.Print "Start Date & Time:" Debug.Print CStr(Month) & "." & CStr(Day) & "." & CStr(Year) Debug.Print CStr(Hour); ":"; CStr(Minute); ":"; CStr(Second) Debug.Print Do While (Counter < DataBytes) ' Maximum number of bytes of EEPROM to be used for data storage Call GetTime(Hour, Minute, Second) ' Convert time to a string StrTime = CStr(Hour) & ":" & CStr(Minute) & ":" & CStr(Second) ' Read all the sensor voltages. ' Set potentiometers appropriately. Make Conductivity resistor low (so you get a low ADC reading). ' Pin 18 is not collecting data for this trial. IntTemp = GetADC(IntTemp_pin) ExtTemp = GetADC(ExtTemp_pin) AmbLight = GetADC(AmbLight_pin) Conduct = GetADC(Conduct_pin) TurbidLight = GetADC(TurbidLight_pin) TurbidLight = GetADC(TurbidScatter_pin) ' 'Comment-out these print statements before running the program for real ' Debug.Print StrTime ' string time ' Debug.Print "Internal Temp: " & CStr(IntTemp) ' Debug.Print "External Temp: " & CStr(ExtTemp) ' Debug.Print "Ambient Light: " & CStr(AmbLight) ' Debug.Print "Conducivity: " & CStr(Conduct) ' Debug.Print "Turbidity: " & CStr(TurbidLight) ' Debug.Print ' Save the sensor data in EEPROM: MemLocation = MemStart + Counter Call PutEEPROM(MemLocation, StrTime, 12) ' time string is 12 characters. 10 bytes plus 2 bytes of overhead for strings Call PutEEPROM((MemLocation + 12), IntTemp, 2) Call PutEEPROM((MemLocation + 14), ExtTemp, 2) Call PutEEPROM((MemLocation + 16), AmbLight, 2) Call PutEEPROM((MemLocation + 18), Conduct, 2) Call PutEEPROM((MemLocation + 20), TurbidLight, 2) Counter = Counter + Bytes_per_Record NumBytesUsed = Counter ' A persistent variable used to verify data output ' Calculate when to recrod the next set of data: Next_Data_Sec = Timer + Data_Interval ' Adjust Next_Data_Sec in case the next point falls on the other side of midnight If (Next_Data_Sec >= 86400#) Then Next_Data_Sec = Next_Data_Sec - 86400# End If Do ' Do nothing until the Data_Interval time has elapsed. ' Placing code inside this loop may produce unwanted effects Loop Until Timer = Next_Data_Sec Loop Debug.Print "The Recording Phase is done." Debug.Print "Turning off the LED..." Call PutPin(LED_pin, 0) ' Turn OFF the LED Debug.Print "LED is off." Debug.Print "Cycle the power to output recorded data." Debug.Print End If ' end the "if DataWrite = True" loop ' ********************************************************************************** ' ** If this is NOT the first time the BX-24 has been powered up then ' ** PRINT the data to the screen. Then copy the data from the screen and import it ' ** into Excel. You can also automatically save the data directly to a FILE as it ' ** prints. This is explained in my book on page 313 (File >> Capture to File). ' ********************************************************************************** If (DataWrite = False) Then Debug.Print "Note that all data is NOT scaled to 5V! Multiply by 5/1023!" Call PutPin(26, 1) ' Turn Green LED off Call PutPin(25, 0) ' Turn Red LED on Debug.Print "Start Date: " & CStr(Month) & "." & CStr(Day) & "." & CStr(Year) Debug.Print "NumBytesUsed: " & CStr(NumBytesUsed) Debug.Print "Data_Interval (s): " & CStr(Data_Interval) Debug.Print "Bytes, Mem, Time, Int Temp, Ext Temp, Light, Conduct, Turbid" i = 0 Do While (i < NumBytesUsed) ' Bytes used for data MemLocation = MemStart + i Call GetEEPROM(MemLocation, StrTime, 12) ' time string is 12 characters. 10 bytes plus 2 bytes of overhead for strings Call GetEEPROM((MemLocation + 12), IntTemp, 2) Call GetEEPROM((MemLocation + 14), ExtTemp, 2) Call GetEEPROM((MemLocation + 16), AmbLight, 2) Call GetEEPROM((MemLocation + 18), Conduct, 2) Call GetEEPROM((MemLocation + 20), TurbidLight, 2) Debug.Print CStr(i) & ", " & CStr(MemLocation) & ", " & StrTime & ", " & CStr(IntTemp) & ", " & CStr(ExtTemp) & ", " & CStr(AmbLight) & ", " & CStr(Conduct) & ", " & CStr(TurbidLight) i = i + Bytes_per_Record Loop ' blink LED's to show that program is over ' this is helpful! -- when you open the apparatus up and see blinking LED's you know the power has been cycled Debug.Print "That's all the data." Do Call PutPin(26, 0) ' Turn Green LED on Call PutPin(25, 1) ' Turn Red LED off Call Delay(0.5) Call PutPin(26, 1) ' Turn Green LED off Call PutPin(25, 0) ' Turn Red LED on Call Delay(0.5) Loop End If ' end the "if DataWrite = False" loop ' ********************************************************** Debug.Print "the program is finished" Call PutPin(26, 1) ' Turn Green LED off Call PutPin(25, 1) ' Turn Red LED off End Sub