You are here

PSoC Creator News and Information | Cypress Semiconductor

Nov 20, 2017

Particle Photon Configuration with Tinker Firmware

In the last article I wrote about using a CY3280 MBR3 Shield on a WICED WiFI 943907AEVAL1F development kit at the GE MegaHackathon.  In the next article I will show you the WICED HTTP firmware that I wrote to connect to the Particle Photon which they were using (I have written about Particle Photon before).  Obviously, I like Particle Photon because it is a WICED 43362 WiFi Radio.  In this article, I am going to show you how to get a Particle Photon going with the Tinker firmware.  Then test it with the iOS app, the web console and finally using CURL.  The CURL is just a mechanism to send HTTP Posts to the Tinker firmware, exactly what I will do in the next article on the WICED development kit.

Configure the Particle Photon

When you get a fresh Particle Photon out of the box you need to get it introduced to your WiFi network, and attached to your console.  To do this, start by going to and following the process.

Particle Photon Configuration


Particle Photon Configuration


Particle Photon Configuration


Particle Photon Configuration


Particle Photon Configuration

Particle Photon Configuration

Particle Photon Configuration


Particle Photon Configuration


Particle Photon Configuration


Testing with iPhone App

One you have “claimed” your Particle Photon and it is connected to the network, then you can talk to it with the Particle iOS app.  Here is what it looked like when I started the App on my phone.  You can see the device called “iotexpert-example” (remember that is what I named it from above).  The “Elkhorn_creek” Photon is the one that I wrote about in this article.

Particle Photon iOS App

Although the console says that I have the Tinker Firmware on the app, I wanted to make sure, so I use the iOS App to re-flash the Tinker Firmware.  You can do this by clicking the new device, then press the little “…” at the top right of the screen.  Finally click “Reflash Tinker”. It is awesome how fast that happens.

Particle Photon iOS Flash Firmware


Once I am sure about the version of the Tinker firmware, I test to make sure that things are working correctly.  First I click on “D7”

Particle Photon iOS Tinker App


Which brings up this screen where you can select digitalRead and digitalWrite.

Particle Photon iOS Tinker App


Then when you press the button it will switch from high to low and vice versa.

Particle Photon iOS Tinker App


Particle Photon iOS Tinker App


You can also call the API directly by pressing “inspect” then “Data”

Particle Photon iOS digitalWrite Data Function

Particle Photon Console

In addition to using the iOS App, you can also interact with the Photon using the console.

Particle Photon Console


When I click on the “iotexpert-example” it brings up this screen where I can run the Tinker firmware functions.  In this case I ran “digitialwrite” with “D7,HIGH” which turns on the LED on the Photon.

Particle Photon Console


Testing the Particle Photon with CURL

The Particle Cloud exposes an API which lets you send Restful API requests to specific devices.  The Unix tool CURL lets me type command line requests (which I will mimic in the next Article using WICED).  The first command that I send is and HTTP GET which will return a JSON document that describes the configuration on my Photon.


You can see the device name etc in the JSON below.  It also shows that the Tinker firmware has four function built into it.


Then I can send a HTTP POST using Curl to turn on the D7 LED.

curl -d access_token=1311f67269d66b -d params=D7,HIGH

You can see the Blue LED right next to D7 turns on.

Particle Photon


Particle Photon Tinker App

I wondered where the Tinker App API was documented?  It turns out that the App is available in Particle library.  You can search by typing “tinker”.

Tinker App Documentation


The section of code that matters is here.  The function takes a “String” and parses it.  It demands that the 2nd character be a PIN number between 0 and 7.  The first character be a capital “D”.  Then you need to have a “HIGH” (in caps) or a “LOW” (in caps)

