twitter sketch posts only once

I am trying to create a tank monitoring system that twitters one of three levels of a tank. I can usually get the sketch to twiter once, and then not again. The twitter.status value returns 200, however. this means that twitter received each message, however they are not displayed. Heres my code:

//INCLUDE LIBRARIES
#include <Client.h>
#include <Server.h>
#include <Ethernet.h>
#include <Twitter.h>

//ETHERNET INITIALIZATON
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 20 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 0, 0 };

//TWITTER INITIALIZATION
Twitter twitter("usernAME:password");
char msg[] = "/Meh/";

//LEVEL SENSoRS
const int levellow =  3;
const int levelhigh =  2;
 
//STORE SENSOR STATES
int lowState = 0;
int medState = 0;
int highState = 0;
  
int lastActiveState = 0; // Keep track of the active state
 
void setup()
  {
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);
 
  pinMode(levellow, INPUT); 
  pinMode(levelhigh, INPUT);
 
  
  Serial.println("Welcome.  SmartHome1144 initializing...");
  char msg[] = "Welcome.  SmartHome1144 initializing...";  
  Tweet;
  delay(5000);
  }
 
void loop()
  {
  // CHECK STATES
  lowState = digitalRead(levellow);
  medState = digitalRead(levellow);
  highState = digitalRead(levelhigh);
   /**********
   *  Each of the following conditionals only sends one Serial message
   *  per state
   **********/
 
  //Water is dangerously high
  if ((highState == HIGH) & (lowState == HIGH))
    {
     //check if last active state was not very high(3) 
    if(lastActiveState != 3)
      {
      Serial.println("Water level is very high.  Immediate attention needed!");
      char msg[] = ("Water level is very high.  Immediate attention needed!");
      lastActiveState = 3;
      Tweet();
      }
    } 
  
 //Water is high
  if ((medState == HIGH) & (highState == LOW))
    {
   //check if last active state was not high(2) 
    if(lastActiveState != 2)
      {
      Serial.println("Water level is high.");
      char msg[] = ("Water level is high");
      lastActiveState = 2;
      Tweet();
      }
    }
    
//Water is normal
  if ((lowState == LOW) & (highState == LOW))
    {
  //check if last active state was not normal(1)    
    if(lastActiveState != 1)
      {
      Serial.println("Water level has returned to normal.");
      char msg[] = ("Water level has returned to normal.");
      lastActiveState = 1;
      Tweet();
      } 
    }
  delay(5000);
  }
  
  void Tweet()
  {
    Serial.println("connecting ...");
      if (twitter.post(msg))
      {
      int status = twitter.wait();
      if (status == 200)
        {
        Serial.print("OK. -");
        Serial.println(status);
        }
        else
          {
          Serial.print("failed : code ");
          Serial.println(status);
          }
        }
        else
        {
        Serial.println("connection failed.");
        }
}

Thanks for looking!

Narrow down the problem. Are you sure that your tweets are sent out? If they are then the problem is in the "tweeting" code on your machine and not the arduino code

Sorry if I wasn't clear before that I'm using an ethernet shield to connect to the internet and the arduino to run it. Basically, I copied the arduino twitter sketch and wrote my program around it. All i'm trying to do is change the message and then tweet it. It WILL tweet once, and then seem to get stuck. I think I may need to add .stop or .flush after the first message has been sent, however, every iteration I try causes a compiler error. Thanks.

Does this work any better...

//INCLUDE LIBRARIES
#include <Client.h>
#include <Server.h>
#include <Ethernet.h>
#include <Twitter.h>

//ETHERNET INITIALIZATON
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 20 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 0, 0 };

//TWITTER INITIALIZATION
Twitter twitter("usernAME:password");
/*rmv
char msg[] = "/Meh/"; */

//LEVEL SENSoRS
const int levellow =  3;
const int levelhigh =  2;

//STORE SENSOR STATES
int lowState = 0;
int medState = 0;
int highState = 0;

int lastActiveState = 0; // Keep track of the active state

void setup()
  {
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);

  pinMode(levellow, INPUT);
  pinMode(levelhigh, INPUT);


  Serial.println("Welcome.  SmartHome1144 initializing...");
/*rmv  
  char msg[] = "Welcome.  SmartHome1144 initializing..."; */
  Tweet( "Welcome.  SmartHome1144 initializing..." );
  delay(5000);
  }

