Showing posts with label utilities. Show all posts
Showing posts with label utilities. Show all posts

Friday, March 29, 2013

Links to USB resources on STM website

I think my older post Some resources for STM32 USB device programmers no longer represents how I look at USB firmware development for STM32, so...

This is just a list of links to USB resources on STM website. I'll use it as a reference for myself, so this post will be updated. The need for me to create this post is because STM finally succeeded in their quest to make any info unsearchable on their website.
If you think anything is missing, please let me know.
I'll split this by Discovery boards, F3 and F4, so apologies in advance.

Thursday, March 21, 2013

STM32 tools: New MicroXplorer generates the STM32 pinout initialization code

While I'm still very angry with STM for what they've done to all the community efforts by breaking, again, all the links on their *new* website rendering all our howtos to useless texts, here's a piece of *presumably* great news: MicroXplorer now is able to generate code. I haven't tried it though yet, so be the first to give it a go and describe your experience.

Saturday, August 25, 2012

How to measure RPM in a glimpse of an eye

So, yes. I just assembled a setup to measure rotation speed of an RC model motor. It uses a reflective IR sensor to provide high level signal to MCU whenever a blade of a propeller comes by in front of it. OK, we've got a series of impulses with the frequency of motor revolutions divided by number of blades, but how do we know how many rpm does it make?

1. Measuring frequency


This was my very first take on the problem. I decided I could take a time interval, a second for simplicity, and just count how many times blades made the sensor go off. Divide than by number of blades and multiply by 60 (seconds in a minute) to get your rpm. Once you do that, you will immediately notice, that the result comes in multiples of 60s. If you had 10 rps (revolutions per second), you calculate for 600 rpm, 11 rps account for 660 rpm. This is good +=5% error, and it's called discretization error. Surely the higher the speed, the lower this error is, but it's still very annoying. Another error comes from instability of revolution period. This also create a lot of trouble if the rotation speed is low.

More here, if you really take 1 second interval, the whole system does not respond very well - you may want to have refresh rate at least 3 times per second... And the shorter the measurement interval is, the bigger is discritization (if you have 330ms, the result will come now in multiples of 180!) error and the higher is the minimum rotation speed you can measure (for minimum of 3rps - for wich you'll have yet to fight, I'd say it's rather 6 rps with 330ms period - you'll have 180 rpms) - which is not a very huge problem, but still lousy.

There must be another method, I thought, that allows e.g. www.HobbyKing.com to create Turnigy Multi-Blade Micro Tachometer and claim minimum rpm of 10 rpm as well as high precision of measurement. And there's one. Thinking of it now, I believe it's a trivial and obvious solution. However I had to read a book on measurements to get to this.

2. Measuring period


That's it and that's really easy. Instead of counting how many blades will pass sensor in time period, you rather count how many time periods pass in between two blades crossing sensor FOV. I initially set up MCU to count 1us intervals, but found out my 16 bit counter overflows too fast and I can't measure low rpm. So I just used prescaler.

It's quite easy to reverse-calculate all the parameters here. Imagine you need to go as low as 10rpm as Turnigy tachometer does. So you need to setup MCU so 16 bit counter overflows in longer than 6s (10 rpm is 0,167rps or 1/0,167 = 6 seconds per revolution). That is 6/65536 = ~92us per timer clock.
Now, what is the highest speed you can measure? With e.g. 1% precision you may want to have at least 100 timer clocks per revolution, i.e. 9,20 ms. That is 108 rps or 6522 rpm.

And that calculation is for 1 blade propeller (that are not often met in the wild). If there are two blades the calculation above will be for 5rpm min and 3260 rpm max.

What's the estimated error? Absolute maximum error for this method is not higher than 1 timer clock (92us). For 10rpm error is 92us/6s. Which is tiiiiinyyyy. Not noticeable. Means not relevant. For 6522 rpm it's 92us/9.2ms = 1%

Now you can almoset instantly measure rpms with high enough accuracy. Oh, you might think 6522 rpm (3260rpm for a two-blade propeller) is nonsense? Tiiiiinyyyy? Not noticeable? Means not relevant? Well, tell me how to handle higher rpm in comments.

Happy measuring!
Cheers!

P.S. Oh, nearly forgot. Here's some code for PIC:

#include "htc.h"
#include "freq_meter.h"
#include "hw_configuration.h"
#include <stdio.h>
#include "lcd.h"

__CONFIG(FOSC_INTOSC & CLKOUTEN_OFF & WDTE_OFF & PWRTE_ON & PLLEN_ON);

#define TMR0_LCD_REFRESH_RATE 5
unsigned char outputBufferStr1[9];
unsigned char outputBufferStr2[9];
unsigned char outputBuffer[40];
unsigned int TMR0_OverflowCounter = TMR0_LCD_REFRESH_RATE;
bit outputResultFlag = 0;
bit peakHoldFlag;
bit errorFlag = 0;
unsigned int cntval = 0;
unsigned int maxcntval = 0;
unsigned long rpm = 0;
unsigned long maxRpm = 0;

void main (void)
{
    picSetup();
    LCD_Init ();

    TMR1H = 0;
    TMR1L = 0;

    peakHoldFlag = 1;

    LCD_WriteStr2 ("Hi!");
    while(1)
    {   
        if (outputResultFlag)
        {
            //LCD_ClearAndHome();
            if (errorFlag)
            {
                RB3 = 1;
                LCD_WriteStr1 ("  Error!");
            } else
            {
                RB3 = 0;
                rpm = 15000000/cntval;
                if (rpm > maxRpm) maxRpm = rpm;
                sprintf(outputBufferStr1, "%5urpm", (unsigned int)rpm);
                LCD_WriteStr1 (outputBufferStr1);
            }
            if (peakHoldFlag)
            {
                sprintf(outputBufferStr2, " pk%5u", (unsigned int)maxRpm);
                LCD_WriteStr2 (outputBufferStr2);
            }
            outputResultFlag = 0;
        }
    }
}

void interrupt isr (void)
{
    if (TMR1IE && TMR1IF)
    {
        TMR1IF = 0;       
        errorFlag = 1;
    }

    if (CCP1IE && CCP1IF)
    {
        CCP1IF = 0;
        if (errorFlag)
        {           
            TMR1L = 0;
            TMR1H = 0;
            cntval = 0;
        }
        else
        {
            cntval = (CCPR1H << 8) + CCPR1L;
            TMR1L -= CCPR1L;
            TMR1H -= CCPR1H;
        }
        errorFlag = 0;
    }

    if (TMR0IF)
    {
        TMR0IF = 0;
        if (TMR0_OverflowCounter-- == 0)
        {
            outputResultFlag = 1;
            TMR0_OverflowCounter = TMR0_LCD_REFRESH_RATE;
        }
    }
    
}


Tuesday, July 31, 2012

Correction on STM32 Micro Explorer configuration utility

I recently wrote about MicroExplorer from STMicroelectronics - STM32 visual configuration tool. And I put a hint there: "Hint 2: Manually selecting an input/output role for a pin (such as Open Drain Output) will prevent you from choosing a peripherial in the drop-down menue. The utility will not tell you that there's a conflict - it will just not allow you to choose a peripherial. So my advise is - select all the peripherials first and then start playing with inputs/outputs manually."


Luckily, this is not true. If there's a conflict, Micro Explorer shows you possible candidates for the conflict - on mouse over:
If you hold you mouse over a conflict sign, you'll see what's the problem
Happy configuration!

Cheers :-)

Thursday, June 14, 2012

MicroExplorer from STMicroelectronics - STM32 visual configuration tool

It's often a pain to properly connect different peripherials to an MCU, especially if the latter has rich remapping capabilities (that is definitely the case for STM32). I used to use MS Excel for playing with configurations for PICs but as I just started with STM32 it would be a nightmare to go through all the remapping info in Reference Manual and try to not assign the same pin for all the devices you want to connect your MCU to.

Luckily ST created a graphical tool for people like me.