I am using the AltBeacon API to send beacons in an Android app. I am using the startRangingBeacon method with the deafult region as an argument -
region = Region("all-beacons", null, null, null).
I know that beacons are sent with the frequency of 1 second. Is it possible to change this frequency?
I tried to search for a frequency variable in the BeaconManager but could not find one.
Simply call:
beaconManager.scanPeriod = 2000L // set callback to 2000ms instead of the default 1100ms
Be aware that increasing the frequency of callbacks will sometimes mean you don’t get detections, as some beacons do not advertise more frequently than once per second. If no detections are made, the callback will have a beacon count of zero.
Related
I am trying to implement an SLM app for iOS using AudioKit. Therefore I need to determine different loudness values to a) display the current loudness (averaged over a second) and b) do further calculations (e.g. to calculate the "Equivalent Continuous Sound Level" over a longer time span). The app should be able to track frequency-weighted decibel values like dB(A) and dB(C).
I do understand that some of the issues im facing are related to my general lack of understanding in the field of signal and audio processing. My question is how one would approach this task with AudioKit. I will describe my current process and would like to get some input:
Create an instance of AKMicrophone and a AKFrequencyTracker on this microphone
Create a Timer instance with some interval (currently 1/48_000.0)
Inside the timer: retrieve the amplitude and frequency. Calculate a decibel value from the amplitude with 20 * log10(amplitude) + calibrationOffset (calibration offset will be determined per device model with the help of a professional SLM). Calculate offsets for the retrieved frequency according to frequency-weighting (A and C) and apply these to the initial dB value. Store dB, dB(A) and dB(C) values in an array.
Calculate the average for arrays over the give timeframe (1 second).
I read somewhere else that using a Timer this is not the best approach. What else is there that I could use for the "sampling"? What exactly is the frequency of AKFrequencyTracker? Will this frequency be sufficient to determine dB(A) and dB(C) values or will I need an AKFFTTap for this? How are values retrieved from the AKFrequencyTracker averaged, i.e. what time frame is used for the RMS?
Possibly related questions: Get dB(a) level from AudioKit in swift, AudioKit FFT conversion to dB?
I read somewhere, that beacons on apple, work in a similar way as geo fences, and there too is a limit of 20 per phone.
Is this the case?
Our use case: We want to send push notifications to users when the app is not running and the phone is not awake (in the pocket). We are thinking of relying on beacons instead of geo fences in order to avoid hitting the limit of 20 fences per phone and having to deal with significant location change function and similar solutions (for now).
Beacons work similar as geofences. You will get notified when entering or exiting a beacon-region (in bluetooth range) and you can also range all beacons around to get their ids.
There is also for CLBeaconRegions the 20 regions limit. See:
https://developer.apple.com/reference/corelocation/cllocationmanager/1423656-startmonitoringforregion
With a combination of monitoring regions and ranging, you could be able to do your stuff even with one region. (Depends heavily on your use case)
If you want to send geo-based notifications, beacons could work for you.
Yes there is a limit of max 20 regions (both beacon and geofence combine).
There are ways you can monitor 1000s of beacons but it depends on the use case.
You can use different wildcards and monitor 1000s of beacons but with some limitations. You have to play with beacon configurations like beacon UDID, major and minor values.
If you are only interested in enter or exit of any of the beacons (and not interested in specific beacon). You can actually just set the same UDID of the all the beacons and only monitor one beacon region will solve your problem.
let region = CLBeaconRegion.init(proximityUUID: UUID.init(uuidString: "YOUR_BEACONS_UDID_32_DIGITS")!, identifier: "beacon_region1")
locationManager.startMonitoring(for: region)
You can also group the beacons with UDID and Major value.
let r1 = CLBeaconRegion.init(proximityUUID: UUID.init(uuidString: "YOUR_BEACONS_UDID_32_DIGITS")!, major: 1000, identifier: "region_1000")
So you can monitor 20 groups of beacons in background and each group can have as many beacons as you want.
Although CoreLocation APIs limit beacon region monitoring to 20 regions (combined with geofence regions), you can look for nearly 86 billion different beacon locations for the purpose of sending notifications to a user.
Yes, that's right. 86 billion -- 85,899,345,920 to be precise. Think that's enough?
The simple technique is to combine beacon monitoring APIs with beacon ranging APIs. Using monitoring, you can wake up your app in the background when any one of your beacons is detected. Then using ranging APIs you can read the exact beacon identifiers detected, and send a push notification to the user. This will all work with the phone still sitting in the user's pocket.
Because each beacon identifier includes a major (0-63355) and a minor (0-63335), you can monitor for the maximum 20 beacon regions with a different ProximityUUID, and get 20 x 65536 x 65536 = 85,899,345,920 different combinations.
let region = CLBeaconRegion.init(proximityUUID: UUID.init(uuidString: "2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6")!, identifier: "beacon_region1")
locationManager.startMonitoring(for: region)
locationManager.startRangingBeacons(in: region)
// TODO: repeat the above for up to 19 more regions
...
public func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
for beacon in beacons {
var uuid = beacon.proximityUUID
var major = beacon.major
var minor = beacon.minor
// TODO: Send a unique local notification to the user for this
// uuid/major/minor combination identifying a particular place
}
}
There are some limits to this approach. If your beacons are placed within overlapping radio range of each other (~ 50 meters) then a user dwelling by one beacon for awhile then walking to the one next door will not get a background wakeup unless the beacons are in two different regions. There are some games you can play to get around this limitation, but for many use cases you don't even need to bother.
I've got a class that implementing CLLocationManagerDelegate and monitors a beacon region. It receives didEnterRegion and didExitRegion events, amongst other things.
Sometimes I get rapid switching between region entered and left states, even though I'm sat next to the beacon within 1m. The beacon advertising frequency is set to 500ms and TX power is set to -79 and the RSSI is around -55 when measured within 1m range.
The entry/exit switching looks like this on a timeline
...
12:01 - didEnterRegion
12:02 - didExitRegion
12:05 - didEnterRegion
...
AFAIK iOS should wait 30 seconds before confirming an exit in order to avoid false, but this isn't happening.
Do you have any tips for solve this problem? Or if there's a library to do it for me?
Potential Solution?
Note: My initial solution idea is to write a class that buffers region entry/exit events for 10 seconds and then detects these false positives and removes them from the event stream. It would republish the event without the fluxuations. E.g. for the previous example on one event would be published.
12:05 - didEnterRegion
If you like this approach, any ideas for a simple implementation in Swift?
I have a bunch of questions concerning Timing Advance in GSM :
When is it defined ?
Is it the phone or the BTS who's in charge of defining it's value ?
is it dynamic, does it depends on certain situations ?
Let's say that I figured out a way to get the exact value of the Timing Advance (GSM Layer 1 Transmission level) from the phone's modem :
In order to verify my solution, I'm supposed to put my phone over and over in a situation where he have to use/change the Timing Advance while I log its value...
How can I do that ?
Thanks
In the GSM cellular mobile phone standard, timing advance value corresponds to the length of time a signal takes to reach the base station from a mobile phone. GSM uses TDMA technology in the radio interface to share a single frequency between several users, assigning sequential timeslots to the individual users sharing a frequency. Each user transmits periodically for less than one-eighth of the time within one of the eight timeslots. Since the users are at various distances from the base station and radio waves travel at the finite speed of light, the precise arrival-time within the slot can be used by the base station to determine the distance to the mobile phone. The time at which the phone is allowed to transmit a burst of traffic within a timeslot must be adjusted accordingly to prevent collisions with adjacent users. Timing Advance (TA) is the variable controlling this adjustment.
Technical Specifications 3GPP TS 05.10[1] and TS 45.010[2] describe the TA value adjustment procedures. The TA value is normally between 0 and 63, with each step representing an advance of one bit period (approximately 3.69 microseconds). With radio waves travelling at about 300,000,000 metres per second (that is 300 metres per microsecond), one TA step then represents a change in round-trip distance (twice the propagation range) of about 1,100 metres. This means that the TA value changes for each 550-metre change in the range between a mobile and the base station. This limit of 63 × 550 metres is the maximum 35 kilometres that a device can be from a base station and is the upper bound on cell placement distance.
A continually adjusted TA value avoids interference to and from other users in adjacent timeslots, thereby minimizing data loss and maintaining Mobile QoS (call quality-of-service).
Timing Advance is significant for privacy and communications security, as its combination with other variables can allow GSM localization to find the device's position and tracking the mobile phone user. TA is also used to adjust transmission power in Space-division multiple access systems.
This limited the original range of a GSM cell site to 35km as mandated by the duration of the standard timeslots defined in the GSM specification. The maximum distance is given by the maximum time that the signal from the mobile/BTS needs to reach the receiver of the mobile/BTS on time to be successfully heard. At the air interface the delay between the transmission of the downlink (BTS) and the uplink (mobile) has an offset of 3 timeslots. Until now the mobile station has used a timing advance to compensate for the propagation delay as the distance to the BTS changes. The timing advance values are coded by 6 bits, which gives the theoretical maximum BTS/mobile separation as 35km.
By implementing the Extended Range feature, the BTS is able to receive the uplink signal in two adjacent timeslots instead of one. When the mobile station reaches its maximum timing advance, i.e. maximum range, the BTS expands its hearing window with an internal timing advance that gives the necessary time for the mobile to be heard by the BTS even from the extended distance. This extra advance is the duration of a single timeslot, a 156 bit period. This gives roughly 120 km range for a cell.[3] and is implemented in sparsely populated areas and to reach islands for example.
Hope this Answer the question:)
It's defined everytime the BTS needs to set the define the phone's transmission power, which happens quite often.
It's the core system (BTS in GSM) who totally in charge of defining it's value.
It's very dynamic, and change a lot. Globally, the GSM core system is constantly trying to find the exact distance between the BTS and the MS, so it constantly make a kind of "ping" to calculate it. The result of such operations is generally not that accurate since there are a lot of obstacles between the mobile and the BTS (it's not a direct link in an open space).
Such operations happens a lot, so use your smartphone. Simply.
I want to set the major and minor value correctly as I enter in a region.For example,I have different queues for different kinds of customer. Like Premium and silver categories.
If a customer goes in the lane of Premium, He should broadcast his major value as the value of the lane he is standing i.e. Premium and the number as minor.
How to set these values correctly according to the current position of the customer?
Premium = 1;
Silver = 2;
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:premium minor:2 identifier:#"com.example.beacon"];
The major and minor values are set on the beacon - these are the values that are received by your app to indicate the region where the device is located.
So, in your case you would have to have two beacons, one configured the with 'premium' value and one with the 'silver' values but with the same UUID. In your app you can define the region just by UUID and examine the major/minor in didEnterRegion To determine which specific beacon was detected.
However, Unless the queues are a fair distance apart you may have difficulty locating the user accurately