'************************************************************************* '* __ __ __________ __ __ ________ * '* / \ | | |___ ___| / \ | | | ___ \ * '* / \ | | | | / \ | | | | \ | * '* / /\ \ | | | | / /\ \ | | | |___/ | * '* / /__\ \ | | | | / /__\ \ | | | __ / * '* / ______ \ | |____ | | / ______ \ | | | | \ \ * '* /__/ \__\ |_______| |__| /__/ \__\ |__| |__| \__\ * '* * '* www.altair.org * '************************************************************************* '* * '* HAM RADIO BALLOON TELEMETRY SOFTWARE FOR THE PARALLAX BASIC STAMP * '* * '* de N4YWK, Will Payne www.altair.org JULY 1995 * '* * '* Uses MAX187 12 bit serial A/D sensor input, sends CW ID, 4 digit * '* altitude, two 3 digit temperatures from thermistors using pot A/D, * '* moves a hobby servo for mirror for video camera, sends long DF tone. * '* Code is fairly tight, if you can fit anything more in, tell me how! * '* * '* Uses Motorola MPX5100A pressure xducer into MAX187 via V divider. * '* Temp probes are Keystone NTC thermistors, (Digi-Key #KC002G) which * '* stay within the stamp's measurement range (R < 20k) at all temps. * '* Use a 0.01uF cap in series with thermistor to ground, like app note. * '* CW has two outputs, one is audio tone for FM TX and ATV subcarrier, * '* the other is straight keyed Vcc for xtal osc modules. (28.322 Mhz) * '* The stamp is directly drives the mirror servo motor's pwm input. * '* If the stamp sleeps, the servo twitches and drifts. (sleep walking?) * '* A CW or servo output may be traded off for a third temp probe. * '* * '* BIG THANKS to WB8ELK Bill Brown the BalloonMeister, and Elktronix. * '* Thanks to Maxim engineering, and to Parallax and their BBS. * '* * '************************************************************************* Symbol CS = 0 'pin 0, to A/D convertor chip select Symbol AD = pin1 'pin 1, to A/D convertor data Symbol CLK = 2 'pin 2, to A/D convertor clock Symbol CW_aud = 3 'pin 3, CW audio tone output Symbol CW_key = 4 'pin 4, CW key output Symbol Servo = 5 'pin 5, servo motor PWM control Symbol Therm1 = 6 'pin 6, thermistor RC Symbol Therm2 = 7 'pin 7, thermistor RC Symbol Character = b0 'variable address, CW character Symbol Elements = b1 'variable address, CW element count Symbol Index1 = b2 'variable address, loop index Symbol Index2 = b3 'variable address, loop index Symbol SrvPos = b10 'servo position register Symbol ADresult = w2 'variable address, A/D convertor data Symbol ADnormal = w3 'variable address, altitude and temp normal Symbol DFTone = 120 'DF tone pitch Symbol Tone = 112 'CW tone pitch Symbol Quiet = 0 'CW silence Symbol Dit_length = 6 'CW rate constant, dit time Symbol Dah_length = 18 'CW rate constant, dah time Symbol Wrd_length = 36 'CW rate constant, word space time Symbol Chr_length = 24 'CW rate constant, char space time Symbol PScale = 46 'scale constant for thermistor RC network Symbol PosA = 100 'servo position A, alternates with below Symbol PosB = 200 'servo position B, alternates with above let pins = 007 'set first three pins high let dirs = %11111101 'set all pins to output except pin 1 Top: for index1 = 0 to 4 'count thru CW characters to send lookup index1,(130,13,180,99,163),Character 'N4YWK gosub Morse 'send it next gosub Word_sp 'send space before continue Telemetry: 'send telemetry in decimal CW gosub ADconv 'acquire 12 bit A/D static pressure gosub Send_4_Digits 'send raw data in decimal CW pot Therm1,PScale,ADresult 'pot read thermistor 1 gosub Send_3_Digits 'send raw data in decimal CW pot Therm2,PScale,ADresult 'pot read thermistor 2 gosub Send_3_Digits 'send raw data in decimal CW sound CW_aud,(DFtone,255) 'sound a long audio tone gosub Move_It 'move something high CW_key 'key down for Index1 = 1 to 100 'wait 100 counts, without sleeping. pause 100 'each count is 100 mS. next 'stay awake so servo will not sleepwalk. low CW_key 'key up 'sleep 10 '10 sec battery saver sleep 'gosub Srvo_pulse 'reposition servo if it sleepwalks. goto Top 'loop forever Move_It: 'move a servo motor using PWM control, 20 mS cycle 10-90% 'cycles the servo between two positions, PosA and PosB, 'alternating every execution cycle. if SrvPos = PosA then Srvo_skip 'if servo is at PosA skip down let SrvPos = PosA 'else next servo command to PosA goto Srvo_pulse 'go command it Srvo_skip: 'if it was already at PosA let SrvPos = PosB 'servo will command to PosB Srvo_pulse: for Index1 = 1 to 100 'Send 100 pulses, about 2 sec. pulsout Servo,SrvPos 'Form the pulse, i * 10 uS wide. pause 18 'Wait 20 mS. next 'Keep cycling. return Send_4_Digits: Character=ADresult/1000//10 'get thousands digit gosub CWval 'look up and send CW code Send_3_Digits: Character=ADresult/100//10 'get hundreds digit gosub CWval 'look up and send CW code Character=ADresult/10//10 'get tens digit gosub CWval 'look up and send CW code Character=ADresult//10 'get ones digit gosub CWval 'look up and send CW code gosub Word_sp 'send space before return debug ADresult 'test port return Morse: 'send a CW character, one byte of packed bits '5 MSBs are 0=dit and 1=dah '3 LSBs are number of elements in character let Elements = Character & %00000111 'mask off element count Bang_Key: for index2 = 1 to Elements 'count thru elements if Character >= 128 then Dah '1 = dah goto Dit '0 = dit Reenter: let Character = Character * 2 'shift to next element next sound CW_aud,(Quiet,Chr_length) 'space after character return 'one character was sent Dit: 'send a Dit high CW_key 'key down sound CW_aud,(Tone,Dit_length) 'sound an audio tone low CW_key 'key up sound CW_aud,(Quiet,Dit_length) 'the sound of silence goto Reenter 'one Dit was sent Dah: 'send a Dah high CW_key 'key down sound CW_aud,(Tone,Dah_length) 'sound an audio tone low CW_key 'key up sound CW_aud,(Quiet,Dit_length) 'the sound of silence goto Reenter 'one Dah was sent Char_sp: 'send space between characters sound CW_aud,(Quiet,Dah_length) return Word_sp: 'send space between words sound CW_aud,(Quiet,Wrd_length) return CWval: 'look up CW code for decimal digits 0-9 lookup Character,(253,125,61,29,13,5,133,197,229,245),Character gosub Morse return ADconv: 'acquire result from MAX187 12 bit serial A/D convertor low CLK 'CLK low before start low CS 'select the convertor pulsout CLK,1 'pulse CLK to start let ADresult = 0 'clear the result register for Index2 = 1 to 12 'count the bits in let ADresult = ADresult * 2 'shift the result pulsout CLK,1 'clock the convertor let ADresult = ADresult + AD 'add the data bit next 'until complete high CS 'deselect the convertor return 'go home with ADresult end 'thats all, folks!