/*
Zonmon datalogger example with 4 channels
Is using Arduino ethernet board, prototype board and a Tiny85
Reads 3 x ºC channels (DS18B20) with 12 bits resolution, 1 pulscounters-on/off detection
This example code is in the public domain. (v1.0.0 1-3-2013)
*/
#include <SoftwareSerial.h>
#include <TimerOne.h>
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB5, 0x64 };
// you can use a url or a IP address;
//IPAddress ServerIP(213,125,106,123);
int port=80;
char ServerName[] = "www.zonmon.com";
// Initialize the Ethernet client library
EthernetClient client;
// Pin 9 has a LED (L9) connected on Arduino ethernet boards.
// L9 will flash slowly when connected to the host can be made, fast when no connection to the host can be made.
// When connection to host is not possible (no internet or host down), the software will try reconnecting till connection is possible again
// pin 3, is the input from the Tiny85 rs232 inverted output and is used for reading the data from the Tiny85
// pin 2 is used to activate the Tiny85 to send the sensor data
int led = 9;
int select_Tiny = 2; // the select port for the tiny85
int rx=3; // rs232 receive port for Tiny85 data
int tx=99; // non existing port, we do not need to transmit over the rs232 port to the Tiny85
int flow=2; // 1=flowswitch 2=flowcounter
int looptime=60; // 60 seconds for zonmon, other intervals will result in wrong calculated yields!
int ethernetFlag = 0;
int SecCounter = 0;
int mSecCounter=0;
String I1 = "";
String tmp = "";
char c;
//Each device should have it's own zonmon id number, compile your own number from the MAC of the ethernet board, starting with ARDN-.... (see byte mac[] =...)
String ZonMonSerial = "ARDN-90A2-DA0D-8E3D";
SoftwareSerial mySerial(rx, tx, true); // RX, TX, inverted output from Tiny85 (compatible for PC)
// the setup routine runs once when you press reset:
void setup() {
// Open serial communications
Serial.begin(9600);
mySerial.begin(9600);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("NET failed");
ethernetFlag=0;
}
else{
ethernetFlag=1;
Serial.println("Net started with DHCP");
}
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
// set SELECT inactive to Tiny (high=unselect)
pinMode(select_Tiny,OUTPUT);
digitalWrite(select_Tiny,HIGH);
Timer1.initialize(1000); // 1 msecond
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
SecCounter=looptime; // start sending
}
// the loop routine runs forever:
void loop() {
//Serial.println(SecCounter);
if (mSecCounter >= 1000){
SecCounter +=1;
mSecCounter=0;
// Toggle LED
digitalWrite( led, digitalRead( led ) ^ 1 );
}
if (SecCounter >= looptime){ // should be 60 seconds between transmissions to zonmon.com
if (ethernetFlag==0){
if (Ethernet.begin(mac) != 0) {
Serial.println("NET Recovered");
ethernetFlag=1;
}
else{
Serial.println("NET failed");
}
}
SecCounter = 0;
I1= ReadTiny();
// strip crlf from string
I1.replace("\n","");
I1.replace("\r","");
// select flow counter or flow switch for channel p4
//c=0001 flow switch
//c=0002 flow counter
if (flow == 1){
I1.replace("p4","p99"); // move p4 out of the range of used channels
I1.replace("p5","p4"); // set p5 on channel p4
I1 += "&c=0001";
}
if (flow==2){
I1.replace("p5","p99"); // move p5 out of the range of used channels
I1 += "&c=0002";
}
I1 += "&p5=0"; // p5 is not used here, safe to mark it with 0 value
Serial.println(I1);
//if (client.connect(ServerIP, port)) {
if (client.connect(ServerName, port)) {
Serial.println("connected");
ethernetFlag=1;
//Make the HTTP request to zonmon.com to deliver the data:
client.print("GET ");
client.print("/pushdata.aspx");
client.print("?id=");
client.print(ZonMonSerial);
client.print("&");
client.print(I1);
client.print(" HTTP/1.0\r\n\r\n");
client.stop();
Serial.println("send");
Serial.println("");
}
else {
Serial.println("No connection");
ethernetFlag=0;
}
}
}
void timerIsr()
{
mSecCounter +=1;
if (ethernetFlag==0){
if (mSecCounter >= 200){
SecCounter +=1;
mSecCounter=0;
digitalWrite( led, digitalRead( led ) ^ 1 );
}
}
}
String ReadTiny(){
tmp="";
digitalWrite(select_Tiny,LOW); // active SELECT pin (low) to get data from Tiny
delay(20);
digitalWrite(select_Tiny,HIGH); // min 10 ms, 20 ms should do for the select to activate transmission of channels
// transmission from Tiny to host takes about 50 ms at 9600 bps
// there is a 10 ms debounce delay on the tiny SELECT input
// to make sure we do not loose a pulse count on the pulse input when a tiny is transmitting
// the minumum pulse length for the pulsecounter should therefore be 50 ms + 2 x 10 msec == 70 ms.
// 100 msec pulse like SO output of kWh counters should be safe, a switch contact like a flow meter will allways be long enough.
delay(100); // to make sure all data has arrived from tiny to host.
while (mySerial.available()){ // read available characters in serial buffer
c = mySerial.read();
if(c!=10){ //eol
tmp = tmp + c;
}
}
if(c==10){ // last value should be LF
tmp = tmp + c;
while (mySerial.available()){ // sync
mySerial.read();
}
return tmp;
}
else{
while (mySerial.available()){ // sync
mySerial.read();
}
return String("ERROR=NO_LF");
}
}