andrewrapp / xbee-arduino

Arduino library for communicating with XBee radios in API mode
GNU General Public License v2.0
334 stars 162 forks source link

Setting the AT Commands via API mode #29

Open rohitsivakumar opened 8 years ago

rohitsivakumar commented 8 years ago

How do I use this library to set the parameters/values of an at command via api mode.

Say for instance, I want to set up the pan ID as as say 23 so ATID = 23. How do I do this via the api mode. the example provided does not seem to work or provide such a solution.

matthijskooijman commented 8 years ago

See here for an example: https://github.com/andrewrapp/xbee-arduino/blob/master/examples/ZdpScan/ZdpScan.ino#L434

Note that the value being set is transferred as a binary number too, not as an ASCII string. This means that if you need more than 1 byte of data (e.g. > 255), you'll need to take particular care of the endianness of the data (and IIRC the XBee expect big endian, while most arduinos use little endian).

sdiaz-qkt commented 5 years ago

@matthijskooijman Hi! I'm sorry, would you mind giving me an example about how to do it with more bytes of data?. In my case I want to change the destination address (DL) of my xbee cellular, and the port (DE). Since I'm using a string as the address and not sure how to do it.

matthijskooijman commented 5 years ago

@sdiaz-qkt, I haven't worked with (or even looked at) the xbee celluar hardware, but here's what I suppose might work (also didn't actually test this code):

uint8_t value[] = "abc";
AtCommandRequest req((uint8_t*)"DL", value, sizeof(value) - 1);

This sets the string value "abc" to the "DL" setting (assuming it takes a string, not an integer). Here, the string "abc" is used to initialize an array which is then passed to the AtCommandRequest constructor. The size passed to the constructor uses the sizeof the array (4) minus one (for the trailing NUL that is also included in the array but does, AFAIK, not need to be sent as part of the command.

A somewhat more explicit version would be this (where the array is initialized one by one and does not include the trailing NUL, so no need to subtract one).

uint8_t value[] = {'a', 'b', 'c'};
AtCommandRequest req((uint8_t*)"DL", value, sizeof(value));

For completeness, here's an example where a 16-bit integer value is passed, rather than a string.

uint16_t intvalue = 0x1234;
uint8_t value[] = {(intvalue >> 8) & 0xff, intvalue & 0xff};
AtCommandRequest req((uint8_t*)"XX", value, sizeof(value));

I'm using "XX" for the command, since I don't know any appropriate command offhand. This explicitly splits up the intvalue into two bytes to pass to the XBee module. This ensures that the value is sent as big endian (Most-significant-byte first), regardless of how the Arduino itself stores data in memory. Note that the & 0xff is not really required (assigning to a uint8_t already implicitly truncates), but shown here for clarity.

sdiaz-qkt commented 5 years ago

@matthijskooijman Unfortunately that does not work. I tried it before asking and tried again now just to double check. Doing it that way gives me this error :

 no known conversion for argument 2 from 'uint8_t (*)[17] {aka unsigned char (*)[17]}' to 'uint8_t* {aka unsigned char*}'

no instance of constructor "AtCommandRequest::AtCommandRequest" matches the argument list -- argument types are: (uint8_t *, uint8_t (*)[4], unsigned long)
matthijskooijman commented 5 years ago

Oh, I made an error there. I used &value, but if value is an array, you'll already get its starting address when referencing it, so no need to use & to get the address. I've corrected my examples above to use value rather than &value.

sdiaz-qkt commented 5 years ago

@matthijskooijman Thanks for your help. Unfortunately I'm still not able to modify the settings in my AT commands. By any chance do you know if this library can be used to send HTTP requests (GET, POST)? That is my final goal so if it is not possible to use this library for that end, I'm thinking to just give up with this and try to do my own functions.

Back to the original issue, I'm using the example to set my destination port to 1 just for testing purposes. The code is :

  monitorSerial.begin(9600);
  xbeeCallbacks.setSerial(monitorSerial);
  uint8_t value = 1;
  AtCommandRequest req((uint8_t*)"DE", &value, sizeof(value));
  req.setFrameId(xbeeCallbacks.getNextFrameId());
  uint8_t status = xbeeCallbacks.sendAndWait(req, 150);

  if (status == 0)
    Serial.println(F("Set DE successfully"));
  else
    Serial.println(F("Failed to set DE, expect problems"));

Where :

XBeeWithCallbacks xbeeCallbacks;
SoftwareSerial monitorSerial = SoftwareSerial(3, 2);

However this code keeps printing "Failed to set DE". This is depressing me.

Thanks again for all the support.

matthijskooijman commented 5 years ago

By any chance do you know if this library can be used to send HTTP requests (GET, POST)?

AFAIK the library itself does not have anything for this, since it is primarily intended to talk to XBee modules. It was written with the 802.15.4 and similar versions in mind, not so much for the cellular version (but it will work, since the basic protocol is the same). Having said that, if the XBee hardware/firmware itself has support for sending HTTP requests, e.g. through specific commands, you could probably use those through this library (though some additions to the library might needed if different packet formats are used, I think). But again, I have not worked with cellular XBees (and not with Xbees in general for a while), so I might be completely off the bat here.

However this code keeps printing "Failed to set DE". This is depressing me.

Perhaps the module is expecting the value as ASCII, rather than a raw number. If so, I think you could use:

uint8_t value = '1';

and see if that works (for more than 1 digit, you might need to go back to the previous string example).