This is the code i have on my Nano 328 where the buttons are connected:
#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <PubSubClient.h>
/**************************************************************
* Connections *
**************************************************************/
#define ONE_WIRE_BUS 5 // oneWire pin is D5
#define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty
// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {14, 15, 16, 17, 18, 19}; // the analog 0-5 pins are also known as 14-19
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'currently pressed'
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
/**************************************************************
* Ethernet Settings *
**************************************************************/
// Ethernet Card Mac Address
byte mac[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
// IPv4 address
byte ip[] = {192, 168, 0, 132};
// Subnet mask
byte subnet[] = {255, 255, 255, 0};
// Default gateway
byte gateway[] = {192, 168, 0, 1};
// MQTT Server
byte server[] = { 192, 168, 0, 1 };
// Preferred DNS sever
// byte dns[] = {192, 168, 0, 1};
void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
}
// Fire up our PubSub client
EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);
/**************************************************************
* Setup *
**************************************************************/
void setup()
{
byte i;
byte dsAddress[8];
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println( "Searching for DS18B20..." );
oneWire.reset_search(); // Start the search with the first device
if( !oneWire.search(dsAddress) )
{
Serial.println( "none found. Using default MAC address." );
} else {
Serial.println( "success. Setting MAC address:" );
Serial.print( " DS18B20 ROM =" );
for( i = 0; i < 8; i++)
{
Serial.write(' ');
Serial.print( dsAddress[i], HEX );
}
Serial.println();
// Offset array to skip DS18B20 family code, and skip mac[0]
mac[1] = dsAddress[3];
mac[2] = dsAddress[4];
mac[3] = dsAddress[5];
mac[4] = dsAddress[6];
mac[5] = dsAddress[7];
}
Serial.print( " Ethernet MAC =" );
for( i = 0; i < 6; i++ )
{
Serial.write( ' ' );
Serial.print( mac[i], HEX );
}
Serial.println();
Ethernet.begin(mac, ip, subnet, gateway);
Serial.print(" IPv4 address: ");
Serial.println(Ethernet.localIP());
// Start up the Dallas Temperature library
sensors.begin(); // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement
// Connect to MQTT Broker, give it Bath-O-Matic as the name
if (client.connect("Bath-O-Matic")) {
// Publish a message to the status topic
client.publish("status","Bath-O-Matic is now online");
}
// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT);
digitalWrite(buttons[i], HIGH);
}
// Run timer2 interrupt every 15 ms
TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1<<TOIE2;
}
SIGNAL(TIMER2_OVF_vect) {
check_switches();
}
void check_switches()
{
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
static long lasttime;
byte index;
if (millis() < lasttime) {
// we wrapped around, lets just try again
lasttime = millis();
}
if ((lasttime + DEBOUNCE) > millis()) {
// not enough time has passed to debounce
return;
}
// ok we have waited DEBOUNCE milliseconds, lets reset the timer
lasttime = millis();
for (index = 0; index < NUMBUTTONS; index++) {
currentstate[index] = digitalRead(buttons[index]); // read the button
/*
Serial.print(index, DEC);
Serial.print(": cstate=");
Serial.print(currentstate[index], DEC);
Serial.print(", pstate=");
Serial.print(previousstate[index], DEC);
Serial.print(", press=");
*/
if (currentstate[index] == previousstate[index]) {
if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
// just pressed
justpressed[index] = 1;
}
else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
// just released
justreleased[index] = 1;
}
pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
}
//Serial.println(pressed[index], DEC);
previousstate[index] = currentstate[index]; // keep a running tally of the buttons
}
}
void loop() {
for (byte i = 0; i < NUMBUTTONS; i++) {
if (justreleased[0]) {
justreleased[0] = 0;
client.publish("foo/shower","1"); // Turn off Shower Light
}
}
}
At the moment the DS18B20's are just to set unique MAC addresses.
On my Windows 2012 Server i have Mosquitto running.
I think the code on the Mega is ok cause i can turn the light on and off many times with PHP
without problems:
<?php
require("phpMQTT.php");
$mqtt = new phpMQTT();
/* broker(broker address, broker port, client id); */
$mqtt->broker("192.168.0.1", 1883, "PHP MQTT Client");
$mqtt->connect();
/* publish( topic, message, qos); */
$mqtt->publish("foo/shower","0",0);
$mqtt->close();
?>