@slt1 Sure can.
/* Sender-10.ino ************************************ WATER LEVEL MONITOR
Consolidate the dual sleep model
Refine DoSoundings to handle wild exceptions
Start bringing back in sleep function
Debug nested do loop
Bring in HC-12 radio
Rationalise Lo/Hi Flow Detection
Tidy Up
Remove twice declare of sumsoundnew bug
Move loop operations to functions
Assemble output into single char packet
Introduce THERM
Switch off ADC when sleeping
*****************************************************/
const byte LOW_POWER_PIN = 5;
const byte TRIGGER = 7;
const byte ECHO = 8;
const byte THERM = 1;
#include <SoftwareSerial.h>
const int RxH = 3, TxH = 4;
SoftwareSerial HC12(RxH, TxH);
const int numsoundings = 10;
const int min_time = 1300, max_time = 15000;
int countPings = 0;
unsigned int cycleNum = 0;
const byte Td = 5;
long int duration[numsoundings] = {};
int Vo = 0;
// Set up for extended sleep when not much change in sounding
bool HiFlowDetected = true;
long int sumsoundold = 0, sumsoundnew = 0;
int sleepcycles = 0; //number of cycles to sleep
const float sumsoundTholdS = 100;
const float sumsoundTholdL = 509;
//*******************************************************************************S
// Debug
//int sleepcyclesS = 3;
//int sleepcyclesL = 3; //83 Secs for 10 cycles
//*******************************************************************************M
// Operational
int sleepcyclesS = 14;
int sleepcyclesL = 140; //83 Secs for 10 cycles
//int sleepSecsS = 148; //Used only in Receiver
//int sleepSecsL = 1480; //Used only in Receiver
//*******************************************************************************M
void setup() {
Serial.begin(9600);
HC12.begin(1200);
pinMode(LOW_POWER_PIN, OUTPUT);
pinMode(TRIGGER, OUTPUT);
pinMode(ECHO, INPUT);
Serial.println("< CycleNo, SumSound, HiFlowDet, countPings > Vo, dSum ***");
// Setup Watchdog Timer
WDTCSR = (24);
WDTCSR = (33); // 8 Seconds sleep
WDTCSR |= (1<<6);
// Disable ADC
// ADCSRA &= ~(1 << 7); // Comment out if analog port needed
// Enable SLEEP
SMCR |= (1 << 2); // power down mode
SMCR |= 1; // enable
}
//======================================
void loop() { //
digitalWrite(LOW_POWER_PIN, HIGH); //
delay(Td); //
countPings = 0; //
sumsoundnew = DoSoundings(); //
sleepMode(); //
ADCSRA |= (1 << 7); //
Vo = analogRead(THERM); //
ADCSRA &= ~(1 << 7); //
sendResults(); //
sumsoundold = sumsoundnew; //
cycleNum++; //
putToSleep(); //
} //
//======================================
long int DoSoundings(){
// Get required number of consistent soundings
// Read first sounding hoping its a candidate
const int durationERR = 300;
int TdSnd = 20;
bool skip = false;
long int sumsound = 0;
do{
int count = 0;
sumsound = 0;
skip = false;
duration[count] = aping(); // Sometimes needed to clear cobwebs?
delay(TdSnd);
byte j = 0;
byte m = 0;
duration[count] = aping();
delay(TdSnd);
sumsound += duration[count];
count++;
do{
duration[count] = aping();
delay(TdSnd);
if(abs(duration[count] - duration[count-1]) < durationERR){
// Sounding should be within 51.5 mm of previous
sumsound += duration[count];
count++;
}else{
m++;
if(m > 10){ // Should trap wildest exceptions
// Need to start again
m = 0;
skip = true;
}
}
}
while(count < numsoundings & !skip);
}
while(skip == true);
return sumsound;
}
//============
long int aping(){
countPings++;
digitalWrite(TRIGGER, LOW);
delayMicroseconds(2); // 2
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10); //10
digitalWrite(TRIGGER, LOW);
long int xx = pulseIn(ECHO, HIGH);
if(xx < min_time){
return min_time;
}else{
if(xx > max_time){
return max_time;
}else{
return xx;
}
}
}
//============
void sleepMode(){
// HiFlowDectected currently reveals status entering last sleep
if(HiFlowDetected){
if(abs(sumsoundnew - sumsoundold) < sumsoundTholdS){
Serial.print("A");
sleepcycles = sleepcyclesL;
HiFlowDetected = false;
}else{
Serial.print("B");
sleepcycles = sleepcyclesS;
}
}else{ // Previous cycle was long
if(abs(sumsoundnew - sumsoundold) < sumsoundTholdL){
Serial.print("C");
sleepcycles = sleepcyclesL;
}else{
Serial.print("D");
sleepcycles = sleepcyclesS;
HiFlowDetected = true;
}
}
}
//============
void sendResults(){
const int TdHome = 100; // Any less than 50 ms is unstable
// Even 60 might not be long enough - try 100 as test
char outstr[30] = {};
char buff[6];
//************* Package to cloud *******************S
itoa(cycleNum, buff, 10);
strcpy(outstr, buff);
strcat(outstr, ",");
ltoa(sumsoundnew, buff, 10);
strcat(outstr, buff);
strcat(outstr, ",");
itoa(HiFlowDetected, buff, 10);
strcat(outstr, buff);
strcat(outstr, ",");
itoa(countPings, buff, 10);
strcat(outstr, buff);
strcat(outstr, ",");
itoa(Vo, buff, 10);
strcat(outstr, buff);
Serial.print(outstr);
HC12.print("XY"); // Clear the cobwebs
delay(TdHome);
HC12.print("YZ"); // Clear the cobwebs
delay(TdHome);
HC12.print("<");
delay(TdHome);
HC12.print(outstr);
delay(TdHome);
HC12.print(">");
delay(TdHome);
//**************************************************F
Serial.print("<");
Serial.print(outstr);
Serial.print("> ");
Serial.print(Vo);
Serial.print(", ");
delay(Td);
Serial.println(sumsoundnew - sumsoundold);
}
//============
void putToSleep(){
digitalWrite(LOW_POWER_PIN, LOW); // Power Down MOSFET
delay(500); // May need to increase if no sleep
// Stop current leakage from floating pins in to HC12 (ryanm)
digitalWrite(RxH, LOW);
digitalWrite(TxH, LOW);
//delay(150); // May need to increase if sleep truncated
delay(500); // Debug - See if HC12 printing is dependent
// Put 328P to sleep - T=8 gives cycle time = 74 secs
sleepLoop(sleepcycles);
}
//============
void sleepLoop(int loopNum){ // as per Keith Darrah
// Sleep duration = 8 * loopNum seconds
for(int i=0; i<loopNum; i++){
// BOD Disable
MCUCR |= (3 << 5);
MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6);
__asm__ __volatile__("sleep"); // go to sleep
}
}
//============
ISR(WDT_vect){ // support watchdog timer
}