Stymied: Why are my data sometimes doubled?[SOLVED] - Page 1
Forum section: electronics / general

author: jpanhalt
author_rank: Super Contributor
timestamp: November 04, 2023, 11:33:39 am
content: Project is reading an older (1990's) Mitutoyo magnetic scale with SPC output.MCU: PIC16F1829 at 8 MHz.Language: Microchip (MPLab) MPASM. Snippet of the pertinent part of code (attached). Note, readings are stored in registers d1....d13.They are in consecutive registers in Bank 7 (big endian) to reduce the need for bank changes. Bit order in each 4-bit "byte" is reversed, i.e., b'0001' is 0x08, which is fairly common practice. Hence, I rotate receiving register right and swap nybbles to put the BCD data in the lowest nybble.Attachments:1) Assembly code2) Datasheet for reading the output. It is 52 bits presented as 13, 4-bit nybbles.3) Schematic4) O'scope with slow scan.5) O'scope with faster scan showing 1's. I read the data on the down slope of the clock.Here's the problem. Reads go fine; however, my results are usually double what the DRO on the Mitutoyo shows. Looks like a rotation problem, right? Unfortunately, that is not always the case. The first couple of reads at the same sensor setting during hardware simulation show the correct value, such as 0.1140. I can repeat that 2 or 3 times, but then it becomes 0.2280 and stays that way. The read value changes appropriately with movement of the scale but remains double. A release version of the code also gives double values, but it is impossible to know what the first 2 readings were. Of course, any value larger than d.4 gets corrupted as the ASCII-based printing routine is limited to 0...9 for each digit. The first 4 "bytes" read all F, i.e., 0x0F consistently. I have tried running the MCU at lower and higher speeds from 500 kHz to 32 MHz without changing the behavior; although, it seems higher speeds >8 MHz may skip the first few correct reads. That latter observation is not easily reproduced.The !REQ signal is inverted by the N-mosfet. So, high on the scope (magenta trace) is actually pulling that input low on the sensor. I have tried running the mCU at lower and higher speeds from 500 kHz to 32 MHz without effectAny ideas of where the problem is?EDIT: Before anyone screams, the attachments are screwed up. They showed fine before posting. I am working on it. Update: All the intended attachments are there, the Mitutoyo datasheet is a little corrupted. And now, the order is not as shown in the body of my post. I don't know how to change that without deleting and starting all over.EDIT2: The first of the Mitutoyo datasheet attachments seems to be corrupted. So, I deleted it. The second has 2 copies of the same page. I don't know why, but it is probably better to leave it than try to fix it.

author: DavidAlfa
author_rank: Super Contributor
timestamp: November 04, 2023, 12:35:53 pm
content: Code:listp=16f1829 ; list directive to define processor#include<p16f1829.inc> ; processor specific variable definitionserrorlevel -302,-305RADIX DEC__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF;10/27/23 changed CLKOUTEN to off!; _____; VDD| |VSS; Req/RA5| |RA0/ICSPDAT; Clk_in/RA4| |RA1/ICSPCLK; RST/!MCLR/RA3| |RA2; RC5| |RC0/Ser_in; RC4| |RC1; RC3| |RC2/LED; RC6| |RB4 ;/Ser_out; RC7| |RB5/USART RX; USART TX/RB7|_____|RB6;;ConstantsRST equ 3 ;PORTAClk_in equ 4 ;PORTAReq equ 5 ;PORTASer_out equ 7 ;PORTBSer_in equ 0 ;PORTCLED equ 2 ;PORTC;flag0 definitions; flag0,0 set = rx in progressListcblock 0x20 ;0x20 thru 0x6F are GP RAM in Bank0char ;used in BIN2ASCIIchar_lo ;used in BIN2ASCIItxbyte;input to Put232;bit_ctrL ;counts 4-bit words (BCD) in 13-word (52-bit) received string;bit_ctrH ;counts BCD words in 13-word received stringendccblock 0x3A0 ;bank 7 GP RAMd1 ;read datad2 ;read datad3 ;read datad4 ;read data;NB: The first 4 "bytes" are 0xF and can be ignoredd5 ;read data, sign bitd6 ; " ,MSD (BCD)d7 ; " ,BCDd8 ; " ,BCDd9 ; " ,BCDd10 ; " ,BCDd11 ; " ,LSD (BCD)d12 ; " ,decimal pointd13 ; " ,units (0x0=mm, 0x8=inch)endccblock 0x70 ;beginning of common RAMbit_ctr;used in Put232 and ISR during data collectiondelayhi;used delay macroflag0 ;flagstemp0 ;general purpose temporary regendc;<snipped>IOCIF_init ;(IOCIF=INTCON,0) on positive edge of Mitutoyo clock (Clk_in)movlb 7 ; |B7bsf IOCAN,Clk_in ;RA4 negative edge |B7clrf IOCAF ;clear all IOC flags |B7clrf INTCON ;INTCON,IOCIE ;enable IOC |B?FSR0_initmovlw high(d1) ;Mitutoyo little endian MSByte has lowest number |B7movwf FSR0H ;used same endian here |B7movlw low(d1) ; |B7movwf FSR0L ; |B7Mainmovlw low(d1) ;initialize FSR0 for new data |B7movwf FSR0L ;movlb 2 ; |B2bsf LATA,Req ;request data (short !REQ to ground) |B2btfss INTCON,IOCIF ;check for first clock bit |B?bra $-1 ; |B?call GetData ; |B2call ClrDisplay ; |B7call Printf ; |B7call ClrData ;returns |B7 |B7bra MainGetDatamovlb 0 ; |B0lsrf PORTC,w ;move PORTC,Ser_in state to STATUS,0 |B0rrf INDF0,f ;reverse bit ordermovlb 7 ; |B7clrf IOCAF ;get ready to detect next bit |B7decfsz bit_ctr,f ;Common RAM |B7bra Nextbit ;continue reading current nubble |B7;11/02 test nybble received, reset !REQ high; movlb 2 ;This location stops "Nextbit"; bcf LATA,Req; movlb 7;11/02 test doneswapf INDF0,f ;4-bit nybble received, divide nybble by 16 |B7comf INDF0,f ;compensate for inversion |B7movlw 0x3F ; |B7andwf INDF0,F ;converts 0xF(BCD) to 0x(ASCII#) |B7bsf bit_ctr,2 ;refresh bit_ctr to d.4 |B7incf FSR0L,f ;get next nybble of data |B7movlw low(d13+1) ;detect end of data |B7xorwf FSR0L,wbtfss STATUS,2; subwf FSR0L,w ; |B7; btfss STATUS,0 ;clear when incremented FSR0L > low(FSR0(d13)) |B7bra Nextbit ;get next 4-but byte |B7movlb 2 ;read done |B2bcf LATA,Req ; |B2movlb 7 ; |B7movlw low(d1) ;end of read, reset FSR0 for next read |B7movwf FSR0L ; " |B7clrf IOCAF ;11/02 Should not make a difference |B7return ; |B7Nextbitbtfss IOCAF,Clk_in ;check clock flag for next bit |B7bra $-1 ;keep checking |B7bra GetData ; |B7END

author: DavidAlfa
author_rank: Super Contributor
timestamp: November 04, 2023, 12:44:29 pm
content: You're holding REQ low for the entire nibble, you should release it after the first bit was received.Where are you checking that first 4 nibbles were 0xF? You might go out of sync otherwise.Also, why asm? PIC16F183xx are much newer and perform pretty nice in C.

author: jpanhalt
author_rank: Super Contributor
timestamp: November 04, 2023, 01:28:33 pm
content: 1) Yes, that is what he datasheet says/implies, but it didn't work, either in code or by actually checking it on the oscilloscope with a release version. The clock stopped when I released the REQ. A current datasheet for the same series, but those devices have added controls, says to release it before the last bit (attachment). Doable but hard to do. What I did was release it at the end of the last byte. The last byte is irrelevant as it tells the processor whether dimensions are metric or imperial. My sensor has that (imperial) as a setting and the last byte doesn't matter. Given the way I capture the data, it is hard to see how the results wouldstart to be doubled after the first few reads. It seems to me that a double read, noise,etc. would lead to corruption of values, but not simply double values. Despite that theory, I tried setting bit_count to 3 and 5 and only got corrupted results. (With right shifts, too few rotations should double results. I have focused on that section and just don't see how it can happen. Maybe fresh eyes will help.).2) Yes, I check the first 4 nubbles and they ar 0x0F (actually 0x3F for printing).3) I code in Assembly because I like to be in control.I am too old to start learning C, and a math error like this is probably not related to whether the code is in ASM or C.

author: jpanhalt
author_rank: Super Contributor
timestamp: November 04, 2023, 01:30:16 pm
content: Here is the code using code tags. Maybe it is more readable.Code:listp=16f1829; list directive to define processor#include <p16f1829.inc> ; processor specific variable definitionserrorlevel -302,-305RADIXDEC__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF;10/27/23 changed CLKOUTEN to off!; _____; VDD| |VSS; Req/RA5| |RA0/ICSPDAT; Clk_in/RA4| |RA1/ICSPCLK; RST/!MCLR/RA3| |RA2; RC5| |RC0/Ser_in; RC4| |RC1; RC3| |RC2/LED; RC6| |RB4 ;/Ser_out; RC7| |RB5/USART RX; USART TX/RB7|_____|RB6;;ConstantsRSTequ3;PORTAClk_inequ4;PORTAReqequ5;PORTASer_outequ7;PORTBSer_inequ0;PORTCLEDequ2;PORTC;flag0 definitions; flag0,0 set = rx in progressListcblock0x20;0x20 thru 0x6F are GP RAM in Bank0char;used in BIN2ASCIIchar_lo;used in BIN2ASCIItxbyte;input to Put232;bit_ctrL ;counts 4-bit words (BCD) in 13-word (52-bit) received string;bit_ctrH ;counts BCD words in 13-word received stringendccblock0x3A0;bank 7 GP RAMd1;read datad2;read datad3;read datad4;read data;NB: The first 4 "bytes" are 0xF and can be ignoredd5;read data, sign bitd6; " ,MSD (BCD)d7; " ,BCDd8; " ,BCDd9; " ,BCDd10; " ,BCDd11; " ,LSD (BCD)d12; " ,decimal pointd13; " ,units (0x0=mm, 0x8=inch)endccblock0x70;beginning of common RAMbit_ctr;used in Put232 and ISR during data collectiondelayhi;used delay macroflag0;flagstemp0;general purpose temporary regendc;<snipped>IOCIF_init;(IOCIF=INTCON,0) on positive edge of Mitutoyo clock (Clk_in)movlb7; |B7bsfIOCAN,Clk_in;RA4 negative edge |B7clrfIOCAF;clear all IOC flags |B7clrfINTCON;INTCON,IOCIE ;enable IOC |B?FSR0_initmovlwhigh(d1);Mitutoyo little endian MSByte has lowest number |B7movwfFSR0H;used same endian here |B7movlwlow(d1); |B7movwfFSR0L; |B7Mainmovlwlow(d1);initialize FSR0 for new data |B7movwfFSR0L;movlb2; |B2bsfLATA,Req;request data (short !REQ to ground) |B2btfssINTCON,IOCIF;check for first clock bit |B?bra$-1; |B?callGetData; |B2callClrDisplay; |B7callPrintf; |B7callClrData;returns |B7 |B7braMainGetDatamovlb0; |B0lsrfPORTC,w;move PORTC,Ser_in state to STATUS,0 |B0rrfINDF0,f;reverse bit ordermovlb7; |B7clrfIOCAF;get ready to detect next bit |B7decfszbit_ctr,f;Common RAM |B7braNextbit;continue reading current nubble |B7;11/02 test nybble received, reset !REQ high; movlb 2 ;This location stops "Nextbit"; bcf LATA,Req; movlb 7;11/02 test doneswapfINDF0,f;4-bit nybble received, divide nybble by 16 |B7comfINDF0,f;compensate for inversion |B7movlw0x3F; |B7andwfINDF0,F;converts 0xF(BCD) to 0x(ASCII#) |B7bsfbit_ctr,2;refresh bit_ctr to d.4 |B7incfFSR0L,f;get next nybble of data |B7movlwlow(d13+1);detect end of data |B7xorwfFSR0L,wbtfssSTATUS,2; subwf FSR0L,w ; |B7; btfss STATUS,0 ;clear when incremented FSR0L > low(FSR0(d13)) |B7braNextbit;get next 4-but byte |B7movlb2;read done |B2bcfLATA,Req; |B2movlb7; |B7movlwlow(d1);end of read, reset FSR0 for next read |B7movwfFSR0L; " |B7clrfIOCAF;11/02 Should not make a difference |B7return; |B7NextbitbtfssIOCAF,Clk_in;check clock flag for next bit |B7bra$-1;keep checking |B7braGetData; |B7END

author: DavidAlfa
author_rank: Super Contributor
timestamp: November 04, 2023, 01:35:37 pm
content: Maybe it's not doubled, but shifted by 1 bit?0.1140 would be 0000 0001 0001 0100 0000.If you miss a clock bit, you'll get 0000 0010 0010 1000 0000 (0.228).Make proper code, count the bits, add timeout countdown, wait of the first 4 sync nibbles (F F F F) .You read the data in the clock faling edge, so release REQ in that exact moment, in last bit.No need to wait for clck rising? Anyways REQ doesn't seem the problem here.

author: Andy Watson
author_rank: Super Contributor
timestamp: November 04, 2023, 02:05:04 pm
content: Quote from: jpanhalt on November 04, 2023, 11:33:39 amIs it ?Probably just a typo but Q1 is drawn wrongly on the diagram - are we to assume that it has been wired correctly? Have you put the scope on the actual REQ pin? Seems a little odd that guage does not respond to the datasheet as per the REQ function.

author: jpanhalt
author_rank: Super Contributor
timestamp: November 04, 2023, 02:10:38 pm
content: I will try that counting the whole string to see if there is a lost bit early on.A left shift with an input, such as, 1111,1111,1111,1111,xxxx,0001,0001,0010,1001,etc. would give a bunch of doubles as expected plus some odd values (i.e., an increase by 1 in preceding bytes) preceding the 9's.I had just pulled the proto board out to change the CD4069 to an Schmitt inverter (e.g, 74xx14) as shown in some of the Mitutoyo datasheets.Will post a follow-up. After that is done.John

author: jpanhalt
author_rank: Super Contributor
timestamp: November 04, 2023, 02:15:43 pm
content: Yes, the FDV303 is shown incorrectly, but wired correctly. There might be more modern devices available, but I started using it in 2008 or so. I will have see what happened with my EAGLE. EDIT: I simply grabbed the wrong symbol (FDN360P) without reading the description carefully. It is now fixed in my schematic. Thanks,

author: DavidAlfa
author_rank: Super Contributor
timestamp: November 04, 2023, 02:34:32 pm
content: If Tck is ~500us, setup Timer2 so it overflows in 2ms.Always check for overflow when waiting for clock.On overflow, release REQ, wait another 2ms before retrying.If clock is detected during waiting, reset timer counter (Reload the 2ms waiting), only restart when idling.Why do you need the buffers? It's a very slow signal, no need for that?Neither need to invert the clock or data signal, use IOCAP instead IOCAN.Or use the SPI peripheral to receive the 13 bytes.Same for REQ. You can do it by toggling the GPIO between input (HI-Z) or output set to low.Set LATA=0, then simply bcf/bsf TRISA0 bit.

author: jpanhalt
author_rank: Super Contributor
timestamp: November 04, 2023, 03:45:02 pm
content: I am leaning toward a clock issue based on the attachment. Code clearly releases REQ after the last byte, but the clock has 2 more beats. Total beats for the read period are sill just 52.I need to work on that. Maybe forget about capturing byte 13. Thus, the statement about releasing REQ before the last bit would be fulfilled.As for buffers, that's what Mitutoyo recommends. I added the two extra resistors to the inputs of the inverter to make proper LPF's, which are not shown in my schematic. It made no difference.

author: DavidAlfa
author_rank: Super Contributor
timestamp: November 04, 2023, 07:19:48 pm
content: Also keep it simple, why are you storing variables in different banks without needing so? It only adds bank switching mess.Did a bit of work, though incomplete, I think it will work better, follow program flow.You still need to implement timer2 init, DecimalPoint, MeasureUnit, and probably other fixes.All BANKSEL should be checked out. I have not taken extreme care of all bank switching.But shows the idea, and the way to avoid unwanted/undefined behavior.Code:Listcblock 0x20 ;0x20 thru 0x6F are GP RAM in Bank0timeoutbit_countdata_countd5 ;read data, sign bitd6 ; " ,MSD (BCD)d7 ; " ,BCDd8 ; " ,BCDd9 ; " ,BCDd10 ; " ,BCDd11 ; " ,LSD (BCD)d12 ; " ,decimal pointd13 ; " ,units (0x0=mm, 0x8=inch)endcIOCIF_init ;(IOCIF=INTCON,0) on positive edge of Mitutoyo clock (Clk_in)BANKSEL IOCAN ;bsf IOCAN,Clk_in ;RA4 negative edge |B7clrf IOCAF ;clear all IOC flags |B7clrf INTCON ;INTCON,IOCIE ;enable IOC |B?FSR0_initmovlw high(d5) ;Mitutoyo little endian MSByte has lowest number |B7movwf FSR0H ;used same endian here |B7movlw low(d5) ; |B7movwf FSR0L ; |B7Mainmovlw low(d5) ;initialize FSR0 for new data |B7movwf FSR0L ;BANKSEL LATA ;bsf LATA,Req ;request data (short !REQ to ground) |B2call GetData ; |B2btfsc timeout,1 ;Check if timeout ocurredbra Timeoutcall ClrDisplay ; |B7call Printf ; |B7call ClrData ;returns |B7bra MainGetDatamovlw 8 ;init valuesmovwf bit_countmovlw 13clrf data_countGetNibblecall GetClk ;Wait for clockbtfsc timeout,1 ;Check if timeout ocurredreturn ;Timeout ocurredmovfw PORTC ;Read PORTCiorwf INDF0,f ;OR value with current nibble datadecfsz bit_count,f ;Check if nibble is donebra GotNibble ;Donerrf INDF0,f ;Not done. Rotate right, make room for next bit (Data is stored in the 4 MSB)bra GetNibble ;ContinueParseNibbleswapf INDF0,flag ;Swap nibblesmovlw 10 ;Subtract 10subwf data_count,w ;To the data countbtfsc STATUS,C ;Check for carry bit (If set, we already received more than 4 nibbles, not header)bra Check_header ;Less than 5 bytes received, check for good headermovlw 9 ;This is not header, subtract 9subwf data_count,w ;To the data countbtfss STATUS,Z ;Check for zero bitbra CheckData ;Not sign data, skipmovlw 0x20 ;This is d5, Sign data. Load ASCII "Space" into waddwf INDF0,f ;Add to sign data (Convert to space, or later to '-' symbol)movlw 0 ;Preload w with 0 for the next stepbtfsc INDF0,0 ;Check for sign LSB (Now it would be 0x21)movlw 0xC ;Override w with 0xC, convert to '-' symbol by adding 0xC (0=x21->0x2D)addwf INF0,f ;Update symbol databra Nibble_OK ;DoneCheckDatamovlw 2 ;Subtract 2subwf data_count,w ;To the data countbtfsc STATUS,C ;Check for carry bit (If set, we already received more than 4 digits)bra DecimaPoint ;This is decimal pointmovlw 1 ;Subtract 1subwf data_count,w ;To the data countbtfsc STATUS,C ;Check for carry bit (If set, we already received more than 4 digits)bra MeasureUnitDecimalPoint;blah blahbra ParseDone ;DoneMeasureUnit;blah blahbra ParseDone ;Donemovlw 0x30 ;Add 0x30addwf INF0,f ;To current data, to convert to ASCIINibble_OKincf FSR0L,f ;point to next databra ParseDone ;DoneCheck_headermovlw 0xF ;Subtract 0xF <--- For non-inverted data input.subwf INDF0,w ;From current nibble <--- For non-inverted data input.movfw INDF0 ;Read nibble <--- For inverted data input.btfss STATUS,Z ;check for zero bit (We should have received 0xF, header nibble)bra Nibble_OK ;OK, Receive next nibblecall SetTimeout ;Bad header data, trigger a timeoutreturn ;Return to mainGotNibblebra ParseNibbleParseDonedecfsz data_count,f ;Decrease data count, got all 13 nibbles?bra NextNibble ;No, continuemovlb 0 ;Yesreturn ;GetClkclrf IOCAF ;Get ready to detect next bit |B7clrf TMR2,f ;Clear the counterclrf timeout,f ;Clear the timeout flagbcf PIR,TMR2IF ;Clear timer flagbtfsc IOCAF, Clk_in ;check clock flag for next bit |B7return ;Got bitbtfss PIR,TMR2IF ;Check for timer overflow (Timeout)bra GetClk ;No timeout, keep waitingSetTimeoutbsf timeout,1 ;Set timeout flagreturn ;Timeout ocurredTimeoutBANKSEL LATA ;bcf LATA,Req ;Release request dataBANKSEL TMR2 ;clrf TMR2,f ;Clear the counterbcf PIR,TMR2IF ;Clear timer flagTimeout_waitbtfsc PIR,TMR2IF ;Check for timer overflow (Timeout)bra Main ;Timeout done, restartbtfss IOCAF, Clk_in ;Not done, check if clock flag is setbra Timeout_wait ;Clock flag not set, keep waitingclrf TMR2,f ;Got clock signal! Clear the counter (Reset the timeout wait)bcf PIR,TMR2IF ;Clear timer flagclrf IOCAF ;Get ready to detect next bitbra Timeout_wait ;Keep waitingEND

author: jpanhalt
author_rank: Super Contributor
timestamp: November 04, 2023, 09:52:09 pm
content: @ David,This project actually dates back to one of my first MCU projects in 2008 when I just used the sign bit to control threading (i.e., stop the carriage) on a small lathe. That was very easy to do. My eventual goal will look only at d5(sign) to d11, but I figured for development to read the full transmission. Is d12 (decimal point) important? Not for this scale using inches. Resolution is limited to 4 places. In fact, d6 is not important as the scale is less than 10 inches long, nor is d13 for me.Right now, I have a lot on my mind with a personal matter. Today was for this project. I started at 3:30AM, and the afternoon was dedicated to Ohio State football (our state university team). That team drives me crazy. It starts cold, then gets going in the second half unless it is playing a pushover. It won again today and is undefeated for the season, but its toughest opponent is yet to come.Tomorrow and most of Monday will be devoted to the personal matter. I will get back to this project in earnest late Monday.I really appreciate your advice, as you freely offer code suggestions. I will try that code. I am not sure SPI will be useful, but will also give it a try. I have used SPI before and with several projects, but that may not work here. It is an intriguing idea, though, unique (to me) and is definitely worth a try.Regards, John

author: jpanhalt
author_rank: Super Contributor
timestamp: November 09, 2023, 05:40:23 pm
content: The personal matter wasted more than a week. Today, I had a clear mind and was able to do some thought. Circuit has been simplified and the buffers deleted, despite Mitutoyo's suggestions. That gives a non-inverted signal with inverted clock (i.e., capture data at clock low). In the attached images, the REQ is measured right at the connector , not MCU as before, and is true, i.e., active low.I simplified the code and just poll Ser_in to start capturing data, then poll Clk_in for actual data. Only 9 registers are used and the first 4 "bytes" are ignored, except as a signal to release the REQ line and let it go high (magenta trace).So, what was the problem? My clue was that the negative sign was not being captured, while data were doubled. It was not that my bit_ctr or byte_ctr were wrong. I was capturing the very first data before being sure the clock was low. I marked with red that point. That shifted the rest of the data. The simple, obvious errors are usually the hardest to catch. There are still some small glitches that should be easy to fix.Corrected code:Code:movlw 4 ; |B0movwf bit_ctr ; |B0movlw low(d5) ;initialize FSR0 for new data |B0movwf FSR0L ; |B0movlb 2 ; |B2bsf LATA,Req ;request data (short !REQ to ground) |B2movlb 0 ;11/06/23 |B0btfsc PORTC,0 ;Ser_in |B0bra $-1 ;check for falling edge on !Ser_in |B0movlb 2 ;clock running, can release !REQ |B2bcf LATA,Req ; " |B2movlb 0 ; |B0;start 11/9/23btfsc PORTA,Clk_in ;be sure clock is lowbra $-1 ;;end 11/9/23call GetData ; |B0nopcall ClrData ;bra Main ;returns in B0 |B0Attachments:1) DS1Z... Full data (omitted are registers 1..4)2) Expanded and highlighted error3) Watch window for -0.1450

author: jpanhalt
author_rank: Super Contributor
timestamp: November 12, 2023, 10:51:49 am
content: In case anyone is curious, here is working code as of this morning in release form. The display is an older SparkFun 4x20. It is flaky. Delays are added to make it work. With a better/faster display, they should not all be necessary.The code includes a "clear data" routine. As rotations are used to add each new 4-bit byte, and the older data is masked before printing with an "andwf INDF0,f" clearing old data is not required. It might be useful to retain if one wanted to do something like calculate a feed rate.This code and design (without the buffers) should work with any enhanced mid-range PIC, including the 12F1xxx. With slight modification and software Put232, it should even work with a baseline 12F509.