#include <PID_Beta6.h> #include "TinyGPS_3.h" #include <stdio.h> #include <util/crc16.h> #include <OneWire.h> TinyGPS gps; OneWire ds(12); // DS18x20 Temperature chip i/o One-wire byte address0[8] = {0x28, 0x22, 0xF8, 0x2D, 0x2, 0x0, 0x0, 0xFC}; byte address1[8] = {0x28, 0x19, 0x7A, 0xC2, 0x2, 0x0, 0x0, 0x72}; byte address2[8] = {0x28, 0xC3, 0x41, 0xC2, 0x2, 0x0, 0x0, 0x8D}; int temp0 = 0, temp1 = 0, temp2 = 0, photo = 0; //PID Controller double Setpoint, Input, Output; PID myPID(&Input, &Output, &Setpoint,10,5,0); int iOutput = 0; int count = 0, nogps_count = 0, navstatus = 0; float flat, flon; unsigned long fix_age, date, time, chars, age; unsigned long milliseconds, old_milliseconds = 0; int hour = 0 , minute = 0 , second = 0; char latbuf[12] = "0", lonbuf[12] = "0"; long int ialt = 123; int numbersats = 99; //Misc int heater = 0; // ------------------------ // RTTY Functions - from RJHARRISON's AVR Code void rtty_txstring (char * string) { /* Simple function to sent a char at a time to ** rtty_txbyte function. ** NB Each char is one byte (8 Bits) */ char c; c = *string++; while ( c != '\0') { rtty_txbyte (c); c = *string++; } } void rtty_txbyte (char c) { /* Simple function to sent each bit of a char to ** rtty_txbit function. ** NB The bits are sent Least Significant Bit first ** ** All chars should be preceded with a 0 and ** proceded with a 1. 0 = Start bit; 1 = Stop bit ** ** ASCII_BIT = 7 or 8 for ASCII-7 / ASCII-8 */ int i; rtty_txbit (0); // Start bit // Send bits for for char LSB first for (i=0;i<8;i++) { if (c & 1) rtty_txbit(1); else rtty_txbit(0); c = c >> 1; } rtty_txbit (1); // Stop bit } void rtty_txbit (int bit) { if (bit) { // high digitalWrite(5, HIGH); digitalWrite(4, LOW); digitalWrite(13, LOW); //LED } else { // low digitalWrite(4, HIGH); digitalWrite(5, LOW); digitalWrite(13, HIGH); //LED } delayMicroseconds(20500); // 10000 = 100 BAUD 20150 } uint16_t gps_CRC16_checksum (char *string) { size_t i; uint16_t crc; uint8_t c; crc = 0xFFFF; // Calculate checksum ignoring the first two $s for (i = 2; i < strlen(string); i++) { c = string[i]; crc = _crc_xmodem_update (crc, c); } return crc; } void lightsensor() { int photocellPin = 0; // the cell and 10K pulldown are connected to a0 //Photocell/ Photodiode External Light Reading photo = analogRead(photocellPin); photo = photo / 10; } // 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 radiotemp() { //Measure temperature sensor and adjust heater. temp0 = getTempdata(address0); //Serial.println(temp0); if((temp0 < 50) && (temp0 > -50)) { Input = double(temp0); //Serial.println(Input); myPID.Compute(); analogWrite(10,Output); //Serial.println(Output); } } // Send a byte array of UBX protocol to the GPS void sendUBX(uint8_t *MSG, uint8_t len) { for(int i=0; i<len; i++) { Serial.print(MSG[i], BYTE); Serial.print(MSG[i], HEX); } Serial.println(); } void setup() { pinMode(13, OUTPUT); //LED digitalWrite(13, HIGH); pinMode(10, OUTPUT); //Heater transistor pinMode(5, OUTPUT); //Radio pinMode(6, OUTPUT); //Radio EN pinMode(4, OUTPUT); //Radio digitalWrite(6, HIGH); Serial.begin(9600); //Turning off all GPS NMEA strings apart on the uBlox module Serial.println("$PUBX,40,GLL,0,0,0,0*5C"); Serial.println("$PUBX,40,GGA,0,0,0,0*5A"); Serial.println("$PUBX,40,GSA,0,0,0,0*4E"); Serial.println("$PUBX,40,RMC,0,0,0,0*47"); Serial.println("$PUBX,40,GSV,0,0,0,0*59"); Serial.println("$PUBX,40,VTG,0,0,0,0*5E"); // Set the navigation mode (Airborne, 1G) //Serial.print("Setting uBlox nav mode: "); uint8_t setNav[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC}; sendUBX(setNav, sizeof(setNav)/sizeof(uint8_t)); Setpoint = 1; myPID.SetMode(AUTO); digitalWrite(13, LOW); } void loop() { milliseconds = millis(); if (milliseconds >= (old_milliseconds + 60000)) { char superbuffer [120]; char checksum [10]; int n; digitalWrite(6, HIGH); delay(3000); Serial.println("$PUBX,00*33"); while (Serial.available()) { int c = Serial.read(); if (gps.encode(c)) { //Get Data from GPS library //Get Time and split it gps.get_datetime(&date, &time, &age); hour = (time / 1000000); minute = ((time - (hour * 1000000)) / 10000); second = ((time - ((hour * 1000000) + (minute * 10000)))); second = second / 100; } } numbersats = gps.sats(); navstatus = gps.navstatus(); temp1 = getTempdata(address1); temp2 = getTempdata(address2); lightsensor(); //dtostrf(Output, 5, 2, outbuf); iOutput = int(Output); if (navstatus == 1) { digitalWrite(13, HIGH); //Get Position gps.f_get_position(&flat, &flon); dtostrf(flat, 7, 4, latbuf); dtostrf(flon, 7, 4, lonbuf); // +/- altitude in meters ialt = (gps.altitude() / 100); } else { digitalWrite(13, LOW); } n=sprintf (superbuffer, "$$ATLAS,%d,%02d:%02d:%02d,%s,%s,%ld,%d,%d,%d;%d;%d;%d;%d", count, hour, minute, second, latbuf, lonbuf, ialt, navstatus, numbersats, temp0, iOutput, temp1, temp2, photo); if (n > -1){ n = sprintf (superbuffer, "%s*%04X\n", superbuffer, gps_CRC16_checksum(superbuffer)); rtty_txstring("VVV"); rtty_txstring(superbuffer); delay(1000); rtty_txstring(superbuffer); } count++; old_milliseconds = milliseconds; digitalWrite(6, LOW); } digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); delay(500); radiotemp(); }