Problems stitching a few pieces of code together.

Hello,

I am pretty new to Arduino and programming in general. I’m trying to combine a piece of code from the VirtualWire library with a piece of code from the Twitter library.

I built a simplex rf transmitter (Arduino 1) that sends a character message to a receiver (Arduino 2). After the message reaches the receiver, I want the receiver to take that message and send it to Twitter.

The first program is for generating and sending the message from the transmitter. This program is working fine.

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
const int buttonPin = 6;
int buttonState = 0;
int lastButtonState = 0;
int buttonPushCounter = 0;
int randomValue = 0;
const char* msg = "meh";

void setup()
{
  pinMode(buttonPin, INPUT);
     // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for RF Link module
    vw_setup(2000);                 // Bits per sec
    vw_set_tx_pin(2);                // pin 2 is used as the transmit data out into the TX Link module.
}

void loop()
{
  
  
  buttonState = digitalRead(buttonPin);
   msg = "Trigger 1";       // Message to send
   if (buttonState != lastButtonState) {
     //if (buttonState == HIGH) {
      { buttonPushCounter++; }
       lastButtonState = buttonState;
       if (buttonPushCounter % 2 == 0) {
         char S[5000];				  //Define twitter message as "S"
  randomValue = random();
  sprintf(S, "%s(%i)", msg, randomValue);
   vw_send((uint8_t *)S, strlen(S));
   vw_wait_tx(); 
   
}   // Wait for message to finish
   delay(200);
     }
   }

Next, I have a sample sketch from the VirtualWire library that receives the message and writes it to serial. This code is also working fine…on its own.

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
    Serial.begin(9600);    

// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(3);           // receive on pin 3  
    vw_rx_start();                      // Start the receiver 
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // check to see if anything has been received
    {
    int i;
     // Message with a good checksum received.
        
    for (i = 0; i < buflen; i++)
    {
        Serial.print(buf[i]);  // the received data is stored in buffer
        }
    Serial.println("");
     }
}

Finally, I have a sample sketch from the Twitter library which is also working fine…on its own.

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>

// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// substitute an address on your own network here
byte ip[] = { 192, 168, 2, 250 };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("YOUR-TOKEN-HERE");

// Message to post
char msg[] = "Hello, World! I'm Arduino!";

void setup()
{
  delay(1000);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  
  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.");
  }
}

void loop()
{
}

I already know about the Oauth token and the duplicate Twitter message ‘bug’ and have resolved those issues.

My problem is that I can’t seem to stitch the Twitter example together with the VirtualWire example in such a way that the resulting program will pick up the transmitted message and send it to Twitter.

Can anyone help? MUCH thanks if you can.

Something like this?

#include <VirtualWire.h>
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif


#undef int
#undef abs
#undef double
#undef float
#undef round




// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// substitute an address on your own network here
byte ip[] = { 192, 168, 2, 250 };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("YOUR-TOKEN-HERE");

// Message to post
char msg[] = "Hello, World! I'm Arduino!";


void setup()
{

    delay(1000);
    Ethernet.begin(mac, ip);
    Serial.begin(9600);    

// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(3);           // receive on pin 3  
    vw_rx_start();                      // Start the receiver 
	
	
	Serial.println("connecting ...");
  
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen-1)) // check to see if anything has been received
    {
	buf[buflen] = '\0';
    Serial.println(buf); 
	Serial.println("sending to Twitter");
	
	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.");
  }
	
	
	
	
	/*uint16_t i;
     // Message with a good checksum received.
        
    for (i = 0; i < buflen; i++)
    {
        Serial.print(buf[i]);  // the received data is stored in buffer
        }
    Serial.println("");
     }*/
}

Not too sure why you don’t want to undef the int type… but ok.
See if this works as intended, I haven’t even compiled it, but it does seem to be close enough to what you want.

Thank you. I'll try it now. It will take a few minutes to setup the hardware but if it works; see this...Arduino Forum You'll have $25 of SparkFun money! Be back in a few.

"call of overloaded 'println(uint8_t[30])' is ambiguous" :frowning: ...seems close though.

Altered a couple things and got it to compile but still no messages making it to Twitter. Have to go to bed. I'll be back tomorrow. Hope there's still interest tomorrow afternoon.

Ok...

But what do you get from the Serial terminal? Without seeing where the program fails, it's hard to know where to correct it. Also, did you add all the Twitter connection stuff to the code?

I've never used any of these objects either, so I don't know of any dependencies they may have that screw up things between them. Let me know what you get on the serial terminal and we'll take it from there. :slight_smile:

When the program spins the first time, I get “connecting…” in the serial terminal. Every time I (succesfully) trigger the transmitter, I get the same thing. Nothing progresses beyond that.

Also, in my original Receiver sketch, I send pin13 high every time a message is received from the transmitter. When I run the Receiver sketch on its own, pin13 (LED) lights up every time I trigger the transmitter and the message from the transmitter appears in the serial window. With your code, I can get the LED to light up intermittently and when it does, instead of the char msg from the transmitter appearing in the serial terminal, I get “connecting…” and then nothing else happens.

BTW: I’m VERY appreciative of your help.

Also, SGU!

Ok…

my head is working better now…

I had another look and one thing I don’t like in my code is this:

uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

Can you please remove it from inside the loop and put it next to all other variables?

I’m not a great expert in the Arduino language, but this may be exhausting the memory on the microcontroller.

Change uint8_t to char while you’re at it.

Delete this:

// Message to post
char msg[] = "Hello, World! I'm Arduino!";

In here:

	if (twitter.post(msg)) {    <<<---- IN THIS LINE


    // 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.");
  }

Change the variable msg to buf. If you did the previous step, this wouldn’t compile either way. I also noticed I screwed up (typical) with the message buffer to add the termination character. If you check, I was writing it out of bounds.

Revised code to test:

#include <VirtualWire.h>
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif


#undef int
#undef abs
#undef double
#undef float
#undef round




// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// substitute an address on your own network here
byte ip[] = { 192, 168, 2, 250 };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("YOUR-TOKEN-HERE");

//Buffers for wireless
char buf[VW_MAX_MESSAGE_LEN];
char buflen = VW_MAX_MESSAGE_LEN;


void setup()
{

    delay(1000);
    Ethernet.begin(mac, ip);
    Serial.begin(9600);    

// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(3);           // receive on pin 3  
    vw_rx_start();                      // Start the receiver 
    Serial.println("connecting ...");
  
}

void loop()
{
 
    if (vw_get_message(buf, &buflen-1)) // check to see if anything has been received
    {
        Serial.println("Eureka");// just to see if we managed to get inside here
	buf[buflen-1] = '\0';
        Serial.println(buf); 
	Serial.println("sending to Twitter");
	
	if (twitter.post(buf)) {
    // 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.");
  }
	
	
	
	
	/*uint16_t i;
     // Message with a good checksum received.
        
    for (i = 0; i < buflen; i++)
    {
        Serial.print(buf[i]);  // the received data is stored in buffer
        }
    Serial.println("");
     }*/
}

Give it another try.

Another idea altogether:

#include <VirtualWire.h>
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif


#undef int
#undef abs
#undef double
#undef float
#undef round




// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// substitute an address on your own network here
byte ip[] = { 192, 168, 2, 250 };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("YOUR-TOKEN-HERE");

//Buffers for wireless
char buf[VW_MAX_MESSAGE_LEN];
char buflen = VW_MAX_MESSAGE_LEN;


int postToTwitter(char * buf)  {
    Ethernet.begin(mac, ip);
    delay(1000);
    Serial.println("sending to Twitter");
    
    if (twitter.post(buf)) {
    // 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);
        return status; 
    }

}

void setup()
{
    Serial.begin(9600);    

// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(3);           // receive on pin 3  
    vw_rx_start();                      // Start the receiver 
    Serial.println("connecting ...");
  
}

void loop()
{
 
    if (vw_get_message(buf, &buflen-1)) // check to see if anything has been received
    {
        Serial.println("Eureka");// just to see if we managed to get inside here
	buf[buflen-1] = '\0';
        Serial.println(buf); 
        int statusTwo = postToTwitter(buf);

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

I was thinking and I believe the Ethernet code reserves about 512 bytes of memory, meaning that with the 160 (???) from the Twitter and everything else we may be running low on memory. Give it another try. In this example is also easier to separate the Twitter side of the code from the serial receiving side of the code. Meaning that you can test the reception and then enable the reception of the ethernet interface with a client example and then put Twitter working.

Just got home from work and tried both of your code examples. This is what I'm getting:

"invalid conversion from "char" to 'uint8_t*'

on this line:

if (vw_get_message(buf, &buflen-1)) // check to see if anything has been received

I commented out "(buf, &buflen-1))" just to see what would happen, it compiled but I still get "connection failed". Also, the receiver is printing "Eureka" to serial without ever receiving a message from the transmitter. From reading your code, it seems like it shouldn't do this, weird.

The receiver doesn't seem to be picking up the transmitted message either. No blink on pin13 and no indication in serial terminal.

Tested again with original tx, rx, and Twitter programs and everything still works individually so no hardware or network problems.

I have to leave home again pretty soon but I'll check back again late tonight. Thanks again.

ok...

define buf as uint8_t instead of char and that should fix it.

If you comment the "(buf, &buflen-1))", how can the function run?
Put that part back and give it another try. Eureka should only appear when you have the buffer defined I suppose. :\ I don't have those functions here so I can look inside and see exactly what they do, so I'm going by instinct.
If you want, give me the wireless function library so I can have a look inside and see what dependencies there may be that make this stop working.

Hey, I finally made it back home.

I tried defining buf as uint8_t but I'm getting basically the opposite error on this line:

        int statusTwo = postToTwitter(buf);

I get: invalid conversion from 'uint8_t*' to 'char'

I seriously don't know what I'm doing here but am I correct in thinking that the VirtualWire library is expecting an unsigned 8 bit integer, while the Twitter library is expecting a char msg? Does that even make any sense?

The VirtualWire library download is:

http://www.open.com.au/mikem/arduino/VirtualWire-1.5.zip

int postToTwitter(char * buf)  {

invalid conversion from ‘uint8_t*’ to ‘char’

Really?

Can you post the code and the error message?

The code is the last version posted by bubulindo with ‘buf’ defined as ‘uint8_t’ (not sure if I did that right):

#include <VirtualWire.h>
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif


#undef int
#undef abs
#undef double
#undef float
#undef round




// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// substitute an address on your own network here
byte ip[] = { 192, 168, 2, 250 };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("YOUR-TOKEN-HERE");

//Buffers for wireless
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;


int postToTwitter(char * buf)  {
    Ethernet.begin(mac, ip);
    delay(1000);
    Serial.println("sending to Twitter");
    
    if (twitter.post(buf)) {
    // 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);
        return status; 
    }

}

void setup()
{
    Serial.begin(9600);    

// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(3);           // receive on pin 3  
    vw_rx_start();                      // Start the receiver 
    Serial.println("connecting ...");
  
}

void loop()
{
 
    if (vw_get_message(buf, &buflen-1)) // check to see if anything has been received
    {
        Serial.println("Eureka");// just to see if we managed to get inside here
	buf[buflen-1] = '\0';
        Serial.println(buf); 
        int statusTwo = postToTwitter(buf);

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

If you compile it, you first get: "call of overloaded function ‘println(uint8_t[30])’ is ambiguous. On this line:

        Serial.println(buf);

I commented this out b/c I didn’t think it was a big deal to skip printing the buf to serial.

After this is commented out, I get invaid conversion from ‘uint8_t*’ to ‘char*’ (sorry I forgot “*” before) on this line:

int statusTwo = postToTwitter(buf);

(sorry I forgot "*" before)

So, a simple cast will fix it.
If you quote, please quote accurately.

I'm guessing you mean something like this?

Serial.println(*buf); 
int statusTwo = postToTwitter (*buf);

Sorry, I'm trying to learn. I did some reading about type casting but I'm still not exactly sure how to use this.

Did it work? :S

If you’re asking about my latest reply to AWOL, not quite. Now I get "invalid conversion from ‘unsigned char’ to ‘char*’ on this line:

        int statusTwo = postToTwitter(*buf);

Here is the latest code:

#include <VirtualWire.h>
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif


#undef int
#undef abs
#undef double
#undef float
#undef round




// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// substitute an address on your own network here
byte ip[] = { 192, 168, 2, 199 };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("YOUR-TOKEN-HERE");

//Buffers for wireless
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;


int postToTwitter(char * buf) {
    Ethernet.begin(mac, ip);
    delay(1000);
    Serial.println("sending to Twitter");
    
    if (twitter.post(buf)) {
    // 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);
        return status; 
    }

}

void setup()
{
    Serial.begin(9600);    

// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(3);           // receive on pin 3  
    vw_rx_start();                      // Start the receiver 
    Serial.println("connecting ...");
  
}

void loop()
{
 
    if (vw_get_message(buf, &buflen-1)) // check to see if anything has been received
    {
        Serial.println("Eureka");// just to see if we managed to get inside here
	buf[buflen-1] = '\0';
        Serial.println(*buf); 
        int statusTwo = postToTwitter(*buf);

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

I don't understand where it's getting "unsigned char" from. Is it expecting this because of something in the Twitter library?

uint8_t = unsigned char. This is why I don’t like it when people don’t use the natural types of C.

int statusTwo = postToTwitter((char) buf);