* Function Name  : tinkerDigitalWrite
* Description    : Sets the specified pin HIGH or LOW
* Input          : Pin and value
* Output         : None.
* Return         : 1 on success and a negative number on failure
int tinkerDigitalWrite(String command)
bool value = 0;
//convert ascii to integer
int pinNumber = command.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;
if(command.substring(3,7) == "HIGH") value = 1;
else if(command.substring(3,6) == "LOW") value = 0;
else return -2;
pinMode(pinNumber, OUTPUT);
digitalWrite(pinNumber, value);
return 1;
else if(command.startsWith("A"))
pinMode(pinNumber+10, OUTPUT);
digitalWrite(pinNumber+10, value);
return 1;
else return -3;

In order to access the digitalwrite function via the network, they publish it (and some others).

* All the based tinker functions are registered. You can add you own code.
// This #include statement was automatically added by the Spark IDE.
#include "Tinker.h"
void setup() {
//Register all the Tinker functions
Spark.function("digitalread", tinkerDigitalRead);
Spark.function("digitalwrite", tinkerDigitalWrite);
Spark.function("analogread", tinkerAnalogRead);
Spark.function("analogwrite", tinkerAnalogWrite);
void loop() {

When I first thought about the Tinker firmware I thought that it must be reasonably complex.  But it is not because it takes advantage of the Particle cloud functionality.  All in all what they did is very elegant and simple..

Now that it looks like my Particle Photon is working, in the next article I will show you WICED firmware to read the CapSense buttons and then Turn On/Off the LED on the Photon.

Nov 09, 2017

Barc Assembled

Barc (finally) got his nose back this week. I replaced the ugly yellow wire loops with some copper tape and added an Adafruit IR sensor that pokes out of his mouth. Subtle stuff! It is way easier to work on this guy now he is stretched out on one level. In my program I am going to detect the presence of a hand via the IR or CapSense sensors. I started with the new IR sensor, which is controlled via three wires.

Barc assembled...


The red wire is power and black is ground. I could just hook them directly to the power rails on the proto board but, since I may decide to turn the sensor on/off in future (and because I soldered a header to the wires), I am just connecting them to PSoC pins and will drive them from my program. The white wire is the analog input, which I am connecting to the PSoC ADC.

Barc ADC and I2C


The I2C component (set to 400kbps data rate) is there so that I can send the ADC data to the PC via the kitprog (more in a while). I configured the ADC to average out noise and give me a steady stream of results. I only need one single-ended channel with a range of 0.0V to 5.5V that returns an averaged result of 256 samples.

Barc ADC Configuration


I then chose pins P1[2], P1[3] and P1[4] for the sensor (ADC), ground and power respectively. The I2C goes on P4[0] and P4[1]. My design was ready and I just needed to write a little code. I was not sure how sensitive the sensor would be so I decided to use our Bridge Control Panel to plot the ADC values in real time. The following code turns on the IR sensor and sets up the ADC.

    Pin_IR_GND_Write( 0 );                              // Make sure ground is low
    Pin_IR_Power_Write( 1 );                            // Turn on the sensor
    CyDelay( IR_SENSOR_SETTLE_TIME );                   // Allow time for sensor output to be valid
    ADC_IR_Sensor_Start();                              // Turn on the ADC
    ADC_IR_Sensor_StartConvert();                       // Start sampling (free running)

This turns on I2C and sets it up to communicate across the kitprog I2C-USB bridge to the PC.

    #define I2CBUFSIZE  (2)
    static uint8 i2cbuf[I2CBUFSIZE];
    EZI2C_Start();                                      // Turn on I2C (over kitprog bridge)
    EZI2C_EzI2CSetBuffer1( I2CBUFSIZE, 0, i2cbuf );     // Set up the buffer for communication

I then put this code into the main loop. It just samples the ADC and writes the 16-bit values into the I2C buffer. The EZI2C component does the hard part - in the background it sends the buffer up to the Bridge Control Panel (BCP) software.

    int16 range = 0;                                    // ADC value

        /* Get an ADC value from the distance sensor and convert it to millivolts */
        if( ADC_IR_Sensor_IsEndConversion( ADC_IR_Sensor_RETURN_STATUS ) )
            range = ADC_IR_Sensor_GetResult16( IR_SENSOR_CHANNEL );
            range = ADC_IR_Sensor_CountsTo_mVolts( IR_SENSOR_CHANNEL, range );
            i2cbuf[0] = ( range >> 8 ) & 0xFF;
            i2cbuf[1] = ( range >> 0 ) & 0xFF;


Once I had this programmed I started up the BCP, selected the kitprog connection, and configured I2C to be 400kHz so that it matches the component speed. I was almost ready to look at the signal from the IR sensor. The PSoC sends 2 bytes and I needed to pack them back into a 16-bit value. So I created a variable, gave it the name "range", and made it 16-bits wide.

Barc EZ-I2C range variable setup


Back in the editor I write a command to read ('r') from address "08" into byte 1 "@1range" and byte 0 "@0range" of the range variable:

r 08 @1range @0range p

When I press the "Repeat" button and switch to the Chart view it shows me the ADC output in real-time.

Barc ADC sensing proximity


You can see that there is a floor of about 1800mV and that, as I moved my hand in and out of range, the value peaked at about 3300V. There are two peaks because I moved my hand from afar, all the way into Barc's nose, and then back out again. If you get too close the IR sensor goes "blind" and the voltage drops. This is really good information because I now know that I can detect the presence of a hand by simply comparing the ADC voltage with a value of about 1800V plus 100mV for safety. That's a simple piece of code that I will add in a week or so... when I re-tune the CapSense sensors and create a state machine for moving the dog around.

Unfortunately, as you may have guessed, Barc missed his flight to Shenzen for Maker Faire. There was a bit of a mix up about when he needed to be ready and after all the arguing stopped there was just a really disappointed dog. So we promised ot take him back to Germany for Embedded World next year...

Nov 06, 2017

CY3280 MBR3 & WICED CYW843807

[re-printed from]

In the last Article I talked about the GE Megahackathon. One of the groups at the event got interested in using a CY3280 MBR3 to send signals via a WICED CYW943907 to the Particle IO server which was connected to a Particle Photon.  I helped them with the implementation and thought that it would be useful to show here.

CYW3280 & WICED CYW943907


Cypress CY3280 MBR3

The CY3280 MBR development kit is a CapSense demonstration kit that shows the Mechanical Button Replacement 3 chip.  It features 4 CapSense buttons with LEDs, a proximity sensor, and a buzzer.  It is connected to another MCU via the Arduino pins. of the WICED CYW943907.  The device sits on the I2C bus and acts as an I2C Slave.  You configure it using EZ Click.

When you run EZ Click you can setup the configure the internal registers of the MBR3 to make the board act like a bunch of different things.  In this case I turned on

The MBR buttons 1-4 (you can see them in the picture above)
The Flanking Sensor rejection which makes it so that you can only press one button at a time.
All of the automatic tuning features.

EZ-Click CY3280


Once the main CapSense is configured, I moved to the other part of the configuration where I setup

The 4 LEDs to toggle and be full brightness when on
The buzzer to buzz for 100ms at 4kHz when something happens
The host interrupt pin as CS15/SH/HI.  This made the Arduino pin D2 be an interrupt when something happened so that WICED would poll the MBR3

EZ-Click CY3280


Once these settings were all done, I downloaded the firmware configuration via the KitProg USB connector.  Then I tested it using the bridge control panel which I have shown you a bunch of different times in the past.  The MBR3 acts as an I2C slave.  To find out what the state of the buttons are you need to read register 0xAA.  The only little trick is that the chip goes to sleep to save power.  In order to wake it up you need to send an I2C transaction, which ends up getting NAK’d.  But the next transaction you send will be ACKd.  In the screenshot below you can see that I tried two of the buttons (0x08 and 0x20)

Bridge Control Panel


One problem that I had is that the power system of this board is setup to take 5V from the Arduino base board but the WICED development kit gives only 3.3v.  Here is a picture of the power system from the MBR3 schematic.

CY3280 Power Supply


The MBR3 can run on 3.3Vs.  In fact it can run all the way down to 1.7v and up to 5.5v, but for some reason (which I can’t remember) we made the board only work with 5.0v.  To fix this problem I removed J12 and then wired a wire from the 3.3V Arduino pin.  The wire is soldered onto the 3.3v pin, but has a female connector on the other side so that it can be plugged into J12.  Here is a picture:



The last thing that I needed to do was move the jumpers to position “A” which made the host interrupt pin be connected to D2, and move the I2C jumpers so that the MBR3 was connected to the Arduino instead of the P5LP kitprog.  You can see that in the J3_scl and J3_sda in the picture above.


The CYW934907AEVAL1F is an development kit for the Cypress 43907 MCU+WiFi module.  The WICED CYW943907 board can do dual band (2.4 and 5Ghz), 802.11 a/b/g/n,  Ethernet and a whole bunch of other stuff.



The first firmware that I wrote in WICED Studio:

  • Sets up an ISR to unlock a semaphore when the interrupt occurs
  • Initialized WICED_GPIO_9 to be an input and connected to an ISR … this is also known as Arduino D2
  • Setup the I2C Master Hardware in the 43907
  • Wait for a semaphore (from the ISR)
  • Read the I2C register 0xAA from the MBR

The only trick in the firmware is that I read the I2C with a “do” loop until I get a valid result, meaning that the MBR3 has woken up.

#include "wiced.h"
#define I2C_ADDRESS (0x37)
#define BUTTON_REG (0xAA)
wiced_semaphore_t buttonPress;
/* Interrupt service routine for the button */
void button_isr(void* arg)
/* Main application */
void application_start( )
    wiced_init(); /* Initialize the WICED device */
    wiced_result_t result;
    // WICED_GPIO_9 is the MBR3 Interrupt Pin
    wiced_gpio_input_irq_enable(WICED_GPIO_9, IRQ_TRIGGER_FALLING_EDGE, button_isr, NULL); /* Setup interrupt */
    /* Setup I2C master */
    const wiced_i2c_device_t i2cDevice = {
            .port = WICED_I2C_2,
            .address = I2C_ADDRESS,
            .address_width = I2C_ADDRESS_WIDTH_7BIT,
            .speed_mode = I2C_STANDARD_SPEED_MODE
    /* Tx buffer is used to set the offset */
    uint8_t tx_buffer[] = {BUTTON_REG};
    uint8_t buttonStatus;
    while ( 1 )
        // Do this until the MBR3 is alive.  It goes into deep sleep and wakes when you
        // send the first command.
        do {
            result = wiced_i2c_write(&i2cDevice, WICED_I2C_START_FLAG | WICED_I2C_STOP_FLAG, tx_buffer, sizeof(tx_buffer));
        while(result != WICED_SUCCESS);
        result=wiced_i2c_read(&i2cDevice, WICED_I2C_START_FLAG | WICED_I2C_STOP_FLAG, &buttonStatus, sizeof(buttonStatus));
        WPRINT_APP_INFO(("Button State = %X\n", buttonStatus)); /* Print data to terminal */

Once that is programmed I program and test the firmware.

Testing WICED CYW943907


In the next article I will modify all of this firmware and make the WICED CYW943907 send data via HTTP to the Cloud.

Nov 03, 2017

Cypress development Kits and the GE Mega Hackathon

[re-printed from]

I spent this weekend attending the GE Mega Hackathon at GE FirstBuild.  First Build is a Maker Space-ish place in Louisville that is sponsored by GE and Louisville Speed School.  The Hackathon was called “Hack the Home” and was a two day thing where teams of makers built stuff for the house… generally by modifying GE white goods. Nicholas, my lab assistant, and I brought a bunch of Cypress Development Kits for people to use… then we helped them modify the kits to put them in their hacking projects.

Nicholas with the pile of Cypress Development Kits


Cypress Development Kits


At the table next to us were two guys from OnShape which is a cloud based 3-d drawing application.  It is super cool and free to use for non-comercial applications.  Nicholas is totally into 3-D printing and has been using Tinker CAD, which is cool… and free… but is still mostly a toy.  OnShape on the other hand is a fully featured pro package.  Philip, one of their applications engineers, helped Nicholas get going.

Nicholas & OnShape


I brought a bunch of different Cypress Development Kits, but what got people really interested was CapSense.  I had three different Capsense kits which fired peoples imagination…. first, the CY8CKIT-145 (which I have written extensively about) has three buttons and a slider… plus LEDs and a Bluetooth module on the back.



The CY8CKIT-024 Proximity shield which works with most any of the Pioneer kits.

CY8CKIT-024 Proximity Shield

And finally the CY3280 MBR3 development kit.  This has 4 capsene buttons, a buzzer and a proximity loop… in an Arduino shield format factor.  To talk to the shield you use I2C.

CY3280 Cypress Development Kit


What is really cool is that you don’t have to write firmware as you just configure it with EZ-Click.



Several people used it, including this guy who was talking to it with a Raspberry Pi.



One of the team used a CYW943907AEVAL1F talking to a CY3280 Capsense talking through cloud to a Particle Photon.  I helped them with the firmware, which I will go through in detail in the next article.

Nov 01, 2017

FreeRTOS PSoC Template Project

[re-printed from]

In the last article I showed you clever FreeRTOS PSoC Component… and the talked about some of the issues that I had with it.  In this article I will talk about a self-contained FreeRTOS PSoC Template project that includes everything for FreeRTOS and Tracealyzer all in one project.  My idea was that when I start a new project I will just make a copy of the template project, rename it, then move on.

My FreeRTOS PSoC Template has

  • FreeRTOS with the files in in the same directory (i.e. not referenced externally)
  • Tracealyzer with the files in the same directory & all of the streamports including RTT and the UART DMA
  • All of the files organized into PSoC Creator folders
  • A template main.c
  • All of the build settings configured

This project is checked into GitHub and you can find it

Building the FreeRTOS PSoC Template

I started the process by creating a blank PSoC project called “FreeRTOS_Template”.  I then went into the Windows Explorer and copied the entire FreeRTOS source directory into the FreeRTOS PSoC Template Project directory.  Then I copied the Percepio TraceRecorder library into the FreeRTOS PSoC Template project.

FreeRTOS PSoC Template Directory Structure

By having both of the source directories in my project it isolated this project from changes in the FreeRTOS or the TraceRecorder.  Obviously that is a double edged sword.  The next thing that I did was use the Windows Explorer to copy FreeRTOSConfig.h, trcConfig.h, trcSnapshotConfig.h and trcStreamingConfig.h into the project.   Once all of the files were in my project directory is was time to fix up the PSoC Creator Project.

To do this I created a folder called “FreeRTOS_Source” in the “Header Files” and “Source Files” folders in my template project.  You can do this by right clicking and selecting “Add->New Folder”.  Then I added all of the appropriate .h and .c files from FreeRTOS source directory.  This gives me the following project view:

FreeRTOS PSoC Template PSoC Creator Header Files

And Source Files (notice that I also added heap_4.c which I generally use for memory management)

FreeRTOS PSoC Template PSoC Creator Source Files

Then I add the configuration files FreeRTOSConfig.h, trcConfig.h, trcSnapshotConfig.h, trcStreamingConfig.h and trcStreamingport.h.  Next I do the same thing for the TraceRecorder library which makes my project look like this:

FreeRTOS and Tracealyzer Configuration Files

Then I modify the build settings to add the include directories:

FreeRTOS PSoC Template Build Settings

FreeRTOS PSoC Template PSoC Creator Include Path

Now you can modify the FreeRTOSConfig.h to include all of the Tracealyzer stuff:

/* A header file that defines trace macro can be included here. */
#if ( configUSE_TRACE_FACILITY == 1 )
#include "trcRecorder.h"
#endif /* FREERTOS_CONFIG_H */

Then I setup a new tab in the schematic to contain the DMA UART Streamport.  You can read all about the UART DMA Streamport in this article.

FreeRTOS PSoC Template PSoC Creator Streamport Schematic

By putting that part of the stream port on a separate schematic page I can now do a right click and disable the page when I am not using the Tracealyzer streamport.  Disabling a page of the schematic completely removes everything from the build.

PSoC Creator Schematic Disable Settings

Next I create files called FreeRTOS_Start.h/.c to put in the startup code:

#include <project.h>
#include "FreeRTOS.h"
extern void xPortPendSVHandler(void);
extern void xPortSysTickHandler(void);
extern void vPortSVCHandler(void);
#define CORTEX_INTERRUPT_BASE          (16)
void FreeRTOS_Start()
    /* Handler for Cortex Supervisor Call (SVC, formerly SWI) - address 11 */
        (cyisraddress)vPortSVCHandler );
    /* Handler for Cortex PendSV Call - address 14 */
        (cyisraddress)xPortPendSVHandler );    
    /* Handler for Cortex SYSTICK - address 15 */
        (cyisraddress)xPortSysTickHandler );

Finally I make a template main.c that starts everything and has a simple ledTask and instructions for changing Memory Management scheme and the TraceRecorder.

// This template has heap_4.c included in the project.  If you want a
// different heap scheme then remove heap_4 from the project and add
// the other scheme from FreeRTOS/Source/portable/memmag
// TraceRecorder
// There are methods
// 1. Snapshot mode
// 2. Streaming UART/DMA
// 3. Streaming JLINK RTT
// To use method 1:
// - in FreeRTOSConfig.h make this line be 1 (currently line 45)
//#define configUSE_TRACE_FACILITY                1
// - in trcConfig.h configure the TRC_CFG_RECORDER
// To use method 2:
// - in FreeRTOSConfig.h make this line be 1 (currently line 45)
//#define configUSE_TRACE_FACILITY                1
// - in trcConfig.h configure the TRC_CFG_RECORDER
// This project currently has the PSoC UART Streaming Port
// add the TraceRecorder/streamports/PSoC_Serial/trcStreamingPort.c to the project
// add the TraceRecorder/streamports/PSoC_Serial/include/trcStreamingPort.h
// add the TraceRecorder/streamports/PSoC_Serial/include to the compiler include directories
// Enable the Trace_DMA schematic sheet and make sure UART pins are assigned correctly
// This port depends on the UART being named UART and the DMA being named "DMA"
// To use method 3: JLINK RTT
// Remove the previous streamport files from the project
// Remove the Streamport include path
// add the TraceRecorder/streamports/JLink_RTT/Segger_RTT.c to the project
// add the TraceRecorder/streamports/JLink_RTT/Segger_RTT_Printf.c to the project
// add the TraceRecorder/streamports/JLink_RTT/include/trcStreamingPort.h
// add the TraceRecorder/streamports/JLink_RTT/include/Segger_RTT.h
// add the TraceRecorder/streamports/JLink_RTT/include/Segger_RTT_Conf.h
// add the TraceRecorder/streamports/JLink_RTT/include to the compiler include directories
#include "project.h"
#include "FreeRTOS.h"
#include "timers.h"
// An example Task
void ledTask(void *arg)
int main(void)
    #if ( configUSE_TRACE_FACILITY == 1 )
    xTaskCreate(ledTask,"LED Task",configMINIMAL_STACK_SIZE,0,1,0);
    vTaskStartScheduler();  // Will never return
    while(1);               // Eliminate compiler warning



Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.