Skip to content

Instantly share code, notes, and snippets.

@dwblair
Created October 27, 2015 14:20
Show Gist options
  • Save dwblair/234712e27e72bc57e37f to your computer and use it in GitHub Desktop.
Save dwblair/234712e27e72bc57e37f to your computer and use it in GitHub Desktop.
#include "Surata_FONA.h"
#include <JeeLib.h>
// sparkfun stuff ------
char idChar [] = "2"; //the sensor id
#define sleepMinutes 0
//
char publicKey[]="EJx6zObavztLJ01MldxE";
char privateKey[]= "dqv42Py602TaMke47DWJ";
//thermistor stuff -----------------------
#define THERMISTORPIN A0
// resistance at 25 degrees C
#define THERMISTORNOMINAL 10000
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 10000
int samples[NUMSAMPLES];
//fona stuff -----------------------------------
#define DEBUG 0
#define FONA_RX 2
#define FONA_TX 9
#define FONA_RST 4
#define FONA_KEY 8
#define FONA_POWER_STATUS A1
#define failCountMax 5
ISR(WDT_vect) { Sleepy::watchdogEvent(); }
// this is a large buffer for replies
char replybuffer[255];
char sendBuffer[220];
// This is to handle the absence of software serial on platforms
// like the Arduino Due. Modify this code if you are using different
// hardware serial port, or if you are using a non-avr platform
// that supports software serial.
#ifdef __AVR__
#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
#else
HardwareSerial *fonaSerial = &Serial1;
#endif
// Use this for FONA 800 and 808s
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
// Use this one for FONA 3G
//Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);
//const String sendString="AT+HTTPPARA=\"URL\",\"http://data.sparkfun.com/input/5JxOrVZzl7HG6QL0pXav?private_key=7BxD1lMdWmFWdbD0V8gX&test=";
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
uint8_t type;
float rando;
//conductivity stuff
long pulseCount = 0; //a pulse counter variable
unsigned long pulseTime,lastTime, duration, totalDuration;
int samplingPeriod=3; // the number of seconds to measure 555 oscillations
int interruptPin = 1; //corresponds to D2
void setup() {
//blink
pinMode(13, OUTPUT);
pinMode(FONA_POWER_STATUS,INPUT);
pinMode(FONA_KEY, OUTPUT);
// make sure the FONA power cycling key is initially pulled 'high' -- i.e. not triggered
digitalWrite(FONA_KEY, HIGH); //go back to non-trigger
if (DEBUG) {
while (!Serial);
Serial.begin(115200);
//Serial.println(F("FONA basic test"));
//Serial.println(F("Initializing....(May take 3 seconds)"));
}
}
void loop() {
if (DEBUG) Serial.println("measurements ...");
// measurements ----------------------------
// conductivity --------------------------------------
pulseCount=0; //reset the pulse counter
totalDuration=0; //reset the totalDuration of all pulses measured
attachInterrupt(interruptPin,onPulse,RISING); //attach an interrupt counter to interrupt pin 1 (digital pin #3) -- the only other possible pin on the 328p is interrupt pin #0 (digital pin #2)
pulseTime=micros(); // start the stopwatch
delay(samplingPeriod*1000); //give ourselves samplingPeriod seconds to make this measurement, during which the "onPulse" function will count up all the pulses, and sum the total time they took as 'totalDuration'
detachInterrupt(interruptPin); //we've finished sampling, so detach the interrupt function -- don't count any more pulses
float freqHertz;
if (pulseCount>0) { //use this logic in case something went wrong
double durationS=(totalDuration/double(pulseCount))/1000000.; //the total duration, in seconds, per pulse (note that totalDuration was in microseconds)
freqHertz=1./durationS;
}
else {
freqHertz=0.;
}
if (DEBUG) {
Serial.print("Conduct=");
Serial.println(freqHertz);
}
// temp -------------------------
uint8_t i;
float average;
// take N samples in a row, with a slight delay
for (i=0; i< NUMSAMPLES; i++) {
samples[i] = analogRead(THERMISTORPIN);
delay(10);
}
// average all the samples out
average = 0;
for (i=0; i< NUMSAMPLES; i++) {
average += samples[i];
}
average /= NUMSAMPLES;
// convert the value to resistance
average = 1023 / average - 1;
average = SERIESRESISTOR / average;
//Serial.print("Thermistor resistance ");
//Serial.println(average);
float steinhart;
steinhart = average / THERMISTORNOMINAL; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
steinhart = 1.0 / steinhart; // Invert
steinhart -= 273.15; // convert to C
if (DEBUG) Serial.println("temp (C) =");
if (DEBUG) Serial.println(steinhart);
// fona ---------------------------------------
if (DEBUG) Serial.println("Fona ...");
power_up_fona();
int fonaStatus=initialize_fona();
if (!fonaStatus) {
if (DEBUG) Serial.println("FONA not found");
power_down_fona();
if (!DEBUG) go_to_sleep_minutes(sleepMinutes);
if(DEBUG) delay(60000);
}
else{
int networkStatus=fona_find_network();
if ((networkStatus!=1)&&(networkStatus!=5)) {
if (DEBUG) Serial.println("Couldn't find network in failCountMax tries. Aborting.");
}
if (((networkStatus==1)||(networkStatus==5))&&fonaStatus) { //then we're good to send a message!
if (DEBUG) Serial.println("POSTING ...");
/*
for (int j=0;j<5;j++) {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(500); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(500);
}
*/
fona.sendCheckReply(F("AT"), F("OK"));
delay(100);
fona.sendCheckReply(F("AT+SAPBR=3,1,\"APN\",\"internet.comcel.com.co\""), F("OK"));
delay(100);
fona.sendCheckReply(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""), F("OK"));
delay(100);
fona.sendCheckReply(F("AT+SAPBR=1,1"),F("OK"));
delay(100);
fona.sendCheckReply(F("AT+CMGF=1"), F("OK"));
delay(5000);
fona.sendCheckReply(F("AT+CGATT=1"), F("OK"));
delay(5000);
if (DEBUG) Serial.println("getting location ...");
uint16_t returncode;
char gpsbuffer[120];
fona.getGSMLoc(&returncode,gpsbuffer,120);
if (DEBUG) {
Serial.print("gpsstring=");
Serial.println(gpsbuffer);
}
char *latChar = strtok(gpsbuffer, ",");
char *lonChar = strtok(NULL,",");
// lat = atof(latp);
// lon = atof(lonp);
char *dateChar = strtok(NULL,",");
char *timeChar = strtok(NULL,",");
if (DEBUG) {
Serial.print("date=");
Serial.println(dateChar);
Serial.print("time=");
Serial.println(timeChar);
Serial.print("lat=");
Serial.println(latChar);
Serial.print("lon=");
Serial.println(lonChar);
Serial.println("got location.");
}
// get battery level
uint16_t battLevel;
fona.getBattVoltage(&battLevel);
if (DEBUG) {Serial.print("batteryMV="); Serial.println(battLevel);}
// Post to Sparkfun
fona.sendCheckReply(F("AT+SAPBR=3,1,\"APN\",\"internet.comcel.com.co\""), F("OK"));
delay(100);
fona.sendCheckReply(F("AT+SAPBR=1,1"),F("OK"));
delay(10000);
fona.sendCheckReply(F("AT+CMGF=0"), F("OK"));
delay(2000);
fona.sendCheckReply(F("AT+HTTPTERM"), F("OK"));
delay(5000);
fona.sendCheckReply(F("AT+HTTPINIT"), F("OK"));
delay(10000);
fona.sendCheckReply(F("AT+HTTPPARA=\"CID\",1"), F("OK"));
delay(10000);
char tempChar[6];
dtostrf(steinhart, 3, 2, tempChar);
char conductChar[6];
dtostrf(freqHertz,3,2,conductChar);
char battChar[6];
dtostrf(battLevel,3,2,battChar);
sprintf(sendBuffer, "AT+HTTPPARA=\"URL\",\"http://data.sparkfun.com/input/%s?private_key=%s&temp=%s&conduct=%s&id=%s&lat=%s&lon=%s&batt=%s&fonadate=%s&fonatime=%s\"",publicKey,privateKey,tempChar,conductChar,idChar,latChar,lonChar,battChar,dateChar,timeChar);
if (DEBUG) Serial.println("size in bytes=");
if (DEBUG) Serial.println(sizeof(sendBuffer));
fona.sendCheckReply(sendBuffer,"OK");
//fona.sendCheckReply("AT+HTTPPARA=\"URL\",\"http://requestb.in/19vv0hj1\"","OK");
//fona.sendCheckReply("AT+HTTPPARA=\"URL\",\"http://data.sparkfun.com/input/5JxOrVZzl7HG6QL0pXav?private_key=7BxD1lMdWmFWdbD0V8gX&temp=20.3\"","OK");
delay(2000);
fona.sendCheckReply(F("AT+HTTPDATA=0,1000"), F("OK"));
delay(1000);
boolean success;
success = fona.sendCheckReply(F("AT+HTTPACTION=1"), F("OK"));
delay(10000);
//if(success) fona.sendCheckReply(F("AT+HTTPTERM"), F("OK")); else {Serial.println("waiting..."); delay(1000);}
fona.sendCheckReply(F("AT+HTTPTERM"), F("OK"));
delay(5000);
fona.sendCheckReply(F("AT+SAPBR=0,1"), F("OK"));
delay(10000);
}
else{
if (DEBUG) Serial.println("Failed to connect.");
if (!DEBUG) go_to_sleep_minutes(sleepMinutes);
if(DEBUG) delay(60000);
}
power_down_fona();
if (!DEBUG) go_to_sleep_minutes(sleepMinutes);
// go_to_sleep_seconds(60);
if(DEBUG) delay(60000);
}
}
void power_up_fona() {
int fonaPower=digitalRead(FONA_POWER_STATUS);
if (!fonaPower) { // off, so power up
digitalWrite(FONA_KEY, HIGH); //go back to non-trigger
digitalWrite(FONA_KEY, LOW); //turn on the SMS subcircuit
delay(2000); //so now it's on
digitalWrite(FONA_KEY, HIGH); //go back to non-trigger
}
else {
// error! was already on for some reason -- do nothing
}
}
int initialize_fona() {
int fonaStatus;
fonaSerial->begin(4800);
if (! fona.begin(*fonaSerial)) {
// things are bad -- couldn't find FONA
fonaStatus=0;
}
else {
//things are good -- FONA OK
fonaStatus=1;
}
return fonaStatus;
}
int fona_find_network() {
uint8_t n = fona.getNetworkStatus();
int avail = fona.available();
int registerCountDelaySeconds=10;
int registerWaitTotalSeconds=0;
int failCount=0;
while ((n!=1)&&(n!=5)&&(failCount<failCountMax)) {
if(DEBUG) Serial.print(F("Network status "));
if(DEBUG) Serial.println(n);
n = fona.getNetworkStatus();
//avail = fona.available();
registerWaitTotalSeconds+=registerCountDelaySeconds;
delay(registerCountDelaySeconds*1000);
failCount=failCount+1;
}
if(DEBUG) Serial.print("Network registration time=");
if(DEBUG) Serial.println(registerWaitTotalSeconds);
return n;
}
void power_down_fona() {
int fonaPower=digitalRead(FONA_POWER_STATUS);
if (fonaPower) { // on, so power down
digitalWrite(FONA_KEY, HIGH); //go back to non-trigger
digitalWrite(FONA_KEY, LOW); //turn on the SMS subcircuit
delay(2000); //so now it's on
digitalWrite(FONA_KEY, HIGH); //go back to non-trigger
}
else {
// error! was already off for some reason -- do nothing
}
}
void go_to_sleep_minutes(int minutes) {
int LOG_INTERVAL_BASE = 60000; // 1 sec
for (int k=0;k<minutes;k++) {
Sleepy::loseSomeTime(LOG_INTERVAL_BASE); //-- will interfere with serial, so don't use when debugging
}
}
void go_to_sleep_seconds(int seconds) {
int LOG_INTERVAL_BASE = 1000; // 1 sec
for (int k=0;k<seconds;k++) {
Sleepy::loseSomeTime(LOG_INTERVAL_BASE); //-- will interfere with serial, so don't use when debugging
}
}
void onPulse()
{
pulseCount++;
//Serial.print("pulsecount=");
//Serial.println(pulseCount);
lastTime = pulseTime;
pulseTime = micros();
duration=pulseTime-lastTime;
totalDuration+=duration;
//Serial.println(totalDuration);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment