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.

Use of PCNT

I am using the N2HET PCNT instruction to measure the shaft speed of a 6-pole machine. There is a sine wave generated by the machine which is then converted to a square wave by electronics, and then sampled in my NHET program as this:

L22 PCNT {next=L23,hr_lr=HIGH,reqnum=0,request=NOREQ,type=FALL2FALL,pin=5,period=0,data=0,hr_data=0}

The problem I have now is that by the physical nature of the machine, each pole produces pulses that are not exactly alike, so I am getting some jitter in my speed readings. What I would like to do is be able to measure every sixth pulse, so I would be measuring the pulse produced by the same physical pole each time.

Do you have a suggestion how I might accomplish this?

Thanks

Alan

  • I am not sure what exactly you want to measure. If you can draw a picture, It will help me understand.

    Usually, play with ECNT, WCAP, CNT, BR and PCNT instructions can get this solved.

    Regards,

    Haixiao

  • I have been measuring the time for 1/6th of a revolution (from falling edge to falling edge of a pulse created by one pole). Now I would like to measure the time of one whole revolution ( the falling edge of every sixth pulse, which would be created by the same pole each time).

    Somehow, I need to be able to count the pulses, and accumulate the result of six consecutive PCNT measurements.

  • Alan,

    The PCNT instruction sets the 'Z' flag whenever an edge is detected.  

    So lets assume you might do something like this:

    L22 PCNT {next=L23,hr_lr=HIGH,reqnum=0,request=NOREQ,type=FALL2FALL,pin=5,period=0,data=0,hr_data=0}
    LC1 BR { event=NZ, cond_addr=L23 }                            ; Skip to L23 unless PCNT detected edge
    LC2 DJNZ {reg=NONE, data=5, cond_addr=L23}                    ; Count 5, 4, 3, 2, 1, 0
    LC3 MOV32 { type=IMTOREG&REM, reg=NONE, remote=LC2, data=5, hr_data=0}; Reset DJNZ to '5'
    LC4 ADD {src1=REM, src2=ZERO, dest=IMM, data=0, hr_data=0, remote=L22}; Copy data from PCNT instruction 
    LC5 ... Do you want to notify the CPU that data is available in LC4? 
    L23 ... your code continues here

    The "ADD" at LC4 which is really a 'MOV' of sorts, is there to make a copy of the PCNT result.  If your CPU is responsive & fast compared to the time between each pole, you might skip this and have the CPU pick directly from the PCNT.  Otherwise the CPU can read the data from LC4 instead of L22 and it'll be valid for much longer.  

    Another option could be to average the last 6 values captured - if you want to do that instead let me know.

    Note that PCNT is not valid for the initial measurement, because on startup you assume you're starting your PCNT asynchronously so the first edge's results are just a partial period measurement (depending on where you started).

    Didn't show anything in the above code to handle that case intentionally, however counting every 6th pulse and grabbing pulse 5 not pulse 0 does have the nice side-effect of handling this case in the N2HET rather than in the CPU.

     

  • Alan,

    Our replies crossed.   I think it would be straight forward to modify the above and actually accumulate 6 pulses with the ADD instruction in LC4,  for example like this:

    L22 PCNT {next=L23,hr_lr=HIGH,reqnum=0,request=NOREQ,type=FALL2FALL,pin=5,period=0,data=0,hr_data=0}
    LC1 BR { event=NZ, cond_addr=L23 }                            ; Skip to L23 unless PCNT detected edge
    LC2 ADD {src1=REM, src2=ZERO, dest=IMM, data=0, hr_data=0, remote=L22} ; Accumulate Pulses
    LC3 DJNZ {reg=NONE, data=5, cond_addr=L23}                    ; Count 5, 4, 3, 2, 1, 0
    LC4 ADD {src1=REM, src2=ZERO, dest=IMM, data=0, hr_data=0, remote=LC2}; Copy data from accumulator
    LC5 MOV32 { type=IMTOREG&REM, reg=NONE, remote=LC3, data=5, hr_data=0}; Reset DJNZ to '5'
    LC6 MOV32 { type=IMTOREG&REM, reg=NONE, remote=LC2, data=0, hr_data=0}; Reset Accumulator to '0'
    LC7 ... Do you want to notify the CPU that data is available in LC4? 
    L23 ... your code continues here