Official Blog of Silicon Labs

    Publish
     
      • Chapter 6 Addendum: Input Modes Explained - Part 1

        lynchtron | 04/115/2017 | 06:27 PM

        ch6_addendum.png

         

        NOTE: This is an addendum to chapter 6, so it appears out-of-order on the blog.  It covers input modes that may not be covered anywhere else in the blog series. 

         

        So far, we have only used the digital input mode of the GPIO peripheral to detect a button press.  In those cases, the pin was used to provide information if the button was pressed or not pressed.  A voltage was present or it wasn’t present.  In this chapter, we will use other peripherals that are capable of detecting input signals, including analog voltages and pulses.  We can use these inputs to measure an external voltage source, or the light intensity of a light source, for example.  There are digital input peripherals that go beyond simple edge detection and can be used to count pulses, which can then be used to tell us the position or speed of rotation of a shaft.

         

        This chapter aims to give you a little background into the many different ways your EFM32 MCU can sample input values.  You will learn how to pick the right peripheral for the task at hand.

        Note that many of the peripherals in the EFM32 family include input pins such as I2C, USART, UART, etc.  Those peripherals are covered elsewhere, but keep in mind that is possible to use just the input pin from, say, a USART (the RX pin) and not make any use of the TX pin.  In addition, there are specialized input methods for OPAMP and LESENSE that are beyond the scope of this chapter.

         

        Setup Your Project for Serial Wire Output (SWO) Console Display

        Before we start experimenting with input modes, let’s set up a debug console to view the results of our experiments.  In the prior chapters, the only way to see evidence of anything happening on the Wonder Gecko Starter Kit as a result of our code was to blink an LED or examine the values of variables in Simplicity Studio’s watch window.   There is, however, a built-in console in the Simplicity Studio IDE that can make use of the standard debugging interface that you use to transfer programs to the EFM32.  This is called Serial Wire Output (SWO) and it uses the serial port protocol.  We don’t need to dive into how serial communication works in this chapter.  We will simply make use of it for displaying simple debug messages to the Simplicity Studio console through standard C library printf statements.

         

        The following code can be used in any project to send printf statements to the Simplicity Studio IDE output console.

         

        #include "em_device.h"
        #include "em_chip.h"
        #include <stdio.h>
         
        int _write(int file, const char *ptr, int len)
        {
            int x;
            for (x = 0; x < len; x++)
            ITM_SendChar (*ptr++);
            return (len);
        }
         
        void SWO_SetupForPrint(void) {
            /* Enable GPIO clock. */
            CMU ->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
            /* Enable Serial wire output pin */
            GPIO ->ROUTE |= GPIO_ROUTE_SWOPEN;
            #if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_LEOPARD_FAMILY) ||         
        defined(_EFM32_WONDER_FAMILY) || defined(_EFM32_GECKO_FAMILY)         /* Set location 0 */         GPIO ->ROUTE = (GPIO ->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) |    
        GPIO_ROUTE_SWLOCATION_LOC0;         /* Enable output on pin - GPIO Port F, Pin 2 */         GPIO ->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);         GPIO ->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;     #else         /* Set location 1 */         GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) |
        GPIO_ROUTE_SWLOCATION_LOC1;         /* Enable output on pin */         GPIO->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE15_MASK);         GPIO->P[2].MODEH |= GPIO_P_MODEH_MODE15_PUSHPULL;     #endif     /* Enable debug clock AUXHFRCO */     CMU ->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;     /* Wait until clock is ready */     while (!(CMU ->STATUS & CMU_STATUS_AUXHFRCORDY)) ;     /* Enable trace in core debug */     CoreDebug ->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;     ITM ->LAR = 0xC5ACCE55;     ITM ->TER = 0x0;     ITM ->TCR = 0x0;     TPI ->SPPR = 2;     TPI ->ACPR = 0xf;     ITM ->TPR = 0x0;     DWT ->CTRL = 0x400003FE;     ITM ->TCR = 0x0001000D;     TPI ->FFCR = 0x00000100;     ITM ->TER = 0x1; } int main(void) {     SWO_SetupForPrint();       printf("hello world!\n");       while (1)     {     } }

        Note that printf formatting (%f) is not supported by default.  To enable it, you must check the box "print floats" in Project > Properties > C/C++ Build > Settings >  GNU ARM Linker > General.

        Also, note that the SWO console will not display anything until it finds a “\n” in your message string!

         

        Keep in mind that you should use the printf statement sparingly.  The statements take time to run and it can disrupt the timing in your code.  Use them only during basic debugging and only during sections of code that have no timing constraints.
         
        General Purpose Input Output (GPIO)

        6_gpio.png

        The most obvious peripheral in the MCU that can sample input pins is the GPIO.  The GPIO input modes can detect if a voltage is closer to ground or VCC and can trigger interrupts on positive or negative edges.  There are filters available to clean up glitches, and pullups and pulldowns to bias the pin high or low in the absence of external drivers.  The GPIO is the easiest input peripheral to configure and use, but should only be used for DC or low-frequency signals, perhaps under 1kHz or so.  Sampling the GPIO constantly consumes power, and interrupting the MCU on every edge requires software to take action, which keeps your software busy.  There are hardware peripherals that can automate the faster signals for you, which is what we will learn about in this chapter.

         

        The following is all that is required to start sampling the state of external GPIO pin PA1.  Note that there are pullups, pulldowns, and filters available for the input mode that can be specified instead of gpioModeInput.

         

        CMU_ClockEnable(cmuClock_GPIO, true);
        GPIO_PinModeSet(gpioPortA, 0, gpioModeInput, 0);
        bool input_state = GPIO_PinInGet(gpioPortA, 1);

        More details about the GPIO peripheral can be found in Application Note AN0012 General Purpose Input Output.


        Analog to Digital Converter (ADC)

        6_adc.png

        While the GPIO is a digital input pin, generating a value of either 0 or 1, the Analog to Digital Converter (ADC) can differentiate 4096 digital levels between ground and VCC, thanks to its 12-bit resolution.  The The ADC is available in all models of the EFM32 family of MCU’s including the Wonder Gecko.  (There are a few of the low-pin-count models that omit the ADC.)  The ADC translates the voltage present on the input pin into a digital value at a rate up to 1 million samples per second.  The ADC can therefore sample complex waveforms such as audio for processing by the MCU. 

         

        There are eight input channels that can be connected to the ADC on the Wonder Gecko, each of which must be used one at a time.  Some inputs can be used in a differential manner, where one pin is the positive input and another ADC pin is the negative input, instead of using ground as the negative input. 

         

        To demonstrate the operation of the ADC, we can use the ambient light sensor on the Starter Kit.  The light sensor is a transistor with the base voltage controlled by light, and it varies between 0V and 2.5V with a pulldown to ground through a 22k-ohm resistor.

        6_light_sense.png

        The light sensor is connected to the EFM32 on the starter kit to pins PD6 (for excitation, a DC voltage) and PC6 as an input to ACMP0.  (Keep this in mind whenever you are using these pins on the Starter Kit for another purpose!)  We can use a wire jumper to connect PC6 (pin 17 on the expansion header) to ADC channel 0 on PD0 and then measure the voltage generated by the light sensor in the ADC. 

        6_adc_light_sensor.png
        The following code configures the ADC for light sensing.

              CMU_ClockEnable(cmuClock_GPIO, true);
              CMU_ClockEnable(cmuClock_ADC0, true);
         
              // Set the sample rate of ADC0
              ADC_Init_TypeDef       init       = ADC_INIT_DEFAULT;
              init.timebase = ADC_TimebaseCalc(0);
              init.prescale = ADC_PrescaleCalc(7000000, 0);
              ADC_Init(ADC0, &init);
         
              // Set up the ADC0 on channel0 (PD0) single-ended, referenced to 2.5V internal reference
              // Note that PD0 must be wire jumpered to PC6, since the light sensor is connected to PC6 on the starter kit
              ADC_InitSingle_TypeDef sInit = ADC_INITSINGLE_DEFAULT;
              sInit.input = adcSingleInputCh0;
              sInit.reference = adcRefVDD;
              sInit.acqTime = adcAcqTime32;
              ADC_InitSingle(ADC0, &sInit);
         
              // Excite the light sensor on PD6
              GPIO_PinModeSet(gpioPortD, 6, gpioModePushPull, 1);

         

        Note that using the VDD as a reference means that the ADC readings will change as VDD changes, for example, as your battery drains.  It would be better to measure against the 2.5V or 1.25V internal references which do not change as VDD voltage changes.  This would then require your input signal to be scaled with a voltage divider.  In our example on the Starter Kit, VDD will remain stable at 3.3V, so we don’t need to take that step.

         

        Once the ADC is configured, we can set up a timer to trigger an interrupt once a second, which was first explained in chapter 5. We will restart this timer after every ADC sample.

        #define ONE_SECOND_TIMER_COUNT            13672
        CMU_ClockEnable(cmuClock_TIMER1, true);
         
              // Create a timerInit object, based on the API default
              TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
              timerInit.prescale = timerPrescale1024;
         
              TIMER_IntEnable(TIMER1, TIMER_IF_OF);
         
              // Enable TIMER0 interrupt vector in NVIC
              NVIC_EnableIRQ(TIMER1_IRQn);
         
              // Set TIMER Top value
              TIMER_TopSet(TIMER1, ONE_SECOND_TIMER_COUNT);
         
              TIMER_Init(TIMER1, &timerInit);
         
              // Wait for the timer to get going
              while (TIMER1->CNT == 0)
                    ;

         

        The TIMER1 interrupt handler must be implemented to stop the timer once it triggers an interrupt and stop the timer from counting further.  As a reminder, this small function can appear anywhere in your source code, since it is declared in the EFM32 libraries and implemented in your source code.

        void TIMER1_IRQHandler(void)
        {
              TIMER_IntClear(TIMER1, TIMER_IF_OF);
              TIMER1->CMD = TIMER_CMD_STOP;
        }

         

        Finally, we can pull it all together in the main function while loop.

         

              uint32_t value;
              uint32_t last_value = 9999; // Impossible ADC value
              uint32_t sample = 0;
              while (1)
              {
                    // Start an ADC aquisition
                    ADC_Start(ADC0, adcStartSingle);
         
                    // Wait for the measurement to complete
                    while ( ADC0->STATUS & ADC_STATUS_SINGLEACT);
         
                    // Get the ADC value
                    value = ADC_DataSingleGet(ADC0);
         
                    // Only print if the value has changed
                    if ((value + ADC_NOISE) < last_value || (value - ADC_NOISE) > last_value)
                    {
                          float voltage = value * 3.3;
                          voltage /= 4096.0;
         
                          // NOTE: To get floating point printing to work, you must enable "print floats" check box in:
                          // Project > Properties > C/C++ Build > GNU ARM Linker > General
                          printf("Sample #%3d ADC:%4d Voltage:%3.2f\n", (int) sample, (int) value, voltage);
                    }
         
                    last_value = value;
                    sample++;
         
                    // Wait a second before the next ADC sample
                    TIMER1->CNT = 0;
                    TIMER1->CMD = TIMER_CMD_START;
         
                    // Sleep until the timer expires.
                    EMU_EnterEM1();
              }

        When you run this code, you will first see the ambient light as expressed as an ADC reading and as a calculated voltage.  As a flashlight is brought to the light sensor, the reading will change to reflect the difference in light intensity.

         

        Chapter 6: Input Modes!
        Sample #  0 ADC: 538 Voltage:0.43  << Room ambient light condition
        Sample #  4 ADC: 500 Voltage:0.40
        Sample #  8 ADC:1250 Voltage:1.01  << Light approaching the sensor
        Sample #  9 ADC:3241 Voltage:2.61
        Sample # 10 ADC:3954 Voltage:3.19  << Light held close to sensor
        Sample # 16 ADC:1166 Voltage:0.94
        Sample # 17 ADC: 461 Voltage:0.37  << Back at ambient lighting

         

        IMPORTANT NOTE: DO NOT connect any ADC pin to the 5V pin on the Wonder Gecko Starter Kit!  The pins on the EFM32 are not capable of tolerating values higher than VCC + 0.3V.  If you input a voltage higher than that, you can permanently damage the input pin.  There is a “5V Reference” in the differential mode of the ADC, but this does not mean that the voltage on a single pin can exceed VCC!

         

        In the test above, the ADC was only called on to perform one sample per second.   However, the ADC is capable of up to 1 million samples per second, and can therefore be used to perform complex signal analysis on analog signals.  Those techniques are beyond the scope of this chapter.

         

        To save power during sleep states, the ADC needs to be stopped before entering energy modes EM2 or EM3 with the WARMUPMODE bit cleared in the ADC CTRL register.

         

        More details about the ADC peripheral can be found in Application Note AN0021 Analog to Digital Converter.

         

        In the next section, we will configure the Analog Comparator (ACMP) to level-shift the detected LED pulse from a weak signal to one that can be used as normal input logic to the MCU.

         

      • Bringing Plug-and-Play Simplicity to Your Next Audio Design with the CP2615 USB-to-I2S-Bridge

        RamyaK | 04/109/2017 | 05:00 PM

        Looking to develop a new USB audio accessory? Need to get that to market quickly? No worries. We’ve got you covered. USB system development often involves significant protocol expertise, design effort, and cost for proper implementation. Additionally, USB audio development requires sophisticated clock synchronization which poses further development challenges. To address these needs, and to get your products to market faster, we’re introducing a highly integrated fixed-function USB-to-I2S bridge device, the CP2615.

         

         

        The CP2615 USB-to-I2S bridge device is designed for rapid development of USB-based audio applications such as USB headphones, headsets, speakers, and other accessories. These devices simplify the process of transferring audio data from USB to I2S without the need for any complex protocol expertise or time consuming code development. The CP2615 includes a USB 2.0 full-speed function controller, USB transceiver, oscillator, I2S (audio) interface and I2C (control) interface in a compact 5x5 mm QFN32 package ideal for space constrained applications.

         

        The device also provides built-in support for USB digital audio streaming and HID user-interface functions for transport control buttons, and is designed to operate with any USB host that supports USB Audio Class 1.0, so no driver installation is required.

         

         

        To simplify development and to provide more flexibility to audio designs, the CP2615 devices are also supported by a simple GUI based Xpress configurator tool within Simplicity Studio. The CP2615 device has a number of properties that can be selected and configured as per the application needs. Download the application note AN1044: CP2615 Customization Utility User Guide for more information on the configuration options.

         

          

        To help you get started with your next design with CP2615, we also designed the CP2615 digital audio bridge evaluation kit CP2615-EK. This comprehensive kit includes everything to evaluate and develop with CP2615 device.

        CP2615-USB-to-I2S-Bridge-EVB copy.png

        You can order a CP2615-EK here. To learn more about digital audio or CP2615, click here

         

      • IoT Hero Braingrid is Redefining Power for the Future

        deirdrewalsh | 04/107/2017 | 10:08 AM

        Braingrid_Banner.jpg

         

        IoT Hero Braingrid is Redefining Power for the Future

        Michael Kadonoff is the CEO of Braingridand we recently had the opportunity to talk to him about how his company is helping customers rethink energy consumption. Based in Canada since 2012, Braingrid designs and manufactures advanced digital communication devices and software systems for clients in the energy and agriculture sectors, including renewable power providers; and energy management, operation, maintenance, and auditing/retrofit personnel. Braingrid was recently honored as an IoT leader at the IoT Evolution Conference & Expo in Ft. Lauderdale.

         

        What’s really at the heart of what Braingrid offers?
        I would say the biggest thing to know about us is that Braingrid is not just a hardware vendor. We are a platform that provides a smart grid–connected solution that lets you thoroughly monitor and manage system devices within the IoT while reducing costs, saving time, and increasing reliability, scalability, and overall system performance.

         

        The other detail I think people should know about us is that we’re really passionate about IoT devices being truly free from having to plug back in for recharging or constantly changing batteries. We want devices to be deployed…and that’s it. You’re done; you’re not going back to worry about power—true energy reform. Because ultimately the IoT is really about two things: collecting data and then controlling that data. And I feel when you have to plug back in, you lose 80 percent of the IoT opportunity. It’s about transforming energy usage in the IoT to us.

         

        For instance, our new Sentroller device is self-powered and doesn’t even have a replaceable battery, and it can be deployed anywhere in the world—from harsh environments to your home. It’s a product we designed for any IoT application. We’ve recently focused on precision agriculture (PA) applications because our platform simplifies the collection of crop data and lets growers reduce growing risk, improve yield, and increase profitability. The Sentroller also gives real-time data and lets the growers feed plants only what they need, only when they need it. And across a massive farming complex, there’s no running around recharging devices, replacing batteries or managing Internet connections after it’s installed. The solution just works and the data flows uninterrupted.

         

        Sentroller dirt.jpg

         

         

        So what was the impetus for creating Braingrid? Was it in response to a particular problem in the industry or a personal interest, or something else altogether?
        I initially founded Braingrid to help businesses and individuals reduce the energy waste/consumption to bring about energy reform. While this is a lofty goal, the first step along this route was to figure out a way to measure energy consumption, equipment statuses, and operational behaviors in an easy and inexpensive way. We addressed this need by inventing both a device and software platform to accomplish gathering this difficult-to-get data. Braingrid delivers on the fundamental principles of IoT: revealing every thing’s voice, one sensor at a time.

         

        Ops Dashboard.jpg

        Can you walk us through a typical application and how the end customer uses it to make their lives easier? It looks like energy management was critical; would it be possible to give an example of how plugging a device back in to recharge would hamper efforts?
        Precision agriculture means that farmers must adopt even more effective methods for producing yield with their existing and new machinery. Braingrid’s solution offers a way to measure any sensor’s value over long distances (typically 10+ miles), using the patent-pending Sentroller device which requires no power connections. Imagine having a device that is rated for 10 years of life without the need to change batteries. Sentrollers are shipped with industry-specific, kitted sensors that connect without tools and are delivering real-time data about soil, watering levels, light levels, and air quality metrics to farmers/growers within minutes. Best of all, the sensors themselves are often the power source; the sensor’s small output power is harvested by the Sentroller. Power autonomy eliminates the expense and effort to hire electricians, skilled trades, integrators, and so on. Having power autonomy means that Sentrollers can be placed nearly anywhere: outdoor fields, service rooms, grain silos, livestock areas, etc. Sentroller gathers this data on its own and relays it to Braingrid's secure cloud network and shows valuable information to the farmer on a smartphone or other device.

         

        Grower Dashboard Main.jpg

        Are there crops that are more conducive to this tool than others?
        Braingrid’s solution applies to thousands of verticals. Inside the Precision Agriculture vertical, there are “high value crops” which have indoor and outdoor applications. We are currently focused on high-value crops grown indoors such as fruits, vegetables, and medical cannabis. The main goal is to deliver real-time indicators about soil, air, and nutrient and light conditions because these factors are tied to plant yields. However, Braingrid’s solutions also identify cost drivers that hit the bottom line too by monitoring the entire facility. For example, energy consumption and time of use, motor/equipment predictive failure, and the rigorous regulatory compliance environment established by health authorities in the medical cannabis industry make this information critical to achieve high crop yield while avoiding crop losses.

         

        Finance Dashboard.jpg

         

        What Silicon Labs’ product are you using at Braingrid, and why did you go with it?
        We’re fond of the Wonder Gecko; our Sentroller exploits everything it’s got. The Wonder Gecko strikes a balance between a powerful processor and a focus on power management. Also, I personally come from an engineering background and had roles where I really had to break and stress my products to their limits. Anything we construct at Braingrid doesn’t just have to deliver value in a variety of environments, it has to last 10+ years as well! The Wonder Gecko meets our durability standards and at a great value.

         

        And finally, Michael, our IoT Heroes Bonus Question: Where do you see the IoT heading in the next 5–8 years in your opinion?
        I think we will finally start to see truly agnostic hardware layers to house wireless protocols—a real departure from the gamut of protocols and standards that the IoT initially started with. That of course will lead to true interoperability and design freedom. I’m also specifically thinking of universal radio or software-defined radio. We’ve gotten used to software-defined networks; we need to be ready for the idea of software-defined radio that can revolutionize application possibility. That’s where things are heading.

      • Detecting User Input with Capacitive Touch and Passive Infrared (PIR) - Part 3

        lynchtron | 04/101/2017 | 12:21 AM

        15_title.png

         

         

        In part 2, we configured the host computer with Python and pyqtgraph.  You should now be able to do some great things with those tools.  We are now ready to build a Python script that fetches data from the serial port and displays the data to a graphing window.  You can see this full file Scrolling.py in Github.

         

        The first thing that we do in the script is import the libraries that we need to do most of the work for us:

        import pyqtgraph as pg 
        from pyqtgraph.Qt import QtCore, QtGui 
        import serial 

        Next, the script opens the serial port.  Note that on a Windows computer, the serial port that pySerial expects is the COM port minus one.  In my case, it uses COM3, so I pass in “3 -  1” to pySerial.  Edit this first line as necessary to match the port on your computer.

        # Set up serial port attached to Wonder Gecko 
        # Your computer may instantiate port numbers differently. 
        port = 3  - 1   # -1 is for Windows 
        baudrate = 115200 
        serial_port = serial.Serial(port, baudrate=baudrate, timeout=0) # 0 for timeoutNonblocking 
        serial_port.flushInput() 

        Then, we will set some configuration options and create a pyqtgraph plot, curve, and curve pen.

        # Switch to using white background and black foreground 
        pg.setConfigOption('background', 'w') 
        pg.setConfigOption('foreground', 'k') 
        
        # Create a pyqtgraph window object 
        win = pg.GraphicsWindow() 
        win.setWindowTitle('Capcitive sense plot') 
        
        # Create a plot inside the window 
        plot = win.addPlot() 
        
        # Create a list of 300 zeros (initially) to hold the streaming data 
        data = [0 for x in range(300)] 
        
        # Create a "pen" that is width of 1 and blue color 
        curve_pen = pg.mkPen(width=1, color='b') 
        
        # Creata "curve" that uses the curve_pen, with data points (symbols) that are filled and outlined with blue 
        curve = plot.plot(data, pen=curve_pen, symbolBrush='b', symbolPen='b', symbolSize=5) 
        
        # Createa place to store the incoming serial port characters 
        value_string = "" 

        We now need an “update” function.  This is the function that will be called from the Qt library to update the active window.  This function will read data from the serial port and then shift the data structure to the left in order to scroll the graph on the screen.

         

        # Define a function that will be called by pyqtgraph periodically to update the screen 
        def update(): 
            # Tell Python that these variables are to be tied to the outside global scope 
            global data, curve, value_string 
             
            # Only do something when the serial port has data 
            while serial_port.inWaiting(): 
                 
                # Read a single character 
                sample = serial_port.read(1) 
                 
                # Add this sample to the value_string if it is not whitespace 
                if sample.strip(): 
                    value_string += sample 
                else: 
                    # Process the data when we find a space in the read data, if the string is not empty 
                    if len(value_string) > 0: 
                         
                        # Convert the ASCII base 16 string to an integer 
                        value = int(value_string, 16) 
                         
                        # Shift the whole datalist by one sample to the left 
                        data[:-1] = data[1:] 
                         
                        # Add the new element to the end of the list 
                        data[-1] = value 
                         
                        # Set the curve with the data 
                        curve.setData(data) 
                         
                        # Clear the string for the next value 
                        value_string = "" 
            return 

         

         

        Next, we set up a timer that pyqtgraph uses to update the graph window.  We pass in a reference to the update() function that we just defined by specifying “update” without the parenthesis , and pyqtgraph will call on this update function whenever the timer expires, which is set here with a 50ms timeout.

         

        # Start Qt timer and pass the update function to it to set up periodic updates 
        timer = pg.QtCore.QTimer() 
        timer.timeout.connect(update) 
        timer.start(50)

         

         

        So far, we have objects ready to handle graphing, but we still don’t have any active windows.  The following lines will configure the pyqtgraph’s Qt system, which handles windowing.  Qt is a software library available for many languages that helps developers create graphical user interfaces.

         

        ## Start Qt event loop unless running in interactive mode or using pyside. 
        if __name__ == '__main__': 
            import sys 
            if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): 
                QtGui.QApplication.instance().exec_()

         

         

        And that’s it.  A file of under 100 lines is all that is required to fetch data from a serial port and create a live streaming graph in Windows, Mac, and Linux.  Note that most of this code was pulled from the pyqtgraph demo programs.  All I had to do was modify the formatting and add the pySerial stuff to the top of the file and in the update() function. 

         

        When you run this file on an OS command prompt by changing directory to the directory that contains the file (i.e. cd c:\users\david\documents” or equivalent), and then typing “python Scrolling.py”, you will see a graphing window that you can use to fine tune the capacitive sensor.  The graph starts out at 0, then quickly jumps up to the ambient count detected by the ACMP in the specified period on TIMER1.  Each touch event causes the count to drop, depending on how close your finger is to the center of the touch pad.

        capacitive_sense_graph_noise.png

         

        You can “zoom in” on the noise band by simply not touching the touch pad for 300 samples, at which time, pyqtgraph will automatically rescale the graph on the noise band as shown in the figure below.  This shows that the noise band is only two counts wide.

        capacitive_sense_ambient.png

         

        Now that you have a tool to create a graph of the ongoing live count, you can use this to fine tune the capacitive sense circuit.  You can adjust the frequency of the oscillator, the frequency of TIMER0 and TIMER1, or change the size and structure of the touch pad, and then use the graph to ensure that your touch event is still 5x the noise band.  You can use copper tape to adjust the size of your capacitive sense pads during the prototyping stage.

         

        Passive Infrared (PIR) Sensor Board Summary

        The PIR sensor board that is obtained from Adafruit contains a raw pyroelectric sensor, some discrete electronics, a controller chip to make sense of the pyroelectric sensor analog output, and a Fresnel lens, which creates an omnidirectional detection field for the sensor.  It also contains some trimming potentiometers to allow you to adjust the delay time, sensitivity of the sensor, and the width of the pulse on its output pin when it detects movement.  There is a great tutorial over at Adafruit to learn more about the sensor and the board: https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/.

         

        pir_sensor.png

        We will be using the PIR sensor board to simply produce a signal whenever someone approaches our circuit, or doorbell in our example, so that we wake up the EFM32, illuminate an LED, and start sampling the capacitive sense button.  It makes no sense to keep the EFM32 awake scanning for capacitive touch inputs and an LED illuminated continuously if there is no one standing in front of our sensor.

         

        Attach the PIR Sensor and Illuminate an LED

        The PIR sensor board has just three pins and is powered by 3 to 5V, so the connection to the Starter Kit is simple.  Attach the sensor to the Starter Kit per the following table.  Note that the Adafruit board contains a 3.3V regulator, so even though we are supplying 5V to the board, it is only producing 3.3V on the OUT pin, and it is therefore safe to use on the Starter Kit.

         

        Starter Kit           PIR Sensor Board
        5V                      +5V
        PC9                    OUT
        GND                   GND

         

        Note that PC9 is only available on the row of pins called J100 on the Starter Kit.  This pin is the only pinreadily available on the Starter Kit capable of bringing the MCU out of EM4 deep sleep state.

         

        wonder_gecko_em4_pin.png

        wonder_gecko_em4_pin._photo.png

        The jumper on the corner of the PIR board is used to set the “retriggering” option.  In our case, it should be set closest to the board edge, which means that the OUT pin will remain high for as long as there is motion detected in the sensor range. 

         

        Configure PC9 as an input and enable the PE2 as an output, which is connected to one of the LEDs on the Starter Kit, using the following code inside the setup_capsense() function:

         

              // Set the LED as push/pull
              GPIO_PinModeSet(gpioPortE, 2, gpioModePushPull, 0);
         
              // Install the PIR sensor on PC9
              GPIO_PinModeSet(gpioPortC, 9, gpioModeInput, 0);

        Add the following code to the top of your while loop to illuminate the LED whenever the PIR sensor’s OUT pin is high. 

         

                    if (GPIO_PinInGet(gpioPortC, 9))
                    {
                          GPIO_PinOutSet(gpioPortE, 2);
                    }
                    else
                    {
                          GPIO_PinOutClear(gpioPortE, 2);
                    }

        Note that the sensor holds the OUT pin high for a few seconds even on the lowest DELAY setting as set by the potentiometer.  This is perfect for our use, since we would want to illuminate the LED for our doorbell for a few seconds after movement has ceased.  You should now see the PIR sensor illuminate the LED0 on the Starter Kit whenever the PIR detects motion.  Note that there is a few seconds of holdoff after the LED has turned off before the PIR sensor board will arm itself again.

         

        Use the PIR Sensor to Wake the EFM32 from EM4 Sleep
        The PC9 pin that we used for the PIR board OUT pin was chosen because it is one of the possible choices as shown in the Wonder Gecko Reference Manual as being able to wake up the MCU from EM4.  Once configured for EM4 wake up, these pins will remain active as inputs even though all other GPIO’s are disabled.

         

        gpio_pins.png

         

        To configure PC9 as an EM4 wake up pin, use the following setup_em4() function:

         

        #define EM4_WAKEUP_ENABLE_PC9     0x04
        void enter_em4(void)
        {
              EMU_EM4Init_TypeDef em4_init = EMU_EM4INIT_DEFAULT;
              EMU_EM4Init(&em4_init);
         
              // Set the wake up enable on PC9 and the polarity of high from the PIR OUT
              GPIO->EM4WUEN = EM4_WAKEUP_ENABLE_PC9;
              GPIO->EM4WUPOL = 1;
         
              // Set EM4WUCLR = 1 in GPIO CMD, to clear all previous events
              GPIO->CMD = 1;
         
              EMU_EnterEM4();
         
              // Now, the system can only be awakened by PC9 or reset, and it acts as
              //   if it is coming out of reset.  Code beyond this point will
              //   never execute.
        }

        Now, augmenting our main while loop is simple.  After we clear the GPIO pin PE2 to LED0, we call the enter_em4() function.  Keep in mind that once this function is called, any data in RAM is lost.  The board can only exit EM4 energy mode by the PC9 pin going high, through the reset signal, or through a power cycle.  In all of those cases, the board will be starting up from the Chip_Init() statement.  The following is the final main() function:

         

        int main(void)
        {
              /* Chip errata */
              CHIP_Init();
         
              setup_utilities();
         
              setup_capsense();
         
              while (1)
              {
                    // Check the PIR OUT signal
                    if (GPIO_PinInGet(gpioPortC, 9))
                    {
                          // PIR is high, so set the LED0 to ON
                          GPIO_PinOutSet(gpioPortE, 2);
                    }
                    else
                    {
                          // PIR is low, so turn off LED0 and enter EM4 engergy mode
                          GPIO_PinOutClear(gpioPortE, 2);
                          enter_em4();
                    }
         
                    // Clear the count and start the timers
                    measurement_complete = false;
                    TIMER0->CNT = 0;
                    TIMER1->CNT = 0;
                    TIMER0->CMD = TIMER_CMD_START;
                    TIMER1->CMD = TIMER_CMD_START;
         
                    // Now, wait for TIMER0 interrupt to set the complete flag
                    while(!measurement_complete)
                    {
                          EMU_EnterEM1();
                    }
         
                    // Now observe the count, send it out the USART
                    print_count();
         
                    // Delay to not overwhelm the serial port
                    delay(100);
              }
        }

        When you run this code in Simplicity Studio, you will see that when the LED0 is not lit, the debugger loses connection with the MCU.  This is expected, because the debug interface shuts down in EM4 energy mode.  When you wave your hand over the PIR sensor, you should see the LED0 illuminate again.  If you watch the Python graphing window (or a terminal output) connected to the USART, you will see that no capacitance counts are streamed while the LED0 is off.  Once you wake up the MCU with the PIR OUT pin, the count of capacitance values resumes on the USART.

         

        When working with EM4 mode, you can sometimes get “stuck” in EM4 if the MCU is booted and then goes to EM4 state too quckly.  You will have to go through the trouble of erasing flash and recovering the part outside of the normal programming process.  To keep this from happening, you should create a “GPIO trap” which looks for a pushbutton pin to be pressed at startup and if so, it does not enter EM4.  Then, by holding the pushbutton while you attempt to reprogram the part, it will prevent it from reentering EM4 too quickly.

         

        This concludes the chapter on capacitive and PIR sensing.  You should be gaining the skills necessary to integrate several of EFM32’s peripherals in a single project to make something awesome.

         

      • April 2017 Member Spotlight: menchopez

        Nari | 04/97/2017 | 07:20 AM

        We are featuring one of the Silicon Labs Community members who is active or new in the community on a monthly basis to help members connect with each other.

         

        Meet our April member of the month: menchopez

         

        0,0,224,224.jpg

         

        Q: Congrats on becoming our featured member of the month! Can you introduce yourself to our community members?

         

        Hi guys! My name is Manuel. I come from Santander (Spain) and I work as an Embedded Software Engineer for SAYME.

         

        Growing up, with a father as an engineer, I learned to think differently and love engineering. In other words, I understand how things work. When I was just 9 years-old, my father and I built an electric crane for a school project, this without a doubt began my curiosity for engineering.  

         

        Then I started to carry out small electronic projects at home while I was studying Telecommunication engineering. During my bachelor degree, I was fortunate enough to have a good teacher, who lead me to a job which allowed me to develop my desire to learn and build new things.

         

        Q: How did you know about the Silicon Labs Community?

         

        I started to design devices with your microcontrollers last year. I’ve been reading a lot about your products (EFM8 and EFM32 series) so we tried them and found them very successful. As always when you build things, problems arise and you need to solve them as quickly as possible (under strict deadlines). I find this online community extremely helpful it gives you the opportunity to ask and answer questions.

         

        Q: What features, products, services would you like to see in the future from Silicon Labs?

         

        Personally, I think that the IoT market growth is strongly linked to cost-effective and energy-efficient solutions. Manufacturers and product developers should work together to achieve these goals as soon as possible.

         

        Things have changed a lot in recent years but I believe much remains to be improved. Nowadays, EFM8 and EFM32 series point clearly to these requirements: MCUs designed in terms of performance, size, cost and power consumption.

         

        Q: What advice would you give to someone new to the community?

         

        Be patient, read, read lots, stop, think over, look for and especially don’t be afraid of asking. There is an incredible community behind Silicon Labs, so enjoy it and take care of it, please.

         

        Q: Thanks for answering the questions. Any final comment?

         

        Keep up the great work, guys. It has been a great honor for me to be included among the Member Spotlight, I have a lot to learn and a lot I would like to contribute to this community.

      • Boosting Solar Power Inverter Reliability

        Lance Looper | 04/95/2017 | 06:11 PM

        Fossil-fueled electric power facilities have proven to be robust and reliable sources of energy for more than a century, but these tried-and-true facilities are large, complex and increasingly expensive to build. It's also challenging and costly to operate them cleanly with a minimal carbon footprint and environmental impact.

        Photovoltaic (PV) power systems consist of multiple components, such as panels that convert sunlight into electricity modules, mechanical and electrical connections and mountings, and solar power inverters, which are essential for conveying solar-generated electricity to the grid.

         

        Photovoltaic_Hero.jpg

         

        What is a PV Solar Inverter?

        PV panels convert sunlight into dc voltage, which must be converted to high-voltage ac to minimize line losses and enable longer power transmission distances. The PV solar inverter performs this dc-to-ac conversion and is the most critical component in any PV power generating system. However, this is just one key function that the PV inverter provides.

         

        The PV inverter also offers a grid disconnect capability to prevent the PV system from powering a disconnected utility; that is, an inverter remaining on-line during grid disconnect or delivering power through an unreliable connection can cause the PV system to back-feed local utility transformers, creating thousands of volts at the utility pole and endangering utility workers. Safety standard specifications IEEE 1547 and UL 1741 state that all grid-tied inverters must disconnect when ac line voltage or frequency is not within specified limits or shut down if the grid is no longer present. Upon reconnect, the inverter cannot deliver power until the inverter detects rated utility voltage and frequency over a five minute period. But again, this is not the end of the inverter’s duties.

         

        The inverter also compensates for environmental conditions that affect power output. For example, PV panel output voltage and current are highly susceptible to variations in temperature and light intensity per cell unit area (referred to as “irradiance”). The cell output voltage is inversely proportional to cell temperature, and cell current is directly proportional to irradiance. The wide variation of these and other key parameters causes the optimum inverter voltage/current operating point to move about significantly. The inverter addresses this issue by using closed-loop control to maintain operation at the so-called maximum power point (MPP), where the product of voltage and current is at its highest value.

         

        In addition to these tasks, the inverter also supports manual and automatic input/output disconnect for service operations, EMI/RFI conducted and radiated suppression, ground fault interruption, PC-compatible communication interfaces and more. Encased in a ruggedized package, the inverter is capable of remaining in full-power outdoor operation for more than 25 years. No small feat.

         

        Taking a Closer Look

        The single-phase PV inverter example shown below uses a digital power controller and a pair of high-side/low-side gate drivers to drive a pulse-width modulated (PWM) full-bridge converter. Full bridge topology is typically used in inverter applications because it has the highest power carrying capability of any switch mode topology. Referring to the image below, the PWM voltage switching action synthesizes a discrete (albeit noisy) 60 Hz current waveform at the full bridge output. The high-frequency noise components are inductively filtered and produce the moderately low amplitude 60 Hz sine-wave. The filtered waveform is then passed through an output transformer that performs three functions: First, it further smoothes the ac waveform; second, it corrects the voltage amplitude to meet specified grid requirements, and third, it galvanically isolates the inverter’s dc input from the high-voltage ac grid.

         

        PV_Image2.jpg

         

        PV inverter design is filled with design compromises that can cause designers much grief if the wrong trade-offs are made. For example, PV systems are expected to operate reliably and at full rated output for a minimum of 25 years, and yet they need to be competitively priced, forcing the designer to make tough cost/reliability trade-offs. PV systems need highly-efficient inverters because higher efficiency inverters run cooler and last longer than their less efficient counterparts, and they generate cash savings for both the PV system manufacturer and user.

         

        The never-ending quest for high inverter efficiency creates more design trade-offs that can impact component selection (primarily gate drivers, power switches and magnetic components, such as transformers), PCB construction and inverter package thermal requirements. The PV panel’s output voltage also wanders badly as the exposure to sunlight changes; so, it is beneficial for the inverter’s input voltage range to match that of the PV panel’s output. This creates yet more design trade-offs that further impact system complexity, cost and efficiency, and this is just the hardware. Now let’s have a look at the control side of the problem.

         

        The “brains” behind the inverter is its controller, usually a digital power controller (DPC) or digital signal processor (DSP). Typically, the controller’s firmware is implemented in a state machine format for the most efficient execution using non-blocking (fall-through) code, which prevents execution from inadvertently entering an endless loop. Firmware execution is hierarchal, typically servicing the highest priority functions more frequently than lower order functions. In the PV inverter case, isolated feedback loop compensation and power switch modulation are usually the highest priorities, followed by critical protection functions to support UL 1741 and IEEE 1547 safety standards, and finally followed by efficiency control (MPP). The remaining firmware tasks pertain mostly to optimizing operation at the present operating point, monitoring system operation and supporting system communication.

         

        The PV inverter’s exposure to blazing heat and/or freezing cold temperatures for 25 years causes one to take pause when considering the components used in the inverter. Clearly, components, such as electrolytic capacitors that filter out ripple and optocouplers that provide galvanic isolation, have no chance of “going the distance.” Electrolytic capacitors dry out and die, and the optocoupler’s LED brightness gradually fades to a dim glow, halting operation. Workarounds for these delicate components consist of replacing electrolytic capacitors with high-value film capacitors (higher reliability but obviously higher cost).The optimal long-term solution is to dismiss the optocoupler in favor of modern CMOS isolation components.

         

        CMOS process technology offers the advantages of high reliability, cost effectiveness, high-speed operation, small feature size, low operating power and operating stability over voltage and temperature extremes as well as many other desirable attributes. Moreover, unlike the Gallium Arsenide (GaAs) process technology used in optocouplers, devices fabricated in CMOS have no intrinsic wear-out mechanisms. The underlying CMOS isolation cell is capacitive, fully differential and highly-optimized for tight timing performance, low-power operation, and high immunity to data errors caused by external fields and fast common-mode transients. In fact, the advantages brought by CMOS process technology combined with proprietary silicon product design are making possible robust, “near ideal” isolation devices for the first time. These devices offer greater across-the-board functional integration, substantially higher reliability (60+ year isolation barrier lifetime), 40°C to +125°C continuous operation at maximum VDD, and substantial improvements in performance, power consumption, board space savings and ease-of-use.

         

        21st Century Component Solutions for PV Inverters

        PV inverter architecture does not end with the single-phase, transformer-based inverter shown in above. Other common types include high-frequency, bipolar, 3-phase, transformerless and battery-powered inverters. While these topologies differ from one another, they often share the need for the same component solutions. The block diagram below shows several CMOS isolation devices used in a transformer-based, three-phase inverter.

         

        Photovoltaic_1.jpg

         

        This is a classic closed loop architecture in which the digital controller modulates the power switch duty cycle to force the PV system output voltage amplitude and phase to exactly match that of the grid. These isolated gate drivers integrate safety-certified galvanic isolation (rated at 1 kV, 2.5 kV or 5 kV) and high-side level shifting functions in a single package, eliminating the need for external isolation devices. Each driver output is isolated from the next, enabling a mix of negative and positive voltage rail voltages to be used without latch-up.

         

        Current feedback to the controller is provided by a single 4 mm x 4 mm x 1 mm CMOS isolated ac current sensor (its 1 kV isolation rating is limited by package size – larger packaged versions are rated up to 5 kVrms). These monolithic sensors have a wider temperature range, higher accuracy and higher reliability compared to current sense transformers. The sensor is reset on a cycle-by-cycle basis using the inverter gate control signals generated by the digital controller, eliminating the need for external reset circuitry. The grid feedback is a critical part of the system feedback control mechanism. A resistive attenuator is used to reduce the grid voltage to a range that is compatible with the PWM modulator, which converts the sine wave input to a discrete PWM waveform, and is safety isolated by the CMOS digital isolator.

         

        Going Forward

        PV systems are relative newcomers to the energy production field. Like other emerging technologies, PV systems will be subject to rapid changes as the technology matures. As a result, PV systems will undoubtedly continue to evolve to meet market demands for higher capacity, lower cost and higher reliability. As this happens, PV inverters will expand in functionality, and designers will demand more integrated, application-specific, component-level devices to further leverage and drive innovation in CMOS isolation. As these events unfold, PV power systems will become more widespread and ultimately represent a viable segment of the utility mainstream that significantly reduces our dependence on fossil fuels.

         

        Learn more about our solutions for solar inverters here.