<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>4343W &#8211; IoT Expert</title>
	<atom:link href="https://iotexpert.com/category/devices/4343w/feed/" rel="self" type="application/rss+xml" />
	<link>https://iotexpert.com</link>
	<description>Engineering for the Internet of Things</description>
	<lastBuildDate>Wed, 27 Jan 2021 13:07:42 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://iotexpert.com/wp-content/uploads/2017/01/cropped-Avatar-32x32.jpg</url>
	<title>4343W &#8211; IoT Expert</title>
	<link>https://iotexpert.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Tilt Hydrometer (Part 1) Overview &#038; Out-of-Box</title>
		<link>https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/</link>
					<comments>https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 04 Jan 2021 12:31:11 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<category><![CDATA[Tilt Hydrometer Data Collection]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=9747</guid>

					<description><![CDATA[Summary A discussion of a new series of articles about using the PSoC 6 + 43XXXX Wifi/Bluetooth combo chips to implement a data collection system for the Tilt2 Hydrometer.  Even if you aren&#8217;t specifically interested in hydrometers, this is a general purpose discussion of the design of an IoT device. Story In the middle of [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>A discussion of a new series of articles about using the PSoC 6 + 43XXXX Wifi/Bluetooth combo chips to implement a data collection system for the <a href="https://tilthydrometer.com/products/copy-of-tilt-floating-wireless-hydrometer-and-thermometer-for-brewing" target="_blank" rel="noopener noreferrer">Tilt2 Hydrometer</a>.  Even if you aren&#8217;t specifically interested in hydrometers, this is a general purpose discussion of the design of an IoT device.</p>
<h1>Story</h1>
<p>In the middle of the Covid lockdown my 21-year-old daughter suggested that we start brewing beer.  This was always something that I have been interested in so I said &#8220;Sure!&#8221;.  What does this have to do with IoT you might ask?  I am an engineer and I love data.  Two of the key pieces of <a href="https://en.wikipedia.org/wiki/Beer_measurement" target="_blank" rel="noopener noreferrer">data</a> that you are interested in while fermenting beer are:</p>
<ul>
<li>The gravity of the beer</li>
<li>The temperature of the beer</li>
</ul>
<p>If you don&#8217;t know anything about brewing beer, it is simple (people have been doing it a long time&#8230; even with no IoT)</p>
<ol>
<li>Start with grain</li>
<li>Mill the grain</li>
<li>Heat the grain with water to turn it into sugar water (called wort)</li>
<li>Add yeast</li>
<li>Wait while the yeast converts the sugar in the wort into alcohol and carbon dioxide</li>
<li>Bottle the beer (or keg)</li>
<li>Drink</li>
</ol>
<p>Back to the metrics.  The &#8220;specific gravity&#8221; or just &#8220;gravity&#8221; is just the ratio of the density of your solution to plain water.  This is an indication of sugar in the wort solution.  At the start of the fermentation you will have &#8220;lots&#8221; of sugar, and no alcohol.  By the end you will have &#8220;lots&#8221; of alcohol and not much sugar.  You can tell how things are going by monitoring the gravity of the beer, which is a proxy metric for how much sugar has been converted to alcohol.</p>
<p>There are two common ways to measure the gravity:</p>
<ul>
<li>A <a href="https://en.wikipedia.org/wiki/Hydrometer" target="_blank" rel="noopener noreferrer">float hydrometer</a> &#8211; sugar water is denser then water, so a &#8220;float&#8221; will float lower in the solution as the sugar gets converted to alcohol.</li>
<li>A <a href="https://en.wikipedia.org/wiki/Refractometer" target="_blank" rel="noopener noreferrer">refractometer</a> &#8211; the index of refraction of the solution changes as the sugar concentration changes (this is an amazing old-school technology</li>
</ul>
<p>As I was learning about this whole process I found the <a href="https://tilthydrometer.com" target="_blank" rel="noopener noreferrer">tilt hydrometer</a>.  This device has</p>
<ul>
<li>A Bluetooth MCU (<a href="https://www.u-blox.com/sites/default/files/BMD-300_DataSheet_%28UBX-19033350%29.pdf" target="_blank" rel="noopener noreferrer">u-blox BMD-300</a>)</li>
<li>An I2C accelerometer (<a href="https://www.nxp.com/docs/en/data-sheet/MMA8451Q.pdf" target="_blank" rel="noopener noreferrer">NXP MMA8451Q</a>)</li>
<li>An I2C temperature sensor (<a href="https://ww1.microchip.com/downloads/en/DeviceDoc/25095A.pdf" target="_blank" rel="noopener noreferrer">Microchip MCP9808</a>)</li>
<li>Enclosed in a sealed plastic tube of known volume and weight (known density)</li>
</ul>
<p>As the gravity of the beer changes, the device floats at a different angle (because it floats lower/higher).  They use the accelerometer to measure the apparent angle of gravity to calculate the angle of the device.  This angle is then used to calculate the density of the solution it is floating in.  They then broadcast the calculated gravity and temperature in Apple Bluetooth iBeacon format.</p>
<p>When I saw this, I thought &#8220;perfect&#8221; I know what to do with that.  I should build a device that can collect all of the data, display it, save it to an SPI flash and put it into the cloud.  It should look something like this: (each Tilt is identified by 1 of 8 colors&#8230; pink in this case).</p>
<p><a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0026/"><img fetchpriority="high" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0026-1024x711.jpg" alt="" class="alignnone wp-image-10642 size-large" width="1024" height="711" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0026-1024x711.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0026-300x208.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0026-768x533.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0026-1536x1066.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0026-2048x1422.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Yes, I know they have an iPhone app, but I want to build a single device that sits in my brewery all of the time.  And yes I know they have a Raspberry Pi app, but that isn&#8217;t the point.</p>
<p>My device will have the following characteristics:</p>
<p>A Display with:</p>
<ul>
<li>A Splash Screen</li>
<li>A Table of all Tilts, Gravity and Temperature</li>
<li>Single: One screen per tilt with the specific data including debugging</li>
<li>Single: A graph of the active data for one specific tilt</li>
<li>Single: A table of all of the recordings from that specific tilt</li>
<li>The WiFi Status</li>
<li>The Bluetooth Status</li>
</ul>
<p>Bluetooth System that can:</p>
<ul>
<li>Record tilt data as broadcast in iBeacon advertising packets</li>
<li>Repeat tilt data (maybe)</li>
<li>Introducer WiFi (probably)</li>
</ul>
<p>CapSense button GUI to:</p>
<ul>
<li>Next Screen</li>
<li>Auto Mode</li>
<li>Reset current</li>
<li>Dump recorded data to the SD Card</li>
</ul>
<p>Command Line</p>
<ul>
<li>A UART based command line to debug &amp; learn</li>
</ul>
<p>USB</p>
<ul>
<li>Mass Storage to see files</li>
<li>USB &lt;-&gt; UART Bridge</li>
</ul>
<p>Power Supply via USB Port</p>
<ul>
<li>Plug in Type-C using Cypress BCR</li>
</ul>
<p>WiFi</p>
<ul>
<li>MQTT Publish to AWS</li>
<li>NTP &#8211; to find the time</li>
<li>Local webserver</li>
<li>MDNS</li>
</ul>
<p>RTC</p>
<ul>
<li>Keep Track of current Time</li>
</ul>
<p>SPI NOR Flash</p>
<ul>
<li>Record the data</li>
</ul>
<p>SD CARD</p>
<ul>
<li>Dump the fixed SPI Flash  recordings to a removable SD CARD &amp; remove data from the SPI Flash</li>
</ul>
<p>Here is another picture of what I am thinking (well actually what I implemented for this series of articles)<br />
<a href="https://iotexpert.com/" rel="attachment wp-att-9748"></a><a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0025-2/"><img decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0025-1024x738.jpg" alt="" class="alignnone wp-image-10645 size-large" width="1024" height="738" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0025-1024x738.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0025-300x216.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0025-768x553.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0025-1536x1107.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0025-2048x1476.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Un-boxing</h1>
<p>To get this show on the road, I ordered three tilts and two repeaters from Baron Brew Equipment.<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0038-2/"><img decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0038-781x1024.jpg" alt="" class="alignnone wp-image-10656 size-large" width="781" height="1024" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0038-781x1024.jpg 781w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0038-229x300.jpg 229w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0038-768x1007.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0038-1172x1536.jpg 1172w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0038-1562x2048.jpg 1562w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0038-scaled.jpg 1953w" sizes="(max-width: 781px) 100vw, 781px" /></a></p>
<p>It included a neat little quick start picture showing how to get going.<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0037-2/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0037-778x1024.jpg" alt="" class="alignnone wp-image-10655 size-large" width="778" height="1024" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0037-778x1024.jpg 778w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0037-228x300.jpg 228w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0037-768x1010.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0037-1168x1536.jpg 1168w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0037-1557x2048.jpg 1557w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0037-scaled.jpg 1946w" sizes="auto, (max-width: 778px) 100vw, 778px" /></a></p>
<p>Then the box of goodies.<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0036/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0036-792x1024.jpg" alt="" class="alignnone wp-image-10654 size-large" width="792" height="1024" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0036-792x1024.jpg 792w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0036-232x300.jpg 232w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0036-768x993.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0036-1188x1536.jpg 1188w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0036-1584x2048.jpg 1584w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0036-scaled.jpg 1980w" sizes="auto, (max-width: 792px) 100vw, 792px" /></a></p>
<p>There are 8-possible tilts, Red, Green, Orange, Blue, Black, Yellow, Purpose and Pink (each Tilt his &#8220;hardcoded&#8221; to identify itself as a specific color)<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0028-scaled-e1598972738342/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0028-scaled-e1598972738342-1024x513.jpg" alt="" class="alignnone wp-image-10646 size-large" width="1024" height="513" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0028-scaled-e1598972738342-1024x513.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0028-scaled-e1598972738342-300x150.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0028-scaled-e1598972738342-768x385.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0028-scaled-e1598972738342-1536x769.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0028-scaled-e1598972738342-2048x1026.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Tilt Hydrometer</h1>
<p>Here is a picture of the &#8220;blue&#8221; one (notice I put the wrong box in the picture)<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0039-2/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0039-1024x585.jpg" alt="" class="alignnone wp-image-10657 size-large" width="1024" height="585" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0039-1024x585.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0039-300x171.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0039-768x439.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0039-1536x877.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0039-2048x1170.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The tilt comes in a plastic tube.  Which has a label to remind you to take it out of the tube (my experience is that you should be embarrassed to have to read most warning labels <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> )<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0033-2/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0033-903x1024.jpg" alt="" class="alignnone wp-image-10652 size-large" width="903" height="1024" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0033-903x1024.jpg 903w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0033-264x300.jpg 264w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0033-768x871.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0033-1354x1536.jpg 1354w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0033-1805x2048.jpg 1805w" sizes="auto, (max-width: 903px) 100vw, 903px" /></a></p>
<p>It is about 100mm long (about 4 inches).  The bluetooth module is at the top, U3 is the temperature sensor and U2 (which is under the black 3-d printed plastic) is the accelerometer.<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0034-2/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0034-1024x619.jpg" alt="" class="alignnone wp-image-10653 size-large" width="1024" height="619" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0034-1024x619.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0034-300x181.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0034-768x464.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0034-1536x928.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0034-2048x1238.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Repeater</h1>
<p>If you put a Bluetooth device floating in a bunch of beer, surrounded by a metal fermentation container, you will not be able to hear the Bluetooth signal.  To solve this problem the Tilt people made a <a href="https://tilthydrometer.com/products/tilt-repeater" target="_blank" rel="noopener noreferrer">repeater</a> which can rest on the top of the fermenter.  It listens for the weak signal, then rebroadcasts with a higher gain antenna.</p>
<p>Here is a picture of the repeater.  Notice that it uses the BMD-301 which has an external SMA antenna.<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0045-2/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0045-1024x710.jpg" alt="" class="alignnone wp-image-10658 size-large" width="1024" height="710" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0045-1024x710.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0045-300x208.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0045-768x532.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0045-1536x1065.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0045-2048x1420.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>It also comes in a nice plastic tube.<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0029-3/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0029-1024x524.jpg" alt="" class="alignnone wp-image-10648 size-large" width="1024" height="524" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0029-1024x524.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0029-300x154.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0029-768x393.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0029-1536x787.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0029-2048x1049.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The repeater can only re-broadcast one color at a time.  The button to switches between the 8 colors and off.<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0032/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0032-1024x740.jpg" alt="" class="alignnone wp-image-10651 size-large" width="1024" height="740" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0032-1024x740.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0032-300x217.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0032-768x555.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0032-1536x1110.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0032-2048x1479.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Each time you press the button the 3-color LED lights up with the color that represents which tilt color that it is repeating. Red-&gt;Green-&gt;&#8230; Pink-&gt;Off<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0030-2/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0030-1024x340.jpg" alt="" class="alignnone wp-image-10649 size-large" width="1024" height="340" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0030-1024x340.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0030-300x100.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0030-768x255.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0030-1536x510.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0030-2048x680.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>It also has a huge rechargeable battery.<br />
<a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/img_0031-2/"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0031-1024x327.jpg" alt="" class="alignnone wp-image-10650 size-large" width="1024" height="327" srcset="https://iotexpert.com/wp-content/uploads/2020/09/IMG_0031-1024x327.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0031-300x96.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0031-768x246.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0031-1536x491.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/09/IMG_0031-2048x655.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>The Plan</h1>
<p>Here is a list of the articles that I plan to write</p>
<p>This series is broken up into the following 12 articles with a few additional possible articles. </p>
<p><a href="https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/" target="_blank" rel="noopener">Tilt Hydrometer (Part 1) Overview &amp; Out-of-Box</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-architecture-part-2/" target="_blank" rel="noopener">Tilt Hydrometer (Part 2) Architecture</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-advertising-scanner-part-3/">Tilt Hydrometer (Part 3) Advertising Scanner</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-4-advertising-packet-error/" target="_blank" rel="noopener">Tilt Hydrometer (Part 4) Advertising Packet Error?</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-5-tilt-simulator-multi-advertising-ibeacons/">Tilt Hydrometer (Part 5) Tilt Simulator &amp; Multi Advertising iBeacons</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-6-tilt-simulator-an-upgrade/" target="_blank" rel="noopener">Tilt Hydrometer (Part 6) Tilt Simulator an Upgrade</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-7-advertising-database/">Tilt Hydrometer (Part 7) Advertising Database</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-8-read-the-database/">Tilt Hydrometer (Part 8) Read the Database</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-9-an-lcd-display/">Tilt Hydrometer (Part 9) An LCD Display</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-10-the-display-state-machine/">Tilt Hydrometer (Part 10) The Display State Machine</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-11-draw-the-display-screens/">Tilt Hydrometer (Part 11) Draw the Display Screens</a></p>
<p><a href="https://iotexpert.com/tilt-hydrometer-part-12-capsense/">Tilt Hydrometer (Part 12) CapSense</a></p>
<p>Tilt Hydrometer: LittleFS &amp; SPI Flash (Part ?)</p>
<p>Tilt Hydrometer: WiFi Introducer (Part ?)</p>
<p>Tilt Hydrometer: WebServer (Part ?)</p>
<p>Tilt Hydrometer: Amazon MQTT (Part ?)</p>
<p>Tilt Hydrometer: Printed Circuit Board (Part ?)</p>
<p>You can get the source code from git@github.com:iotexpert/Tilt2.git  This repository has tags for each of the articles which can be accessed with "git checkout part12"  You can find the Tilt Simulator at  git@github.com:iotexpert/TiltSimulator.git.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/tilt-hydrometer-overview-out-of-box-part-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 10)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 28 Dec 2020 13:00:47 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[ModusToolbox]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10250</guid>

					<description><![CDATA[Summary We have finally reached the end of the AnyCloud Bluetooth Advertising Scanner.  In this article I will add the ability to sort the database.  In addition I will add the ability to purge a device.  And finally, truly finally, a bit of commentary. Story I originally built this program to help me learn about [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>We have finally reached the end of the AnyCloud Bluetooth Advertising Scanner.  In this article I will add the ability to sort the database.  In addition I will add the ability to purge a device.  And finally, truly finally, a bit of commentary.</p>
<h1>Story</h1>
<p>I originally built this program to help me learn about the AnyCloud Bluetooth SDK.  Well, originally I built this functionality to try to find and talk to a specific device (in an upcoming series).  The problem is that there are so many devices at my house that are blasting out so much data it is hard to see what I am looking for.  What I realized would help is add the ability to sort the devices from newest to oldest.  In addition I noticed that occasionally my database would fill up&#8230; and it would be nice to purge out old entries.  So that is what we are going to do.</p>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Fix the Database Data Structure</h1>
<p>You might remember that the database was built as an array of structures.  This mean that any moving around of the data would be a require a replacement of the whole structure.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static adb_adv_t adb_database[ADB_MAX_SIZE];</pre>
<p>To fix this problem I moved the database to a an array of pointers.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static adb_adv_t *adb_database[ADB_MAX_SIZE];</pre>
<p>To support this, when I see a new device I malloc a block of memory to hold the actual structure.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    // If it is NOT found &amp;&amp; you have room
    if(entry == -1)
    {
        adb_database[adb_db_count] = malloc(sizeof(adb_adv_t));</pre>
<p>Then I had to fix all of the references to the structure.  And there were a bunch (actually 43 of them).  But the replacement was pretty simple</p>
<p>adb_database[&#8230;].xxx is replaced by adb_database[&#8230;]-&gt; &#8230;. here are the three different cases</p>
<p>case 1: adb_database[adb_db_count].</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-7-40-36-am/" rel="attachment wp-att-10254"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM.png" alt="" class="alignnone size-full wp-image-10254" width="834" height="126" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM.png 834w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM-300x45.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM-768x116.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM-600x91.png 600w" sizes="auto, (max-width: 834px) 100vw, 834px" /></a></p>
<p>case 2: adb_database[entry].</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-7-32-54-am/" rel="attachment wp-att-10251"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM.png" alt="" class="alignnone size-full wp-image-10251" width="842" height="132" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM.png 842w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM-300x47.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM-768x120.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM-600x94.png 600w" sizes="auto, (max-width: 842px) 100vw, 842px" /></a></p>
<p>case 1: adb_database[i].</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-7-33-23-am/" rel="attachment wp-att-10252"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM.png" alt="" class="alignnone size-full wp-image-10252" width="838" height="132" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM.png 838w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM-300x47.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM-768x121.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM-600x95.png 600w" sizes="auto, (max-width: 838px) 100vw, 838px" /></a></p>
<p>That was actually way less painful that I thought it was going to be.  Probably what would actually be best is a library of these data structures with an API that would not have changed when the key changed, but that I suppose, is for another day.</p>
<h1>Add Two New Commands</h1>
<p>Now I add the sort and purge commands to my command list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_ADD,
    ADB_PRINT_RAW,
    ADB_PRINT_DECODE,
    ADB_WATCH,
    ADB_ERASE,
    ADB_RECORD,
    ADB_FILTER,
    ADB_SORT,
    ADB_PURGE,
} adb_cmd_t;
</pre>
<h1>Create the Sort Functionality</h1>
<p>To sort, I will use the c-standard library function qsort.  It requires a function that compares two entries a/b and returns</p>
<ol>
<li>a negative number of a&lt;b</li>
<li>0 if a=b</li>
<li>a positive number if a&gt;b</li>
</ol>
<p>Here is the function.  Hey Hassane you like those pointers?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int adb_sort_cmpfunc(const void * a, const void * b) 
{
    adb_adv_t *p1 = *((adb_adv_t **)a);
    adb_adv_t *p2 = *((adb_adv_t **)b);
        
    return p2-&gt;lastSeen - p1-&gt;lastSeen;
}</pre>
<p>The sort is actually really simple now.  Just a call to sort (then I decided to print out the table)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_SORT:
                    qsort(adb_database, adb_db_count, sizeof(adb_adv_t *), adb_sort_cmpfunc);
                    adb_db_print(ADB_PRINT_METHOD_BYTES,true,-1);
                break;</pre>
<p>Now instead of this&#8230;.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-4-35-26-pm/" rel="attachment wp-att-10256"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-1024x678.png" alt="" class="alignnone size-large wp-image-10256" width="1024" height="678" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-1024x678.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-300x199.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-768x508.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-1536x1017.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-600x397.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM.png 1970w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I get this&#8230;</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-4-35-37-pm/" rel="attachment wp-att-10257"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-1024x660.png" alt="" class="alignnone size-large wp-image-10257" width="1024" height="660" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-1024x660.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-300x193.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-768x495.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-1536x990.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-600x387.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM.png 2042w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Create the Purge Functionality</h1>
<p>The purge function needs to do two things</p>
<ol>
<li>Free all of the memory from an entry</li>
<li>Move the pointers so that the &#8220;purged&#8221; entry is gone.</li>
</ol>
<p>First I erase all of the data in the linked list with the adb_eraseEntry function.</p>
<p>Then I free the head of the list</p>
<p>Then I free the actual structure</p>
<p>Then I move all of the pointers to squeeze the able.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_purgeEntry(int entry)
{

    adb_eraseEntry(entry);
    free(adb_database[entry]-&gt;list);
    free(adb_database[entry]-&gt;result);
    free(adb_database[entry]);
    adb_db_count -= 1;
    for(int i=entry;i&lt;adb_db_count;i++)
    {
        adb_database[i] = adb_database[i+1];
    }
}
</pre>
<p>And you need to add the actual command.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_PURGE:
                    if((int)msg.data0&lt;0 || (int)msg.data0&gt;=adb_db_count)
                    {
                        printf("Purge error %d\n",(int)msg.data0);
                        break;
                    }   
                    adb_purgeEntry((int)msg.data0);
                break;</pre>
<h1>The End &amp; Commentary</h1>
<p>I would like to add and maybe will one day:</p>
<ol>
<li>A connect function with a GATT browser</li>
<li>A smarter way to deal with the fact that device change addresses</li>
</ol>
<p>Finally a couple of comments about this</p>
<ol>
<li>You might notice that I don&#8217;t check very many possible errors.  I do this in the interest of simpler to read code.  This is a tradeoff that I make for &#8220;teaching&#8221; code.  I hope that you understand that if you want to do something like this in a real product that you need to be much more careful.</li>
<li>I don&#8217;t have unit testing.  This falls into the same category as the error checking.  Really this is a bad idea as code without unit testing is obsolete the second it comes out of your fingers.  But, it is easier to read.</li>
<li>I don&#8217;t have many comments.  This is something that my colleagues bitch about all of the time with me.  And I know that it must be a personality defect.</li>
<li>I use malloc/free all over the place.  This is a religious war.  You can make a static allocation scheme, but it would be really complicated in this case.  I personally think that the tradeoff of using a battle worn and tested malloc/free is totally worthwhile against the complexity of custom static memory allocation schemes.</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 8)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 14 Dec 2020 13:00:23 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10220</guid>

					<description><![CDATA[Summary In this series of articles I am building a Bluetooth Low Energy Scanner using the Cypress/Infineon AnyCloud SDK running on a PSoC 6 and CYW43xxx.  In Part 8 I will turn on the ability to filter duplicate advertising packets. Story In the previous article I added the ability to record advertising packets.  The problem [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In this series of articles I am building a Bluetooth Low Energy Scanner using the Cypress/Infineon AnyCloud SDK running on a PSoC 6 and CYW43xxx.  In Part 8 I will turn on the ability to filter duplicate advertising packets.</p>
<h1>Story</h1>
<p>In the previous article I added the ability to record advertising packets.  The problem is, of course, that many devices are blasting out advertising packets, which will quickly overwhelm you.  I suppose more importantly it will overwhelm the packet buffer.  Most of the device are just advertising their presence, so they send the same data over and over.  Some devices alternate between a small number of different advertising packets, e.g. an iBeacon then and Eddystone beacon.</p>
<p>The way that the filter will work is that I will update the &#8220;add&#8221; function to search through all of the packets that device has launched, then if I have seen the packet before (Ill use a memcmp) then I will just keep a count of how many times I have see that packet.</p>
<p>The other thing that needs to happen is for me to add a &#8220;filter&#8221; command so that I can turn on packet filtering on a device by device basis.</p>
<p>And I need to fix the printing to use the new filtered packet database.</p>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Update the Data Structures</h1>
<p>In order to do the filters, and keep track of the data I will add</p>
<ol>
<li>A &#8220;count&#8221; field to the packet data structure</li>
<li>A &#8220;filter&#8221; boolean field to the device data structure.</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct {
    uint8_t *data;
    int count;
    struct adb_adv_data_t *next;
} adb_adv_data_t;

typedef struct {
    wiced_bt_ble_scan_results_t *result;
    bool record;
    bool filter;
    int numSeen;
    int listCount;
    adb_adv_data_t *list;
} adb_adv_t ;</pre>
<h1>Update the Add Function</h1>
<p>In the function &#8220;static void adb_db_add(wiced_bt_ble_scan_results_t *scan_result,uint8_t *data)&#8221; which is called every time I see a new advertising packet I will need to handle four different cases:</p>
<ol>
<li>The first time you see a device</li>
<li>A device you have seen AND you are recording AND have the filtering turned on</li>
<li>A device you are recording but not filtering</li>
<li>A device you have seen, but are not recording or filter.</li>
</ol>
<p>In the first case, a device you haven&#8217;t seen before, you need to</p>
<ol>
<li>Automatically turn on the filtering</li>
<li>Initialize the counts to 1</li>
<li>Do the other initialization (as before)</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    // If it is NOT found
    if(entry == -1)
    {
        adb_database[adb_db_count].result = scan_result;
        adb_database[adb_db_count].listCount = 1;
        adb_database[adb_db_count].record = false;
        adb_database[adb_db_count].filter = true;
        adb_database[adb_db_count].numSeen = 1;

        adb_adv_data_t *current = malloc(sizeof(adb_adv_data_t));
        current-&gt;next = 0;
        current-&gt;data = data;
        current-&gt;count = 1;</pre>
<p>In the case where you have</p>
<ol>
<li>See the device before</li>
<li>You have room in the record buffer</li>
<li>And you are in record mode</li>
</ol>
<p>You will then decide if you are filtering.</p>
<p>Then you will iterate through all of the packets and compare the data to the data you just received.  If there is a match then you update the count, free the duplicate data and return.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    else if(adb_database[entry].record &amp;&amp; adb_recording_count&lt;ADB_RECORD_MAX &amp;&amp; adb_recording)
    {
        adb_database[entry].numSeen += 1;

        if(adb_database[entry].filter) // if filtering is on.
        {
            int len = btutil_adv_len(data); 
            for(adb_adv_data_t *list = adb_database[entry].list;list;list = (adb_adv_data_t *)list-&gt;next)
            {
                if(memcmp(list-&gt;data,data,len) == 0) // Found the data
                {
                    list-&gt;count += 1;
                    printf("Count = %d\n",list-&gt;count);
                    free(data);
                    free(scan_result);
                    return;
                }
            }
        }
</pre>
<p>If you have not see the data before, then you need to add it to the linked list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">        adb_adv_data_t *current = malloc(sizeof(adb_adv_data_t));
        current-&gt;next = (struct adb_adv_data_t *)adb_database[entry].list;
        current-&gt;data = data;
        current-&gt;count = 1;</pre>
<p>If you are not recording and not filtering, just increment counts.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    else
    {
        adb_database[entry].numSeen += 1;
        adb_database[entry].list-&gt;count += 1;</pre>
<h1>Add a &#8220;filter&#8221; Command</h1>
<p>I want the ability for a user to &#8220;filter all&#8221; or &#8220;filter clear&#8221; or &#8220;filter #&#8221; &#8211; just like we did with watch.  So, add the #defines and new function to advDatabase.h</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define ADB_FILTER_ALL -1
#define ADB_FILTER_CLEAR -2
void adb_filter(int entry);
</pre>
<p>Then add the new filter command in advDatabase.c</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_ADD,
    ADB_PRINT_RAW,
    ADB_PRINT_DECODE,
    ADB_WATCH,
    ADB_ERASE,
    ADB_RECORD,
    ADB_FILTER,
} adb_cmd_t;</pre>
<p>I will use the adb_queueCmd function that I created in the last article.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">inline void adb_filter(int entry) { adb_queueCmd(ADB_FILTER,(void*)entry,(void *)0); }
</pre>
<p>The filter command has three cases</p>
<ol>
<li>All &#8211; turn the bool for all on</li>
<li>Clear &#8211; turn the bool for all off</li>
<li>Just a specific number &#8211; toggle that specific number</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_filter(int entry)
{
    if(entry == ADB_FILTER_ALL)
    {
        for(int i=0;i&lt;adb_db_count;i++)
        {
            adb_database[i].filter = true;
        }
        return;
    }

    if(entry == ADB_FILTER_CLEAR)
    {
        for(int i=0;i&lt;adb_db_count;i++)
        {
            adb_database[i].filter = false;
        }
        return;
    }

    if(entry &gt; adb_db_count-1 || entry &lt; ADB_WATCH_CLEAR)
    {
        printf("Record doesnt exist: %d\n",entry);
        return;      
    }
    adb_database[entry].filter = !adb_database[entry].filter; 

}
</pre>
<p>And you need to fix up the main command processor</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_FILTER:
                    adb_db_filter((int)msg.data0);
                break;</pre>
<p>Finally add the command to the usrcmd.c</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int usrcmd_filter(int argc, char **argv)
{

    if(argc == 2 &amp;&amp; !strcmp(argv[1],"all"))
    {
        adb_filter(ADB_FILTER_ALL); // all
        return 0;
    }


    if(argc == 2 &amp;&amp; !strcmp(argv[1],"clear"))
    {
        adb_filter(ADB_FILTER_CLEAR);
        return 0;
    }

    if(argc == 2)
    {
        int i;
        sscanf(argv[1],"%d",&amp;i);
        adb_filter(i);
        return 0;
    }

    return 0;
}</pre>
<h1>Fix the Printing</h1>
<p>Now we nee to fix the printing.  I want to add an indicate of the filtering to the output.  Remember from the previous article I indicated &#8220;Watch&#8221; with a &#8220;*&#8221;.  When I looked at it, I decided that I should indicate filter with an &#8220;F&#8221; and watch with a &#8220;W&#8221;.  So I fix that.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">        printf("%c%c%02d %05d %03d MAC: ",adb_database[i].record?'W':' ',
            adb_database[i].filter?'F':' ',
            i,adb_database[i].numSeen,adb_database[i].listCount);
        btutil_printBDaddress(adb_database[i].result-&gt;remote_bd_addr);
        switch(method)
        {</pre>
<p>Then I test the &#8220;filter&#8221; command</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/screen-shot-2020-11-14-at-9-49-32-am/" rel="attachment wp-att-10235"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-1024x622.jpg" alt="" class="alignnone size-large wp-image-10235" width="1024" height="622" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-1024x622.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-300x182.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-768x466.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-1536x933.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-600x364.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM.jpg 2042w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Fix the Printing Part (2)</h1>
<p>As I noodled on how to change the printing I decide that it would be nice to sometimes print out only one packet e.g. no history and sometimes print them all out e.g. history.  So, I add a new parameter to the function called &#8220;history&#8221;</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_print(adb_print_method_t method,bool history,int entry)
</pre>
<p>As I looked at the printing code, I decided that it would be better to have a new function to print only one entry.  I suppose that I could have left the code inline, but I thought that intent was clearer.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_printEntry(adb_print_method_t method, int entry, adb_adv_data_t *adv_data)
{
    printf("%c%c%02d %05d %03d MAC: ",adb_database[entry].record?'W':' ',
    adb_database[entry].filter?'F':' ',
    entry,adb_database[entry].numSeen,adb_database[entry].listCount);
    btutil_printBDaddress(adb_database[entry].result-&gt;remote_bd_addr);

    switch(method)
    {
    
    case ADB_PRINT_METHOD_BYTES:
        printf(" Data: ");
        btutil_adv_printPacketBytes(adv_data-&gt;data);
    break;

    case ADB_PRINT_METHOD_DECODE:
        printf("\n");
        btutil_adv_printPacketDecode(adv_data-&gt;data);
    break;
    } 
    printf("\n");

}
</pre>
<p>With the new function in place I now need to update the print function to call the new entry function.  Printing the history is just a matter of iterating through the linked list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_print(adb_print_method_t method,bool history,int entry)
{
    int start,end;
 
    if(entry &lt; 0)
    {
        start = 0;
        end = adb_db_count;
    }
    else
    {
        start = entry;
        end = entry+1;
    }

    if(end&gt;adb_db_count)
        end = adb_db_count; 

    for(int i=start;i&lt;end;i++)
    {
        if(history) // then iterate through the linked list print all of the packets
        {
            for(adb_adv_data_t *list = adb_database[i].list;list;list = (adb_adv_data_t *)list-&gt;next)
            {
                adb_db_printEntry(method,i,list);    
            }
        }
        else // Just print the first packet in the list
            adb_db_printEntry(method,i,adb_database[i].list);
    }
}</pre>
<p>Now, I need to update all of the calls to adb_db_print to have the new history parameter.  First, I made the decision that when you &#8220;print&#8221; from the command line that you are interested in the history.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_PRINT_RAW:
                    adb_db_print(ADB_PRINT_METHOD_BYTES,true,(int)msg.data0);
                break;
                case ADB_PRINT_DECODE:
                    adb_db_print(ADB_PRINT_METHOD_DECODE,true,(int)msg.data0);
                break;</pre>
<p>But when you are printing out the packet for a new device don&#8217;t print out the history</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">            adb_db_print(ADB_PRINT_METHOD_BYTES,false,adb_db_count-1);
</pre>
<h1>Program and Test</h1>
<p>After I program my development kit, I start by typing &#8220;watch all&#8221;.  Very quickly, at my house, you can see that a bunch of devices are discovered.  You can see that all of these have a &#8220;W&#8221; (meaning that I am watching them) and an &#8220;F&#8221; meaning they are filtering out duplicates.  Then I type &#8220;record&#8221; to turn on recording. After a minute I turn off recording then do the print you can see below.</p>
<p>A couple of things to notice.</p>
<ol>
<li>Device #4 (which I highlighted) appears to be sending out a pattern of alternating packets.  See that I have heard 3335 packets yet there are only two in the buffer</li>
<li>You can see device 11 seems to be sending out 16 different packets.  Why?  I don&#8217;t know.</li>
</ol>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/screen-shot-2020-11-14-at-12-33-06-pm/" rel="attachment wp-att-10236"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-1024x624.png" alt="" class="alignnone size-large wp-image-10236" width="1024" height="624" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-1024x624.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-300x183.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-768x468.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-1536x936.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-600x366.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM.png 2032w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>But we can &#8220;decode 11&#8221; to try to figure it out.  You can see that it is advertising manufactures specific data with Apple&#8217;s UUID which I happen to know is 0x004C.  But why?  I don&#8217;t know.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/screen-shot-2020-11-14-at-12-37-51-pm/" rel="attachment wp-att-10237"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-1024x807.jpg" alt="" class="alignnone size-large wp-image-10237" width="1024" height="807" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-1024x807.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-300x236.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-768x605.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-1536x1210.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-600x473.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM.jpg 1554w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I really want to move onto a new series of articles&#8230; but there are two functions which I will add to the program.  Stay tuned for what they do.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 6)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 30 Nov 2020 13:00:38 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10206</guid>

					<description><![CDATA[Summary In part 6 of this series I will update the AnyCloud BLE Advertising Scanner to decode advertising packets into a more human readable textual output Story We are now 6 (or maybe 7 depending on how you count) articles into this series and we are still looking at raw bytes.  I have gotten to [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In part 6 of this series I will update the AnyCloud BLE Advertising Scanner to decode advertising packets into a more human readable textual output</p>
<h1>Story</h1>
<p>We are now 6 (or maybe 7 depending on how you count) articles into this series and we are still looking at raw bytes.  I have gotten to where I am pretty good at understanding those bytes, but that is now way to roll.  You might remember from the <a href="https://iotexpert.com/anycloud-bluetooth-utilities-library/">article</a> on the IoT Expert Bluetooth Utility library that there were a some interesting functions defined in the header.  Here it is:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">wiced_bool_t btutil_isEddystone(uint8_t *data);
wiced_bool_t btutil_is_iBeacon(uint8_t *data);
wiced_bool_t btutil_isCypress(uint8_t *data);

int btutil_adv_len(uint8_t *packet);
void btutil_adv_printPacketDecode(uint8_t *packet);
void btutil_adv_printPacketBytes(uint8_t *packet);</pre>
<p>Lets transform our  project from part 6 to use these functions.  In this article I will</p>
<ul>
<li>Redo the print bytes (to be smarter) functionality and to use the built in function</li>
<li>Rework the logic for the &#8220;print&#8221; command implementation</li>
<li>Add a new command &#8220;decode&#8221; which will run the decode function</li>
</ul>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Replace two code blocks with function calls</h1>
<p>Do you remember this block of code?  It print&#8217;s out the 6-bytes of the Bluetooth Address.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    for(int i=0;i&lt;BD_ADDR_LEN;i++)
    {
        printf("%02X:",adb_database[entry].result-&gt;remote_bd_addr[i]);
    }
</pre>
<p>You might have noticed that this function already exists in the BT Utility Library.  Use it.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    btutil_printBDaddress(adb_database[entry].result-&gt;remote_bd_addr);</pre>
<p>Then you remember this block of code which iterates through and advertising packet and prints out the raw bytes?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">// Print the RAW Data of the ADV Packet
    printf(" Data: ");
    int i=0;
    while(adb_database[entry].data[i])
    {
        for(int j=0;j&lt;adb_database[entry].data[i];j++)
        {
            printf("%02X ",adb_database[entry].data[i+1+j]);
        }
        i = i + adb_database[entry].data[i]+1;
    }
</pre>
<p>Well, it exists in the library as well.  Use it.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">btutil_adv_printPacketBytes(adb_database[entry].data);</pre>
<h1>Fix the &#8220;print&#8221; Command</h1>
<p>In the previous implementation I had two functions for &#8220;print&#8221;.  The first one printed one entry and the second one printed the whole table.  I decided that I didnt really like this logic, so I compressed those two functions into one function.  Specifically, it take a number &#8220;entry&#8221;.  If that number is -1 then it will print the whole table.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_printRawPacket(int entry)
{
    int start,end;
 
    if(entry &lt;= -1)
    {
        start = 0;
        end = adb_db_count;
    }
    else
    {
        start = entry;
        end = entry;
    }

    if(end&gt;adb_db_count)
        end = adb_db_count; 

    for(int i=start;i&lt;=end;i++)
    {
    
        printf("%02d MAC: ",i);
        btutil_printBDaddress(adb_database[i].result-&gt;remote_bd_addr);
        printf(" Data: ");
        btutil_adv_printPacketBytes(adb_database[i].data);

        printf("\n");
    }
}
</pre>
<h1>Add a new &#8220;decode&#8221; Command</h1>
<p>The next thing to do is to add a function to print out decoded packets (or the whole table).  So I wrote this:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_printDecodePacket(int entry)
{
    int start,end;
 
    if(entry == -1)
    {
        start = 0;
        end = adb_db_count;
    }
    else
    {
        start = entry;
        end = entry;
    }

    if(end&gt;adb_db_count)
        end = adb_db_count; 

    for(int i=start;i&lt;=end;i++)
    {

        printf("%02d MAC: ",i);
        btutil_printBDaddress(adb_database[i].result-&gt;remote_bd_addr);
        printf("\n");
        btutil_adv_printPacketDecode(adb_database[i].data);
        printf("\n");
    }
}</pre>
<p>After finishing that block of code, I realized I had implemented almost exactly the same functionality which two different functions.  So, I decided to redo this by doing this.  Notice that it take in a adb_print_method, in other words raw bytes or decoded packet.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_PRINT_METHOD_BYTES,
    ADB_PRINT_METHOD_DECODE,
} adb_print_method_t;

static void adb_db_print(adb_print_method_t method,int entry)
{
    int start,end;
 
    if(entry &lt; 0)
    {
        start = 0;
        end = adb_db_count;
    }
    else
    {
        start = entry;
        end = entry;
    }

    if(end&gt;adb_db_count)
        end = adb_db_count; 

    for(int i=start;i&lt;=end;i++)
    {
    
        printf("%02d MAC: ",i);
        btutil_printBDaddress(adb_database[i].result-&gt;remote_bd_addr);
        switch(method)
        {
        
        case ADB_PRINT_METHOD_BYTES:
            printf(" Data: ");
            btutil_adv_printPacketBytes(adb_database[i].data);
        break;

        case ADB_PRINT_METHOD_DECODE:
            printf("\n");
            btutil_adv_printPacketDecode(adb_database[i].data);
        break;
        } 
        printf("\n");
    }
}
</pre>
<p>I don&#8217;t show it here, but after changing this I had to fix up the function calls in several places in the advDatabase.</p>
<h1>Add a new command to print decode packets</h1>
<p>Now that I have a new method to print packets, I add a command to the database to allow the user to call it:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_ADD,
    ADB_PRINT_RAW,
    ADB_PRINT_DECODE,
} adb_cmd_t;
</pre>
<p>Then in the queue loop:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">switch(msg.cmd)
            {
                case ADB_ADD:
                    scan_result = (wiced_bt_ble_scan_results_t *)msg.data0;
                    data = (uint8_t *)msg.data1;
                    adb_db_add(scan_result,data);
                break;
                case ADB_PRINT_RAW:
                    adb_db_print(ADB_PRINT_METHOD_BYTES,(int)msg.data0);
                break;
                case ADB_PRINT_DECODE:
                    adb_db_print(ADB_PRINT_METHOD_DECODE,(int)msg.data0);
                break;
            }</pre>
<p>Then the actual function</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_printDecode(int entry)
{
    adb_cmdMsg_t msg;
    msg.cmd = ADB_PRINT_DECODE;
    msg.data0 = (void *)entry;
    xQueueSend(adb_cmdQueue,&amp;msg,0); // If the queue is full... oh well
}</pre>
<p>Then add it to advDatabase.h</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_printDecode(int entry);
</pre>
<p>Finally to the usercmd.c</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int usrcmd_printDecode(int argc, char **argv)
{
    if(argc == 1)
    {
        adb_printDecode(-1);
    }

    if(argc == 2)
    {
        int val;
        sscanf(argv[1],"%d",&amp;val);
        adb_printDecode(val);
    }
    return 0;
}</pre>
<h1>Program and Test</h1>
<p>When I actually program the scanner you can see that I can print out 1 item.  OR I can decode one item.  Notice that one contains 3 fields</p>
<ul>
<li>flags</li>
<li>Tx Power Level</li>
<li>Manufacturers data.  Apparently an Apple something or the other</li>
</ul>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/screen-shot-2020-11-09-at-7-53-43-am/" rel="attachment wp-att-10211"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-1024x219.png" alt="" class="alignnone size-large wp-image-10211" width="1024" height="219" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-1024x219.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-300x64.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-768x164.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-600x128.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM.png 1358w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And I can print the whole table</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/screen-shot-2020-11-09-at-7-51-10-am/" rel="attachment wp-att-10213"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-1024x629.jpg" alt="" class="alignnone size-large wp-image-10213" width="1024" height="629" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-1024x629.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-300x184.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-768x472.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-1536x944.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-2048x1259.jpg 2048w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-600x369.jpg 600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Or decode the whole table.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/screen-shot-2020-11-09-at-7-51-33-am/" rel="attachment wp-att-10212"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-1024x633.jpg" alt="" class="alignnone size-large wp-image-10212" width="1024" height="633" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-1024x633.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-300x185.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-768x475.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-1536x949.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-2048x1266.jpg 2048w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-600x371.jpg 600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 5)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 23 Nov 2020 18:03:57 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10196</guid>

					<description><![CDATA[Summary In this article I will add a new task to the AnyCloud BLE Advertising Scanning application which will save the advertising data into a database. Story There is still a boatload of mostly unintelligible advertising data coming ripping onto our screen.  It is FINALLY time to start fixing that.  In this article I will [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In this article I will add a new task to the AnyCloud BLE Advertising Scanning application which will save the advertising data into a database.</p>
<h1>Story</h1>
<p>There is still a boatload of mostly unintelligible advertising data coming ripping onto our screen.  It is FINALLY time to start fixing that.  In this article I will create a new task called the advertising database task which will hold the history of advertising packets that I have seen.  I will update the Bluetooth Manager task to submit the advertising packets to a queue running in the advertising database task.</p>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Create an Advertising Data Database Task</h1>
<p>We need to create the file advertisingDatabase.h which will hold the task prototype (so that main can get going).</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

void adb_task(void *arg);
</pre>
<p>Then create the advertisingDatabase.c to hold the actual database code.  It will start with the definition of messages which can be sent to the task.  For now just &#8220;ADB_ADD&#8221;.  To make things a little bit simpler these command can have two data elements (which I call data0 and data1).  Then the main part of the task just</p>
<ol>
<li>Creates the queue to manage the messages</li>
<li>Process the message until the end of time</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include "FreeRTOS.h"
#include "queue.h"

static QueueHandle_t adb_cmdQueue;
typedef enum {
    ADB_ADD,
} adb_cmd_t;

typedef struct
{
    adb_cmd_t cmd;
    void *data0;
    void *data1;
} adb_cmdMsg_t;

void adb_task(void *arg)
{
    // setup the queue
    adb_cmdMsg_t msg;

    adb_cmdQueue = xQueueCreate(10,sizeof(adb_cmdMsg_t));
    
    while(1)
    {
        BaseType_t status = xQueueReceive(adb_cmdQueue,&amp;msg,portMAX_DELAY);
        if(status == pdTRUE) 
        {
            switch(msg.cmd)
            {
                case ADB_ADD:
                break;
            }

        }
    }
}
</pre>
<p>To start the task, you need to add it to main.c.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    xTaskCreate(adb_task,"adv database",configMINIMAL_STACK_SIZE*4,0,1,0);
</pre>
<p>When I build and program this, you can now see the new task.  Good that working.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">AnyCloud&gt; Unhandled Bluetooth Management Event: BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT
Started BT Stack Succesfully

AnyCloud&gt; tasks
Name          State Priority   Stack  Num
------------------------------------------
usrcmd_ta       X       0       228     5
IDLE            R       0       115     7
Tmr Svc         B       0       223     8
CYBT_HCI_       B       5       950     3
sleep_tas       B       6       221     1
CYBT_BT_T       B       4       1371    2
blinkTask       B       0       98      4
adv datab       B       1       479     6
‘B’ – Blocked
‘R’ – Ready
‘D’ – Deleted (waiting clean up)
‘S’ – Suspended, or Blocked without a timeout
Stack = bytes free at highwater
AnyCloud&gt;</pre>
<h1>Update the Advertising Database to Accept Submitted ADV Packets</h1>
<p>If you recall our original setup was to take advertising packets in the Bluetooth Manager thread and print out the data.  The first thing that we want to fix up is the ability of the advertising database task to accept advertising packets which are pushed to its command queue.   To prepare for this I create two local variables to hold the data.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_task(void *arg)
{
    // setup the queue
    adb_cmdMsg_t msg;
    wiced_bt_ble_scan_results_t *scan_result;
    uint8_t *data;</pre>
<p>Then I update the ADB_ADD command.  My first, and really simple fix, is to grab the printing code from the Bluetooth Manager task.  Obviously this won&#8217;t be an improvement from the original program as far as the users goes, but it will verify that the tasks are working properly together.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_ADD:
                    // Print the MAC Address
                    scan_result = (wiced_bt_ble_scan_results_t *)msg.data0;
                    data = (uint8_t *)msg.data1;

                    printf("MAC: ");
                    for(int i=0;i&lt;BD_ADDR_LEN;i++)
                    {
                        printf("%02X:",scan_result-&gt;remote_bd_addr[i]);
                    }
                    // Print the RAW Data of the ADV Packet
                    printf(" Data: ");
                    int i=0;
                    while(data[i])
                    {
                        for(int j=0;j&lt;data[i];j++)
                        {
                            printf("%02X ",data[i+1+j]);
                        }
                        i = i + data[i]+1;
                    }
                    printf("\n");
    
                    free(msg.data0);
                    free(msg.data1);
                break;
</pre>
<p>Then I add a command to the advertisingDatabase.h which the Bluetooth Manager task can call to submit advertising packets</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_addAdv(wiced_bt_ble_scan_results_t *scan_result,void *data);</pre>
<p>The actual command in advertisingDatabase.c just takes the advertising information, puts it in a command message, then submits it to the command queue.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_addAdv(wiced_bt_ble_scan_results_t *scan_result,void *data)
{
    adb_cmdMsg_t msg;
    msg.cmd = ADB_ADD;
    msg.data0 = (void *)scan_result;
    msg.data1 = (void *)data;
    xQueueSend(adb_cmdQueue,&amp;msg,0); // If you loose an adv packet it is OK...
}
</pre>
<h1>Update the Bluetooth Manager to Submit Adv Packets</h1>
<p>Now I go and edit the bluetoothManager. c to submit packets rather than print them.  To do this I greatly simplify the callback.  There is one VERY important issue to deal with, which is one of those potential religious war issues.  Memory.</p>
<p>When you get the callback from the stack, it gives you POINTERS to data for the advertising packet that reside inside of buffers inside of the stack.  As soon as this callback returns this memory is purged.  To prevent this data from getting cleaned up by the stack I</p>
<ol>
<li>Malloc some memory for the wiced_bt_ble_scan_results</li>
<li>Malloc some memory for the advertising data</li>
<li>Make a copy of the data</li>
<li>Submit it to the Advertising Database</li>
</ol>
<p>I KNOW from the spec that the largest data packet is 31-bytes (actually it is 31-bytes + one more field with length 0).  So I know the maximum length is 32-bytes  This means that in many situations I will be copying GARBAGE into my buffer if the packet is less than 32 bytes long.  I think that this is simpler than calculating the length and then only copying that much data.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void btm_advCallback(wiced_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data)
{
    wiced_bt_ble_scan_results_t *scan_result = malloc(sizeof(wiced_bt_ble_scan_results_t));
    uint8_t *data = malloc(32);
   
    memcpy(data,p_adv_data,32);
    memcpy(scan_result,p_scan_result-&gt;remote_bd_addr,BD_ADDR_LEN);
    adb_addAdv(scan_result,data);
}
</pre>
<p>When I run this updated program I should get the same stream of data coming out on the serial port.  Sure enough the new thread is working.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/screen-shot-2020-11-07-at-10-23-16-am/" rel="attachment wp-att-10198"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-1024x577.png" alt="" width="1024" height="577" class="alignnone size-large wp-image-10198" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-1024x577.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-300x169.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-768x433.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-1536x865.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-600x338.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM.png 1868w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Create an Advertising Data Database</h1>
<p>Now, lets create an actual database.  To simplify things my database is just an array of structures.  One structure per bluetooth device.  The structure will contain a pointer to the information about the device it just saw and the actual raw data.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct {
    wiced_bt_ble_scan_results_t *result;
    uint8_t *data;
} adb_adv_t ;

#define ADB_MAX_SIZE (40)
adb_adv_t adb_database[ADB_MAX_SIZE];
int adb_db_count=0;
</pre>
<p>Then I will create several helper functions to work with the database</p>
<ol>
<li>Find devices in the database given a mac address</li>
<li>Print an entry in the database</li>
<li>Add entries to the database</li>
</ol>
<p>First, find an entry in the database.  This function will search through the database and compare the mac address against the mac address in the database.  When the memcmp ==0 meaning it found a match, it will return that entry.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static int adb_db_find(wiced_bt_device_address_t *add)
{
    int rval=-1;
    for(int i=0;i&lt;adb_db_count;i++)
    {
        if(memcmp(add,&amp;adb_database[i].result-&gt;remote_bd_addr,BD_ADDR_LEN)==0)
        {
            rval = i;
            break;
        }
    }
    return rval;
}</pre>
<p>The print function will make sure that you asked for a legal entry (much must be greater than 0&#8230; and less than the max).  Then it will print out the mac address and the raw data.  In a future post I will add a smarter print out.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_printEntry(int entry)
{
    if(!(entry&gt;= 0 &amp;&amp; entry &lt;= adb_db_count))
    {
        printf("Illegal entry\n");
        return;
    }
    printf("%02d MAC: ",entry);

    for(int i=0;i&lt;BD_ADDR_LEN;i++)
    {
        printf("%02X:",adb_database[entry].result-&gt;remote_bd_addr[i]);
    }

    // Print the RAW Data of the ADV Packet
    printf(" Data: ");
    int i=0;
    while(adb_database[entry].data[i])
    {
        for(int j=0;j&lt;adb_database[entry].data[i];j++)
        {
            printf("%02X ",adb_database[entry].data[i+1+j]);
        }
        i = i + adb_database[entry].data[i]+1;
    }
    printf("\n");
}</pre>
<p>To add an entry to the database, first make sure that it isn&#8217;t already in the database.  Then when you are sure that it isn&#8217;t the database, you just add the pointers to your table.  You need to make sure and not go beyond the end of the table, and if you did, you will have effectively blown away the last entry in the table.  Oh well.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_add(wiced_bt_ble_scan_results_t *scan_result,uint8_t *data)
{
 
    int entry = adb_db_find(&amp;scan_result-&gt;remote_bd_addr);
    if(entry == -1)
    {
        
        adb_database[adb_db_count].result = scan_result;
        adb_database[adb_db_count].data = data;
        adb_db_printEntry(adb_db_count);
        adb_db_count = adb_db_count + 1;
        if(adb_db_count == ADB_MAX_SIZE)
        {
            printf("ADV Table Max Size\n");
            adb_db_count = adb_db_count - 1;
        }
    }
    else
    {
        free(scan_result);
        free(data);
    }
}
</pre>
<h1>Add a Command to Print the Database</h1>
<p>Now we want to add the ability to print from the command line.  So add a new command message to the list of legal commands.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_ADD,
    ADB_PRINT,
} adb_cmd_t;
</pre>
<p>Then create a new function to print.  If you send in a &#8220;-1&#8221; it will print the whole table.  Otherwise just print the individual entry.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static void adb_printTable(int entry)
{
    if(entry == -1)
    {
        for(int i=0;i&lt;adb_db_count;i++)
        {
            adb_db_printEntry(i);
        }

    }
    else
    {
        adb_db_printEntry(entry);
    }
    

}</pre>
<p>Now edit usercmd.c to have the new command line.  Notice that I use &#8220;sscanf&#8221; which obviously has some issues.  Too bad.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static int usrcmd_print(int argc, char **argv)
{

    if(argc == 1)
    {
        adb_print(-1); // Print whole table
    }

    if(argc == 2)
    {
        int val;
        sscanf(argv[1],"%d",&amp;val);
        adb_print(val);
    }

    return 0;
}</pre>
<p>When I program the project it immediately prints out a bunch of devices that are at my house.  Then you can see I run the &#8220;print&#8221; command which prints the table.  Finally P do a print 0 to just print the first entry.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/screen-shot-2020-11-08-at-9-34-13-am/" rel="attachment wp-att-10201"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-1024x782.jpg" alt="" width="1024" height="782" class="alignnone size-large wp-image-10201" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-1024x782.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-300x229.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-768x587.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-1536x1173.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-600x458.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM.jpg 1864w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In the next article I will add smarter diagnostics to the advertising packets.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Utilities Library</title>
		<link>https://iotexpert.com/anycloud-bluetooth-utilities-library/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-utilities-library/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 09 Nov 2020 13:18:17 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-BLE]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10175</guid>

					<description><![CDATA[Summary This article is a discussion of a library of utilities functions that support AnyCloud Bluetooth development.  It includes settings to configure the hardware, functions to decode stack events, functions to decode advertising packets etc. Story The Cypress, now Infineon, Modus Toolbox team has been working to bring the WICED Bluetooth devices to be closer [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This article is a discussion of a library of utilities functions that support AnyCloud Bluetooth development.  It includes settings to configure the hardware, functions to decode stack events, functions to decode advertising packets etc.</p>
<h1>Story</h1>
<p>The Cypress, now Infineon, Modus Toolbox team has been working to bring the WICED Bluetooth devices to be closer and more compatible with the PSoC 6 tools.  One of the important enablement things we have done is turn on the WICED Bluetooth Host stack on the PSoC 6 so that it can effectively talk to the CYW43XXX Bluetooth / WiFi combo chips.</p>
<p>As I have been using all of the new stuff I found myself adding my own custom functionality&#8230;. and after a while I realized (finally) that I should put all of those little helper things into a library, specifically an IoT Expert library.  For now this library contains:</p>
<ul>
<li>The Bluetooth Platform Configuration Settings</li>
<li>Functions to decode stack events</li>
<li>Functions to decode advertising packets</li>
</ul>
<p>but imagine with time I will add more functions and templates.</p>
<h1><span>bt_platform_cfg_settings</span></h1>
<p>As I discussed in the article <a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener noreferrer">AnyCloud Bluetooth Advertising Scanner (Part 1)</a>, every single AnyCloud BLE Stack project will require a structure of type wiced_bt_cfg_settings_t.  This structure is used to setup the hardware before getting the stack going.  Remember you need to make a call like this to initialize the Bluetooth hardware.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    cybt_platform_config_init(&amp;bt_platform_cfg_settings);
</pre>
<p>At some point this file will be included automatically for you by the Modus Toolbox team, but for now I have added this to my library.  This file look like this.  Basically a bunch of pin definitions which are set for you automatically by the BSP.  Obviously you can make your own, but this should work on all of the Cypress development kits (I think)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include "cybt_platform_config.h"
#include "cybsp.h"
#include "wiced_bt_stack.h"

const cybt_platform_config_t bt_platform_cfg_settings =
{
    .hci_config =
    {
        .hci_transport = CYBT_HCI_UART,

        .hci =
        {
            .hci_uart =
            {
                .uart_tx_pin = CYBSP_BT_UART_TX,
                .uart_rx_pin = CYBSP_BT_UART_RX,
                .uart_rts_pin = CYBSP_BT_UART_RTS,
                .uart_cts_pin = CYBSP_BT_UART_CTS,

                .baud_rate_for_fw_download = 115200,
                .baud_rate_for_feature     = 115200,

                .data_bits = 8,
                .stop_bits = 1,
                .parity = CYHAL_UART_PARITY_NONE,
                .flow_control = WICED_TRUE
            }
        }
    },

    .controller_config =
    {
        .bt_power_pin      = CYBSP_BT_POWER,
        .sleep_mode =
        {
            #if (bt_0_power_0_ENABLED == 1) /* BT Power control is enabled in the LPA */
            #if (CYCFG_BT_LP_ENABLED == 1) /* Low power is enabled in the LPA, use the LPA configuration */
            .sleep_mode_enabled = true,
            .device_wakeup_pin = CYCFG_BT_DEV_WAKE_GPIO,
            .host_wakeup_pin = CYCFG_BT_HOST_WAKE_GPIO,
            .device_wake_polarity = CYCFG_BT_DEV_WAKE_POLARITY,
            .host_wake_polarity = CYCFG_BT_HOST_WAKE_IRQ_EVENT
            #else /* Low power is disabled in the LPA, disable low power */
            .sleep_mode_enabled = false
            #endif
            #else /* BT Power control is disabled in the LPA – default to BSP low power configuration */
            .sleep_mode_enabled = true,
            .device_wakeup_pin = CYBSP_BT_DEVICE_WAKE,
            .host_wakeup_pin = CYBSP_BT_HOST_WAKE,
            .device_wake_polarity = CYBT_WAKE_ACTIVE_LOW,
            .host_wake_polarity = CYBT_WAKE_ACTIVE_LOW
            #endif
        }
    },

    .task_mem_pool_size    = 2048
};</pre>
<h1><span>btutil_stack</span></h1>
<p>When you startup the Bluetooth Host stack you are responsible for providing a &#8220;management callback&#8221; which has the function prototype</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef wiced_result_t (wiced_bt_management_cback_t) (wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data);
</pre>
<p>The first parameter is an &#8220;event&#8221; which is  just an enumerated list of possible events by the Bluetooth Host Stack.  Here is the actual list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">enum wiced_bt_management_evt_e {
    /* Bluetooth status events */
    BTM_ENABLED_EVT,                                /**&lt; Bluetooth controller and host stack enabled. Event data: wiced_bt_dev_enabled_t */
    BTM_DISABLED_EVT,                               /**&lt; Bluetooth controller and host stack disabled. Event data: NULL */
    BTM_POWER_MANAGEMENT_STATUS_EVT,                /**&lt; Power management status change. Event data: wiced_bt_power_mgmt_notification_t */
    BTM_RE_START_EVT,                               /**&lt; Bluetooth controller and host stack re-enabled. Event data: tBTM_ENABLED_EVT */
    /* Security events */
    BTM_PIN_REQUEST_EVT,                            /**&lt; PIN request (used only with legacy devices). Event data: #wiced_bt_dev_name_and_class_t */
    BTM_USER_CONFIRMATION_REQUEST_EVT,              /**&lt; received USER_CONFIRMATION_REQUEST event (respond using #wiced_bt_dev_confirm_req_reply). Event data: #wiced_bt_dev_user_cfm_req_t */
    BTM_PASSKEY_NOTIFICATION_EVT,                   /**&lt; received USER_PASSKEY_NOTIFY event. Event data: #wiced_bt_dev_user_key_notif_t */
    BTM_PASSKEY_REQUEST_EVT,                        /**&lt; received USER_PASSKEY_REQUEST event @cond DUAL_MODE (respond using #wiced_bt_dev_pass_key_req_reply). Event data: #wiced_bt_dev_user_key_req_t @endcond
                                                     @note  BR/EDR Only */
    BTM_KEYPRESS_NOTIFICATION_EVT,                  /**&lt; received KEYPRESS_NOTIFY event. Event data: #wiced_bt_dev_user_keypress_t */
    BTM_PAIRING_IO_CAPABILITIES_BR_EDR_REQUEST_EVT, /**&lt; Requesting IO capabilities for BR/EDR pairing. Event data: #wiced_bt_dev_bredr_io_caps_req_t 
                                                        @note  BR/EDR Only */
    BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT,/**&lt; Received IO capabilities response for BR/EDR pairing. Event data: @cond DUAL_MODE #wiced_bt_dev_bredr_io_caps_rsp_t @endcond
                                                        @note  BR/EDR Only*/
    BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT,    /**&lt; Requesting IO capabilities for BLE pairing. Slave can check peer io capabilities in event data before updating with local io capabilities. Event data: #wiced_bt_dev_ble_io_caps_req_t */
    BTM_PAIRING_COMPLETE_EVT,                       /**&lt; received SIMPLE_PAIRING_COMPLETE event. Event data: #wiced_bt_dev_pairing_cplt_t */
    BTM_ENCRYPTION_STATUS_EVT,                      /**&lt; Encryption status change. Event data: #wiced_bt_dev_encryption_status_t */
    BTM_SECURITY_REQUEST_EVT,                       /**&lt; Security request (respond using #wiced_bt_ble_security_grant). Event data: #wiced_bt_dev_security_request_t */
    BTM_SECURITY_FAILED_EVT,                        /**&lt; Security procedure/authentication failed. Event data: #wiced_bt_dev_security_failed_t */
    BTM_SECURITY_ABORTED_EVT,                       /**&lt; Security procedure aborted locally, or unexpected link drop. Event data: #wiced_bt_dev_name_and_class_t */

    BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT,           /**&lt; Result of reading local OOB data @cond DUAL_MODE (#wiced_bt_dev_read_local_oob_data). Event data: #wiced_bt_dev_local_oob_t @endcond 
                                                        @note  BR/EDR Only */

    BTM_REMOTE_OOB_DATA_REQUEST_EVT,                /**&lt; OOB data from remote device @cond DUAL_MODE (respond using #wiced_bt_dev_remote_oob_data_reply). Event data: #wiced_bt_dev_remote_oob_t @endcond 
                                                        @note  BR/EDR Only */

    BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT,         /**&lt; Updated remote device link keys (store device_link_keys to  NV memory). This is the place to
verify that the correct link key has been generated. Event data: #wiced_bt_device_link_keys_t */
    BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT,        /**&lt; Request for stored remote device link keys (restore device_link_keys from NV memory). If successful, return WICED_BT_SUCCESS. Event data: #wiced_bt_device_link_keys_t */

    BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT,             /**&lt; Update local identity key (stored local_identity_keys NV memory). Event data: #wiced_bt_local_identity_keys_t */
    BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT,            /**&lt; Request local identity key (get local_identity_keys from NV memory). If successful, return WICED_BT_SUCCESS. Event data: #wiced_bt_local_identity_keys_t */

    BTM_BLE_SCAN_STATE_CHANGED_EVT,                 /**&lt; BLE scan state change. Event data: #wiced_bt_ble_scan_type_t */
    BTM_BLE_ADVERT_STATE_CHANGED_EVT,               /**&lt; BLE advertisement state change. Event data: #wiced_bt_ble_advert_mode_t */

    /* BLE Secure Connection events */
    BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT,            /**&lt; SMP remote oob data request. Reply using wiced_bt_smp_oob_data_reply. Event data: #wiced_bt_smp_remote_oob_req_t  */
    BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT,         /**&lt; LE secure connection remote oob data request. Reply using wiced_bt_smp_sc_oob_reply. Event data: #wiced_bt_smp_sc_remote_oob_req_t 
                                                        @note  BR/EDR Only */
    BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT,     /**&lt; LE secure connection local OOB data (wiced_bt_smp_create_local_sc_oob_data). Event data: #wiced_bt_smp_sc_local_oob_t */

    BTM_SCO_CONNECTED_EVT,                          /**&lt; SCO connected event. Event data: @cond DUAL_MODE #wiced_bt_sco_connected_t @endcond
                                                        @note  BR/EDR Only */
    BTM_SCO_DISCONNECTED_EVT,                       /**&lt; SCO disconnected event. Event data: @cond #wiced_bt_sco_disconnected_t @endcond
                                                        @note  BR/EDR Only */
    BTM_SCO_CONNECTION_REQUEST_EVT,                 /**&lt; SCO connection request event. Event data: @cond #wiced_bt_sco_connection_request_t @endcond
                                                        @note  BR/EDR Only */
    BTM_SCO_CONNECTION_CHANGE_EVT,                  /**&lt; SCO connection change event. Event data: @cond #wiced_bt_sco_connection_change_t @endcond
                                                        @note  BR/EDR Only */
    BTM_BLE_CONNECTION_PARAM_UPDATE,                /**&lt; BLE connection parameter update. Event data: #wiced_bt_ble_connection_param_update_t */
    BTM_BLE_PHY_UPDATE_EVT,                         /**&lt; BLE Physical link update. Event data: wiced_bt_ble_phy_update_t */
    BTM_LPM_STATE_LOW_POWER,                        /**&lt; BT device wake has been deasserted. Used for Host Stack Use Case. */
    BTM_MULTI_ADVERT_RESP_EVENT,                    /**&lt; Multi adv command status event Used for the status of the command sent */
#if SMP_CATB_CONFORMANCE_TESTER == TRUE
    BTM_SMP_SC_PEER_INFO_EVT                        /** The Secure Connections support information of the peer device */
#endif

};</pre>
<p>While you are trying to figure out what is going on during the development, it is very useful to be able to print out the name of the events (instead of the numbers).  In other words instead of doing</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">printf("Event = %02X\n",event);</pre>
<p>it is way better to do</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">printf("Event Name=%s\n",btutil_getBTEventName(event));</pre>
<p>While I was looking at an example project I found this function which I thought was awesome.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">const char *btutil_getBTEventName(wiced_bt_management_evt_t event)
{
    switch ( (int)event )
    {
    CASE_RETURN_STR(BTM_ENABLED_EVT)
    CASE_RETURN_STR(BTM_DISABLED_EVT)
    CASE_RETURN_STR(BTM_POWER_MANAGEMENT_STATUS_EVT)
    CASE_RETURN_STR(BTM_PIN_REQUEST_EVT)
    CASE_RETURN_STR(BTM_USER_CONFIRMATION_REQUEST_EVT)
    CASE_RETURN_STR(BTM_PASSKEY_NOTIFICATION_EVT)
    CASE_RETURN_STR(BTM_PASSKEY_REQUEST_EVT)
    CASE_RETURN_STR(BTM_KEYPRESS_NOTIFICATION_EVT)
    CASE_RETURN_STR(BTM_PAIRING_IO_CAPABILITIES_BR_EDR_REQUEST_EVT)
    CASE_RETURN_STR(BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT)
    CASE_RETURN_STR(BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT)
    CASE_RETURN_STR(BTM_PAIRING_COMPLETE_EVT)
    CASE_RETURN_STR(BTM_ENCRYPTION_STATUS_EVT)
    CASE_RETURN_STR(BTM_SECURITY_REQUEST_EVT)
    CASE_RETURN_STR(BTM_SECURITY_FAILED_EVT)
    CASE_RETURN_STR(BTM_SECURITY_ABORTED_EVT)
    CASE_RETURN_STR(BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT)
    CASE_RETURN_STR(BTM_REMOTE_OOB_DATA_REQUEST_EVT)
    CASE_RETURN_STR(BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT)
    CASE_RETURN_STR(BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT)
    CASE_RETURN_STR(BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT)
    CASE_RETURN_STR(BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT)
    CASE_RETURN_STR(BTM_BLE_SCAN_STATE_CHANGED_EVT)
    CASE_RETURN_STR(BTM_BLE_ADVERT_STATE_CHANGED_EVT)
    CASE_RETURN_STR(BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT)
    CASE_RETURN_STR(BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT)
    CASE_RETURN_STR(BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT)
    CASE_RETURN_STR(BTM_SCO_CONNECTED_EVT)
    CASE_RETURN_STR(BTM_SCO_DISCONNECTED_EVT)
    CASE_RETURN_STR(BTM_SCO_CONNECTION_REQUEST_EVT)
    CASE_RETURN_STR(BTM_SCO_CONNECTION_CHANGE_EVT)
    CASE_RETURN_STR(BTM_BLE_CONNECTION_PARAM_UPDATE)
#ifdef CYW20819A1
    CASE_RETURN_STR(BTM_BLE_PHY_UPDATE_EVT)
#endif
    }

    return NULL;
}</pre>
<p>And then I learned something new when I looked at the &#8220;function&#8221; CASE_RETURN_STR which used compiler trick to turn an enumerated value into a string.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define CASE_RETURN_STR(enum_val)          case enum_val: return #enum_val;</pre>
<p>This allows you to do this in your management callback (notice line 16 where the string is printed out)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">wiced_result_t app_bt_management_callback(wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data)
{
    wiced_result_t result = WICED_BT_SUCCESS;

    switch (event)
    {
        case BTM_ENABLED_EVT:
            if (WICED_BT_SUCCESS == p_event_data-&gt;enabled.status)
            {
                printf("Started BT Stack Succesfully\n");
                wiced_bt_ble_observe(WICED_TRUE,0,obv_callback);
            }
            break;

        default:
            printf("Unhandled Bluetooth Management Event: %s\n", btutil_getBTEventName(event));
            break;
    }

    return result;
}</pre>
<p>It turns out that there are several other places where the stack gives you an event-ish thing.  So these functions were created as well</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

const char *btutil_getBTEventName(wiced_bt_management_evt_t event);
const char *btutil_getBLEAdvertModeName(wiced_bt_ble_advert_mode_t mode);
const char *btutil_getBLEGattDisconnReasonName(wiced_bt_gatt_disconn_reason_t reason);
const char *btutil_getBLEGattStatusName(wiced_bt_gatt_status_t status);</pre>
<h1><span>btutil_adv_decode</span></h1>
<p>In <a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener noreferrer">AnyCloud Bluetooth Advertising Scanner (Part 3)</a> I discussed the format of the advertising packet.  So I created functions which will decode the data in the advertising packets.  More on the future article AnyCloud Bluetooth Advertising Scanner (Part 4 or maybe 5 or maybe 6).  Here are the functions:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

wiced_bool_t btutil_isEddystone(uint8_t *data);
wiced_bool_t btutil_is_iBeacon(uint8_t *data);
wiced_bool_t btutil_isCypress(uint8_t *data);

int btutil_adv_len(uint8_t *packet);
void btutil_adv_printPacketDecode(uint8_t *packet);
void btutil_adv_printPacketBytes(uint8_t *packet);</pre>
<h1>btutil</h1>
<p>And because I like to have just one include to get access to all of the function I created &#8220;btutil.h&#8221; which just includes all of the headers in one place.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

#include "btutil_adv_decode.h"
#include "btutil_stack.h"
#include "btutil_general.h"
#include "bt_platform_cfg_settings.h"
</pre>
<h1>Add to the IoT Expert Manifest</h1>
<p>In order to set it up for my library to live in the library manager I updated the IoT Expert Manifest file to have a link to the GitHub repository</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">&lt;middleware&gt;
  
    &lt;name&gt;Bluetooth Utilities&lt;/name&gt;
    &lt;id&gt;btutil&lt;/id&gt;
    &lt;uri&gt;https://github.com/iotexpert/btutil&lt;/uri&gt;
    &lt;desc&gt;A library of Bluetooth Debugging Utilties for Cypress PSoC6 Anycloud&lt;/desc&gt;
    &lt;category&gt;IoT Expert&lt;/category&gt;
    &lt;req_capabilities&gt;psoc6&lt;/req_capabilities&gt;
    &lt;versions&gt;
      &lt;version flow_version="1.0,2.0"&gt;
        &lt;num&gt;master&lt;/num&gt;
        &lt;commit&gt;master&lt;/commit&gt;
        &lt;desc&gt;master&lt;/desc&gt;
      &lt;/version&gt;
    &lt;/versions&gt;
  &lt;/middleware&gt;
</pre>
<p>And now the library manager has the IoT Expert Bluetooth Utilities.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-utilities-library/screen-shot-2020-11-01-at-10-43-31-am/" rel="attachment wp-att-10180"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-1024x815.png" alt="" class="alignnone size-large wp-image-10180" width="1024" height="815" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-1024x815.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-300x239.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-768x611.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-600x477.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM.png 1116w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1></h1>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-utilities-library/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 1)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 19 Oct 2020 12:40:29 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[ModusToolbox]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10102</guid>

					<description><![CDATA[Summary The first of several articles discussing the use of the AnyCloud BLE Stack to build advertising scanner/observers. Story A few summers ago while I was writing the WICED Bluetooth Academy book, I created a WICED based BLE advertising scanner.  Actually, I created a framework for the scanner and the remarkable summer intern I had [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>The first of several articles discussing the use of the AnyCloud BLE Stack to build advertising scanner/observers.</p>
<h1>Story</h1>
<p>A few summers ago while I was writing the WICED Bluetooth Academy book, I created a WICED based BLE advertising scanner.  Actually, I created a framework for the scanner and the remarkable summer intern I had finished the work.  That project has been sitting in the source code repository for the Bluetooth class, mostly only shown to face-to-face students.  This scanner is built using some of the original code combined with the new AnyCloud Bluetooth SDK.  It will act sort-of-like <a href="https://punchthrough.com/lightblue/" target="_blank" rel="noopener noreferrer">LightBlue</a> or one of the other Bluetooth advertising scanners you might run on your phone, but with a serial console.</p>
<p>Sometime in the last few months we released the Bluetooth SDK for AnyCloud (things have been crazy and I have lost track of time)  This SDK has all of the stuff needed to add Bluetooth to your AnyCloud project using one of the Cypress Bluetooth/WiFi combo chips.  I had not had a chance to try it out, so I decided to build a Bluetooth project and then port the scanning code.</p>
<p><span><p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p></span></p>
<h1>Bluetooth Application Architecture</h1>
<p>Bluetooth applications are divided into these four pieces</p>
<ol>
<li>You user application which responds to events and sends messages from/to the Bluetooth host stack</li>
<li>A Bluetooth Host Stack</li>
<li>A Bluetooth Controller Stack</li>
<li>The Bluetooth Radio</li>
</ol>
<p>These four pieces can be divided into multiple chips, as few as one or as many as four.  However, for this article, the project will be built to run on a PSoC 6 + CYW43012 WiFi/Bluetooth Combo chip.  Specifically:</p>
<ol>
<li>My scanner application running on the PSoC 6</li>
<li>The Bluetooth Host Stack running on the PSoC 6</li>
<li>The BlueTooth Controller Firmware running on the CYW43012</li>
<li>A Bluetooth Radio on the CYW43012</li>
</ol>
<p>But how do they talk?  Simple, there is:</p>
<ol>
<li>A UART Host Controller Interface (HCI) between the two chips</li>
<li>A GPIO to serve as a deep sleep wakeup from the 43012 &#8211;&gt; PSoC 6</li>
<li>A GPIO to serve as the bluetooth controller wakeup from the PSoC 6 &#8211;&gt; 43012</li>
<li>A GPIO to turn on the Bluetooth regulator from the PSoC 6 &#8211;&gt; 43012</li>
</ol>
<p>Here is the block diagram from the CY8CKIT-062S2-43012 Kit Guide.  Notice that signals labeled UART and Control going between the PSoC 6 and the CYW43012.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/screen-shot-2020-10-18-at-9-34-51-am/" rel="attachment wp-att-10129"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.51-AM-1024x486.png" alt="" width="1024" height="486" class="alignnone size-large wp-image-10129" srcset="https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.51-AM-1024x486.png 1024w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.51-AM-300x142.png 300w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.51-AM-768x364.png 768w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.51-AM-1536x729.png 1536w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.51-AM-2048x972.png 2048w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.51-AM-600x285.png 600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And when you read more deeply into the schematic you can see the signals labeled</p>
<ul>
<li>BT_UART_TXD/RXD/CTS/RTS</li>
<li>BT_HOST_WAKE</li>
<li>BT_DEV_WAKE</li>
<li>BT_REG_ON</li>
</ul>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/screen-shot-2020-10-18-at-9-34-25-am/" rel="attachment wp-att-10128"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.25-AM-1024x875.jpg" alt="" width="1024" height="875" class="alignnone size-large wp-image-10128" srcset="https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.25-AM-1024x875.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.25-AM-300x256.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.25-AM-768x656.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.25-AM-600x512.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/10/Screen-Shot-2020-10-18-at-9.34.25-AM.jpg 1192w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>How to Start the AnyCloud Bluetooth Stack</h1>
<p>To actually start the AnyCloud Bluetooth stack you will call two functions</p>
<ol>
<li><strong>cybt_platform_config_init</strong> &#8211; that will setup the hardware interface to the CYW43012</li>
<li><strong>wiced_bt_stack_init</strong> that will:
<ol>
<li>Start a task to manage the Host Controller Interface</li>
<li>Download the controller firmware to the CYW43012</li>
<li>Start a task to manage the host stack</li>
<li>Initialize both the host and the controller</li>
<li>Call you back when that is all done</li>
</ol>
</li>
</ol>
<p>Here is an example from main.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    cybt_platform_config_init(&amp;bt_platform_cfg_settings);
    wiced_bt_stack_init (app_bt_management_callback, &amp;wiced_bt_cfg_settings);</pre>
<p>When you look at these two function calls, you will find that you need to provide three things:</p>
<ol>
<li>A platform hardware configuration structure called bt_platform_cfg_settings</li>
<li>The Bluetooth stack configuration settings structure called wiced_bt_cfg_settings</li>
<li>A management callback called app_bt_management_callback</li>
</ol>
<h1>bt_platform_cfg_settings</h1>
<p>The purpose of the hardware configuration structure is to define the UART + parameters and the wakeup GPIOs.  Specifically, the hardware configuration structure defines the configuration of the host controller interface (hci)</p>
<ol>
<li>The HCI transport scheme (in this case UART)</li>
<li>The pins of the UART</li>
<li>Baud Rate</li>
<li>Data Bits</li>
<li>Stop Bits</li>
<li>Parity</li>
<li>Flow Control</li>
</ol>
<p>And the controller low power behavior (in the .controller_config member)</p>
<p>This is a fairly standard configuration and I think that we should help you by providing this structure somewhere in the BSP.  But for now, you need to provide it (in an upcoming article I&#8217;ll update the IoT Expert Bluetooth Library to provide it).  Here is the specific structure that I will be using.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">const cybt_platform_config_t bt_platform_cfg_settings =
{
    .hci_config =
    {
        .hci_transport = CYBT_HCI_UART,

        .hci =
        {
            .hci_uart =
            {
                .uart_tx_pin = CYBSP_BT_UART_TX,
                .uart_rx_pin = CYBSP_BT_UART_RX,
                .uart_rts_pin = CYBSP_BT_UART_RTS,
                .uart_cts_pin = CYBSP_BT_UART_CTS,

                .baud_rate_for_fw_download = 115200,
                .baud_rate_for_feature     = 115200,

                .data_bits = 8,
                .stop_bits = 1,
                .parity = CYHAL_UART_PARITY_NONE,
                .flow_control = WICED_TRUE
            }
        }
    },

    .controller_config =
    {
        .bt_power_pin      = CYBSP_BT_POWER,
        .sleep_mode =
        {
            #if (bt_0_power_0_ENABLED == 1) /* BT Power control is enabled in the LPA */
            #if (CYCFG_BT_LP_ENABLED == 1) /* Low power is enabled in the LPA, use the LPA configuration */
            .sleep_mode_enabled = true,
            .device_wakeup_pin = CYCFG_BT_DEV_WAKE_GPIO,
            .host_wakeup_pin = CYCFG_BT_HOST_WAKE_GPIO,
            .device_wake_polarity = CYCFG_BT_DEV_WAKE_POLARITY,
            .host_wake_polarity = CYCFG_BT_HOST_WAKE_IRQ_EVENT
            #else /* Low power is disabled in the LPA, disable low power */
            .sleep_mode_enabled = false
            #endif
            #else /* BT Power control is disabled in the LPA – default to BSP low power configuration */
            .sleep_mode_enabled = true,
            .device_wakeup_pin = CYBSP_BT_DEVICE_WAKE,
            .host_wakeup_pin = CYBSP_BT_HOST_WAKE,
            .device_wake_polarity = CYBT_WAKE_ACTIVE_LOW,
            .host_wake_polarity = CYBT_WAKE_ACTIVE_LOW
            #endif
        }
    },

    .task_mem_pool_size    = 2048
};
</pre>
<h1>wiced_bt_cfg_settings</h1>
<p>The Cypress WICED Bluetooth Stack has a boatload of configuration settings.  When you call the stack start function you need to provide all of those settings in a structure of type &#8220;wiced_bt_cfg_settings_t&#8221; which is actually a structure of structures.  There are several basic ways to set these settings</p>
<ul>
<li>Start from scratch and build you own settings</li>
<li>Copy from an example project</li>
<li>Use the Bluetooth Configurator to generate the structure</li>
</ul>
<p>For the purposes of THIS project I started by copying the structure from on of the example projects and then modifying the three numbers that were relevant to me.  Specifically</p>
<ul>
<li>max_simultanous_link &#8211; which I changed to 0 because this is simply a Bluetooth Observer</li>
<li>low_duty_scan_interval &#8211; how long in the window to listen for advertising packets</li>
<li>low_duty_scan_window &#8211; how wide the window of listening should be</li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="c">const wiced_bt_cfg_settings_t wiced_bt_cfg_settings =
{
    .device_name                         = (uint8_t *)BT_LOCAL_NAME,                                   /**&lt; Local device name (NULL terminated) */
    .device_class                        = {0x00, 0x00, 0x00},                                         /**&lt; Local device class */
    .security_requirement_mask           = BTM_SEC_NONE,                                               /**&lt; Security requirements mask (BTM_SEC_NONE, or combinination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT (see #wiced_bt_sec_level_e)) */

    .max_simultaneous_links              = 0,                                                          /**&lt; Maximum number simultaneous links to different devices */

    .ble_scan_cfg =                                                 /* BLE scan settings  */
    {
        .scan_mode                       = BTM_BLE_SCAN_MODE_PASSIVE,                                  /**&lt; BLE scan mode (BTM_BLE_SCAN_MODE_PASSIVE, BTM_BLE_SCAN_MODE_ACTIVE, or BTM_BLE_SCAN_MODE_NONE) */

        /* Advertisement scan configuration */
        .high_duty_scan_interval         = WICED_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL,               /**&lt; High duty scan interval */
        .high_duty_scan_window           = WICED_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW,                 /**&lt; High duty scan window */
        .high_duty_scan_duration         = 0,                                                          /**&lt; High duty scan duration in seconds (0 for infinite) */

        .low_duty_scan_interval          = 96,                                                         /**&lt; Low duty scan interval  */
        .low_duty_scan_window            = 96,                                                         /**&lt; Low duty scan window */
        .low_duty_scan_duration          = 0,                                                          /**&lt; Low duty scan duration in seconds (0 for infinite) */

        /* Connection scan configuration */
        .high_duty_conn_scan_interval    = WICED_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL,          /**&lt; High duty cycle connection scan interval */
        .high_duty_conn_scan_window      = WICED_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW,            /**&lt; High duty cycle connection scan window */
        .high_duty_conn_duration         = 0,                                                         /**&lt; High duty cycle connection duration in seconds (0 for infinite) */

        .low_duty_conn_scan_interval     = WICED_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL,           /**&lt; Low duty cycle connection scan interval */
        .low_duty_conn_scan_window       = WICED_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW,             /**&lt; Low duty cycle connection scan window */
        .low_duty_conn_duration          = 0,                                                         /**&lt; Low duty cycle connection duration in seconds (0 for infinite) */

        /* Connection configuration */
        .conn_min_interval               = WICED_BT_CFG_DEFAULT_CONN_MIN_INTERVAL,                     /**&lt; Minimum connection interval */
        .conn_max_interval               = WICED_BT_CFG_DEFAULT_CONN_MAX_INTERVAL,                     /**&lt; Maximum connection interval */
        .conn_latency                    = WICED_BT_CFG_DEFAULT_CONN_LATENCY,                          /**&lt; Connection latency */
        .conn_supervision_timeout        = WICED_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT,              /**&lt; Connection link supervision timeout */
    },

    .default_ble_power_level            = 12                                                           /**&lt; Default LE power level, Refer lm_TxPwrTable table for the power range */
};
</pre>
<h1>app_bt_management_callback</h1>
<p>The last thing that you need to provide is a management callback.  This function is called by the Bluetooth Stack when a &#8220;management event&#8221; occurs.  There is a big-long-list of enumerated events of type wiced_bt_management_event_t.  The events include things like the the stack started &#8220;BTM_ENABLED_EVENT&#8221;.  Each event may have data associated with the event which is passed to you in a pointer to wiced_bt_management_event_data_t.</p>
<p>You typically deal with these events with a giant switch statement like this:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">wiced_result_t app_bt_management_callback(wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data)
{
    wiced_result_t result = WICED_BT_SUCCESS;

    switch (event)
    {
        case BTM_ENABLED_EVT:

            if (WICED_BT_SUCCESS == p_event_data-&gt;enabled.status)
            {
               printf("Stack Started Successfully\n");
            }

            break;


        default:
            printf("Unhandled Bluetooth Management Event: 0x%x %s\n", event, btutil_getBTEventName(event));
            break;
    }

    return result;
}
</pre>
<h1>Tasks</h1>
<p>The Bluetooth stack on the PSoC6 is operated with two tasks.  Specifically, when you call the wiced_bt_stack_init it will startup:</p>
<ol>
<li>CYBT_HCI_Task &#8211; a task that sends and receives HCI packets going to the Radio chip</li>
<li>CY_BT_Task &#8211; a task that manages the Bluetooth Host Stack</li>
</ol>
<p>Here is print of the task list from my project:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">AnyCloud&gt; tasks
Name          State Priority   Stack  Num
------------------------------------------
nt shell        X       0       236     5
IDLE            R       0       115     6
blink           B       0       98      4
CYBT_BT_Task    B       4       1371    2
sleep_task      B       6       217     1
CYBT_HCI_Task   B       5       950     3
Tmr Svc         B       6       76      7
‘B’ – Blocked
‘R’ – Ready
‘D’ – Deleted (waiting clean up)
‘S’ – Suspended, or Blocked without a timeout
Stack = bytes free at highwater</pre>
<p>&nbsp;</p>
<p>Now with the background in place, in the next article I will discuss Bluetooth advertising and how to build the observer project.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud &#8211; Wireless Connection Manager (Part 1)</title>
		<link>https://iotexpert.com/anycloud-wireless-connection-manager-part-1/</link>
					<comments>https://iotexpert.com/anycloud-wireless-connection-manager-part-1/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 04 May 2020 12:00:44 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=9019</guid>

					<description><![CDATA[Summary A discussion of using the Infineon (Cypress) PSoC 6 with a CYW4343W and the AnyCloud Connection Manager with Modus Toolbox.  The AnyCloud Connection Manager is an RTOS thread that lets you manage a connection to a WiFi network.  It knows how to scan for networks, attach, detach etc. and was recently released for use [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>A discussion of using the Infineon (Cypress) PSoC 6 with a CYW4343W and the AnyCloud Connection Manager with Modus Toolbox.  The AnyCloud Connection Manager is an RTOS thread that lets you manage a connection to a WiFi network.  It knows how to scan for networks, attach, detach etc. and was recently released for use with PSoC6 and 43xxx WiFi combos.</p>
<h1>The Story</h1>
<p>In the WICED WiFI SDK there is an example program called &#8220;test.console&#8221; which allows you to use a UART command line to do networking &#8220;stuff&#8221;.  With the release of the new AnyCloud SDK I decided that I should rebuild some of that program using the PSoC and WiFi.  Basically a set of commands like &#8220;scan&#8221; to interact with the Radio World!  In the picture you below you can see that I use the command &#8220;scan&#8221; to list out the networks at my house.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-1-04-36-pm/" rel="attachment wp-att-9021"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1024x623.png" alt="" width="1024" height="623" class="alignnone size-large wp-image-9021" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1024x623.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-600x365.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-300x182.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-768x467.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1536x934.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM.png 1950w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>You can also use the command &#8220;help&#8221; to list out the commands.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-1-04-58-pm/" rel="attachment wp-att-9022"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-1024x299.png" alt="" width="1024" height="299" class="alignnone size-large wp-image-9022" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-1024x299.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-600x175.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-300x88.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-768x224.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-1536x449.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM.png 1732w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-1-04-58-pm/" rel="attachment wp-att-9022"></a></p>
<h1>Architecture</h1>
<p>My implementation will have three tasks</p>
<ol>
<li>A Blinking LED Task (which doesn&#8217;t interact with any other tasks)</li>
<li>The NT Shell &#8211; which will send commands to the network queue.</li>
<li>The Network Task which will receive commands from the NT Shell task and trigger the Wireless Connection Manager to do something</li>
<li>The Wireless Connection Manager which will interact with the WiFI Radio via the Wireless Host driver.</li>
</ol>
<p><a href="https://iotexpert.com/?attachment_id=9131" rel="attachment wp-att-9131"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/05/arch-1-1024x569.png" alt="" width="1024" height="569" class="alignnone size-large wp-image-9131" srcset="https://iotexpert.com/wp-content/uploads/2020/05/arch-1-1024x569.png 1024w, https://iotexpert.com/wp-content/uploads/2020/05/arch-1-600x333.png 600w, https://iotexpert.com/wp-content/uploads/2020/05/arch-1-300x167.png 300w, https://iotexpert.com/wp-content/uploads/2020/05/arch-1-768x426.png 768w, https://iotexpert.com/wp-content/uploads/2020/05/arch-1.png 1358w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Make the Basic Project</h1>
<p>To build this project start by creating a new project.  The development board that I had plugged into my computer when I began this project is a CY8CPROTO-062-4343W so this is the one I will select.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/img_1741/" rel="attachment wp-att-9045"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-1024x768.jpg" alt="" width="1024" height="768" class="alignnone size-large wp-image-9045" srcset="https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-scaled-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-768x576.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-1536x1152.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-2048x1536.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In the new project creator pick the &#8220;CY8CPROTO-062-4343W&#8221;</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-52-43-pm/" rel="attachment wp-att-9031"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-1024x757.png" alt="" width="1024" height="757" class="alignnone size-large wp-image-9031" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-1024x757.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-600x443.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-300x222.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-768x567.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-1536x1135.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-2048x1513.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I created a FreeRTOS template project that does all of the right stuff.  I wrote an article about how to use the IoT Expert Manifestt <a href="https://iotexpert.com/2020/03/30/modustoolbox-2-0-libraries-an-example-for-emwin-super-manifests/">here</a>, and until you add the IoT Manifest to your setup you will not get the FreeRTOS Template project.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-53-09-pm/" rel="attachment wp-att-9032"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-1024x756.png" alt="" width="1024" height="756" class="alignnone size-large wp-image-9032" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-1024x756.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-600x443.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-300x222.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-768x567.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-1536x1134.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-2048x1512.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>After the new project work is done you should see</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-53-33-pm/" rel="attachment wp-att-9033"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-1024x228.png" alt="" width="1024" height="228" class="alignnone size-large wp-image-9033" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-1024x228.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-600x134.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-300x67.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-768x171.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-1536x342.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-2048x456.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Add the nt-shell, which comes from my IoT Expert library (read about how to add the IoT Expert library <a href="https://iotexpert.com/2020/03/30/modustoolbox-2-0-libraries-an-example-for-emwin-super-manifests/">here</a>).</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-57-07-pm/" rel="attachment wp-att-9034"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-1024x889.png" alt="" width="1024" height="889" class="alignnone size-large wp-image-9034" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-1024x889.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-600x521.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-300x261.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-768x667.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-1536x1334.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM.png 1976w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I have been on a kick of using Visual Studio code.  So, run &#8220;make vscode&#8221; to setup the project for Visual Studio Code.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-57-32-pm/" rel="attachment wp-att-9035"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-870x1024.png" alt="" width="870" height="1024" class="alignnone size-large wp-image-9035" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-870x1024.png 870w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-600x706.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-255x300.png 255w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-768x904.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-1305x1536.png 1305w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM.png 1704w" sizes="auto, (max-width: 870px) 100vw, 870px" /></a></p>
<p>In the finder, copy the template files from nt-shell into your project.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-23-34-pm/" rel="attachment wp-att-9027"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM.png" alt="" width="1012" height="604" class="alignnone size-full wp-image-9027" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM.png 1012w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM-600x358.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM-300x179.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM-768x458.png 768w" sizes="auto, (max-width: 1012px) 100vw, 1012px" /></a></p>
<p>You can also do it with the command line.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-58-45-pm/" rel="attachment wp-att-9036"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-1024x139.png" alt="" width="1024" height="139" class="alignnone size-large wp-image-9036" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-1024x139.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-600x81.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-300x41.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-768x104.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM.png 1168w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Edit main.c to include the configuration.</p>
<pre class="start-line:9 EnlighterJSRAW" data-enlighter-language="c"">#include "ntshell.h"
#include "psoc6_ntshell_port.h"</pre>
<p>Update the main.c to have the ntShellThread</p>
<pre class="start-line:18 EnlighterJSRAW" data-enlighter-language="c"">// Global variable with a handle to the shell
ntshell_t ntshell;

void ntShellTask()
{

  printf("Started ntshell\n");
  setvbuf(stdin, NULL, _IONBF, 0);
  ntshell_init(
               &amp;ntshell,
               ntshell_read,
               ntshell_write,
               ntshell_callback,
               (void *)&amp;ntshell);
  ntshell_set_prompt(&amp;ntshell, "AnyCloud&gt; ");
  vtsend_erase_display(&amp;ntshell.vtsend);
  ntshell_execute(&amp;ntshell);
}</pre>
<p>And start the ntshell task.</p>
<pre class="start-line:71 EnlighterJSRAW" data-enlighter-language="c"">    xTaskCreate(ntShellTask, "nt shell task", configMINIMAL_STACK_SIZE*2,0 /* args */ ,4 /* priority */, 0);</pre>
<p>When you want to add a command to the shell you need to do three things</p>
<ol>
<li>Add a function prototype for the command</li>
<li>Add the command to the command list</li>
<li>Write the function</li>
</ol>
<pre class="start-line:54 EnlighterJSRAW" data-enlighter-language="c"">static int usrcmd_help(int argc, char **argv);
static int usrcmd_info(int argc, char **argv);
static int usrcmd_clear(int argc, char **argv);
static int usrcmd_printargs(int argc, char **argv);
static const cmd_table_t cmdlist[] = {
    { "help", "This is a description text string for help command.", usrcmd_help },
    { "info", "This is a description text string for info command.", usrcmd_info },
    { "clear", "Clear the screen", usrcmd_clear },
    { "printargs","print the list of arguments", usrcmd_printargs},
};</pre>
<p>Here is an example of of the printargs command.  The shell will call your function with a ARGC=number of arguments and ARGV[] an array of the pointers to the actual arguments.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static int usrcmd_printargs(int argc, char **argv)
{
    printf("ARGC = %d\n",argc);

    for(int i =0;i&lt;argc;i++)
    {
        printf("argv[%d] = %s\n",i,argv[i]);
    }
    return 0;

}</pre>
<p>Build and test your program.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-28-29-pm/" rel="attachment wp-att-9029"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-1024x288.png" alt="" width="1024" height="288" class="alignnone size-large wp-image-9029" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-1024x288.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-600x169.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-300x84.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-768x216.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-1536x431.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM.png 1666w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Turn on the Connection Manager and Core Middleware Library</h1>
<p>Now, add the wifi-mw-core library &amp; Connection Manager using the library manager.  You can start it with &#8220;make modlibs&#8221;.  These two libraries are in the &#8220;WiFi Middleware&#8221; category.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-3-04-40-pm/" rel="attachment wp-att-9037"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-1024x787.png" alt="" width="1024" height="787" class="alignnone size-large wp-image-9037" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-1024x787.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-600x461.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-300x231.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-768x591.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-1536x1181.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-2048x1575.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Copy the FreeRTOSConfig.h from the libs/wifi-mw-core/configs directory into your project (so you can modify it)</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-13-57-pm/" rel="attachment wp-att-9026"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-1024x677.png" alt="" width="1024" height="677" class="alignnone size-large wp-image-9026" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-1024x677.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-600x396.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-300x198.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-768x507.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-1536x1015.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM.png 1562w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Update the Makefile to include the WiFi components (line 71) and the MBED TLS configuration (line 86)</p>
<pre class="start-line:70 EnlighterJSRAW" data-enlighter-language="c"">COMPONENTS=FREERTOS PSOC6HAL LWIP MBEDTLS 4343W
# Like COMPONENTS, but disable optional code that was enabled by default.
DISABLE_COMPONENTS=

# By default the build system automatically looks in the Makefile's directory
# tree for source code and builds it. The SOURCES variable can be used to
# manually add source code to the build process from a location not searched
# by default, or otherwise not found by the build system.
SOURCES=

# Like SOURCES, but for include directories. Value should be paths to
# directories (without a leading -I).
INCLUDES=

# Add additional defines to the build process (without a leading -D).
DEFINES=MBEDTLS_USER_CONFIG_FILE='"configs/mbedtls_user_config.h"' CYBSP_WIFI_CAPABLE</pre>
<h1>Create networkTask.h/.c &amp; Start the Task in main.c</h1>
<p>Now let&#8217;s create the networkTask.  This task will control all of the networking functions in the system.  The first file, networkTask.h, is the public interface.  It declares a Queue where you can push messages (line 5) an enumeration of the messages (lines 7-14), a definition of the message data (lines 17-22) and finally the network task declaration (line 24).</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">#pragma once
#include "FreeRTOS.h"
#include "queue.h"

extern QueueHandle_t networkQueue;

typedef enum {
    net_scan,
    net_connect,
    net_disconnect,
    net_printip,
    net_printmac,

} networkCmd_t;


typedef struct {
    networkCmd_t cmd;
    uint32_t val0;
    uint32_t val1;

} networkQueueMsg_t;

void networkTask(void *arg);</pre>
<p>Ill go ahead and modify main.c to start the yet to be written network task.  You need to include the header file for the task and define a handle for the task.</p>
<pre class="start-line:11 EnlighterJSRAW" data-enlighter-language="c"">#include "networkTask.h"

TaskHandle_t networkTaskHandle;</pre>
<p>Finally in main function, start the task.</p>
<pre class="start-line:60 EnlighterJSRAW" data-enlighter-language="c"">    xTaskCreate(networkTask, "networkTask", configMINIMAL_STACK_SIZE*8,0 /* args */ ,4/* priority */, &amp;networkTaskHandle);</pre>
<p>Create the file networkTask.c.  Make a bunch of includes.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include "FreeRTOS.h"
#include "task.h"
#include "cy_wcm.h"
#include "cy_wcm_error.h"
#include "whd_types.h"
#include "queue.h"
#include "semphr.h"
#include "networkTask.h"</pre>
<p>Now let&#8217;s define the actual task function.  This function will</p>
<ol>
<li>Call the wcm_init function to make a WiFi Station (lines 201-203)</li>
<li>Tell the task that you would like to be called back when things happen (line 205)</li>
<li>Initialize the Queue to receive command messages from other tasks.</li>
<li>Make an infinite loop to receive the commands and process the messages.  Notice that I dont do anything with the message for now.  Ill add the code later.</li>
</ol>
<pre class="start-line:190 EnlighterJSRAW" data-enlighter-language="c"">// The networkTask will:
// - startup the wireless connection manager
// - sit waiting on the rtos queue... getting messages from other tasks
// - and do ( net_scan, net_connect, net_disconnect, net_printip, net_printmac,)

void networkTask(void *arg)
{
	cy_rslt_t result;
	cy_wcm_config_t config;
	cy_wcm_scan_filter_t scanFilter;

	memset(&amp;config, 0, sizeof(cy_wcm_config_t));
    config.interface = CY_WCM_INTERFACE_TYPE_STA;
	cy_wcm_init	(&amp;config);

	cy_wcm_register_event_callback(	wcmCallback	);

	networkQueue = xQueueCreate( 5, sizeof(networkQueueMsg_t));

	while(1)
	{
		networkQueueMsg_t msg;

		xQueueReceive(networkQueue,(void *)&amp;msg,portMAX_DELAY);  // Wait for commands from other tasks

		switch(msg.cmd)
		{
			case net_scan: // 0=stop scan !0=start scan
			break;

			case net_connect:
			break;

			case net_disconnect:
			break;

			case net_printip:
			break;

			case net_printmac:
			break;
		}
	}

}</pre>
<h1>Create Utilities for Printing out the IP and MAC Address</h1>
<p>It the network task I want to be able to print out IP address (both IPV4 and IPV6).  I also want to be able to print out 6-byte MAC address.  In the Cypress drivers, an IP address is a structure that holds either a IPV4 or and IPV6 address.  It then contains the 4 or 6 bytes of the address.  Here is the type definition.</p>
<pre class="start-line:387 EnlighterJSRAW" data-enlighter-language="c"">/**
 * IP Address Structure
 */
typedef struct
{
    cy_wcm_ip_version_t version;  /**&lt; IP version */
    union
    {
        uint32_t v4;     /**&lt; IPv4 address bytes */
        uint32_t v6[4];  /**&lt; IPv6 address bytes */
    } ip;                /**&lt; IP address bytes */
} cy_wcm_ip_address_t;</pre>
<p>The IP v ersion is just an enumeration.</p>
<pre class="start-line:164 EnlighterJSRAW" data-enlighter-language="c"">/**
 * IP Version
 */
typedef enum
{
    CY_WCM_IP_VER_V4 = 4,      /**&lt; Denotes IPv4 version */
    CY_WCM_IP_VER_V6 = 6       /**&lt; Denotes IPv6 version */
} cy_wcm_ip_version_t;</pre>
<p>To print an address, figure out which version you are working on.  Then dump the raw bytes.  Notice in the IPV4 case it is encoded into a uint32_t as 4 continuous bytes.</p>
<pre class="start-line:18 EnlighterJSRAW" data-enlighter-language="c"">void printIp(cy_wcm_ip_address_t *ipad)
{
	if(ip_addr.version == CY_WCM_IP_VER_V4)
	{
		printf("%d.%d.%d.%d",(int)ipad-&gt;ip.v4&gt;&gt;0&amp;0xFF,(int)ipad-&gt;ip.v4&gt;&gt;8&amp;0xFF,(int)ipad-&gt;ip.v4&gt;&gt;16&amp;0xFF,(int)ipad-&gt;ip.v4&gt;&gt;24&amp;0xFF);
	}
	else if (ip_addr.version == CY_WCM_IP_VER_V6)
	{
		for(int i=0;i&lt;4;i++)
		{
			printf("%0X:",(unsigned int)ip_addr.ip.v6[i]);
		}
	}
	else
	{
		printf("IP ERROR %d",ipad-&gt;version);
	}			
}</pre>
<p>A MAC address is just an array of uint8_t of length CY_WCM_MAC_ADDR_LEN  (which we pound defined to 6)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef uint8_t cy_wcm_mac_t[CY_WCM_MAC_ADDR_LEN];                   /**&lt; Unique 6-byte MAC address */</pre>
<p>So, the print is just a loop. (probably should have done something slightly better so I dont end up with the trailing : &#8211; oh well)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">void printMac(cy_wcm_mac_t mac)
{
	for(int i=0;i&lt;CY_WCM_MAC_ADDR_LEN;i++)
	{
		uint8_t val = mac[i];
		printf("%02X:",val);
	}
}</pre>
<h1>Add the Scan Command</h1>
<p>For the scan I want to print out the:</p>
<ol>
<li>SSID</li>
<li>RSSI (in dBM)</li>
<li>Channel</li>
<li>Band</li>
<li>Speed</li>
<li>Type of Ap</li>
<li>Country Code</li>
<li>MAC address of the Access Point (AKA BSSID)</li>
<li>Type of Security</li>
</ol>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-1-04-36-pm/" rel="attachment wp-att-9021"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1024x623.png" alt="" width="1024" height="623" class="alignnone size-large wp-image-9021" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1024x623.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-600x365.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-300x182.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-768x467.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1536x934.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM.png 1950w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In order to have the WCM run a scan you need to call the function cy_wcm_start_scan.  What this will do is tell the 4343W to scan all the channels on the 2.4GHZ band and listen for access point beacons.  This function has three arguments</p>
<ol>
<li>A function pointer to call back when you find an AP</li>
<li>A user settable data pointer</li>
<li>A filter (which can limit to an SSID, BSSID or RSSI)</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">cy_rslt_t cy_wcm_start_scan(cy_wcm_scan_result_callback_t callback, void *user_data, cy_wcm_scan_filter_t *scan_filter)</pre>
<p>Here is my version of the scanCallback which I put in the networkTask.c file.</p>
<pre class="start-line:60 EnlighterJSRAW" data-enlighter-language="c"">// This function is called back when the user asks for an overall scan.
// It just prints out the information about the networks that it hears about
void scanCallback( cy_wcm_scan_result_t *result_ptr, void *user_data, cy_wcm_scan_status_t status )</pre>
<p>The result_ptr is a pointer to a structure that contains the data for the found access point.</p>
<pre class="start-line:460 EnlighterJSRAW" data-enlighter-language="c" ">/**
 * Structure for storing scan results
 */
typedef struct
{
    cy_wcm_ssid_t                SSID;             /**&lt; Service Set Identification (i.e. Name of Access Point)                    */
    cy_wcm_mac_t                 BSSID;            /**&lt; Basic Service Set Identification (i.e. MAC address of Access Point)       */
    int16_t                      signal_strength;  /**&lt; Receive Signal Strength Indication in dBm. &lt;-90=Very poor, &gt;-30=Excellent */
    uint32_t                     max_data_rate;    /**&lt; Maximum data rate in kilobits/s                                           */
    cy_wcm_bss_type_t            bss_type;         /**&lt; Network type                                                              */
    cy_wcm_security_t            security;         /**&lt; Security type                                                             */
    uint8_t                      channel;          /**&lt; Radio channel that the AP beacon was received on                          */
    cy_wcm_wifi_band_t           band;             /**&lt; Radio band                                                                */
    uint8_t                      ccode[2];         /**&lt; Two letter ISO country code from AP                                       */
    uint8_t                      flags;            /**&lt; flags                                                                     */
    uint8_t                      *ie_ptr;          /**&lt; Pointer to received Beacon/Probe Response IE(Information Element)         */
    uint32_t                     ie_len;           /**&lt; Length of IE(Information Element)                                         */
} cy_wcm_scan_result_t;
</pre>
<p>The other parameter to the callback is the status.  The status will either be CY_WCM_SCAN_COMPLETE or CY_WCM_SCAN_INCOMPLETE.  The first thing that to do is see if this callback is the one that tells me that the scan is complete, if so I just return (and don&#8217;t print anything)</p>
<pre class="start-line:67 EnlighterJSRAW" data-enlighter-language="c"">	if(status == CY_WCM_SCAN_COMPLETE)
		return;</pre>
<p>Then I print out the raw SSID, Signal Strength and Channel.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">	printf("%32s\t%d\t%d\t",result_ptr-&gt;SSID,result_ptr-&gt;signal_strength,result_ptr-&gt;channel);</pre>
<p>Next I figure out what channel we are talking about.  The 4343W is single band 2.4GHZ, however, other Cypress chips have dual band.</p>
<pre class="start-line:68 EnlighterJSRAW" data-enlighter-language="c"">	switch(result_ptr-&gt;band)
	{
		case CY_WCM_WIFI_BAND_ANY:
			printf("ANY");
		break;
		case CY_WCM_WIFI_BAND_5GHZ:
			printf("5.0 GHZ");
		break;
		case CY_WCM_WIFI_BAND_2_4GHZ:
			printf("2.4 GHZ");
		break;
	}</pre>
<p>Then I printout the maximum data rate, which is 0 for all of my test cases.  I have no idea why.</p>
<pre class="start-line:82 EnlighterJSRAW" data-enlighter-language="c"">	printf("%d",(int)result_ptr-&gt;max_data_rate);</pre>
<p>Then I printout what type of AP we are talking about.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">	switch(result_ptr-&gt;bss_type)
	{
		case CY_WCM_BSS_TYPE_INFRASTRUCTURE:
			printf("INFR");
		break; 	
		case CY_WCM_BSS_TYPE_ADHOC: 
			printf("ADHOC");
		break;	
		case CY_WCM__BSS_TYPE_ANY: 	
			printf("ANY");
		break;
		case CY_WCM_BSS_TYPE_MESH:
			printf("MESG");
		break;
		case CY_WCM_BSS_TYPE_UNKNOWN: 
			printf("UNKWN");
		break;
	}</pre>
<p>Then the country code.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">	printf("%c%c",result_ptr-&gt;ccode[0],result_ptr-&gt;ccode[1]);
</pre>
<p>Then the Basic Service Set ID of the AP, which is also known as the MAC address of the AP.</p>
<pre class="start-line:105 EnlighterJSRAW" data-enlighter-language="c"">	printMac(result_ptr-&gt;BSSID);</pre>
<p>Then the security type.</p>
<pre class="start-line:108 EnlighterJSRAW" data-enlighter-language="c"">	switch(result_ptr-&gt;security)
	{
		case CY_WCM_SECURITY_OPEN:
			printf("OPEN");
		break;
    	case CY_WCM_SECURITY_WEP_PSK:
			printf("WEP_PSK");
		break;
		case CY_WCM_SECURITY_WEP_SHARED:
			printf("WEP_SHARED");
		break;
    	case CY_WCM_SECURITY_WPA_TKIP_PSK:
			printf("WPA_TKIP_PSK");
		break;
		case CY_WCM_SECURITY_WPA_AES_PSK:
			printf("WPA_AES_PSK");
		break;
		case CY_WCM_SECURITY_WPA_MIXED_PSK:
			printf("WPA_MIXED_PSK");
		break;
		case CY_WCM_SECURITY_WPA2_AES_PSK:
			printf("WPA2_AES_PSK");
		break;
		case CY_WCM_SECURITY_WPA2_TKIP_PSK:
			printf("WPA2_TKIP_PSK");
		break;
		case CY_WCM_SECURITY_WPA2_MIXED_PSK:
			printf("WPA2_MIXED_PSK");
		break;
		case CY_WCM_SECURITY_WPA2_FBT_PSK:
			printf("WPA2_FBT_PSK");
		break;
		case CY_WCM_SECURITY_WPA3_SAE:
			printf("WPA3_SAE");
		break;
		case CY_WCM_SECURITY_WPA3_WPA2_PSK:
			printf("WPA3_WPA2_PSK");
		break;
		case CY_WCM_SECURITY_IBSS_OPEN:
			printf("IBSS_OPEN");
		break;
		case CY_WCM_SECURITY_WPS_SECURE:
			printf("WPS_SECURE");
		break;
		case CY_WCM_SECURITY_UNKNOWN:
			printf("UNKNOWN");
		break;
		case CY_WCM_SECURITY_FORCE_32_BIT:
			printf("FORCE_32_BIT");
		break;
	}</pre>
<p>With a complete scanCallback function I can now update the networkTask to deal with the queued commands of net_scan type.  This simply either stops or starts the scan based on the message parameter.</p>
<pre class="start-line:212 EnlighterJSRAW" data-enlighter-language="c"">			case net_scan: // 0=stop scan !0=start scan
				if(msg.val0 == 0)
					cy_wcm_stop_scan();
				else
				{
					printf("\n");
					result = cy_wcm_start_scan(scanCallback,0,0);
					if(result != CY_RSLT_SUCCESS)
						printf("Scan error\n");
				}
			break;</pre>
<p>The last things to do is to add the scan command to the usrcmd.c</p>
<pre class="start-line:149 EnlighterJSRAW" data-enlighter-language="c"">static int usrcmd_scan(int argc, char **argv)
{

    static int state=0;

    if(argc==1)
    {
        state = (state ==0)?1:0;
    }
    else if(argc == 2)
    {
        if(strcmp(argv[1],"on") == 0)
        {
            state=1;
        } 
        else if(strcmp(argv[1],"off") == 0)
        {
            state = 0;
        }
        else
        {
            printf("usage: scan [on|off]\n");
            return 0;
        }
        
    }
    else
    {
        printf("usage scan: [on|off]\n");
        return 0;
    }
    
    networkQueueMsg_t msg;
    msg.cmd = net_scan;
    msg.val0 = state;
    xQueueSend(networkQueue,(const void *)&amp;msg,portMAX_DELAY);
    return 0;
}</pre>
<p>OK.  Let it rip.  You should be able to run network scans.  In the next Article I will add a connect and disconnect commands.</p>
<p>You can find all of this example code at https://github.com/iotexpert/wcm_example</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-wireless-connection-manager-part-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MBED OS &#038; PSoC 6 &#038; SSD1306</title>
		<link>https://iotexpert.com/mbed-os-psoc-6-ssd1306/</link>
					<comments>https://iotexpert.com/mbed-os-psoc-6-ssd1306/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Sun, 17 Feb 2019 16:29:44 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[Embedded World 2019]]></category>
		<category><![CDATA[MBED OS]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6600</guid>

					<description><![CDATA[Summary As I wrote about in the last article I have been working to get ready for Embedded World 2019 in a week and a bit.  For my demo, I will be handing out remote controls that have a 128&#215;64 monochrome OLED display that is driven by an I2C SSD1306.  This whole board is controlled [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>As I wrote about in the <a href="https://iotexpert.com/2019/02/11/mbedos-ble/" target="_blank" rel="noopener">last article</a> I have been working to get ready for Embedded World 2019 in a week and a bit.  For my demo, I will be handing out remote controls that have a 128&#215;64 monochrome OLED display that is driven by an I2C SSD1306.  This whole board is controlled by a PSoC 6 &amp; a 4343W WiFi / Bluetooth Combo.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/img_0227/" rel="attachment wp-att-6602"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-493x1024.jpg" alt="" width="493" height="1024" class="alignnone size-large wp-image-6602" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-493x1024.jpg 493w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-600x1246.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-144x300.jpg 144w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-768x1595.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-scaled.jpg 1233w" sizes="auto, (max-width: 493px) 100vw, 493px" /></a></p>
<p>This morning I started to port the <a href="https://iotexpert.com/?s=u8g2" target="_blank" rel="noopener">U8G2</a> library to MBEDOS&#8230; but ran into some problems, so I i decided to see what ports were already out there.  I immediately found a port of the <a href="https://os.mbed.com/users/nkhorman/code/Adafruit_GFX/" target="_blank" rel="noopener">Adafruit_GFX library</a>.  This article talks about using it on my CY8CPROTO_062_4343W board.  As part of this journey I also wanted to be able to draw the Cypress logo on the screen&#8230; so I had to figure out how to create a logo in a format that could be drawn on the screen.</p>
<p>I will follow these steps:</p>
<ol>
<li>Create a new project &amp; add the Adafruit_GFX_library</li>
<li>Create a main.cpp, configure the library and test</li>
<li>Make a Cypress logo using GIMP</li>
<li>Create a function to draw X11 bitmaps &amp; test</li>
</ol>
<h1>Create a new project &amp; add the Adafruit_GFX_library</h1>
<p>The first step to get everything going by running</p>
<ol>
<li>mbed new .</li>
<li>mbed add http://os.mbed.com/users/nkhorman/code/Adafruit_GFX/</li>
</ol>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-9-41-48-am/" rel="attachment wp-att-6603"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM.png" alt="" width="797" height="465" class="alignnone size-full wp-image-6603" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM.png 797w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM-600x350.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM-300x175.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM-768x448.png 768w" sizes="auto, (max-width: 797px) 100vw, 797px" /></a></p>
<p>The way to figure out how to add the library is by going to the library webpage on the mbedos website.  Then clicking the arrow on &#8220;Import into Compiler&#8221; where you will see two options, &#8220;Import into Compiler&#8221; and &#8220;Import with mbed CLI&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-9-41-03-am/" rel="attachment wp-att-6606"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-1024x278.png" alt="" width="1024" height="278" class="alignnone size-large wp-image-6606" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-1024x278.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-600x163.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-300x81.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-768x209.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM.png 1182w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>When you select that option you will get a window that tells you the exact command to run.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-9-41-15-am/" rel="attachment wp-att-6605"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.15-AM.png" alt="" width="402" height="161" class="alignnone size-large wp-image-6605" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.15-AM.png 402w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.15-AM-300x120.png 300w" sizes="auto, (max-width: 402px) 100vw, 402px" /></a></p>
<p>I have been using <a href="https://atom.io" target="_blank" rel="noopener">Atom</a> as an editor (and sort of IDE).  When you open the lcd-example directory using Atom you will see your project including</p>
<ol>
<li>The mbed-os directory with all of the mbed stuff in it.</li>
<li>The Adafruit_GFX library</li>
</ol>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-9-46-14-am/" rel="attachment wp-att-6609"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM.png" alt="" width="815" height="662" class="alignnone size-full wp-image-6609" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM.png 815w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM-600x487.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM-300x244.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM-768x624.png 768w" sizes="auto, (max-width: 815px) 100vw, 815px" /></a></p>
<h1>Create a main.cpp, configure the library and test</h1>
<p>The next step is to create a main.cpp.</p>
<ol>
<li>Setup the I2C.  In order to use the graphics library you need to setup a communication vehicle.  In my case that is an I2C bus that is connected to P6[0] and P6[1] on my development board.  Lines 6-15 create the communication class of I2CPreInit, configure it to 400kbs and connect the I2C master to P6[0]/P6[1]</li>
<li>Line 16 actually setups up the graphics library and get it going.</li>
<li>The main simply prints out some information about the display on lines 22-23</li>
<li>Line 24 causes the current frame buffer to be displayed (more on this in a second)</li>
<li>The main loop blinks the LED and prints a counter on the top of the screen.</li>
</ol>
<pre class="lang:c++ decode:true">#include "mbed.h"
#include "Adafruit_SSD1306.h"

DigitalOut myled(LED1);

class I2CPreInit : public I2C
{
public:
    I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
    {
        frequency(400000);
        start();
    };
};
I2CPreInit gI2C(P6_1,P6_0);
Adafruit_SSD1306_I2c gOled2(gI2C,P0_2,0x78,64,128);

int main()
{   uint16_t x=0;

    printf("Started\n");
    printf("%ux%u OLED Display\r\n", gOled2.width(), gOled2.height());
    printf("Rotation = %u\n",gOled2.getRotation());
    gOled2.display();
    while(1)
    {
        x += 1;
        myled = !myled;
        gOled2.printf("%u\r",x);
        gOled2.display();
        wait(1.0);
    }
}
</pre>
<p>In order to build this thing I run &#8220;mbed compile -t GCC_ARM -m CY8CPROTO_062_4343w&#8221;.  When I run the project it looks like this:</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/img_0228/" rel="attachment wp-att-6612"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-1024x768.jpg" alt="" width="1024" height="768" class="alignnone wp-image-6612 size-large" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>There are several things to notice about this picture.  First, there is an Adafruit logo on the screen.  Where did this come from?  Simple on line 152 of Adafruit_ssd1306.cpp there is a function called &#8220;splash&#8221; which is called by the constructor.  The spash function just copies a bitmap into the frame buffer of the Adafruit_SSD1306 object.</p>
<pre class="start-line:152 EnlighterJSRAW" data-enlighter-language="c" ">void Adafruit_SSD1306::splash(void)
{
#ifndef NO_SPLASH_ADAFRUIT
	uint8_t adaFruitLogo[64 * 128 / 8] =
	{ 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
</pre>
<p>The constructor is in Adafruit_ssd1306.h on line 152</p>
<pre class="start-line:173 lang:c++ decode:true ">	Adafruit_SSD1306_I2c(I2C &amp;i2c, PinName RST, uint8_t i2cAddress = SSD_I2C_ADDRESS, uint8_t rawHeight = 32, uint8_t rawWidth = 128)
	    : Adafruit_SSD1306(RST, rawHeight, rawWidth)
	    , mi2c(i2c)
	    , mi2cAddress(i2cAddress)
	    {
		    begin();
		    splash();
		    display();
	    };</pre>
<p>And if you don&#8217;t want to have this splash screen you can uncomment the #define NO_SPLASH_ADAFRUIT in the file &#8220;Adafruit_GFC_Config.h&#8221;</p>
<pre class="lang:c++ decode:true ">#ifndef _ADAFRUIT_GFX_CONFIG_H_
#define _ADAFRUIT_GFX_CONFIG_H_

// Uncomment this to turn off the builtin splash
#define NO_SPLASH_ADAFRUIT

// Uncomment this to enable all functionality
//#define GFX_WANT_ABSTRACTS

// Uncomment this to enable only runtime font scaling, without all the rest of the Abstracts
//#define GFX_SIZEABLE_TEXT


#endif</pre>
<p>The next thing to notice in the picture is that I have lead wires attached to the LCD pins&#8230; and those wires are attached to a logic analyzer because I typed the I2C incorrectly and I couldn&#8217;t figure out why they didn&#8217;t talk.  And finally notice my grandfathers magnifying glass which I use every day.</p>
<h1>Make a Cypress logo using GIMP</h1>
<p>For my project I am less interested in displaying Adafruits Logo and more interested in displaying Cypress&#8217;.  To do this I loaded up the Cypress logo in <a href="https://www.gimp.org" target="_blank" rel="noopener">Gimp</a>.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-22-23-am/" rel="attachment wp-att-6614"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-1024x658.png" alt="" width="1024" height="658" class="alignnone size-large wp-image-6614" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-1024x658.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-600x385.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-300x193.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-768x493.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM.png 1194w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I then converted it to pure black and white using the &#8220;Image-&gt;Mode-&gt;Indexed&#8230;&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-23-11-am/" rel="attachment wp-att-6616"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.11-AM.png" alt="" width="438" height="156" class="alignnone size-large wp-image-6616" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.11-AM.png 438w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.11-AM-300x107.png 300w" sizes="auto, (max-width: 438px) 100vw, 438px" /></a></p>
<p>Then selected &#8220;black and white palette&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-23-23-am/" rel="attachment wp-att-6615"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.23-AM.png" alt="" width="367" height="395" class="alignnone size-full wp-image-6615" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.23-AM.png 367w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.23-AM-279x300.png 279w" sizes="auto, (max-width: 367px) 100vw, 367px" /></a></p>
<p>Then I scaled the image to 128&#215;40 using the &#8220;Image-&gt;Scale Image&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-25-10-am/" rel="attachment wp-att-6619"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.10-AM.png" alt="" width="226" height="194" class="alignnone size-large wp-image-6619" /></a></p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-25-22-am/" rel="attachment wp-att-6618"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.22-AM.png" alt="" width="380" height="385" class="alignnone size-large wp-image-6618" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.22-AM.png 380w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.22-AM-100x100.png 100w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.22-AM-296x300.png 296w" sizes="auto, (max-width: 380px) 100vw, 380px" /></a></p>
<p>Unfortunately it made a bit of a mess of the logo during the scaling process&#8230; so I put my son to editing it.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-25-52-am/" rel="attachment wp-att-6617"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.52-AM.png" alt="" width="654" height="390" class="alignnone size-full wp-image-6617" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.52-AM.png 654w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.52-AM-600x358.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.52-AM-300x179.png 300w" sizes="auto, (max-width: 654px) 100vw, 654px" /></a></p>
<p>Which looks like this after he was done.  Pretty good eh?</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-28-26-am/" rel="attachment wp-att-6620"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.28.26-AM.png" alt="" width="542" height="317" class="alignnone size-full wp-image-6620" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.28.26-AM.png 542w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.28.26-AM-300x175.png 300w" sizes="auto, (max-width: 542px) 100vw, 542px" /></a></p>
<p>In order to use the image you need a &#8220;C program&#8221; version of it.  It turns out that there is a format called &#8220;X11&#8221; or &#8220;xbm&#8221; which is exactly that (a c-file).  You can read about the format on <a href="http://www.fileformat.info/format/xbm/egff.htm" target="_blank" rel="noopener">this website</a>.  To get one of these files, just run &#8220;File-&gt;Export As&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-29-14-am/" rel="attachment wp-att-6623"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.14-AM.png" alt="" width="204" height="281" class="alignnone size-full wp-image-6623" /></a></p>
<p>Then give it a name with a &#8220;.xbm&#8221; on the end</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-29-45-am/" rel="attachment wp-att-6622"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.45-AM.png" alt="" width="617" height="117" class="alignnone size-large wp-image-6622" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.45-AM.png 617w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.45-AM-600x114.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.45-AM-300x57.png 300w" sizes="auto, (max-width: 617px) 100vw, 617px" /></a></p>
<p>Make sure and &#8220;de-select the X10 format bitmap&#8221; (and older version of the xbm format)</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-29-56-am/" rel="attachment wp-att-6621"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.56-AM.png" alt="" width="321" height="351" class="alignnone size-full wp-image-6621" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.56-AM.png 321w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.56-AM-274x300.png 274w" sizes="auto, (max-width: 321px) 100vw, 321px" /></a></p>
<p>When all that is said and done you will find the xbm file with goodness in it.  Here is the top of it.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define cylogo_width 128
#define cylogo_height 40
static unsigned char cylogo_bits[] = {
   0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x3f,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
</pre>
<p>The format of this file is unsigned 8-bit integers&#8230; each bit represents the bit of one pixel&#8230; in BIG ENDIAN!!!! format.  In other words this table will be 128&#215;40/8 bytes long.</p>
<h1>Create a function to draw X11 bitmaps &amp; test</h1>
<p>But how do we use this format?  Well, write a new function in the Adafruit library to draw X11 bitmaps.</p>
<p>First add the new function name to the class on line 168 of &#8220;Adafruit_GFX.h&#8221;</p>
<pre class="start-line:72 EnlighterJSRAW" data-enlighter-language="c"">    virtual void drawX11BitMap(const uint8_t bitmap[],uint16_t bitMapWidth,uint16_t bitMapSize,uint16_t posX,uint16_t posY);
</pre>
<p>Then add the code.</p>
<pre class="start-line:152 EnlighterJSRAW" data-enlighter-language="c"">// Write an X11 formatted bitmap to the screen at posX, posY
void Adafruit_GFX::drawX11BitMap(const uint8_t bitmap[],uint16_t bitMapWidth,uint16_t bitMapSize,uint16_t posX,uint16_t posY)
{
  int16_t x1 = posX;
  int16_t y1 = posY;

  for(unsigned int i=0;i&lt;bitMapSize;i++)
  {
    uint8_t val = bitmap[i];

    for(int j=0;j&lt;8;j++)
    {
        uint16_t pixColor;
        if(val&gt;&gt;j &amp; 0x01)
          pixColor = 1;
        else
          pixColor = 0;

        drawPixel(x1,y1, pixColor);
        x1 = x1 + 1;
        if(x1 == posX + bitMapWidth)
        {
          x1 = posX;
          y1 = y1 + 1;
        }
    }
  }</pre>
<p>This may not be the most beautiful code in the world&#8230; which I suppose makes it fit right in with some of the other stuff in this driver.  Oh well it works.</p>
<p>Once you have added the function to the library, lets test it to see if it can draw the logo.  First, copy the &#8220;cylogo.xbm&#8221; into the project and call it &#8220;cylogo.h&#8221;.  Then modify the &#8220;main.cpp&#8221; to use it.  Add an include of the &#8220;cylogo.h&#8221;.  Then on line 26, call the function to draw it at 0,(half way down the screen)</p>
<pre class="lang:c++ decode:true ">#include "mbed.h"
#include "Adafruit_SSD1306.h"
#include "cylogo.h"
DigitalOut myled(LED1);

class I2CPreInit : public I2C
{
public:
    I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
    {
        frequency(400000);
        start();
    };
};
I2CPreInit gI2C(P6_1,P6_0);
Adafruit_SSD1306_I2c gOled2(gI2C,P0_2,0x78,64,128);

int main()
{   uint16_t x=0;

    printf("Started\n");
    printf("%ux%u OLED Display\r\n", gOled2.width(), gOled2.height());
    printf("Rotation = %u\n",gOled2.getRotation());


    gOled2.drawX11BitMap(cylogo_bits,cylogo_width,sizeof(cylogo_bits),0,(64-cylogo_height)/2);

    gOled2.display();
</pre>
<p>When you program this&#8230; everything seems to be good.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/img_0229/" rel="attachment wp-att-6625"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-1024x768.jpg" alt="" width="1024" height="768" class="alignnone size-large wp-image-6625" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>By the way if it isn&#8217;t clear by now, I did a solder in a male header onto the board so that I could attach the I2C wires for the display.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/img_0230/" rel="attachment wp-att-6626"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-1024x768.jpg" alt="" width="1024" height="768" class="alignnone size-large wp-image-6626" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mbed-os-psoc-6-ssd1306/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cypress &#038; MBED OS</title>
		<link>https://iotexpert.com/cypress-mbed-os/</link>
					<comments>https://iotexpert.com/cypress-mbed-os/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Sat, 09 Feb 2019 13:00:20 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[MBED OS]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6550</guid>

					<description><![CDATA[Summary This morning I saw something exciting.  When I went to the ARM mbed-os GitHub site I saw the latest accepted merge commit was from vmedcy and it says something interesting.  &#8220;Add Cypress PSoC 6 Targets&#8221;.  I cannot even begin to describe how gratifying it is to see this commit. But what does it mean? [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This morning I saw something exciting.  When I went to the<a href="https://github.com/ARMmbed/mbed-os" target="_blank" rel="noopener"> ARM mbed-os GitHub</a> site I saw the latest accepted merge commit was from vmedcy and it says something interesting.  &#8220;Add Cypress PSoC 6 Targets&#8221;.  I cannot even begin to describe how gratifying it is to see this commit.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-5-53-34-am/" rel="attachment wp-att-6551"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-1024x338.png" alt="" width="1024" height="338" class="alignnone size-large wp-image-6551" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-1024x338.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-600x198.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-300x99.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-768x253.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM.png 1978w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>But what does it mean?  Lets look.  I am using a Mac, so I simply install the MBED-CLI using the instructions found on the <a href="https://os.mbed.com/docs/mbed-os/v5.11/tools/installation-and-setup.html" target="_blank" rel="noopener">MBED CLI webpage</a>.</p>
<p>Like all good embedded people, the first thing to do is make sure that the toolchain and everything else works using a simple blinking LED project.  And, the easiest way to do this is to import the ARM example using: &#8220;<span>mbed import mbed-os-example-blinky&#8221;.</span></p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-6-07-26-am/" rel="attachment wp-att-6552"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-1024x535.png" alt="" width="1024" height="535" class="alignnone size-large wp-image-6552" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-1024x535.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-600x314.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-300x157.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-768x401.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM.png 1186w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The current release of mbed-os is 5.11.3 which you can see on the Tags page of the <a href="https://github.com/ARMmbed/mbed-os/tags" target="_blank" rel="noopener">mbed-os</a> GitHub site.  Notice in the screenshot above that the commit number for mbed-os is &#8220;a8d1d2&#8230;&#8221;  which means that by default, when you import a project it gives you the &#8220;latest&#8221; version of mbed-os, which really means the latest official release.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-6-11-14-am/" rel="attachment wp-att-6554"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-1024x919.png" alt="" width="1024" height="919" class="alignnone size-large wp-image-6554" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-1024x919.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-600x539.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-300x269.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-768x690.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM.png 1058w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>But, I want to use the version that was accepted with the new Cypress stuff (which will become part of the official release starting with mbed-os-5.11.4).  I can do this by running &#8220;cd mbed-os&#8221; and &#8220;mbed update master&#8221;.  This will move the git repository to point at the head of the master branch, AKA the latest and greatest.  When I do that I get a version that looks like &#8220;32525&#8230;&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-18-30-am/" rel="attachment wp-att-6556"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM.png" alt="" width="853" height="219" class="alignnone size-full wp-image-6556" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM.png 853w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM-600x154.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM-300x77.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM-768x197.png 768w" sizes="auto, (max-width: 853px) 100vw, 853px" /></a></p>
<p>And when I look at the commit history in GitHub I can see the interesting commit has the same number.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-19-45-am/" rel="attachment wp-att-6557"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-1024x310.png" alt="" width="1024" height="310" class="alignnone size-large wp-image-6557" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-1024x310.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-600x182.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-300x91.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-768x233.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM.png 1148w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now to the good stuff.  When I look in the targets directory I see that there is a TARGET_CYPRESS.  Where is see two targets:</p>
<ul>
<li>TARGET_PSOC &#8211; the stuff that Cypress created</li>
<li>TARGET_PSOC6_FUTURE &#8211; a really cool target that Future Electronics created.</li>
</ul>
<p>When when I look in the Cypress directory I see a bunch of my favorite Cypress PSoC 6 and WICED wireless development Kits.</p>
<ul>
<li>TARGET_CY8CKIT_062_BLE</li>
<li>TARGET_CY8CKIT_062_4343W</li>
<li>TARGET_CY8CKIT_062_WIFI_BT</li>
<li>TARGET_CYW943012P6EVB_01</li>
<li>TARGET_CY8CMOD_062_4343W</li>
<li>TARGET_CY8CPROTO_062_4343W</li>
</ul>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-25-52-am/" rel="attachment wp-att-6559"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM.png" alt="" width="851" height="468" class="alignnone size-full wp-image-6559" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM.png 851w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM-600x330.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM-300x165.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM-768x422.png 768w" sizes="auto, (max-width: 851px) 100vw, 851px" /></a></p>
<p>I happen to have a <a href="https://www.cypress.com/documentation/development-kitsboards/psoc-6-wi-fi-bt-prototyping-kit" target="_blank" rel="noopener">CY8CPROTO_062_4343W</a> on my desk at home.  This kit has a bunch of cool stuff on it, but most importantly it a 4343W WiFi Bluetooth Combo chip and a PSoC 6 together.  Finally, A PSoC 6 2M (which is really called CY8C624ABZI-D44) and a WICED 4343W &#8211; a Dual Band 802.11n and Bluetooth 5.0 Combo.  Here is a picture from the development <a href="https://www.cypress.com/file/457891/download" target="_blank" rel="noopener">kit guide</a>.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-43-09-am/" rel="attachment wp-att-6564"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-967x1024.png" alt="" width="967" height="1024" class="alignnone size-large wp-image-6564" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-967x1024.png 967w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-600x635.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-283x300.png 283w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-768x813.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM.png 1039w" sizes="auto, (max-width: 967px) 100vw, 967px" /></a></p>
<p>Now we have something to program.  Let&#8217;s look at the blinking LED example program.  It resides in the file &#8220;main.cpp&#8221; which is in the root directory of the &#8220;mbed-os-example-blinky&#8221;</p>
<pre class="lang:c++ decode:true ">/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"
#include "stats_report.h"

DigitalOut led1(LED1);

#define SLEEP_TIME                  500 // (msec)
#define PRINT_AFTER_N_LOOPS         20

// main() runs in its own thread in the OS
int main()
{
    SystemReport sys_state( SLEEP_TIME * PRINT_AFTER_N_LOOPS /* Loop delay time in ms */);

    int count = 0;
    while (true) {
        // Blink LED and wait 0.5 seconds
        led1 = !led1;
        wait_ms(SLEEP_TIME);

        if ((0 == count) || (PRINT_AFTER_N_LOOPS == count)) {
            // Following the main thread wait, report on the current system status
            sys_state.report_state();
            count = 0;
        }
        ++count;
    }
}
</pre>
<p>This looks simple enough, but I am never a fan of &#8220;other&#8221; stuff in the blinking LED example.  So Ill trim it down to the most basic.</p>
<pre class="lang:c++ decode:true ">/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"

DigitalOut led1(LED1);

#define SLEEP_TIME                  500 // (msec)

// main() runs in its own thread in the OS
int main()
{
    while (true) {
        // Blink LED and wait 0.5 seconds
        led1 = !led1;
        wait_ms(SLEEP_TIME);
    }
}
</pre>
<p>All-right, how do I compile this?  Well, run the mbed command line interface with &#8220;<span>mbed compile -m CY8CPROTO_062_4343W -t GCC_ARM</span>&#8220;&#8230; and after a bit of compiling you should end up with a window like this:</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-52-14-am/" rel="attachment wp-att-6565"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM.png" alt="" width="852" height="731" class="alignnone size-full wp-image-6565" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM.png 852w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM-600x515.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM-300x257.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM-768x659.png 768w" sizes="auto, (max-width: 852px) 100vw, 852px" /></a></p>
<p>&nbsp;</p>
<p>Now I have a &#8220;hex file&#8221;.  How do I program it?  There are three ways.</p>
<p>#1 You can add the &#8220;-f&#8221; option to the command line and it will &#8220;flash&#8221; the device after it gets done compiling using PyOCD.  In order to do this your development kit&#8217;s KitProg 3 must be in the DAPLink mode.  To get into this mode hold down the KitProg button for 2 seconds and the LED will turn off. (If the LED turns on that means you put the programmer into CMSIS-DAP mode, so hold down the button for 2 seconds again).  At the time of this writing the -f option doesn&#8217;t work in the released version of mbed-cli,  but that will be fixed shortly with an update to the program debug system in mbed (hopefully by the time you read this)</p>
<p>#2 Copy the hex file from the BUILD directory onto the Mass Storage device called &#8220;DAP Link&#8221; using the finder. (drag and drop).  To use this method your KitProg needs to be in DAPLink mode.  (so follow the steps above)</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-10-00-13-am/" rel="attachment wp-att-6580"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM.png" alt="" width="925" height="482" class="alignnone size-full wp-image-6580" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM.png 925w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM-600x313.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM-300x156.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM-768x400.png 768w" sizes="auto, (max-width: 925px) 100vw, 925px" /></a></p>
<p>#3 Use the &#8220;Cypress Programmer&#8221; to program the flash.  You can download it for Windows, Mac or Linux from this <a href="https://www.cypress.com/products/psoc-programming-solutions" target="_blank" rel="noopener">link</a> on cypress.com  When I run Cypress Programmer it looks like this:</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-06-25-am/" rel="attachment wp-att-6570"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM.png" alt="" width="891" height="549" class="alignnone size-full wp-image-6570" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM.png 891w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM-600x370.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM-300x185.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM-768x473.png 768w" sizes="auto, (max-width: 891px) 100vw, 891px" /></a></p>
<p>Open the hex file by pressing the &#8220;Open&#8221; button and navigating into the BUILD directory to find the hex file called &#8220;mbed-os-example-blinky.hex&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-08-32-am/" rel="attachment wp-att-6571"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.08.32-AM.png" alt="" width="638" height="499" class="alignnone size-full wp-image-6571" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.08.32-AM.png 638w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.08.32-AM-600x469.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.08.32-AM-300x235.png 300w" sizes="auto, (max-width: 638px) 100vw, 638px" /></a></p>
<p>Then press &#8220;connect&#8221; and &#8220;program&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-09-56-am/" rel="attachment wp-att-6572"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-789x1024.png" alt="" width="789" height="1024" class="alignnone size-large wp-image-6572" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-789x1024.png 789w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-600x779.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-231x300.png 231w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-768x997.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM.png 889w" sizes="auto, (max-width: 789px) 100vw, 789px" /></a></p>
<p>Nothing happens on my development kit?  So I press the reset button and now I get a blinking LED.  But why do I have to press reset?   Do you see the &#8220;Reset Chip&#8221; checkbox at the top of the &#8220;Program Settings&#8221; window?  That has to be clicked.  Now when you program, the debugger will reset the chip and you will be off to the races.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-12-05-am/" rel="attachment wp-att-6573"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM.png" alt="" width="888" height="165" class="alignnone size-full wp-image-6573" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM.png 888w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM-600x111.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM-300x56.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM-768x143.png 768w" sizes="auto, (max-width: 888px) 100vw, 888px" /></a></p>
<p>So, what was going on with the rest of that program that came by default?  If you attach a serial terminal to the devkit you will see that the blinky example program is putting out information about the RTOS.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-15-40-am/" rel="attachment wp-att-6575"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.15.40-AM.png" alt="" width="703" height="525" class="alignnone size-full wp-image-6575" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.15.40-AM.png 703w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.15.40-AM-600x448.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.15.40-AM-300x224.png 300w" sizes="auto, (max-width: 703px) 100vw, 703px" /></a></p>
<p>It turns out the mbed-os is really an os&#8230; an operation system.  Actually it is a real time operating system that traces it genealogy to RTX, a product from the old <a href="https://en.wikipedia.org/wiki/Keil_(company)" target="_blank" rel="noopener">Keil Corporation</a> which was acquired by ARM&#8230;. a lot more on this later.</p>
<p>One final note that may cause confusion (I certainly have been confused).  There are four different modes of KitProg 3 (the programmer that is built into most of the Cypress development kits).</p>
<div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Mode</th>
<th >LED</th>
<th >Change modes</th>
</tr>
</thead>
<tbody>
<tr><td >CMSIS-DAP BULK</td>
<td >Solid LED</td>
<td >Short button press toggles between BULK and HID</td>
</tr>

<tr><td >CMSIS-DAP HID</td>
<td >Breathing LED</td>
<td >Short button press toggles between BULK and HID</td>
</tr>

<tr><td >DAPLink</td>
<td >LED Off</td>
<td >Hold KitProg button for &gt;2 seconds (gets in and out of this mode)</td>
</tr>

<tr><td >B00tloader</td>
<td >Fast blinking LED</td>
<td >hold reset button and plug in kit</td>
</tr>
</tbody></table></div>
<p>In order to program from the command line using &#8220;mbed compile -f&#8221; you need to be in &#8220;DAPLink&#8221; mode.  In order to program with Cypress Programmer you need one of the CMSIS-DAP modes.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/cypress-mbed-os/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Mouser PSoC 6-WiFi-BT L8: Integrate WiFi and AWS Into the Game</title>
		<link>https://iotexpert.com/mouser-vtw-lesson-8-integrate-wifi-and-aws-into-the-game/</link>
					<comments>https://iotexpert.com/mouser-vtw-lesson-8-integrate-wifi-and-aws-into-the-game/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Wed, 24 Oct 2018 09:08:53 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[Mouser 10-24-18 PSoC 6 & 4343W WiFi/BLE]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<category><![CDATA[WICED]]></category>
		<category><![CDATA[WIFI]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=5965</guid>

					<description><![CDATA[Summary In this lesson we will move the subscriber app functionality into the main GameBle project (now called GameBleAws).  In order to do this, you need to turn the subscriber into a thread, and fix it so that messages that are sent to the PADDLE topic get turned into messages that can be sent to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span><h1>Designing low-power, cloud-connected IoT devices with PSoC® 6 MCU’s and WICED® Wi-Fi/Bluetooth</h1>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >#</th>
<th >Lesson</th>
</tr>
</thead>
<tbody>
<tr><td >0</td>
<td ><a href="https://iotexpert.com/2018/10/23/mouser-psoc6-wifi-bt-l0-designing-low-power-cloud-connected-iot-devices-with-psoc-6-mcus-and-wiced-wi-fi-bluetooth/">Introduction</a></td>
</tr>

<tr><td >1</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l1-developers-resources/">Developer Resources</a></td>
</tr>

<tr><td >2</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l2-wiced-studio-capsense/">WICED Studio &amp; CapSense</a></td>
</tr>

<tr><td >3</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-3-using-the-tft/">Using the CY8CKIT-028-TFT Shield</a></td>
</tr>

<tr><td >4</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l4-the-video-game/">The Video Game</a></td>
</tr>

<tr><td >5</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l5-goble-ble-remote-control-for-the-game/">GoBle &amp; Bluetooth</a></td>
</tr>

<tr><td >6</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l6-integrate-goble-bluetooth-into-the-game/">Integrate GoBle Bluetooth into the Game</a></td>
</tr>

<tr><td >7</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l7-implement-wifi-and-aws/">Implement WiFi and AWS</a></td>
</tr>

<tr><td >8</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-8-integrate-wifi-and-aws-into-the-game/">Integrate WiFi and AWS Into the Game</a></td>
</tr>
</tbody></table></div></p></span></p>
<h1>Summary</h1>
<p>In this lesson we will move the subscriber app functionality into the main GameBle project (now called GameBleAws).  In order to do this, you need to turn the subscriber into a thread, and fix it so that messages that are sent to the PADDLE topic get turned into messages that can be sent to the paddleQueue.</p>
<p>To implement this lesson I will follow these steps:</p>
<ol>
<li>Create a New Project starting from L6GameBle</li>
<li>Copy over subscriber.c and wifi_config_dct.h</li>
<li>Update the Makefile</li>
<li>Create subscriber.h</li>
<li>Update main.c</li>
<li>Update subscriber.c</li>
<li>Test</li>
</ol>
<h1>Create a New Project</h1>
<p>Copy and paste the L6GameBle project into a new project called L8GameBleAws using Copy/Paste</p>
<p><a href="https://iotexpert.com/?attachment_id=6009" rel="attachment wp-att-6009"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.01.02-PM.png" alt="" width="936" height="336" class="alignnone size-full wp-image-6009" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.01.02-PM.png 936w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.01.02-PM-600x215.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.01.02-PM-300x108.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.01.02-PM-768x276.png 768w" sizes="auto, (max-width: 936px) 100vw, 936px" /></a></p>
<p>Create a new Make target for the GameBleAws project</p>
<p><a href="https://iotexpert.com/?attachment_id=6008" rel="attachment wp-att-6008"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-1.58.35-PM.png" alt="" width="808" height="824" class="alignnone size-full wp-image-6008" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-1.58.35-PM.png 808w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-1.58.35-PM-600x612.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-1.58.35-PM-294x300.png 294w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-1.58.35-PM-768x783.png 768w" sizes="auto, (max-width: 808px) 100vw, 808px" /></a></p>
<h1>Copy subscriber.c &amp; wifi_config_dct.h</h1>
<p>Use copy/paste to make a copy of the subscriber application and paste it into the GameBleAws project.  Once done your folder should look like this:</p>
<p><a href="https://iotexpert.com/?attachment_id=6010" rel="attachment wp-att-6010"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.01.58-PM.png" alt="" width="384" height="556" class="alignnone size-full wp-image-6010" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.01.58-PM.png 384w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.01.58-PM-207x300.png 207w" sizes="auto, (max-width: 384px) 100vw, 384px" /></a></p>
<p><a href="https://iotexpert.com/?attachment_id=5969" rel="attachment wp-att-5969"></a></p>
<h1>Update the Makefile</h1>
<pre class="EnlighterJSRAW" data-enlighter-language="c">NAME := App_WStudio_L8GameBleAws

$(NAME)_SOURCES := main.c \
    CapSenseThread.c \
	GameThread.c \
	cy_tft_display.c \
	GoBleThread.c \
	GoBle_db.c \
	wiced_bt_cfg.c \
	subscriber.c

$(NAME)_COMPONENTS := graphics/ugui \
                      libraries/drivers/bluetooth/low_energy \
                      protocols/AWS

WIFI_CONFIG_DCT_H := wifi_config_dct.h

$(NAME)_RESOURCES  := apps/aws/iot/rootca.cer \
                      apps/aws/iot/subscriber/client.cer \
                      apps/aws/iot/subscriber/privkey.cer
                      
# To support Low memory platforms, disabling components which are not required
GLOBAL_DEFINES += WICED_CONFIG_DISABLE_SSL_SERVER \
                  WICED_CONFIG_DISABLE_DTLS \
                  WICED_CONFIG_DISABLE_ENTERPRISE_SECURITY \
                  WICED_CONFIG_DISABLE_DES \
                  WICED_CONFIG_DISABLE_ADVANCED_SECURITY_CURVES</pre>
<h1>Create subscriber.h</h1>
<p>In order for the main.c to know about the awsThread (which is the former application_start of subscriber.c) you should create a file called subscriber.h.  Then you should define the awsThread function to match the wiced_thread_t function prototype (just a function that takes a wiced_thread_arg and returns void).</p>
<pre class="lang:c decode:true">#pragma once
extern void awsThread( wiced_thread_arg_t arg );
</pre>
<h1>Update main.c</h1>
<p>To integrate the awsThread thread into your main project you need to add the &#8220;subscriber.h&#8221; to the includes:</p>
<pre class="lang:c decode:true">#include "GameThread.h"
#include "GoBleThread.h"
#include "CapSenseThread.h"
#include "subscriber.h"
#include "wiced.h"
</pre>
<p>Add a new variable to hold the awsThreadHandle.</p>
<pre class="start-line:39 lang:c decode:true ">wiced_thread_t awsThreadHandle;</pre>
<p>Finally you should launch the AWS thread by creating it with wiced_rtos_create_thread.</p>
<pre class="start-line:96 lang:c decode:true ">void application_start( )
{
    wiced_init( );
    wiced_rtos_init_queue(&amp;paddleQueue,"paddleQueue",sizeof(game_msg_t),10);
    wiced_rtos_create_thread(&amp;blinkThreadHandle,7,"Blink Thread",pdlBlinkThread,500,0);
    wiced_rtos_create_thread(&amp;capsenseThreadHandle,7,"CapSense Thread",capSenseThread,1024,0);
    wiced_rtos_create_thread(&amp;gameThreadHandle,7,"game Thread",gameThread,4096,0);
    GoBleThread_start();
    wiced_rtos_create_thread(&amp;awsThreadHandle,7,"AWS Thread",awsThread,4096,0);
 }
</pre>
<h1>Update subscriber.c</h1>
<p>In order for subscriber.c to be useful you need to fix the includes, send the messages from the PADDLE topic to the game thread, and turn application_start into a thread.  Start by fixing the includes (just like we did in the BLE Example in Lesson 6)</p>
<pre class="start-line:88 lang:c decode:true">#include "SystemGlobal.h"
#include "GameThread.h"</pre>
<p>When you get a message to the PADDLE topic, you should parse it, then send a message to the game thread to move the paddle.  You do this exactly the same way as you did in the BLE project.  Notice that I protect the game thread by making sure it send a value less than 100.</p>
<pre class="start-line:176 lang:c decode:true">        case WICED_AWS_EVENT_PAYLOAD_RECEIVED:
        {
            uint32_t val;
            WPRINT_APP_INFO( ("[Application/AWS] Payload Received[ Topic: %.*s ]:\n", (int)data-&gt;message.topic_length, data-&gt;message.topic ) );

            if(strncmp(WICED_TOPIC,(const char *)data-&gt;message.topic,strlen(WICED_TOPIC)) == 0 &amp;&amp; data-&gt;message.data_length &lt; 4)
            {
                sscanf((const char *)data-&gt;message.data,"%d",(int *)&amp;val);
                if(val&gt;100)
                    val = 100;

                WPRINT_APP_INFO(("Val = %d\n",(int)val));
                game_msg_t msg;
                msg.evt = MSG_POSITION;
                msg.val = val;
                wiced_rtos_push_to_queue(&amp;paddleQueue,&amp;msg,0);
            }
        }
        break;
</pre>
<h1>Test</h1>
<p>I don&#8217;t really have a good program (like the GoBle) to test moving the paddle live.  But you can see that when the game is over, you can still move the paddle using AWS console.  In the screen shot below you can see that I moved the paddle to position 0.  And you can see that the BLE started at the same time as AWS.  Score.</p>
<p><a href="https://iotexpert.com/?attachment_id=5970" rel="attachment wp-att-5970"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-6.55.02-PM.png" alt="" width="837" height="501" class="alignnone size-full wp-image-5970" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-6.55.02-PM.png 837w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-6.55.02-PM-600x359.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-6.55.02-PM-300x180.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-6.55.02-PM-768x460.png 768w" sizes="auto, (max-width: 837px) 100vw, 837px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mouser-vtw-lesson-8-integrate-wifi-and-aws-into-the-game/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mouser PSoC 6-WiFi-BT L7 : Implement WiFi and AWS</title>
		<link>https://iotexpert.com/mouser-psoc6-wifi-bt-l7-implement-wifi-and-aws/</link>
					<comments>https://iotexpert.com/mouser-psoc6-wifi-bt-l7-implement-wifi-and-aws/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Wed, 24 Oct 2018 09:07:00 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[Mouser 10-24-18 PSoC 6 & 4343W WiFi/BLE]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<category><![CDATA[WICED]]></category>
		<category><![CDATA[WIFI]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=5946</guid>

					<description><![CDATA[Summary In this lesson I am going to update one of the predefined application which we deliver as part of WICED Studio which knows how to connect to the AWS IoT Cloud to work on my network.  This will demonstrate WiFi and MQTT.  I will also fix the application so that it knows about a [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span><h1>Designing low-power, cloud-connected IoT devices with PSoC® 6 MCU’s and WICED® Wi-Fi/Bluetooth</h1>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >#</th>
<th >Lesson</th>
</tr>
</thead>
<tbody>
<tr><td >0</td>
<td ><a href="https://iotexpert.com/2018/10/23/mouser-psoc6-wifi-bt-l0-designing-low-power-cloud-connected-iot-devices-with-psoc-6-mcus-and-wiced-wi-fi-bluetooth/">Introduction</a></td>
</tr>

<tr><td >1</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l1-developers-resources/">Developer Resources</a></td>
</tr>

<tr><td >2</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l2-wiced-studio-capsense/">WICED Studio &amp; CapSense</a></td>
</tr>

<tr><td >3</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-3-using-the-tft/">Using the CY8CKIT-028-TFT Shield</a></td>
</tr>

<tr><td >4</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l4-the-video-game/">The Video Game</a></td>
</tr>

<tr><td >5</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l5-goble-ble-remote-control-for-the-game/">GoBle &amp; Bluetooth</a></td>
</tr>

<tr><td >6</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l6-integrate-goble-bluetooth-into-the-game/">Integrate GoBle Bluetooth into the Game</a></td>
</tr>

<tr><td >7</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l7-implement-wifi-and-aws/">Implement WiFi and AWS</a></td>
</tr>

<tr><td >8</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-8-integrate-wifi-and-aws-into-the-game/">Integrate WiFi and AWS Into the Game</a></td>
</tr>
</tbody></table></div></p></span></p>
<h1>Summary</h1>
<p>In this lesson I am going to update one of the predefined application which we deliver as part of WICED Studio which knows how to connect to the AWS IoT Cloud to work on my network.  This will demonstrate WiFi and MQTT.  I will also fix the application so that it knows about a new MQTT Topic called &#8220;PADDLE&#8221; which will be used to send messages to move the game paddle.</p>
<p>To implement this project I will:</p>
<ol>
<li>Copy the subscriber from demo/aws/iot/pub_sub/subscriber</li>
<li>Setup a &#8220;thing&#8221; on AWS and download the certificates</li>
<li>Update the certificates in the WICED installation</li>
<li>Update the project with my AWS configuration</li>
<li>Test</li>
<li>Update the project to be compatible with the Game</li>
<li>Test</li>
</ol>
<h1>Copy Subscriber &amp; Fix the Makefile</h1>
<p>The first thing that I will do is copy/paste the subscriber application which can be found at demo/aws/iot/pub_sub/subscriber into my folder.  I will also rename the project to L7subscriber. Once that is done it should look like this:</p>
<p><a href="https://iotexpert.com/?attachment_id=6013" rel="attachment wp-att-6013"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.08.29-PM.png" alt="" width="332" height="146" class="alignnone size-full wp-image-6013" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.08.29-PM.png 332w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.08.29-PM-300x132.png 300w" sizes="auto, (max-width: 332px) 100vw, 332px" /></a></p>
<p>Then you need to edit the Makefile to update the name of the project.</p>
<pre class="start-line:37 EnlighterJSRAW" data-enlighter-language="c" ">NAME := App_WStudio_L7subscriber
<a href="https://iotexpert.com/?attachment_id=5975" rel="attachment wp-att-5975"></a></pre>
<h1>Go to Amazon.com and Create a &#8220;thing&#8221;</h1>
<p>In order to connect to the AWS cloud you need to create a &#8220;thing&#8221;.  Go to the AWS console and click &#8220;Create&#8221;</p>
<p><a href="https://iotexpert.com/?attachment_id=5953" rel="attachment wp-att-5953"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.47.55-PM-1024x593.png" alt="" width="1024" height="593" class="alignnone size-large wp-image-5953" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.47.55-PM-1024x593.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.47.55-PM-600x347.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.47.55-PM-300x174.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.47.55-PM-768x445.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.47.55-PM.png 1166w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>We are just going to create one thing.  So, click &#8220;Create a single thing&#8221;</p>
<p><a href="https://iotexpert.com/?attachment_id=5952" rel="attachment wp-att-5952"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.12-PM-1024x589.png" alt="" width="1024" height="589" class="alignnone size-large wp-image-5952" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.12-PM-1024x589.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.12-PM-600x345.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.12-PM-300x172.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.12-PM-768x441.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.12-PM.png 1164w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Give it a name, in this case Mouser.</p>
<p><a href="https://iotexpert.com/?attachment_id=5951" rel="attachment wp-att-5951"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.54-PM-1024x1007.png" alt="" width="1024" height="1007" class="alignnone size-large wp-image-5951" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.54-PM-1024x1007.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.54-PM-600x590.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.54-PM-300x295.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.54-PM-768x755.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.48.54-PM.png 1153w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>AWS has device level security which is implemented with RSA certificates for each device.  So,  you need to let AWS create a certificate for you.</p>
<p><a href="https://iotexpert.com/?attachment_id=5950" rel="attachment wp-att-5950"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.13-PM-1024x992.png" alt="" width="1024" height="992" class="alignnone size-large wp-image-5950" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.13-PM-1024x992.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.13-PM-600x581.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.13-PM-300x291.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.13-PM-768x744.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.13-PM.png 1169w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Once that is done download the device certificate and the two keys.  You need to 100% make sure you do this now, because you wont get another chance. I&#8217;m also going to activate the certificate once I have the certificate and keys.</p>
<p><a href="https://iotexpert.com/?attachment_id=5949" rel="attachment wp-att-5949"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.37-PM-1024x665.png" alt="" width="1024" height="665" class="alignnone size-large wp-image-5949" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.37-PM-1024x665.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.37-PM-600x390.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.37-PM-300x195.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.37-PM-768x499.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.49.37-PM.png 1165w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now attach a policy to your thing.  I already have the &#8220;ww101_policy&#8221; setup.</p>
<p><a href="https://iotexpert.com/?attachment_id=5948" rel="attachment wp-att-5948"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.55.43-PM-1024x573.png" alt="" width="1024" height="573" class="alignnone size-large wp-image-5948" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.55.43-PM-1024x573.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.55.43-PM-600x336.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.55.43-PM-300x168.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.55.43-PM-768x430.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-3.55.43-PM.png 1165w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The policy looks like this.  Basically, things are wide open.</p>
<p><a href="https://iotexpert.com/?attachment_id=5962" rel="attachment wp-att-5962"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.54.21-PM-1024x943.png" alt="" width="1024" height="943" class="alignnone size-large wp-image-5962" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.54.21-PM-1024x943.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.54.21-PM-600x553.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.54.21-PM-300x276.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.54.21-PM-768x707.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.54.21-PM.png 1062w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Update the Certificates</h1>
<p>The last thing that you need is the most recent AWS certificate.  WICED expects that you use the RSA2048 bit key.</p>
<p><a href="https://iotexpert.com/?attachment_id=5955" rel="attachment wp-att-5955"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.05.09-PM-1024x526.png" alt="" width="1024" height="526" class="alignnone size-large wp-image-5955" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.05.09-PM-1024x526.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.05.09-PM-600x308.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.05.09-PM-300x154.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.05.09-PM-768x395.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.05.09-PM.png 1282w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now that you have the four security documents., you need to integrate them into your WICED installation.  To do this, change directories to ~/Documents/WICED-Studio-6.2/43xxx_Wi-Fi/resources/apps/aws/iot  Then copy the files, and then make symbolic links.  If you are not on a Mac or Linux then just copy the files and rename them appropriately.</p>
<p><a href="https://iotexpert.com/?attachment_id=5958" rel="attachment wp-att-5958"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.30.16-PM.png" alt="" width="776" height="211" class="alignnone size-full wp-image-5958" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.30.16-PM.png 776w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.30.16-PM-600x163.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.30.16-PM-300x82.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.30.16-PM-768x209.png 768w" sizes="auto, (max-width: 776px) 100vw, 776px" /></a></p>
<h1>Update the Project</h1>
<p>AWS creates a virtual machine and runs an MQTT server on that machine.  You can find out the DNS name of that machine on the settings screen.  Here you can see my endpoint.  You will need to configure the WICED project to talk to your server.</p>
<p><a href="https://iotexpert.com/?attachment_id=5947" rel="attachment wp-att-5947"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.00.34-PM-1024x418.png" alt="" width="1024" height="418" class="alignnone size-large wp-image-5947" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.00.34-PM-1024x418.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.00.34-PM-600x245.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.00.34-PM-300x122.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.00.34-PM-768x314.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.00.34-PM.png 1166w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>You need to change the actual endpoint of your MQTT server in the AWS cloud on line 119</p>
<pre class="start-line:117 EnlighterJSRAW" data-enlighter-language="c"">static wiced_aws_endpoint_info_t my_subscriber_aws_iot_endpoint = {
    .transport           = WICED_AWS_TRANSPORT_MQTT_NATIVE,
    .uri                 = "amk6m51qrxr2u-ats.iot.us-east-1.amazonaws.com",
    .peer_common_name    = NULL,
    .ip_addr             = {0},
    .port                = WICED_AWS_IOT_DEFAULT_MQTT_PORT,
    .root_ca_certificate = NULL,
    .root_ca_length      = 0,
};</pre>
<p>In the file wifi_config_dct.h you will need to change the CLIENT_AP_SSID and CLIENT_AP_PASSPHRASE for your network</p>
<pre class="start-line:60 EnlighterJSRAW" data-enlighter-language="c" ">/* This is the default AP the device will connect to (as a client)*/
#define CLIENT_AP_SSID       "WW101WPA"
#define CLIENT_AP_PASSPHRASE "yourpassword"
#define CLIENT_AP_BSS_TYPE   WICED_BSS_TYPE_INFRASTRUCTURE
#define CLIENT_AP_SECURITY   WICED_SECURITY_WPA2_MIXED_PSK
#define CLIENT_AP_CHANNEL    1
#define CLIENT_AP_BAND       WICED_802_11_BAND_2_4GHZ</pre>
<h1>Test</h1>
<p>In order to test the project you will need to create a make target and program your development kit.</p>
<p><a href="https://iotexpert.com/?attachment_id=6014" rel="attachment wp-att-6014"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.12.13-PM.png" alt="" width="942" height="762" class="alignnone size-full wp-image-6014" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.12.13-PM.png 942w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.12.13-PM-600x485.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.12.13-PM-300x243.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-21-at-2.12.13-PM-768x621.png 768w" sizes="auto, (max-width: 942px) 100vw, 942px" /></a></p>
<p>Once that is done you can go to the Amazon.com test console and send MQTT messages to the correct topic.</p>
<p><a href="https://iotexpert.com/?attachment_id=5956" rel="attachment wp-att-5956"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.25.03-PM-1024x825.png" alt="" width="1024" height="825" class="alignnone size-large wp-image-5956" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.25.03-PM-1024x825.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.25.03-PM-600x483.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.25.03-PM-300x242.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.25.03-PM-768x619.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.25.03-PM.png 1354w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Here you can see the project attached to my network.  And successfully received the LIGHT ON message.</p>
<p><a href="https://iotexpert.com/?attachment_id=5957" rel="attachment wp-att-5957"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.26.29-PM.png" alt="" width="839" height="524" class="alignnone size-full wp-image-5957" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.26.29-PM.png 839w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.26.29-PM-600x375.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.26.29-PM-300x187.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.26.29-PM-768x480.png 768w" sizes="auto, (max-width: 839px) 100vw, 839px" /></a></p>
<h1>Update the Project for the Game</h1>
<p>We know that the game doesn&#8217;t care about the LIGHT topic so, let&#8217;s change it to PADDLE.</p>
<pre class="start-line:100 lang:c decode:true">#define WICED_TOPIC                                 "PADDLE"</pre>
<p>And let&#8217;s assume that messages to the paddle topic are ASCII numbers &lt;100.  So, we can parse the message and print it out.  Notice that I used sscanf to parse the message and we all know that is super dangerous.</p>
<pre class="start-line:173 EnlighterJSRAW" data-enlighter-language="c"">        case WICED_AWS_EVENT_PAYLOAD_RECEIVED:
        {
            char buff[10];
            uint32_t val;
            WPRINT_APP_INFO( ("[Application/AWS] Payload Received[ Topic: %.*s ]:\n", (int)data-&gt;message.topic_length, data-&gt;message.topic ) );

            if(strncmp(WICED_TOPIC,data-&gt;message.topic,strlen(WICED_TOPIC)) == 0 &amp;&amp; data-&gt;message.data_length &lt; 4)
            {
                sscanf(data-&gt;message.data,"%d",&amp;val);
                WPRINT_APP_INFO(("Val = %d\n",val));
            }
        }
        break;
</pre>
<h1>Test</h1>
<p>After making those updates let&#8217;s program the whole shooting match again.  Then test by sending some messages to the PADDLE topic.</p>
<p><a href="https://iotexpert.com/?attachment_id=5961" rel="attachment wp-att-5961"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.51.23-PM-1024x941.png" alt="" width="1024" height="941" class="alignnone size-large wp-image-5961" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.51.23-PM-1024x941.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.51.23-PM-600x551.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.51.23-PM-300x276.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.51.23-PM-768x706.png 768w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.51.23-PM.png 1181w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>It&#8217;s good.  Things are working.</p>
<p><a href="https://iotexpert.com/?attachment_id=5960" rel="attachment wp-att-5960"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.48.01-PM.png" alt="" width="838" height="700" class="alignnone size-full wp-image-5960" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.48.01-PM.png 838w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.48.01-PM-600x501.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.48.01-PM-300x251.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-4.48.01-PM-768x642.png 768w" sizes="auto, (max-width: 838px) 100vw, 838px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mouser-psoc6-wifi-bt-l7-implement-wifi-and-aws/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mouser PSoC6-WiFi-BT L6 : Integrate GoBle Bluetooth into the Game</title>
		<link>https://iotexpert.com/mouser-psoc6-wifi-bt-l6-integrate-goble-bluetooth-into-the-game/</link>
					<comments>https://iotexpert.com/mouser-psoc6-wifi-bt-l6-integrate-goble-bluetooth-into-the-game/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Wed, 24 Oct 2018 09:06:32 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[Mouser 10-24-18 PSoC 6 & 4343W WiFi/BLE]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<category><![CDATA[WICED]]></category>
		<category><![CDATA[WIFI]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=5930</guid>

					<description><![CDATA[Summary At this point we have a working BLE Remote Control and a working Game.  In this lesson I&#8217;ll merge the two projects together so that the GoBle remote control will be able to control the game paddle.  It will do this by creating messages (just like the CapSense messages) and sending them to the [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span><h1>Designing low-power, cloud-connected IoT devices with PSoC® 6 MCU’s and WICED® Wi-Fi/Bluetooth</h1>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >#</th>
<th >Lesson</th>
</tr>
</thead>
<tbody>
<tr><td >0</td>
<td ><a href="https://iotexpert.com/2018/10/23/mouser-psoc6-wifi-bt-l0-designing-low-power-cloud-connected-iot-devices-with-psoc-6-mcus-and-wiced-wi-fi-bluetooth/">Introduction</a></td>
</tr>

<tr><td >1</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l1-developers-resources/">Developer Resources</a></td>
</tr>

<tr><td >2</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l2-wiced-studio-capsense/">WICED Studio &amp; CapSense</a></td>
</tr>

<tr><td >3</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-3-using-the-tft/">Using the CY8CKIT-028-TFT Shield</a></td>
</tr>

<tr><td >4</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l4-the-video-game/">The Video Game</a></td>
</tr>

<tr><td >5</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l5-goble-ble-remote-control-for-the-game/">GoBle &amp; Bluetooth</a></td>
</tr>

<tr><td >6</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l6-integrate-goble-bluetooth-into-the-game/">Integrate GoBle Bluetooth into the Game</a></td>
</tr>

<tr><td >7</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l7-implement-wifi-and-aws/">Implement WiFi and AWS</a></td>
</tr>

<tr><td >8</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-8-integrate-wifi-and-aws-into-the-game/">Integrate WiFi and AWS Into the Game</a></td>
</tr>
</tbody></table></div></p></span></p>
<h1>Summary</h1>
<p>At this point we have a working BLE Remote Control and a working Game.  In this lesson I&#8217;ll merge the two projects together so that the GoBle remote control will be able to control the game paddle.  It will do this by creating messages (just like the CapSense messages) and sending them to the Game thread via the paddleQueue.  And it will send &#8220;Button0&#8221; messages when &#8220;Button A&#8221; is pressed.</p>
<p>To implement this lesson I will follow these steps:</p>
<ol>
<li>Copy everything into a new project</li>
<li>Modify the Makefile</li>
<li>Modify main.c</li>
<li>Create a new make target</li>
<li>Test it all to make sure things are still working</li>
<li>Modify GoBleThread.c</li>
<li>Program and Test</li>
</ol>
<h1>Copy L4Game into a new project L6GameBle</h1>
<p>Use &#8220;copy&#8221; and &#8220;paste&#8221; to create a new project, when you paste give it the name &#8220;L6GameBle&#8221; (there is an error in the screenshot)</p>
<p><a href="https://iotexpert.com/?attachment_id=5940" rel="attachment wp-att-5940"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-1.22.49-PM.png" alt="" width="471" height="168" class="alignnone size-full wp-image-5940" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-1.22.49-PM.png 471w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-1.22.49-PM-300x107.png 300w" sizes="auto, (max-width: 471px) 100vw, 471px" /></a></p>
<p>Copy the files GoBle_db.c/h, GoBleThread.c/h, and wiced_bt_cfg.c from the GoBle project into your new GameBle project.  After that is done your project should look like this:</p>
<p><a href="https://iotexpert.com/?attachment_id=5939" rel="attachment wp-att-5939"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-1.20.59-PM.png" alt="" width="285" height="226" class="alignnone size-full wp-image-5939" /></a></p>
<h1>Modify the Makefile</h1>
<ol>
<li>Change the name of the App to &#8220;App_WStudio_L6GameBle&#8221;</li>
<li>Add the new source files</li>
<li>Add the BLE Library &#8220;libraries/drivers/bluetooth/low_energy&#8221;</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">NAME := App_WStudio_L6GameBle

$(NAME)_SOURCES := main.c \
    CapSenseThread.c \
	GameThread.c \
	cy_tft_display.c \
	GoBleThread.c \
	GoBle_db.c \
	wiced_bt_cfg.c

$(NAME)_COMPONENTS := graphics/ugui \
                      libraries/drivers/bluetooth/low_energy
</pre>
<h1>Modify main.c</h1>
<p>Add the include for the GeBleThread.</p>
<pre class="lang:c decode:true">#include "GameThread.h"
#include "GoBleThread.h"
#include "CapSenseThread.h"
#include "wiced.h"</pre>
<p>In the application_start function add a call GoBleThread_start() to get the GoBle thread going</p>
<pre class="start-line:93 EnlighterJSRAW" data-enlighter-language="c"">void application_start( )
{
    wiced_init( );
    wiced_rtos_init_queue(&amp;paddleQueue,"paddleQueue",sizeof(game_msg_t),10);
    wiced_rtos_create_thread(&amp;blinkThreadHandle,7,"Blink Thread",pdlBlinkThread,500,0);
    wiced_rtos_create_thread(&amp;capSenseThreadHandle,7,"CapSense Thread",capSenseThread,1024,0);
    wiced_rtos_create_thread(&amp;gameThreadHandle,7,"game Thread",gameThread,4096,0);
    GoBleThread_start();
 }
</pre>
<h1>Create a new make target</h1>
<p><a href="https://iotexpert.com/?attachment_id=5935" rel="attachment wp-att-5935"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-1.03.56-PM.png" alt="" width="430" height="421" class="alignnone size-full wp-image-5935" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-1.03.56-PM.png 430w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-20-at-1.03.56-PM-300x294.png 300w" sizes="auto, (max-width: 430px) 100vw, 430px" /></a></p>
<h1>Test it all to make sure things are still working</h1>
<p>Run the make target and make sure that the game still plays and that you can get remote control messages.</p>
<h1>Modify GoBleThread.c</h1>
<p>Add the includes for the GameThread (to get access to the game message structure) and SystemGlobal (to get access to the queue)</p>
<pre class="start-line:8 lang:c decode:true">#include "GameThread.h"
#include "SystemGlobal.h"</pre>
<p>I don&#8217;t need (or want) the button/slider printout information.  So I will delete the old button code from goble_event_handler. (delete this stuff)</p>
<pre class="start-line:137 lang:c decode:true">            WPRINT_APP_INFO(("# Buttons = %d ButtonMask=%02X Slider x=%02X Slider Y=%02X Raw=",(int)numButtons,(unsigned int)buttonMask,(unsigned int)sliderX,(unsigned int)sliderY));

            for(int i=0;i&lt;p_attr_req-&gt;data.write_req.val_len;i++)
            {
                WPRINT_APP_INFO(("%02X ",p_attr_req-&gt;data.write_req.p_val[i]));
            }
            WPRINT_APP_INFO(("\n"));</pre>
<p>Now, update the code to send the slider and button information to the GameThread (via the paddleQueue).  You may have noticed that the slider on GoBle gives you 0-&gt;0xFF and the direction is the inverse from the game we setup.  So, I will scale the value to 100 and invert it so that the controller moves the paddle the right way on line 143.  The message format is exactly the same as what we setup for the CapSense.  This means the CapSense slider works at the same time as the GoBle controller.</p>
<pre class="start-line:127 EnlighterJSRAW" data-enlighter-language="c"">   case GATT_ATTRIBUTE_REQUEST_EVT:

        p_attr_req = &amp;p_event_data-&gt;attribute_request;
        if( p_attr_req-&gt;request_type == GATTS_REQ_TYPE_WRITE  &amp;&amp; p_attr_req-&gt;data.handle == HDLC_GOBLE_SERIALPORTID_VALUE)
        {
            uint32_t numButtons = p_attr_req-&gt;data.write_req.p_val[3];
            uint32_t sliderY = p_attr_req-&gt;data.write_req.p_val[5+numButtons];
            uint32_t sliderX = p_attr_req-&gt;data.write_req.p_val[6+numButtons];
            uint32_t buttonMask = 0x00;
            for(int i=0;i&lt;numButtons;i++)
            {
                buttonMask |= (1&lt;&lt;p_attr_req-&gt;data.write_req.p_val[5+i]);
            }

            game_msg_t msg;
            msg.evt = MSG_POSITION;
            msg.val = 100 - (100*sliderY/255);
            wiced_rtos_push_to_queue(&amp;paddleQueue,&amp;msg,0);
            if(buttonMask &amp; 0x10)
            {
                msg.evt = MSG_BUTTON0;
                msg.val = 1;
                wiced_result_t result=wiced_rtos_push_to_queue(&amp;paddleQueue,&amp;msg,0);
            }
            status = WICED_BT_GATT_SUCCESS;
        }
        break;
</pre>
<h1>Program and Test</h1>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mouser-psoc6-wifi-bt-l6-integrate-goble-bluetooth-into-the-game/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mouser PSoC6-WiFi-BT L5 : GoBLE &#8211;  BLE Remote Control for the Game</title>
		<link>https://iotexpert.com/mouser-psoc6-wifi-bt-l5-goble-ble-remote-control-for-the-game/</link>
					<comments>https://iotexpert.com/mouser-psoc6-wifi-bt-l5-goble-ble-remote-control-for-the-game/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Wed, 24 Oct 2018 09:05:43 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[Mouser 10-24-18 PSoC 6 & 4343W WiFi/BLE]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<category><![CDATA[WICED]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6019</guid>

					<description><![CDATA[Summary Although I a like the video game, it is for sure missing something.  That something is IoT.  The first IoT thing that we will do to the game is to add a BLE remote control.  I wanted a pre-done remote control that could be downloaded from the App store.  After looking around a little [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span><h1>Designing low-power, cloud-connected IoT devices with PSoC® 6 MCU’s and WICED® Wi-Fi/Bluetooth</h1>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >#</th>
<th >Lesson</th>
</tr>
</thead>
<tbody>
<tr><td >0</td>
<td ><a href="https://iotexpert.com/2018/10/23/mouser-psoc6-wifi-bt-l0-designing-low-power-cloud-connected-iot-devices-with-psoc-6-mcus-and-wiced-wi-fi-bluetooth/">Introduction</a></td>
</tr>

<tr><td >1</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l1-developers-resources/">Developer Resources</a></td>
</tr>

<tr><td >2</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l2-wiced-studio-capsense/">WICED Studio &amp; CapSense</a></td>
</tr>

<tr><td >3</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-3-using-the-tft/">Using the CY8CKIT-028-TFT Shield</a></td>
</tr>

<tr><td >4</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l4-the-video-game/">The Video Game</a></td>
</tr>

<tr><td >5</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l5-goble-ble-remote-control-for-the-game/">GoBle &amp; Bluetooth</a></td>
</tr>

<tr><td >6</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l6-integrate-goble-bluetooth-into-the-game/">Integrate GoBle Bluetooth into the Game</a></td>
</tr>

<tr><td >7</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l7-implement-wifi-and-aws/">Implement WiFi and AWS</a></td>
</tr>

<tr><td >8</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-8-integrate-wifi-and-aws-into-the-game/">Integrate WiFi and AWS Into the Game</a></td>
</tr>
</tbody></table></div></p></span></p>
<h1>Summary</h1>
<p>Although I a like the video game, it is for sure missing something.  That something is IoT.  The first IoT thing that we will do to the game is to add a BLE remote control.  I wanted a pre-done remote control that could be downloaded from the App store.  After looking around a little bit I found GoBle.  I published a detailed article about GoBle <a href="https://iotexpert.com/2018/10/19/goble-remote-control-wiced-bluetooth-implementation/" target="_blank" rel="noopener">here</a>, but I&#8217;ll explain enough to make it work with the game.</p>
<p>Here is a screen shot of what the remote control looks like.  You can see that on the left there is a joystick, and on the right there are some buttons.  My son tells me that this is a classic layout for a remote control.</p>
<p><a href="https://iotexpert.com/2018/10/19/goble-remote-control-wiced-bluetooth-implementation/img_6351/" rel="attachment wp-att-5907"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/IMG_6351-1024x576.png" alt="" width="1024" height="576" class="alignnone size-large wp-image-5907" srcset="https://iotexpert.com/wp-content/uploads/2018/10/IMG_6351-1024x576.png 1024w, https://iotexpert.com/wp-content/uploads/2018/10/IMG_6351-600x338.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/IMG_6351-300x169.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/IMG_6351-768x432.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>This remote control works as a &#8220;Central&#8221; meaning it knows how to connect to Peripherals.  For this lesson we will turn on the CYW4343W and make it be a Bluetooth Peripheral.</p>
<p>To implement this lesson I will follow these steps:</p>
<ol>
<li>Create a folder called &#8220;L5GoBle&#8221;</li>
<li>Create a makefile called L5GoBle.mk</li>
<li>Setup a GATT database by creating GoBle_db.h and GoBle_db.c</li>
<li>Setup wiced_bt_cfg.c</li>
<li>Create GoBleThread.c</li>
<li>Create GoBle.c to startup the GoBleThread</li>
<li>Build, Program and Test</li>
</ol>
<h1>Create a directory called &#8220;L5GoBle&#8221;</h1>
<h1>Create a makefile called L5GoBle.mk</h1>
<pre class="EnlighterJSRAW" data-enlighter-language="c">NAME := App_WStudio_L5GoBle

$(NAME)_SOURCES    := GoBle.c \
			          GoBleThread.c \
                      GoBle_db.c \
                      wiced_bt_cfg.c

$(NAME)_INCLUDES   := .

$(NAME)_COMPONENTS += libraries/drivers/bluetooth/low_energy 
</pre>
<h1>Setup a GATT database by creating GoBle_db.h and GoBle_db.c</h1>
<p>Create a file called &#8220;GoBle_db.h&#8221;</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">// GoBle_db.h

#ifndef __GATT_DATABASE_H__
#define __GATT_DATABASE_H__

#include "wiced.h"

#define __UUID_GOBLE                                 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xb0, 0xdf, 0x00, 0x00
#define __UUID_GOBLE_SERIALPORTID                    0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xb1, 0xdf, 0x00, 0x00

// ***** Primary Service 'Generic Attribute'
#define HDLS_GENERIC_ATTRIBUTE                       0x0001

// ***** Primary Service 'Generic Access'
#define HDLS_GENERIC_ACCESS                          0x0014
// ----- Characteristic 'Device Name'
#define HDLC_GENERIC_ACCESS_DEVICE_NAME              0x0015
#define HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE        0x0016
// ----- Characteristic 'Appearance'
#define HDLC_GENERIC_ACCESS_APPEARANCE               0x0017
#define HDLC_GENERIC_ACCESS_APPEARANCE_VALUE         0x0018

// ***** Primary Service 'GoBle'
#define HDLS_GOBLE                                   0x0028
// ----- Characteristic 'SerialPortId'
#define HDLC_GOBLE_SERIALPORTID                      0x0029
#define HDLC_GOBLE_SERIALPORTID_VALUE                0x002A
// ===== Descriptor 'Client Configuration'
#define HDLD_GOBLE_SERIALPORTID_CLIENT_CONFIGURATION 0x002B


// External definitions
extern const uint8_t  gatt_database[];
extern const uint16_t gatt_database_len;
extern uint8_t BT_LOCAL_NAME[];
extern const uint16_t BT_LOCAL_NAME_CAPACITY;

#endif /* __GATT_DATABASE_H__ */
</pre>
<p>Create a file called &#8220;GoBle.c&#8221;</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">/*
 * This file has been automatically generated by the WICED 20719-B1 Designer.
 * BLE device's GATT database and device configuration.
 *
 */

// GoBle_db.c

#include "GoBle_db.h"

#include "wiced.h"
#include "wiced_bt_uuid.h"
#include "wiced_bt_gatt.h"

/*************************************************************************************
** GATT server definitions
*************************************************************************************/

const uint8_t gatt_database[] = // Define GATT database
{
    /* Primary Service 'Generic Attribute' */
    PRIMARY_SERVICE_UUID16 (HDLS_GENERIC_ATTRIBUTE, UUID_SERVICE_GATT),

    /* Primary Service 'Generic Access' */
    PRIMARY_SERVICE_UUID16 (HDLS_GENERIC_ACCESS, UUID_SERVICE_GAP),

    /* Primary Service 'GoBle' */
    PRIMARY_SERVICE_UUID128 (HDLS_GOBLE, __UUID_GOBLE),

        /* Characteristic 'SerialPortId' */
        CHARACTERISTIC_UUID128_WRITABLE (HDLC_GOBLE_SERIALPORTID, HDLC_GOBLE_SERIALPORTID_VALUE,
            __UUID_GOBLE_SERIALPORTID, LEGATTDB_CHAR_PROP_READ | LEGATTDB_CHAR_PROP_WRITE_NO_RESPONSE | LEGATTDB_CHAR_PROP_WRITE | LEGATTDB_CHAR_PROP_NOTIFY,
            LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ),

            /* Descriptor 'Client Characteristic Configuration' */
            CHAR_DESCRIPTOR_UUID16_WRITABLE (HDLD_GOBLE_SERIALPORTID_CLIENT_CONFIGURATION,
                UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION, LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_REQ | LEGATTDB_PERM_AUTH_WRITABLE),

};

// Length of the GATT database
const uint16_t gatt_database_len = sizeof(gatt_database);
</pre>
<h1>Setup wiced_bt_cfg.c</h1>
<p>The WICED Bluetooth Configuration file is called &#8220;wiced_bt_config.c&#8221;.  The only change I made from the default is the timeout value of the advertising.  You can copy this directly into your file.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">/*
 * This file has been automatically generated by the WICED 20719-B1 Designer.
 * Device Configuration.
 *
 */

/** wiced_bt_cfg.c
 *
 * Runtime Bluetooth stack configuration parameters
 *
 */

#include "wiced_bt_dev.h"
#include "wiced_bt_ble.h"
#include "wiced_bt_uuid.h"
#include "wiced_bt_gatt.h"
#include "wiced_bt_avrc.h"
#include "wiced_bt_cfg.h"

/* Null-Terminated Local Device Name */
uint8_t BT_LOCAL_NAME[] = { 'G','o','B','l','e','T','e','s','t','\0' };
const uint16_t BT_LOCAL_NAME_CAPACITY = sizeof(BT_LOCAL_NAME);


/*******************************************************************
 * wiced_bt core stack configuration
 ******************************************************************/
const wiced_bt_cfg_settings_t wiced_bt_cfg_settings =
{
    .device_name =                          (uint8_t*)BT_LOCAL_NAME,                                    /**&lt; Local device name (NULL terminated) */
    .device_class =                         {0x00, 0x00, 0x00},                                         /**&lt; Local device class */
    .security_requirement_mask =            BTM_SEC_NONE,                                               /**&lt; Security requirements mask (BTM_SEC_NONE, or combination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT */
    .max_simultaneous_links =               1,                                                          /**&lt; Maximum number of simultaneous links to different devices */

    /* BR/EDR Scan Configuration */
    .br_edr_scan_cfg = {
        .inquiry_scan_type =                BTM_SCAN_TYPE_STANDARD,                                     /**&lt; Inquiry Scan Type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */
        .inquiry_scan_interval =            0x0000,                                                     /**&lt; Inquiry Scan Interval (0 to use default) */
        .inquiry_scan_window =              0x0000,                                                     /**&lt; Inquiry Scan Window (0 to use default) */

        .page_scan_type =                   BTM_SCAN_TYPE_STANDARD,                                     /**&lt; Page Scan Type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */
        .page_scan_interval =               0x0000,                                                     /**&lt; Page Scan Interval (0 to use default) */
        .page_scan_window =                 0x0000,                                                     /**&lt; Page Scan Window (0 to use default) */
    },

    /* BLE Scan Settings */
    .ble_scan_cfg = {
        .scan_mode =                        BTM_BLE_SCAN_MODE_PASSIVE,                                  /**&lt; BLE Scan Mode (BTM_BLE_SCAN_MODE_PASSIVE or BTM_BLE_SCAN_MODE_ACTIVE) */

        /* Advertisement Scan Configuration */
        .high_duty_scan_interval =          WICED_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL,               /**&lt; High Duty Scan Interval */
        .high_duty_scan_window =            WICED_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW,                 /**&lt; High Duty Scan Window */
        .high_duty_scan_duration =          5,                                                          /**&lt; High Duty Scan Duration in seconds (0 for infinite) */

        .low_duty_scan_interval =           WICED_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL,                /**&lt; Low Duty Scan Interval */
        .low_duty_scan_window =             WICED_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW,                  /**&lt; Low Duty Scan Window */
        .low_duty_scan_duration =           5,                                                          /**&lt; Low Duty Scan Duration in seconds (0 for infinite) */

        /* Connection Scan Configuration */
        .high_duty_conn_scan_interval =     WICED_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL,          /**&lt; High Duty Connection Cycle Connection Scan Interval */
        .high_duty_conn_scan_window =       WICED_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW,            /**&lt; High Duty Connection Cycle Connection Scan Window */
        .high_duty_conn_duration =          30,                                                         /**&lt; High Duty Connection Cycle Connection Duration in seconds (0 for infinite) */

        .low_duty_conn_scan_interval =      WICED_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL,           /**&lt; Low Duty Connection Cycle Connection Scan Interval */
        .low_duty_conn_scan_window =        WICED_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW,             /**&lt; Low Duty Connection Cycle Connection Scan Window */
        .low_duty_conn_duration =           30,                                                         /**&lt; Low Duty Connection Cycle Connection Duration in seconds (0 for infinite) */

        /* Connection Configuration */
        .conn_min_interval =                WICED_BT_CFG_DEFAULT_CONN_MIN_INTERVAL,                     /**&lt; Minimum Connection Interval */
        .conn_max_interval =                WICED_BT_CFG_DEFAULT_CONN_MAX_INTERVAL,                     /**&lt; Maximum Connection Interval */
        .conn_latency =                     WICED_BT_CFG_DEFAULT_CONN_LATENCY,                          /**&lt; Connection Latency */
        .conn_supervision_timeout =         WICED_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT,              /**&lt; Connection Link Supervision Timeout */
    },

    /* BLE Advertisement Settings */
    .ble_advert_cfg = {
        .channel_map =                      BTM_BLE_ADVERT_CHNL_37 |                                    /**&lt; Advertising Channel Map (mask of BTM_BLE_ADVERT_CHNL_37, BTM_BLE_ADVERT_CHNL_38, BTM_BLE_ADVERT_CHNL_39) */
                                            BTM_BLE_ADVERT_CHNL_38 |
                                            BTM_BLE_ADVERT_CHNL_39,

        .high_duty_min_interval =           WICED_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL,            /**&lt; High Duty Undirected Connectable Minimum Advertising Interval */
        .high_duty_max_interval =           WICED_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL,            /**&lt; High Duty Undirected Connectable Maximum Advertising Interval */
        .high_duty_duration =               0,                                                         /**&lt; High Duty Undirected Connectable Advertising Duration in seconds (0 for infinite) */

        .low_duty_min_interval =            WICED_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL,             /**&lt; Low Duty Undirected Connectable Minimum Advertising Interval */
        .low_duty_max_interval =            WICED_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL,             /**&lt; Low Duty Undirected Connectable Maximum Advertising Interval */
        .low_duty_duration =                60,                                                         /**&lt; Low Duty Undirected Connectable Advertising Duration in seconds (0 for infinite) */

        .high_duty_directed_min_interval =  WICED_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL,   /**&lt; High Duty Directed Minimum Advertising Interval */
        .high_duty_directed_max_interval =  WICED_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL,   /**&lt; High Duty Directed Maximum Advertising Interval */

        .low_duty_directed_min_interval =   WICED_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL,    /**&lt; Low Duty Directed Minimum Advertising Interval */
        .low_duty_directed_max_interval =   WICED_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL,    /**&lt; Low Duty Directed Maximum Advertising Interval */
        .low_duty_directed_duration =       30,                                                         /**&lt; Low Duty Directed Advertising Duration in seconds (0 for infinite) */

        .high_duty_nonconn_min_interval =   WICED_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL,    /**&lt; High Duty Non-Connectable Minimum Advertising Interval */
        .high_duty_nonconn_max_interval =   WICED_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL,    /**&lt; High Duty Non-Connectable Maximum Advertising Interval */
        .high_duty_nonconn_duration =       30,                                                         /**&lt; High Duty Non-Connectable Advertising Duration in seconds (0 for infinite) */

        .low_duty_nonconn_min_interval =    WICED_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL,     /**&lt; Low Duty Non-Connectable Minimum Advertising Interval */
        .low_duty_nonconn_max_interval =    WICED_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL,     /**&lt; Low Duty Non-Connectable Maximum Advertising Interval */
        .low_duty_nonconn_duration =        0,                                                          /**&lt; Low Duty Non-Connectable Advertising Duration in seconds (0 for infinite) */
    },

    /* GATT Configuration */
    .gatt_cfg = {
        .appearance =                       0x0000,                                                     /**&lt; GATT Appearance */
        .client_max_links =                 1,                                                          /**&lt; Client Config: Maximum number of servers that local client can connect to */
        .server_max_links =                 1,                                                          /**&lt; Server Config: Maximum number of remote client connections allowed by local server */
        .max_attr_len =                     512,                                                        /**&lt; Maximum attribute length; wiced_bt_cfg must have a corresponding buffer pool that can hold this length */
        .max_mtu_size =                     515,                                                        /**&lt; Maximum MTU size for GATT connections, should be between 23 and (max_attr_len + 5) */
    },

    /* RFCOMM Configuration */
    .rfcomm_cfg = {
        .max_links =                        0,                                                          /**&lt; Maximum number of simultaneous connected remote devices */
        .max_ports =                        0,                                                          /**&lt; Maximum Number of simultaneous RFCOMM ports */
    },

    /* Application-Managed L2CAP Protocol Configuration */
    .l2cap_application = {
        .max_links =                        0,                                                          /**&lt; Maximum Number of Application-Managed L2CAP Links (BR/EDR and BLE) */
        .max_psm =                          0,                                                          /**&lt; Maximum Number of Application-Managed BR/EDR PSMs */
        .max_channels =                     0,                                                          /**&lt; Maximum Number of Application-Managed BR/EDR Channels */
        .max_le_psm =                       0,                                                          /**&lt; Maximum Number of Application-Managed LE PSMs */
        .max_le_channels =                  0,                                                          /**&lt; Maximum Number of Application-Managed LE Channels */
        .max_le_l2cap_fixed_channels =      0,                                                          /**&lt; Maximum Number of Application-Managed LE L2CAP Fixed Channnels supported (in addition to mandatory channels 4, 5, and 6 */
    },

    /* Audio/Video Distribution Configuration */
    .avdt_cfg = {
        .max_links =                        0,                                                          /**&lt; Maximum Number of simultaneous Audio/Video links */
        .max_seps =                         0,                                                          /**&lt; Maximum Number of stream end points */
    },

    /* AVRC Configuration */
    .avrc_cfg = {
        .roles =                            0,                                                          /**&lt; Local Roles supported (AVRC_CONN_INITIATOR or AVRC_CONN_ACCEPTOR) */
        .max_links =                        0,                                                          /**&lt; Maximum simultaneous Remote Control links */
    },

    /* LE Address Resolution Database Settings */
    .addr_resolution_db_size =              10,                                                         /**&lt; LE Address Resolution Database Size - Effective only for pre-4.2 controller */
    .max_number_of_buffer_pools =           4,                                                          /**&lt; Maximum number of buffer pools in p_btm_cfg_buf_pools and by wiced_create_pool */
    .rpa_refresh_timeout =                  0,         /**&lt; Interval of random address refreshing - secs */
};

/*******************************************************************
 * wiced_bt_stack buffer pool configuration
 *
 * Configure buffer pools used by the stack
 *
 * Pools must be ordered in increasing buf_size.
 * If a pools runs out of buffers, the next pool will be used.
 ******************************************************************/
const wiced_bt_cfg_buf_pool_t wiced_bt_cfg_buf_pools[WICED_BT_CFG_NUM_BUF_POOLS] =
{
/*  { buf_size, buf_count, }, */
    { 64,       12,        }, /* Small Buffer Pool */
    { 360,      4,         }, /* Medium Buffer Pool (used for HCI &amp; RFCOMM control messages, min recommended size is 360) */
    { 512,      4,         }, /* Large Buffer Pool  (used for HCI ACL messages) */
    { 1024,     2,         }, /* Extra Large Buffer Pool (used for AVDT media packets and miscellaneous; if not needed, set buf_count to 0) */
};
</pre>
<h1>Create GoBleThread.c</h1>
<p>In  order for the GoBleThread to work you need:</p>
<ol>
<li>The includes for the GATT Database and the WICED bluetooth stack.</li>
<li>External References to the GATT Database.</li>
<li>A few function prototypes.</li>
<li>A function called &#8220;GoBleThread_start&#8221; to startup the Bluetooth stack and get things going. This includes providing Bluetooth management and GATT event handler functions.</li>
</ol>
<pre class="lang:c decode:true">#include "GoBle_db.h"
#include "wiced.h"
#include "wiced_bt_ble.h"
#include "wiced_bt_gatt.h"
#include "wiced_bt_stack.h"

/*******************************************************************
 * Variable Definitions
 ******************************************************************/
extern const wiced_bt_cfg_settings_t wiced_bt_cfg_settings;
extern const wiced_bt_cfg_buf_pool_t wiced_bt_cfg_buf_pools[WICED_BT_CFG_NUM_BUF_POOLS];

/*******************************************************************
 * Function Prototypes
 ******************************************************************/
static wiced_bt_dev_status_t  goble_management_callback    ( wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data );
static void                   goble_set_advertisement_data ( void );
static wiced_bt_gatt_status_t goble_event_handler          ( wiced_bt_gatt_evt_t  event, wiced_bt_gatt_event_data_t *p_event_data );

/*******************************************************************
 * Function Definitions
 ******************************************************************/
void GoBleThread_start(void)
{
    wiced_bt_stack_init(goble_management_callback, &amp;wiced_bt_cfg_settings, wiced_bt_cfg_buf_pools);
}
</pre>
<p>Create a function to setup the advertising data.  The GoBle iOS App looks for Peripherals that are advertising the UUID of the GoBLE Service.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">/* Set Advertisement Data */
void goble_set_advertisement_data( void )
{
    wiced_bt_ble_advert_elem_t adv_elem[3] = { 0 };
    uint8_t adv_flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED;
    uint8_t num_elem = 0; 

    /* Advertisement Element for Flags */
    adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_FLAG;
    adv_elem[num_elem].len = sizeof(uint8_t);
    adv_elem[num_elem].p_data = &amp;adv_flag;
    num_elem++;

    uint8_t gobleuuid[] = {__UUID_GOBLE};

    /* Advertisement Element for Name */
    adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_128SRV_COMPLETE;
    adv_elem[num_elem].len = 16;
    adv_elem[num_elem].p_data = gobleuuid;
    num_elem++;

    /* Set Raw Advertisement Data */
    wiced_bt_ble_set_raw_advertisement_data(num_elem, adv_elem);
}
</pre>
<p>The Bluetooth Management Event Handler needs to take actions when the stack turns on, or one of the pairing events occur.</p>
<pre class="lang:c decode:true">/* Bluetooth Management Event Handler */
wiced_bt_dev_status_t goble_management_callback( wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data )
{
    wiced_bt_dev_status_t status = WICED_BT_SUCCESS;

    switch (event)
    {
    case BTM_ENABLED_EVT:
        goble_set_advertisement_data();
        wiced_bt_gatt_register( goble_event_handler );
        wiced_bt_gatt_db_init( gatt_database, gatt_database_len );
        wiced_bt_start_advertisements(BTM_BLE_ADVERT_UNDIRECTED_HIGH, 0, NULL);
        break;

    case BTM_SECURITY_REQUEST_EVT:
        wiced_bt_ble_security_grant(p_event_data-&gt;security_request.bd_addr, WICED_BT_SUCCESS);
        break;

    case BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT:
        p_event_data-&gt;pairing_io_capabilities_ble_request.local_io_cap = BTM_IO_CAPABILITIES_NONE;
        p_event_data-&gt;pairing_io_capabilities_ble_request.oob_data = BTM_OOB_NONE;
        p_event_data-&gt;pairing_io_capabilities_ble_request.auth_req = BTM_LE_AUTH_REQ_NO_BOND;
        break;


    case BTM_USER_CONFIRMATION_REQUEST_EVT: // Just confirm
        wiced_bt_dev_confirm_req_reply( WICED_BT_SUCCESS , p_event_data-&gt;user_confirmation_request.bd_addr);
        break;

    case BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT:
        WPRINT_APP_INFO(("Paired linke keys\n"));
        status = WICED_BT_ERROR;
        break;

    case BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT:
    case BTM_PAIRING_COMPLETE_EVT:
    case BTM_ENCRYPTION_STATUS_EVT:
    case BTM_BLE_ADVERT_STATE_CHANGED_EVT:
    case BTM_LPM_STATE_LOW_POWER:
        break;

    default:
        WPRINT_APP_INFO(("Unhandled Bluetooth Management Event: 0x%x (%d)\n", event, event));
        break;
    }

    return status;
}
</pre>
<p>The GATT Event Handler is called</p>
<ol>
<li>When a connection is made or terminated</li>
<li>When the GoBle app writes to your GATT database.  When that happens we will just printout the value that was written</li>
</ol>
<pre class="lang:c decode:true">/* GATT Event Handler */
wiced_bt_gatt_status_t goble_event_handler( wiced_bt_gatt_evt_t event, wiced_bt_gatt_event_data_t *p_event_data )
{
    wiced_bt_gatt_status_t status = WICED_BT_GATT_ERROR;
    wiced_bt_gatt_attribute_request_t *p_attr_req = NULL;

    switch ( event )
    {
    case GATT_CONNECTION_STATUS_EVT:
        if(!p_event_data-&gt;connection_status.connected)
        {
            WPRINT_APP_INFO(("Disconnected\n"));
            wiced_bt_start_advertisements(BTM_BLE_ADVERT_UNDIRECTED_HIGH, 0, NULL);
        }
        else
            WPRINT_APP_INFO(("Connected\n"));
        break;
    case GATT_ATTRIBUTE_REQUEST_EVT:

        p_attr_req = &amp;p_event_data-&gt;attribute_request;
        if( p_attr_req-&gt;request_type == GATTS_REQ_TYPE_WRITE  &amp;&amp; p_attr_req-&gt;data.handle == HDLC_GOBLE_SERIALPORTID_VALUE)
        {
            uint32_t numButtons = p_attr_req-&gt;data.write_req.p_val[3];
            uint32_t sliderY = p_attr_req-&gt;data.write_req.p_val[5+numButtons];
            uint32_t sliderX = p_attr_req-&gt;data.write_req.p_val[6+numButtons];
            uint32_t buttonMask = 0x00;
            for(int i=0;i&lt;numButtons;i++)
            {
                buttonMask |= (1&lt;&lt;p_attr_req-&gt;data.write_req.p_val[5+i]);
            }

            WPRINT_APP_INFO(("# Buttons = %d ButtonMask=%02X Slider x=%02X Slider Y=%02X Raw=",(int)numButtons,(unsigned int)buttonMask,(unsigned int)sliderX,(unsigned int)sliderY));

            for(int i=0;i&lt;p_attr_req-&gt;data.write_req.val_len;i++)
            {
                WPRINT_APP_INFO(("%02X ",p_attr_req-&gt;data.write_req.p_val[i]));
            }
            WPRINT_APP_INFO(("\n"));
            status = WICED_BT_GATT_SUCCESS;
        }
        break;
    default:
        status = WICED_BT_GATT_SUCCESS;
        break;
    }

    return status;
}
</pre>
<h1>Create GoBleThread.h</h1>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

extern void GoBleThread_start(void);
</pre>
<h1>Create GoBle.c to startup the GoBleThread</h1>
<pre class="lang:c decode:true ">#include "GoBleThread.h"
#include "wiced.h"


/*******************************************************************
 * Function Definitions
 ******************************************************************/
void application_start(void)
{
    wiced_init();
    GoBleThread_start();

}

</pre>
<h1>Build, Program and Test</h1>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mouser-psoc6-wifi-bt-l5-goble-ble-remote-control-for-the-game/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Mouser PSoC6-WiFi-BT L4 : The Video Game</title>
		<link>https://iotexpert.com/mouser-psoc6-wifi-bt-l4-the-video-game/</link>
					<comments>https://iotexpert.com/mouser-psoc6-wifi-bt-l4-the-video-game/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Wed, 24 Oct 2018 09:04:40 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[Mouser 10-24-18 PSoC 6 & 4343W WiFi/BLE]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<category><![CDATA[WICED]]></category>
		<category><![CDATA[WIFI]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6017</guid>

					<description><![CDATA[Summary In this lesson I&#8217;ll finish the video game thread by adding the graphics etc. to play the game.  In addition I&#8217;ll fix up the CapSense thread so that it is connected to the game via an RTOS queue. There are three main things going on in this game. A state machine for the game [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span><h1>Designing low-power, cloud-connected IoT devices with PSoC® 6 MCU’s and WICED® Wi-Fi/Bluetooth</h1>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >#</th>
<th >Lesson</th>
</tr>
</thead>
<tbody>
<tr><td >0</td>
<td ><a href="https://iotexpert.com/2018/10/23/mouser-psoc6-wifi-bt-l0-designing-low-power-cloud-connected-iot-devices-with-psoc-6-mcus-and-wiced-wi-fi-bluetooth/">Introduction</a></td>
</tr>

<tr><td >1</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l1-developers-resources/">Developer Resources</a></td>
</tr>

<tr><td >2</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l2-wiced-studio-capsense/">WICED Studio &amp; CapSense</a></td>
</tr>

<tr><td >3</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-3-using-the-tft/">Using the CY8CKIT-028-TFT Shield</a></td>
</tr>

<tr><td >4</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l4-the-video-game/">The Video Game</a></td>
</tr>

<tr><td >5</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l5-goble-ble-remote-control-for-the-game/">GoBle &amp; Bluetooth</a></td>
</tr>

<tr><td >6</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l6-integrate-goble-bluetooth-into-the-game/">Integrate GoBle Bluetooth into the Game</a></td>
</tr>

<tr><td >7</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-psoc6-wifi-bt-l7-implement-wifi-and-aws/">Implement WiFi and AWS</a></td>
</tr>

<tr><td >8</td>
<td ><a href="https://iotexpert.com/2018/10/24/mouser-vtw-lesson-8-integrate-wifi-and-aws-into-the-game/">Integrate WiFi and AWS Into the Game</a></td>
</tr>
</tbody></table></div></p></span></p>
<h1>Summary</h1>
<p>In this lesson I&#8217;ll finish the video game thread by adding the graphics etc. to play the game.  In addition I&#8217;ll fix up the CapSense thread so that it is connected to the game via an RTOS queue.</p>
<p>There are three main things going on in this game.</p>
<ol>
<li>A state machine for the game screen (Splash, Start, Running, Over)</li>
<li>A 20ms timer that updates the screen while the game is running (moves the Paddle and the Ball)</li>
<li>A GUI queue where the rest of the system &#8211; CapSense,  Bluetooth and WiFi &#8211; can send Button and Paddle messages.</li>
</ol>
<p>To implement this project I will:</p>
<ol>
<li>Setup the project and makefile by copying L3CapSenseTft</li>
<li>Update gamethread.h to define the GUI queue messages</li>
<li>Fix main.c to create the queue</li>
<li>Create SystemGlobal.h to give the rest of the files access to the gui queue</li>
<li>Updating the CapSenseThread to send GUI messages</li>
<li>Update the includes in GameThread.c</li>
<li>Add some #define macros to define game parameters</li>
<li>Add a State Machine for the game &amp; define some paddle movement methods</li>
<li>Make forward declarations for the thread functions</li>
<li>Create some variables to maintain game state</li>
<li>Add display functions for the score and the speed</li>
<li>Add functions to start and end the game</li>
<li>Add helper functions to calculate the top and bottom of the paddle</li>
<li>Add a function to update and draw the paddle</li>
<li>Add a function to update and draw the ball</li>
<li>Add a function for the game timer to call</li>
<li>Update the main game thread</li>
</ol>
<h1>Setup the project and makefile by copying L3CapSenseTft</h1>
<p>Use copy/paste to copy the L3CapSenseTft project to a new folder name L4Game.   Change the name of the makefile to be L4Game.mk.</p>
<p>Edit the makefile and change the name of the application.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">NAME := App_WStudio_L4Game

$(NAME)_SOURCES := main.c \
    CapSenseThread.c \
	GameThread.c \
	cy_tft_display.c

$(NAME)_COMPONENTS := graphics/ugui
</pre>
<p>Create a make target for this project</p>
<p><a href="https://iotexpert.com/?attachment_id=6080" rel="attachment wp-att-6080"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-23-at-6.48.06-AM.png" alt="" width="904" height="726" class="alignnone size-full wp-image-6080" srcset="https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-23-at-6.48.06-AM.png 904w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-23-at-6.48.06-AM-600x482.png 600w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-23-at-6.48.06-AM-300x241.png 300w, https://iotexpert.com/wp-content/uploads/2018/10/Screen-Shot-2018-10-23-at-6.48.06-AM-768x617.png 768w" sizes="auto, (max-width: 904px) 100vw, 904px" /></a></p>
<h1>Update GameThread.h to Define the GUI Messages</h1>
<p>All of the threads in the system (CapSense, Bluetooth, and WiFi) will control the paddle and the button by sending messages to an RTOS queue.  In gameThread.h we will add a definition of that message.  The message is just a structure with two values &#8211; which GUI element and what value to send.</p>
<pre class="lang:c decode:true">#pragma once
#include "wiced.h"

typedef enum {
    MSG_POSITION,
    MSG_BUTTON0,
    MSG_BUTTON1,
} game_evt_t;

typedef struct {
    game_evt_t evt;
    uint32_t val;
} game_msg_t;

void gameThread(wiced_thread_arg_t arg);
</pre>
<h1>Fix main.c to Create the Queue</h1>
<p>I typically believe that the RTOS primitives should be owned by the main.c.  To do this edit main.c and fix the includes.</p>
<pre class="lang:c decode:true">#include "GameThread.h"
#include "wiced.h"
#include "CapSenseThread.h"
#include "SystemGlobal.h"</pre>
<p>Then define the queue variable &#8220;paddleQueue&#8221; which I should have names &#8220;guiQueue&#8221; but it is way to late to fix it now &#8212; oh well.</p>
<pre class="start-line:31 lang:c decode:true ">/******************************************************
 *               Variable Definitions
 ******************************************************/

wiced_thread_t blinkThreadHandle;
wiced_thread_t capSenseThreadHandle;
wiced_thread_t gameThreadHandle;
wiced_queue_t paddleQueue;
</pre>
<p>Create the queue</p>
<pre class="start-line:55 lang:c decode:true">void application_start( )
{
    wiced_init( );
    wiced_rtos_init_queue(&amp;paddleQueue,"paddleQueue",sizeof(game_msg_t),10);
    wiced_rtos_create_thread(&amp;blinkThreadHandle,7,"Blink Thread",pdlBlinkThread,500,0);
    wiced_rtos_create_thread(&amp;capSenseThreadHandle,7,"CapSense Thread",capSenseThread,1024,0);
    wiced_rtos_create_thread(&amp;gameThreadHandle,7,"game Thread",gameThread,4096,0);
 }
</pre>
<h1>Create SystemGlobal.h</h1>
<p>Each of the threads in the system need to have access to the paddleQueue.  In order to do that create a file called SystemGlobal.h and extern the variable to give them that access.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

extern wiced_queue_t paddleQueue;
</pre>
<h1>Updating the CapSenseThread to send GUI messages</h1>
<p>Remember that when we setup the CapSenseThread originally, it just printed out the values.  Let&#8217;s fix it so send messages.  So, edit CapSenseThread.c.</p>
<ol>
<li>Add a message variable (line 8)</li>
<li>Fix the button0 and button 1 to make and send RTOS messages (lines 20/21 and 26/27)</li>
<li>Fix the slider to send the position (lines 33-35)</li>
</ol>
<pre class="lang:c decode:true ">#include "wiced.h"
#include "GameThread.h"
#include "SystemGlobal.h"

void capSenseThread(wiced_thread_arg_t arg)
{

    game_msg_t msg;

    CapSense_Start();
    CapSense_ScanAllWidgets();
    while(1)
    {
        if(!CapSense_IsBusy())
        {

            CapSense_ProcessAllWidgets();
            if(CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID))
            {
                msg.evt = MSG_BUTTON0;
                wiced_rtos_push_to_queue(&amp;paddleQueue,&amp;msg,0);
            }

            if(CapSense_IsWidgetActive(CapSense_BUTTON1_WDGT_ID))
            {
                msg.evt = MSG_BUTTON1;
                wiced_rtos_push_to_queue(&amp;paddleQueue,&amp;msg,0);
            }

            uint32_t val = CapSense_GetCentroidPos(CapSense_LINEARSLIDER0_WDGT_ID);
            if(val &lt; 0xFFFF)
            {
                msg.evt = MSG_POSITION;
                msg.val = val;
                wiced_rtos_push_to_queue(&amp;paddleQueue,&amp;msg,0);
            }
            CapSense_ScanAllWidgets();
        }
        wiced_rtos_delay_milliseconds(25); // Poll every 25ms (actual scan time ~8ms)
    }
}
</pre>
<h1>Update the includes in GameThread.c</h1>
<p>Now let&#8217;s fix GameThread.c.  Start by editing the includes to add a new file called &#8220;SystemGlobal.h&#8221; which contains the global variable for the GUI queue.</p>
<pre class="lang:c decode:true">#include "GameThread.h"
#include "cy_tft_display.h"
#include "SystemGlobal.h"
#include "ugui.h"
</pre>
<h1>Add some #define macros in GameThread.c</h1>
<p>There are a number of constants which I use in the game.  In this section I use #define macros to define them.</p>
<pre class="start-line:10 lang:c decode:true">#define UPDATE_SCREEN_TIME (20) // Update the screen every 20ms
#define SPEED (2)
#define SCREEN_X (320)
#define SCREEN_Y (240)
#define TOP_FIELD (21)
#define PD_WIDTH (10)
#define PD_LEN (70)
#define DOTS (3)
#define PADDLE0_COLOR (C_BLUE)
#define BALL_COLOR (C_GREEN)
#define BALL_SIZE (10)</pre>
<h1>Add a State Machine for the Game &amp; Define Paddle Movement</h1>
<p>Open up GameThread.c &#8211; all of the game control functions will go there.</p>
<p>There will be four screens in the game.  A splash screen to display Cypress and Mouser, a Ready Player 1 Screen, the actual game screen and a game over screen.</p>
<p>In addition the paddle can move a little bit at a time (increment) or jump directly to the position (absolute)</p>
<pre class="start-line:33 lang:c decode:true">// States of the game
typedef enum {
    GS_SPLASH,
    GS_START,
    GS_RUNNING,
    GS_OVER
} game_state_t;

// Methods to move the paddle
typedef enum {
    PADDLE_INCREMENT,
    PADDLE_ABSOLUTE
} paddle_update_t;</pre>
<h1>Fix the gameState statemachine</h1>
<p>In the splash screen I need to set the state machine to GS_SPLASH</p>
<pre class="start-line:242 lang:c decode:true">static void displaySplashScreen()
{
    gameState = GS_SPLASH;
    UG_FontSelect( &amp;FONT_22X36 );
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/5,22,36,"Cypress");
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/5*2,22,36,"Mouser");
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/5*3,22,36,"PSoC 6");
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/5*4,22,36,"WICED 4343");

    wiced_rtos_delay_milliseconds(2000);
}
</pre>
<p>In the start screen I need to set the state machine to GS_START</p>
<pre class="start-line:262 EnlighterJSRAW" data-enlighter-language="c" ">// Display the Start Screen
static void  displayStartScreen()
{
    gameState = GS_START;
    UG_FillScreen( C_BLACK );
    UG_FontSelect( &amp;FONT_22X36 );
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/2 -2 - 18 ,22,36,"Ready");
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/2 + 2 + 18 ,22,36,"Player 1");
    displayStartButton();
}
</pre>
<h1>Make Forward Declarations for Functions</h1>
<p>You should define the functions in advance of using them</p>
<pre class="start-line:52 lang:c decode:true">/******************************************************
 *               Static Function Declarations
 ******************************************************/
static void UG_PutStringCenter(uint32_t x, uint32_t y, uint32_t fontx, uint32_t fonty,char *string);
static void displaySplashScreen();
static void displayStartButton();
static void  displayStartScreen();
static void displayScore();
static void displaySpeed();
static void endGame();
static inline uint32_t calcPaddleTop();
static inline uint32_t calcPaddleBottom();
static void updatePaddle(paddle_update_t type);
static void updateBall();
static void updateScreen(void *arg);
</pre>
<h1>Create some variables to maintain game state</h1>
<p>The updateScreenTimer is used while the game is running to call the updateScreen every 20ms.  The rest of the variables are self explanatory.</p>
<pre class="start-line:68 lang:c decode:true">/******************************************************
 *               Variable Definitions
 ******************************************************/
static UG_GUI   gui;
static wiced_timer_t updateScreenTimer;

static uint32_t gameScore;
static game_state_t gameState;

// position of the paddle
static uint32_t paddle0_desire_pos=0;
static uint32_t paddle0_cur_pos=0;

// Position, direction and speed of the ball
static uint32_t ballx,bally;
static int32_t ballXdir, ballYdir;
static uint32_t ballSpeed;
</pre>
<h1>Add Display Functions for the Score &amp; Speed</h1>
<p>These two functions print the speed and score at the top of the screen.</p>
<pre class="start-line:134 EnlighterJSRAW" data-enlighter-language="c"">// This function displays the score
static void displayScore()
{
    char buff[10];
    sprintf(buff,"%2X",(unsigned int)gameScore);
    UG_FontSelect(&amp;FONT_12X20);
    UG_PutString( 75, 0, buff);
}

// This function displays the speed
static void displaySpeed()
{
    char buff[10];
    sprintf(buff,"%2X",(unsigned int)ballSpeed-1);
    UG_FontSelect(&amp;FONT_12X20);
    UG_PutString( 275, 0, buff);
}
</pre>
<h1>Add Function to Start the Game</h1>
<p>When the game needs to start you:</p>
<ol>
<li>Reset the score</li>
<li>Set the paddle position</li>
<li>Move the ball to the middle of the paddle</li>
<li>Set the ball to move to the right and down</li>
<li>Clear the screen, display score and speed</li>
<li>Start the game running</li>
</ol>
<pre class="start-line:153 lang:c decode:true">// This function initializes everything and starts a new game
static void startGame()
{
    gameScore = 0;

    paddle0_desire_pos = 50; // start the game with the paddle moving
    paddle0_cur_pos = 0;

    ballx = PD_WIDTH ;                   // start the ball on the paddle on the right of the screen
    bally  = calcPaddleTop() + PD_LEN/2; // start the ball in the middle of the paddle

    ballSpeed = SPEED;

    ballXdir = ballSpeed;
    ballYdir = ballSpeed;

    UG_FillScreen( C_BLACK );  // clear screen
    UG_FontSelect(&amp;FONT_12X20);
    UG_PutString( 0, 0,  "Score:");
    displayScore();
    UG_PutString(200,0,"Speed:");
    displaySpeed();
    UG_DrawLine(0,20,SCREEN_X,20,C_RED); // red line under text to represent top of play screen

    gameState = GS_RUNNING;
    wiced_rtos_start_timer(&amp;updateScreenTimer); // Timer to update screen
}

</pre>
<h1>Add Function to End the Game</h1>
<p>When the game is over you should:</p>
<ol>
<li>Move the game state to over</li>
<li>Stop the timer</li>
<li>Display game over</li>
<li>Display press button 0 to start</li>
</ol>
<pre class="start-line:181 lang:c decode:true">// Stop the game
static void endGame()
{
    gameState = GS_OVER;
    wiced_rtos_stop_timer(&amp;updateScreenTimer);
    UG_FontSelect( &amp;FONT_22X36 );
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/2,22,36,"Game Over");
    displayStartButton();
}
</pre>
<h1>Add Helper Functions to Calculate Paddle Top &amp; Bottom</h1>
<p>There are two places where you need to know the position of the Paddle.  Specifically:</p>
<ol>
<li>To draw the paddle</li>
<li>To figure out if the ball hit the paddle or not.</li>
</ol>
<p>These two functions calculate the pixel position of the top and bottom of the paddle based on it current position</p>
<pre class="lang:c decode:true ">// Figure out the y position of the top of the paddle
static inline uint32_t calcPaddleTop()
{
    return (paddle0_cur_pos)*DOTS+TOP_FIELD;
}

// Figure out the y position of the bottom of the paddle
static inline uint32_t calcPaddleBottom()
{
    return (paddle0_cur_pos)*DOTS+PD_LEN+TOP_FIELD;
}</pre>
<h1>Add a Function to Update &amp; Draw the Paddle</h1>
<p>While the game is running you need the paddle to move.  There are two methods:</p>
<ol>
<li>Absolute just moves the current position immediately to the desired position.</li>
<li>Incremental, which moves the paddle a little bit towards the desired position.</li>
</ol>
<pre class="start-line:204 lang:c decode:true">// Move the paddle either to : PADDLE_INCREMENT the next location or PADDLE_ABSOLUTE - final location
static void updatePaddle(paddle_update_t type)
{
    // If the paddle is where it is supposed to be then just return
    if(paddle0_cur_pos == paddle0_desire_pos)
        return;

    // erase the current paddle
    UG_FillFrame(0,calcPaddleTop(),PD_WIDTH,calcPaddleBottom(),C_BLACK);

    switch (type)
    {

    case PADDLE_INCREMENT:

        if(paddle0_cur_pos &lt; paddle0_desire_pos)
            paddle0_cur_pos += SPEED;
        else
            paddle0_cur_pos -= SPEED;

        // If the paddle is within one move of the final spot, put it there
        if(abs((int)paddle0_cur_pos-(int)paddle0_desire_pos) &lt; SPEED)
            paddle0_cur_pos = paddle0_desire_pos;
        break;

    case PADDLE_ABSOLUTE:
        paddle0_cur_pos = paddle0_desire_pos;
        break;
    }
    // draw the paddle
    UG_FillFrame(0,calcPaddleTop(),PD_WIDTH,calcPaddleBottom(),PADDLE0_COLOR);
}
</pre>
<h1>Add a function to update and draw the ball</h1>
<p>You need a function to:</p>
<ol>
<li>Move the ball</li>
<li>Figure out if it hit the right/left/top/bottom of the screen and do the right thing.</li>
</ol>
<p>When the ball hits one of those surfaces it needs to change direction to either plus or minus.</p>
<p>Every time it hits the paddle the score should increase and possibly speed up.</p>
<p>If it misses the paddle the game is over.</p>
<pre class="start-line:237 EnlighterJSRAW" data-enlighter-language="c" ">// Move the ball to the next location
static void updateBall()
{
    static const uint32_t BallFudgeFactor=3;

    UG_DrawCircle(ballx,bally,BALL_SIZE,C_BLACK);

    ballx += ballXdir;
    bally += ballYdir;

    // Check to see if the ball hit the far right side
    if(ballx &gt; SCREEN_X - BALL_SIZE)
    {

        ballx = SCREEN_X - BALL_SIZE;
        ballXdir = -ballSpeed;
    }

    // check to see if the ball hit the far left side... or the paddle
    if(ballx &lt; (BALL_SIZE + PD_WIDTH + BallFudgeFactor))
    {
        // See if the ball missed the paddle
        if(bally + BALL_SIZE &lt; calcPaddleTop() || bally - BALL_SIZE &gt; calcPaddleBottom())
        {
            endGame();
            //WPRINT_APP_INFO(("Missed Paddle\r\n"));
        }

        gameScore = gameScore + 1;
        displayScore();
        if(gameScore % 3 == 0) // Speed up every three hits
        {
            ballSpeed +=1;
            displaySpeed();
        }

        ballx = BALL_SIZE + PD_WIDTH + BallFudgeFactor;
        ballXdir = +ballSpeed;
    }
    // Check to see if the ball hit the top or bottom
    if(bally &gt; SCREEN_Y - BALL_SIZE) // bottom
    {
        bally = SCREEN_Y - BALL_SIZE;
        ballYdir = -ballSpeed;
    }

    if(bally &lt; TOP_FIELD+BALL_SIZE) // top
    {
        bally = BALL_SIZE+TOP_FIELD;
        ballYdir = +ballSpeed;
    }
    UG_DrawCircle(ballx,bally,BALL_SIZE,BALL_COLOR);
}
</pre>
<h1>Create a Function for the Game Timer</h1>
<p>An RTOS timer runs every 20ms.  That timer needs a function to move the paddle and move the ball.</p>
<pre class="start-line:291 EnlighterJSRAW" data-enlighter-language="c"">// This function is called every UPADTE_SCREEN_TIME milliseconds by the updateScreenTimer
static void updateScreen(void *arg)
{
    updatePaddle(PADDLE_INCREMENT);
    updateBall();
}</pre>
<h1>Update the Main Game Thread</h1>
<p>The main game thread needs to get messages out of the queue and then do the right thing based on the game state.</p>
<pre class="start-line:298 EnlighterJSRAW" data-enlighter-language="c"">// Main game thread
void gameThread(wiced_thread_arg_t arg)
{
    game_msg_t msg;

    Cy_TFT_Init();                                             // Init the TFT
    UG_Init( &amp;gui, Cy_TFT_displayDriver, SCREEN_X, SCREEN_Y ); // Connect the driver

    UG_FillScreen( C_BLACK );   // Clear the screen
    UG_SetBackcolor( C_BLACK );
    UG_SetForecolor( C_WHITE );

    wiced_rtos_init_timer(&amp;updateScreenTimer,UPDATE_SCREEN_TIME,updateScreen,0);
    displaySplashScreen();
    displayStartScreen();

    while(1)
    {
        wiced_rtos_pop_from_queue(&amp;paddleQueue,&amp;msg,WICED_WAIT_FOREVER);
        switch(msg.evt)
        {
        case MSG_POSITION:
            if(gameState == GS_RUNNING)
                paddle0_desire_pos = msg.val/2;
            if(gameState == GS_OVER)
            {
                paddle0_desire_pos = msg.val/2;
                updatePaddle(PADDLE_ABSOLUTE);
            }
            break;

        case MSG_BUTTON0:
            if(gameState == GS_OVER || gameState == GS_START)
                startGame();
            break;
        case MSG_BUTTON1:
            break;
        }
    }
}
</pre>
<h1>Program and Test</h1>
<p>Now that it is all done&#8230; program and test it.</p>
<h1>GameThread.c</h1>
<p>Here is the whole thread is here so you can copy/paste it into your file.</p>
<pre class="lang:c decode:true ">#include "GameThread.h"
#include "cy_tft_display.h"
#include "SystemGlobal.h"
#include "ugui.h"

/******************************************************
 *                      Macros
 ******************************************************/
#define UPDATE_SCREEN_TIME (20) // Update the screen every 20ms
#define SPEED (2)
#define SCREEN_X (320)
#define SCREEN_Y (240)
#define TOP_FIELD (21)
#define PD_WIDTH (10)
#define PD_LEN (70)
#define DOTS (3)
#define PADDLE0_COLOR (C_BLUE)
#define BALL_COLOR (C_GREEN)
#define BALL_SIZE (10)

/******************************************************
 *                    Constants
 ******************************************************/

/******************************************************
 *                   Enumerations
 ******************************************************/

/******************************************************
 *                 Type Definitions
 ******************************************************/
// States of the game
typedef enum {
    GS_SPLASH,
    GS_START,
    GS_RUNNING,
    GS_OVER
} game_state_t;

// Methods to move the paddle
typedef enum {
    PADDLE_INCREMENT,
    PADDLE_ABSOLUTE
} paddle_update_t;

/******************************************************
 *                    Structures
 ******************************************************/


/******************************************************
 *               Static Function Declarations
 ******************************************************/
static void UG_PutStringCenter(uint32_t x, uint32_t y, uint32_t fontx, uint32_t fonty,char *string);
static void displaySplashScreen();
static void displayStartButton();
static void  displayStartScreen();
static void displayScore();
static void displaySpeed();
static void endGame();
static inline uint32_t calcPaddleTop();
static inline uint32_t calcPaddleBottom();
static void updatePaddle(paddle_update_t type);
static void updateBall();
static void updateScreen(void *arg);

/******************************************************
 *               Variable Definitions
 ******************************************************/
static UG_GUI   gui;
static wiced_timer_t updateScreenTimer;

static uint32_t gameScore;
static game_state_t gameState;

// position of the paddle
static uint32_t paddle0_desire_pos=0;
static uint32_t paddle0_cur_pos=0;

// Position, direction and speed of the ball
static uint32_t ballx,bally;
static int32_t ballXdir, ballYdir;
static uint32_t ballSpeed;


/******************************************************
 *               Functions
 ******************************************************/

// ARH Function to put text in the center of a point (UG_PutString does upper left)
static void UG_PutStringCenter(uint32_t x, uint32_t y, uint32_t fontx, uint32_t fonty,char *string)
{
    y = y - fonty/2;
    x = x - (strlen(string)/2)*fontx;
    if(strlen(string)%2)
        x = x - fontx/2;
    UG_PutString(x,y,string);
}


// Display the splash screen
static void displaySplashScreen()
{
    gameState = GS_SPLASH;
    UG_FontSelect( &amp;FONT_22X36 );
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/5,22,36,"Cypress");
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/5*2,22,36,"Mouser");
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/5*3,22,36,"PSoC 6");
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/5*4,22,36,"WICED 4343");

    wiced_rtos_delay_milliseconds(2000);
}

// This function displays the start button message
static void displayStartButton()
{
    UG_FontSelect(&amp;FONT_12X20);
    UG_PutStringCenter(SCREEN_X/2 , SCREEN_Y - 30 ,12,22,  "Press B0 To Start");
}

// Display the Start Screen
static void  displayStartScreen()
{
    gameState = GS_START;
    UG_FillScreen( C_BLACK );
    UG_FontSelect( &amp;FONT_22X36 );
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/2 -2 - 18 ,22,36,"Ready");
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/2 + 2 + 18 ,22,36,"Player 1");
    displayStartButton();
}


// This function displays the score
static void displayScore()
{
    char buff[10];
    sprintf(buff,"%2X",(unsigned int)gameScore);
    UG_FontSelect(&amp;FONT_12X20);
    UG_PutString( 75, 0, buff);
}

// This function displays the speed
static void displaySpeed()
{
    char buff[10];
    sprintf(buff,"%2X",(unsigned int)ballSpeed-1);
    UG_FontSelect(&amp;FONT_12X20);
    UG_PutString( 275, 0, buff);
}


// This function initializes everything and starts a new game
static void startGame()
{
    gameScore = 0;

    paddle0_desire_pos = 50; // start the game with the paddle moving
    paddle0_cur_pos = 0;

    ballx = PD_WIDTH ;                   // start the ball on the paddle on the right of the screen
    bally  = calcPaddleTop() + PD_LEN/2; // start the ball in the middle of the paddle

    ballSpeed = SPEED;

    ballXdir = ballSpeed;
    ballYdir = ballSpeed;

    UG_FillScreen( C_BLACK );  // clear screen
    UG_FontSelect(&amp;FONT_12X20);
    UG_PutString( 0, 0,  "Score:");
    displayScore();
    UG_PutString(200,0,"Speed:");
    displaySpeed();
    UG_DrawLine(0,20,SCREEN_X,20,C_RED); // red line under text to represent top of play screen

    gameState = GS_RUNNING;
    wiced_rtos_start_timer(&amp;updateScreenTimer); // Timer to update screen
}

// Stop the game
static void endGame()
{
    gameState = GS_OVER;
    wiced_rtos_stop_timer(&amp;updateScreenTimer);
    UG_FontSelect( &amp;FONT_22X36 );
    UG_PutStringCenter(SCREEN_X/2,SCREEN_Y/2,22,36,"Game Over");
    displayStartButton();
}


// Figure out the y position of the top of the paddle
static inline uint32_t calcPaddleTop()
{
    return (paddle0_cur_pos)*DOTS+TOP_FIELD;
}

// Figure out the y position of the bottom of the paddle
static inline uint32_t calcPaddleBottom()
{
    return (paddle0_cur_pos)*DOTS+PD_LEN+TOP_FIELD;
}

// Move the paddle either to : PADDLE_INCREMENT the next location or PADDLE_ABSOLUTE - final location
static void updatePaddle(paddle_update_t type)
{
    // If the paddle is where it is supposed to be then just return
    if(paddle0_cur_pos == paddle0_desire_pos)
        return;

    // erase the current paddle
    UG_FillFrame(0,calcPaddleTop(),PD_WIDTH,calcPaddleBottom(),C_BLACK);

    switch (type)
    {

    case PADDLE_INCREMENT:

        if(paddle0_cur_pos &lt; paddle0_desire_pos)
            paddle0_cur_pos += SPEED;
        else
            paddle0_cur_pos -= SPEED;

        // If the paddle is within one move of the final spot, put it there
        if(abs((int)paddle0_cur_pos-(int)paddle0_desire_pos) &lt; SPEED)
            paddle0_cur_pos = paddle0_desire_pos;
        break;

    case PADDLE_ABSOLUTE:
        paddle0_cur_pos = paddle0_desire_pos;
        break;
    }
    // draw the paddle
    UG_FillFrame(0,calcPaddleTop(),PD_WIDTH,calcPaddleBottom(),PADDLE0_COLOR);
}

// Move the ball to the next location
static void updateBall()
{
    static const uint32_t BallFudgeFactor=3;

    UG_DrawCircle(ballx,bally,BALL_SIZE,C_BLACK);

    ballx += ballXdir;
    bally += ballYdir;

    // Check to see if the ball hit the far right side
    if(ballx &gt; SCREEN_X - BALL_SIZE)
    {

        ballx = SCREEN_X - BALL_SIZE;
        ballXdir = -ballSpeed;
    }

    // check to see if the ball hit the far left side... or the paddle
    if(ballx &lt; (BALL_SIZE + PD_WIDTH + BallFudgeFactor))
    {
        // See if the ball missed the paddle
        if(bally + BALL_SIZE &lt; calcPaddleTop() || bally - BALL_SIZE &gt; calcPaddleBottom())
        {
            endGame();
            //WPRINT_APP_INFO(("Missed Paddle\r\n"));
        }

        gameScore = gameScore + 1;
        displayScore();
        if(gameScore % 3 == 0) // Speed up every three hits
        {
            ballSpeed +=1;
            displaySpeed();
        }

        ballx = BALL_SIZE + PD_WIDTH + BallFudgeFactor;
        ballXdir = +ballSpeed;
    }
    // Check to see if the ball hit the top or bottom
    if(bally &gt; SCREEN_Y - BALL_SIZE) // bottom
    {
        bally = SCREEN_Y - BALL_SIZE;
        ballYdir = -ballSpeed;
    }

    if(bally &lt; TOP_FIELD+BALL_SIZE) // top
    {
        bally = BALL_SIZE+TOP_FIELD;
        ballYdir = +ballSpeed;
    }
    UG_DrawCircle(ballx,bally,BALL_SIZE,BALL_COLOR);
}

// This function is called every UPADTE_SCREEN_TIME milliseconds by the updateScreenTimer
static void updateScreen(void *arg)
{
    updatePaddle(PADDLE_INCREMENT);
    updateBall();
}


// Main game thread
void gameThread(wiced_thread_arg_t arg)
{
    game_msg_t msg;

    Cy_TFT_Init();                                             // Init the TFT
    UG_Init( &amp;gui, Cy_TFT_displayDriver, SCREEN_X, SCREEN_Y ); // Connect the driver

    UG_FillScreen( C_BLACK );   // Clear the screen
    UG_SetBackcolor( C_BLACK );
    UG_SetForecolor( C_WHITE );

    wiced_rtos_init_timer(&amp;updateScreenTimer,UPDATE_SCREEN_TIME,updateScreen,0);
    displaySplashScreen();
    displayStartScreen();

    while(1)
    {
        wiced_rtos_pop_from_queue(&amp;paddleQueue,&amp;msg,WICED_WAIT_FOREVER);
        switch(msg.evt)
        {
        case MSG_POSITION:
            if(gameState == GS_RUNNING)
                paddle0_desire_pos = msg.val/2;
            if(gameState == GS_OVER)
            {
                paddle0_desire_pos = msg.val/2;
                updatePaddle(PADDLE_ABSOLUTE);
            }
            break;

        case MSG_BUTTON0:
            if(gameState == GS_OVER || gameState == GS_START)
                startGame();
            break;
        case MSG_BUTTON1:
            break;
        }
    }
}
</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mouser-psoc6-wifi-bt-l4-the-video-game/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
