16 Arduino relays with xbee module

Hi all.

I am trying to connect an Arduino with 16 relays to the Smartthings Hub, while avoiding the Smartthings shield. Ideally, I would like to see each relay as an individual device (On/Off output) but I am not sure how to proceed. For now, I am trying to set it as a device with multiple EndPoints, but this would imply seeing it as a single device, am I right? So far I have followed George’s (http://www.falco.co.nz/electronic-projects/xbee-to-smartthings) and @JohnR instructions from the forums, and got the device to show in the app, near my other Things (although for the last hours there seems to be a glitch even with this).

So, to detail: I send the Device Announcement packet, I receive from the Hub:

ZBExplicitRxResponse:
From: 0xD052A853EE1C0001
From: 0x0000
Receive options: 0x01
Src endpoint: 0x00
Dst endpoint: 0x00
Cluster id: 0x0005
Profile id: 0x0000
Payload: 2A 42 E6 --> all ok, this is a frameId + my xbee address

Next, I report an endPoint (0xBB), and I get back:

ZBExplicitRxResponse:
From: 0xD052A853EE1C0001
From: 0x0000
Receive options: 0x01
Src endpoint: 0x00
Dst endpoint: 0x00
Cluster id: 0x0004
Profile id: 0x0000
Payload: 2B 42 E6 BB --> frameId + my xbee address + endPoint address

All seems fine, it asks for an Endpoint Description, I send a packet similar to George’s (ClusterID 0x8004, inClusters 0x0000,0x0003,0x0006), and I get back:

ZBExplicitRxResponse:
From: 0xD052A853EE1C0001
From: 0x0000
Receive options: 0x01
Src endpoint: 0x01
Dst endpoint: 0xBB
Cluster id: 0x0000
Profile id: 0x0104
Payload: 10 25 00 01 00 --> where 0x25 seems to be a frameId, it increases for the next 2 (repeated) packets.

I don’t know how to proceed any further. What’s with the last packet? (I get the same response, even when I announce multiple EndPoints, and I was expecting it to inquire about all the endPoints). I can provide more details if needed. Thanks for all your help.

Not sure what ST is saying in that last message, but you should be careful using multiple endpoints. They are only partially supported in the ST API. Not at all supported in the new zigbee.writeAttribute etc functions. Maybe someone here can correct me, but I’ve had better luck putting everything on one endpoint.

Also I’d love to see your solution to a multiple-contact device type. The only solution I have found is using the capability for one and custom commands for the others. Ideally, something like adding virtual child devices to the device handler, but I don’t think that’s possible.

I know you said you’re wanting to avoid the ST ThingShield… may I ask why?

Take a look at my full solution for controlling 16 relays with support for local pushbutton control here. I also explain the data flow required for a many to one / one to many device using what I call a “Multiplexer SmartApp” with virtual devices.

Hopefully, it at least helps get you started.

@jh0

1 Like

Thanks both for your message. I managed to decode that last payload using the Zigbee Cluster Library documentation: it’s sent to the Basic Cluster (Cluster id: 0x0000), Payload: 10 25 00 01 00 (where 0x10 = Server to client, 25 = frame number, 00 = Read Attribute command, 0x00 01 = Attribute 01). So basically it’s asking what’s the value of that attribute. After answering with a Read Attribute Response command (containing the string “off”), I was asked similarly about Attribute 04 and 05. I’m not yet sure what they stand for, but I sent “off” to all of them and finally the device was automatically added to the Hub.

When I reported 2 endpoints, the hub asked the same things about the second endpoint. However, the device is now listed in MyDevices only with the first endpoint. I’m not exactly sure how to proceed further, but I’ll update when I get something usable. As I mentioned, I’d like to see them as individual devices.

As for the ST ThingShield: it’s not yet available in Europe due to some missing certifications, and it’s also a little more expensive than a plain xbee. I like your implementation in Arduino, and I think I might end up using your trick to get independent (virtual) devices.

Thanks.

1 Like

You may have noticed this but the header (first few bytes) in the data packet changes a little between ZDO and ZCL packets. When your device receives a packet with the destination of End Point 0 (ZDO ZigBee Device Objects) you will have to parse them different than packets with a destination above End Point > 0 (ZCL ZigBee Cluster Library).

Sounds like you have been doing your homework!! As I think you have discovered attribute 0x0004 of ZCL 0x0000 (basic cluster) is the Manufacture Name and Attribute 0x0005 is the Model Identifier (see table 3.8 in the ZB Cluster Library on page 79). To respond to these read attribute request you should format your packets as detailed in that section. On the other hand you can also just ignore them for now. SmartThings will want you to give them a manufacture name and model ID if you want to get this device certified. But for now you should be fine just ignoring these request if you answered all the previous packets correctly.

I think your next step is to create a device handler and connect it to your device. You can then experiment with sending on / off commands to various end points.

End Points: Maybe this will help a little. The following is all from your Arduino’s perspective. Each ZigBee packet has a source and destination endpoint. The source endpoint is simple to deal with just use it in your reply as the destination endpoint. The destination endpoint is where the magic happens. As I mentioned above, if the destination end point is 0 (and the profile ID is 0x00) then the packet is a ZDO packet. You usually will only have to parse these packets at boot-up and whenever you reconnect to the hub.
End Points above 0x00 are there to be used as application level addressing and the ZigBee Cluster Library can take advantage of them. Lets take your 16 port relay board as an example. You have already discovered the ZigBee On/off cluster (0x0006). It defines how your device will receive an on, off, and toggle command. By having this defined you can write a method on your Arduino to parse the packet and figure out if it is a on command, off command, or toggle command. Lets say on your Arduino you have a method called setRelay1(action) you call that method with your ZigBee packet parsing routine like this setRelay1(“on”);. That’s simple enough but in your case you have 16 relays to control. Now lets add destination endpoint support to your application. If you assign an endpoint to each relay you can change your setRealy1(action) to setRealy(ep, action) now your parse method just needs to pass the ep number along with the command to the setRealy method. So the destination endpoint is being used to actually address your relays!! One last tip on destination endpoints: Often endpoint address 0xFF is used as a broadcast endpoint. So say you want to turn all your relays on at the same time. Well just send the on command to endpoint 0xFF form your SmartThings device handler and on your Arduino send the on command to each relay.

I hope this helps and encourages you to keep plugging away. Once you get your first app working a huge world is going to open up for you!! I’m looking forward to reading about your progress!!

2 Likes