Xbee, Arduino & Processing Design Query - arduino

I have a processing sketch that pumps out basic serial commands to an xbee.
Then I have two (soon to be 3, maybe 4) arduino's with their own xbee's who receive the data and do stuff.
Thing is each Arduino has it's own purpose, and therefore it's own data packet.
So, to implement this. Is there a way to send a message to a particular xbee? I.e. can I assign the xbee an index or channel of some sort, then get the broadcasting xbee to send data to whatever index or channel it needs to?
Or, will this need to be implemented in the Arduino software?
i.e. Processing prefix the data packet with an index/identifier and the arduino ignore incoming messages with that prefix?
Or is there another option entirely :P
Thanks in advance for your advice.

While not a specific answer to your question, with this type of communication some packet error checking would be beneficial. Send the data using a crc error checking algorithm. Packet structure could look something like:
0x7F 0x02 (Address Bytes) (Command Bytes) (CRC bytes) 0x7F 0x03
Where 0x7F is the DLE character used to indicate either a start byte will follow, and end byte will follow, or a data byte with the value of DLE will follow. This means any DLE character that is part of the address or command should be preceded by a 'Stuffed' DLE character. The CRC is calculated from the address and command bytes and used to check the integrity of the data that is received. The CRC check bytes are included in each packet.
This type of communication will prevent packets going to the wrong source from being used, and also packets that are in error from being used.
To read more on serial framing here is a good place to start: http://eli.thegreenplace.net/2009/08/12/framing-in-serial-communications/.

To what i understood is that you want to be able to tell the diffrence to what Xbee you are sending data to. You can do this by using IP adresses. If you have for example two Xbees with the IPs:
Xbee1 - 192.168.80.50
Xbee2 - 192.168.80.51
Xbee3 - 192.168.80.52
You can send information between them by just connecting the Xbee that will start the communication to the Xbee that will receive it. If you want to have any kind of communication over the wireless network (or ethernet) you must have an IP assigned to every Xbee.
EDIT:
If you have a server on a computer that you have made yourself in for example Java. You can connect the Xbees to that and connect of them to the computer server. Then you can set up the server to receive and send data to the diffrent Xbee clients.
I did something similar to this: Maintaining communication between Arduino and Java program , but i didn't use a Xbee, i used the official WiFi shield.
Hope this helped!
-Kad

Related

modbus rtu over tcp (modbus tcp gateway)

