Using mBed to create a simple MQTT application which logs ambient light sensor data to the AWS IoT Cloud
This project takes a look at using one of the two Cypress PSoC 6 wireless kits to connect to the AWS IoT cloud. Using MQTT with TLS, we then publish some data collected from a light sensor. The project goes step-by-step over getting AWS IoT set up (not an easy thing without instructions!) as well as modifying the example code Cypress provides to publish our collected data.
Amazon Web Services (or AWS) is a massive suite of services, including cloud servers, databases, DNS, machine learning, even quantum computing! Plus the service that is especially interesting to us -- IoT. Go poke around on their front page, and you'll see just how many services they offer. It's truly mind-boggling.
While you're there, you can either create a new account, or you should be able to log in with your existing Amazon account credentials. Don't worry about costs yet -- AWS has their Free Tier which gives very reasonable limits you can use to try out their products. Some of these are limited to 12 months, including IoT, but it includes 250 000 MQTT messages per month, 3 devices (or "things"), 50 device commands per month (this includes device creation and remote management, which we won't be using), as well as 2 500 events per month (events are automatic reactions to messages that are sent from your things) and access to their graphing service. Pretty neat! If you plan to use it after 12 months, the prices are quite low, and there are other services besides AWS that are free -- but often they don't support TLS, and having the integration with other AWS services is nice.
The downside of AWS, especially for first-time users, is its inherent complexity. Many of their services are tied together, and they often offer confusingly similarly named services that do different things. AWS really is targeted at enterprise users -- but that doesn't mean hobbyists can't use it too! You just need to be prepared to approach things in a methodical way.
Side note: if you are joining AWS for the first time, be sure to check out the other services offered, especially the 12 months of a cloud server for free.
Create your AWS IoT Thing
Now that you are logged in, head over to the AWS Management Console. At the top, click Services, and scroll down until you see Internet of Things on the right hand side. Click on IoT Core.
On the left hand side, click Manage, and then click Create in the upper right. Choose "Create a Single Thing" and then give it a name. You can safely ignore everything else on this page for now. Scroll down and click Next.
The next page shows certificate creation options. AWS IoT is only accessible via TLS, meaning we have to deal with private keys and certificates. If you were starting from scratch, this would be quite the speed bump, but luckily mbed and Cypress have provided excellent example code and libraries. Choose the top option, One-click Certificate Creation.
Super important note! The next page that shows up will only ever be shown once, as a security measure. Make sure to download all three files: certificate, public key, and private key. After you have downloaded them, click the Activate button.
Next is a super-important step that I skipped when I first started working on this project, and it caused me hours of headaches thinking something completely different was wrong. Click Done, which should take you to the details page for your newly created Thing. Click the grey back arrow in the upper left hand corner.
Now we need to create a policy and attach it to the thing we just created (remember when I warned you about how AWS is targeted for enterprise usage? Now you can see I wasn't kidding!). On the main IoT Core page, click Secure in the left-hand menu. This will open a sub-menu where you can see the certificate we just created. Below Certificates, click on Policies, and then click on Create in the upper right. Give it a name like "Open". In the statements section below the name, enter iot:* as the action, and * as the resource ARN. Check off Allow, and then click Create at the bottom right.
Now go back to the Certificates sub-menu, and click the three dots in the certificate box. Choose Attach Policy, check off the policy we just created, and click Attach! Now we are finally ready to cloud surf.
If you click the Import into Compiler button in the top left, it will copy that code into your mbed workspace. This example contains two different programs, one for publishing and one for subscribing. For this example we will only be publishing, and the compiler seemed to get confused with both folders present, so I deleted the subscriber folder.
Note: If you end up using the mbed command-line tools instead, it's not necessary to delete the subscriber folder. Simply issue the command "mbed config root ." It's also helpful to set the board you are using, which you can do with "mbed target cy8cproto_062_4343w" or "mbed target cy8ckit_062_wifi_bt". Note these names use underscores, not hyphens!
The first and most critical step to getting this example working is to set up your AWS credentials in the aws_config.h header file. I will go through each item in this file, and explain exactly what you need to put in each.
AWSIOT_ENDPOINT_ADDRESS: This is the actual address that your thing will communicate with. You can find it in the IoT panel by clicking on Manage, then clicking on your Thing. Select Interact from the left-hand menu, and then copy and paste the URL under the HTTPS heading. It will end in .amazonaws.com
AWSIOT_THING_NAME: This is the human-readable name you gave your thing when creating it back in step 2. I just called mine "Cypress" but just make sure it matches whatever name you gave it in AWS.
AWSIOT_TOPIC: This is the name of the topic it will publish to. This can be anything you like, as long as you remember it!
const char SSL_CLIENTCERT_PEM: This is the certificate file that we downloaded earlier. It needs to be formatted in a particular manner, as shown in the example section. Copy and paste the entire file between the quotes, and then format it as shown. You will need to put quotes around each line, as well as add \n to the end of each line. You also need a backslash as the last character on the line. I will include a redacted screenshot of what mine look like.
const char SSL_CLIENTKEY_PEM: This is the private key file that we downloaded. It needs to be formatted exactly as above.
The last thing we need to do before launching the example code is adding our Wi-Fi credentials to the mbed_app.json file. Replace the SSID and password with your details, making sure to leave the escaped quotes in place. It should look like this:
With all that inserted, you should be able to compile the example code. This will create a .hex file that will be automatically downloaded. Save it somewhere, and then plug your board in to your PC. If your board does not show up as a USB drive, read the instructions below on how to get your board's firmware updated. Otherwise, drag the downloaded .hex file into the USB drive that appears, and the firmware will self-program.
Cypress have released a tool to update the firmware on their boards. By default, these boards come with KitProg2 installed, but we need KitProg3. Download the latest release from their GitHub repository depending on which OS you run, and unzip it. Connect your board, and navigate to the bin/ folder inside the extracted folder. Run
and allow it to finish. Once this is complete, you can either push the button on the programmer portion of the board labelled "MODE" to get it into DAPLINK mode. Or, you can simply run
and it should appear as a USB drive. From now on, all you need to do to update the code running is simply drag and drop the downloaded .hex file into the USB drive. It will automatically self-program and then delete the .hex from the USB interface.