I in essence made the sort of simplified counter you suggest from the encoder.c with the addition of some logging in the update thread and the addition of some fields to the cntr struct to keep track of runs between counts and time between counts:
static void update(void *arg, long period) { counter_t *cntr; atomic *buf; int n; unsigned char state; int latch, old_latch, rising, falling; cntr = arg; for (n = 0; n < howmany; n++) { cntr->runs_between = cntr->runs_between + 1; cntr->time_between = cntr->time_between + period; rtapi_print_msg(RTAPI_MSG_ERR,"ENCODER update running\n"); buf = (atomic *) cntr->bp; /* get state machine current state */ state = cntr->state; /* add input bits to state code */ if (*(cntr->phaseA)) { rtapi_print_msg(RTAPI_MSG_ERR,"ENCODER phase A true\n"); state |= SM_PHASE_A_MASK; } if (*(cntr->phaseB)) { state |= SM_PHASE_B_MASK; } /* look up new state */ if ( *(cntr->counter_mode) ) { state = lut_ctr[state & (SM_LOOKUP_MASK & ~SM_PHASE_B_MASK)]; } else if ( *(cntr->x4_mode) ) { state = lut_x4[state & SM_LOOKUP_MASK]; } else { state = lut_x1[state & SM_LOOKUP_MASK]; } /* should we count? */ if (state & SM_CNT_UP_MASK) { rtapi_print_msg(RTAPI_MSG_ERR,"ENCODER saw a count\n"); rtapi_print_msg(RTAPI_MSG_ERR,"ENCODER time between: %d\n", cntr->time_between); rtapi_print_msg(RTAPI_MSG_ERR,"ENCODER runs between: %d\n", cntr->runs_between); (*cntr->raw_counts)++; cntr->runs_between = 0; cntr->time_between = 0; buf->raw_count = *(cntr->raw_counts); buf->timestamp = timebase; buf->count_detected = 1; } else if (state & SM_CNT_DN_MASK) { (*cntr->raw_counts)--; buf->raw_count = *(cntr->raw_counts); buf->timestamp = timebase; buf->count_detected = 1; } ... which when run gives me the following example output (grep'ing for just the times and runs between): Jun 30 17:48:41 scott-desktop kernel: [ 4078.211529] ENCODER time between: 1015869 Jun 30 17:48:41 scott-desktop kernel: [ 4078.211542] ENCODER runs between: 51 Jun 30 17:48:41 scott-desktop kernel: [ 4078.243537] ENCODER time between: 1015869 Jun 30 17:48:41 scott-desktop kernel: [ 4078.243554] ENCODER runs between: 51 Jun 30 17:48:41 scott-desktop kernel: [ 4078.244788] ENCODER time between: 1035788 Jun 30 17:48:41 scott-desktop kernel: [ 4078.244804] ENCODER runs between: 52 Jun 30 17:48:41 scott-desktop kernel: [ 4078.245520] ENCODER time between: 956112 Jun 30 17:48:41 scott-desktop kernel: [ 4078.245524] ENCODER runs between: 48 Jun 30 17:48:41 scott-desktop kernel: [ 4078.246410] ENCODER time between: 1015869 Jun 30 17:48:41 scott-desktop kernel: [ 4078.246424] ENCODER runs between: 51 Jun 30 17:48:41 scott-desktop kernel: [ 4078.247367] ENCODER time between: 956112 Jun 30 17:48:41 scott-desktop kernel: [ 4078.247381] ENCODER runs between: 48 Jun 30 17:48:41 scott-desktop kernel: [ 4078.248402] ENCODER time between: 1035788 Jun 30 17:48:41 scott-desktop kernel: [ 4078.248417] ENCODER runs between: 52 Jun 30 17:48:41 scott-desktop kernel: [ 4078.249451] ENCODER time between: 1035788 Jun 30 17:48:41 scott-desktop kernel: [ 4078.249455] ENCODER runs between: 52 Jun 30 17:48:41 scott-desktop kernel: [ 4078.250414] ENCODER time between: 976031 Jun 30 17:48:41 scott-desktop kernel: [ 4078.250429] ENCODER runs between: 49 Jun 30 17:48:41 scott-desktop kernel: [ 4078.251506] ENCODER time between: 1075626 Jun 30 17:48:41 scott-desktop kernel: [ 4078.251510] ENCODER runs between: 54 Jun 30 17:48:41 scott-desktop kernel: [ 4078.252586] ENCODER time between: 1095545 Jun 30 17:48:41 scott-desktop kernel: [ 4078.252600] ENCODER runs between: 55 Jun 30 17:48:41 scott-desktop kernel: [ 4078.253423] ENCODER time between: 836598 Jun 30 17:48:41 scott-desktop kernel: [ 4078.253438] ENCODER runs between: 42 Jun 30 17:48:41 scott-desktop kernel: [ 4078.254339] ENCODER time between: 916274 Jun 30 17:48:41 scott-desktop kernel: [ 4078.254353] ENCODER runs between: 46 Jun 30 17:48:41 scott-desktop kernel: [ 4078.255533] ENCODER time between: 1195140 Jun 30 17:48:41 scott-desktop kernel: [ 4078.255547] ENCODER runs between: 60 Jun 30 17:48:41 scott-desktop kernel: [ 4078.256330] ENCODER time between: 796760 Jun 30 17:48:41 scott-desktop kernel: [ 4078.256344] ENCODER runs between: 40 Jun 30 17:48:41 scott-desktop kernel: [ 4078.257366] ENCODER time between: 1035788 Jun 30 17:48:41 scott-desktop kernel: [ 4078.257380] ENCODER runs between: 52 Jun 30 17:48:41 scott-desktop kernel: [ 4078.258323] ENCODER time between: 956112 Jun 30 17:48:41 scott-desktop kernel: [ 4078.258336] ENCODER runs between: 48 Jun 30 17:48:41 scott-desktop kernel: [ 4078.259278] ENCODER time between: 956112 Jun 30 17:48:41 scott-desktop kernel: [ 4078.259292] ENCODER runs between: 48 Jun 30 17:48:41 scott-desktop kernel: [ 4078.260315] ENCODER time between: 1035788 Jun 30 17:48:41 scott-desktop kernel: [ 4078.260329] ENCODER runs between: 52 Jun 30 17:48:41 scott-desktop kernel: [ 4078.261291] ENCODER time between: 976031 Jun 30 17:48:41 scott-desktop kernel: [ 4078.261305] ENCODER runs between: 49 Jun 30 17:48:41 scott-desktop kernel: [ 4078.262266] ENCODER time between: 976031 Jun 30 17:48:41 scott-desktop kernel: [ 4078.262280] ENCODER runs between: 49 Jun 30 17:48:41 scott-desktop kernel: [ 4078.263323] ENCODER time between: 1055707 Jun 30 17:48:41 scott-desktop kernel: [ 4078.263337] ENCODER runs between: 53 Jun 30 17:48:41 scott-desktop kernel: [ 4078.264299] ENCODER time between: 976031 Jun 30 17:48:41 scott-desktop kernel: [ 4078.264313] ENCODER runs between: 49 Jun 30 17:48:41 scott-desktop kernel: [ 4078.265487] ENCODER time between: 1175221 Jun 30 17:48:41 scott-desktop kernel: [ 4078.265490] ENCODER runs between: 59 Jun 30 17:48:41 scott-desktop kernel: [ 4078.266422] ENCODER time between: 936193 Jun 30 17:48:41 scott-desktop kernel: [ 4078.266426] ENCODER runs between: 47 Jun 30 17:48:41 scott-desktop kernel: [ 4078.267327] ENCODER time between: 916274 Jun 30 17:48:41 scott-desktop kernel: [ 4078.267342] ENCODER runs between: 46 Jun 30 17:48:41 scott-desktop kernel: [ 4078.268503] ENCODER time between: 1175221 Jun 30 17:48:41 scott-desktop kernel: [ 4078.268517] ENCODER runs between: 59 Jun 30 17:48:41 scott-desktop kernel: [ 4078.269529] ENCODER time between: 1015869 Jun 30 17:48:41 scott-desktop kernel: [ 4078.269533] ENCODER runs between: 51 Jun 30 17:48:41 scott-desktop kernel: [ 4078.270446] ENCODER time between: 916274 Jun 30 17:48:41 scott-desktop kernel: [ 4078.270450] ENCODER runs between: 46 Jun 30 17:48:41 scott-desktop kernel: [ 4078.271231] ENCODER time between: 796760 Jun 30 17:48:41 scott-desktop kernel: [ 4078.271245] ENCODER runs between: 40 Jun 30 17:48:41 scott-desktop kernel: [ 4078.272267] ENCODER time between: 1035788 Jun 30 17:48:41 scott-desktop kernel: [ 4078.272281] ENCODER runs between: 52 Jun 30 17:48:41 scott-desktop kernel: [ 4078.273243] ENCODER time between: 976031 Jun 30 17:48:41 scott-desktop kernel: [ 4078.273257] ENCODER runs between: 49 Jun 30 17:48:41 scott-desktop kernel: [ 4078.274259] ENCODER time between: 1015869 Jun 30 17:48:41 scott-desktop kernel: [ 4078.274274] ENCODER runs between: 51 The between-pulse variance is clear in that data, which I think for the most part rules out an encoder.c defect. It is seeing and counting the pulses. I think my next step is to either get a hold of a real frequency generator or scope (local hackerspace to the rescue!) so I can confirm my current LM331-based frequency generator. Unfortunately, that will have to wait a week as I am heading out on vacation today. Thanks much for the solid advice so far and I'll update this thread once I get a good look at my frequency generator to confirm how stable it is. Scott On Sat, Jun 30, 2012 at 7:10 PM, Peter C. Wallace <p...@mesanet.com> wrote: > On Sat, 30 Jun 2012, Scott Hasse wrote: > > > Date: Sat, 30 Jun 2012 18:01:02 -0500 > > From: Scott Hasse <scott.ha...@gmail.com> > > Reply-To: "Enhanced Machine Controller (EMC)" > > <emc-users@lists.sourceforge.net> > > To: "Enhanced Machine Controller (EMC)" <emc-users@lists.sourceforge.net > > > > Subject: Re: [Emc-users] encoder component in counter mode velocity > stability > > issues > > > > My base thread is 20000 ns (50 khz) and my servo thread is 1000000 ns. I > > am running the update-counters in the base thread. I was thinking that > > should limit my sampling noise to ~2% but instead it is ~20%. I don't > > think I'm getting bounce errors as the parallel port pins in halscope > show > > regular pulses as I would expect. To understand this issue better, I've > > set up the following standalone hal configuration: > > > > ****************** > > loadrt threads name1=base-thread period1=20000 name2=servo-thread > > period2=1000000 > > loadrt probe_parport > > loadrt hal_parport cfg="0x378 out " > > setp parport.0.reset-time 5000 > > addf parport.0.read base-thread > > addf parport.0.write base-thread > > addf parport.0.reset base-thread > > > > loadrt encoder num_chan=1 > > loadrt lowpass > > setp encoder.0.counter-mode true > > net encoder-0-phase-A encoder.0.phase-A <= parport.0.pin-10-in > > setp encoder.0.position-scale 1.0 > > addf lowpass.0 servo-thread > > setp lowpass.0.gain 0.001 > > net lowpass-0-in lowpass.0.in <= encoder.0.velocity > > net temp-0-in-filtered <= lowpass.0.out > > addf encoder.update-counters base-thread > > addf encoder.capture-position servo-thread > > start > > ****************** > > > > that I kick off like so: > > > > halrun -U > > sudo /etc/init.d/realtime restart > > halcmd -f thermal-input.hal > > halmeter & > > > > and added some logging to the encoder.c component and installed it via: > > > > sudo comp --install encoder.c > > > > and then I see the my additional error-level logging in /var/log/messages > > > > As an aside, I was astounded how easy it is to develop (or at least > modify > > and debug existing) c-level components. Great job to all who have made > > that system what it is. I thought it might take me days to get a > > re-compiled encoder.c component working and was pleased to find it was > > actually only minutes. > > > > Doing that showed me that although the base thread runs were sufficient > in > > number and capturing the transitions properly, there actually was > variance > > between the between-rising-edge times it was catching, ranging in a short > > sample from 817us to 1173us for what should be a fairly steady > 1khz/1000us > > signal. Modifying the encoder component to have it log a count of update > > runs between pulses shows anywhere from 40 to 60 runs between a rising > edge > > detection, but always averaging right at 50 and typically subsequent > > intervals compensating for the previous intervals in terms of overall > time. > > For instance, an interval with 45 base thread runs between a rising edge > > detected would be followed by an interval with 55 base thread runs. > > > > This is leading me to wonder about timing in the parport driver. I see > > there is a reset function for pushing values faster, but it seems like > that > > is for output. Is anyone aware of how input data propagates through the > > parport driver and if there are opportunities for delay? > > > > Thanks much, > > > > Scott > > > ------------------------------------------------------------------------------ > > Live Security Virtual Conference > > Exclusive live event will cover all the ways today's security and > > threat landscape has changed and how IT managers can respond. Discussions > > will include endpoint security, mobile security and the latest in malware > > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > > _______________________________________________ > > Emc-users mailing list > > Emc-users@lists.sourceforge.net > > https://lists.sourceforge.net/lists/listinfo/emc-users > > > a couple of thoughts: > > It seems unlikely that the parallel port driver could cause this large a > jitter, as it really only does a little bit munging and a direct inb or > outb > for the parallel port I/O (hal_parport.c). Also jitter this large would > pretty > much kill step generation > > Is it possible that your V-F has noise/hum ? A 1 KHz > square wave from a hardware stepgen or some other known source could test > this if thats handy. > > I wonder if its just a bug in the encoder comp (its pretty involved with > the 2 > threads and the possibility of the base thread interrupting the servo > thread > code) > > you might be able to check this with a simplified counter comp that just > counts base thread executions between signal rising edges (double buffered > of > course) > > Peter Wallace > Mesa Electronics > > (\__/) > (='.'=) This is Bunny. Copy and paste bunny into your > (")_(") signature to help him gain world domination. > > > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > Emc-users mailing list > Emc-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/emc-users > ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Emc-users mailing list Emc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/emc-users