Is it possible to build a modbus-RTU ethernet gateway using a linux box or arduino?
I have plc slaves linked together using modbus RTU, and I want to connect one of them over TCP with my pc as master.
I wonder if I can use a linux box (rasbery pi/raspbian) connected to a router, as a modbus-to-tcp converter by piping the usb port to my local ip on some port, as one plc will be connected in modbus rtu to the linux box`s usb port.
Piping command will be something Like this:
nc -l 5626 > /dev/ttyUSB0 < /dev/ttyUSB0
My goal is to connect a pc (networked with the linux box) to that plc through the linux box using modbus.
Yes you can use a linux box with ethernet port.
Its not a simple 'nc' is it.
First things first, you need to know, Does your PLC's support Modbus TCP or Modbus RTU over TCP.
bcos both the formats are not the same, they are not interchangeable.
once you ascertain this, you need to write a TCP Client to Connect to the Slaves as they run the Servers.
If they don't support Modbus TCP yet, you need to write a TCP servers as well.
on top of that, you have the handshaking delays and half open connections and what not.
If it is a commercial device, you need to look at the setup it will be running as well.
Hope this helps
I'm not entirely sure as to what your requirements are, but you may want to have a look at the following library. It's a Modbus TCP->RTU library I assume you can use.
https://github.com/3cky/mbusd
Best Regards
While it's certainly possible to build a Modbus TCP/RTU gateway, you won't be able to do it with a simple nc command, for two reasons:
The actual Modbus protocol data unit (PDU), merely containing the Modbus function code and data, is embedded in an application data unit (ADU) so the request reaches the correct device free of communication errors. This ADU is different for RTU and TCP. Generically, the ADU looks like this:
------------------------------------------
| Additional address | PDU | Error check |
------------------------------------------
For RTU, the "Additional address" is a single byte identifying the unit/slave on the serial line, and the "Error check" is a 16-bit CRC.
For TCP, the "Additional address" is the 7-byte Modbus application protocol header (MBAP), consisting of transaction identifier, protocol identifier, and a length field (2 bytes each), plus a single byte identifying the unit/slave (usually 255, though for a gateway, this would be the ID of the RTU slave behind it). The "Error check" is empty (zero bytes) as that is already taken care of by TCP.
The communication semantics are different for RTU and TCP.
For RTU, you write a request to the serial line, wait for the reply, and only then write the next request. There must be 3½ characters of silence between frames.
For TCP, you can in principle have multiple connections being served concurrently. If you tried to forward two TCP requests to the serial line simultaneously, chaos would ensue.
Still, you can build a working gateway with a slightly more complicated program than nc:
Accept connections on TCP port 5626 (note that the actually recommended port number for Modbus TCP is 502), convert the received TCP ADUs to RTU ADUs and put them into a queue together with a back channel.
Another part of your program takes one item at a time from that queue, sends the ADU over the serial line and reports the result back through the back channel. Then it goes on the to the next item, and so on.
The results arriving on the back channels are converted to TCP ADUs and sent back on the respective TCP connection.
This would certainly work on a Raspberry Pi, and possibly also on Arduino, depending on how large you want your queue to be.
Sources:
http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf

Multi-drop bus to rs232 Convert

I have a project using MDB (multi-drop bus) for vending machine (VDM).
The VDM has a MDB-RS232.
I'm not sure if it converts 9bit - 8bit (MDB-UART).
How do I read data from VDM in my computer?
Thanks all
MDB (multi-drop bus) is 9 bit, because after the standard 8 data bits (like in standard RS232 UART communication) there is a 9th bit called "mode".
(Wikipedia on MDB: "the mode bit differentiates between ADDRESS and DATA bytes.")
But you can read such data even with regular 8-bit RS232 interfaces, e.g. a plain standard USB-to-RS232 device for PC.
Here is how:
Use 9600 baud, 8 data bits, 1 stop bit, but RS232 parity setting "Space". Make sure you receive the original character value even in case of a Parity Error indication. Any MDB address byte from your VDM will be received with a Parity Error (but still be displayed correctly). Any data byte will be displayed without error.
For sending MDB ADDRESS and DATA bytes using a standard 8-bit RS232 port, you could apply temporary parity changes: Change the parity setting to "Mark" before sending an address byte, then change back to "Space" before sending data bytes.
On Windows, you can do such tricks with our Docklight software (see Docklight and MDB). It's free for basic testing and there is also a related 9-bit example project.
On Linux / Raspberry Pi other users have successfully implemented the parity trick, too, see this stackexchange post about a MDB + Pi.
But also with RealTerm, Teraterm, Termite, Bray, YAT or any other RS232 application you should be able to read the data, as long as it handles "Space" or "Mark" parity settings correctly.
You'll need an adapter which will do all convert operations on-the-fly and in real time. If you want to emulate VMC (master), you'll need MDB-UART master adapter. If you want to emulate MDB peripheral device (such as coin changer, bill validator etc), you'll need this. For two-way "sniffing" MDB bus you'll need a combination of these devices.
Direct connection PC's RS-232 to MDB will not work due to strict MDB timings (delay between VMC command and peripheral response must not exceed 5ms, delays between POLL requests are 50-300ms in general). I mean pretty reliable functioning available for commercial purposes.

Wire High&Low Address

With regards to Arduino EEPROM when writing and reading to certain EEPROM devices it asks for a transmission of the following format:
Wire.beginTransmission(ADDR);
Wire.write(highADDR);
Wire.write(lowADDR);
Wire.write(data);
Wire.endTransmission();
What do the high address and low address mean? Why can I not just tell it to write to the byte at address 4. Why do I need to prove a high and low?
It looks to me like you are using I2C, I am going to make that assumption and base my answer off of it. Perhaps you should clarify which EEPROM you are using.
The way I2C works is that you can have one master (your Arduino) communicate with multiple slaves (your EEPROM for example) on the same I2C bus. Since it is possible to have multiple slaves connected on the same bus, I2C protocol requires you to specify what slave device you are communicating with. This is what Wire.beginTransmission(ADDR) does. It is selecting which device it wants to initiate communication with. If you want to communicate with your EEPROM you will need to send the address of your EEPROM (you should be able to find the address in the EEPROM datasheet).
Next, you need to specify the memory location inside your EEPROM where you want to access. This is done using the two bytes highADDR and lowADDR. If for instance you wanted to access the address 0x01AB, then set highADDR to 0x01 and lowADDR to 0xAB.
The rest is fairly simple. You send your data then end the transmission.
To Summarize:
Select device to communicate with (Select your EEPROM)
Wire.beginTransmission(ADDR);
Tell your EEPROM what memory address you want to write to
Wire.write(highADDR); // Send the most significant address bits
Wire.write(lowADDR); // Send the least significant address bits
Send data to write.
Wire.write(data);
End the transmission
Wire.endTransmission();
I strongly recommend reading more about how the I2C protocol works. http://en.wikipedia.org/wiki/I%C2%B2C#Message_protocols

Arduino: Packet loss on Serial communication

I am trying connect multiple Arduino Mega Boards via their Serial pins to allow communication between the boards. I want to be able to connect an arbitrary amount of arduinos by daisy-chaning them and I want one board to be the master, taking control over the actions of the other boards. The master should be determined dynamically by the boards. I am aware that the daisy chaining method introduces delays to the communication due to the forwarding of packets, but so far I am planning on connection 4 boards at most. In the future this might increase to maybe 10 boards. My boards all have a separate power source, since they are connected to some other hardware which has its own power source.
My idea was to connect the boards in such a way, that the master would be determined by the wireing of the boards. I thought about having the "Serial" port as 'To-Master' serial port and the "Serial1" port as "To-Child" serial port. The boards send hello messages on the "To-Master" serial port and the master replies if it received such a message on the "To-Child" serial port. If no answer is received after some seconds, the board determines itself to be the master.
I wired the boards up by connecting the ground pins, and wiring RX1 of the master to TX0 of the child and TX1 of the master to RX0 of the child:
Basically my setup is working, since the boards do detect each other and exchange hello messages and replies. There is however a significant amount of packet loss or corruption which I would like to eliminate.
As a simple measure of packet verification, I begin each packet with a "magic number". The receiving board looks for this byte and only tries to read a packet after receiving this byte. Any other bytes received are simply discarded.
As it seems, it happens quite often that something is received on either serial port that does not start with the magic number and is therefore discarded. The timestamps of these events are however consistent with the timestamps of sending of the other board meaning that the packet was at least partially transmitted but somehow the magic byte got corrupted or discarded.
Is this a known problem with the arduinos serial ports?
Can it be related to my wiring?
Are there any measures I can take to ensure a save delivery of the packets?
Can it be a problem of the boards not reading the signal at the correct time (I used a baud rate of 9600)?
I also looked into I2C communication, but I did not find any resource or information if it is possible to dynamically choose the master for this type of communication. Also in the documentation it stated, that it is important that all devices share a common power source which is not possible in my scenario. However, the basic master-slave principle of this I2C conforms with my requirements, as I have a master that sends commands to all other boards. Could I2C be utilized in my case?
Thank you for your thoughts!
Here is a discussion about multi-master I2C topology of Arduinos, seems that it is supported (haven't tested it myself). - http://forum.arduino.cc/index.php/topic,13579.0.html
You can test SPI as well, here is a comparison between the two - http://components.about.com/od/Theory/a/Selecting-Between-I2c-And-Spi.htm.
Slave might be selected with generic GPIOs
I don't know any known implementation of multi-clients on top of Serial bus (usually it is intended for peer2peer communication only) - even though, your configuration seems reasonable, I would be considering other options.
BTW, from your comment about different power sources, I assume your boards are away from each-other. Have you considered very cheap ($2) RF modules, such as nRF24L01+ (http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/). THere is a library for networking those in multi-node network
Might be better off with I2C or SPI like people have suggested here.
However, to address your question directly, it is most likely wiring. I am assuming you are using cheap jumper wires to plug directly into the Arduino Headers. Noise on this connection is the most likely problem or garbled serial messages. Try implementing with twisted pair cables and connecting directly to the board.
SPI or I2C might have better error correction than your customer serial protocol. I would see the other answers for that.

XBee Send To All

I have a simple xbee network operating where there are a bunch of slaves operating remotely and all talking to one master, who is connected to the server computer. That works no problem.
The slaves all send their ID as part of the packet and I'd like to have the master deliberately send an Ack after a delay. I'm trying to figure out how to do this efficiently and it seems that the only plausible way that doesn't involve reprogramming the master before each Ack is to send the Ack to all slaves and have them ignore the packet if it's not meant for them.
That solution is ok - I just can't figure out the command to use to do this. Is there some sort of Serial sendAll command? All of the devices are on the same ATID.
Typically in this situation, you would configure the master in API mode so you would get "Receive Explicit" frames with source addressing information, and could send with the "Transmit Explicit" frame type, and include addressing information in your frames.
If you use AT mode (transparent serial mode), then you're stuck having to change the DH and DL parameters on your coordinator every time you want to change who you send to. You should avoid using broadcast packets, since each one results in lots of network traffic (IIRC, each router will send the broadcast packet three times).
I do not know of a good XBee library on the Arduino, but it might be possible to port Digi's Open Source ANSI C XBee Host Library to that platform.

Resources