Hieronder de huidige code van mijn BMS met een paar aanpassingen.
- twee regels toegevoegd om de rollover van millis() te tackelen (nog niet getest)
- ik heb een hysterese ingebouwd voor de kachel, maar volgens mij de verkeerde kant op ...
in onderstaande code is dus de - en + gewisseld t.o.v. de code zoals die nu draait. (zie sub kachel_aan)
// include the GSM library
#include <GSM.h>;
#include <dht.h>;
#include <TinyGPS++.h>
#define dataPin_t1 8 //voor de temperatuur sensor
//#define dataPin_t2 9 //voor de temperatuur sensor
#define PINNUMBER "6495"
// APN information obrained from your network provider
#define GPRS_APN "internet" // replace with your GPRS APN
#define GPRS_LOGIN "KPN" // replace with your GPRS login
#define GPRS_PASSWORD "gprs" // replace with your GPRS password
dht DHT;
TinyGPSPlus gps;
GSM gsmAccess(false); // include a 'true' parameter for debug enabled
GSM_SMS sms;
GSMClient client;
GPRS gprs;
int readData;
float t1; float t1_min; float t1_max; boolean t1_min_alarm = false; boolean t1_max_alarm = false; boolean t1_alarm = false;
float h1; float h1_min; float h1_max; boolean h1_min_alarm = false; boolean h1_max_alarm = false; boolean h1_alarm = false;
//float t2; float t2_min; float t2_max; boolean t2_min_alarm = false; boolean t2_max_alarm = false; boolean t2_alarm = false;
//float h2; float h2_min; float h2_max; boolean h2_min_alarm = false; boolean h2_max_alarm = false; boolean h2_alarm = false;
boolean log_aan = true;
boolean alarm_aan = true;
boolean request_alarm = true;
char remoteNumber[20];
String toegestaan_nummer[] = {"+316", "+316"};
int aantal_nummers = 2;
char c;
String bericht;
String item;
String waarde_item;
char server[] = ""; // the base URL
char path[] = "; // the path
int port = 80; // the port, 80 for HTTP
String waarde = "";
unsigned long previousMillis = 0;
unsigned long interval = 600000;
int analogInput_3 = A3;
int value_3 = 0;
float vout_3= 0.0;
int analogInput_1 = A4;
float vout_1 = 0.0;
float vin_1 = 0.0; float vin_1_min; float vin_1_max; boolean vin_1_min_alarm = false; boolean vin_1_max_alarm = false; boolean vin_1_alarm = false;
float R1_1 = 30000;//29970.0;
float R2_1 = 7500;//7520.0;
int value_1 = 0;
const int RunningAverageCount = 10;
boolean RunningAvarageReady = false;
float RunningAverageBuffer_1[RunningAverageCount];
int NextRunningAverage_1;
int analogInput_2 = A5;
float vout_2 = 0.0;
float vin_2 = 0.0; float vin_2_min; float vin_2_max; boolean vin_2_min_alarm = false; boolean vin_2_max_alarm = false; boolean vin_2_alarm = false;
float R1_2 = 30000.0;
float R2_2 = 7500;//7510.0;
int value_2 = 0;
float RunningAverageBuffer_2[RunningAverageCount];
int NextRunningAverage_2;
long valueAvarage = 0;
int MeasurementsToAverage = 100;
int relay_kachel = 12;
boolean kachel = false;
float t_kachel = 5.0;
boolean kachel_aan = false;
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0) ;
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
pinMode(A1, OUTPUT);
digitalWrite(A1, LOW);
pinMode(A2, OUTPUT);
digitalWrite(A2, LOW);
pinMode(A3, OUTPUT);
digitalWrite(A3, LOW);
pinMode(A6, OUTPUT);
digitalWrite(A6, LOW);
pinMode(A7, OUTPUT);
digitalWrite(A7, LOW);
pinMode(A8, OUTPUT);
digitalWrite(A8, LOW);
pinMode(A9, OUTPUT);
digitalWrite(A9, LOW);
pinMode(A10, OUTPUT);
digitalWrite(A10, LOW);
pinMode(A11, OUTPUT);
digitalWrite(A11, LOW);
pinMode(A12, OUTPUT);
digitalWrite(A12, LOW);
pinMode(A13, OUTPUT);
digitalWrite(A13, LOW);
pinMode(A14, OUTPUT);
digitalWrite(A14, LOW);
pinMode(A15, OUTPUT);
digitalWrite(A15, LOW);
for (int i = 14; i <= 53; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
//Serial.begin(9600);
//Serial.println("Starting Arduino web client.");
Serial1.begin(9600);
pinMode(analogInput_1, INPUT);
pinMode(analogInput_2, INPUT);
pinMode(analogInput_3, INPUT);
pinMode(relay_kachel, OUTPUT);
digitalWrite(relay_kachel, HIGH);
// connection state
connect_to_network();
}
void connect_to_network()
{
boolean notConnected = true;
// Start GSM shield
// pass the PIN of your SIM as a parameter of gsmAccess.begin()
while(notConnected)
{
if((gsmAccess.begin(PINNUMBER, true)==GSM_READY) &
(gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)){
notConnected = false;
//Serial.println("Connected to network");
}
else
{
//Serial.println("Not connected");
delay(1000);
}
}
//Serial.println("GSM connected");
//zend_data();
}
void zend_data()
{
//Serialprintln("connecting...http");
// if you get a connection, report back via serial:
if (client.connect(server, port))
{
//Serial.println("http connected");
// Make a HTTP request:
client.print("GET ");
client.print(path);
client.print(waarde);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Connection: close");
client.println();
//client.stop();
}
else
{
// if you didn't get a connection to the server:
//Serial.println("http connection failed");
connect_to_network();
zend_data();
}
}
void loop(){
//Serial.println(request_alarm);
if(client.available()){
lees_http();
}
readData = DHT.read22(dataPin_t1);
t1 = DHT.temperature;
h1 = DHT.humidity;
//readData = DHT.read22(dataPin_t2);
//t2 = DHT.temperature;
//h2 = DHT.humidity;
lees_spanning();
unsigned long currentMillis = millis();
if(currentMillis < previousMillis){previousMillis = currentMillis;} //toegevoegd ivm millis() rollover
if (sms.available()){
lees_sms();
}
else{
if (currentMillis +8000 < millis()) {
//Serial.println(millis() - currentMillis);
//Serial.println("sms connect");
connect_to_network();
}
}
if(log_aan && RunningAvarageReady){
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
//lees_gps();
waarde = "id=";
waarde.concat("&T1=");
waarde.concat(t1);
waarde.concat("&H1=");
waarde.concat(h1);
//waarde.concat("&T2=");
//waarde.concat(t2);
//waarde.concat("&H2=");
//waarde.concat(h2);
waarde.concat("&V1=");
waarde.concat(vin_1);
waarde.concat("&V2=");
waarde.concat(vin_2);
waarde.concat("&R1=");
waarde.concat(kachel_aan);
waarde.concat("&POS=");
waarde.concat(String(gps.location.lat(), 7));
waarde.concat(",");
waarde.concat(String(gps.location.lng(), 7));
if(request_alarm){
waarde.concat("&RA=TRUE"); //RA = request alarm settings
}
zend_data();
}
}
lees_gps();
//Serial.print(gps.location.lat(), 6);
//Serial.print(", ");
//Serial.println(gps.location.lng(), 6);
//Serial.println(gps.location.isValid());
//Serial.print(gps.satellites.value());
//Serial.print(", ");
//Serial.println(gps.satellites.isValid());
if(RunningAvarageReady && alarm_aan){
if(t1_min_alarm && t1_min > t1 && !(t1_alarm)){alarm("Low Temperature Alarm T1", t1);t1_alarm = true;}
if(t1_max_alarm && t1_max < t1 && !(t1_alarm)){alarm("High Temperature Alarm T1", t1);t1_alarm = true;}
if(t1_alarm && (t1_min < t1 || !(t1_min_alarm)) && (t1_max > t1 || !(t1_max_alarm))){t1_alarm = false;}
//if(t2_min_alarm && t2_min > t2 && !(t2_alarm)){alarm("Low Temperature Alarm T2", t2);t2_alarm = true;}
//if(t2_max_alarm && t2_max < t2 && !(t2_alarm)){alarm("High Temperature Alarm T2", t2);t2_alarm = true;}
//if(t2_alarm && (t2_min < t2 || !(t2_min_alarm)) && (t2_max > t2 || !(t2_max_alarm))){t2_alarm = false;}
if(h1_min_alarm && h1_min > h1 && !(h1_alarm)){alarm("Low Humidity Alarm H1", h1);h1_alarm = true;}
if(h1_max_alarm && h1_max < h1 && !(h1_alarm)){alarm("High Humidity Alarm H1", h1);h1_alarm = true;}
if(h1_alarm && (h1_min < h1 || !(h1_min_alarm)) && (h1_max > h1 || !(h1_max_alarm))){h1_alarm = false;}
//if(h2_min_alarm && h2_min > h1 && !(h2_alarm)){alarm("Low Humidity Alarm H2", h2);h2_alarm = true;}
//if(h2_max_alarm && h2_max < h1 && !(h2_alarm)){alarm("High Humidity Alarm H2", h2);h2_alarm = true;}
//if(h2_alarm && (h2_min < h2 || !(h2_min_alarm)) && (h2_max > h2 || !(h2_max_alarm))){h2_alarm = false;}
if(vin_1_min_alarm && vin_1_min > vin_1 && !(vin_1_alarm)){alarm("Under Voltage Alarm V1", vin_1);vin_1_alarm = true;}
if(vin_1_max_alarm && vin_1_max < vin_1 && !(vin_1_alarm)){alarm("Over Voltage Alarm V1", vin_1);vin_1_alarm = true;}
if(vin_1_alarm && (vin_1_min < vin_1 || !(vin_1_min_alarm)) && (vin_1_max > vin_1 || !(vin_1_max_alarm))){vin_1_alarm = false;}
if(vin_2_min_alarm && vin_2_min > vin_2 && !(vin_2_alarm)){alarm("Under Voltage Alarm V2", vin_2);vin_2_alarm = true;}
if(vin_2_max_alarm && vin_2_max < vin_2 && !(vin_2_alarm)){alarm("Over Voltage Alarm V2", vin_2);vin_2_alarm = true;}
if(vin_2_alarm && (vin_2_min < vin_2 || !(vin_2_min_alarm)) && (vin_2_max > vin_2 || !(vin_2_max_alarm))){vin_2_alarm = false;}
}
delay(5000);
bedien_kachel();
}
void bedien_kachel(){
if(kachel){
if((t1 + 0.25) < t_kachel){
kachel_aan = true;
//Serial.println("kachel aan");
}
if((t1 - 0.25) > t_kachel){
kachel_aan = false;
//Serial.println("kachel uit");
}
}
else{
kachel_aan = false;
//Serial.println("kachel uit");
}
if(kachel_aan){
digitalWrite(relay_kachel, LOW);
}
else{
digitalWrite(relay_kachel, HIGH);
}
}
void lees_spanning(){
//Serial.print("referentie spanning : ");
float vccValue=readVcc()/1000.0;
//Serial.println(vccValue);
value_3 = analogRead(analogInput_3);
vout_3 = vccValue - ((value_3 * vccValue *2) / 1023.0);
//Serial.print("Nul spanning : ");
//Serial.println(vout_3);
valueAvarage = 0;
for(int i=0;i<MeasurementsToAverage;i++){
value_1 = analogRead(analogInput_1);
valueAvarage += value_1;
delay(10);
}
value_1 = (valueAvarage / MeasurementsToAverage);//*1.0131;//1.0131;
vout_1 = (value_1 * vccValue) / 1023.0;
vin_1 = (vout_1 / (R2_1/(R1_1+R2_1))) + vout_3;
RunningAverageBuffer_1[NextRunningAverage_1++] = vin_1;
if(NextRunningAverage_1 >= RunningAverageCount){
NextRunningAverage_1 =0;
RunningAvarageReady = true;
}
float RunningAverageVoltage = 0;
for(int i=0;i<RunningAverageCount;i++){
RunningAverageVoltage += RunningAverageBuffer_1[i];
}
vin_1 = (RunningAverageVoltage / RunningAverageCount)-0.32;
//Serial.print("V1 : ");
//Serial.println(vin_1);
valueAvarage = 0;
for(int i=0;i<MeasurementsToAverage;i++){
value_2 = analogRead(analogInput_2);
valueAvarage += value_2;
delay(10);
}
value_2 = (valueAvarage / MeasurementsToAverage);// *1.0131;//1.0131;
vout_2 = (value_2 * vccValue) / 1023.0;
vin_2 = (vout_2 / (R2_2/(R1_2+R2_2))) + vout_3;
RunningAverageBuffer_2[NextRunningAverage_2++] = vin_2;
if(NextRunningAverage_2 >= RunningAverageCount){
NextRunningAverage_2 =0;
}
RunningAverageVoltage = 0;
for(int i=0;i<RunningAverageCount;i++){
RunningAverageVoltage += RunningAverageBuffer_2[i];
}
vin_2 = (RunningAverageVoltage / RunningAverageCount)-0.32;
//Serial.print("V2 : ");
//Serial.println(vin_2);
}
void alarm(String tekst, float waarde){
for (int dit_nummer = 0; dit_nummer < aantal_nummers; dit_nummer++) {
toegestaan_nummer[dit_nummer].toCharArray(remoteNumber, 20);
sms.beginSMS(remoteNumber);
sms.println(tekst);
sms.println(waarde);
sms.endSMS();
}
}
void lees_gps(){
unsigned long start = millis();
do
{
while (Serial1.available())
gps.encode(Serial1.read());
} while ((millis() - start < 1000) && (millis() > start)); //&& (millis() > start) toegevoegd ivm millis() rollover
}
void lees_http(){
bericht = "";
while(c=client.read()){
//Serial.print(c);
bericht.concat(c);
if(c=='!'){
bericht = "";
}
if(c=='#'){
item = bericht.substring(0,bericht.length()-1);
bericht = "";
}
if(c=='*'){
request_alarm = false;
waarde_item = bericht.substring(0,bericht.length()-1);
bericht = "";
//Serial.print(item);
//Serial.print(" - ");
//Serial.println(waarde_item);
if(item == "V1_min"){
vin_1_min = waarde_item.toFloat();
}
if(item == "V1_max"){
vin_1_max = waarde_item.toFloat();
}
if(item == "V1_min_alarm"){
vin_1_alarm = false;
if(waarde_item == "true"){
vin_1_min_alarm = true;
}
else{
vin_1_min_alarm = false;
}
}
if(item == "V1_max_alarm"){
vin_1_alarm = false;
if(waarde_item == "true"){
vin_1_max_alarm = true;
}
else{
vin_1_max_alarm = false;
}
}
if(item == "V2_min"){
vin_2_min = waarde_item.toFloat();
}
if(item == "V2_max"){
vin_2_max = waarde_item.toFloat();
}
if(item == "V2_min_alarm"){
vin_2_alarm = false;
if(waarde_item == "true"){
vin_2_min_alarm = true;
}
else{
vin_2_min_alarm = false;
}
}
if(item == "V2_max_alarm"){
vin_2_alarm = false;
if(waarde_item == "true"){
vin_2_max_alarm = true;
}
else{
vin_2_max_alarm = false;
}
}
if(item == "T1_min"){
t1_min = waarde_item.toFloat();
}
if(item == "T1_max"){
t1_max = waarde_item.toFloat();
}
if(item == "T1_min_alarm"){
t1_alarm = false;
if(waarde_item == "true"){
t1_min_alarm = true;
}
else{
t1_min_alarm = false;
}
}
if(item == "T1_max_alarm"){
t1_alarm = false;
if(waarde_item == "true"){
t1_max_alarm = true;
}
else{
t1_max_alarm = false;
}
}
//if(item == "T2_min"){
// t2_min = waarde_item.toFloat();
//}
//if(item == "T2_max"){
// t2_max = waarde_item.toFloat();
//}
//if(item == "T2_min_alarm"){
// t2_alarm = false;
// if(waarde_item == "true"){
// t2_min_alarm = true;
// }
// else{
// t2_min_alarm = false;
// }
//}
//if(item == "T2_max_alarm"){
// t2_alarm = false;
// if(waarde_item == "true"){
// t2_max_alarm = true;
// }
// else{
// t2_max_alarm = false;
// }
//}
if(item == "H1_min"){
h1_min = waarde_item.toFloat();
}
if(item == "H1_max"){
h1_max = waarde_item.toFloat();
}
if(item == "H1_min_alarm"){
h1_alarm = false;
if(waarde_item == "true"){
h1_min_alarm = true;
}
else{
h1_min_alarm = false;
}
}
if(item == "H1_max_alarm"){
h1_alarm = false;
if(waarde_item == "true"){
h1_max_alarm = true;
}
else{
h1_max_alarm = false;
}
}
//if(item == "H2_min"){
// h2_min = waarde_item.toFloat();
//}
//if(item == "H2_max"){
// h2_max = waarde_item.toFloat();
//}
//if(item == "H2_min_alarm"){
// h2_alarm = false;
// if(waarde_item == "true"){
// h2_min_alarm = true;
// }
// else{
// h2_min_alarm = false;
// }
//}
//if(item == "H2_max_alarm"){
// h2_alarm = false;
// if(waarde_item == "true"){
// h2_max_alarm = true;
// }
// else{
// h2_max_alarm = false;
// }
//}
}
}
//Serial.println(bericht);
client.stop();
}
void lees_sms(){
//Serial.println("Message received from:");
sms.remoteNumber(remoteNumber, 20);
//Serial.println(remoteNumber);
boolean toegestaan = false;
for (int dit_nummer = 0; dit_nummer < aantal_nummers; dit_nummer++) {
//Serial.println(toegestaan_nummer[dit_nummer]);
if(toegestaan_nummer[dit_nummer] == remoteNumber){
toegestaan = true;
//Serial.println("toegestaan");
}
}
if(toegestaan){
bericht = "";
while(c=sms.read()){
bericht.concat(c);
}
bericht.toUpperCase();
//Serial.println(bericht);
//Serial.println(bericht.substring(0,3));
//Serial.println(bericht.substring(4,7));
if(bericht.substring(0,3) == "LOG"){
//Serial.println("LOG");
if(bericht.substring(4,7) == "AAN"){
//Serial.print("LOG AAN");
log_aan = true;
}
if(bericht.substring(4,7) == "UIT"){
//Serial.print("LOG UIT");
log_aan = false;
}
}
if(bericht.substring(0,5) == "ALARM"){
if(bericht.substring(6,9) == "AAN"){
alarm_aan = true;
}
if(bericht.substring(6,9) == "UIT"){
alarm_aan = false;
}
}
if(bericht.substring(0,4) == "INFO"){
schrijf_sms();
}
if(bericht.substring(0,8) == "INTERVAL"){
interval = (bericht.substring(9).toInt())*60000;
}
if(bericht.substring(0,6) == "KACHEL"){
if(bericht.substring(7,10) == "AAN"){
kachel = true;
}
if(bericht.substring(7,10) == "UIT"){
kachel = false;
}
}
if(bericht.substring(0,4) == "TEMP"){
t_kachel = bericht.substring(5).toFloat();
}
}
sms.flush();
}
void schrijf_sms(){
sms.beginSMS(remoteNumber);
sms.print("Log function :");
sms.println(log_aan);
sms.print("Alarm function :");
sms.println(alarm_aan);
sms.print("Heater function :");
sms.println(kachel);
sms.print("Kachel SP. :");
sms.println(t_kachel);
sms.print("V1 :");
sms.print(vin_1);
if(vin_1_min_alarm){
sms.print(" -: ");
sms.print(vin_1_min);
}
if(vin_1_max_alarm){
sms.print(" +: ");
sms.print(vin_1_max);
}
sms.println();
sms.print("V2 :");
sms.print(vin_2);
if(vin_2_min_alarm){
sms.print(" -: ");
sms.print(vin_2_min);
}
if(vin_2_max_alarm){
sms.print(" +: ");
sms.print(vin_2_max);
}
sms.println();
sms.print("T1 :");
sms.print(t1);
if(t1_min_alarm){
sms.print(" -: ");
sms.print(t1_min);
}
if(t1_max_alarm){
sms.print(" +: ");
sms.print(t1_max);
}
sms.println();
sms.print("H1 :");
sms.print(h1);
if(h1_min_alarm){
sms.print(" -: ");
sms.print(h1_min);
}
if(h1_max_alarm){
sms.print(" +: ");
sms.print(h1_max);
}
sms.println();
//sms.print("T2 :");
//sms.print(t2);
//if(t2_min_alarm){
// sms.print(" -: ");
// sms.print(t2_min);
//}
//if(t2_max_alarm){
// sms.print(" +: ");
// sms.print(t2_max);
//}
//sms.println();
//sms.print("H2 :");
//sms.print(h2);
//if(h2_min_alarm){
// sms.print(" -: ");
// sms.print(h2_min);
//}
//if(h2_max_alarm){
// sms.print(" +: ");
// sms.print(h2_max);
//}
sms.println();
if(gps.location.isValid()){
sms.print("http://maps.google.com/maps?f=q&q=(");
sms.print(gps.location.lat(), 7);
sms.print(",");
sms.print(gps.location.lng(), 7);
sms.println(")");
}
else{
sms.println("NO FIX");
}
sms.print("interval :");
sms.println(interval/60000);
sms.endSMS();
}