Store Digital signal input

kikopataya

New Member
i was wondering if anyone can help me out with a project im working on. i want to check to see if one of the input pins is high or low. my signal is coming in at around 1.85 kHz so each high and low state is around 250 or 260 micro seconds. what i want to do is store the ones and zeros somewhere so i can go back and see if the signal is coming low to high or high to low on each cycle. can anyone help with this problem please. i don't necessarily need source code already made but maybe commands i can use and stuff like that. i am pretty bad at programming in general and this is kicking my butt right now :confused:
Victor
 

womai

Senior Member
What you describe sounds very much like a logic analyzer to me ;)

250us bit period is somewhat on the fast side for a Picaxe. I'd say right away your best bet is probably a Picaxe 28X2 clocked at 40 MHz (i.e. 10 MHz external resonator). That will give you an execution speed of approx. 15000 commands per second, or roughly 60 commands per bit. It also has the largest storage RAM of all Picaxes.

You could use the scratchpad to store the values; something like

Code:
ptr=0

for w0 = 0 to 1023
   @ptrinc = pinB.0
   pauseus xxxx
next w0
will store 1024 samples (measured on pin B.0). How many samples do you need to store in one shot? With a little effort you could even pack 8 sample values into the 8 bits of each scratchpad byte, effectively increasing your record length to 8192 samples. The 28X2 would be fast enough for that.

What will be more tricky is making sure each time you sample you are actually looking at a new bit. What determines the bit boundaries? Is there a clock signal in addition to the data? (similar to a standard SPI interface when a transition of the clock signal indicates that the new bit is ready to be read). If not, how do you decide where one incoming bit ends and the next one starts? Otherwise you may sample twice the same bit (once at the beginning of the bit period and once towards the end) or even more often, or you may sample just when the bits change, which will result in unpredictable values.

Wolfgang
 

QuIcK

Senior Member
small improvement so that it will last more than 1s before the scratchpad overflows. This will save the stats to individual bits in the scratchpad or eeprom

Code:
ptr=0
SYMBOL BitRead = b0        'temporary reading variable
SYMBOL BitPoint = b1        'which bit we are rading into
SYMBOL BitSave = b2        'for the total of 8bits to save
SYMBOL LoopCounter = w2 'scratchpad loop
for w1 = 0 to 1023
'read the bit into a temporary variable
   BitRead = pinB.0
'shift the bit into the right place, so we dont overwrite anything
   BitRead = BitRead << BitPoint
'put that into the previous states
   BitSave = BitSave OR BitRead
'increment which bit we are saving to
   INC BitPoint
'if we have filled a byte then
   IF BitPoint = 8 then
'save
'comment out one of the following lines
       @ptrinc = BitSave     'save to scratchpad, volatile
       WRITE ptr, BitSave   'save to permanent eeprom, non-volatile
'reset
       BitPoint = 0
       BitSave = 0
   END IF
   pauseus xxxx
next w0
 

hippy

Ex-Staff (retired)
The trouble with WRITE is that it's not fast, typically in the region of a couple of milliseconds ( you'd have to check each Microchip datasheet ) This is the nature of the hardware and canot be avoided.

Also the more you do between samples the lower the sample rate will be. This includes extraneous instructions and wrapping in a FOR-NEXT loop. The fastest sampling will be a long sequence of '@ptrinc=pins'. The problem there, due to each assignment having potentially different alignment within code image, is that there may not be consistency of sampling times.
 

womai

Senior Member
Hippy, agree, getting stable and accurate timing will be a challenge. pauseus could be used to trim the delay between samples, but how do you know where the Picaxe actually sampled? That's why I was asking if there is some strobe (sample clock) telling when the bit shall be sampled.

Also, my brain was off last night - 15000 commands/sec mean only 4 commands per bit, not 60, so the code better be very tight. I don't think there is even the possibility to do the bit-packing I mentioned.

If there is indeed a clock, one could set up an interrupt on the rising or falling edge and then in the interrupt routine store the bit into the scratchpad. Again, 2000 samples/sec will be borderline if feasible at all.

Wolfgang
 

kikopataya

New Member
thanks for all the input you guys. im just gonna tell you guys what i was thinking about doing and see if maybe this will work or not. first off, the signal coming into pin0 is encoded in manchester. so what i want to do is read the second half of each period since a logic low to logic high represents a binary 1 all i would need to do to decode it is read the second half. i know exactly how my signal begins and ends since it is coming from an RFID reader i made and i know how the tags send the information. when the reader does not detect a tag, the output will be just a logic high. but as soon as it detects a tag, it will send the information inside the tag. the datasheet for the tags is attached in the pdf file if anyone is interested but what i got from it is that i would get 9 bits of header all ones so logic low to logic high 9 times and then the actual ID number starts. i also saw on my oscilloscope that one clock cycle is roughly 500 micro seconds. what i was thinking about doing was using the pulsin command to detect a low pulse and as soon as it does, read the input port and save the information every 500 micro seconds since i am only interested in the transition. if i set the picaxe 28x1 to work at 8 MHz a pause 1 will give me a pause of 500 micro seconds which is exactly what i need. do you guys think this will work?
 

Attachments

boriz

Senior Member
Facing a similar problem, I took a leaf out of Hippys book and used a string of PULSIN commands. My application was decoding an IR remote. The Picaxe built in IR system only uses Sony signals and my remote is Hitachi.

At 4MHz, PULSIN will return 25 for a 250uS pulse. So, assuming your data is encoded by different lengths of pulse, then it’s simply a matter of measuring each pulse with a list of PULSIN commands, like this:

Code:
PULSIN 0,1,b0
PULSIN 0,1,b1
PULSIN 0,1,b2
Etc..
Then you follow this with a little decoding. Something like ... IF b0<100 then “bit0 is zero” ELSE “bit0 is 1”. IF b1<100 then “bit1 is 0” ELSE “BIT1 is 1”. And so on until you have your complete byte (or word) of data.

It took a while, and lots of squinting at my CRO (old non-storage type), but I eventually got it working just fine. Because of a computer failure, and additional cockups, I have lost the source code, but it’s essentially similar to the IR decoding routines on Hippys site.

NOTE:
-PULSIN wait’s for a transition before it starts timing then waits for the opposite transition to stop timing.
-When no appropriate transitions are detected, it time’s out after 0.65 seconds. With a list of PULSIN commands, this delay can be significant.
-You must know beforehand exactly how many pulses you will be measuring (how many PULSIN commands), so some sort of synchronisation is essential.
-This, of course, only works with pulse-width type coding.

Good luck.
 

Andrew Cowan

Senior Member
-When no appropriate transitions are detected, it time’s out after 0.65 seconds. With a list of PULSIN commands, this delay can be significant.
However, overclocking the PICAXE does decrease this time. It also increases the precision of the timing.

A
 

womai

Senior Member
After looking at the data sheet, I think I know a good way to have the Picaxe receive this data stream. Don't bother trying to sample the bits directly - you will never get the program timing accurate enough for this to work (and even if you do, it will break whenever the data rate is slightly off or when the next Picaxe firmware revision comes out). A bare PIC programmed in assembler or some compiled language could do it (in fact, the Picaxe uses that approach from serial communication over the download connection and for the serin command), but the Picaxe timing is just way too unpredicatble for such precise timing.

But Boriz got me onto a different track with his pulsin:

(1) set the scratchpad pointer to zero (ptr = 0)

(2) wait for a falling edge on the data pin which indicates the start of the data stream (most elegant solution - set up an interrupt on the falling edge, that's one of the new features on the 28X2).

after that, in the interrupt routine, repeat (3) + (4) for as many bits as you expect:
(3) measure positive pulse width using the pulsin command
(4) store measured pulsewidth in the scratchpad

i.e. something along the lines of

pulsin pinB.0, @ptrinc
pulsin pinB.0, @ptrinc
pulsin pinB.0, @ptrinc
pulsin pinB.0, @ptrinc
....
pulsin pinB.0, @ptrinc


Now comes the clever part: If you look at the Manchester encoded data stream, you will see that a short pulse (half a bit period) means "current bit is the same as previous bit", while a long pulse width (full bit period) menas "current bit is the inverse of the previous bit". So you need to parse the stored pulse width sequence and build up your data stream; initial value for the bit is a logic "1".

E.g. say you measured pulse widths of

250us --> same as before = "1"
250us --> same as before = "1"
250us --> same as before = "1"
500us --> inverse --> "0"
250us --> same as before = "0"
500us --> inverse --> "1"
500us --> inverse --> "0"

Of course in reality there will be some variation to the exact numbers, so you'd compare to "larger than 375us" to decide if a pulse is long or short.

Since that strategy uses only a single command (pulsin) per byte, you should have no problems capturing data streams up to 5 kbit/sec or more if you run the 28X at 40 MHz.

Wolfgang
 
Last edited:

kikopataya

New Member
I dont think that will work. i wrote down every possibility from 110000 to 111111 and for a lot of them it would not work like 110011. this is something i had in mind but i dont know how to read weather it is a 1 or 0 in the values.
[CODE/]
symbol val1 = $50
symbol val2 = $51
symbol val3 = $52
symbol val4 = $53
symbol val5 = $54
symbol val6 = $55
symbol val7 = $56
symbol val8 = $57
symbol val9 = $58
symbol val10 = $59
symbol val11 = $5a
symbol val12 = $5b
symbol val13 = $5c
symbol val14 = $5d
symbol val15 = $5e
symbol val16 = $5f
symbol val17 = $60
symbol val18 = $61
symbol val19 = $62
symbol val20 = $63
symbol val21 = $64
symbol val22 = $65
symbol val23 = $66
symbol val24 = $67
symbol val25 = $68
symbol val26 = $69
symbol val27 = $6a
symbol val28 = $6b
symbol val29 = $6c
symbol val30 = $6d
symbol val31 = $6e
symbol val32 = $6f

main:
setfreq m8
again: pulsin 0,0,w13
if w13=0 then
goto again
else
goto tag
endif

tag: debug
b0=pin0
poke val1,b0
pause 1
poke val2,b0
pause 1
poke val3,b0
pause 1
poke val4,b0
pause 1
poke val5,b0
pause 1
poke val6,b0
pause 1
poke val7,b0
pause 1
poke val8,b0
pause 1
poke val9,b0
pause 1
poke val10,b0
pause 1
poke val11,b0
pause 1
poke val12,b0
pause 1
poke val13,b0
pause 1
poke val14,b0
pause 1
poke val15,b0
pause 1
poke val16,b0
pause 1
poke val17,b0
pause 1
poke val18,b0
pause 1
poke val19,b0
pause 1
poke val20,b0
pause 1
poke val21,b0
pause 1
poke val22,b0
pause 1
poke val23,b0
pause 1
poke val24,b0
pause 1
poke val25,b0
pause 1
poke val26,b0
pause 1
poke val27,b0
pause 1
poke val28,b0
pause 1
poke val29,b0
pause 1
poke val30,b0
pause 1
poke val31,b0
pause 1
poke val32,b0
pause 1
[/CODE]
what do you guys think? how can i check what values are in my val#'s. i tried saving them in b0,b1 etc and debug them but all i see is the address. any ideas?
 

kikopataya

New Member
ok i set up my circuit so i can have an input clock at the same frequency as my data but with a small phase difference. basically whenever theres a rising edge on the clock, i am right smack in the middle of the data that i need to get. can anyone help me software wise on how to store the data on the rising edge of my clock. the way i see it is i have to make a subroutine to check my pin0 where the data is coming in from for a logic low and as soon as it detects the logic low, branch out to another subroutine that checks pin2 which is my clock for a rising edge and store the data, either 1 or 0, 64 times because its 64 values that i need to get, and convert the binary numbers into hex to get the id number of my tag. can anyone help me out with that please. i appreciate everyones help for real. this is my final project in school that i have to finish soon because i have a job lined up already but i have to finish this project by next friday in order to keep this job so i greatly appreciate everyone's help. thanks again
 

womai

Senior Member
A separate clock does make it a lot easier.

If you are using an 28X2 or 40X2, the easiest is to route the clock to pinB.0. Then set up a hardware interrupt that triggers on the rising edge (see the Basic manual for the hintsetup command). That way the clock transition detection is pretty much "hands off" - every time the clock has a rising edge your interrupt routine gets called; in the interrupt routine simply store the state of the data pin (I really suggest using the scratchpad for that; e.g. if the data comes in at pinB.1 then all you have to do is "@ptrinc = pinB.1"). Don't forget to re-enable the interrupt at the end of the interrupt routine.

Wolfgang
 

womai

Senior Member
The 28X1 cannot trigger on e certain edge polarity (e.g. rising edge), only on a certain pin state (e.g. high). But you should still be able to use it; set up an interrupt on "high" of your clock input pin. Then in the interrupt routine save the state of the data pin. After that you have to wait until the clock pin becomes low again before you re-enable the interrupt and return from the interrupt routine. Lookup the "setint" command, it has some applicable code.

The 28X1 is also slower (max. clock rate 20 MHz) compared to the 28X2 (40 MHz max), but less than you would expect because the 28X2 need more cycles to execute the commands; real speed difference is closer to 50%, not 100%.

Wolfgang
 

kikopataya

New Member
ok i wrote the program how i thought it would work but it's not consistent. i use b9 just to check what values i read and when i scan the tag, i get different numbers everytime. any suggestions. i think the timing is off or something.
[CODE/]
Main: setfreq m8
Try: ptr=$00
NoYet: if pin0=1 then NoYet
goto tag

tag: b0=64
setint %00000100,%00000100
Keep: pulsin 0,0,w1
if w1=0 then Try
goto Keep

Interrupt: b9=pin0
@ptrinc=pin0
sertxd (#b9)
dec b0
if b0=0 then Don
goto Set
Set: setint %00000100,%00000100
Don: return
[/CODE]
 

lanternfish

Senior Member
Try this:

Initialise: setfreq m8
setint %00000100,%00000100

Main: ptr=0
b0=64

NotYet: goto NotYet

' Insert binary to hex code here

end

Interrupt: do until b0=0
b9=pin0
@ptrinc=b9
sertxd (#b9)
dec b0
loop
setint %00000100,%00000100

return
 

kikopataya

New Member
that didn't work either, i think my picaxe 28x1 is just too slow, i dont have a ceramic resonator all i have is a 13.56 MHz crystal oscillator but i dunno if i can put that on the picaxe. if anyone can tell me if i can add my crystal oscillator and if yes, how to do it i would really appreciate it.
 

womai

Senior Member
No, you need a resonator, not an oscillator. I'd go for 16 MHz (that keeps the option of using sertxd for debug) or 20 MHz (if you go for maximum speed). If you have to order them, order several of both types both (they are cheap). Try Jameco. The Picaxe is really at the limit speed-wise with what you are trying to do, so using it at 8 MHz will just create additional trouble (and may not work at all).

Wolfgang
 

lanternfish

Senior Member
Hi again.

Made a bit of an error in my suggestion - move the sertx from the interrupt routine.

Try this:

Initialise: setfreq m8
setint %00000100,%00000100

Main: ptr=0
b0=64

NotYet: goto NotYet

Transmit: sertxd (#b9) 'or use debug, initially

' Insert binary to hex code here

end

Interrupt: do until b0=0
b9=pin0
@ptrinc=b9
dec b0
loop
setint %00000100,%00000100

return

Can you give a description of the whole project?

Lindsay
 

hippy

Ex-Staff (retired)
If you have a clock synchronised with your data you may be able to use a PICAXE configured for SPI Slave mode to clock those bits in as bytes at a time. If the bits arrive every 500uS that gives 4ms between bytes which should be plenty of time to process them or store them away and be ready for the next set.

The attached code works for a 28X1 using push buttons but only reads in bytes. PIR1<SSPIF> ( or SPSTAT<BF> ) can be read to determine when the buffer is full, after every 8 bits. I'm not sure how one would reset the internal counter to say 'count 8 bits from now' if there were extraneous clock pulse but I expect it can be done - Added : Set SSPCON<SSPEN> to 0 then back to 1.

Using SPI Slave would also be another way to communicate from a Master PICAXE to a Slave PICAXE. Should work on all X1 and X2 devices and can be achieved on an 18X.
 

Attachments

Last edited:

hippy

Ex-Staff (retired)
this is my final project in school that i have to finish soon because i have a job lined up already but i have to finish this project by next friday in order to keep this job so i greatly appreciate everyone's help.
From reading other forums it appears you may be considering using something other than a PICAXE; if you are going that route then please let people know so they don't waste time trying to solve a problem and their effort goes to waste. I'm sure we can appreciate that you may want to throw all the eggs in the air and will accept whichever lands unbroken first and if that's the case then people will accept that.

Manchester decoding is quite a complicated task but should be achievable. Coming from behind with no previous experience of it, lack of familiarity with whatever processor you choose and its programming language will be a steep hill to climb. I doubt there are many people here who have had to do the entire decoding in software and have previous experience.

I am assuming you have a RFID reader which gives out data but is in Manchester encoded format. Given the shortness of time in which you have to complete the project and the consequences of not doing so it may be easier to find a commercial RFID reader which does the decoding and re-formatting of data rather than attempting to do all that yourself. If you can find one with a serial output that should be easily usable with a PICAXE. There used to also be standalone chips which converted Manchester encoded data to NRZ serial which may make life easier. If a job really depends on it then it may be worth considering finding a commercial developer to write the code for you but that will cost money and may not be acceptable if the project is to be assessed as your own work. Then again, it may be considered initiative worth applause.

I've done Manchester decoding on a PICmicro for SMPTE (VITC) timecode but it was a long while ago. As best I can remember and determine is that it went like this ...

1) Read the bitstream in, time between transitions, and keep a flag of what the data represents ( 0 or 1 ). Initialise the flag bit to 0 or 1, whatever the first header bit would represent.

2) If the time between transitions is < T keep the flag bit the same, output the flag bit, trigger a clock pulse.

3) If the time is > T then output the flag bit, trigger a clock pulse, toggle the flag bit, output the flag bit, trigger another clock pulse.

4) Restart the interval timer after every input transition.

5) Take those clock pulses, and on every second pulse clock in the bit; that will be the stream of bits which represents the decoded signal.

6) The bit stream has to then be bit-shifted to remove the synchronisation / header signal.

This can all be folded into a single code routine which does everything using a Finite State Machine. This all required doing work between each bit transitions so may not be suitable for a PICAXE.
 

kikopataya

New Member
What I'm gonna do is just buy a 28x2 and a 10 MHz resonator and work with rising edge interrupts. Now if that doesn't work then I don't know what will. Anyone know where i can order one from cause I checked the picaxe website and I didn't see it there?
 

eclectic

Moderator
Rev-Ed sell the 28X2 (both versions), but not the 10MHz resonator.

Nearer home to you are Sparkfun and HVW (Canada)

See the Picaxe homepage for the links.

e
 

hippy

Ex-Staff (retired)
Some Manchester Decoding Demo Code

Looks like my algorithm posted earlier works, but I'm sure there's more which could be done to make it more robust and it doesn't do header code checking / initialisation / synchronising.

This just pulls characters from Eeprom rather then read actual I/O pins and times between transitions. The timing has to run quicker than the transitions so no way will it work with pulses arriving every 50us but it does demonstrate the principle.

There are two things about Manchester Encoding; first it has zero DC content so ideal for wireless transmission, and secondly it is 'self-clocking'. Unlike RS232 which is synchronised to the rising edge of the start bit this synchronises at least once on each bit. That improves tolerance for baud rate error from +/-6% for RS232 to around +/-30% ( or +25%/-50% ) for Manchester encoding. Very handy to overcome doppler effect when reading from a signal source which is moving. In the source there are two bits which are stretched <0> and <1> to show this tolerance.
 

Attachments

Last edited:

kikopataya

New Member
ok i finally got my code to work. I realized that i had to wait for the 9 header bits to be sent and then start storing my data. my code is 300 lines of ugly code and could easily be cut down to around 75 easily but it works and thats all i care about :p. There's still one more part to my project but it doesn't involve the picaxe. i have to make a program that reads the serial port and stores the data coming in from the serial port. if anyone can help me out with that i would appreciate it. Thanks for all your help everyone, i greatly appreciate everything.

Victor
 

hippy

Ex-Staff (retired)
Glad to hear you got it working. What PICAXE, resonator and technique did you use in the end ? I'm sure that would be of interest to anyone else who may be doing this in the future.
 

kikopataya

New Member
Yea apparently the 28x1 was good enough to do the job in the end. what I did was read the width of the high pulses until i got 9 pulses with width of around 250 micro seconds then right after that store the data in pin0 (data coming from RFID reader) every 500 micro seconds (pause 1 in 8MHz) since the period was 500 micro seconds. it worked for all the tags i have so i must assume it will work for pretty much every tag. but my prof says its good enough so i will not complain. Thanks once again for all your help. if anyone is interested in the schematic for my project i will be more than happy to post it up.
 
Top