A side note, a statement like
IF PORTC.4=1 THEN
actually sets PORTC.4 high.
Is this bug or feature?
I've added 1 transistor signal inverter, but no help. Also, your code does not work.
OK, I will give up with this idea.
A side note, a statement like
IF PORTC.4=1 THEN
actually sets PORTC.4 high.
Is this bug or feature?
I've added 1 transistor signal inverter, but no help. Also, your code does not work.
OK, I will give up with this idea.
This, to me, is the classic problem of how to tell (program) your micro controller to recognize and interpret the pattern.
The human brain combined with an eyeball can recognize it... now you just need to figure out how to translate that into code.
I would start by watching for the start pulse, which is longer than the other pulses. Then keep track of the width of the following pulses (or the width of the "low" part. Then watch for one or more extended "low" pulses.
Since you only need to differentiate between 0 and any other number/key press, then just watch for an extended "low" in a given time period after the extended "high" start pulse. If in the given time period you do not get any extended "low" pulses then the digit is "0" other wise if you get an extended "low" pulse then the keypress was non-zero.
Since the quantity of pulses in each character is always 34 then you should be able to just set up a counter to increment whenever the pulse is low and stop incrementing when the pulse goes back high. Then if the counter has incremented above a certain threshold then that particular "low" pulse was a "wide" one and indicates a non zero digit. (I hope that makes sense)
I believe it is easily do-able. you just need to distill it down to how to detect the extended low pulse that indicates a non-zero digit pressed.
that is how I would attack the challenge.
Last edited by Heckler; - 8th July 2016 at 16:13.
Dwight
These PIC's are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.
Code for that is in post #11 except it waits for transition from low to high to start measure 34 low intervals.
Yes, I know how to implement detection logically, I have no issues with algorithm, but I can't implement it in hardware, also, I can't understand, why statement
IF PORTC.4=1
or
IF PORTC.4=0
makes corresponding pin high or low?
I highly doubt that. I don't know how you're testing it, but if that's the case things are seriously broken.IF PORTC.4=1
or
IF PORTC.4=0
makes corresponding pin high or low?
You likely have some other issue.
The IF statement per se should not and I'm pretty sure does not twiddle the pin but if what you you're doing is somehing like......and there happens to be analog functions on the pins which you haven't disabled then the actual state of PortC.4 isn't read correctly and you're getting into the classic RMW issue where the "invalid" state of PortC.4 is being written back to PortC.4 when the write operation to PortC.1 occurs but without seeing the rest of the code it's hard to say for sure.Code:If PortC.4 = 0 THEN PortC.1 = 1 ENDIF
/Henrik.
Here is the complete code:
I have source of signal (chip with name grinded off, but holtek logo is recognizable), which is connected directly to PORTC.4. Also, scope is connected to same pin.Code:Include "modedefs.bas" ' Include serial modes TRISA = %11111111 ' Set PORTA to all input TRISC = %00000000 ' Sets all PortB pins to output ADCON1 = %10000101 ' Set PORTA analog and right justify result ADCON0=%00000000 low portc.4 low portc.5 X VAR PORTC.4 DEFINE LCD_DREG PORTB DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTB DEFINE LCD_RSBIT 0 DEFINE LCD_EREG PORTB DEFINE LCD_EBIT 1 DEFINE LCD_BITS 4 DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 1500 DEFINE LCD_DATAUS 44 DEFINE OSC 4 lcdout "test 2" PAUSE 500 LABEL VAR WORD DROEBITI VAR WORD taki: if portc.4=0 then COUNT PORTC.4, 60, LABEL endif if label=0 then goto taki endif LCDOUT $FE,$c0, DEC(LABEL), " " GOTO TAKI
As long as I introduce the statement "if portc.4=0 then"
If it is "=0" then pin is sunk to ground, so no pulses can be detected, and nothing can be seen on scope. If it is "=1", then pin gets driven high, and no pulses can be seen with scope or read too.
Chip is 16F870.
for comparison I came up with this , oddly it uses mode code space
Code:'**************************************************************** '* Name : deMODULATOR.BAS * '* Author : richard * '* Notice : Copyright (c) 2016 * '* : All Rights Reserved * '* Date : 5/29/2016 * '* Version : 1.0 * '* Notes : decodes missing pulse encoded data stream A.5 * '* : 16F1825 * '**************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF __config _CONFIG2, _PLLEN_ON & _LVP_OFF #ENDCONFIG OSCCON=$70 DEFINE OSC 32 ' PIC 16F1825 TRISA = %111110 ' Make somepins Input trisc = %111100 ;Make some pins Input ANSELA=0 ANSELC=0 led var latc.0 ;DEBUG led2 var latc.1 ;DEBUG demod var porta.5 ;demod in X VAR byte darta VAR byte[4] counter var word dm_state VAR byte lata.0=1 ;DEBUG clear led=0 DEFINE DEBUG_REG PORTA DEFINE DEBUG_BIT 0 DEFINE DEBUG_BAUD 9600 DEFINE DEBUG_MODE 0 pause 2000 Debug "Start",13 ,10 DEFINE PULSIN_MAX 9000 main: select case dm_state case 0 PULSIN demod, 0, counter if counter > 7800 then dm_state=1 x=0 endif case 1 pir1.1=0 tmr2=0 t2con=7 while demod : wend if pir1.1 | (tmr2 < 220) then dm_state=0 else dm_state=2 tmr2=0 endif case 2 while !demod : wend t2con=0 if pir1.1 then dm_state=0 led=1 endif if tmr2 < 150 then darta.0[x]=0 else darta.0[x]=1 endif tmr2=0 x=x+1 if x >31 then dm_state=3 else while demod : wend t2con=7 endif case 3 led2=1 ;DEBUG ' Debug 13 ,10 ,hex2 darta[3] ,hex2 darta[2],hex2 darta[1],hex2 darta[0] ;DEBUG Debug 13 ,10 ,bin8 darta[3],bin8 darta[2],bin8 darta[1],bin8 darta[0] ;DEBUG pause 200 led2=0 ;DEBUG dm_state=0 end select goto main
Last edited by richard; - 10th October 2016 at 11:38. Reason: left a line out
Warning I'm not a teacher
Bookmarks