![]() |
Forum Index : Microcontroller and PC projects : Manchester code
Author | Message | ||||
homa![]() Guru ![]() Joined: 05/11/2021 Location: GermanyPosts: 464 |
Hello matherp (Peter Mather) and Geoffg (Geoff Graham), Over the weekend I spent a lot of time with Picomite and learned a lot. First of all, I dealt with the interrupts. I wanted to use this to read a Manchester code from an rfid chip of the EM4095. https://en.wikipedia.org/wiki/Manchester_code I found out that my interrupt routine is just too long or too slow. That's why I have already defined fixed timings, in order not to lose even more time through calculations. I tried to use the following listing: 'rfid reader - by mikroelektronika EM4095 SetPin gp25, dout ' interne LED Pin(gp25)=0 ' LED aus SetPin gp12, din ' OUT SetPin gp13, din ' RDY/CLK SetPin gp14, dout ' MOD SetPin gp15, dout ' SHD SetPin gp16, dout ' test pin oscilloscope Pin(gp16)=0 Pin(gp14)=1 Pin(gp15)=1 Pause 750 Pin(gp14)=0 Pin(gp15)=0 ' old_timer=0 diff=0 timebase =0.384 ' 1 Bit ~ 512 mikrosec. ~x0.75 bzw. 1.25 timebase2 =0.192 bitstate=0 bit=0 ' Timer =0 SetPin gp12, intb, rfOut ' Sub rfOut diff=Timer-old_timer old_timer=Timer pinstate=Pin(gp12) ' If (diff > timebase ) Then 'this is a long pulse after a short pulse bitstate=0 Else If (diff < timebase2 ) Then 'this is a short pulse after a long pulse bitstate=1 Exit Sub Else 'same pulse length (within 0.75x and < 1.5x of last length)5 If (bitstate=1) Then ' even number of consecutive short times at this place bitstate=2 Else If (bitstate=2) Then ' odd number of short times at this place bitstate=1 Exit Sub EndIf EndIf EndIf EndIf ' timebase = 3 * diff / 2 'to slow? If (bitstate <> 1) Then If pinstate=0 Then bit=1 Else bit=0 'Pin(gp25)=bit Pin(gp16)=bit 'debug pin EndIf End Sub ' Print "Los gehts im Dauerloop ..." Do Loop But in the picture of the oscilloscope you can see that I miss more interrupts on edges of the signal. And this although the CPUSPEED is set to 250MHz. Yellow is the Manchester code, blue the wrong bits (sometimes). ![]() Now there are several points (questions or wishes): 1.) A generic routine for the decoding of Manchestercode (with self-learning time base) as a command with interrupt that always happens when a bit is ready, then one could do the decoding etc. for the protocol in Basic itself. (Dream wish :-) !) How can I persuade you or you Peter (matherp) to do this? ;-) - This can be used for many different things: RFID transponders, time code, SPDIF, propeller clocks, and much more. or 2.) I would try to program the function myself in C and then create my own command. But I would have to be able to create the .uf2 file myself. This would be generally helpful! 2b.) Is there a step by step guide on how to compile the source code to create said .uf2 file? Or can someone explain this please? Or 4.) Or is my assumption or the timing problem unfounded and I am just clumsy? And the whole thing could be solved directly in Basic? or 5.) Or could the PIO be used for this? But I don't have the idea or the understanding, so I would need help from the forum. Does anyone want to help? Thank you for your comments. Regards Matthias |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2593 |
TassyJim used ADC to read a stream of fast variable width pulses then process them later for the DHT11 sensor. All in MMBasic. See here:- https://www.thebackshed.com/forum/ViewTopic.php?FID=16&TID=13832#169533 Gizmo also did a RFID / Manchester code project on this forum. Search for that there may be more useful info. there. https://www.thebackshed.com/forum/ViewTopic.php?TID=14312&P=1#177801 Edited 2022-01-11 07:57 by phil99 |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4036 |
2b. Follow the RPi doc (for the C/C++ SDK) so you can build their examples. PicoMite is built the same way. BTW You don't need VSCODE if you don't want it. It looks easiest if you do it on their suggested RPi host. (I didn't, as I don't have one conveniently attached. So I'm cross-compiling from Linux on a x86 laptop. In case you want to do that, it suited me to get the latest gcc cross-compiler toolchain for arm-none-eabi from the ARM site.) 4. Sorry, don't know. 5. Maybe PIO could be used. (I don't know.) John Edited 2022-01-11 19:22 by JohnS |
||||
Tinine Guru ![]() Joined: 30/03/2016 Location: United KingdomPosts: 1646 |
I wouldn't normally throw this out because I can't tell what kind of performance improvement is required and I am away from my MM stuff so I can't experiment but: 1) I remember someone realising a significant speed-up by shortening the variable names (I don't know if this still applies) 2) On a different processor, I was using 3 single-precision variables and for giggles I replaced them with integers, using shl and shr jiggery-pokery to preserve precision....this boosted my loop speed by a factor of 5(!!!) |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9589 |
Interrupts should be AS SHORT AS POSSIBLE. I know it's tempting to put all the code you want inside the interrupt sub, but that is a bad idea, cos if another interrupt is triggered while the code is already inside the interrupt, bad things can happen. Set flags only in the interrupt, or at MOST read the data, then exit the interrupt. Have your main loop examine the flags and decide what to do, or process the data - or a combination of both. Not saying this is the cause of your problems, but you should NOT put the processing code for the interrupt, inside the interrupt itself. From the coding bible: "Thou shalt not hang around in interrupts." ![]() Smoke makes things work. When the smoke gets out, it stops! |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4036 |
'Twas always thus. John |
||||
disco4now![]() Guru ![]() Joined: 18/12/2014 Location: AustraliaPosts: 1000 |
You might get some ideas from this thread that has a solution to decode some remote controls. Latest F4 Latest H7 FotS |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2593 |
This thread reminds me of an idea that has been mentioned before. How many Mite users think this is a bad idea? (note 1) (note 2) There are so many different methods / protocols for serial input / output that a generic pulse stream recorder / generator might be useful. Only the fastest Mites can readily do this with the current MMBasic commands. (note 3) Conversion to or from bits to pulse lengths and interpretation of the bits could then be left for the user to do in MMBasic. One possibility would be extensions to PULSIN and PULSE commands. Adding parameters for the total number of high & low pulses and an array variable for input or output. Odd numbered elements could hold the high durations and low durations in the even elements. (Zero is even) To make room for this perhaps lesser used device functions could be moved from firmware to CSubs, as with the MM2 DHT22 function. Note 1: Have been taking lessons from our politicians on how to frame a question to get the answer you want not what the majority want or is realistic. Note 2: Damn, did I say that out loud? Note 3: For the MM2 TassyJim has a method that uses PWM and COUNT but needs two extra pins, which might not be spare on the 28 Pin. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
The PICO manual suggest that ADC command can sample a single channel at 500kHz. That should be plenty fast enough. Provided the data is coming in batches and not continuous, using ADC to do the sample then whatever is needed to analyze and display. A lot of the current offerings have the ADC command. Jim VK7JH MMedit |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2593 |
Yes the ADC command can do the job for the Mites that have it, for input. For output the PULSE command has plenty of speed and accuracy but it is difficult to get short, accurate pauses between. For the Pico and F4 using the PAUSE command there are fluctuations of +/- 8uS or so and a gap between 40uS and 80uS. With a very short FOR / NEXT loop down to 55uS is possible but not entirely consistent. Perhaps some means of chaining Pulse High and Pulse Low commands could achieve speed and accuracy. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
Does the BITBANG BITSTREAM command have the same resolution limitation? Jim VK7JH MMedit |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2593 |
I have not tried that. Thanks for the tip. Yes, perfect for the Pico. It and ADC would be nice on the MM2 and others. Greedy aren't I? Edited 2022-01-13 13:59 by phil99 |
||||
disco4now![]() Guru ![]() Joined: 18/12/2014 Location: AustraliaPosts: 1000 |
For the F4 as I understand it the SYNC command could be used to generate an accurate pause, accurate to 1/84,000,000 seconds. The SYNC command with parameters sets up a fast timer and stores the period. The SYNC command without parameters waits for the timer to reach the period specified and then resets the timer and returns. As this all happens in the firmware the timing period is extremely accurate. Valid units are: If parameter is omitted: the period is expressed in raw clock counts 1/84,000,000 seconds U or u: the period is expressed in microseconds M or m: the period is expressed in milliseconds S or s: the period is expressed in seconds Latest F4 Latest H7 FotS |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2593 |
"The SYNC command with parameters sets up a fast timer" I spent some time trying to get the SYNC command to produce short pauses (a few tens of uS) between Pulse commands but did not do as well as just using the time it takes to go round a FOR - NEXT loop with which the time can be tweaked upward by adding dummy statements but the shortest I could get was 55uS. A DO WHILE...- LOOP or DO - LOOP UNTIL... takes a little longer and with some variability. With SYNC it is ok for short bursts, say 1 byte you can just repeat the alternating commands one after the other but at 16 commands per byte it soon becomes tedious. Any sort of loop adds too much time. The BITBANG BITSTREAM command on the Pico is perfect for output. I don't know why I didn't see that. (perhaps I did and forgot - going senile) If that could be made into CSubs for other Mites it would be very handy. A BITSTREAM INPUT CSub for Mites without ADC to compliment it would complete the wish list. Edited 2022-01-13 20:58 by phil99 |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
For the UM2, we have a BITBANG BITSTREAM equivalent CSUB already: https://www.thebackshed.com/forum/ViewTopic.php?TID=8765&PID=102944#102944#95168 Jim VK7JH MMedit |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2593 |
Thanks very much for that link Jim. Yet another thing I missed or forgot. |
||||
homa![]() Guru ![]() Joined: 05/11/2021 Location: GermanyPosts: 464 |
hello folks, I didn't want to leave the contributions and numerous replies without comment. first of all, thank you very much. there are enough ideas for more than one weekend. I found a simplification somewhere else. I will continue to work on it and learn this weekend, and I will report back later. many greetings matthias |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |