element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Members
    Members
    • Benefits of Membership
    • Achievement Levels
    • Members Area
    • Personal Blogs
    • Feedback and Support
    • What's New on element14
  • Learn
    Learn
    • Learning Center
    • eBooks
    • STEM Academy
    • Webinars, Training and Events
    • More
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • More
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • More
  • Products
    Products
    • Arduino
    • Dev Tools
    • Manufacturers
    • Raspberry Pi
    • RoadTests & Reviews
    • Avnet Boards Community
    • More
  • Store
    Store
    • Visit Your Store
    • Choose Another Store
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
Bluetooth Unleashed Design Challenge
  • Challenges & Projects
  • Design Challenges
  • Bluetooth Unleashed Design Challenge
  • More
  • Cancel
Bluetooth Unleashed Design Challenge
Blog Smart exercise bike computer. Part #9: Hero has come
  • Blog
  • Forum
  • Documents
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Blog Post Actions
  • Subscribe by email
  • More
  • Cancel
  • Share
  • Subscribe by email
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: yuritikhonov
  • Date Created: 5 Jul 2018 7:06 AM Date Created
  • Views 359 views
  • Likes 8 likes
  • Comments 8 comments
  • bluetooth
  • freedom_development_platform
  • bluetooth_unleashed
  • frdm-k64f
  • frdm
  • design_challenges
  • frdm-kw41z
  • hd44780
  • bosch
  • nxp
  • bt_exercise_bike
  • sport
Related
Recommended

Smart exercise bike computer. Part #9: Hero has come

yuritikhonov
yuritikhonov
5 Jul 2018

Good day!

 

I barely reconciled myself to the idea that I will not get a development board very soon it suddenly arrived Today we finally get to know the hero of my project the  FRDM-KW41ZFRDM-KW41Z board

 

Items received

 

Let's start with the announcement of the list of items that I ordered:

  1. Development board FRDM_KW41Z [NXP].
  2. Hot air gun [Bosch].
  3. Electric screwdriver [Bosch].
  4. LCD display [Adafruit].

 

Due to some circumstances, I have not received the last two items from this list yet (I'm sure that their receipt is just a matter of time), but this will not prevent me from continuing the project.

 

The hot air gun I ordered is necessary for me to work with plastic. When choosing I was guided by the following criteria:

  • a well-known and reliable brand (in Russia everybody knows and loves Bosch);
  • low price (this hot air gun cost less than $50);
  • relatively high power (1600 W);
  • possibility of power adjustment;
  • possibility of installing additional attachments.

 

 

I was a little surprised by the fact that one of our contest participants fvan uses exactly the same hot air gun, it turns out that the engineers ideas converge!

 

Now for the development board For me it was a surprise that  FRDM-KW41ZFRDM-KW41Z is not a development board but two development boards in one package!

 

In this regard I have several ways to further develop the project:

 

  1. Use only one KW41Z in the computer.
  2. Use one KW41Z to work with Bluetooth and another KW41Z for working with LCD and sensors.
  3. Use KW41Z to work with Bluetooth and K64F for working with LCD and sensors.

 

First experiment with KW41Z: Keil

 

To implement solutions (1) and (2), it is required to write software for KW41Z using the Keil environment. As I said Keil does not have a full SDK from NXP, for this reason I needed to integrate the SDK components manually. The most difficult aspect (as though it did not seem strange) of this task was writing the custom linker configuration file:

 

#! armcc -E

// -----------------------------------------------
 Custom linker for  FRDM-KW41Z by Yuri Tikhonov 
//           Created on NXP samples
// -----------------------------------------------

#if (defined(__ram_vector_table__))
    #define __ram_vector_table_size__ 0x00000200
#else
    #define __ram_vector_table_size__ 0x00000000
#endif


#define m_interrupts_start              0x00000000
#define m_interrupts_size               0x00000200

#define m_flash_config_start            0x00000400
#define m_flash_config_size             0x00000010

#define m_text_start                    0x00000410
#define m_text_size                     0x0007FBF0

#define m_interrupts_ram_start        0x1FFF8000
#define m_interrupts_ram_size        __ram_vector_table_size__

#define m_data_start                    m_interrupts_ram_start + __ram_vector_table_size__
#define m_data_size                     0x20018000 - m_data_start


/* Sizes */
#if (defined(__stack_size__))
  #define Stack_Size                    __stack_size__
#else
  #define Stack_Size                    0x0400
#endif

#if (defined(__heap_size__))
  #define Heap_Size                     __heap_size__
#else
  #define Heap_Size                     0x0400
#endif

LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start  ; load region size_region
{
  VECTOR_ROM m_interrupts_start m_interrupts_size ; load address = execution address
  {
    * (RESET,+First)
  }
 
  ER_m_flash_config m_flash_config_start FIXED m_flash_config_size ; load address = execution address
  {
    .ANY (FlashConfig)
  }
  
  ER_m_text m_text_start m_text_size ; load address = execution address
  {
    * (InRoot$$Sections)
    .ANY (+RO)
  }

  VECTOR_RAM m_interrupts_ram_start m_interrupts_ram_size ; edition by Yuri
  {
    .ANY (.m_interrupts_ram)
  }

  RW_m_data m_data_start m_data_size  ; RW data
  {
    .ANY (+RW +ZI)
  }
  
}

 

Another thing I had to tinker with just like in the case of [K64F] – was a problem with the DAP-Link Debugger, but today everything was much simpler: you just had to choose J-LINK instead of DAP Debugger in Keil's settings and it all worked right away!

Having coped with all the problems, I was able to write my first program for KW41Z, the main function of which is listed below, and the full listings are available in the [official repository] of the project in [KW41Z] branch.

 

// main function
int main(void)
{
    // initialization of peripheral
    gpio::init();
    BOARD_BootClockRUN();

    // infinity loop
    for(;;)
    {
            delay();
            gpio::write(GREEN, true);
            delay();
            gpio::write(GREEN, false);
    }
}

 

Having written this simple program, I realized that porting the SDK is not a quick thing and it will take me a long time to implement the full operation with Bluetooth. In order to overcome this problem at the current stage, I decided to follow the way (3) and continue to use the already practical ready-made project for K64F together with KW41Z, while implementing in KW41Z only a small set of functions that support Bluetooth on the basis of a demo project from SDK.

 

The problem is that I can compile this project (from KW41Z) only in MCUExpresso IDE or IAR. Given that I did not use IAR before, my choice fell on MCUExpresso.

 

Second experiment with KW41Z: MCUExpresso IDE

 

As a basis, I used a demo-project of a bike speedometer program called cycling_speed_cadence_sensor. A little deeper into the research, I found out that in this application there are four parameters that I need to set in accordance with the actual values of training process:

  • measurement.cumulativeCrankRevs –  total number of turns of pedals;
  • measurement.lastCrankEventTime – time of the last measurement of pedal rotation [ms];
  • measurement.cumulativeWheelRevs – the total number of wheel turns;
  • measurement.lastWheelEventTime – time of last measurement of wheel rotation [ms].

 

The last two values I decided not to fill in yet and focus only on the first two. The parameter measurement.lastCrankEventTime in the demo program is already being processed: it is incremented by 1024 each time the corresponding function is called (i.e., pedal turns are determined approximately 1 time per second).

 

It remains to define measurement.cumulativeCrankRevs and here the problem arises: if the number of revolutions is an integer, then the measurement accuracy will be horrendous ±60 RPM! In order to cope with this problem, I decided to record in this variable not just the speed of pedal rotation, but the speed of pedal rotation multiplied by 100, so the measurement accuracy is ±0.6 RPM. Another idea occurred to me that instead of speed (N) I can output the speed in km/h to the program, for this, assuming [as we did before] that the rider is traveling in the 8th gear (G = 8), the following calculation is required:

 

measurement.cumulativeCrankRevs = N * 100 / 2.5

 

There remains only one question: where do we take the variable N from I decided to transfer it from the  FRDM-K64FFRDM-K64F board via UART while ensuring the synchronization of receiving and sending packets I will not go into details but I'll just show you the code of my solution

 

// timer interrupt handler
static void TimerMeasurementCallback(void * pParam)
{
    cscsMeasurement_t measurement;
    
    if ( cscsServiceConfig.calibrationInProgress)
    {
        Cscs_FinishSensorCalibration(&cscsServiceConfig, TRUE);
    }

    // ----------------------------------------------------------------------------

    static unsigned char last_value = 0, count = 0;
    static long long time = 0;
    unsigned char value = 0xff;

    // led indication
    Led3Toggle();

    // synchronization
    LPUART_WriteBlocking(DEMO_LPUART, &value, 1);

    // read data excluding invalid packets
    while (value == 0xff)
    LPUART_ReadBlocking(DEMO_LPUART, &value, 1);

    // data recognition and correction
       if (value <  last_value) time += 0xff;
       if (value == last_value) count ++;
       if (value != last_value || count > 3)
    {
        count = 0;
        lastEventTime += 1024; // time variable [ms]
    }

    // turns count variable
    mCscsUserData.cumulativeCrankRevs = time + (long long)value;
    last_value = value;
    Led3Toggle();

    // ----------------------------------------------------------------------------
    
    // save data
    measurement.crankRevDataPresent = TRUE;
    measurement.cumulativeCrankRevs = mCscsUserData.cumulativeCrankRevs;
    measurement.lastCrankEventTime = lastEventTime;
    
    measurement.wheelRevDataPresent = TRUE;
    measurement.cumulativeWheelRevs = mCscsUserData.cumulativeWheelRevs;
    measurement.lastWheelEventTime = lastEventTime;
    
    Cscs_RecordMeasurement(service_csc, &measurement);

}

 

Adjustment of K64F firmware

 

In order to combine KW41Z and K64F, it took me a little bit of work to improve the bike computer's program: I added to the program an additional RTOS thread called interconnect, which is responsible for communicating with the KW41Z board via the UART interface.

 

I got the following algorithm for working with UART:

  1. In the sensors thread in real time, the calculation of the variable N (which is called tcnt) is performed, the calculation is performed at each turn of the pedals.
  2. The interconnect thread waits for a UART request from KW41Z.
  3. As soon as the request for data arrives, a value generated on the basis of tcnt is transferred to KW41Z, the specified conversion is necessary to reduce the data flow between the MCUs.

 

Simplified interconnect and sensors threads are listed below

 

// second thread: for work with sensors
static void sensors(void const *args);
osThreadDef(sensors, osPriorityNormal, 1, 0);
static void sensors(void const *args)
{
    static char tcnt_flag   = 0;    // flag for Bluetooth feature
    char      state            = 0;    // current state of reed
    float     clc_speed      = 0;    // calculated speed
    
    // calculation of the distance (rotation count) and wavelength
    for (;;)
    {
        if (!state && gpio::read(REED))
        {
            // .. code ...
            tcnt_flag = 1;
        }
        else if (state && !gpio::read(REED))
        {
            // .. code ...
        }

        // .. code ...

        // if it's a new turn then we convert speed to KW41Z format
        if (tcnt_flag == 1)
        {
            tcnt += clc_speed * 20.5f / 60.0f * 5.0f;
            tcnt_flag = 0;
        }
    }
}

// forth thread: for work with interconnection
static void interconnect(void const *args);
osThreadDef(interconnect, osPriorityNormal, 1, 0);
static void interconnect(void const *args)
{
    for(;;)
    {
        unsigned char value;

        // we waiting for request
        UART_ReadBlocking(UART3, &value, 1);

        // convert tcnt to 'short' format
        value = tcnt % 0xff;

        // send data to KW41Z
        UART_WriteBlocking(UART3, &value, 1);
    }
}

 

Testing of the device

 

To conduct the tests, I collected all the components of the bike computer on my desk and as experience I applied to this system by simulating a reed sensors signal with a frequency of ~1 Hz:

 

For today's experiments, I installed the NXP IoT Toolbox on my smartphone Samsung Galaxy A5. This application almost immediately started working with my bike computer, so I did not need any further work on this part:

 

As you can see, the discrepancy between the speed values on the bike computer screen (22.97 km/h) and the mobile application screen (23.40 km/h) is 0.43 km/h, which is below the maximum permissible error, which we mentioned above.

 

Conclusion

 

Today I finally got my  FRDM-KW41ZFRDM-KW41Z and in a very short time I managed to do a lot of work to integrate Bluetooth into my program! Now I'm a little worried about the appearance of my computer: because of the abundance of details, I just can not fix it on exercise bike, so next week I plan to tackle this issue.

 

Nevertheless, the most important part of the project is finally completed and now I have no doubt that the project will be completed on time, and if within the next two weeks I receive all the missing items of my order, things will go even better!

 

Thanks for reading and have a nice day!

Anonymous

Top Comments

  • aspork42
    aspork42 over 4 years ago +2

    Nice work! I love the part of the project when all the components start to come together and make one complete system.

  • genebren
    genebren over 4 years ago +1

    Great update on your design challenge project. Wow, it took quite a while for your parts (hero) to arrive.  And to think, I get upset if my parts are delayed by a day or two.

    Good luck on you remaining tasks…

  • yuritikhonov
    yuritikhonov over 4 years ago in reply to genebren +1

    Thanks Gene! On early stages I was rescued by FRDM-K64F that  was a very similar with my 'hero'.

  • stevesmythe
    stevesmythe over 3 years ago in reply to yuritikhonov

    Thank you. I guess I'll need to work out how to replicate the _delay_ms() function with the KW41Z and then map the pins using the Pins tool in MCUXpress.

    • Cancel
    • Vote Up 0 Vote Down
    • Reply
    • More
    • Cancel
  • yuritikhonov
    yuritikhonov over 3 years ago in reply to stevesmythe

    I think your need LCD with 4-bit interface, because it's simplest way to connect LCD to any MCU.

    I found for you my old program in pure C, that uses LCD with 4-bit interface. I guess you can rewrite it for your project:

     

    https://bitbucket.org/snippets/geovas/Aeazbg

    • Cancel
    • Vote Up 0 Vote Down
    • Reply
    • More
    • Cancel
  • stevesmythe
    stevesmythe over 3 years ago in reply to yuritikhonov

    Thank you for accepting my connection request. I am trying to connect an LCD to the KW41Z but I need to code in C because I am using NXP's example code for connecting an NFC I2C reader to the board and all their examples are in C. I have little experience so far with C and am trying to understand how to connect the LCD. I could use I2C as I have an LCD with an I2C  "backpack" or perhaps UART as I have a UART LCD backpack too, but I am thinking maybe connecting the LCD in 4 bit mode might be easier for me to understand. That would still leave me enough pins. I see you used C++ in your project. Did you ever try to use C to connect your LCD to the KW41Z?

     

    Steve

    • Cancel
    • Vote Up +1 Vote Down
    • Reply
    • More
    • Cancel
  • yuritikhonov
    yuritikhonov over 3 years ago in reply to stevesmythe

    Hello! Of course it's OK.

    Only sometimes I don’t visit elementary14 for weeks, but I always try to answer the questions of my readers.

    • Cancel
    • Vote Up 0 Vote Down
    • Reply
    • More
    • Cancel
  • stevesmythe
    stevesmythe over 3 years ago

    Hi Yuri

     

    This is a great project! I have sent you a "follow" request because I am doing a RoadTest involving the KW41Z board and would like to benefit from your experience of using it with MCUXpresso. Would that be OK?

     

    Thanks

     

    Steve

    • Cancel
    • Vote Up +1 Vote Down
    • Reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2022 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • Facebook
  • Twitter
  • linkedin
  • YouTube