Good afternoon. I'm a graduate student working on building an autonomous system that measures gas components of a water column. We're utilizing arduinos due to their cost and the semi-disposable nature of these systems once they are deployed. I have written code to read in 2 serial sensors and 3 analog sensors as well as switch a FET and use a DS18B20 temp probe. Then I write the lines of data to an SD card in a .txt file. I'm looking for help in reducing code size, as I need to add in GSM/GPRS capability and I'm out of room. Right now I have a lot of Serial.print lines for troubleshooting on the benchtop, and I know that removing those will help. I also tried this originally with an Arduion Mega but was unable to get the GSM shield modem to work with it despite extensive troubleshooting with Robotshop (the vendor). Other help would be greatly appreciated! Thank you!!
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <Metro.h>
#include <SD.h>
#include <GSM.h>
#define pump A3
const int chipSelect = 10;
OneWire ds(4);
File dataFile;
SoftwareSerial co2Serial(19,18);
SoftwareSerial gpsSerial(9,8);
byte readCO2[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25}; //Command packet to read Co2 (see app note)
byte response[] = {0,0,0,0,0,0,0}; //create an array to store the response
//multiplier for value. default is 1. set to 3 for K-30 3% and 10 for K-33 ICB
int valMultiplier = 1;
char inChar;
int index;
String inData;
String gpsString;
int pumpstate = LOW;
int pumpcycle = 0;
Metro pumpMetro = Metro(250);
void setup(){
Serial.begin(9600);
pinMode(pump,OUTPUT);
digitalWrite(pump,pumpstate);
pinMode(10,OUTPUT);
analogReference(DEFAULT);
//initialize SD card and generate .txt file to store data
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
while (1) ;
}
Serial.println("card initialized.");
dataFile = SD.open("datalog.txt",FILE_WRITE);
}
void loop() {
delay(2000); //change to vary sampling frequency in milliseconds
if (pumpMetro.check() == 1){
if (pumpstate == LOW) {
pumpstate = HIGH;
pumpMetro.interval(5000);
pumpcycle ++;
}
else {
pumpMetro.interval(5000);
pumpstate = LOW;
}
digitalWrite (pump,pumpstate);
}
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr)) {
ds.reset_search();
delay(250);
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(750); // 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(addr);
ds.write(0xBE); // Read Scratchpad
for (i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
unsigned int raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
}
float wTemp = (float)raw / 16.0;
Serial.print(wTemp);
Serial.write(44);
co2Serial.begin(9600);
sendRequest(readCO2);
unsigned long trueCO2 = getValue(response);
Serial.print(trueCO2);
Serial.write(44);
co2Serial.end();
int rawstemp = analogRead (A1);
float stempmv = (rawstemp * (5.0 / 1023));
float iTemp = (((stempmv * 1000) - 500) / 100);
Serial.print(iTemp);
Serial.write(44);
int rawpressure = analogRead(A0);
float pressure = ((rawpressure * (5.0 / 1023.0)) * 125 + 572.75);
Serial.print(pressure);
Serial.write(44);
float rawcond = analogRead(A1);
float mv_cond = rawcond * (5.0 / 1023.0);
float inv_cond = (1 / mv_cond);
float lin_cond = (inv_cond * 18147) + 4968.6;
//float pow_cond = 25017 * (Pow(5,-0.664));
//float conductivity = (lin_cond + pow_cond) / 2;
float conductivity = lin_cond;
Serial.print(conductivity);
Serial.write(44);
Serial.print(mv_cond);
Serial.write(44);
gpsSerial.begin(4800);
gpsString = "";
index = 0;
inData = 0;
inChar = 0;
delay(800);
while(gpsSerial.available()>0) {
inChar = gpsSerial.read();
inData[index] = inChar;
index++;
gpsString += inChar;
if (inChar == 42){
//36 = $, 42 = *
index = 0;
Serial.println(gpsString);
} }
gpsSerial.end();
uint32_t m = millis();
dataFile.print(m);
dataFile.print(", ");
dataFile.print(wTemp);
dataFile.print(", ");
dataFile.print(trueCO2);
dataFile.print(", ");
dataFile.print(iTemp);
dataFile.print(", ");
dataFile.print(pressure);
dataFile.print(", ");
dataFile.print(conductivity);
dataFile.print(", ");
dataFile.print(mv_cond);
dataFile.print(", ");
dataFile.print(pumpstate);
dataFile.print(", ");
dataFile.print(gpsString);
dataFile.flush();
}
void sendRequest(byte packet[])
{
while(!co2Serial.available()) //keep sending request until we start to get a response
{
co2Serial.write(readCO2,7);
delay(50);
}
int timeout=0; //set a timeoute counter
while(co2Serial.available() < 7 ) //Wait to get a 7 byte response
{
timeout++;
if(timeout > 10) //if it takes to long there was probably an error
{
while(co2Serial.available()) //flush whatever we have
co2Serial.read();
break; //exit and try again
}
delay(50);
}
for (int i=0; i < 7; i++)
{
response[i] = co2Serial.read();
}
}
unsigned long getValue(byte packet[])
{
int high = packet[3]; //high byte for value is 4th byte in packet in the packet
int low = packet[4]; //low byte for value is 5th byte in the packet
unsigned long val = high*256 + low; //Combine high byte and low byte with this formula to get value
return val* valMultiplier;
}