Can RaspberryPi with BLE Dongle detect iBeacons? - raspberry-pi
I bought a developer kit from Radius Networks that includes a ioGear GBU521 BLE 4.0 dongle and a Raspberry Pi. I also bought one of their RadBeacon iBeacons. They both work as advertised, but I was kind of surprised by what I got.
I had assumed that the RaspPi could detect iBeacons. Instead, the kit is setup to create an iBeacon. My use case is to detect when a forklift enters a particular room so I can send work to them. My thought was to put an iBeacon on the forklift then put a RaspPi searching for iBeacons. And when an iBeacon (forklift) was detected, you could conclude that it is nearby. I would wire the RaspPi into the LAN and have it communicate the information via REST or similar. I know I could put a suitable Android or Apple device and accomplish it that way, but I don't see why this dongle can't detect these iBeacons and tell me what their UUID's are? What am I missing?
Yes! You can use your Raspberry Pi to scan for iBeacons. We've put together a script below that does this, you can also do it yourself with these steps:
Start a background process that does a bluetooth LE scan:
sudo hcitool lescan --duplicates &
With the --duplicates setting the scan will not ignore multiple packets from the same iBeacon.
Start an hcidump and pipe the raw output to a script that will filter for iBeacon packets:
sudo hcidump --raw
The filtering is the tricky part, the raw output from hcidump isn't formatted nicely and also shows packets that aren't iBeacon transmissions. To solve this, we made a filter script that reads in the output line by line and separates out the raw packets from the other output (i.e., MAC addresses, etc.). We've done a lot of research at Radius Networks on the iBeacon bluetooth profile, which we used to identify iBeacon packets and filter them out from packets from other devices.
We've put this all together into an ibeacon_scan script that does everything, including converting the raw identifiers into human-readable form. You can download it here. Soon, we'll include this in the iBeacon Development Kit to add scanning capability.
Here's an example of the output from the script:
$ ./ibeacon_scan
UUID: 74278BDA-B644-4520-8F0C-720EAF059935 MAJOR: 0 MINOR: 73 POWER: -50
UUID: 2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 MAJOR: 1 MINOR: 6 POWER: -59
UUID: E2C56DB5-DFFB-48D2-B060-D0F5A71096E0 MAJOR: 6 MINOR: 9 POWER: -55
We've also included a -b option for bare output that is easy to parse into other scripts, here's an example:
$ ./ibeacon_scan -b
2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 1 6 -59
E2C56DB5-DFFB-48D2-B060-D0F5A71096E0 6 9 -55
74278BDA-B644-4520-8F0C-720EAF059935 0 73 -50
You can use this option and pipe the script's output to your script to trigger actions when iBeacons with certain identifiers are detected.
EDIT: We've reworked this script to make it more responsive and robust and incorporated it into the latest version of the development kit. The update is available to download here.
EDIT2: As pointed out by #sai-ramachandran, you can augment this script to capture the RSSI of each iBeacon packet in addition to POWER. To do this, add the following lines to the script:
RSSI=`echo $packet | sed 's/^.\{132\}\(.\{2\}\).*$/\1/'`
RSSI=`echo "ibase=16; $RSSI" | bc`
RSSI=$[RSSI - 256]
and be sure to add RSSI to the output:
echo "UUID: $UUID MAJOR: $MAJOR MINOR: $MINOR POWER: $POWER RSSI: $RSSI"
You are correct that the iBeacon Development Kit is not designed to detect iBeacons -- it is designed to transmit as an iBeacon.
That said, it is possible to detect iBeacons with a Raspberry Pi using a variation of what #ChrisStratton suggests in his comment. See the answer from my colleague #jjnebeker who has made a script to do want you want.
https://github.com/RadiusNetworks/android-ibeacon-service
Use this to detect iBeacons.
It allows Android devices to use iBeacons much like iOS devices do. An app can request to get notifications when one or more iBeacons appear or disappear. An app can also request to get a ranging update from one or more iBeacons at a frequency of 1Hz.
Related
No GPS on Raspberry Pi LineageOS 18.1
UPDATED See edit! I have installed LineageOS 18.1 for Raspberry Pi 4 (which is an awesome piece of software) and everything seems to be working correctly. With the exception of GPS. I have an A9G connected to the Pi. It is connected to the first Pi's UART and I can see the data coming on ttyAMA0. :/ # microcom -s 9600 /dev/ttyAMA0 $GNGGA,092800.998,4955.7547,N,00900.2330,E,0,0,,102.0,M,48.0,M,,*5E $GPGSA,A,1,,,,,,,,,,,,,,,*1E $BDGSA,A,1,,,,,,,,,,,,,,,*0F $GPGSV,1,1,00*79 $BDGSV,1,1,00*68 $GNRMC,092800.998,V,4955.7547,N,00900.2330,E,0.000,0.00,211021,,,N*55 $GNVTG,0.00,T,,M,0.000,N,0.000,K,N*2C $GNGGA,092801.998,4955.7547,N,00900.2330,E,0,0,,102.0,M,48.0,M,,*5F $GPGSA,A,1,,,,,,,,,,,,,,,*1E $BDGSA,A,1,,,,,,,,,,,,,,,*0F $GPGSV,1,1,00*79 $BDGSV,1,1,00*68 $GNRMC,092801.998,V,4955.7547,N,00900.2330,E,0.000,0.00,211021,,,N*54 $GNVTG,0.00,T,,M,0.000,N,0.000,K,N*2C $GNGGA,092802.998,4955.7547,N,00900.2330,E,0,0,,102.0,M,48.0,M,,*5C I changed the GPS receiver to use ttyAMA0 in /vendor/build.prop # GPS ro.kernel.android.gps=ttyAMA0 I also trying with adding ro.kernel.android.gpsttybaud = 9600 or ro.kernel.android.gps.speed = 9600 But not a single App can receive GPS data. I have the feeling I am missing something very simple but essential. Any help very appreciated EDIT Ok, I am a step further. The first problem was apparently, what a bummer, a permission issue. I adjusted it in the file: /vendor/ueventd.rc From: /dev/ttyAMA0 0660 bluetooth bluetooth To: /dev/ttyAMA0 0660 system radio Now it seems that the data is being received and correctly interpreted. But when I open a GPS testing App, the signal is flickering. It almost like if something else is reading from ttyACM0. Is it possible? just to clarify what I mean with "flickering", please take a look at https://cloud.sobi.pro/f/68f0398aea1549918376/
I also had the same flickering issue. I can see it in a map program or with physics toolbox where I can see the GPS LAT LONG. It flickers between the "real" position and 0.00000 for the LAT and LONG. I am using LineageOS17.1 on a Raspberry Pi 4 my Ultimate GPS USB is from Adafruit and is on /dev/ttyUSB0 I tried updating build.prop in both /vendor and /system with the ro.kernel.android.gps.speed = 9600 and ro.kernel.android.gps = ttyUSB0 The solution that I eventually used was to remove the r0.kernel... from both build.prop and use the app GPS Connector https://play.google.com/store/apps/details?id=de.pilablu.gpsconnector&hl=en_US&gl=US Enable in developer options under "select mock location app" you can select the GPS Connector. You can have the GPS Connector app start at boot. If you find a more elegant solution than using an app, please reply.
Flutter and Iot devices
I am currently building an app that controls a single actuator and a LED strip. The controller for the actuator and LED strip is based on an ESP32. On the ESP32 I have used the <ESPAsyncWebServer.h>, <ESPAsyncWiFiManager.h> to set up and connect the ESP to the local wireless network. In the app I would like to send some commands to the ESP like http://<ESP32_IP>/led_set?level=<level> and http://<ESP32_IP>/act_open and so on, this shouldn't be an issue. Normally I would set up mDNS on the ESP and in the Flutter app, however several of the ESP controllers are already shipped to the customers. So I am looking for another way to identify the ESP. At the moment I have used the ping_discover_network library and the ESP shows up fine on port 80. I am however not able to separate the ESP from the other devices that shows up on port 80. Do any of you have any suggestions? Thank you in advance
You don't have many good options. If you only want to identify a few devices which have slipped through your fingers without mDNS, you can use their MAC address as a filter. If you happen to know their individual MAC addresses, then that should be quite painless. Otherwise you'd have to look for devices with MAC OUI (first 3 bytes, usually) ranges allocated to Espressif. Espressif has several OUI ranges, but if your devices were from a single batch of ESP32 module of the same type, they'll be using the same OUI so it should be quite easy to figure out. E.g. a batch of modules I have all start with 40:F5:20:... Of course, if a third party installs their (unrelated) ESP32 module into the same network, you'll have a chance of identifying those as well, but such is life. This is obviously a stop-gap measure. Make sure further devices go out of door with some identification (mDNS or otherwise).
Attendance reader with iBeacon/eddystone and raspberry
I'm a bit confused. I explain to you my project, I would like to make a "reader" by using beacon technology (ibeacon for apple, eddystone for android) using a raspberry pi 3. The smatphone application sends an acknowledgment code when passing the person. The raspberry marks and updates an online database. I wanted to ask, first of all can this be done? My problem is to realize the beacon transmission, then for the app and the database I have no problems. I tried using bluez but I can not detect the phone. Is there any online tutorial that could help me? Thanks
If you are looking to use the phone to emit a beacon transmission and then use the Raspberry Pi 3 to detect the beacon, then yes, this is possible. I put together a tutorial on how to use the Android Things to detect beacons on the Raspberry Pi 3. The problem with using BlueZ for beacon detection is that it is simply not stable on the Raspberry Pi, and will freeze up and stop detecting requiring a reboot.
How do I detect iPhone on network?
I am trying to detect if my iPhone is in the same network as my Raspberry Pi. I would like to execute a script when I am at home and my iPhone's presence is registered in my LAN. It seems that when the phone is in standby not even the iphone-sync port (6207/tcp) is found. "/usr/bin/nmap -n -sT -p62078 [my phone's local IP]" shows no host. I wonder what else I could scan for. Obviously the phone is online and ready to accept facetime calls (data via 3G is deactivated). Could I accomplish something with avahi which I am using on my Raspberry Pi, or are there other ways.
I've just spent a week beating on this problem so I can refrain from sending SMS home alarms to my wife when she's at work. Pinging won't work because the iPhone won't respond to ICMP when asleep. Reading the ARP cache won't work because a sleeping iPhone will come and go (check it every 30 seconds for a few minutes). The only way I have found to 'reliably' determine when my two iPhones are on my local (home) network is to use the PCAP dotnet library to look for any packets originating from either of the phones' MAC addresses. For example, if you run Wireshark with the capture filter ether src <iphone-mac-address> you will see a surprising amount of network discovery/announcement traffic from the phone. It still has quiescent states, but so far the longest interval I have seen between captured packets is around 10 minutes. You would have to wait until you have not heard from the phone for some interval (I use 15 minutes) before declaring it not-home. With this technique you will find a phone quickly when it rejoins the home network, assuming your phone is configured for DHCP. I also use port mirroring on my main Ethernet switch to include traffic from my wireless access points. I don't have a Raspberry Pi solution for this, because my linux expertise is very limited, but someone else may be able to help you along those lines. I have a Windows Service using the PCAP library and so far it works reliably, with the limitation of waiting 15 minutes before deciding an iPhone has left the network. * update 2-3-2018 * I have this detection algorithm down to about 5 minutes, using a combination of ping/arp messages directed to each phone, about once per minute. Seems to work great.
You can find a list of devices on your network by investigating your arp cache. arp -a Simply write a bash script to run arp -a at a regular interval, and search for the mac address of your phone. You could go even further with this and perform different actions depending on what brand of device is connected. The first 3 hexadecimal digits of a mac address are the vendor id. Take the following mac address: 00:19:E3:AB:CD:EF 00:19:E3: is one of the registered mac address for apple devices. By comparing the devices on your network with this list, you could detect when for example a '3com' device, or a 'dell' device attaches to your network. http://www.coffer.com/mac_find/?string=apple
You can do "arp-scan -l -r10" for that (tested this myself), but the problem is if mobile data enabled the iphone will go and suspend wifi if screen is locked to safe battery. so you need to disable mobile data .. then arp-scan will work.
How to send data to iPhone from external device
I have an external device that we manufacture that basically monitors 4 voltages, converts them to a 16 bit digital number then streams this info back to a PC every 100mS or so, using a serial over USB style chip. Basically a data logging system. We would now like to collect this information on an iPhone and I am wondering what is the best way to get the data into the iPhone? I am assuming there is no way we can physically connect directly to the iPhone dock connector as the protocol to do this is not available to iOS developers? Obviously we could do it over a WiFi network but there will not always be one and we want to keep the external hardware fairly simple, i.e. no need for a computer or Wireless router etc. If we add Bluetooth connectivity to our hardware would this work? I read that only 'Made for iPod' type Bluetooth devices will connect, in which case how can we achieve 'made for iPod' status? It would be relatively easy to add the necessary Bluetooth chips to get the system up and running. In an ideal world we would like to do this without having to use a 3rd party interface. I have been thinking about trying to digitise data as an audio signal – like a modem, and send it into the line input jack, but I don’t think it will be fast enough – this would be new territory for me. Anyway all suggestions gratefully received! Thanks!