' ' {$STAMP BS2} ' {$PBASIC 2.5} ' ' ============================================================================== ' ' File....... MAWDBOE_w_CO2_WORKS_OK - June 25, 2010.BS2E ' ' Purpose.... Humidity, temperature, altitude, and carbon dioxide data logging ' Rocketeers. Andrew (am), Sean (sd), Dylan (dl), Justin (ja), Mike (mp) ' Faculty.... Mark Kibler (mk) ' Peanut gallery... Tracy Allen (ta), Paul Smith (Sylvie) (ps-s) ' E-mail..... mkibler@alumni.unity.edu ' Started.... February, 2008 & repurposed June, 2010 ' ' ' ============================================================================== ' -----[ Program Description ]--------------------------------------------- ' ' ASP-2/MAWDBOE program with a Parallax CO2 sensor: The Air Sampling Probe (ASP-2) measures and records ' temperature, humidity, altitude, CO2 concentration, flight time, sand sample number. The MAWD is a ' PerfectFlite brand "Mini Altimeter With Deployment" feature wire into a Parallax Board of Education. ' ' -----[ Revision History ]------------------------------------------------ ' ' -- 08 March 2008 (ta, pk) ' 1) added header section delineating the Vinculum thumb drive record structure ' 2) added subroutines for Vinculum init and file handling ' V_synchronize, V_check_disk, V_short_commands -- these are initialization ' V_getdata, V_purge these two are the same routine, sometimes data simply purged ' V_open_file, V_close_file, these are in the main LOOP ' 3) forging the disk, a startup message shows how many tries TO access the disk ' 4) if the data file is opened successfully, "DaedelusCRLF" is written to the file ' 5) added one Word variable to hold more status flags or data. Buffer is 12 bytes ' 6) LED flashes briefly each time through the loop. ' '-- 06 March 2008 (mk, am, mw, bl, ds, jr, nm) ' 1) Changed data sampling time at descent to 1 sec intervals (from 2>10 to 2>100) per (ta) ' 2) Commented out 'GOSUB morse reading' twice in 'main:' subroutine per (ta) ' 3) Shortened duration of 'motormovement' times so we could bench test the program. These will be changed ' back to their original 1 meter distance (0 TO 681) when we finalize the program. ' 4) The Rocketeers experimented by changing various settings to see what would happen, ' and marveled at the Morse code light. Bandit the Rocket Dog was little help. ' '-- 05 Mar 2008 (ta) ' Added increment of sample counter index2. Displays on debug. Land flag ' is set by either elapsed time or index2 accumulation. ' ' -- 04 Mar 2008 (ta) Mar04a ' Major restructuring from template, variables, starting point "RocketRobot_Feb29.BS2" ' Streamlined the Sensirion and movement routines with subroutine structure. ' Consolidated variables, named all pins ' This version incorporates the clock, LED and movements, but not yet the datalogger ' '-- 01 July 2009 (mk) ' 1) 'Commented out' (not deleted) robot movement commands (servomotor movements) and inputs ' 2) 'Commented out' Morse code program for servomotor movement - Kept Morse code program for sync and disk tries ' ' -- 9 July 2009, (ta) ' 1) added device pin numbers in () in comments ' 2) made initial debug message a subroutine, "init_message" ' 3) added code to return a data value for MAWD, and to show it on debug screen after %RH ' initially this is initially a dummy value, 12345 and RETURN, to test program loop and logging ' added word VARiable "feet", PIN "MAWDin" on p3, and subroutine "MAWD_get" ' call to MAWD_get inserted in MAIN loop. ' 4) increased size of data string for USB drive to 29 bytes, added field for feet of altitude ' 5) changed DS pins to p7,p6,p5 instead of p2,p5,p7 ' 6) added means to synchronize data recording with DS1302 RTC ' added CONstant "logInterval" (allowed intervals in seconds is 1,2,3,4,5,6,10,12,15,20,or 30) ' e.g. if logInterval=5 then data will be logged at 5 second intervals ' added subroutine sync_RTC, and MAIN calls sync_RTC instead of read_RTC ' new VARiable second0 holds a comparison value to track the change in seconds ' ' -- 10 July 2009, (ta) ' 1) debugged subroutine MAWD_get using 2nd BASIC Stamp to simulate MAWD ' ' -- 25 June 2010, (mk) ' 1) Defined analog-digital converter (ADC) I/O pins for wires that go to the ASP-BOE. ' 2) Added Tracy and Andrew's 'MCP_get:' subroutine ' ' -- 29 June 2010, (mk) ' 1) Defined ALM - PIN 3 ' 2) Defined CNTL - PIN 4 ' ' -- 30 June 2010 (ta), (mk) ' 1) Condensed VAR 'result0, result1, mVolts0, and mVolts1' into a shorter, ' more effficient 'MCP_get' subroutine (ta) ' 2) Commented out 'HIGH 4' command which was causing erratic CO2 mV data (mk) ' 3) Added column headings for 'CO2 mV' and 'CO2 ppm' (mk) ' 4) Commented out the 'carbon collect' command that made ALARM status 0 and 1 appear (ck) ' ========================================================================================== ' -----[ I/O Definitions ]------------------------------------------------- ShtDta PIN 1 ' bi-directional data with pullup resistor SHTdta=(1) ShtClk PIN 0 ' clock (for Sensirion) with pulldown resistor SHTclk=(3) ' power (4)=Vss 4, (8)=Vdd MAWDin PIN 15 ' mk changed PIN 3 to PIN 15 - July 11 - input from altitude, 9600 baud inverted, 20 per second, 5 bytes. DSclk PIN 2 ' DS1302 RTC clock=(7) ' ta moved DS pins to 7,6,5 instead of 2,5,7 - mk moved back to 2, 5, 7 - July 11 DSdta PIN 5 ' DS1302 RTC data line=(6) DSce PIN 7 ' DS1302 RTC chip enable (high enable)=(5) ' power to DS1302 Vdd=(1), Vss=(4), Vbat=(8) TX PIN 8 ' Transmit Data --> 27937.4 (RXD) output to Vinculum=(4) RTS PIN 9 ' Request To Send --> 27937.6 (CTS) to Vinculum=(6) RX PIN 10 ' Receive Data <-- 27937.5 (TXD) from Vinculum=(5) CTS PIN 11 ' Clear To Send <-- 27937.2 (RTS) from Vinculum=(2) ' power (1)=Vss, (3)=Vdd, (7)=n/c, (8)=ri ' ----- [ MCP I/O definitions ] ------- ALM PIN 3 ' Wire comes from the CH0 pin on the ADC breadboard to TP1 on the CO2 sensor. CNTL PIN 4 ' Wire comes from the CH1 pin on the ADC breadboard to TP3 on the CO2 sensor. DataOut PIN 6 ' DataIn and DataOut ADC pins are jump-connected with 1 K ohm resistor. ' A separate wire runs from each ADC pin. DataIn and DataOut wires ' are connected into one wire. This single wire goes into p6 on the ASP-BOE. DataIn PIN 6 ' DataIn and DataOut ADC pins are jump-connected with 1 K ohm resistor. ' A separate wire runs from each ADC pin. DataIn and DataOut wires ' are connected into one wire. This single wire goes into p6 on the ASP-BOE. CS PIN 12 ' Wire comes from the CS/SHDN pin on the ADC. It goes to BOE p12. Clock PIN 13 ' Wire comes from the CLK pin on the ADC. It goes to BOE p13. ' -----[ Constants ]------------------------------------------------------- vBaud CON 84 ' Serial Baud Rate 9600 bps for Vinculum datalogger ShtTemp CON %00011 ' read temperature command for Sensirion ShtHumi CON %00101 ' read humidity command for Sensirion Ack CON 0 ' responses for Sensirion NoAck CON 1 logInterval CON 1 ' choose 1,2,3,4,5,6,10,12,15,20,30 seconds DegSym CON 186 ' degrees symbol for DEBUG Cnts2Mv CON $0139 ' x 1.22 (To Millivolts) ' -----[ Variables ]------------------------------------------------------- CO2pp VAR Word ' new variable: Tracy - June 11, 2010 primo VAR Word iobyte VAR primo.BYTE0 ' io to/from datalogger, humidty sensor, & debug index VAR primo.NIB2 ' loop counter in some routines unused1 VAR primo.NIB3 secundo VAR Word flags VAR secundo.BYTE0 ackbit VAR flags.BIT0 ' acknowledge Sensirion shtErr VAR flags.BIT1 ' = 1 if error in sensirion read dskErr VAR flags.BIT2 ' =1 if the logger fails to work land VAR flags.BIT3 ' =1 after alloted time interval ' bits 4 to 7 are unused second0 VAR secundo.BYTE1 waldo VAR Word ' scratch variable soSHT VAR waldo ' alias as scratch variable for Sensirion soSHT0 VAR soSHT.BYTE0 ' byte by byte soSHT1 VAR soSHT.BYTE1 delay VAR waldo ' timeout for Sensirion ' motormovementtime VAR waldo ' alias as timer variable for movements degC VAR Word ' temperature in Celsius*10 from Sensirion rh VAR Word ' humidity in percent*10 from Sensirion feet VAR Word ' reading from MAAWD altimeter time0 VAR Word second VAR time0.BYTE0 ' from DS1302 RTC minute VAR time0.BYTE1 ' ditto time1 VAR Word hour VAR time1.BYTE0 ' ditto index2 VAR time1.BYTE1 ' extra index for loop count buffer VAR Word ' for data returned from logger or RTC buf0 VAR buffer.BYTE0 ' will return as bytes buf1 VAR buffer.BYTE1 ' note the buffer can extend into unassigned space, take care. '---- [ carbon VAR Word ] ---- 'result0 VAR Word ' Conversion Result CH0 'result1 VAR Byte ' Conversion Result CH1 'mVolts0 VAR Word ' Result0 --> mVolts 'mVolts1 VAR Byte ' Result1 --> mVolts ' -----[ EEPROM Data ]----------------------------------------------------- ' ' ' -----[ Thumb Drive Data Format ]----------------------------------------- ' ' data format with RTC clock time included ' ' 2 bytes hour ' 1 byte ":" <---- colon time separator ' 2 bytes minute ' 1 byte ":" <-- okay ' 2 bytes second ' 1 byte "," <--- comma as field separator ' 1 byte sign, either - or space ' 3 bytes temperature integer part ' 1 byte "." ' 1 byte temperature decimal part ' 1 byte "," ' 3 bytes humidity integer part ' 1 byte "." ' 1 byte humidity decimal part ' 1 byte "," ' 5 byte altitude from MAWD ' 1 byte CR <---- CRLF as record separator ' 1 byte LF ' 1 byte CR for the Vinculum terminator, this does not appear in the data file ' = ' 29 bytes total for Vinculum character count, 23 bytes per record on Thummb drive. ' -----[ Initialization ]-------------------------------------------------- Reset: 'OUTS = %0001001000000000 ' indicator led is on. rts (p9) high to start, tx (p8) low to start. 'fedcba9876543210 - commented out by JA, June 14, 2010 'DIRS = %1111001111111101 ' p1 is input for sensirion data, pa and pb input for rx and cts - commented out by JA, ' June 14, 2010 OUTS = %0001001000000000 ' indicator led is on. rts (p9) high to start, tx (p8) low to start. 'fedcba9876543210 - TA Program fix added by JA, June 14, 2010 DIRS = %1111001111110101 ' p1 is input for sensirion data, pa and pb ' TA Program fix added by JA, June 14, 2010 ' input FOR rx AND cts AND p3 FOR CO2 DEBUG CR, "Initializing...",BELL,CR, CR ' mk changed 'wait' to 'initializing' July 11 GOSUB init_Message PAUSE 10 GOSUB RTC_init ' reset the clock to 00:00:00 PAUSE 1000 GOSUB RTC_init ' mk added 08 March 2008 PAUSE 512 HIGH TX ' Initialize Transmit Line LOW RTS ' Take Vinculum Out Of Reset PAUSE 512 ' Allow 1/2 Second To Settle ' LOW ledP ' LED indicator off - long pulse signals reset GOSUB V_synchronize ' get ready to send data to thumb drive DEBUG CR,"sync tries: ",DEC waldo iobyte=waldo : GOSUB morse_numeral ' show the tries count for debugging GOSUB V_short_commands ' enable short command mode on Vinculum/thumb drive GOSUB V_Check_Drive DEBUG CR,"disk tries: ",DEC waldo, CR iobyte=waldo : GOSUB morse_numeral ' show the tries count for debugging ' either print disk not found, else write IF dskerr=1 THEN DEBUG " not found" ELSE GOSUB V_open_datafile SEROUT TX\CTS, vBaud, [ $8,$20,0,0,0,10,CR,"ASP data",CR, LF] GOSUB V_purge GOSUB V_close_datafile ENDIF DEBUG CR,"Time (sec) Sample# CO2(mV) CO2(ppm) Temp(C) Humidity(%) Altitude(ft)",BELL,CR GOSUB SHT_Connection_Reset PAUSE 256 ' -----[ Program Code ]---------------------------------------------------- Main: DO ' PULSOUT ledP,50 ' GOSUB RTC_read GOSUB RTC_sync ' mk removed " minute =$01 OR " from the next line, right after IF command - 01 July 2009 ' IF index2>100 THEN land=1 ' set flag to start movements after descent of one minute index2 = index2 + 1 DEBUG CR,HEX2 hour,":",HEX2 minute,":",HEX2 second, TAB, DEC index2 GOSUB MAWD_get GOSUB SHT_Measure_Temp GOSUB SHT_Measure_Humidity GOSUB Carbon_collect GOSUB MCP_get DEBUG TAB,REP "-"\degC.BIT15,DEC ABS degC/10,".",DEC1 ABS degC,degSym DEBUG TAB, DEC rH/10, ".", DEC1 rH, "%" DEBUG TAB, TAB, DEC feet, CR ' mk added a second tab - July 11 GOSUB V_open_datafile ' thumb drive GOSUB V_write_record ' one data record GOSUB V_close_datafile ' close the file ' IF land THEN GOSUB movement - mk commented out - 01 July 2009 LOOP END ' -----[ Subroutines ]----------------------------------------------------- ' ' -----[ RTC ]----- RTC_init: ' send $00 to DS1302 control register (command $8E) to enable write HIGH DSce SHIFTOUT DSdta,DSclk,LSBFIRST,[$8E,$00] LOW DSce ' set the clock time using burst command $BE ' second=0, minute=0, hour=0, date31=4, month=7, day7=9, year=2009 ' also disable further writes: $80 at loc $7 HIGH DSce SHIFTOUT DSdta,DSclk,LSBFIRST,[$BE,$00,$00,$00,$04,$07,$09,$09,$80] LOW DSce RETURN rtc_Sync: ' paces data logging to the number of seconds specified ' in CONstant "logInterval" buffer=loginterval*200 ' this variable is used as a temporary counter DO:DO GOSUB RTC_read buffer=buffer-1 ' this countdown is an escape from loop in case RTC fails LOOP UNTIL second<>second0 OR buffer=0 ' second0=second ' change, update old value for tracking LOOP UNTIL second.NIB1*10+second.NIB0//logInterval=0 OR buffer=0 ' wait for log interval to arrive ' DEBUG CR,?buffer RETURN RTC_read: ' retrieves the time to variable: second, minute, hour HIGH DSce SHIFTOUT DSdta,DSclk,LSBFIRST,[$BF] ' burst mode read $BF command SHIFTIN DSdta,DSclk,LSBPRE,[second,minute,hour] LOW DSce RETURN ' -----[ Vinculum/Thumb Drive]----- ' ' refer to email discussion around email at: ' http://forums.parallax.com/forums/default.aspx?f=6&p=7&m=247882#m252750 V_purge: V_Get_Data: SERIN RX\RTS, vbaud,128, V_Timeout, [STR buf0\12] V_Timeout: ' timeout is the normal exit, buffer not full RETURN V_synchronize: ' Send 'E' to start the synchronization process. ' Expect 'E' and a CR for the response, timing per pk waldo=0 ' count tries DO GOSUB V_purge ' clear the vinculum tx data buffer PAUSE 256 ' wait about 1/4 second SEROUT TX\CTS, vbaud, ["E", CR] ' Sync Command Character GOSUB V_get_Data ' Get Response waldo=waldo+1 LOOP UNTIL (buf0="E" AND buf1=CR) OR waldo=8 GOSUB V_purge ' Purge Buffer of leftover junk SEROUT TX\CTS, vbaud, ["e", CR] ' next Sync Command Character GOSUB V_get_Data ' Get Response/purge IF (buf0<>"e" OR buf1<>CR) THEN waldo=waldo + 1 IF waldo>7 THEN dskerr=1 ' returns with number of tries in waldo ' returns with dskerr=1 if cant sync RETURN V_Check_Drive: waldo=0 DO GOSUB V_purge SEROUT TX\CTS, vbaud, [CR] GOSUB V_get_Data IF buf0="N" AND buf1="D" THEN waldo=9 ' error: disk not found EXIT ' no point to test more ENDIF waldo=waldo+1 PAUSE 100 LOOP UNTIL buf0=">" OR waldo=8 IF waldo>7 THEN dskerr=1 ' return with number of tries in waldo ' waldo=9 means it got the no disk error ' dskerr flag=1 is tries>7 RETURN V_short_commands: SEROUT TX\CTS, vbaud, ["SCS", CR] GOSUB v_get_Data ' purge RETURN V_Open_DataFile: GOSUB V_purge ' purge receive buffer SEROUT TX\CTS, vbaud, [$09, $20, "datafile.txt", CR] GOSUB V_purge ' purge receive buffer RETURN v_Close_DataFile: GOSUB V_purge ' Purge Receive Buffer SEROUT TX\CTS, vbaud, [$0A, $20, "datafile.txt", CR] GOSUB V_purge ' purge receive buffer RETURN V_write_record: ' Write data with time to flash drive ' Added 'CO2 ppm' - June 11, 2010 - Tracy, Dylan, Justin LOW RTS SEROUT TX\CTS, vBaud, [ $8,$20,0,0,0,35,CR, HEX2 hour, ":" , HEX2 minute, ":", HEX2 second, "," , degC.BIT15*13+32,DEC3 ABS (degC/10),".", DEC1 ABS degC,",",DEC3 (RH/10),".",DEC1 RH,",", DEC5 feet,",",DEC5 CO2pp, CR, LF] HIGH RTS GOSUB V_purge RETURN ' -----[ Sensirion ]----- SHT_Connection_Reset: SHIFTOUT ShtDta, ShtClk, LSBFIRST, [$FFF\9] RETURN ' ' generates SHT1x "start" sequence ' _____ _____ ' ShtData |_______| ' ___ ___ ' Clock ___| |___| |___ ' ' SHT_Start: INPUT ShtDta ' let pull-up take line high LOW ShtClk HIGH ShtClk LOW ShtDta LOW ShtClk HIGH ShtClk INPUT ShtDta LOW ShtClk RETURN ' sends start sequence & command byte & retrieves two data bytes from Sensirion SHT_measure: GOSUB SHT_Start ' alert device GOSUB SHT_Write_Byte ' send command (iobyte) GOSUB SHT_Wait ' wait until measurement done ackBit = Ack ' another read follows GOSUB SHT_Read_Byte ' get MSB soSHT1 = ioByte ackBit = NoAck ' last read GOSUB SHT_Read_Byte ' get LSB soSHT0 = ioByte RETURN ' ' measure temperature: ' -- celsius = soT * 0.01 - 40 SHT_Measure_Temp: ioByte = ShtTemp ' temperature command GOSUB SHT_measure ' send command degC = soSHT / 10 - 400 ' convert to tenths C RETURN ' measure humidity SHT_Measure_Humidity: ioByte = ShtHumi ' humidity command GOSUB SHT_measure ' send command rh = (soSHT ** 26542) rh = rh - ((soSHT ** 3468) * (soSHT ** 3468) + 50 / 100) rh = rh - 40 rh = ((degC + 250 / 10 - 50) * (soSHT ** 524 + 1) + (rh * 10)) + 5 / 10 RETURN ' sends "ioByte" ' returns "ackBit" SHT_Write_Byte: SHIFTOUT ShtDta, ShtClk, MSBFIRST, [ioByte] ' send byte SHIFTIN ShtDta, ShtClk, LSBPRE, [ackBit\1] ' get ack bit RETURN ' returns "ioByte" ' sends "ackBit" SHT_Read_Byte: SHIFTIN ShtDta, ShtClk, MSBPRE, [ioByte] ' get byte SHIFTOUT ShtDta, ShtClk, LSBFIRST, [ackBit\1] ' send ack bit INPUT ShtDta ' release data line RETURN ' wait for sht to finish measurement ' (data line pulled low by SHT within 1/4 second) SHT_Wait: INPUT ShtDta ' data line is input delay = 255 ' give >1/4 second to finish DO delay=delay-1 PAUSE 1 LOOP UNTIL ShtDta=0 OR delay=0 IF delay=0 THEN GOSUB SHT_Connection_Reset shtErr=1 ENDIF RETURN ' -----[ Carbon dioxide ]----- ' Added June 11, 2010 - Tracy, Dylan, Justin Carbon_collect: HIGH 4 'This activates the Heat Switch (HSW) ' <--- this does not really need to be repeated, but it doesn't hurt CO2pp = IN3 ' read the CO2 level. Later, we will make this do more than just the alarm status ' DEBUG TAB, DEC CO2pp ' show the CO2 level ALARM STATUS 0 or 1 RETURN ' -----[ MCP3202 ADC ]----- ' Added June 14, 2010 by Andrew from Tracy MCP_get: 'read channel 1 first, potentiometer, will NOT be logged HIGH 4 'This activates the Heat Switch (HSW) LOW CS ' Enable ADC SHIFTOUT DataIn, Clock, MSBFIRST, [ %1111\4] ' Select CH1, Single-Ended SHIFTIN DataOut, Clock, MSBPOST, [ CO2pp\12] ' Read ADC HIGH CS ' Disable ADC CO2pp = CO2pp */ Cnts2Mv ' Convert To Millivolts DEBUG TAB, DEC CO2pp ' shows the potentiometer voltage ' read channel 0, CO2 voltage, variable CO2pp will be logged on flash drive LOW CS ' Enable ADC SHIFTOUT DataIn, Clock, MSBFIRST, [ %1101\4] ' Select CH0, Single-Ended SHIFTIN DataOut, Clock, MSBPOST, [ CO2pp\12] ' Read ADC HIGH CS ' Disable ADC CO2pp = CO2pp */ Cnts2Mv ' Convert To Millivolts DEBUG TAB, DEC CO2pp ' show the CO2 voltage ' mVolts1 writes mV for CO2 potientiometer RETURN ' -----[ Morse code ]----- Morse_numeral: iobyte = %11110000011111 >> iobyte & %11111 | %10100000 Morse: FOR index = iobyte>>5 TO 1 ' HIGH ledP PAUSE 192*iobyte.BIT0(index-1)+64 ' LOW ledP PAUSE 256 NEXT PAUSE 512 RETURN morse_reading: DEBUG 32 FOR ackbit=1 TO 0 iobyte = waldo DIG ackbit DEBUG DEC1 iobyte GOSUB morse_numeral NEXT RETURN mcs CON 3*32+%000 ' dit dit dit mco CON 3*32+%111 ' dah dah dah mcn CON 2*32+%10 ' dah dit mcf CON 4*32+%0010 ' dit dit dah dit mcb CON 4*32+%1000 ' dah dit dit dit mcc CON 4*32+%1010 ' dah dit dah dit mcw CON 3*32+%011 ' dit dah dah mce CON 1*32+%0 ' dit mcv CON 4*32+%0001 ' dit dit dit dah morse_message: ' plays back morse message up to null ' enter with waldo pointing to message start ' e.g. waldo=message1 : GOSUB morse_message ' message1 DATA mcs,mco,mcs,0 ' sos, example message for LED DO READ waldo,iobyte IF iobyte=0 THEN EXIT GOSUB morse waldo=waldo+1 LOOP RETURN init_message: 'DEBUG CR, "ARLISS - A Rocket Launch for International Student Satellites", CR DEBUG CR,"ARLISS Team New Hampshire - June, 2010", CR, CR DEBUG "Temperature, humidity, carbon dioxide, and altitude data logging program",CR, CR DEBUG "With sincere thanks to Dr. Tracy Allen and Paul Smith",CR, CR DEBUG "And our friends at Parallax Inc. - www.parallax.com", CR,CR ' DEBUG "__________________________________________________________________________ ", CR RETURN MAWD_get: ' alternative code to acquire MAWD data, uses DEC5 instead of STR in SERIN PULSIN MAWDin,1,iobyte ' the purpose of this is to synchronize with the MAWD timing. PAUSE 10 ' this assures the SERIN will start waiting in the silent period before ' a MAWD xmission feet=0 SERIN MAWDin,84,64,MAWDnot,[DEC5 feet] MAWDnot: RETURN 'The end - Mark - June 25, 2010