Are you the publisher? Claim this channel


Embed this content in your HTML

Search



Account: (login)

More Channels


Channel Catalog


Channel Description:

All Content in element14

older | 1 | .... | 32 | 33 | 34 | (Page 35) | 36 | 37 | 38 | .... | 253 | newer

     

    Brian Coates, Lumex LED and LCD expert is no longer taking new questions, but his colleage Dwight Turner would be happy to help answer any of your LCD/LED questions!  Just post your question here.   Also, don't forget, you must be logged on in order to ask Dwight a question.

     


    Please feel free to browse the achive of past member questions and Brian's answers below!

     

    Message was edited by: Nicole Fusz


  • 01/07/13--11:36: Page Visibility (chan 5145677)
  • Your site is very interesting. but the contrast is very poor for anybody with any vision problems.

    More contrast will help.

    Thanks


    Anyone know where I can buy ATTINY45 chips in the Toronto area?

    I was going to order 5 of them from Mouser at $1.22 each but they want $20.00 to ship them to Toronto.  I think that is a bit steep considering there is very little weight involved.

     

    Thanks


    This is a project I'd love to do myself, but am already overloaded.

     

    I'd like to test the feasability of using a 3D printer to make custom dice, so I need to prove that they're balanced, or not. I have a 3D printer. What I'm thinking is an automatically reloading dice tower with a camera and a PC, possibly a Raspberry Pi, with image reconginition software to count the sides as they come up. To make image recognition easier each side of the dice can be printed a different color using nail polish (the best thing I've found for painting an ABS 3D print). In this way 3 or 4 dice can be rerolled over and over again and you can just let the machine go over night until you have thousands of rolls, then look at the curve of the side count to see if the dice is balanced. This same tool could be used to adjust the build of a dice until it is level. And if you're concerned that the nail polish is effecting results you can simply take your final dice and paint a layer of clear nailpolish to make everything fair.

     

    I've never seen Ben write this sort of software so I don't know if this is the sort of project he'd be up for doing. It's on my "one day list" if he doesn't tho.


    This tutorial was extracted from Erich Styger bloghttp://mcuoneclipse.wordpress.comwith his agreement.

     

    Freescale.bmpKinetis-L.jpg

     

    The Freedom KL25Z board has a great price of less than $15. Adding a typical LCD usually will add a multiple of that price to the budget. But hey, there is a way to add a LCD to that board at almost no costs! With the idea that I have an old outdated Nokia phone, and the cost of a small capacitor plus some wires are considered as ‘zero’ ;-) .

     

    Say Hello from the Freedom Board

    Say Hello from the Freedom Board

     

     

     

    All what I need is:

    1. An old Nokia phone with one of these monocolor LCD displays
    2. Disassemble the phone to grab the display
    3. Adding a small capacitor and wires to my FRDM-KL25Z board
    4. Using a Processor Expert component as display driver
    5. Having fun :-)

     

    

    Nokia ‘Classic’ Phones

     

    A key reason for low price is high production volume. Similar to boards, this applies to other electronic goods as well, and this includes mobile phones. They are definitely produced in high volumes. Today is the area of smart phones, but not a long time ago Nokia was dominating the market with phones like the 3310:

     

    Nokia 3310 Mobile Phone

    Nokia 3310 Mobile Phone

    The Nokia 3310 and similar models are still available today in second-hand markets for a handful Euros. Or even available free of charge if you collect them from recycling stations. what is of interest for me are the displays: the phone features a 84×48 graphical LCD display.

     

     

     

     

    Another Way of Recycling

     

     

    I had one as well years ago, and was very happy with it. It still works. Since then, it was in a box with other ‘old’ electronics intended to use maybe later on. And I guess many of you have the same thing: such an old phone stored somewhere. So I decided give my old phone a new life (well, only for the display). And I have asked around in my family, and guess what: they were happy to give me their old phones. Asking students: and I had even more old phone displays to use :-) .

     

    I have found that I’m able to use the displays from following phone types:

     

    • Nokia 3210
    • Nokia 3310
    • Nokia 3330
    • Nokia 5510

     

    Disassembling the phone is rather easy. More problematic is to find out what kind of display/controller is used. Thanks to the SerDispLib project a lot of reverse engineering information is already available. 

      

     

     

     

    Type 1 or Type 2?

     

    There are two different types of displays known:

      

     

    Type 1 displays

       +-----------------------+

       |    1 2 3 4 5 6 7 8    |

       +-----------------------+

       |                       |

       |       Rear View       |

       |(Connector is visible) |

       |       LPH7779         |

       +-----------------------+

      

    Type 1 display has following pinout:

     

    • 1: Vdd (+5V or 3.3V, up to 7.4 mA)
    • 2: SCKL (SPI Clock)
    • 3: MOSI (SPI Master Out Slave In)
    • 4: D/C (Data or Command)
    • 5: SCE (SPI Chip Enable (Chip Select, active low))
    • 6: GND (Ground)
    • 7: VOUT (Display voltage out, connect with 1-4.7uF to ground, not connected to the microcontroller)
    • 8: RST (Reset, active low)

     

      

    Type 2 displays

       +-----------------------+

       |   1 2 3 4 5 6 7 8 9   |

       +-----------------------+

       |                       |

       |       Rear View       |

       |(Connector is visible) |

       |       LPH7366         |

       |                       |

       +-----------------------+

     

    Type 2 display has following pinout: 

     

    • 1: Vdd (+5V or 3.3V, up to 7.4 mA)
    • 2: SCKL (SPI Clock)
    • 3: MOSI (SPI Master Out Slave In)
    • 4: D/C (Data or Command)
    • 5: SCE (SPI Chip Enable (Chip Select, active low))
    • 6: External clock. Connect to Vdd.
    • 7: GND (Ground)
    • 8: VOUT (Display voltage out, connect with 1-4.7uF to ground, not connected to the microcontroller)
    • 9: RST (Reset, active low)

     

     

     

    Display Connector

     

      

    Basically the difference is the number of pins. I have found that some Nokia 3310 are especially useful as they have metal pins on the backside which makes it easy to solder wires on it, plus the needed capacitor:

     

    Nokia 3310 Display Rear Side with Pinout

    Nokia 3310 Display Rear Side with Pinout

     

     

    Other Nokia phones like the 5110 and 6150 are more problematic. The following picture shows the backside of the board:

     

    Backside of Nokia 5110 and 6150

    Backside of Nokia 5110 and 6150

     

     

    The issue is that not normal metal connectors are used. It uses kind of conductive ‘gum’ connector:

     

    Nokia 6150 LCD connector

    Nokia 6150 LCD connector

     

      

    :idea: Note the writing “LPH7366″ on the backside of the display which tells me the display controller used :-) .

     

    So instead of using metal contacts, it is using such conductive material to connect to the board. For this, the LCD display is pressed on the front side contacts of the board:

     

    Contacts on the front side of the board

    Contacts on the front side of the board

    The LCD itself has a metal frame which is clipped on the board. I decided to cut the board to have a connector plus the 6 green backlight LED on it:

     

     

    Board CutBoard Cut

      

      

    To connect to the my microcontroller board, I had to solder connection wires, and clipped the board to the PCB:

     

     

    Wired 5110 Display with LCD clipped on

    Wired 5110 Display with LCD clipped on

     

     

    Both the Nokia 5110 and 6150 have backlight LED’s on the board which I can use too :-) . The picture below shows the board wired to a breadboard and the green backlight LED’s of the display turned on:

     

    Breadboard Wiring with Backlight on

    Breadboard Wiring with Backlight on

    ‘Gum’ Connector

     

    But other (earlier?) Nokia 3310 are different again: their board has a lot of component on it:

     

     

    Nokia Phone Board with Connector

    Nokia Phone Board with Connector

    Here as well the ‘gum’ connector type is used:

     

    Nokia 3310 Display with 'Gum' Connector

    Nokia 3310 Display with ‘Gum’ Connector

     

    With these phones, the phone plastic cover is pressing the LCD on the base board. So for this kind of display another approach had to be used: a PCB with the connectors replicated and the capacitor on it:

     

     

    Connector PCB

    Connector PCB (Front Side)

     

     

    The back side of the board has a 2×5 connector on it for easier wiring:

      

     

    Connector PCB Back Side

    Connector PCB Back Side

     

     

    Then the display needs to be pressed on the PCB to make contact:

     

     

    Pressing Display on Connector PCB

    Pressing Display on Connector PCB

     

     

    A second revision of the connector board includes a plexiglass cover to press the display on the connector:

     

     

    LCD with Plexiglass Cover

    LCD with Plexiglass Cover

     

     

    Additionally, the second revision of the boards integrates LCD’s with backlight LED’s:

     

     

    Plexiglass cover with backlight LED display

    Plexiglass cover with backlight LED display

     

    Test Wiring to the Freedom Board

     

     

    I used a bread board to connect the Display to the Freedom board. To verify the signals, a logic analyzer is used.

      

     

    Connection to theFreedom  Board

    Connection to the Freedom Board

     

     

    PDC8544 Processor Expert Component

     

     

    According to the information in the internet, the display features a Philips PDC8544 controller. So the next thing was to develop a Processor Expert driver for it:

     

     

    PDC8544 Processor Expert Component

    PDC8544 Processor Expert Component

     

    The driver implements the low-level protocol and basic routines, including writing text to the display. Graphical routines like drawing lines/etc are subject of another component. But it is easy to write some text to the display with the low-level component.

     

    As there are different variants of the display, the type of the display plus supply voltage is configured in the component properties:

     

     

    PDC8544 Properties

    PDC8544 Properties

      

     

    Initialization Sequence and Communication Protocol

     

        

    The display uses 5 communication lines (beside of GND and Vcc):

     

     

    • D_C: Data or Command. Low for Command, High for Data
    • CLK: SPI clock signal
    • MOSI: SPI Master Out-Slave In
    • RES: Display Reset line
    • SCE: SPI chip select

    

    The display has no MISO line, as it is not possible to read from the display.

     

    The component Init() method initializes the display automatically:

    1. Setting RES and SCE to HIGH
    2. Waiting for 10 ms
    3. Setting RES to LOW
    4. Waiting 100 ms
    5. Setting RES to HIGH again

      

    The sequence is best shown with a logic analyzer:

     

    LCD Initialization Start Sequence 

    LCD Initialization Start Sequence

    Next, a sequence of command bytes is sent to the display:

     

     

    LCD Initialization Sequence

    LCD Initialization Sequence

     

    With 3V power supply, the sequence is 0×21 0xC8 0×13 0x 20 0×09, while for 5V display supply voltage it is 0×21 0xC2 0×13 0x 20 0×09.

     

    The screenshot below shows the SPI details of the first command:

     

     

    Sending 0x21 command

    Sending 0×21 command

     

     

     

    This means:

     

     

    • 8bit per transfer
    • MSB (Most Significant Byte) first
    • Clock Idle Polarity high (CPOL=1)
    • Data is valid on Clock Leading Edge (CPHA=0)

     

    

     

    Using it with the Freedom Board

     

    I used following connections on the FRDM-KL25Z Arduino header: 

     

     

    • D3: RES
    • D8: SCE
    • D9: D_C
    • D12: MOSI
    • D13: CLK

     

    FRDM-KL25Z Board Connections

    FRDM-KL25Z Board Connections

       

     

    This means following connections for the KL25Z microcontroller on the FRDM-KL25Z board:

      

    =================================================================

    SIGNAL LIST

    -----------------------------------------------------------------

    SIGNAL-NAME [DIR]        => PIN-NAME [PIN-NUMBER]

    -----------------------------------------------------------------

    CLK_D13 [Output]         => ADC0_SE5b/PTD1/SPI0_SCK/TPM0_CH1 [74]

    D_C_D9 [Output]          => ADC0_SE6b/PTD5/SPI1_SCK/UART2_TX/TPM0_CH5 [78]

    MOSI_D12 [Output]        => PTD3/SPI0_MISO/UART2_TX/TPM0_CH3/SPI0_MOSI [76]

    RES_D3 [Output]          => PTA12/TPM1_CH0 [32]

    SCE_D8 [Output]          => PTA13/TPM1_CH1 [33]

    =================================================================

     
     

    A Simple Demo Program

     

      

    Here is how to create a simple demo program to test the display:

     

    After having created a Processor Expert project in CodeWarrior for MCU10.3 (File > New > Bareboard Project), I add the PDC8544 component to my project. It will ask me to add a new Wait component. The PDC8544 will show an error as I need to further configure it:

      

     

    Added PDC8544

    Added PDC8544

     

     

    I need to add a new SPI component in the PDC1 properties:

     

     

    Add new SPIMaster_LDD Component

    Add new SPIMaster_LDD Component

     

    SPI Bus, RES and D/C Signals

     

      

    This will create a new SPIMaster_LDD component:

     

    Note: Processor Expert in MCU10.3 creates a new folder ‘Referenced_Components’

     

    The SPI component gets configured according to my pin mapping:

     

     

    SPI Configuration

    SPI Configuration

    If communication does not work well, try a slower clock rate. For me it worked well above 1 MHz.

    Next to configure the RES, SCE and D_C pins:

     

     

    RES Pin Configuration

    RES Pin Configuration

     

     

    SCE Pin Configuration

    SCE Pin Configuration

      

      

    D_C Pin Configuration

    D_C Pin Configuration

    Display Settings

     

     

    Finally, the display driver properties:

     

     

    The Type has to correspond to the display type used. The following types are supported:

     

     

    • LPH7366: Nokia 5110, 5120, 5130, 5160, 6110, 6150
    • LPH7677: Nokia 3210, 5510
    • LPH7779: Nokia 3310, 3315, 3330, 3350, 3410

     

      

    The Contrast is a bit tricky: depending on the display type, that value needs to be set differently. LPH7677 and LPH7779 typically need a value of 68, where LPH7366 needs a value around 50. In doubt, you need to experiment with that value. Additionally you can change the contract using the SetContrast() method at runtime. Last but not least it is needed to specify the correct supply voltage of the display, as the initialization is different for 3.3V and 5V displays: 

      

    PDC8544 Display Properties

    PDC8544 Display Properties

      

     

    Writing Text

     

      

    Now time to generate Processor Expert code and to add a few lines of code to write some text. WriteLineStr() writes a string to a line starting with number 1. To keep things simple I add my code into the main() routine in ProcessorExpert.c:

     

    01 int main(void)

    02 /*lint -restore Enable MISRA rule (6.3) checking. */

    03 {

    04 /* Write your local variable definition here */

    05 

    06 /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

    07 PE_low_level_init();

    08 /*** End of Processor Expert internal initialization. ***/

    09 

    10 /* Write some text */

    11 PDC1_WriteLineStr(1, "Hello World");

    12 PDC1_WriteLineStr(2, "from the");

    13 PDC1_WriteLineStr(3, "KL25Z Freedom");

    14 PDC1_WriteLineStr(4, "Board!");

    15 /*** Don't write any code pass this line, or it will be deleted during code generation. ***/

    16 /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/

    17 #ifdef PEX_RTOS_START

    18 PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */

    19 #endif

    20 /*** End of RTOS startup code. ***/

    21 /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/

    22 for(;;){}

    23 /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/

    24 } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

      

    Compile, download and the result should be like this:

     

     

    Hello World

    Hello World

    Summary

     

      

    I’m able to get a free-of-charge used Nokia phones, or very cheap replacement parts from the internet. With this and the Processor Expert component created, it is very easy to integrate a small graphical LCD display to my FRDM-KL25Z board (or any other board). Which is a great thing and enhancements of my Freedom board for many projects. I hope you enjoy it as I do.

     

     

     

     

    Software

     

     

    A demo project is available from this link. The needed Processor Expert components are available from www.steinerberg.com/EmbeddedComponents: Wait and PDC8544.

     

     

     

     

    More? Yes!

     

      

    Well, it does not stop here. There are other Processor Expert components to draw lines, boxes, circles, images and fonts, as already shown in some of the pictures above. But this is a subject for a follow-up blog :-) .

     

     

     

    Further Information

    

    

    Happy Nokiaing :-)


  • 01/07/13--16:24: Account disappeared (chan 5145677)
  • My account has vanished into thin air.

    My email is: maciek100@gmail.com.

    I believe the user name was maciek100, please let me know what happened.

     

    Regards,

    Maciej Stoszko


    If you need help on solid state relays and their applications, please post your question here by hitting "Reply"!


    Make sure your personal email notifications preference is set up appropriately--so you'll see when Pete answers your question.

     

    Pete Bamburak

     

    Pete Bamburak

    As the Field Applications Sales Engineer for Crydom North America, Pete offers 26 years of expertise and experience in solid state relay use and applications.


     

    If not already, you'll need to

    login_exprt3.png orregister_exprrt3.png

     


    to ask your question.

    Otherwise, click reply below.


    This tutorial was extracted from Erich Styger blog http://mcuoneclipse.wordpress.com with his agreement.

     

    Freescale.bmpKinetis-L.jpg

     

    With Processor Expert projects, I have a nice overview of pins used in my application:

     

    processor-view.png

    Processor View

     

     

     

    While that Processor View is nice, I want a list of pins and signals too:

     

     

    =================================================================

    SIGNAL LIST

    -----------------------------------------------------------------

    SIGNAL-NAME [DIR]        => PIN-NAME [PIN-NUMBER]

    -----------------------------------------------------------------

    LED_Green [Output]       => TSI0_CH12/PTB19/TPM2_CH1 [54]

    LED_Red [Output]         => TSI0_CH11/PTB18/TPM2_CH0 [53]

    OpenSDA_RxD [Input]      => TSI0_CH2/PTA1/UART0_RX/TPM2_CH0 [27]

    OpenSDA_TxD [Output]     => TSI0_CH3/PTA2/UART0_TX/TPM2_CH1 [28]

    SD_CD                    => ADC0_SE6b/PTD5/SPI1_SCK/UART2_TX/TPM0_CH5 [78]

    SD_CLK [Output]          => ADC0_SE5b/PTD1/SPI0_SCK/TPM0_CH1 [74]

    SD_MISO [Input]          => PTD3/SPI0_MISO/UART2_TX/TPM0_CH3/SPI0_MOSI [76]

    SD_MOSI [Output]         => PTD2/SPI0_MOSI/UART2_RX/TPM0_CH2/SPI0_MISO [75]

    SD_Shield_Green_LED [Output] => CMP0_IN3/PTC9/I2C0_SDA/TPM0_CH5 [66]

    SD_Shield_RED_LED [Output] => CMP0_IN2/PTC8/I2C0_SCL/TPM0_CH4 [65]

    SD_SS [Output]           => PTD0/SPI0_PCS0/TPM0_CH0 [73]

    SD_WP                    => PTA13/TPM1_CH1 [33]

    =================================================================

     

    =================================================================

    PIN LIST

    -----------------------------------------------------------------

    PIN-NAME [PIN-NUM]       => SIGNAL-NAME [DIRECTION]

    -----------------------------------------------------------------

    ADC0_SE5b/PTD1/SPI0_SCK/TPM0_CH1 [74] => SD_CLK [Output]

    ADC0_SE6b/PTD5/SPI1_SCK/UART2_TX/TPM0_CH5 [78] => SD_CD

    CMP0_IN2/PTC8/I2C0_SCL/TPM0_CH4 [65] => SD_Shield_RED_LED [Output]

    CMP0_IN3/PTC9/I2C0_SDA/TPM0_CH5 [66] => SD_Shield_Green_LED [Output]

    PTA13/TPM1_CH1 [33]      => SD_WP

    PTD0/SPI0_PCS0/TPM0_CH0 [73] => SD_SS [Output]

    PTD2/SPI0_MOSI/UART2_RX/TPM0_CH2/SPI0_MISO [75] => SD_MOSI [Output]

    PTD3/SPI0_MISO/UART2_TX/TPM0_CH3/SPI0_MOSI [76] => SD_MISO [Input]

    TSI0_CH11/PTB18/TPM2_CH0 [53] => LED_Red [Output]

    TSI0_CH12/PTB19/TPM2_CH1 [54] => LED_Green [Output]

    TSI0_CH2/PTA1/UART0_RX/TPM2_CH0 [27] => OpenSDA_RxD [Input]

    TSI0_CH3/PTA2/UART0_TX/TPM2_CH1 [28] => OpenSDA_TxD [Output]

    =================================================================

     

     

    That gives me information about each pin used, along with the pin number on the microcontroller package (e.g. [27] denotes pin number 27).

    To have such a list requires little work on my side. What I need to do is to fill out the ‘pin signal’ field for all the pins. That field is available in ‘Expert’ mode:

     

     

    pin-signal-in-expert-mode.png

    Pin Signal in Expert Mode

     

     

     

    Then I get that above pin/signal list generated in the ‘Documentation’ folder as text file in my project:

     

     

    processor-expert-signals-text-file.png

    Processor Expert Signals Text File

     

     

     

    Simple as that :-)

     

    :idea:  Have a look as well into the other XML/text files created in the ‘Documentation’ folder, as they give valuable information.

     

    Happy Signalling :-)


    This tutorial was extracted from Erich Styger blog http://mcuoneclipse.wordpress.com with his agreement.

     

    Freescale.bmpKinetis-L.jpg

     

     

    I have successfully used CodeWarrior for MCU10.3 beta version for many projects. With the advent of the final CodeWarrior for MCU10.3, I want to migrate my existing projects to the new and final version. First: my existing projects work as well in the final version, which is good news. But there are two things to change to take advantage of the final 10.3:

     

    1. Linker file memory split
    2. ARM Micro Trace Buffer (MTB) support

    

     

     

    Linker File Memory Split at 0×2000’0000

     

    In the beta version, linker files for Kinetis L family had a memory split at address 0×2000’0000:

     

    MEMORY {

      m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000000C0

      m_text      (RX) : ORIGIN = 0x00000410, LENGTH = 0x0001FBF0

      m_data_1FFFF000 (RW) : ORIGIN = 0x1FFFF000, LENGTH = 0x00001000

      m_data      (RW) : ORIGIN = 0x20000000, LENGTH = 0x00003000

      m_cfmprotrom  (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010

    }

     

     

    In the above linker file, the whole SRAM is splitted into m_data and m_data_1FFFF000. Such a memory split is required for the Kinetis K family (e.g. K60), as different memory controllers are used for each area. As such, linker objects shall not cross that boundary at 0×2000’0000.

     

    However, the L family implements things differently, and such a split is not necessary any more. Keeping that split is not a big issue at first hand. But if I want to use the whole SRAM memory, having such an unneeded split is complicating things. New projects created with MCU10.3 do not have that split any more. So I want to apply this to my existing projects too.

      

    :idea: Such an ‘unsplitted’ memory map is as well needed for the MTB (Micro Trace Buffer) feature presented later in this post.

      

    To migrate existing Processor Expert projects to the simplified memory map, I select the CPU component. In the Build Options tab I choose ‘Click to set default’ to apply the new memory map:

     

    click-to-set-default.png

    Click to set default

     

     

    Actually, it means clicking into the field and then click on the ‘…’ button:

     

    :idea: Clicking into the property field first to show the ‘…’ button is a problem of the UI.

      

     

    click-button-to-set-default.png

    Click button to set default

     

     

     

    This triggers a confirmation dialog:

     

    do-you-really-want-to-set-all-areas-to-the-default.png

    Do you really want to set all areas to the default

     

     

     

    After confirming that, my memory areas get reduced, and after code generation my linker file gets simplified too:

     

    MEMORY {

      m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000000C0

      m_text      (RX) : ORIGIN = 0x00000410, LENGTH = 0x0001FBF0

      m_data      (RW) : ORIGIN = 0x1FFFF000, LENGTH = 0x00004000

      m_cfmprotrom  (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010

    }

     

     

    Now my SRAM is in one nice and large memory area. And this will hep me with the Micro Trace Buffer support, which is the next topic.

     

     

    Micro Trace Buffer in Linker File

     

    The other change is that Processor Expert adds the following to support the Micro Trace Buffer:

     

    /* reserve MTB memory at the beginning of m_data */

    .mtb : /* MTB buffer address as defined by the hardware */

    {

      . = ALIGN(8);

      _mtb_start = .;

      KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */

      . = ALIGN(8);

      _mtb_end = .;

    } > m_data

     

     

    :idea: The KEEP GNU gcc linker directive is needed to avoid that the linker dead-strips that buffer from my application. Usually the linker will remove any variables which are not used. That trace buffer is not used by the application, but it is used by the trace feature in the debugger. As such, the KEEP directive tells the linker to keep it. Don’t worry that it will occupy SRAM if not used: if not used, that buffer size will be zero (more on this below). 

     

    Recreating the linker file with Processor Expert adds the above section. If I have switched off linker file creation, then I should add the above part to my linker file. More about why such an entry is needed in the next paragraph…

     

     

    Micro Trace Buffer Support

     

    One of the greatest added features in MCU10.3 is the ability to trace my application with a MTB (Micro Trace Buffer). For this there is a setting in the Debug/Launch configuration:

     

    enable-trace-and-profile.png

    Enable Trace And Profile

      

      

    In order to have this functionality working, it needs a software buffer in RAM. That’s what has been added as .mtb in the linker file (see above). Projects created with MCU10.3 add that trace buffer to the sources:

     

      sa_mtb-c-in-project.png

    sa_mtb.c in project

      

      

      

    To enable trace support for 10.3 beta project, that file has to be added. This can be done with creating a new project with 10.3 and then copy that file over, or simply create a new file sa_mtb.c with following content:

     

    /*

    02 * sa_mtb.c

    03 *

    04 * Contains the definition of the buffer used for allocating SRAM space for the MTB trace.

    05 */

    06 

    07 #if (defined(__SA_MTB_SIZE) && (__SA_MTB_SIZE > 0))

    08 /*

    09 * MTB (Micro Trace Buffer) is using its own section name, which is used in the linker script.

    10 */

    11 

    12 #define SA_MTB_ALIGNEMENT 64 /* alignment of the MTB buffer */

    13 

    14 unsigned char __attribute__((section (".mtb_buf"))) mtb_buf[__SA_MTB_SIZE] __attribute__ ((aligned (SA_MTB_ALIGNEMENT)));

    15 

    16 #endif /* __SA_MTB_SIZE */

     

     

    If I enable trace, then it will tell me to rebuild my project:

     

     

    trace-enabled-please-rebuild-the-project.png

    Trace Enabled. Please rebuild the project

     

     

    The reason is, it has set a define in the compiler setting with the trace buffer size:

    sa_mtb_size-defined-in-the-gcc-preprocessor-settings.png

    __SA_MTB_SIZE defined in the GCC Preprocessor Settings

    :idea:NOTE: If I enable trace through Project Properties > Run/Debug Settings, then the compiler define does not get properly set. But it works if I do it through the menu Run > Debug Configurations.

     

     

    Summary

     

    To take advantage of MCU10.3, two simple things are needed for my beta projects: Resetting the linker memory map and to add the sa_mtb.c file to my project. With this I have the advantage of a simpler memory map, plus I can use the hardware trace functionality. How to use the MTB will be a topic in one of my next posts.

     

    :idea:  The Freedom FRDM-KL25Z projects I have made available here are already migrated.

     

    Happy migrating :-)


    This tutorial was extracted from Erich Styger bloghttp://mcuoneclipse.wordpress.comwith his agreement.

     

    Freescale.bmpKinetis-L.jpg

      

    In “Optimizing the Kinetis gcc Startup” I stripped down the fat of my startup code. Now time to add some useful things. And what does a microcontroller like the KL25Z on the Freedom FRDM-KL25Z board have: Pins! And this means I have bits to set and read :-) .

      

    frdm-kl25z-board1.png

    FRDM-KL25Z Board

     

     

     

    So this post is about how to use digital I/O pins on the KL25Z to either turn on or off, or to read in values. In the LED tutorial I used my LED component to control them, but of course it is possible to do that kind of thing on a lower level: BitIO_LDD.

     

    Note: I assume that you are familiar with the basics like creating a Processor Expert project, generating code and debugging it. If not, please see one of my earlier tutorials: Enlightening the Freedom Board

     

     

    BitIO_LDD for an Output Pin

     

    The BitIO_LDD is included in CodeWarrior for MCU10.3. Adding that component to the project is easy from them Components Library View:

      

    adding-bitio-component.png

    Adding BitIO_LDD Component

     

     

    :!: There is as well a BitsIO_LDD component available (notice the ‘s’). This one is able to deal with multiple bits in a port, but we want here just to do it with a single bit.

     

    This adds it to my project:

     

    bitio-in-project.png

    BitIO in Project

     

      

    Time to configure it! I map it to the Red LED on my FRDM-KL25Z board which is connected to pin PTB18. For this I use the ‘Expert’ mode, give it a name (“RED”), assign it to PTB18, name the (optional) signal name and set it to output. I enable ‘Auto Initialization’ so the Processor Expert startup code initializes the pin for me:

     

    configured-pin-for-red-led.png

    Configured Pin for Red LED

     

     

    Time to try it out! For this I add two lines of code to the main() routine:

     

      

    01 int main(void)

    02 /*lint -restore Enable MISRA rule (6.3) checking. */

    03 {

    04 /* Write your local variable definition here */

    05 

    06 /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

    07 PE_low_level_init();

    08 /*** End of Processor Expert internal initialization. ***/

    09 

    10 RED_SetVal(NULL);

    11 RED_ClrVal(NULL);

    12 

    13 /*** Don't write any code pass this line, or it will be deleted during code generation. ***/

    14 /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/

    15 #ifdef PEX_RTOS_START

    16 PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */

    17 #endif

    18 /*** End of RTOS startup code. ***/

    19 /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/

    20 for(;;){}

    21 /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/

    22 } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

     

      

    :?: Wondering about the NULL parameter? The logical device drivers (LDD) components in Processor Expert need this. I will explore things how this can be optimized later on as the overhead caused by this is really not good even for such a powerful ARM Cortex-M0+ microcontroller. 

     

    Time to create code (selecting the ProcessorExpert.pe file and context menu t ‘Generate Processor Expert Code’, build it and download it. The code should turn on the RED led, and then turn it off. Simple as that :-) .

     

    The same way as of above, I add a BitIO_LDD for Green (pin PTB19) and Blue (pin PTD1):

     

    red-green-and-blue-led-as-bitio_ldd.png

    Red, Green and Blue LED as BitIO_LDD

       

       

    BitIO_LDD for an Input Pin

      

    Now I want to use a pin as input. As the FRDM-KL25Z has no dedicated button, I’m going to use the Reset button (SW1) instead which is connected to PTA20:

      

    sw1-on-the-frdm-kl25z-board1.png

    SW1 on the FRDM-KL25Z Board

      

       

    Again I add a BitIO_LDD to my project and configure it:

      

    sw1-connected-to-pta20.png

    SW1 connected to PTA20

      

      

    Now I have a little problem, as PTA20 is configured as reset pin for the CPU. So I need to tell the CPU component that I’m using the reset pin for my purpose. For this I select the Cpu in the Components view and use the Inspector menu:

      

    cpu-in-components-view.png

    CPU in Components View

     

     

    Here it tells me again that I’m ‘double booking’ that pin:

     

    cpu-with-component-inspector.png

    Cpu with Component Inspector

      

     

    What I need to do is to disable it:

     

    disabled-reset-pin1.png

    Disabled Reset Pin

     

       

    :idea: Disabling the Reset Pin has other impact too, see “How (not) to Secure my Microcontroller”

     

    But wait: there is one more setting:

       

    reset-pin-function-disabled.png

    Reset Pin Function Disabled

      

      

    Normally would need to configure an input pin with an internal pull-up resistor or similar. But SW1 already has a 10k Ohm pull-up resistor R4 attached:

     

    target-reset-and-bootloader-push-button.png

    Target Reset and Bootloader Push Button

      

      

    Time to test it in my code.

     

    I change the above code in main()now to turn on the LED if I press the button, plus to prove that pressing the reset button does *not* cause a reset, I turn on the green LED for a second (using the Wait component):

     

    added-wait-component.png

    Added Wait Component

     

     

    And my code looks like this:

     

      

    01 GREEN_ClrVal(NULL); /* turn on green LED */

    02 WAIT1_Waitms(1000);

    03 GREEN_SetVal(NULL); /* turn off green LED */

    04 for(;;) {

    05 if (SW1_GetVal(NULL)==0) { /* button low level => pressed */

    06 RED_ClrVal(NULL); /* LED cathode is connected to microcontroller pin: low level turns it on */

    07 BLUE_SetVal(NULL); /* turn off blue led */

    08 } else {

    09 RED_SetVal(NULL); /* turn off red led */

    10 BLUE_ClrVal(NULL); /* turn on blue led */

    11 }

    12 }

     

     

    While reset/SW1 is not pressed, the blue LED is on:

      

    blue-led-on-if-button-is-not-pressed.png

    Blue LED on if button is not pressed

        

        

    Pressing the reset/SW1 button turns the red LED on:

      

    pressing-sw1-turns-red-led-on.png

    Pressing SW1 turns Red LED on

         

        

    Hardware Settings

       

    I know now how to configure pins for input or output, and how to set or read them. But there is more you typically can configure. Things like pull-up or pull-down resistors, slew rates or driving strength. All these settings are missing in the above components. But they are available in the non-LDD (Logical Device Driver) land :-( .

      

    :idea: For other Processor Expert supported (non-LDD) cores (like the S08), such hardware settings can be configured in the BitIO component.

       

    So it looks like these important settings are missing here. I was lucky that my reset pin in the example above had a pull-up resistor on the board. But I know that the hardware supports an internal pull-up (or pull-down) resistor. So it should be possible to establish a ‘resistor-less’ switch between GND and pin 14 on the J2 header on the FRDM-KL25Z board:

      

    j2-with-switch-connection.png

    J2 with switch connection (Source: Freescale FRDM-KL25Z Schematics)

      

      

    D15 is connected to the PTE1 pin on the KL25Z. And I want it as an input with an internal pull-up. So how to configure it? The trick is to use Init_GPIO with pin sharing.

     

     

    Pin with Pin Sharing

      

    First, I add a normal BitIO_LDD for my new switch SW2, and configure it for PTE1:

     

    sw2-configured.png

    SW2 Configured

       

       

    I’m no going to configure the hardware (internal pull-up) in an Init_GPIO.

     

     

    Init_GPIO

     

    Init_GPIO is a component which only performs initialization, nothing else. So I add it to my project:

      

    init_gpio-component-added-to-project.png

    Init_GPIO Component Added to Project

      

      

    Next, I configure it to use PTE1 with enabled pull-up resistor:

      

    init-of-pte1-with-error.png

    Init of PTE1 with Error

      

      

    But: it reports an error as PTE1 is already used by my BitIO_LDD component. How to solve this? The solution is to configure the pin for ‘pin sharing’: this means that several Processor Expert components can share that pin. To enable pin sharing I select the context menu on that pin:

      

    enabling-pin-sharing1.png

    Enabling Pin Sharing

      

     

    Now notice the subtle color change of that icon which can easily be missed:

     

    pin-sharing-enabled-icon.png

    Pin Sharing Enabled Icon

      

     

    But: it means that it is enabled for sharing, and the error from above is fixed :mrgreen: .

     

    Time to generate Processor Expert code and to update my source:

     

     

    01 GREEN_ClrVal(NULL); /* turn on green LED */

    02 WAIT1_Waitms(1000);

    03 GREEN_SetVal(NULL); /* turn off green LED */

    04 for(;;) {

    05 if (SW1_GetVal(NULL)==0) { /* button low level => pressed */

    06 RED_ClrVal(NULL); /* LED cathode is connected to microcontroller pin: low level turns it on */

    07 } else {

    08 RED_SetVal(NULL); /* turn off red led */

    09 }

    10 if (SW1_GetVal(NULL)==0) { /* button low level => pressed */

    11 BLUE_SetVal(NULL); /* turn off blue led */

    12 } else {

    13 BLUE_ClrVal(NULL); /* turn on blue led */

    14 }

    15 }

     

      

    Time again to try it out on the board: it will turn on the green LED for a second and then turn it off. Then the LED will be off. If I press SW1, the led will be red (as above).

      

    led-off-with-open-switch.png

    LED off with open switch

      

      

    If make put PTE1 to ground with a wire (emulating a switch), the LED will turn blue:

     

    blue-led-on-with-switch-closed.png

    Blue LED on with switch closed

     

     

    Summary

     

    Doing Bit I/O really is easy with the Eclipse based CodeWarrior for MCU10.3. The project and source files created and discussed is available here.

     

    Happy Biting :-)

      

    PS: As noticed earlier: The LDD approach comes with some avoidable overhead. I preparing a follow-up article on this how to get things optimized, so it fits my needs and expectations. Stay tuned …


    This tutorial was extracted from Erich Styger bloghttp://mcuoneclipse.wordpress.comwith his agreement.

     

    Freescale.bmpKinetis-L.jpg

      

    One success factor of the Arduino platform is the broad availability so-called ‘shields’: hardware plugin-modules which extend the capability of platform. Shieldlist.org currently lists 288 different shields available! Clearly, Freescale wants to benefit from that ecosystem with the Freedom FRDM-KL25Z board which features Arduino compatible headers. Time to use the Freedom board with an Arduino shield :-) .

       

    data-logger-shield.png

    Data Logger Shield on Top of Freedom Board

      

       

     

    Data Logger Shield Hardware

       

    I ordered a the Adafruit Data Logger Shield as a kit: to solder such a kit is fun :-) , and gives me the freedom what to put on the board. The schematics of the shield can be found here.

      

    The board features an SD card with level shifter (required to work with 3.3V and 5V devices), two LED’s, a reset button, an I2C battery buffered realtime clock plus a prototype area. The minimal SD card pins (MISO, MOSI, DeviceSelect, BusCock) and I2C (SDA, SCL) bus are connected to the shield connector rows, while the two LEDs and the card write protect and card detect pins can be routed to any pins with a wire or any other kind of connection.

       

    data-logger-top-view.png

    Data Logger Top View

      

      

    In above picture the green wire is for WP (SD card Write Protection pin), the white wire is for the CD (SD Card Detect) pin. The yellow wires are for the red and green LED.

     

      

    Freedom_FatFS Application

      

    The application is Eclipse based CodeWarrior for MCU10.3 application. It uses the SD card with the open source FatFS file system.

     

    :!: The FAT_FileSystem and SD_Card component have been updated to work with Kinetis. So make sure you use the latest component from EmbeddedComponents for this project.

      

    freedom_fatfs-processor-expert-components.png

    Freedom_FatFS Processor Expert Components

      

      

    • GenericTimeDate: needed for date and time information, as the file system needs date/time attributes for files on the file system
    • Wait: generic busy wait routines, needed by the SD card driver because initialization of the SD card driver needs to wait for a time as specified in the SD card standard.
    • Timeout: As SD card operations can take a very long time (several hundreds of milliseconds), this timeout driver allows to wait for a given time.
    • SPIMaster_LDD: implements the SPI bus driver using interrupts.
    • FAT_FileSystem: Implements the FAT file system.
    • SD_Card: Low level SD card driver implementing the memory device.
    • TimerInt_LDD and TimerUnit_LDD: implement a 10 ms timer used for the Timeout component.
    • Init_GPIO: Init components used for pull up resistors for the WP and CD signals (see this tutorial).
    • LED and GPIO_LDD: Driver for the RGB LED on the Freedom board (see this tutorial). Note that the signal for the blue RGB LED is used for the SD card SPI clock signal by the Data Logger Shield.
    • BitIO_LDD: Used for the green and red LED on the shield (see this tutorial).

     

    The project and components can be easily changed for any other SD cards. In any case, here are tips and hints how the project is configured:

     

     

    KL25Z with 48 MHz

     

    In order to run the SPI bus with up to 12 MHz, the CPU core clock is configured to run at 48 MHz:

      

    48-mhz-core-clock.png

    48 MHz Core Clock

       

       

    SPIMaster_LDD Configuration

      

    The SPI component needs to be configured for the MISO, MOSI and CLK pins, *without*:!: Chip select and two:!: clock configurations, each with ‘MSB first’, ‘Low Clock polarity’ and ‘capture on leading edge’:

        

    spi-configuration1.png

    SPI Configuration

        

      

    The Attribute Set 0 needs to point to Clock rate index 0, and the so the Attribute Set 1 to Clock rate index 1. The reason is that we need to SPI clock speeds: a maximum of 400 kHz for card initialization and up to 20 MHz for normal operation. What we can achieve here is 375 kHz and 12 MHz.

       

    The two speed modes need to be set in the clock rate settings:

      

    clock-rate-settings.png

    Clock Rate Settings

      

      

    In the Timing Dialog the two SPI clock speeds need to be configured with ‘list of values’:

     

    timing-dialog.png

    Timing Dialog

      

      

    The two speed modes are referenced from the SD_Card component properties:

      

    slow-and-fast-speed-modes.png

    Slow and Fast Speed Modes

       

       

    Timeout Component

      

    As the SD card requires up to several hundreds of milliseconds delay, the Timeout component is used.

      

    sd_card-timeout-properties.png

    SD_Card Timeout Properties

      

      

    For this a 10 ms timer is configured with the TimerInt_LDD component. What easily gets missed is to call the AddTick() method in Events.c from the 10 ms timer interrupt:

      

    01 /*

    02 ** ===================================================================

    03 ** Event : TI1_OnInterrupt (module Events)

    04 **

    05 ** Component : TI1 [TimerInt_LDD]

    06 ** Description :

    07 ** Called if periodic event occur. Component and OnInterrupt

    08 ** event must be enabled. See and

    09 ** methods. This event is available only if a <Interrupt

    10 ** service/event> is enabled.

    11 ** Parameters :

    12 ** NAME - DESCRIPTION

    13 ** * UserDataPtr - Pointer to the user or

    14 ** RTOS specific data. The pointer passed as

    15 ** the parameter of Init method.

    16 ** Returns : Nothing

    17 ** ===================================================================

    18 */

    19 void TI1_OnInterrupt(LDD_TUserData *UserDataPtr)

    20 {

    21 TMOUT1_AddTick();

    22 }

      

     

    WP and CD Pins

      

    Optionally the SD card holder can provide WP (Write Protect) and CD (Card Detect) signals. They are available in the SD_Card component settings:

      

    cd-and-wp-pins.png

    CD and WP Pins

      

      

    If the signals do not have pull-ups or pull-down resistors on the board (as for my shield), they need to be configured in ‘pin-sharing’ mode and with pull-ups enabled (see this tutorial).

     

    The WP signal is connected to the shield D8 line, and the CD signal is connected to D9.

     

     

    LED’s

      

    The projects used the RGB LED on the Freedom board plus the two LED’s on the Shield. The two shield LED’s are connected to the shield D7 and D6 lines.

       

    leds-in-project-view.png

    LED Components in Component View

      

      

    Example Code

     

    The example code is in ProcessorExpert.c:

     

    01 static FATFS fs;

    02 static FIL fp;

    03 

    04 static void Test(void) {

    05 UINT bw; /* number of bytes written */

    06 

    07 if (FAT1_isDiskPresent()) { /* if no hardware CardDetect pin is assigned, it will always return TRUE */

    08 LED_Rd_On(); /* turn red RGB LED on */

    09 FAT1_mount(0, &fs); /* mount file system */

    10 if (!FAT1_isWriteProtected()) { /* if no hardware WritePtotect pin is assigned, it will always return FALSE */

    11 LED_Gr_On(); /* turn green RGB LED on */

    12 if (FAT1_open(&fp, "./test.txt", FA_CREATE_ALWAYS|FA_WRITE)!=FR_OK) { /* open file, will always create it if not already on disk */

    13 for(;;){} /* error! */

    14 }

    15 if (FAT1_write(&fp, "Hello World!", sizeof("Hello World!")-1, &bw)!=FR_OK) { /* write string to file */

    16 for(;;){} /* error! */

    17 }

    18 }

    19 (void)FAT1_close(&fp); /* close file */

    20 FAT1_mount(0, NULL); /* unmount file system */

    21 }

    22 }

     

    If a card is inserted, the Red RGB LED will be on and the file system will be mounted. If the card has not the write protection tab on, it will write a file ‘test.txt’ with an example text in it.

     

     

    Summary

     

    For now I only have this shield, and it worked very well with the Freedom board. The shield has an I2C Real-Time-Clock on it for which I did not wrote a driver yet. That would give me a battery backed up clock which would make it ideal for a data logger application. Again, still some work to do :-) .

     

    I need to check/measure the SD card speed, but for now it is reasonable for my tests. For sure I will need to extend my Shell Project with the SD card capabilities.

     

    The project and sources is available from this link. Code size with gcc and even not optimized at all is less than 18 KByte, so very reasonable.

     

    Happy Shielding :-)


    This tutorial was extracted from Erich Styger bloghttp://mcuoneclipse.wordpress.comwith his agreement.

       

    Freescale.bmpKinetis-L.jpg

       

    There was one part missing to complete the software support for my Arduino DataLogger Shield on top of my Freescale FRDM-KL25Z Freedom board: support for the Maxim DS1307 RTC (Real Time Clock).

       

    ds1307-on-the-adafruit-data-logger-shield.png

    DS1307 on the Adafruit Data Logger Shield (Source: http://www.ladyada.net/make/logshield/design.html)

       

      

    Things got delayed a bit, as I first needed to get the I2C infrastructure up and running (see this post). But finally, I have things working :-) . I proudly present: RTC_Maxim!

        

       

    Maxim I2C Real Time Clocks

     

    The component now supports two different Maxim I2C Realtime Clocks: the DS3232 and the DS1307.

      

    The DS1307 present on the Adafruit Data Logger Shield:

      

    ds1307.png

    DS1307 on the Arduino Data Logger Shield, on top of the FRDM-KL25Z

      

       

    The DS3232 is a device I have used in many of my designs:

     

    ds3232.png

    DS3232 on custom Tower Board

     

     

    For ‘classic’ (non-LDD) Processor Expert, there has been a component (RTC_I2C_DS1307) for the DS1307 with my custom extensions for the DS3232. But as with many other things: these ‘classic’ components do not work for Kinetis, as with Kinetis there are LDD (Logical Device Driver) components, and they are not compatible. That’s why I ended up implementing my own RTC_Maxim component which works both for the LDD and non-LDD world (see as well this post).

     

     

    RTC_Maxim Processor Expert Component

     

    The component takes advantage of the GenericI2C component.

     

    properties1.png

    Properties of the RTC_Maxim Processor Expert component

     

     

    As ‘Device’ either the DS3232 or the DS1307 can be selected. The component features an optional Shell interface (ParseCommand()) to the FSShell. Beside of this, it features the usual functions to get/set date and time:

     

    project1.png

    Methods of the RTC_Maxim Processor Expert component

     

     

    The Read() and Write() methods are used to to access the device non-volatile memory and registers.

     

     

    Limitations

     

    The component now only supports date and time functions, plus access to the device non-volatile RAM. Support for the other features (temperature sensor, alarm functions, oscillator output, etc) would be a topic for further work. Maybe somebody volunteers to extend the current functionality ?

     

     

    Component Sources

     

    The component (and sources) can be downloaded from this link: RTC_Maxim.

    The FSShell and FAT_FileSystem components have been updated as well with new interfaces.

     

    Happy Maximing :-)


    This tutorial was extracted from Erich Styger bloghttp://mcuoneclipse.wordpress.comwith his agreement.

     

    Freescale.bmpKinetis-L.jpg

      

     

    In my earlier Nokia LCD post I described a ‘free of charge’ way to add a LCD display to my FRDM-KL25Z board. If that Nokia display is not available, or an alphanumeric display is enough, then the Hitachi HD44780 display is a low cost option as well.

      

    The HD44780 (or compatible) display is one of the most common displays available. And they usually conly costs around $10 or less. I have used a ‘blue’ 3.3V version of such a display already in my lectures with a Freescale S08 microcontroller. So I thought it would be nice to port the driver to the Kinetis and the KL25Z on it.

      

    lcd-boards-with-frdm-kl25z.png

    LCD Boards with FRDM-KL25Z

     

     

    A recent post of TKJ Electronics about such a really inexpensive (only $5) HD44780 display caught my attention. And finally I had two of such TKJ displays in my postal mail box yesterday. Time to have some fun on a weekend :-)

     

     

     

    TKJ Electronics Display

     

    The LCD from TKJ Electronics has no connector solderd, so this makes it convenient to solder my own ones. The small (66 mm x 27 mm) size makes it ideal for many applications.

     

    tkj-lcd-frontside.png

    TKJ LCD Frontside

      

       

    The display features two ‘half-holes’ on the side for easy mounting, e.g. for robotic applications.

     

    tkj-lcd-backside.png

    TKJ LCD Backside

      

       

    The display is available from http://shop.tkjelectronics.dk/.

     

     

    Processor Expert LCD Component

     

    To simplify usage of the LCD, I have written a Processor Expert component: LCDHTA. ‘HTA’ is the abbreviation of the University of Lucerne where I teach Embedded Systems Software. The LCDHTA offers the following methods:

     

    lcdhta-methods.png

    LCDHTA Methods

      

       

    In the properties, the display settings are configured:

     

    lcdhta-properties.png

    LCDHTA Properties

        

       

    It supports both 4-bit and 8-bit data bus connection. If used in 4-bit mode, then DB4 to DB7 lines need to be connected. For the 8-bit mode, all data lines (DB0 to DB7) are connected.

      

    4bit-lcd-mode.png

    4-bit LCD Mode

      

       

    The following pins are supported in the component:

     

    • LCD Enable (optional): used to select/deselect display if multiple displays are used
    • RW (optional): Read/Write signal. Some displays have that pin which allows to read from the display. This is used to check if the display is busy or ready for new data.
    • E (required): this ‘Enable’ signal is a strobe signal to start read/write operations.
    • RS (required): Register Select, used to switch between command (RS=0) and data (RS=1) mode
    • DBx (required): either 4 or 8 pins have to be assigned for the data/command bus.

     

    The screenshot below shows the communication: first it reads from the LCD if it is ready (pulling down RS, then reading two 4-bit values). If ready, it pulls RS to HIGH level and puts the data on the bus. Then the data is transmitted with a Strobe signal on the E line:

     

      communication-detail.png

    Communication Detail

     

     

    In 4-bit mode, I used the following pin connections on the Freedom Board:

     

     

    =================================================================

    SIGNAL LIST

    -----------------------------------------------------------------

    SIGNAL-NAME [DIR]        => PIN-NAME [PIN-NUMBER]

    -----------------------------------------------------------------

    DB4_D4 [I/O]             => TSI0_CH5/PTA4/I2C1_SDA/TPM0_CH1/NMI_b [30]

    DB5_D5 [I/O]             => PTA5/USB_CLKIN/TPM0_CH2 [31]

    DB6_D6 [I/O]             => CMP0_IN2/PTC8/I2C0_SCL/TPM0_CH4 [65]

    DB7_D7 [I/O]             => CMP0_IN3/PTC9/I2C0_SDA/TPM0_CH5 [66]

    E_D10 [Output]           => PTD0/SPI0_PCS0/TPM0_CH0 [73]

    RS_D8 [Output]           => PTA13/TPM1_CH1 [33]

    RW_D9 [Output]           => ADC0_SE6b/PTD5/SPI1_SCK/UART2_TX/TPM0_CH5 [78]

    =================================================================

     

     

    8bit-lcd-mode.png

    8-bit LCD Mode

      

      

    While in 8-bit mode I used the following pin mapping:

     

     

    =================================================================

    SIGNAL LIST

    -----------------------------------------------------------------

    SIGNAL-NAME [DIR]        => PIN-NAME [PIN-NUMBER]

    -----------------------------------------------------------------

    DB0_D0 [I/O]             => TSI0_CH2/PTA1/UART0_RX/TPM2_CH0 [27]

    DB1_D1 [I/O]             => TSI0_CH3/PTA2/UART0_TX/TPM2_CH1 [28]

    DB2_D2 [I/O]             => PTD4/LLWU_P14/SPI1_PCS0/UART2_RX/TPM0_CH4 [77]

    DB3_D3 [I/O]             => PTA12/TPM1_CH0 [32]

    DB4_D4 [I/O]             => TSI0_CH5/PTA4/I2C1_SDA/TPM0_CH1/NMI_b [30]

    DB5_D5 [I/O]             => PTA5/USB_CLKIN/TPM0_CH2 [31]

    DB6_D6 [I/O]             => CMP0_IN2/PTC8/I2C0_SCL/TPM0_CH4 [65]

    DB7_D7 [I/O]             => CMP0_IN3/PTC9/I2C0_SDA/TPM0_CH5 [66]

    E_D10 [Output]           => PTD0/SPI0_PCS0/TPM0_CH0 [73]

    RS_D8 [Output]           => PTA13/TPM1_CH1 [33]

    RW_D9 [Output]           => ADC0_SE6b/PTD5/SPI1_SCK/UART2_TX/TPM0_CH5 [78]

    =================================================================

     

     

    The blue LCD we use at the university is a true 3.3V one. So the supply voltage of this one is connected to the 3.3V on the FRDM-KL25Z board. The display needs about 10 mA for operation because of the backlight feature.

     

    And here the LCD from TKJ Electronics gets really interesting, as the current needed for it is only 2-3 mA, but without backlight support. But that display needs 5V supply voltage. That 5V is provided from the Freedom board:

     

    tkj-lcd-supply-details.png

    TKJ LCD Supply Details

      

      

    The LCD Driving Voltage/Contast can be affected with a potentiometer (10-20k Ohm between Vdd and Vss to V0).

     

    :idea: Pulling V0 to Ground/GND is an easy way to avoid the potentiometer.

     

     

    Software

     

    Using the LCDHTA component, writing to the LCD is easy:

     

      

    01 int main(void)
    02 /*lint -restore Enable MISRA rule (6.3) checking. */
    03 {
    04 /* Write your local variable definition here */
    05 
    06 /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
    07 PE_low_level_init();
    08 /*** End of Processor Expert internal initialization.                    ***/
    09 
    10 /* Write your code here */
    11 LCD1_Clear();
    12 LCD1_WriteLineStr(1, "Hello FRDM-KL25K");
    13 for(;;) {
    14 uint8_t cnt;
    15 uint8_t buf[5];
    16 
    17 LCD1_GotoXY(2,1);
    18 UTIL1_Num16uToStr(buf, sizeof(buf), cnt);
    19 LCD1_WriteString((char*)buf);
    20 cnt++;
    21 WAIT1_Waitms(100);
    22 }
    23 /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
    24 /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
    25 #ifdef PEX_RTOS_START
    26 PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
    27 #endif
    28 /*** End of RTOS startup code.  ***/
    29 /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
    30 for(;;){}
    31 /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
    32 } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

     

     

    The above code writes a welcome message to the display and then increments a counter every 100 ms:

     

    hello-on-the-tkj-display.png

    Hello on the TKJ Display

       

        

    Summary

     

    Using HD44780 displays with this Processor Expert component driver makes my life much easier. And having access to a broad range of inexpensive displays makes creating embedded systems projects even more fun. The LCDHTA component is available here, an example project here.

     

    Happy Displaying :-)


    This tutorial was extracted from Erich Styger bloghttp://mcuoneclipse.wordpress.comwith his agreement.

     

    Freescale.bmpKinetis-L.jpg

      

    The great thing with the Freedom FRDM-KL25Z board is its compatibility with Arduino Shields: a great set of board available at very reasonable prices. I had my hands on the Adafruit Data Logger shield, and now it was time to use the original Arduino Motor Shield R3.

     

    motor-side.png

    Freedom FRDM-KL25Z with Arduino Motor Shield and Arexx Chassis

     

     

     

    I already had an Arexx Robo Chassis available: a simple platform with two DC motors. So I added the FRDM-KL25Z with the Arduino Motor Shield R3 on top of it:

     

    motor-top.png

    Top View with Arduino Motor Shield on top of Freedom board and motor chassis

     

     

    Power Supply

     

    The battery pack (4 AAA NiMH rechargeable batteries) provide 5V to the motor shield. That 5V is powering the FRDM-KL25Z through trace on the Motor Shield. There is an outstanding issue: the Motor Shield expects that the CPU board provides both 3.3V and 5V. 3.3V is provided, but the FRDM-KL25Z only provides 5V is either the KL25Z or the K20 is USB powered. So for now I need to power the system as well with a USB cable until I find a different solution.

     

     

    Current Sensing

      

    The shield provides two analog pins for motor current sensing. According to the documentation 3.3V should be full-scale for 2A. However, I’m measuring around 60 mV even with no current. It is not clear to me from the shield schematics if the analog signal depens on the AREF signal or not: the problem could be because the Freedom board does *not* route that signal to the header without hardware modification. So not sure where I am now with this, as I’m measuring the wrong values.

     

     

    Console/Shell Interface

     

    To manually control the motor, I have added a simple shell interface:

      

    shell-interface.png

    Shell Interface

     

     

    That way I can manually control the motors and get status information:

      

    shell-motor-commands-and-status.png

    Shell Motor Commands and Status

     

     

    Processor Expert

     

    The CodeWarrior for MCU10.3 project is using Processor Expert components to abstract from the hardware, and runs FreeRTOS:

     

    motor-processor-expert-components.png

    Arduino Motor Processor Expert Components

      

      

    Motor Driver

     

    The motor driver functionality is in Motor.c and Motor.h. The interface is as below:

     

    01 /*

    02 * Motor.h

    03 *

    04 * Author: Erich Styger

    05 */

    06 

    07 #ifndef MOTOR_H_

    08 #define MOTOR_H_

    09 

    10 #include &quot;PE_Types.h&quot;

    11 #include &quot;FSSH1.h&quot;

    12 

    13 typedef enum {

    14 MOT_DIR_FORWARD, /*!&lt; Motor forward direction */

    15 MOT_DIR_BACKWARD /*!&lt; Motor backward direction */

    16 } MOT_Direction;

    17 

    18 typedef int8_t MOT_SpeedPercent; /* -100%...+100%, where negative is backward */

    19 

    20 typedef struct MOT_MotorDevice_ {

    21 bool brake; /* if brake is enabled or not */

    22 MOT_SpeedPercent currSpeedPercent; /* our current speed in %, negative percent means backward */

    23 uint16_t currPWMvalue; /* current PWM value used */

    24 LDD_TError (*SetRatio16)(LDD_TDeviceData*, uint16_t);

    25 LDD_TDeviceData *PWMdeviceData; /* LDD device handle for PWM */

    26 void (*DirPutVal)(LDD_TDeviceData *, bool); /* function to set direction bit */

    27 LDD_TDeviceData *DIRdeviceData; /* LDD device handle for direction */

    28 void (*BrakePutVal)(LDD_TDeviceData *, bool); /* function to enable/disable brake */

    29 LDD_TDeviceData *BRAKEdeviceData; /* LDD device handle for brake pin */

    30 uint16_t currentValue; /* current AD current sensor value */

    31 uint16_t offset; /* current AD sensor offset value */

    32 LDD_TDeviceData *SNSdeviceData; /* LDD current AD device handle */

    33 } MOT_MotorDevice;

    34 

    35 /*!

    36 * \brief Sets the PWM value for the motor.

    37 * \param[in] motor Motor handle

    38 * \param[in] val New PWM value.

    39 */

    40 void MOT_SetVal(MOT_MotorDevice *motor, uint16_t val);

    41 

    42 /*!

    43 * \brief Return the current PWM value of the motor.

    44 * \param[in] motor Motor handle

    45 * \return Current PWM value.

    46 */

    47 uint16_t MOT_GetVal(MOT_MotorDevice *motor);

    48 

    49 /*!

    50 * \brief Change the direction of the motor

    51 * \param[in] motor Motor handle

    52 * \param[in] dir Direction to be used

    53 */

    54 void MOT_SetDirection(MOT_MotorDevice *motor, MOT_Direction dir);

    55 

    56 /*!

    57 * \brief Returns the direction of the motor

    58 * \param[in] motor Motor handle

    59 * \return Current direction of the motor

    60 */

    61 MOT_Direction MOT_GetDirection(MOT_MotorDevice *motor);

    62 

    63 /*!

    64 * \brief Shell command line parser.

    65 * \param[in] cmd Pointer to command string

    66 * \param[out] handled If command is handled by the parser

    67 * \param[in] io Std I/O handler of shell

    68 */

    69 uint8_t MOT_ParseCommand(const unsigned char *cmd, bool *handled, const FSSH1_StdIOType *io);

    70 

    71 /*!

    72 * \brief Initialization function.

    73 */

    74 void MOT_Init(void);

    75 

    76 #endif /* MOTOR_H_ */

     

     

    Summary

     

    It was very easy to use the Motor Shield with the help of CodeWarrior for MCU10.3 and Processor Expert. The basic functionality with the exception of current sensing works and with the shell interface it is easy to explore and add further functionality. I still have an ultrasonic sensor to integrate :-) .

     

    The CodeWarrior project and sources are available from this link.

     

    Happy Motoring :-)


    This tutorial was extracted from Erich Styger bloghttp://mcuoneclipse.wordpress.comwith his agreement.

     

    Freescale.bmpKinetis-L.jpg

     

     

    Question: What makes 8 times ‘beep’, but I cannot hear it?

     

     

    Answer: My ultrasonic range finder :-)

     

     

     

    frdm-kl25z-with-hc-sr04.png

    FRDM-KL25Z with HC-SR04

     

     

     

    What I have added to my FRDM-KL25Z board is an ultrasonic distance sensor, measuring distances up to 4 meters.

     

     

     

     

    HC-SR04 Ultrasonic Sensor

     

     

    The HC-SR04 sensor is a 4 pin sensor, at an incredible price point. I have mine from Play-Zone, but I have seen offers in the internet for around $6 too.

     

     

    hc-sr04-front-side.png

    HC-SR04 Front Side

     

     

    The backside features all the electronics to which simply usage of the sensor:

     

    hc-sr04-back-side.png

    HC-SR04 Back Side

     

     

     

     

     

    With simple I mean, it only needs 4 pins:

    1. Vcc (+5V DC supply)
    2. Trig (TTL input, to trigger a measurement)
    3. Echo (TTL output, pulse proportional to distance)
    4. GND (ground)

     

     

    :idea: There is a similar module on the market: the Parallax Ping))) or Seedstudio one which only use 3 pins (Vcc, Trig+Echo, GND). While this saves a pin, it makes usage a big more complicated as I would have to switch between output and input on a single pin. So I prefer the 4 pin variant.

     

     

    Using the sensor is simple:

     

     

    hc-sr04-timing-diagram.png

    HC-SR04 Timing Diagram

     

     

     

     

    

    1. Send a 10 us pulse on Trig
    2. In reaction to this, the sensor will send 8 sonic bursts to measure the distance
    3. After sending the burst, the sensor will raise the Echo signal until it receives the echo back. That means the length of the Echo signal corresponds to time the burst was travelling forward and echoed back.

    

    

    Below is a snapshot with a logic analyzer:

     

     

    hc-sr04-timing.png

    HC-SR04 Timing

     

     

     

    After the 10 us Trigger signal, the sensor sends the burst during ’1′ and ’2′ (around 456 us), followed by the Echo signal duration of 756 us. The 756 us corresponds to the time it took for the burst to come back.

     

    The speed of sound is about 340 m per second (depends on temperature and air relative humidity). A good approximation is 29 us per cm (or 58 us per centimeter as it is for back and forward). With the above example, the 756 us would result in 756/29/2 = 13 cm distance.

     

     

    :idea:For decimal system challenged engineers: instead of a divider of 58, use a divider of 148 to get the result in inch instead of centimeter.

     

     

     

    Hardware Connection

     

    I’m using a breadboard for easy wiring and connection.

     

     

     

    breadboard-wiring1.png

    Breadboard Wiring with Freedom Board, Sensor, LCD and Logic analyzer

     

     

     

     

     

    To visualize the measurement, I’m using the 2×16 Character display I have used in my earlier post. Of course a LCD is optional. I used the same wiring as before:

     

     

    signals-with-labels.png

    Signals with Labels

     

     

     

     

     

    =========================================================================

    SIGNAL LIST

    -------------------------------------------------------------------------

    SIGNAL-NAME [DIR]        => PIN-NAME [PIN-NUMBER]

    -------------------------------------------------------------------------

    DB4_D4 [I/O]             => TSI0_CH5/PTA4/I2C1_SDA/TPM0_CH1/NMI_b [30]

    DB5_D5 [I/O]             => PTA5/USB_CLKIN/TPM0_CH2 [31]

    DB6_D6 [I/O]             => CMP0_IN2/PTC8/I2C0_SCL/TPM0_CH4 [65]

    DB7_D7 [I/O]             => CMP0_IN3/PTC9/I2C0_SDA/TPM0_CH5 [66]

    E_D10 [Output]           => PTD0/SPI0_PCS0/TPM0_CH0 [73]

    LED_BLUE [Output]        => ADC0_SE5b/PTD1/SPI0_SCK/TPM0_CH1 [74]

    LED_GREEN [Output]       => TSI0_CH12/PTB19/TPM2_CH1 [54]

    LED_RED [Output]         => TSI0_CH11/PTB18/TPM2_CH0 [53]

    RS_D8 [Output]           => PTA13/TPM1_CH1 [33]

    RW_D9 [Output]           => ADC0_SE6b/PTD5/SPI1_SCK/UART2_TX/TPM0_CH5 [78]

    US_Echo_D2 [Input]       => PTD4/LLWU_P14/SPI1_PCS0/UART2_RX/TPM0_CH4 [77]

    US_Trig_D3 [Output]      => PTA12/TPM1_CH0 [32]

    ==========================================================================

     

     

     

     

     

    What I need is the supply voltage, ground, an output pin (Trig) and an input pin to measure the signal (Echo).

    The HC-SR04 uses TTL (5V) supply voltage and logic levels. The FRDM-KL25Z processor is a 3.3V one, but the board provides 5V on the header. The HC-SR04 can use 3.3V levels on the Trig signal, but provides a 5V signal on the Echo pin. To get the signal to the 3.3V level, I use a simple voltage divider with a 27k Ohm and 15k Ohm resistor:

     

    voltage-divider.png

    Voltage Divider with two resistors

     

     

     

    voltage-divider-detail.png

    Voltage Divider Detail

     

    CodeWarrior Project

     

     

    With the wizard (File > New Bareboard Project) I create a new project for the KL25Z and Processor Expert. I need two things:

    1. Create a 10 us pulse on the Trig (Trigger) pin
    2. Measure the echo on the Echo pin

    

     

    Trigger

     

     

    For the Trigger pin I add a BitIO_LDD component to my project:

     

     

     

    bitio_ldd-component1.png

    BitIO_LDD Component

     

     

     

    I configure it as Output pin on PTA12:

     

     

    trigger-properties.png

    Trigger Properties

     

     

     

     

    Additionally I add the Wait component to the project:

     

     

     

    wait-component.png

    Wait Component

     

     

     

     

    Generating the 10 us pulse now is trivial:

     


    ========================

    TRIG_SetVal(trigDevice);

    WAIT1_Waitus(10);

    TRIG_ClrVal(trigDevice);

    ========================

     

     

     

     

    Wait! There is some more infrastructure needed, such as this trigDevice handle. More on this below.

     

     

     

     

    Echo Pulse Measurement

     

     

    To measure the echo, I add a TimerUnit_LDD component:

     

     

    timerunit_ldd-added.png

    TimerUnit_LDD added

     

     

     

    That component shows errors for now, because I need to configure it for my needs. What I want is a timer measuring the echo signal. For this I need to set up a timer which starts counting on the echo raising edge, and stops at the falling edge. For this I need a timer channel.

     

    I add a new channel using the ‘+’ icon:

     

     

    adding-timer-unit-channel.png

    Adding Timer Unit Channel

     

     

     

     

     

    For this I’m selecting the TPM0_CNT as counter and configure the channel for ‘capture’:

     

     

    :idea: You will understand later on why I have selected this particular counter.

     

     

     

    using-tpm0_cnt-and-capture-mode1.png

    Using TPM0_CNT and Capture Mode

     

     

     

     

    As I have connected the Echo signal on PTD4, I need to use that pin as ‘Capture input pin’:

     

     

    ptd4-as-input-capture-pin.png

    PTD4 as input capture pin

     

     

     

    As hinted by the pin name (PTD4/LLWU_P14/SPI1_PCS0/UART2_RX/TPM0_CH4), this pin is available on TPM0_CH4, so I need to configure this as capture device:

     

     

     

    selected-capture-device.png

    selected capture device

     

     

     

    :idea:  Now you see why I have selected TPM0_CNT above as Counter device. I admit: that’s not something easy to know about, because this KL25Z has mirades of pin and mapping configuration (called Pin Muxing) :-( . One way is to guess what is behind from the pin names (this is what I try first). Otherwise you need to read through the device reference manual (which is very time-consuming). I wish these devices would be much less complicated and easier to use….

     

     

     

    I want to get an interrupt for both the raising edge and falling edge of the Echo signal: I enable interrupts and configure it for both edges. And I give the signal a nice name:

     

     

     

    interrupt-settings.png

    Interrupt Settings

     

     

     

     

    That’s not enough: I need to enable interrupts for the counter too:

     

     

    enabled-interrupts-for-counter.png

    Enabled Interrupts for Counter

     

     

     

    Counter Frequency

     

     

    I still have errors showing up for my Timer/Counter: I need to configure the counter frequency: This is the clock which is used for my counter. In principle: the higher the frequency, the more precise the measurement will be. As always: a good balance is required. First, I configure the counter frequency:

     

     

    configuring-the-counter-frequency1.png

    Configuring the counter frequency

     

     

     

     

    The first thing to do is to disable ‘Auto select timing’:

     

     

    disabling-auto-select-timing.png

    Disabling Auto Select timing

     

     

     

     

    :idea: Processor Expert usually chooses good default values, but fails (for whatever reason?) to do this properly for timers on the ARM platform. So as solution I always disable auto-select-timing and explicitly make my choice. Maybe better that way anyway :-) 

     

     

     

    I make a gut guess and select a 2.x MHz clock from the list (double-click to assign it):

     

     

    selected-clock-frequency.png

    Selected clock frequency

     

     

     

    Counter Overrun

     

     

    There one thing to consider: when will the counter overflow? I keep in mind that with the speed of sound, around 4 meters distance means 400*58us makes 23.5ms Echo signal pulse. So I need to make sure that for this distance, my counter does *not* overflow. I can check this in the ‘Overrun period’ settings:

     

     

     

     

    overrun-period.png

    Overrun period

     

     

     

    Deselecting ‘auto select timing’ again will show the overrun period time:

     

     

     

    overrun-period1.png

    Overrun period

     

     

     

     

     

    So my timer will overrun after 25 ms, so I’m fine :-)

     

     

    Next, I need to enable two methods I want to use. I need to read the counter value, and I need to reset it. As such, I enable the two methods (right-click on the method name and select ‘Toggle Enable/Disable’):

     

     

    enabled-timerunit_ldd-methods.png

    Enabled TimerUnit_LDD Methods

     

     

     

    I notice the two events called:

    • OnCounterRestart() is called when there is a restart/overflow of the counter
    • OnChannel() is called for every interrupt of my channel. Remember that I have it configured for creating an interrupt/event for both raising and falling edge.

    

     

    State Machine

     

     

    I’m using a state machine to go through the different measurement phases:

     

     

    state-diagram.png

    State Diagram

     

     

     

    • Idle: Sensor is idle
    • Triggered: we sent the trigger signal to the sensor
    • Measure: we received raising edge of echo signal and are measuring
    • Overflow: Counter overflow happened (see above)
    • Finished: received falling echo signal edge and we have captured the echo signal time

    

    Another way is to show the different states on the timing diagram (without the Overflow case):

     

     

     

    timing-and-state-diagram.png

    Timing and State Diagram

     

     

     

    With this in mind, the implementation is pretty straight forward. First, an enumeration for the state machine states:

     

    1 typedef enum {

    2 ECHO_IDLE, /* device not used */

    3 ECHO_TRIGGERED, /* started trigger pulse */

    4 ECHO_MEASURE, /* measuring echo pulse */

    5 ECHO_OVERFLOW, /* measurement took too long */

    6 ECHO_FINISHED /* measurement finished */

    7 } US_EchoState;

     

     

     

    Next the data structure to keep all my data:

     

    1 typedef struct {

    2 LDD_TDeviceData *trigDevice; /* device handle for the Trigger pin */

    3 LDD_TDeviceData *echoDevice; /* input capture device handle (echo pin) */

    4 volatile US_EchoState state; /* state */

    5 TU1_TValueType capture; /* input capture value */

    6 } US_DeviceType;

    8 static US_DeviceType usDevice; /* device handle for the ultrasonic device */

     

     

     

    And here is how it gets initialized:

     

    1 void US_Init(void) {

    2 usDevice.state = ECHO_IDLE;

    3 usDevice.capture = 0;

    4 usDevice.trigDevice = TRIG_Init(NULL);

    5 usDevice.echoDevice = TU1_Init(&usDevice);

    6 }

     

     

    Event Handlers

     

     

    Notice the call to TU1_Init() where I pass a pointer to my data structure: That way I get a nice handle passed from the Processor Expert event routines (in events.c) I can use for my own routines.

    Remember that I get interrupts for raising and falling edge, and for overflow.

     

    I handle that in Events.c:

     

     

    01 /*

    02 ** ===================================================================

    03 ** Event : TU1_OnChannel0 (module Events)

    04 **

    05 ** Component : TU1 [TimerUnit_LDD]

    06 ** Description :

    07 ** Called if compare register match the counter registers or

    08 ** capture register has a new content. OnChannel0 event and

    09 ** Timer unit must be enabled. See and

    10 ** methods. This event is available only if a

    11 ** is enabled.

    12 ** Parameters :

    13 ** NAME - DESCRIPTION

    14 ** * UserDataPtr - Pointer to the user or

    15 ** RTOS specific data. The pointer passed as

    16 ** the parameter of Init method.

    17 ** Returns : Nothing

    18 ** ===================================================================

    19 */

    20 void TU1_OnChannel0(LDD_TUserData *UserDataPtr)

    21 {

    22 US_EventEchoCapture(UserDataPtr);

    23 }

    24 

    25 /*

    26 ** ===================================================================

    27 ** Event : TU1_OnCounterRestart (module Events)

    28 **

    29 ** Component : TU1 [TimerUnit_LDD]

    30 ** Description :

    31 ** Called if counter overflow/underflow or counter is

    32 ** reinitialized by modulo or compare register matching.

    33 ** OnCounterRestart event and Timer unit must be enabled. See

    34 ** and methods. This event is

    35 ** available only if a is enabled.

    36 ** Parameters :

    37 ** NAME - DESCRIPTION

    38 ** * UserDataPtr - Pointer to the user or

    39 ** RTOS specific data. The pointer passed as

    40 ** the parameter of Init method.

    41 ** Returns : Nothing

    42 ** ===================================================================

    43 */

    44 void TU1_OnCounterRestart(LDD_TUserData *UserDataPtr)

    45 {

    46 US_EventEchoOverflow(UserDataPtr);

    47 }

     

     

    In case of Overflow I simply set the state machine to the overflow state:

     

    1 void US_EventEchoOverflow(LDD_TUserData *UserDataPtr) {

    2 US_DeviceType *ptr = (US_DeviceType*)UserDataPtr;

    4 ptr->state = ECHO_OVERFLOW;

    5 }

     

     

     

    While in the interrupt/event for raising or falling edge, I reset the counter value at raising edge, or read out the counter value at falling edge:

     

    1 US_DeviceType *ptr = (US_DeviceType*)UserDataPtr;

    3 if (ptr->state==ECHO_TRIGGERED) { /* 1st edge, this is the raising edge, start measurement */

    4 TU1_ResetCounter(ptr->echoDevice);

    5 ptr->state = ECHO_MEASURE;

    6 } else if (ptr->state==ECHO_MEASURE) { /* 2nd edge, this is the falling edge: use measurement */

    7 (void)TU1_GetCaptureValue(ptr->echoDevice, 0, &ptr->capture);

    8 ptr->state = ECHO_FINISHED;

    9 }

     

     

    With this I reset the counter on the raising edge, and get the counter value at the falling edge. Then I set the state to ‘finished’: this will be the state I wait for (polling) we will see later.

     

     

     

     

    Measure!

     

     

    I have implemented a function which sends the trigger, and then waits until the measurement has been finished:

     

    01 uint16_t US_Measure_us(void) {

    02 uint16_t us;

    03 

    04 /* send 10us pulse on TRIG line. */

    05 TRIG_SetVal(usDevice.trigDevice);

    06 WAIT1_Waitus(10);

    07 usDevice.state = ECHO_TRIGGERED;

    08 TRIG_ClrVal(usDevice.trigDevice);

    09 while(usDevice.state!=ECHO_FINISHED) {

    10 /* measure echo pulse */

    11 if (usDevice.state==ECHO_OVERFLOW) { /* measurement took too long? */

    12 usDevice.state = ECHO_IDLE;

    13 return 0; /* no echo, error case */

    14 }

    15 }

    16 us = (usDevice.capture*1000UL)/(TU1_CNT_INP_FREQ_U_0/1000);

    17 return us;

    18 }

     

    It sends the 10 us trigger and then waits for the finished state. In case of overflow (no echo received), I simply return a value of zero.

     

    The function returns the measured echo time in microseconds. To deal with different timer frequencies, the macro TU1_CNT_INP_FREQ_U_0 is used which is generated by Processor Expert.

     

     

     

    Calculating to Distance

     

     

    Usually I’m not interested in the echo time, but rather in the distance itself. For this I have created a utility function to transform the echo time (microsecond) into centimeter distance:

     

    01 static uint16_t calcAirspeed_dms(uint8_t temperatureCelsius) {

    02 /* Return the airspeed depending on the temperature, in deci-meter per second */

    03 unsigned int airspeed; /* decimeters per second */

    04 

    05 airspeed = 3313 + (6 * temperatureCelsius); /* dry air, 0% humidity, see http://en.wikipedia.org/wiki/Speed_of_sound */

    06 airspeed -= (airspeed/100)*15; /* factor in ~15% for a relative humidity of ~40% */

    07 return airspeed;

    08 }

    09 

    10 uint16_t US_usToCentimeters(uint16_t microseconds, uint8_t temperatureCelsius) {

    11 return (microseconds*100UL)/calcAirspeed_dms(temperatureCelsius)/2; /* 2 because of two way */

    12 }

     

     

     

     

    :idea: Speed of sound depends on factors like temperature, relative humidity and above sea level (media density). The above function is not counting in everything, but is accurate enough for me.

     

     

     

    Example Application

     

     

    Now using it is pretty simple: from my main routine I intialize my drivers, and then periodically call the function to measure the distance. To make things visual, I show values on a LCD plus show with the RGB LED the distance:

     

     

    01 static void Measure(void) {

    02 uint16_t us, cm;

    03 uint8_t buf[8];

    04 

    05 us = US_Measure_us();

    06 UTIL1_Num16uToStrFormatted(buf, sizeof(buf), us, ' ', 5);

    07 LCD1_GotoXY(1,5);

    08 LCD1_WriteString((char*)buf);

    09 

    10 cm = US_usToCentimeters(us, 22);

    11 UTIL1_Num16uToStrFormatted(buf, sizeof(buf), cm, ' ', 5);

    12 LCD1_GotoXY(2,5);

    13 LCD1_WriteString((char*)buf);

    14 

    15 LEDR_Put(cm<10); /* red LED if object closer than 10 cm */

    16 LEDB_Put(cm>=10&&cm<=100); /* blue LED if object is in 10..100 cm range */

    17 LEDG_Put(cm>100); /* blue LED if object is in 10..100 cm range */

    18 }

    19 

    20 /*lint -save -e970 Disable MISRA rule (6.3) checking. */

    21 int main(void)

    22 /*lint -restore Enable MISRA rule (6.3) checking. */

    23 {

    24 /* Write your local variable definition here */

    25 

    26 /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

    27 PE_low_level_init();

    28 /*** End of Processor Expert internal initialization. ***/

    29 

    30 /* Write your code here */

    31 US_Init();

    32 LCD1_Clear();

    33 LCD1_WriteLineStr(1, "us: ");

    34 LCD1_WriteLineStr(2, "cm: ");

    35 for(;;) {

    36 Measure();

    37 WAIT1_Waitms(50); /* wait at least for 50 ms until the next measurement to avoid echos */

    38 }

    39 

    40 /*** Don't write any code pass this line, or it will be deleted during code generation. ***/

    41 /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/

    42 #ifdef PEX_RTOS_START

    43 PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */

    44 #endif

    45 /*** End of RTOS startup code. ***/

    46 /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/

    47 for(;;){}

    48 /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/

    49 } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

     

      

     

     

    :idea: If you do not have a LCD, simply strip off the LCD code :-) .

      

     

    The other thing to consider: inside the main() loop I use a delay of 50 ms: In case of an echo it will take about 25 ms for the echo to arrive: with 50 ms I will be calm for some time until I send another ‘ping’.

     

    And here is a short video to see everything in action:

     

     

     

     

    Summary

     

    Once getting through the concept and principles, it is rather easy to use an ultrasonic range sensor like the HC-SR04. Setting up the input capture/counter is the most tricky part. But I think with the concepts and steps outlined above, this should work out pretty good for any other microcontroller, especially if used with CodeWarrior and Processor Expert.

     

    The project shown above is available here.

     

    If you are looking for improvements, here are some ideas:

    • properly calculate in the humidity and air density.
    • Using a temperature sensor to factor in the current air temperature.
    • Averaging the samples.
    • Dynamic measurement time, adaptive to the distance found to save battery energy.
    • Using an RTOS like FreeRTOS. Especially to reduce the ‘busy waiting’ time and to do something useful during that time.
    • Shell support (e.g. FSShell) to show values on a console, including setting of calibration values.
    • Create a Processor Expert Component for it.
    • As the ultrasonic beam is rather focused: add a pan a tilt servo to it to ‘explore’ more.
    • Adding more sensors and actuators to use it for a robot application :-)

    

    Happy Ultrasonic-Sounding :-)


    This tutorial was extracted from Erich Styger bloghttp://mcuoneclipse.wordpress.comwith his agreement.

     

    Freescale.bmpKinetis-L.jpg

     

    I have the Arduino Motor Shield working, the Ultrasonic module is pinging around, Christmas brought some small DC toy motors, and a bag of plastic gears is on my desk. All the good ingredients for a small robot: the Freedom Robot!

     

    :!: Warning: Multiple Coke bottles have been destroyed, and a FRDM box got hurt during his experiment! :shock: Do not try yourself if you cannot handle it.:-)

      

    smile.png

    Smile

     

     

     

    What I have in mind is to build a small autonomous robot wandering around in th house. Well, ok, at least on table or on the floor of my office. At least it should move :-) . Similar to the many robots on ‘Let’s make Robots!‘ web site which I enjoyed watching.

     

     

    Budget

     

    After all the Christmas expenses I wanted to do things with a small budget: this means re-using as much as possible, or recycle material available in the house. A given is already the FRDM-KL25Z board for about $15. I want the robot to do something ‘useful’, so I want to re-use the HC-SR04 ultrasonic sensor (around $10). And I have that Arduino Motor Shield available, although it adds another $25. So that would already make $50 of purchased parts.
    To build an autonomous robot I’m missing wheels, a chassis, motors and batteries. And for this I want to recycle existing material.

     

     

    Motors

     

    Small DC motors are very cheap (around $2). But even better: they are in many toys and that way can be recycled. I have several around from old toys.

     

    small-dc-motors.png

    Small DC Motors

     

     

    The challenge is more that I do not have a data sheet available. Experimenting with them showed that they work well in the 3V-8V range.

     

     

    Wheels

     

    Looking around for ’round things which could be used for wheels’, I was first thinking of using old CD’s. I made some experiments, but the two DC motors did not give enough torque. So I abandoned the idea and switched to a ‘small wheel + gear’ model. And a bunch of plastic wheel parts were available:

     

    plastic-tooth-wheels.png

    plastic tooth wheels

     

     

    :idea: My local electronic and hobby store sells such wheels.

     

    As wheels I have found that the plastic caps of soda bottles would be an option. So I have made my decision to use the caps as wheels:

     

    plasic-bottle-caps.png

    Plastic Bottle Caps with plastic tooth wheel

     

     

    I simply drilled a hole into the center of the cap, slightly smaller than the inner tooth wheel of the plastic gear. Then pressed the inner tooth wheel into the cap. To compensate the distance, I used a metal ring.

     

    :!: Make sure you have several caps available. I destroyed several ones until I have found the ‘perfect’ fit. Alternatively it is possible to glue the tooth wheel to the cap.

     

    Then the wheel gets put on a metal rod:

     

    wheel-cap-with-metal-rod.png

    Wheel Cap with Metal Rod

     

     

    Chassis

     

    Question: What could be the chassis for a Freedom Robot?
    Answer: The Freedom Box!

     

    Actually, the FRDM-KL25Z cannibalized the box of the FRDM-KL05 board ;-) :

     

    freedom-chassis.png

    Freedom Chassis

     

     

    The metal rod is going through the box. And a second rod with gears gets added. Both rods get drilled through the box.

      

    The two DC motors get mounted on top of the box.Two rubber bands help to keep the motors in place:

     

    motors-attached-to-the-gears.png

    Motors attached to the gears

     

      

    motor-chassis-top-view.png

    Motor Chassis Top View

     

     

    Two wheels are not enough: something else is missing to stabilize the chassis. One way is to use a third wheel, or to use a ball or similar which rolls on the ground. I have found that the plastic caps are usable too: they are cheap and available, and serve as a ‘ground slider’ if there is not much friction:

     

    position-for-ground-slider.png

    Position for ground slider

     

     

    With a cap I draw a circle and cut it out. To attach the cap, I have cut the top-most part of an (empty!) bottle:

     

    top-of-bottle-mounted.png

    Top of Bottle mounted

     

     

    Then the cab gets mounted:

     

    cap-mounted.png

    Cap mounted

     

     

    Power Supply

     

    For an autonomous robot, batteries are needed. The Arduino Motor shield has a dedicated motor power supply connector, and it can pass the motor voltage to the FRDM-KL25Z board.

     

    :idea: In general it is a good idea to separate the motor power from the microcontroller. To keep things simple, I used only one battery.

     

    But this would only give 3.3V to the FRDM-KL25Z, and no 5V which are needed for both the motor shield and the ultrasonic sensor. The FRDM-KL25Z has a coin battery holder, but again: no 5V :-( .

     

    The best option I have found is to give 5V through the USB connector (either OpenSDA or KL25Z). For this an old L7805CV positive voltage regulator from STM was right at hand. To connect it to the Freedom board, a USB cable got hurt for writing this article:

     

    powering-though-usb.png

    Powering though USB

     

     

    As battery a LiPo with two cells (7.4V) is used to power the motors, and the L7805CV generates the 5V for the Freedom board:

     

    lipo-powering-boards-and-motors.png

    LiPo Powering Boards and Motors

     

     

    Battery Compartment

     

    Why not place the battery inside the freedom box? The black ‘inlet’ box could be easily used for this:

     

    inner-black-freedom-box.png

    Inner Black Freedom Box

     

     

    Remember that the two metal rods for the gears are going through the outer box? Well, that means that I need to cut some parts of the black inner box to make it fit again:

     

    cut-parts-of-the-black-inner-box.png

    Cut parts of the black inner box

     

     

    The result is a U-shaped inner box, with that U just fitting above and blow the two metal rods:

     

    u-shaped-inner-box.png

    U Shaped Inner Box

     

     

    That way the inter box fits into the outer box:

     

    inner-box-fits-again.png

    inner box fits again

     

     

    While the sliding of the cap on the underground is desirable, it is not good for the wheels. For this I pulled rubber bands over the wheels:

     

    rubber-bands-mounted.png

    Rubber Bands Mounted

     

     

    :idea:I loved the look and feel of the original caps. I feel that the rubber bands ruined the look :-( .

     

     

    Finishing Robot

     

    Two rubber band safety belts keep the Freedom board in place:

     

    rubber-bands-for-freedcom-board.png

    Rubber Bands for Freedom Board

     

     

    The Motor Shield and the Ultrasonic Module get stacked onto the Freedom board. And the battery fits easily in the inner box compartement:

     

    battery-compartement.png

    Battery Compartment

     

     

    With this, here is it: the Freedom Robot:

     

    whats-that.png

    Front View

     

    side-view.png

    Side View

     

    back-view.png

    Back View

     

    top-view.png

    Top View

     

     

    Oh, yes, one more thing: my daughter thought that this way the robot is *much* better:

     

    modding-of-a-robot.png

    Modding of a Robot

     

     

    Summary

     

    It might not be the most robust and advanced robot, but creating it in an afternoon was not too hard, including programming a small demo application. So this might be even something for junior programming and robotics projects. The most expensive part is the Arduino Motor Shield. I was just lacy to build a cheaper one (time is money too).

     

    As always, there are multiple ways for improvements:

     

    • Use motors with built-in gears: more expensive, but simpler to use
    • Build a 4-wheel chassis
    • Use toy rubber tires
    • Add a position/wheel/quadrature encoder/decoder
    • Use the accelerometer to detect obstacles (running into it), or use it to sense the ground
    • Separate battery pack for the microcontroller
    • Adding more sensors
    • Improving the moving options
    • Experiment with beer caps instead of soft drink ones ;-)
    • Try different post-it :-)

    

    Happy Roboting :-)


    Hi got my Raspberry Pi but it's running very slow. Put it this way when I move the terminal window in X mode using the mouse the CPU usage jumps up to 70% - 80% thats not normal surely?

     

    Im not new to Linux so I checked the logs DMESG etc. but there seem to be no problems. I am awaiting a multimeter to check powersupply using T1 T2 on the board. I have also looked into the possible cause being the SD card. Mine is a Kingston branded (but made in China) 4GB micro SD with a SDHC logo on it rated at class 4. When the multimeter arrives I will also check the polyfuse. I thought it may be a formatting or partitioning problem so I used berryboot which seems to be idiot proof, and still no joy. Can someone give me any ideas?? oh yeah tried to do a benchmark using sysbench ran a random I/O mode with 50MB of data and after an hour i had ot abort the process! This can't be normal. Is anyone else having similar problems / or has solved any problems??

     

    Cheers Hungdonk3y


    Hi

     

    A group of students trying to come up with a project using arduino for coming school exhibition. Anyone out that could give a suggestion and idea as to one outstanding project that students can showcase and impress other class mates.

     

     

    Thank you.


    Hi there

    I purchased STM32F4DISCOVERY extension boards from element14.

     

    Order Number: 779604

    Three boards:

    STM32F4DIS-BB

    STM32F4DIS-LCD

    STM32F4DIS-CAM

     

    I have received three boards today. I bought a STM32F4DISCOVERY board before.

    The problem is I don't receive any software(possibly a CD) with them.

    I was trying to find any software and firmware codes to test them but I could find only document manuals.

    Please email me the related softwares and sample codes or let me know the link to download.

     

    Inside all three boxes, there is a color leaflet it says

    All related documents, schematics, source code and project binaries available at:

    element14.com/stm32f4-expansion

    However there are only pdf documents only. The schematic linked there is the stm32f4 discovery board schematic

    not the extension board ones.

     


    These should help to get you started with the Discover More expansion modules:

     

    Software Examples

     

    Application Notes

     

    User Manual

     

    Schematics


older | 1 | .... | 32 | 33 | 34 | (Page 35) | 36 | 37 | 38 | .... | 253 | newer