This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Using N2HET for RPM measurement

I would like to use the N2HET on the RM48 MCU to measure angular velocity (i.e. shaft rpm), where the frequency of the tach signal can have a relatively wide range - from hundreds to tens of thousands rpm. I definitely want to avoid firing off interrupts on every edge. I wrote the following HET program, containing 5 instructions:

; Edge counter
EDGE0_Detect ECNT { prv=ON, pin=IO_PIN0, event=RISE, reg=A, irq=OFF, data=0 }

; Signaling counter
EDGE0_Signal CNT { reg=B, max=NUMLR_IN_IRQ, data=0 }

; At signaling time
EDGE0_IsSignal BR { next=PIN0_End, cond_addr=EDGE0_Save, event=ZERO, irq=ON }

; Save edge counter value
EDGE0_Save ADD { src1=A, src2=ZERO, dest=IMM, data=0, hr_data=0 }

; Reset edge counter
EDGE0_Reset MOV32 { remote=EDGE0_Detect, type=IMTOREG&REM, reg=A, data=0, hr_data=0 }

The program counts signal edges as they occur and, at a lower fixed frequency of my choice (defined by NUMLR_IN_IRQ parameter), fires off an interrupt, saves the counter value, and resets the edge counter. The interrupt handler in my program will then read the counter value from the data field of EDGE0_Save and divide it by (NUMLR_IN_IRQ * LRPeriod) to obtain the number of edges per unit of time.

I was wondering if this or similar can be accomplished with less than 5 HET instructions.

Thanks,

Marius

  • Marius,

    Thanks for using our forum.

    If I understand your code, the BR instruction (label EDGE0_IsSignal) is used to generate your IRQ when your max count (NUMLR_IN_REQ) overflows.
    This can be done in the CNT instruction itself.
    Use the irq=on in CNT instruction.

    if irq=ON generates an interrupt when the counter overflows to zero. The interrupt is not generated until the data field is reset to zero.
    If irq is set to OFF (default), no interrupt is generated.

    Please let me know if this will help you.

  • I am aware that I could fire off the interrupt from CNT instead of BR, but I think I still need to branch when the counter resets, such that I execute the next two instructions that save the event counter value and then reset it. Or am I making this more complicated than it needs to be ? If I remove the last 3 instructions and keep only the event counter and my slow counter, I suppose I could read directly the data field of the ECNT instruction and then reset it to zero, from my interrupt handler in the main program. Would that work ? If that's the case, then this can be simplified even further to just the event counter instruction, and read/reset the ECNT data field from an interrupt fired by an RTC timer ?

    Thanks,

    Marius

  • I saw your code. Im doing something similar. I need to count the encoder pulses (12 encoders) up to 360 pulses per revolution per channel (A+B=720 pulses). I have a couple of questions. 

    the first: why did you use different registers on the Edge detect and the signal count?

    the second: 

    A1_edge_detect ECNT { prv=ON,pin=0,event=RISE,reg=A,irq=OFF,data=0};
    A1_count CNT { reg=A,comp=EQ,irq=OFF,max=360,data=0};

    these are the two lines of the first channel but I'm not sure how the count will work, or from where the data come. (Why can't the A1_edge_detect make the count i need? and how the data from  edge to count transfers to be the same count, according to the edges detected)

    As you can see, the max number of the count is the 360, and I the irq is OFF. I dont need to know if it gave a complete turn. Once the count reaches 360, it goes to 0 and start again.

    the third: how can I reach the data from the N2HET?. I explain myself. Once every X time, I need the data so I can adjust the PI control. So I want to know how can I do that.... 

     

    best regards