void loop()
  {
  // CHECK STATES
  lowState = digitalRead(levellow);
  medState = digitalRead(levellow);
  highState = digitalRead(levelhigh);
   /**********
   *  Each of the following conditionals only sends one Serial message
   *  per state
   **********/

  //Water is dangerously high
  if ((highState == HIGH) & (lowState == HIGH))
    {
     //check if last active state was not very high(3)
    if(lastActiveState != 3)
      {
      Serial.println("Water level is very high.  Immediate attention needed!");
/*rmv
      char msg[] = ("Water level is very high.  Immediate attention needed!"); */
      lastActiveState = 3;
      Tweet( "Water level is very high.  Immediate attention needed!" );
      }
    }

 //Water is high
  if ((medState == HIGH) & (highState == LOW))
    {
   //check if last active state was not high(2)
    if(lastActiveState != 2)
      {
      Serial.println("Water level is high.");
/*rmv
      char msg[] = ("Water level is high"); */
      lastActiveState = 2;
      Tweet( "Water level is high" );
      }
    }

//Water is normal
  if ((lowState == LOW) & (highState == LOW))
    {
  //check if last active state was not normal(1)
    if(lastActiveState != 1)
      {
      Serial.println("Water level has returned to normal.");
/* rmv
      char msg[] = ("Water level has returned to normal."); */
      lastActiveState = 1;
      Tweet( "Water level has returned to normal." );
      }
    }
  delay(5000);
  }

  void Tweet( const char* msg )
  {
    Serial.println("connecting ...");
      if (twitter.post(msg))
      {
      int status = twitter.wait();
      if (status == 200)
        {
        Serial.print("OK. -");
        Serial.println(status);
        }
        else
          {
          Serial.print("failed : code ");
          Serial.println(status);
          }
        }
        else
        {
        Serial.println("connection failed.");
        }
}

Thanks, Coding Badly, It works a treat! I would never have thought of passing the variable into the subroutine like that. Now, however, twitter rejects some of my tweets because they don't allow re-posts of the same messages for a certain amount of time. is there way to add an integer to the message? Example: Tweet ( "water is high, ", count, "tweets"); Similar to using serial.print and serial.println to compose readable messages ou of the serial port? Thanks!

I have no way to test this but it should be close...

//INCLUDE LIBRARIES
#include <Client.h>
#include <Server.h>
#include <Ethernet.h>
#include <Twitter.h>
#include <stdarg.h>

void Tweet( const char* msg, ... );  // Uh oh!  Bug in Arduino requires this to be prototyped.
  
//ETHERNET INITIALIZATON
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 20 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 0, 0 };

//TWITTER INITIALIZATION
Twitter twitter("usernAME:password");
/*rmv
char msg[] = "/Meh/"; */

//LEVEL SENSoRS
const int levellow =  3;
const int levelhigh =  2;

//STORE SENSOR STATES
int lowState = 0;
int medState = 0;
int highState = 0;

int lastActiveState = 0; // Keep track of the active state

int sequence;

void setup()
  {
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);

  pinMode(levellow, INPUT);
  pinMode(levelhigh, INPUT);


/*rmv  
  Serial.println("Welcome.  SmartHome1144 initializing...");
  char msg[] = "Welcome.  SmartHome1144 initializing..."; */
  Tweet( "(%i) Welcome.  SmartHome1144 initializing...", ++sequence );
  delay(5000);
  }

void loop()
  {
  // CHECK STATES
  lowState = digitalRead(levellow);
  medState = digitalRead(levellow);
  highState = digitalRead(levelhigh);
   /**********
   *  Each of the following conditionals only sends one Serial message
   *  per state
   **********/

  //Water is dangerously high
  if ((highState == HIGH) && (lowState == HIGH))
    {
     //check if last active state was not very high(3)
    if(lastActiveState != 3)
      {
/*rmv
      Serial.println("Water level is very high.  Immediate attention needed!");
      char msg[] = ("Water level is very high.  Immediate attention needed!"); */
      lastActiveState = 3;
      Tweet( "(%i) Water level is very high.  Immediate attention needed!", ++sequence );
      }
    }

 //Water is high
  if ((medState == HIGH) && (highState == LOW))
    {
   //check if last active state was not high(2)
    if(lastActiveState != 2)
      {
/*rmv
      Serial.println("Water level is high.");
      char msg[] = ("Water level is high"); */
      lastActiveState = 2;
      Tweet( "(%i) Water level is high", ++sequence );
      }
    }

//Water is normal
  if ((lowState == LOW) & (highState == LOW))
    {
  //check if last active state was not normal(1)
    if(lastActiveState != 1)
      {
/* rmv
      Serial.println("Water level has returned to normal.");
      char msg[] = ("Water level has returned to normal."); */
      lastActiveState = 1;
      Tweet( "(%i) Water level has returned to normal.", ++sequence );
      }
    }
  delay(5000);
  }


