Skip to content

Instantly share code, notes, and snippets.

@nilrog
Last active January 4, 2016 17:59
Show Gist options
  • Save nilrog/990536d313e6c9db1fe9 to your computer and use it in GitHub Desktop.
Save nilrog/990536d313e6c9db1fe9 to your computer and use it in GitHub Desktop.
// 2014-01-21 <roger@nilrogsplace.se> http://opensource.org/licenses/mit-license.php
// This is for ENC28J60
#include <UIPEthernet.h>
// This is for W5x00
//#include <Ethernet.h>
//#include <SPI.h>
#include <elapsedMillis.h> // http://playground.arduino.cc/Code/ElapsedMillis
#include <TimerOne.h> // http://www.pjrc.com/teensy/arduino_libraries/TimerOne.zip
// change these settings to match your own setup
char emonCMS_host[] = "emoncms.org";
char emonCMS_apikey[] = "7371f6db7cb1846f62909305503ffd6b";
char emonCMS_node[] = "13";
uint16_t remote_port = 80;
// ethernet interface mac address, must be unique on the LAN
byte mymac[] = { 0x4e, 0x61, 0x6e, 0x6f, 0x30, 0x33 };
EthernetClient client;
elapsedMillis timeout = 0;
elapsedMillis lastPostTime = 0;
elapsedMillis totalElapsedTime = 0;
volatile uint32_t pulseCount = 0;
/**
* All available application states handled by the loop()
*/
#define STATE_NONE 0 // No state has been set. Illegal.
#define STATE_NEED_TO_POST_UPDATE 1
#define STATE_POSTING_UPDATE 2
#define STATE_NOCONNECTION 3 // Everything is ready, waiting to post new value.
/**
* The current state the application is in
*/
volatile static uint8_t app_state = STATE_NOCONNECTION;
volatile static uint8_t last_known_app_state = STATE_NONE;
/**
* Flags related to the application state. Generally, the application state
* will transition when one of these flags changes state.
*/
struct app_flags_t
{
uint8_t time_to_post:1;
};
/**
* The current state of the application flags
*/
volatile static app_flags_t app_flags = { 0 };
// Timer1 interrupt handler
void readyToPost(void)
{
static int timerCount = 0;
// post every 30 sec (timer is 6 sec)
if (timerCount % 5 == 0) {
app_flags.time_to_post = 1;
}
timerCount++;
}
void disconnect(void)
{
Serial.println(F("\n"));
Serial.print(totalElapsedTime);
Serial.println(F(": <<< Disconnecting!"));
Serial.flush();
client.stop();
app_state = STATE_NOCONNECTION;
}
void setup(void)
{
// start serial console
Serial.begin(115200);
Serial.println(F("\n[UIPClientTest]"));
Serial.println();
// start ethernet interface
Ethernet.begin(mymac);
Serial.print(F("IP: "));
Serial.println(Ethernet.localIP());
Serial.print(F("GW: "));
Serial.println(Ethernet.gatewayIP());
Serial.print(F("DNS: "));
Serial.println(Ethernet.dnsServerIP());
Serial.println();
Serial.println(F("\n"));
Serial.print(totalElapsedTime);
Serial.println(F(": Setting up timer..."));
Serial.flush();
//Timer1.initialize(6000000); // 6s
//Timer1.attachInterrupt(readyToPost);
lastPostTime = 0;
totalElapsedTime = 0;
}
void loop(void)
{
static boolean lastConnected = false; // state of the connection last time through the main loop
uint16_t ret;
if (app_state != last_known_app_state) {
Serial.print(millis());
Serial.print(F(": State = "));
switch (app_state) {
case STATE_NEED_TO_POST_UPDATE:
Serial.println(F("STATE_NEED_TO_POST_UPDATE"));
break;
case STATE_POSTING_UPDATE:
Serial.println(F("STATE_POSTING_UPDATE"));
break;
case STATE_NOCONNECTION:
Serial.println(F("STATE_NOCONNECTION"));
break;
}
Serial.flush();
last_known_app_state = app_state;
}
Ethernet.maintain();
// application state-machine
switch (app_state) {
case STATE_NEED_TO_POST_UPDATE:
Serial.print(F("\n"));
Serial.print(totalElapsedTime);
Serial.println(F(": Posting update..."));
Serial.flush();
if (client.connected()) {
Serial.print(F("\n"));
Serial.print(totalElapsedTime);
Serial.println(F(": Client still connected! #1"));
Serial.flush();
}
ret = client.connect(emonCMS_host, remote_port);
if (ret > 0) {
Serial.println(F(">>> Making HTTP request..."));
client.print(F("PUT "));
client.print(F("/input/post.json?node="));
client.print(emonCMS_node);
client.print(F("&apikey="));
client.print(emonCMS_apikey);
client.print(F("&json="));
client.print(F("{\""));
client.print(F("pulse"));
client.print(F("\":\""));
client.print(pulseCount);
client.print(F("\"}"));
client.println(F(" HTTP/1.1"));
client.print(F("HOST: "));
client.println(emonCMS_host);
client.println(F("Connection: close"));
client.println();
// NOTE: Increment counter just for testing purposes...
pulseCount++;
Serial.println(F("<<< Waiting..."));
Serial.flush();
timeout = 0;
lastPostTime = 0;
app_state = STATE_POSTING_UPDATE;
} else {
// if you couldn't make a connection:
Serial.print(F("Connection failed ("));
Serial.print(ret);
Serial.println(F(")..."));
disconnect();
}
break;
case STATE_POSTING_UPDATE:
// read response
if (client.connected()) {
while (client.available()) {
char c = client.read();
Serial.print(c);
// stop if it takes more than 10 secs to read response
if (timeout > 10000) {
Serial.println(F("Timeout #1"));
//cli();
//app_flags.time_to_post = 0;
//sei();
disconnect();
break;
}
}
}
// stop if it has taken more than 10 seconds and we are not connected
if (timeout > 10000) {
Serial.println(F("Timeout #2"));
//cli();
//app_flags.time_to_post = 0;
//sei();
disconnect();
}
Serial.flush();
break;
case STATE_NOCONNECTION:
if (lastPostTime >= 30000) {
if (client.connected()) {
Serial.print(F("\n"));
Serial.print(totalElapsedTime);
Serial.println(F(": Client still connected! #2"));
Serial.flush();
}
app_state = STATE_NEED_TO_POST_UPDATE;
//cli();
//app_flags.time_to_post = 0;
//sei();
}
break;
}
// if there's no net connection, but there was one last time through the loop, then stop the client:
if (!client.connected() && lastConnected) {
disconnect();
}
// store the state of the connection for next time through the loop
lastConnected = client.connected();
delay(50);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment