Posting from Arduino to a microblog - need help to understand a 3rd-party code

Hello everyone,

After buying and setting up (by the way, dvo1, if you read this, thanks for your tip :)) the ENC Ethernet chip for my Arduino the next task is to make Arduino communicate with some internet services, microblogs, for instance. I've already made a small weather station, in the end it gets two integers, let name them temp and humid.

Of course, there must be loads of tutorials how to get your Arduino send Twitter posts, but, the problem is, I'm now in Beijing, China, I think some of you know the situation with Twitter here (it's blocked). Of course, VPN can be used, but i think it's too hard or even impossible to make Arduino and ENC serve as VPN client. So, I've thought about using not Twitter, but China-based Sina Weibo microblog service instead. After searching. I've found a code made by one of Chinese websites to make Arduino communicating with Weibo. It uses a? intermediate platform set by its creators, but I think that to understand my problem it's not neccessary to understand how this platform works.

Okay, the code just for posting (doesn't include the get ints part, written by the 3-rd party) is

#include <EtherCard.h>

static byte mymac[] = {0xDD,0xDD,0xDD,0x00,0x00,0x01};
char website[] PROGMEM = "nupttemp.duapp.com";
int j;


const char *T;
byte Ethernet::buffer[700];
static uint32_t timer;
int i=0;
//////There must be the Weibo access token instead of 333..., I have my own
char q[200]="api.php?access_token=333333333333333333333333&status=The status goes here";
static void response_callback (byte status, word off, word len) {
  Serial.print((const char*) Ethernet::buffer + off);
} 
 
void setup () {
  Serial.begin(9600);
  Serial.println("Client Demo");
  Serial.println();
 
  if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
    Serial.println( "Failed to access Ethernet controller");
 else
   Serial.println("Ethernet controller initialized");
 Serial.println();
 
  if (!ether.dhcpSetup())
    Serial.println("Failed to get configuration from DHCP");
  else
    Serial.println("DHCP configuration done");
 
  ether.printIp("IP Address:\t", ether.myip);
  ether.printIp("Netmask:\t", ether.mymask);
  ether.printIp("Gateway:\t", ether.gwip);
  Serial.println();
  
  if (!ether.dnsLookup(website))
    Serial.println("DNS failed");
  else 
    Serial.println("DNS resolution done");  
  ether.printIp("SRV IP:\t", ether.hisip);
  Serial.println();
}
 
void loop() {
  ether.packetLoop(ether.packetReceive());
 if (millis() > timer) {
    timer = millis() + 20000;
    ether.browseUrl(PSTR("/"), q, website, response_callback);
    Serial.println(q);
   
   }
}

The problem is, if I understand correctly, this code was initially made to send a fixed message. But is it possible to use the two ints got in a previous parts of the program as the message text? If possible, how should be the code modified (I feel that's all about the "char q[200]="api.php?access_token=333..." string) (for example, i tried just using the "+" operation in different ways, but it didn't help)? Can anybody understand how this code works? I'm a newbie in programming, so there are lot of things I can't understand by myself. The communication with the author of the script is too slow, the first email to him got the answer only after some 5 days, so in this way it will take too long to understand how the thing works.

Thanks for any help,
Paul.

byte Ethernet::buffer[700];
static uint32_t timer;
int i=0;
//////There must be the Weibo access token instead of 333..., I have my own
char q[200]="api.php?access_token=333333333333333333333333&status=The status goes here";

There's nearly half the memory of any Arduino other than the Mega or Due.

I feel that's all about the "char q[200]="api.php?access_token=333..." string) (for example, i tried just using the "+" operation in different ways, but it didn't help)?

It is. You can't ADDING char arrays is a silly idea. Look at sprintf(), strcat(), and strcpy().

Okay, it seems I've got the meaning of the strcat and strcpy. Not so hard :slight_smile:

(sorry, if my questions are too noob)

But, about this program. If I try to make anything like this for a try

const char *T;
byte Ethernet::buffer[700];
static uint32_t timer;
int i=0;
//////access_token your status message
char q[200];
strcpy(q, "api.php?access_token=xxx&status=from+arduino+??????µ??§???????¬?????¤??");
static void response_callback (byte status, word off, word len) {
  Serial.print((const char*) Ethernet::buffer + off);
}

,

it breaks on the strcpy string with the message "expected constructor,destructor or type conversion before the "(" token). Aren't the
q[200]="something"
and

char q[200]; 
strcpy(q,"something");

equal?

Is the problem in the pointers? I'm a newbie in C and the C used by Arduino, so I haven't completely understand the thing about pointers. What I've understood is they are pointing to the address in the memory. For example, we have two ints. The first thing to do is to make the pointers to these ints? How exactly it's made and used? Maybe there are some tutorials or other threads which deal with the same topic.

Thanks,
Paul.

You can only call the strcat() function from within a function.

Aren't the...and...equal?

They are, IF strcat() is called in setup(), loop(), or some other function.

sempol:
What I've understood is they are pointing to the address in the memory. For example, we have two ints. The first thing to do is to make the pointers to these ints? How exactly it's made and used? Maybe there are some tutorials or other threads which deal with the same topic.

Pointers point to things in memory, yes.

I suggest you read some tutorials about C and managing strings. Twitter may be blocked, but this is fundamental stuff. Try Googling. Virtually any beginner C tutorial will cover it.

Ok, thank you! Okay, then it's time to read something.

Well, it seems I have understood something about pointers in such case. The matter is, you can't directly make a cast from int to a part of a char array, but it's possible to use not the int itself, but the data from the address where the int is stored (which is just the number I want). Do I understand it correctly?

I've tried to make a simple code to check have I understood it correctly:
(in the end it should display something like this "api.php?access_token=333334443512366525543302333967&status=Arduino reporting. Temperature and humidity are 25 64" in the SM)

int a = 25;
int a= 64;
int* pa; //set the two pointers
int* pb;

char q[200]="api.php?access_token=333334443512366525543302333967&status=Arduino reporting. Temperature and humidity are ";

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

}

void loop()
{
  pa = &a; //linking the pointers and the ints
  pb = &b; 
  q[109]=*pa; 
  q[112]=*pb;
  Serial.println(q);
  delay(20000);
}

But in the serial monitor there's only initial q, without two added elements. What's the problem with the code? The problem is I still haven't understood the thing about pointers?

The matter is, you can't directly make a cast from int to a part of a char array,

A cast is NOT what you want. Casting an int as a char is not the same as converting an int to an array of chars.

void loop()
{
  pa = &a; //linking the pointers and the ints
  pb = &b; 
  q[109]=*pa; 
  q[112]=*pb;
  Serial.println(q);
  delay(20000);
}

Not even close.

Try something like this:

char part1[] = "api.php?access_token=333334443512366525543302333967&status=Arduino reporting. Temperature and humidity are ";
char temp[10];
char humid[10];
char all[200];

void loop()
{
   int tempVal = 72;
   int humidVal = 30;

   sprintf(temp, "%d", tempVal);
   sprintf(humid, "%d", humidVal);

   all[0] = '\0';
   strcat(all, part1);
   strcat(all, temp);
   strcat(all, " and ");
   strcat(all, humid);

   Serial.print("all: [");
   Serial.print(all);
   Serial.println("]");

   delay(1000);
}