#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);
}
 
missions/ballasthalo/flight3/secondary_code.txt · Last modified: 2009/12/17 23:49 by jamescoxon
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki