Ethernet shield + If/else statement + Twitter

Let me preface this post by stating that I have very little experience with programming.

I very recently started using the Arduino microcontroller and I've completed Lady Ada's lessons 0-5 along with the easier tutorials on the Arduino.cc site with relatively few hiccups. My next task is to come up with a prototype with an output we haven't had experience using in my class -- I've chosen to use Twitter as that output.

I've been able to post a tweet to the account with a simple button press, but I need to increase the difficulty by adding if/else statements to tweet various phrases depending on which button I press. It didn't seem too hard but I've encountered problems. I've searched through these forums with the purpose of "borrowing" code to suit my needs. I've come across another thread entitled "twitter sketch posts only once" and it had what I needed. I did try using that code but I am now unable to tweet anything. Will anyone help a newbie out?

Thanks for your time,
Ouchb.

// LIBRARIES
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <Client.h>
#include <Server.h>

// USA
const int buttonPinUSA = 0;  // USA BUTTON/SWITCH
const int buttonLedUSA = 1;  // USA BUTTON/SWITCH LED
int buttonStateUSA = 0;  // USA BUTTON/SWITCH STATE (HIGH OR LOW)

// SOVIET UNION
const int buttonPinSOVIETUNION = 2;  // SOVIET UNION BUTTON/SWITCH
const int buttonLedSOVIETUNION = 3;  // SOVIET UNION BUTTON/SWITCH LED
int buttonStateSOVIETUNION = 0;  // SOVIET UNION BUTTON/SWITCH STATE (High OR LOW)

// RANDOM INTEGER TO INSERT INTO TWEETS TO ALLOW DUPLICATE TWEETS
int randomValue = 0;

// KEEP TRACK OF LAST ACTIVATE STATE
int lastActivateState = 0;

// ETHERNET INITIALIZATON
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 109 };  // ETHERNET SHIELD IP ADDRESS
byte gateway[] = { 192, 168, 1, 1 };  // NETWORK DEFAULT GATEWAY
byte subnet[] = { 255, 255, 255, 0 };  // NETWORK SUBNET MASK

// TWITTER INITIALIZATION
Twitter twitter("TWITTER TOKEN");  // TWITTER TOKEN FROM HTTP://ARDUINO-TWEET.APPSPOT.COM/
const char* msg ="/meh/";  // PLACEHOLDER MESSAGE OTHERWISE COMPILER WILL ERROR

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);
  pinMode(buttonPinUSA, INPUT);
  pinMode(buttonLedUSA, OUTPUT);
  pinMode(buttonPinSOVIETUNION, INPUT);
  pinMode(buttonLedSOVIETUNION, OUTPUT);
  Serial.println("I am connecting ...");
  msg = "initializing";
  Tweet(); 
  delay(2000);
}

void loop()
{
  buttonStateUSA = digitalRead(buttonPinUSA);  // READ USA BUTTON/SWITCH STATE
  buttonStateSOVIETUNION = digitalRead(buttonPinSOVIETUNION);  // READ SOVIET UNION BUTTON/SWITCH STATE
  
  // CONDITION #1: THE USA BUTTON/SWITCH HAS BEEN ACTIVATED
  if (buttonStateUSA == HIGH)
  {
    if (lastActivateState =! 1)
    {
      lastActivateState = 1;
      digitalWrite(buttonLedUSA, HIGH);
      msg = "Country: USA has been selected!"; 
      Tweet();
      Serial.println("USA Button/Switch has been activated");
    }
  }
   
   // CONDITION #2: THE SOVIET UNION BUTTON/SWITCH HAS BEEN ACTIVATED
 if (buttonStateSOVIETUNION == HIGH)
 {
   if (lastActivateState =! 2)
   {
     lastActivateState = 2;
     digitalWrite(buttonLedSOVIETUNION, HIGH);
     msg = "Country: SOVIET UNION has been selected!"; 
     Tweet();
     Serial.println("SOVIET UNION Button/Switch has been activated");
   }
 }

  // DELAY WHILE TWITTER POSTS MESSAGES
  delay(2000);

  // ENDING VOID LOOP()
}  

void Tweet()
{
  char S[50];                        
  randomValue = random(HEX);
  
  /**********
   *  SprintF "stitches" together a string(msg) and a variable(randomVariable) into
   *  another string, "S".
   **********/

  sprintf(S, "SOMETHING %s(%i)tweets", msg, randomValue);

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

  // TWITTER POST EXAMPLE REMAINING CODE
  
  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.");
  }
}

Just a guess - your character buffer S[] may be too short for some of your messages

const char* msg ="/meh/";  // PLACEHOLDER MESSAGE OTHERWISE COMPILER WILL ERROR

  msg = "initializing";

Do you have any idea what const in the declaration of msg means? Do you know how to use pointers?

It's fairly obvious that the answer to both questions is no. Time to learn something.

Regarding pointers -- I've seen the '*' in different locations among threads about pointers. Both go through the compiler without error, so I guess they mean different things. What is that exactly?

char *msg;
char* msg;

I've removed the msg = "initializing";

I also have another question about the character buffer. Would it be okay if I put in a value that was greater than the amount of characters I would have in the tweet?

char S[100];                        
randomValue = random(HEX);
sprintf(S, "COUNTRY:", msg, randomValue);

The position of the * is not important. Some people like char*, with the * next to the type. Others like char *, with the * next to the variable. I like the * next to the variable, to remind me that the variable IS a pointer.

The const in front of the pointer variable declaration means that you can't change where the variable points to. You can change the data that it points to, as long as the new data fits in the space being pointed to, but you can't make the pointer point somewhere else.

You can make S larger than it needs to be, with no ill effects. You can't make it smaller than it needs to be, though, and you can't change it's size once it is defined.

By the way, your sprintf statement won't do what you are hoping it will do, since you have no format specifiers for the variables you want converted to characters.

Should my sprintf statement look something like this instead?

sprintf(S, "COUNTRY: %s ", msg, randomValue);

Blerg

It is tweeting automatically and not upon a button press. It is trying to tweet condition #1 repeatedly (according to the serial monitor). The random number didn't appear at the end of the statement like I had hoped :frowning:

COUNTRY: USA has been selected!

Well, I'm getting closer... It's still sending the tweet automatically (not relying on any of my button presses for whatever reason).

sprintf(S, "COUNTRY: %s %x", msg, randomValue);

COUNTRY: USA has been selected! d
half a minute ago via Arduino

COUNTRY: USA has been selected! 3
half a minute ago via Arduino

COUNTRY: USA has been selected! e
less than a minute ago via Arduino

I still don't see why it's automatically tweeting my first condition in the if statement.

Could I get an experienced eye to look at my if statement and give me a hint of why it's doing what it's doing?

The due date for my assignment is drawing nearer. :-[

The format specifier needs to match the data type being formatted. If you want to format an integer, the format specifier is %d.

Try switching the order of the if tests around. It's possible that one of your buttons is not wired correctly.

I've switched the conditions around and it is still selecting the first condition automatically. I was in the process of switching out the buttons when I noticed that I was getting the serial print messages for the button presses (there wasn't anything attached to the board at the time -- aside from the ethernet cable and power source).

I was in the process of switching out the buttons when I noticed that I was getting the serial print messages for the button presses (there wasn't anything attached to the board at the time -- aside from the ethernet cable and power source).

Keep this up and you'll soon be posting over in Hardware + Troubleshooting forum asking for help on determining why your Arduino no longer works. Once little slip, and the Arduino is toast.

Anyway, digitalRead is meaningful only if there is something to read. I don't see any calls to digitalWrite() in setup(), so it appears that you are not using the internal pull-up resistors. This implies that you are using external pull-up or pull-down resistors. You are, aren't you?

Keep this up and you'll soon be posting over in Hardware + Troubleshooting forum asking for help on determining why your Arduino no longer works. Once little slip, and the Arduino is toast.

Geez. I did unplug it immediately after I saw that it was automatically running condition 1.

I am using external pull-down resistors (at least I think that's what my instructor said we were using). 100-ohm - 220-ohm resistors for the LEDs and 10k-ohm resistors for the switches.

Build a simple sketch to read each switch independently, and print to the Serial Monitor when the switch is pressed.

If both switches cause messages to appear in the Serial Monitor, then the switches are working, and the issue is with the code. If not, the problem is with the hardware.

[edit]Wait a minute. I just looked at your code again. You can't do this:

const int buttonPinUSA = 0;  // USA BUTTON/SWITCH
const int buttonLedUSA = 1;  // USA BUTTON/SWITCH LED

Pins 0 and 1 are the TX/RX (Serial) pins. You can't use them as switch pins at the same time you are using them for Serial communication.
[/edit]

Wait a minute. I just looked at your code again. You can't do this:

const int buttonPinUSA = 0;  // USA BUTTON/SWITCH

const int buttonLedUSA = 1;  // USA BUTTON/SWITCH LED




Pins 0 and 1 are the TX/RX (Serial) pins. You can't use them as switch pins at the same time you are using them for Serial communication.

:-[

That was it!

Thank you MarkT and PaulS. I very much appreciate you taking time to help me out.

Working if/else twitter code for any other newbie's reference.

// LIBRARIES
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <Client.h>
#include <Server.h>

// USA
const int buttonPinUSA = 2;  // USA BUTTON/SWITCH
const int buttonLedUSA = 3;  // USA BUTTON/SWITCH LED
int buttonStateUSA = 0;  // USA BUTTON/SWITCH STATE (HIGH OR LOW)

// SOVIET UNION
const int buttonPinSovietUnion = 4;  // SOVIET UNION BUTTON/SWITCH
const int buttonLedSovietUnion = 5; // SOVIET UNION BUTTON/SWITCH LED
int buttonStateSovietUnion = 0;  // SOVIET UNION BUTTON/SWITCH STATE (HIGH OR LOW)

// RANDOM INTERGER TO INSERT AFTER TWEET MESSAGE TO ALLOW DYNAMIC TWEETS
int randomValue = 0;

// ETHERNET INITIALIZATON
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  // ETHERNET SHIELD MAC ADDRESS
byte ip[] = { 0, 0, 0, 0 };  // ETHERNET SHIELD IP ADDRESS
byte gateway[] = { 0, 0, 0, 0 };  // NETWORK DEFAULT GATEWAY
byte subnet[] = { 0, 0, 0, 0 };  // NETWORK SUBNET MASK

// TWITTER INITIALIZATION
Twitter twitter("TWITTER-TOKEN");  // TWITTER TOKEN FROM HTTP://ARDUINO-TWEET.APPSPOT.COM/

// MESSAGE POINTER USED TO MOVE MSG AROUND
char *msg;

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);
  pinMode(buttonPinUSA, INPUT);
  pinMode(buttonLedUSA, OUTPUT);
  pinMode(buttonPinSovietUnion, INPUT);
  pinMode(buttonLedSovietUnion, OUTPUT);
  Serial.println("Doomsday Machine is online...");
  delay(1000);
}

void loop()
{
  buttonStateUSA = digitalRead(buttonPinUSA);  // READ USA BUTTON/SWITCH STATE
  buttonStateSovietUnion = digitalRead(buttonPinSovietUnion);  // READ SOVIET UNION BUTTON/SWITCH STATE
  
  // CONDITION #1: THE USA BUTTON/SWITCH HAS BEEN ACTIVATED
  if (buttonStateUSA == HIGH)
  {
    digitalWrite(buttonLedUSA, HIGH);
    Serial.println("USA Button/Switch has been activated");
    msg = "USA has been targetted!";
    Tweet();  // CALLS THE Tweet() FUNCTION
    delay(1000);
  }

  // CONDITION #2: THE SOVIET UNION BUTTON/SWITCH HAS BEEN ACTIVATED
  else if (buttonStateSovietUnion == HIGH)
  {
    digitalWrite(buttonLedSovietUnion, HIGH);
    Serial.println("Soviet Union Button/Switch has been activated");
    msg = "Soviet Union has been targetted!";
    Tweet();  // CALLS THE Tweet() FUNCTION
    delay(1000);
  }
  else
  {
    digitalWrite(buttonLedUSA, LOW);
    digitalWrite(buttonLedSovietUnion, LOW);
    Serial.println("No button/switch has been activated");
    delay(1000);
  }
  
  // DELAY TWITTER POSTS MESSAGES
  delay(1000);
}

// Tweet() FUNCTION
void Tweet()
{
  char S[100];
  randomValue = random(HEX);
  sprintf(S, "COUNTRY: %s %d" , msg, randomValue);
  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.");
  }
}