Greetings, I am just trying to get up and going with PSoC Creator to make a prototype and have found some example code that I think will help me greatly in the 100 Projects in 100 Days, namely, the Day 10: Observer and the Day 11: Central Observer projects. However, in them the BLE component is v.1.10 and PSoc Creator 4.0 is completely unable to deal with that; it just errors and can't build.

Is there any way around this? Or any way I can update the component? I can drag the new BLE_3.20 component into the schematic, of course, but I don't know how to configure it and make it work (at all! That's the whole point of the example code: to show me how!)

OK, awesome! Will do. I just got done downloading and installing, in turn, Creator 3.0 SP2 and then 3.2, since those were the versions around back when this project was made. Neither of them were able to build it either.

Cypress should update the PDFs with all those projects to give build instructions including that necessary Update Components step. Even though it was essentially telling me that right in the error message, I would have probably never figured it out.

For all future Googlers: The Observer project is working great on my CY8CKIT-042-BLE, cranking out beautiful reports telling me about all my BLE beacons from CYALKIT-E02 and CYALKIT-E03. All build errors are solved. Such as:

Error in component: cy_boot. The cy_boot_v4_20 component (cy_boot) is not compatible with the selected device. Please check the component datasheet for details on updating to a compatible component.

The instance 'BLE', of component BLE_v1_10, contains an error. Unable to locate and customize component 'BLE_v1_10' used in schematic

The fitter aborted due to errors, please address all errors and rebuild.

Thanks again, Bob. If Cypress doesn't pay you, they should! Have the happiest of Christmases!

I think that I had heard that before, actually, but I'd forgotten. Tomorrow then, that's great!

I have another question. My project is to have one BLE device periodically (every ten seconds) scan for the presence of several BLE beacons. It doesn't connect to them or anything else, just passively scans to see if they're there in range and advertising. Then when it sees one is missing it triggers an action -- say, a red LED to turn on.

Do you happen to know of any sample code that's a little closer to what I'm trying to do?

The Observer project that you're already working with is probably one of the simplest places to start for the functionality you're after. Don't worry about the periodic nature just yet (though you'll likely want to use the watchdog timer to trigger it periodically if you're at all concerned with power consumption, otherwise the TCPWM component is easiest for simple timers).

You'll have to modify the code inside the CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT event handler case, originally on line 98 of main.c. You will want to look at the contents of the "data" member of the advReport object, and you will have to parse through the advertisement field(s) from the beacon to see whether the contents match what you're looking for (i.e. the scan result came from a beacon of interest or not).

Separately, you'll have to add an output GPIO (add a Digital Output Pin component to the schematic) that you can assert or de-assert based on whatever your found/missing criteria are.

I am a non-programmer groping blindly through this, but your tutorials are good and I'm learning!

Now the next step I need to figure out is how to make the scan go through and recognize each dongle only once (or zero times if it's not there) and then how to make the scan periodic (every, say, 15 seconds -- hopefully that's long enough to very reliably read advertising packets from up to ten dongles. Is it?).

I'll attach a bundle of my current code. Right now I have it set up to scan for the data I've changed in the UUID (in 24u). Depending on which dongle is found, it increments an integer variable in such a way that I'll be able to know which dongle(s) may be missing by just checking the value of that variable. It also changes the built-in LED color depending on which one it finds, but that's just for learning and testing purposes. In the end the goal is a green light on for all there, off for one or more missing, and then multiple red LEDs which turn on corresponding to which dongle(s) may be missing.

So, it does the first scan, finds all dongles there, so a green LED turns on. It does another scan in 15 seconds, finds all dongles still there, so the green LED stays on. Eventually, many 15 seconds down the road, it does a scan, finds two dongles suddenly missing and so turns off the green LED and turns on the proper two red LEDs.

This looks good so far. One thing I would recommend after looking at your code is that you first/also validate that the rest of the advertisement report (other than the ID byte at index 24u) also matches what you expect from the devices you're scanning for. This would likely be a simple memcmp() against a pre-initialized byte array containing the preceding data in the advertisement payload, likely a "Flags" field and probably a 128-bit UUID field or something like that. If you don't filter results for this data first, you may get false positives from completely random BLE devices nearby which just happen to have a valid byte in position 24u.

Concerning the periodic scan and finding up to ten dongles, that depends on exactly what you mean. Scanning every 15 seconds is long enough to find 10 dongles as long as the scan itself is active for a large enough portion of that time (see docs on Scan Interval vs. Scan Window) and if the broadcasting devices are advertising at a suitably fast rate (e.g. 10 Hz or something). Typically, scanning devices run at a relatively high duty cycle like 50%-100%, and are much less power-constrained than broadcasting devices--or they are AC-powered and have no power constraints at all. A scanning device needs to be in an RX state usually for hundreds of milliseconds at a time, at least, in order to reliably pick up a packet from a device that is advertising every 100ms or so. This is because the scanning device needs to cycle between all three available advertisement channels and hope it overlaps at some point with the one the advertising device is using at that moment, since there is no synchronization between typical adv/scan processes prior to a connection establishment.

I can control 13 bytes of the the advReport.data array -- [12u] - [24u].

Using memcmp() to compare *portions* of byte arrays seems either to be "a huge bottleneck," or to be very complicated, and prone to bugs and errors even for professional programmers! That's from what I can tell from this conversation:

So, I decided to nix that idea and just compare the 13 bytes in the simple == matching method I was using to compare the one byte.

And I succeeded in making a timer. I figured out that the watchdog timer only goes up to 1 second (changing the RTC_COUNT_PERIOD to anything bigger than 32767 does not do anything! Be warned!) but with some simple multiplication was able to make a nice seven second timer. Or any arbitrary number of seconds, but seven seems enough to read five dongles 95-99% of the time.

So, find attached the code for a program that periodically polls for object detection, in case it's useful to anyone else in the future.

Next step: to figure out how to reprogram the CYALKIT-E02 kit's solar dongles to stop wasting energy reading the temperature and humidity and instead just advertise at an interval of my choosing!

StackOverflow is an excellent resource (I use it almost daily!), though in this case it looks like you've found an answer that doesn't actually apply in your case. The question you posted deals with bitfields within multibyte arrays, which is more complex than what I recommended. Remember that each byte is made up of 8 bits, so their use of the term "bit" doesn't just mean "small portion" but rather refers to splitting up bytes on atypical boundaries. It is true that memcmp() doesn't give you that functionality on its own. However, even if you needed it, the extra processing overhead required to do the bit shifting and masking that the answers recommend would be negligible.

In any case, let's say you have an advertisement payload that always contains the same 13 bytes [0x00, 0x11, ..., 0xCC] starting in index 5 of the payload. You could use a predefined byte array and memcmp() as follows:

Of course, your method of comparing individual bytes will be just as functional. It's just a little more cumbersome to write. But since you have it working already, there's no compelling reason to change it.