void Tweet( const char* msg, ... )
{
  char S[81];
  va_list V;
  
  va_start( V, msg );
  vsprintf( S, msg, V );
  va_end( V );

  Serial.println(S);
  Serial.println("connecting ...");

  if (twitter.post(S))
  {
    int status = twitter.wait();

    if (status == 200)
    {
      Serial.print("OK. -");
      Serial.println(status);
    }
    else
    {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  }
  else
  {
    Serial.println("connection failed.");
  }
}

Works, but it resets alot, I think because of overflow errors. I'll post my current code, you can see that I am passing MSG and randomValue to the subroutine. This isn't necessary, because it can be called in the subroutine.
I looked up vsprintf, and still cant understand how you impliment it here:

  char S[81];
  va_list V;

  va_start( V, msg );
  vsprintf( S, msg, V );
  va_end( V );

My revised code:

//INCLUDE LIBRARIES
#include <Client.h>
#include <Server.h>
#include <Ethernet.h>
#include <Twitter.h>
#include <stdarg.h>

void Tweet( const char* msg, ... );  // Uh oh!  Bug in Arduino requires this to be prototyped.

//ETHERNET INITIALIZATON
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 
  192, 168, 1, 20 };
byte gateway[] = { 
  192, 168, 1, 1 };
byte subnet[] = { 
  255, 255, 0, 0 };

//TWITTER INITIALIZATION
Twitter twitter("user:pass");

//LEVEL SENSoRS
const int levellow =  3;
const int levelhigh =  2;

//STORE SENSOR STATES
int lowState = 0;
int highState = 0;
int lastActiveState = 0; // Keep track of the active state
int randomValue = 0;

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);
  pinMode(levellow, INPUT);
  pinMode(levelhigh, INPUT);
  randomValue = random(HEX);
  Tweet( "(%i) Welcome.  SmartHome1144 initializing...", ++randomValue );
  delay(5000);
}

void loop()
{
  // CHECK STATES
  lowState = digitalRead(levellow);
  highState = digitalRead(levelhigh);
  randomValue = random(HEX);
 
  /**********
   *  Each of the following conditionals only sends one Serial message
   *  per state
   **********/

  //Condition 3: Water is dangerously high
  if ((highState == HIGH) && (lowState == HIGH))
  {
    //check if last Condition was not Condition3
    if(lastActiveState != 3)
    {
      lastActiveState = 3;
      Tweet( "(%i) Water level is very high.  Immediate attention needed!", ++randomValue );
    }
  }

  //Condition2: Water is high
  if ((lowState == HIGH) && (highState == LOW))
  {
    //check if last Condition was not Condition2
    if(lastActiveState != 2)
    {
      lastActiveState = 2;
      Tweet( "(%i) Water level is high", ++randomValue );
    }
  }

  //Condition 1: Water is normal
  if ((lowState == LOW) & (highState == LOW))
  {
    //check if last Condition was not Condition1
    if(lastActiveState != 1)
    {
      lastActiveState = 1;
      Tweet( "(%i) Water level has returned to normal.", ++randomValue );
    }
  }
//Delay while twitter post messages
  delay(5000);
}
//End Void Loop

void Tweet( const char* msg, ... )
{
  char S[81];
  va_list V;

  va_start( V, msg );
  vsprintf( S, msg, V );
  va_end( V );

  Serial.println(S);
  Serial.println("connecting ...");

  if (twitter.post(S))
  {
    int status = twitter.wait();

    if (status == 200)
    {
      Serial.print("OK. code-");
      Serial.println(status);
    }
    else
    {
      Serial.print("failed : code-");
      Serial.println(status);
    }
  }
  else
  {
    Serial.println("connection failed.");
  }
}

Thanks for your help.

Works,

Excellent.

but it resets alot, I think because of overflow errors.

That's not good. There's a function in the forum that returns the number of bytes free. That may help determine if your Sketch is using too much memory. You can reduce the memory used by moving the string constants into program memory.

I looked up vsprintf, and still cant understand how you impliment it here:

It isn't difficult to understand but I'm not certain I can explain it.

When a function is called, the parameters are put on the stack. In C(++), the parameters are put on the stack from right to left. This allows the left-most parameter (the last one on the stack) to act as an anchor; the other parameters can be located as an offset from it. In Tweet, msg is the anchor.

