I cleaned up the code and got rid of the String class but I still get the same problem: when I press the button again to send a second tweet, the code starts to run but gets hung up in the sendNTPpacket() method at the Udp.endPacket(); statement.
new code:
#include <SPI.h> // needed in Arduino 0019 or later
#include <Ethernet.h>
#include <Twitter.h>
#include <EthernetUdp.h>
#include <stdlib.h>
// The includion of EthernetDNS is not needed in Arduino IDE 1.0 or later.
// Please uncomment below in Arduino IDE 0022 or earlier.
//#include <EthernetDNS.h>
#define LED_red 5 // the pin for the red LED
#define LED_grn 6 // the pin for the green LED
#define BUTTON 7 // input pin of the pushbutton
int btn_val = 0; // stores the state of the input pin
int shop_status = 0; // 0 = We're currently CLOSED
// 1 = We're currently OPEN
// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// If you don't specify the IP address, DHCP is used(only in Arduino 1.0 or later).
// byte ip[] = { 192, 168, 2, 250 };
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("you-shall-not-pass");
// Messages to post
char msgOpen[] = "We're open"; // 11 chars
char msgClosed[] = "We're closed"; // 13 chars
char tweet[141]; // The tweet to send
char timestamp[8];
// ************************************************************
void setup()
{
pinMode(LED_red, OUTPUT); // tell Arduino LED_red is an output
pinMode(LED_grn, OUTPUT); // tell Arduino LED_grn is an output
pinMode(BUTTON, INPUT); // tell Arduino BUTTON is an input
Serial.begin(9600);
Ethernet.begin(mac);
Udp.begin(localPort);
}
// ************************************************************
void loop()
{
delay(1000);
Serial.print("Ready! btn_val: ");
btn_val = digitalRead(BUTTON); // read input value and store it fresh
Serial.println(btn_val);
// check if button has been pressed
if ((btn_val == HIGH)) {
if (shop_status == 0) { // we were closed but now we're OPENING
Serial.print("shop_status: ");
Serial.println(shop_status);
Serial.println("We're closed. Time to OPEN!");
Serial.println("");
strcpy(tweet, msgOpen);
} else { // else shop_status == 1, which means we were open but now we're CLOSING
Serial.print("shop_status: ");
Serial.println(shop_status);
Serial.println("We're open. Time to CLOSE!");
Serial.println("");
strcpy(tweet, msgClosed);
}
boolean gotTime = getTime(); // returns TRUE if timestamp was created successfully
if (gotTime) { // == 1, then the timestamp was created successfully
strcat(tweet, " as of ");
strcat(tweet, timestamp);
} // ELSE returned 0, send tweet w/o timestamp
strcat(tweet, "!");
sendTweet(tweet);
Serial.print("Tweet successfully sent: ");
Serial.println(tweet);
// shop_status = 1 - shop_status;
if (shop_status){ // == 1, then we're now OPEN
digitalWrite(LED_grn, HIGH); // Turn green LED on
digitalWrite(LED_red, LOW); // Turn red LED off
} else { // == 0, then we're now CLOSED
digitalWrite(LED_grn, LOW); // Turn green LED off
digitalWrite(LED_red, HIGH); // Turn red LED on
}
delay(60000); // one minute required by website
}
}
// ************************************************************
boolean getTime() {
Serial.println("getTime() begins!");
Serial.println("");
int hour = 0;
int timezone = -7; // AZ timezone is UTC-7.
Serial.println("Moving to sendNTPpacket()!");
Serial.println("");
sendNTPpacket(timeServer); // send an NTP packet to a time server
Serial.println("Back to getTime()!");
// wait to see if a reply is available
delay(1000);
if ( Udp.parsePacket() ) {
// We've received a packet, read the data from it
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
int hour24 = ((epoch % 86400L) / 3600) + timezone; // print the hour (86400 equals secs per day).
if (hour24 < 0)
hour24 += 24;
if (hour24 == 0)
hour = 12;
else if (hour24 <= 12)
hour = hour24;
else
hour = hour24 - 12;
int minute = (epoch % 3600) / 60;
// build the timestamp
char hourStr [3];
char minStr [3];
itoa(hour, hourStr, 10);
itoa(minute, minStr, 10);
strcpy(timestamp, hourStr);
if (minute < 10)
strcat(timestamp, ":0");
else
strcat(timestamp, ":");
strcat(timestamp, minStr);
if (hour24 < 12)
strcat(timestamp, "am");
else
strcat(timestamp, "pm");
}
Serial.print("Current time: ");
Serial.println(timestamp);
return 1; // add return 0;
}
// ************************************************************
void sendTweet(char* msg) { // change to boolean
Serial.println("sendTweet() begins!");
if (Ethernet.begin(mac) == 0) { //move this
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for(;;) // BAD!
Serial.println("infinite loop!");
}
Serial.println("connecting ...");
if (twitter.post(msg)) {
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait(&Serial);
if (status == 200) {
Serial.println("OK.");
} else {
Serial.print("failed : code ");
Serial.println(status);
}
} else {
Serial.println("connection failed.");
}
Serial.println("sendTweet() ENDING!");
Serial.println("");
}
// ************************************************************
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
Serial.println("sendNTPpacket() begins!");
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
Serial.println("memset set!");
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
Serial.println("adding to packetBuffer!");
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Serial.println("packetBuffer set!");
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Serial.println("beginPacket set!");
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Serial.println("write set!");
Serial.print("NTP_PACKET_SIZE: ");
Serial.println(NTP_PACKET_SIZE);
Udp.endPacket(); // << Code hangs here when I try to send a second tweet
Serial.println("packet ended!");
Serial.println("sendNTPpacket() ENDING!");
Serial.println("");
}