|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #1 on: January 07, 2013, 05:00:15 am » |
First thing i don't get is how i can trigger something with the code (for example turn on an LED). In loop, there is a call to check_switches(). After that is a loop that shows the state of each of the switches. In the appropriate if block, add the code you want. And the second thing i don't understand is that interrupts are used on all the pins in the second example. What don't you understand? The switches don't trigger the interrupt. The clock does.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #2 on: January 10, 2013, 09:28:34 pm » |
so in if (justreleased[i]) i have to replace the "i" with the button number. This works. But my code gets send to many times. As long as i press the button if i use "pressed". So how to make sure it gets send just one time? The switches don't trigger the interrupt. The clock does. So this interrupt has nothing to do with the Arduino hardware interrupts that i have only on some pins like 2 and 3?
|
|
|
|
|
Logged
|
|
|
|
|
East Anglia (UK)
Online
Edison Member
Karma: 46
Posts: 1380
May all of your blinks be without delay
|
 |
« Reply #3 on: January 11, 2013, 03:23:52 am » |
As long as i press the button if i use "pressed". So how to make sure it gets send just one time?
Check justreleased instead of pressed. It will tell you that the button has been released and will not be true again until the button is pressed and released again. Or check the value of justpressed to find out if the button has just been pressed and may or may not have been released. Which way you do it depends on whether you want something to happen when a button is pressed or when it is released.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #4 on: January 11, 2013, 08:31:08 am » |
So this interrupt has nothing to do with the Arduino hardware interrupts that i have only on some pins like 2 and 3? Correct.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #5 on: February 05, 2013, 09:14:44 am » |
Hm, I'm unsure how where i have to replace the "i" with the button number. if (justreleased[i]) { justreleased[i] = 0; // remember, check_switches() will CLEAR the 'just pressed' flag } It works a view times and then it stops working. And how do i make it that the light goes on when i press and send my code just one time? But here is the whole thing: I want to switch the light from one Arduino on another Arduino via MQTT over my windows server. This is the code that i have on my Mega 2560 where the light is 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 showerPin 6 // Shower Light is D6
// 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, 131}; // 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};
/************************************************************** * MQTT * **************************************************************/ EthernetClient ethClient; PubSubClient client(server, 1883, callback, ethClient);
void callback(char* topic, byte* payload, unsigned int length) { Serial.print("New message from broker on topic:"); Serial.println(topic);
Serial.print("Payload:"); Serial.write(payload, length); if (strcmp(topic,"foo/shower")==0) { if (payload[0] == '0') { digitalWrite(showerPin, LOW); // Turn off Shower Light } else if (payload[0] == '1') { digitalWrite(showerPin, HIGH); // Turn on Shower Light } } }
/************************************************************** * 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 Switch-O-Matic as the name if (client.connect("Switch-O-Matic")) { // Publish a message to the status topic client.publish("status","Switch-O-Matic is now online"); // Listen for messages on the control topic client.subscribe("foo/#"); }
pinMode(showerPin, OUTPUT); digitalWrite(showerPin, LOW); } void loop() { client.loop(); }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #6 on: February 05, 2013, 09:15:05 am » |
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(); ?>
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #7 on: February 07, 2013, 02:58:09 pm » |
I have the code now on an Mega and set: byte buttons[] = {54, 55, 56, 57, 58, 59}; But it's the same. It works and after some time stops working (also without doing anything). In the command prompt on my windows server i receive nothing when it stops working. If it works i see: Client mosqsub/4868-SIREN received PUBLISH (d0, q0, r0, m0, 'foo/shower', ... (1 bytes)) 0 if Mosquitto is started with "mosquitto_sub -d -t foo/#" in the command prompt.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #8 on: February 07, 2013, 06:15:38 pm » |
I have the code now on an Mega and set: What exactly does buttons represent? Not pin numbers, since those are not valid pin numbers for a Mega.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #9 on: February 07, 2013, 07:32:11 pm » |
In Ladyada's code it's: // 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 So for the Mega i thought it's "54, 55, 56, 57, 58, 59". And looks like this is correct cause the button (A0) works.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #10 on: February 07, 2013, 07:50:30 pm » |
Sorry. I read the page for the Mega, and saw 54 digital pins. For some reason, I forgot about the analog pins.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #11 on: February 07, 2013, 09:04:44 pm » |
Is there a way to debug this stuff to find out why it stops working after some time?
|
|
|
|
|
Logged
|
|
|
|
|
East Anglia (UK)
Online
Edison Member
Karma: 46
Posts: 1380
May all of your blinks be without delay
|
 |
« Reply #12 on: February 08, 2013, 02:04:43 am » |
Just about the only way is to put Serial.println()s in your code so that you can follow the flow of the program and the value of variables
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #13 on: February 08, 2013, 02:36:54 pm » |
Ok, it must be the button naming. Can somebody tell me where i have to change the "i" to a button number: if (justreleased[i]) { justreleased[i] = 0; Serial.print(i, DEC); Serial.println(" Just released"); client.publish("foo/shower","0"); // Turn off Shower Light } I don't get it. And maybe how to make it work with "just pressed" and sending the code just one time.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #14 on: February 08, 2013, 05:33:33 pm » |
Can somebody tell me where i have to change the "i" to a button number: In the square brackets. And maybe how to make it work with "just pressed" and sending the code just one time. If you are having problems with that happening, perhaps you need a sketch that illustrates JUST that problem. I fail to see how all that code dealing with the ethernet class, etc. is related to your problem with the switches.
|
|
|
|
|
Logged
|
|
|
|
|
|