#include <Wire.h> #include <OneWire.h> #include <math.h> // I/O Pins int ledPin = 6; // red led connected to digital pin 6 int ballastPin = 9; //connected to transistor - relay int txPin = 8; // radio tx line int radioPin = 7; //connected to transistor and Relay to control resistor heaters on gps. int ballastSensorLED = 10; //Connected to IR LED in base of ballast tank, pulses rapidly allowing comparison between ambient and IR OneWire ds(11); // DS18x20 Temperature chip i/o One-wire int photocellPin = 0; // the cell and 10K pulldown are connected to a0 int ballastSensorPin = 1; // Connected to Vout of Opamp (photodiode) int photocellReading; // the analog reading from the sensor divider int light1 = 0; int temp0 = 0, temp1 = 0, temp2 = 0, temp3 = 0; //temperature sensors byte address0[8] = {0x10, 0x22, 0x4A, 0xDB, 0x0, 0x8, 0x0, 0x94}; //Internal DS18S20 onboard daughter board byte address1[8] = {0x28, 0x2D, 0x28, 0x2E, 0x2, 0x0, 0x0, 0xE}; // External DS18B20 byte address2[8] = {0x28, 0x5D, 0x26, 0x2E, 0x2, 0x0, 0x0, 0x34}; // Internal DS18B20 Pump Sensor byte address3[8] = {0x28, 0x26, 0xF5, 0x2D, 0x2, 0x0, 0x0, 0xCC}; // Internal DS18B20 GPS Sensor int blevel = 0, blevelon = 0, bleveloff = 0, totalblevel = 0, y = 0, blevelperc = 100, ballastpump_count = 0; float blevelmls, tempA; int blevelint, ballastmode = 0, startTanklevel, finishTanklevel, dumpVolume = 20; //blevel - ballast tank level, long timePumpstart, totalPumptime; //pump - how many seconds has run for; int totalPumpseconds = 0; int heater_status = 0; long int ialt = 0; int n, requestsense = 1, loopcount = 0, cycle = 0; //Tx Stuff char txbuf[12]; struct t_mtab { char c, pat; } ; struct t_mtab morsetab[] = { {'.', 106}, {',', 115}, {'?', 76}, {'/', 41}, {'-', 97}, {'A', 6}, {'B', 17}, {'C', 21}, {'D', 9}, {'E', 2}, {'F', 20}, {'G', 11}, {'H', 16}, {'I', 4}, {'J', 30}, {'K', 13}, {'L', 18}, {'M', 7}, {'N', 5}, {'O', 15}, {'P', 22}, {'Q', 27}, {'R', 10}, {'S', 8}, {'T', 3}, {'U', 12}, {'V', 24}, {'W', 14}, {'X', 25}, {'Y', 29}, {'Z', 19}, {'1', 62}, {'2', 60}, {'3', 56}, {'4', 48}, {'5', 32}, {'6', 33}, {'7', 35}, {'8', 39}, {'9', 47}, {'0', 63} } ; #define N_MORSE (sizeof(morsetab)/sizeof(morsetab[0])) #define SPEED (20) #define DOTLEN (1200/SPEED) #define DASHLEN (3*(1200/SPEED)) void dash() { digitalWrite(ledPin, HIGH) ; digitalWrite(txPin, HIGH) ; delay(DASHLEN); digitalWrite(ledPin, LOW) ; digitalWrite(txPin, LOW) ; delay(DOTLEN) ; } void dit() { digitalWrite(ledPin, HIGH) ; digitalWrite(txPin, HIGH) ; delay(DOTLEN); digitalWrite(ledPin, LOW) ; digitalWrite(txPin, LOW) ; delay(DOTLEN); } void send(char c) { int i ; if (c == ' ') { Serial.print(c) ; delay(7*DOTLEN) ; return ; } for (i=0; i<N_MORSE; i++) { if (morsetab[i].c == c) { unsigned char p = morsetab[i].pat ; Serial.print(morsetab[i].c) ; while (p != 1) { if (p & 1) dash() ; else dit() ; p = p / 2 ; } delay(2*DOTLEN) ; return ; } } /* if we drop off the end, then we send a space */ Serial.print("?") ; } void sendmsg(char *str) { while (*str) send(*str++) ; Serial.println(""); } // *********************** // Functions // *********************** // function that executes whenever data is received from master // this function is registered as an event, see setup() void requestEvent() { digitalWrite(ledPin, HIGH); switch(requestsense) { case 1: Wire.send(temp0); break; case 2: Wire.send(temp1); break; case 3: Wire.send(temp2); break; case 4: Wire.send(temp3); break; case 5: Wire.send(totalPumpseconds); break; case 6: Wire.send(blevelperc); break; case 7: Wire.send(ballastmode); break; case 8: Wire.send(heater_status); break; case 9: Wire.send(light1); break; } digitalWrite(ledPin, LOW); } // ------------------------------- // function that executes whenever data is received from master // this function is registered as an event, see setup() void receiveEvent(int numBytes) { digitalWrite(ledPin, HIGH); while(1 < Wire.available()) // loop through all but the last { char c = Wire.receive(); // receive byte as a character Serial.print(c); // print the character } int requestint = Wire.receive(); // receive byte as an integer requestsense = requestint; Serial.print("Number of Bytes : "); Serial.println(numBytes); Serial.print("Requestsense : "); Serial.println(requestsense); if(requestsense == 12) { ballastmode = 1; } digitalWrite(ledPin, LOW); } // gets temperature data from onewire sensor network, need to supply byte address, it'll check to see what type of sensor and convert appropriately int getTempdata(byte sensorAddress[8]) { int HighByte, LowByte, TReading, SignBit, Tc_100, Whole; byte data[12], i, present = 0; ds.reset(); ds.select(sensorAddress); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(sensorAddress); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } LowByte = data[0]; HighByte = data[1]; TReading = (HighByte << 8) + LowByte; SignBit = TReading & 0x8000; // test most sig bit if (SignBit) // negative { TReading = (TReading ^ 0xffff) + 1; // 2's comp } if (sensorAddress[0] == 0x10) { Tc_100 = TReading * 50; // multiply by (100 * 0.0625) or 6.25 } else { Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 } Whole = Tc_100 / 100; // separate off the whole and fractional portions if (SignBit) // If its negative { Whole = Whole * -1; } return Whole; } void setup() { Wire.begin(2); // join i2c bus with address #2` Wire.onRequest(requestEvent); // register event Wire.onReceive(receiveEvent); // register event Serial.begin(4800); // start serial for output Serial.println("Starting..."); pinMode(ledPin, OUTPUT); pinMode(txPin, OUTPUT); pinMode(radioPin, OUTPUT); pinMode(ballastPin, OUTPUT); pinMode(ballastSensorLED, OUTPUT); digitalWrite(ledPin, HIGH); delay(2000); digitalWrite(ledPin,LOW); } void loop() { temp0 = getTempdata(address0); delay(100); temp1 = getTempdata(address1); delay(100); temp2 = getTempdata(address2); delay(100); temp3 = getTempdata(address3); Serial.print(temp0); Serial.print(","); Serial.print(temp1); Serial.print(","); Serial.print(temp2); Serial.print(","); Serial.print(temp3); //Photocell/ Photodiode External Light Reading photocellReading = analogRead(photocellPin); Serial.print(" Analog = "); Serial.print(photocellReading); // the raw analog reading light1 = photocellReading / 10; //Measure level of ballast tank using photodiode y = 0; while(y < 200) { digitalWrite(ballastSensorLED, HIGH); delay(1); blevelon = analogRead(ballastSensorPin); //Serial.println(blevelon); digitalWrite(ballastSensorLED, LOW); delay(1); bleveloff = analogRead(ballastSensorPin); blevel = blevelon - bleveloff; totalblevel = totalblevel + blevel; y++; } totalblevel = totalblevel / y; Serial.print(" B = "); Serial.print(totalblevel); // the raw analog reading //Convert to mls //blevelperc = ((-30.771742) * log(totalblevel)) + 212.773002; blevelmls = exp(((totalblevel - 212.77) / - 30.77)); Serial.print(" mls = "); blevelint = int(blevelmls); Serial.print(blevelint); //convert totalblevel into blevelperc tempA = blevelmls / 500; tempA = tempA * 100; blevelperc = int(tempA); Serial.print(" Perc = "); Serial.println(int(blevelperc)); //Controlling the Pump/Valve // ATLAS M tells S that we are floating (looks at ascent rate), after 30mins of float - tells S to dump 100mls of ballast // 4 modes - 1) new 2) mid ballast dump 3) nothing, if(ballastmode == 1) { Serial.print("Time to Start Ballast Drop"); startTanklevel = blevelperc; finishTanklevel = blevelperc - dumpVolume; Serial.print(startTanklevel); Serial.print(" "); Serial.print(finishTanklevel); digitalWrite(ballastPin, HIGH); timePumpstart = millis(); ballastmode = 2; } else if (ballastmode == 2) { totalPumptime = millis() - timePumpstart; //calculating how long the pump has been on for totalPumpseconds = totalPumptime / 5; if (blevelperc <= finishTanklevel) { //Stop pump digitalWrite(ballastPin, LOW); ballastmode = 0; } else { if (ballastpump_count == 5){ digitalWrite(ballastPin, LOW); ballastpump_count++; } else if (ballastpump_count >= 7) { digitalWrite(ballastPin, HIGH); ballastpump_count = 0; } else { ballastpump_count++; } } } else { Serial.println("Nothing to do"); //Do nothing } //Tx Stuff if(cycle >= 30) { digitalWrite(radioPin, HIGH); delay(100); cycle = 0; loopcount++; if (loopcount > 3) { loopcount = 0; } switch(loopcount) { case 1: itoa(temp0, txbuf, 10); sendmsg("VVV,ATLAS,1/3,HIGH,ALTITUDE,BALLOON,TEMP"); sendmsg(txbuf); break; case 2: itoa(blevelperc, txbuf, 10); sendmsg("VVV,ATLAS,2/3,RTTY,434.075,ASCII8,50,350,0,1.5,BALLAST"); sendmsg(txbuf); break; case 3: itoa(light1, txbuf, 10); sendmsg("VVV,ATLAS,3/3,WWW.SPACENEAR.US/TRACKER/,LDR"); sendmsg(txbuf); break; } digitalWrite(radioPin, LOW); } else { cycle++; } delay(5000); }