The va_* stuff in Tweet constructs a pointer to the first argument after the anchor. In your Sketch, V ends up pointing to the value of randomValue on the stack.

  V --> [randomValue]

Let's say you passed two parameters when you called Tweet...

Tweet( "(%i) (%i) Welcome. SmartHome1144 initializing...", ++randomValue, 42 );

V ends up pointing to the same place but the stack now has two parameters..

  V --> [randomValue,42]

The third parameter to vsprintf is a pointer to a list of arguments. Conveniently, V points to a list of arguments.

Does that make sense?

Solved!

Thanks, CodingBadly, for your input. I took a better look at "sprintf" and figured out how to use it. I used a derivitive of your code to get it to work. I shortened up my messages and made some variables global, to save on buffer space. The result, works as good as I could hope for. It turns out that Twitter only accepts unique posts, so I chose to add a random value to each to trick it into posting every message. I'd mark this post as "solved."

Check out my code:

/********************************
 * This Sketch sends a unique post to
 * Twitter for each level of a water tank.
 * 
 * The possible states of the tank are:
 * LOW: Low sensor off, high sensor off
 * HIGH: Low sensor on, high sensor off
 * VERY HIGH: High sensor on
 * 
 * Twitter will not allow repeat posts,
 * therefore each post has a random number
 * inserted into it to make it unique.
 *******************************/

//INCLUDE LIBRARIES
#include <Client.h>
#include <Server.h>
#include <Ethernet.h>
#include <Twitter.h>

//ETHERNET INITIALIZATON
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  //create unique MAC address for your Tweet-ject
byte ip[] = { 
  192, 168, 1, 20 };                     //Give your Tweet-ject an IP address
byte gateway[] = { 
  192, 168, 1, 1 };                      //Give the IP of you nework's default gateway
byte subnet[] = { 
  255, 255, 0, 0 };                      //Define the subnet of your Tweet-ject

//TWITTER INITIALIZATION
Twitter twitter("user:pass");            //place Twitter Username and Password here
const char* msg ="/meh/";                //Placeholder message otherwise compiler will error

//LEVEL SENSoRS
const int levellow =  3;
const int levelhigh =  2;

//STORE SENSOR STATES
int lowState = 0;                        //State of lower sensor
int highState = 0;                       //State of higher sensor
int lastActiveState = 0;                 //Keep track of the active state
int randomValue = 0;                     //Random integer to insert into Tweets 

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);
  pinMode(levellow, INPUT);
  pinMode(levelhigh, INPUT);
  msg = "initializing";                 //Change msg 
  Tweet();
  delay(5000);
}

void loop()
{
  // CHECK STATES
  lowState = digitalRead(levellow);    //Read Lower Sensor state
  highState = digitalRead(levelhigh);  //Read Higher Sensor state

  /**********
   *  Each of the following conditionals only sends one Serial message
   *  and Tweet per state
   **********/

  //Condition 3: Water level is dangerously high
  if (highState == HIGH)
  {
    //check if last Condition was not Condition3
    if(lastActiveState != 3)
    {
      lastActiveState = 3;
      msg = "EXTREMELY HIGH!";
      Tweet();
    }
  }

  //Condition2: Water level is high
  if ((lowState == HIGH) && (highState == LOW))
  {
    //check if last Condition was not Condition2
    if(lastActiveState != 2)
    {
      lastActiveState = 2;
      msg = "high.";
      Tweet();
    }
  }

  //Condition 1: Water level is normal
  if ((lowState == LOW) & (highState == LOW))
  {
    //check if last Condition was not Condition1
    if(lastActiveState != 1)
    {
      lastActiveState = 1;
      msg = "normal.";
      Tweet();
    }
  }
  //Delay while twitter post messages
  delay(5000);
}
//End Void Loop

void Tweet()
{
  char S[50];                          //Define twitter message as "S"
  randomValue = random(HEX);           //Produce random value

  /**********
   *  SprintF "stitches" together a string(msg) and a variable(randomVariable) into
   *  another string, "S".
   **********/

  sprintf(S, "Water level is %s(%i)tweets",msg, randomValue);  // 

  Serial.println(S);
  Serial.println("connecting ...");

  //The rest is lifted from the Twitter post example. 

  if (twitter.post(S))
  {
    int status = twitter.wait();
    if (status == 200)
    {
      Serial.print("OK. code-");
      Serial.println(status);
    }
    else
    {
      Serial.print("failed : code-");
      Serial.println(status);
    }
  }
  else
  {
    Serial.println("connection failed.");
  }
}

Still won't tweet consecutively the same message, needs to alternate the message.