I'm trying to figure out, how to connect two hm-10 module, when I do not know the slave MAC address. Imagine you have an electric longboard and lost you remote. You got yourself a new one and now want to pair with the board.
In the data sheet I cannot find any useful functions, to make this process easy.
I thought about making an unique name of the slave device and by making a pairing button on the master device. The pairing button would set the master device in the pairing mode (AT-ROLE1, AT+IMME1 in order to execute AT+DISC?). The results of the AT+DISC? command would be saved to an array and after finding the unique name of slave device, the index of the device/MAC address would be saved and used as a parameter for establishing the connection.
I'm using the firmware version v707.
The problem is, I do not find this solution as elegant and I think there must be a better way to do that, but I cannot find any information about it. Did anyone tried to do that and maybe has some insight? I'd very much appreciate it.
Only way I can think of on the HM10 is setting a unique name and scanning for that name.
Another way I have seen is some devices allow you to see service UUIDs in the advertising information so you can connect to the device that has the desired service UUID. But this doesn't seem possible on the HM10
Related
I can't find example how to do BLE pairing with Seeed XIAO nrf52840 board. It doesn't matter to me if it will be Arduino or Circuitpython libraries. Is there something like this somewhere?
I would like to use this board for my project, but would like to ensure that anyone cannot read or change values in the BLE services.
My idea of use is that on the server side I select the device I want to pair with and on the device side I confirm the pairing manually e.g. with a button. From that point on, the server can then communicate with the unit and read or change its values.
Thank you
With Arduino you could try this example: https://github.com/adafruit/Adafruit_nRF52_Arduino/tree/master/libraries/Bluefruit52Lib/examples/Peripheral/pairing_passkey
I am actually trying to implement this feature as well. I was trying in CircuitPython, but I could not find a suitable way. I opened an issue, as there was nothing in their documentation to help.
UPDATE 2023-01-03 - In CircuitPython BLE security is not yet implemented, see answer to the issue I opened.
I am engineering two BLE devices, a central and peripheral. (Using a PSoC 4 BLE, not that it matters)
There will be a lot of these in a small space, maybe up to 8 within range, but hundreds of peripherals and tens of centrals all coming and going, with no particular rhyme or reason behind which one central/peripheral the user will want to pair at any given time.
I also have an unrelated technology that makes it very easy for the user to move a blob of data from the central to the peripheral of their choosing. I believe this will make pairing much easier in most but not all scenarios.
I figure the non-BLE blob would contain at least the central's mac address, and maybe a randomly generated pin or shared key. Because the blob can only go from the central to the peripheral, the receiving peripheral is really the only device that knows the addresses of the two devices that are supposed to connect.
However, as I understand it, peripherals can't make outgoing connections. I can't swap roles because I still need the BLE search to work the traditional way.
I can think of a lot of ways to get this done, but I'm very interested in hearing the opinion of someone who has worked with BLE long enough to know what might fit best (or if I'm wrong about some assumption).
Some constraints I'm working with:
The peripheral is battery powered.
The usual search and pair method must also still work.
My own half-baked ideas:
Make the peripheral able to be a central too, but then does that
introduce more nuances and complications?
Broadcast from the peripheral, "whoever has X mac address,
please connect to me"
Put a similar message in the advertising packet and increase advertising
rate.
Directed advertising similar to above?
You could let the "non-BLE blob" contain a static random address which the central generates. After the peripheral receives that, it starts advertising with that static random address. The central is also configured to initiate a connection to that particular static random address. Will this work?
Being somewhat of a newbie I was wondering if there is a way to hard-code something on a peripheral that would only allow a single unique central/master to connect.....?
i.e. / eg
I have the ‘simple chat’ Arduino app on a RedBearLab Blend-Micro (which is for all intensive purposes the same as a Arduino Uno with a BLE shield) and I only want one single / unique phone to BE ABLE TO connect with it and therefore work with it.
My understanding is that the GAP handles security features during a BLE connection.
Therefore, is there some way to ‘code’ the peripheral device in / below one of the following includes:
spi.h ?
boards.h ?
EEPROM.h ?
RBL_nRF8001.h (or similar) ?
Other?
Didn't quite get an answer from Restricting the BLE peripheral device to connect to only one Master
OR
Am I stuck with EVERYTHING connecting but coding the peripheral in some other way in a GATT profile (I think) to ONLY do something with a predefined unique central/master (how/where to code?).
Many thanks for thoughts in advance
Being somewhat of a newbie I was wondering if there is a way to hard-code something on a peripheral that would only allow a single unique central/master to connect.....?
Theres the "Advertising Filter Policy" as specified in the Bluetooth Core V4.0 specification. Its a Byte in the Advertising Parameters as specified in Section 7.8.5 LE Set Advertising Parameters Command.
For example the value 0x02 reads Allow Scan Request from Any, Allow Connect Request from White List Only.
Then theres section 7.8.16 LE Add Device To White List Command.
That said, if your device confirms to the Bluetooth 4.0 specification, it should support these HCI commands. However there might be functions that simplify these procedures, wrapping those HCI commands for easier use. Check the Documentation of your device for such methods.
Good Luck!
I was asked to answer this question via email. It's been almost a year since I quit working on BLE. So I only answer this question based on my memories.
Basically #dominik has it right.
If the device is freshly new, it should advertise normally (without setting the whitelist only bit), then any central device could connect and bond. Once it is bonded, you should save this bonded flag and the bonded master's bd_addr to EEPROM. If the next time the master is lost, you will advertise with that white-list-only flag set. If a new central tries to connect, you could verify if its address is the same as your master.
I don't have the BLE spec at hand and I kind of forgot a lot about BLE already. Probably the spec says somewhere that if a central sees a peripheral device is broadcasting with white-list-only flag set, it wouldn't try to connect if it doesn't recognize that peripheral device. This saves both some effort.
But a master could always initiate a connection to your peripheral device regardless the white-list-only flag. So checking if the connecting central device's address is the same as your previously bonded master is the last resort.
[Update]
I used CSR1010 chips. I remembered that the BLE stack actually allows me to insert a list of bd_addr to the white-list data structure maintained by the stack. Then, with the white-list-only flag set, the lower-level stack layer will help you filter devices that are not in that white-list without your knowing.
However, you can always filter bd_addrs from your application code.
Does anyone know of a scheme whereby MODBUS addresses can be automatically set? In my situation I'll have a number of slaves power up and need some automatic way of assigning them addresses.
I know this is an old post, but I just came across this and thought I would give my answer just in case someone is attempting to do this now or in the future. If the goal is to assign a slave ID to a new slave (and you are developing the firmware for the slave devices), you can have the ID stored in a holding register that you can write a new ID to. This does require that:
You know the ID already. Maybe have all new slaves have a default ID, say ID = 1, so you know the ID beforehand.
You can only add one slave at a time and must change the ID before adding another slave to the network.
For example: Connect and power up the first slave device, which has a default ID of 1. Send a write command that will change the ID to 2 and send the master a response (using the slave ID of 1 in the response so it doesn’t timeout). Now the slave ID is 2. Next, add the next slave to the network, which it’s ID is 1. Now you have two slaves on the network with unique IDs. Just repeat as many of times that you need to.
Are you talking about SLAVE ID's? If so, that's just not going to happen... The SlaveID is vitally important for the Client to be able to address said slaves on the serial network. (RS485 serial network, presumably...).
So, there is no way to even send out a Modbus message and address it to SlaveID 1, and then somehow get that device to be SlaveID 1, because ALL of the devices would attempt to respond, in that case. Not to mention, there is NO method in Modbus to ASSIGN a Slave an ID... On the flip side of this...
Are you talking about performing some type of query to ask the slave devices which Modbus REGISTERS they have? Again, there is no Modbus way to do this, but with some code, you COULD query 40001, and if you get an error 2 back, then you know that register is not available. If you then loop through all of the registers, keeping track of which ones returned non-error, well--then you COULD do a form of "auto-configure", but... In all honesty? I would NOT recommend this, and I don't see a lot of value to even DOING this, because you not only have to know the REGISTER numbers, you have to know WHAT THE DATA IN THE REGISTER ACTUALLY MEANS!
What exactly are you trying to do anyway? Perhaps there is another way to accomplish this goal?
What you think you want: automatic Slave ID assignment in Modbus RTU.
What you actually want: constant, common Slave ID with Modbus TCP.
In a nutshell, all your Modbus Slave ID's get set to a fixed, common value and then you bridge them with a TCP stack that supports things like link-local addressing or DHCP. Then the TCP address assignment can be dynamically handled while preserving a constant SlaveID for each unit.
There are three broad options here depending on what hardware you already have:
There are commercial off-the-shelf devices (such as this) that can emulate TCP over RTU. I've not delved too deep into what they support and how well they work.
You could also add a whole ton of TCP to RTU bridges which will have built-in management for the TCP/IP layer and then use real Ethernet cabling. For a lot of devices, this could get expensive fast, but with Ethernet you have all sorts of bonus features like basically unlimited distance and improved CRCs. If you're looking to do this on the cheap, grab a dual-port Linux SBC (such as this or this) and throw mbusd (from here) on it.
If you have access to or are developing the firmware yourself, you could adapt something like uIP (simpler) or lwIP (faster) to communicate over RS-485 (UART). This would certainly be the cheapest option. Note that you should also have the ability to detect collisions on RS-485 to implement an IP stack correctly -- this involves echoing the receiver at all times and checking that the data-in and data-out match.
I am trying to network multiple Arduino Fio with Xbee as slaves and my computer as Master with an Explore and Xbee.
Suppose i send and command 'Read' over serial to all Arduinos. Everyone responds suppose 'OK'.
My problem is to make them respond something like 'Arduino ID1 says OK' or 'Arduino ID2 says OK' etc.
Now this may be easy of each arduinos have separate programs burnt into them. But in my case all arduinos are suppose to have identical programs.
I know we assign MyID and Pan ID to each Xbee while configuring them for the first time.
So i am looking for some function in the program burnt into the Arduinos example
'readMyXbeeID()' or something.
Any ideas how i can do this? Or any other way to achieveArd the same thing?
I was able to get MYID by using AT commands.
You will need to read the XBEE documentation confirm these.
Use "+++" to get in to command mode (not forgetting the > one second delay to 'guard' this sequence).
{ I used: delay(1200); Serial.print ( "+++" ) ; }
The XBEE will respond OK\r.
Then ATMY\r will give you MYID returned as an ascii string terminated with "\r".
[In my case I had set a MYID of 2 so I saw the string "2\r"]
Finish with the command ATCN\r to exit command mode.
If you want to manage communications with several devices, I recommend you to use the API mode instead of the AT mode. If you are working with Arduino, there are some really good libraries: Xbee-Api and XBee-Arduino. Here you will find useful information and examples that may help in your project.
I mentored a few projects with these libraries (complete beginners in ZigBee technology), and they got all concepts really fast. 100% recomendable.
Regarding your question, you are right about writing just one program for all Arduinos. Otherwise you will have to create different hex-files for each node, which makes no sense. The easiest way for identifiying the ZigBee nodes is just using i.e. the 64-bit physical address. You can get this address easily through AT Commands. But keep in mind that in API Mode, whenever you send a message, the source address is automatically included in the frame, so you do not have to include explicity this information.