SIMPLE communication between to 08M2 chips

FunFlyer

New Member
I want one of the chips to generate a signal with 8 pulses between 0.8 and 1.4 ms and a pause of 0.4ms in between. A ninth pulse is added to complete a frame of 25ms. I got this running when the chip is set to 32Mhz and a constant pulselength of 1.1ms is used. It´s all done by "PULSEOUT" and "PAUSEUS" commands.

Then I wanted to read pulses between 1.0 to 2.0 ms and uses those values to dynamically adjust first 8 pulses. I tried several approaches so far. None of them worked.

1. Get the Input just before outputting a pulse. That throws off the timing of the 0.4 ms pause.

2. Read the inputs (I tried two), then generate the output. I thought there should be plenty of time in the 25ms frametime, but unfortunately reading 2 pulses between 1 and 2 ms with the "PULSIN" commands takes about 50ms, I have no idea why, but thats what the signal look like on my scope.

3. I wanted to try multitasking (one for reading, one for creating the output) that didn´t get very far, since it´s not possible to use multitasking with 32Mhz, which I need to use the "PAUSEUS" command for the 0.4ms pause.

4. next idea is to use two 08M2 chips. But can´t figure out how to pass the data from one to the other. All I found are solutions that seem to be capable of everything short of making a PCAXE fly. I just need a simple oneway coms. in a "fire and forget" fashion, since a potentially false value is overwritten 25ms later anyway. So here´s the pseudocode for the chips:

Chip1:

read input chanel 1 (pulselength 1 to 2 ms, repeated every 25ms)
read input chanel 2 (pulselength 1 to 2 ms, repeated every 25ms)
send values to chip 2
start over

Chip 2:

receive values from chip 1
store them
generate the signal from the latest stored data
start over

Does anybody have any ideas? thanks in advance


Herbert
 

cpedw

Senior Member
I have found SEROUT/SERIN to be very reliable. The sender makes a short pulse on the serial line before sending the data. The receiver has an interrupt set up on the serial line to start the SERIN process. It wouldn't work if the receiver has any code that might block the interrupt.
The values I chose for pwake and p100 in the sender code might be reducable to speed it up. I chose these and it worked for my application so I didn't investigate further.
This scheme allows for other interrupts in the receiver.

Sender code:
Code:
#PICAXE 08M2

Symbol Srout    = C.1                ' Output to Display (leg 6)

SYMBOL baud= N4800_32        'For freq M32
SYMBOL pwake =40000            'Wake up using pulsout @ 32MHz for 50mSec
Symbol p100= 800                    'Pause 100ms @32 MHz

SETFREQ M32

#Macro Sendout(code,d1,d2)
  PULSOUT srout, pwake
  SEROUT srout, baud, (code, d1, d2)
  PAUSE p100
#EndMacro
Receiver
Code:
#PICAXE  14M2

Symbol SIGNAL      = pinC.0              ' Clock signal Input Pin from DS83 Clock (leg 7)
SYMBOL Srin        = C.0                ' As above for SERIN command

SYMBOL intrp    = %00000011            ' Interrupt flag/mask using C.1 (switches) or C.0 (clock in)
SYMBOL intrc    = %00000001            ' Interrupt flag/mask using C.0 (clock in) only

SETFREQ M32

SETINT OR intrp, intrp            'Interrupt on any of the setting switches or SIGNAL from Clock

INTERRUPT:            ; Interrupt on Mode, Up and Down switches OR Clock

    IF PinC.0=1 THEN     'Clock interrupt
        GOSUB Clockout

    ELSE                         'Switches interrrupt
 .....
    ENDIF
    SETINT OR intrp,intrp        'Reset all interupts
RETURN

Clockout:                    'interrupted by a pulse from the Clock
DO : LOOP UNTIL SIGNAL=0    'Wait for end of interrupt
    SERIN Srin, baud, code, d1, d2
RETURN
I hope I copied enough of the programs to explain the process. Let me know if you need clarification.
Derek
 

FunFlyer

New Member
I have found SEROUT/SERIN to be very reliable. The sender makes a short pulse on the serial line before sending the data. The receiver has an interrupt set up on the serial line to start the SERIN process. It wouldn't work if the receiver has any code that might block the interrupt.
The values I chose for pwake and p100 in the sender code might be reducable to speed it up. I chose these and it worked for my application so I didn't investigate further.
This scheme allows for other interrupts in the receiver.

Sender code:
Code:
#PICAXE 08M2

Symbol Srout    = C.1                ' Output to Display (leg 6)

SYMBOL baud= N4800_32        'For freq M32
SYMBOL pwake =40000            'Wake up using pulsout @ 32MHz for 50mSec
Symbol p100= 800                    'Pause 100ms @32 MHz

SETFREQ M32

#Macro Sendout(code,d1,d2)
  PULSOUT srout, pwake
  SEROUT srout, baud, (code, d1, d2)
  PAUSE p100
#EndMacro
Receiver
Code:
#PICAXE  14M2

Symbol SIGNAL      = pinC.0              ' Clock signal Input Pin from DS83 Clock (leg 7)
SYMBOL Srin        = C.0                ' As above for SERIN command

SYMBOL intrp    = %00000011            ' Interrupt flag/mask using C.1 (switches) or C.0 (clock in)
SYMBOL intrc    = %00000001            ' Interrupt flag/mask using C.0 (clock in) only

SETFREQ M32

SETINT OR intrp, intrp            'Interrupt on any of the setting switches or SIGNAL from Clock

INTERRUPT:            ; Interrupt on Mode, Up and Down switches OR Clock

    IF PinC.0=1 THEN     'Clock interrupt
        GOSUB Clockout

    ELSE                         'Switches interrrupt
.....
    ENDIF
    SETINT OR intrp,intrp        'Reset all interupts
RETURN

Clockout:                    'interrupted by a pulse from the Clock
DO : LOOP UNTIL SIGNAL=0    'Wait for end of interrupt
    SERIN Srin, baud, code, d1, d2
RETURN
I hope I copied enough of the programs to explain the process. Let me know if you need clarification.
Derek
Hi Derek,

thank You for the quick reply. I got some of what You wrote, but definitely not enough to continue on my own from here. So If You would be willing to coach me on this, I would try to develope the code further incrementally and give it to You for comments.
One thing that concerns me right away with Your solution (DO : LOOP UNTIL SIGNAL=0 'Wait for end of interrupt) is the timing. Using Your values, would the receiver (my chip2) be able to generate the pulses fast enough in the timing contraints I posted in my original post?

But before we get into that, here´s another question. This is really already my second attempt to solve my original problem, which I posted in another thread (Implementing SRXL protocol in a PICAXE). I talked back and forth to Hippy, unfortunately I got no reply after May last year. So could I kindly ask You to take a look at that threat, and maybe we can continue that way? That approach seems to be more promising to me, because the data I need are readily available. I just need to get them into the chip, and then generate the pulses.
 

AllyCat

Senior Member
Hi,

To answer the "Subject" of this thread, the "Simple" way to send data between PICaxe chips is to use serial communications with "TTL" Levels. Single bytes can be transmitted by SEROUT, SERTXD or HSEROUT commands, but it is probably better to use HSERIN to receive bytes in the "background" and then the software can read the buffer when convenient.

However, the main data transfer method would have been better discussed in your Original Thread. Although hippy said "it does look like a PICAXE might be able to read and decode the SRXL / MULTIPLEX / M-LINK protocol" , he then went on to say "Using an X2 with background serial receive (which has a 64 MHz clock capability). But you are trying to use an M2 with only 32 MHz and NO Background reception. Note that the HSERIN Command Reference specifies 115 kbaud only at 64 MHz. **

I don't understand why you are describing pulses of around 1 ms, when 115 kbaud has bit times of only about 9 microseconds (which is beyond the capabilities of PICaxe Basic). However, I'm not saying that it is impossible to do what you describe, but I think it may need quite "Advanced" Programming techniques, using the Hardware features of the "base PIC" and not just "PICaxe Basic" instructions. For example the "Timer 1 Gate" hardware might be a better way to read narrow pulse widths.

** EDIT: The HSERIN Hardware can be set to 115 kbaud even at 4 MHz, but that's really intended for the "Background Receive" of X2 chips. It is possible for an M2 to receive Individual Bytes at 115 kbaud but there isn't much point in receiving each character in 90us when a spacing of hundreds of us, or even some ms, is required for the PICaxe to do anything useful with the byte that it receives.

Cheers, Alan
 
Last edited:

cpedw

Senior Member
My scheme uses a 50 msec wakeup pulse to start the data transfer. From Allycat's post, it seems that is several orders of magnitude too slow for your application.

Derek
 

FunFlyer

New Member
My scheme uses a 50 msec wakeup pulse to start the data transfer. From Allycat's post, it seems that is several orders of magnitude too slow for your application.

Derek
Thanks Alan and Derek,

but I think You got mixed up between the threads. The pulses of 1 to 2 ms come out of the radio control receiver and control a servo or other device e.g. a speedcontroller. Using the SRXL protocoll I wouldn´t need to measure those pulses, since the pulsewidths are encoded digitally and transmitted and directly availbe from the receiver. That would require about 14000 bits per second, which shouldn´t be a problem for an 20X2 chip as Hippy described. That "digital" approch would still be my goal. Also I wouldn´t need an additional chip to measure the pulses, and hence no comuniction between two chips.

Since I got stuck on that path, I tried to come up with a different solution, which involves measuring the 1 to 2 ms pulses. They don´t need to be transmitted over the serial line, just the value of the pulsewidth, obtained by the "PULSIN" command. So for 2 channels it´s just two word variables taking up four bytes, transmitted every 25ms. I think that shouldn´t be a problem either. The problem is the time to measure those pulses, which takes about 50ms, god knows why.

I hope that all makes sense. So any idea where to go from here with this clarification/explanation?

my regards

Herbert

PS. sorry for my English, but it´s not my native tongue.
 
Last edited:

AllyCat

Senior Member
Hi,

The PICaxe's "overhead" on reading a 1 ms pulse is about 100us (at 32 MHz clock), plus however long the PICaxe needs to wait for the leading edge of the pulse to start. Also, if the gap between the two pulses is less than perhaps 100us, then the PICaxe will totally miss the second pulse (and you will need to adopt a completely different measurement strategy). Don't forget that each PULSIN has to be set to look for either a rising or falling leading edge.

Therefore, you need to find out WHY the program appears to be taking much longer to detect the pulses. As you have a 'scope, probably the easiest method is to insert some High, Low or Toggle <pin> (or short PULSOUT) commands (onto a spare pin) at critical parts of the waveforms. Those commands take about 50us each at 32 MHz. I presume you are aware that the PULSIN, PULSOUT, SERIN, SEROUT (and some other commands) are "blocking", i.e. the program "counts" their elapsed times, so it can do NOTHING else at the same time (or whilst waiting for a pulse to start). That applies even in PICaxe (M2's) "multi-tasking" mode, which is very unlikely to be of any use in this application.

I have done a lot of work on using the HSERIN command with M2s and I think you can assume that an M2 cannot receive 115k baud (see particularly posts #6-7), unless there is a long space between each individual byte. But my German is MUCH worse than your English. :)

Cheers, Alan.
 

FunFlyer

New Member
Hi,

The PICaxe's "overhead" on reading a 1 ms pulse is about 100us (at 32 MHz clock), plus however long the PICaxe needs to wait for the leading edge of the pulse to start. Also, if the gap between the two pulses is less than perhaps 100us, then the PICaxe will totally miss the second pulse (and you will need to adopt a completely different measurement strategy). Don't forget that each PULSIN has to be set to look for either a rising or falling leading edge.

Therefore, you need to find out WHY the program appears to be taking much longer to detect the pulses. As you have a 'scope, probably the easiest method is to insert some High, Low or Toggle <pin> (or short PULSOUT) commands (onto a spare pin) at critical parts of the waveforms. Those commands take about 50us each at 32 MHz. I presume you are aware that the PULSIN, PULSOUT, SERIN, SEROUT (and some other commands) are "blocking", i.e. the program "counts" their elapsed times, so it can do NOTHING else at the same time (or whilst waiting for a pulse to start). That applies even in PICaxe (M2's) "multi-tasking" mode, which is very unlikely to be of any use in this application.

I have done a lot of work on using the HSERIN command with M2s and I think you can assume that an M2 cannot receive 115k baud (see particularly posts #6-7), unless there is a long space between each individual byte. But my German is MUCH worse than your English. :)

Cheers, Alan.
Looks like I´m back to square one. Can You "translate" the part of the implementation of the CRC function, which is commented out, into PICAxe BASIC?

CalcCrcFromAtPtr:
b0 = @ptr
CalcCrcFromB0:
; u16 CRC16(u16 crc, u8 value)
; {
; u8 i;
; crc = crc ^ (s16)value<<8;
; for(i = 0; i < 8; i++)
; {
; if(crc & 0x8000)
; crc = crc << 1^0x1021;
; else
; crc = crc << 1;
; }
; return crc;
; }
Return

Regards Herbert
 

AllyCat

Senior Member
Hi,

In principle you don't need to decode the CRC just to receive the data (but you would in a transmitter if the receiver was going to test it).

Sorry, I can't even decide if (or to what extent) that code is in C (which I hate) or PICaxe Basic (X2 commands, which I don't use). Also, I think one would need some "sample data" to check the validity of the coding. But I can give few "tips": "crc" and "value" are probably word values and <<8 is the same as * 256 (and <<1 the same as * 2), and of course 0x the same as $. ^ is the bitwise XOR (Exclusive OR) function, & should be obvious and I think the FOR is a loop with 8 passes.

Hippy actually showed a CRC calculation in this SHT31 thread which was resurrected recently, but I think that uses an 8-bit CRC?

Cheers, Alan.
 

AllyCat

Senior Member
Hi,
Looks like I´m back to square one.
The "sensible" solution is to use an X2 PICaxe at 64 MHz with Background Receive enabled, which appears to be able to receive the required 115 kBaud.

However, I believe it might be "possible" to receive that protocol with an M2 chip. The data packet appears to be 35 bytes "concatonated" (continuous without any gaps) at 115 kbaud, which is about 87us per byte. That certainly cannot be done with a SERIN or even an HSERIN command at the maximum 32 MHz, but it might just be possible to receive the bytes by using some "linear" code, loading bytes into a buffer (RAM). Note that there are two "Known Bugs" with the M2's HSERIN and @BPTRINC commands, which I why I suggest the following:

The instruction PEEKSFR RCREG , ramaddress stores a byte from the HSERIN buffer into the RAM located above the normal registers and executes in about 75us. Therefore a list of about 50 repeated lines as follows should "store" all the received bytes.
Code:
symbol RCREG 	= $79		; Serial receive register
;  Detect the Start of the Data stream (somehow)
PEEKSFR  RCREG , 28   ; Copy byte from HSERIN buffer into RAM location 28
PEEKSFR  RCREG , 29
PEEKSFR  RCREG , 30
....
PEEKSFR  RCREG , 77
FOR bptr = 28 TO 77
   sertxd(" ",#@bptr)
NEXT bptr
That code does NOT detect that a "new" byte has arrived into the buffer, so typically about 1 byte in 7 will be the same as the previous byte. The problem will be "Post-Processing" the received bytes back to the actual data which was transmitted and received into the RCREG. I don't know if that will be possible in the time available but there are two characteristics which might be helpful. The data is transmitted in the form HiByte : LowByte (note that PICaxe Basic uses LowByte : HighByte by default), but only 12 bits are used, so the bytes are of the form: %0000 abcd : %efgh ijkl so the High bytes will always be less than 16 . However, the Low Byte also can be less than 16 and the "real" data stream may contain repeated bytes, so extracting the invalid, repeated bytes won't be easy.

Secondly you have the CRC which may allow the program to detect if the decoding has been completely successful. But there won't be time to correct any errors, the byte will just have to be marked as "bad". Note that the program will need to receive the whole message to calculate the CRC, but then for a "normal" servo you only need to extract 8 bits from the Word value, to form a single byte: %abcd efgh .

If you want to persevere with this project, it's probably best to revert to your original thread as that title/topic seems more appropriate.

Cheers, Alan.
 

FunFlyer

New Member
Thanks Alan,

I ordered 20x2s today and will go back to the original thread. I took the code Hippy provided, completed it and commented all lines referring to the crc out. When the chips arrive, I´ll give it a try and see what values I (hopefully) get. Hope to see You there when I need additional help.

regards
Herbert
 

BillBWann

Member
I want one of the chips to generate a signal with 8 pulses between 0.8 and 1.4 ms and a pause of 0.4ms in between.
Hi Herbert,

As I understand the project you outlined in #1, you wish to read in a train of 8 pulses whose pulse width varies between 1 and 2 msecs and output a shrunken stream of these same pulses with widths varying from 0.8 to 1.4 msecs. In both cases the pulse train is repeated every 25 msecs.

The following code implements my understanding of your project using three 08M2s. The first synthesizes the pulse train coming from the 8 channel radio control receiver and the other 2 operate as you suggested with the first using pulsin to measure each of the 8 pulses and then sending this digital data as quickly as possible to the second 08M2 which calculates the new width of each pulse and then uses pulsout to generate them.

The 16 bytes of digitized data needs to be sent in the interval between the last of the 8 pulses and the start of the next pulse train. The fastest readily transmittable rate for an 08M2 is 38,400 baud. To send 16 bytes at this rate takes about 5.1 msecs. In addition to this there needs to be a bit of processing time. By trial and error, I’ve found that the minimum transmissible interval is about 5.8 msecs. This leaves 19.2 msecs for the 8 channel pulse train or 2.4 msecs per channel. The pulse train output by the first 08M2 assumes that the 8 pulses are each 2 msecs wide and separated by a gap of 0.4 msecs. I believe that this test pulse train is the most demanding one that could be expected to be received by the second 08M2. In reality, the actual pulse widths and gaps aren’t important as long as the total pulse train doesn’t exceed 19.2 msecs.
Code:
#picaxe 08m2
#no_data

setfreq m32

w6=200*8
w7=200*8
w8=200*8
w9=200*8
w10=200*8
w11=200*8
w12=200*8
w13=200*8

do
    pulsout c.4,w6
    pauseus 213            '0.4    msecs
    pulsout c.4,w7
    pauseus 213
    pulsout c.4,w8
    pauseus 213
    pulsout c.4,w9
    pauseus 213
    pulsout c.4,w10
    pauseus 213
    pulsout c.4,w11
    pauseus 213
    pulsout c.4,w12
    pauseus 213
    pulsout c.4,w13
    pauseus 213
    
    pause 42            '5.8 msecs
loop
#endrem
The second 08M2 monitors pin c.1 waiting for a quiet interval at least 3 msecs wide to get to the start of the sequence and then measures the width of each pulse and sends these 8 words (sixteen bytes) out on pin c.4. While it is transmitting the digital data it checks, using the hardware latch, that no pulses have arrived at pin c.1 before it gets a chance to get back to start measuring the next pulse train. If pin c.1 has gone high, then it has to go through a new synchronising process which will cause the entire next pulse train to be skipped over. This would occur if the quiet interval was less than 5.8 msecs.

If you haven’t come across this hardware latch before, read this thread where Hippy and AllyCat told me all about how it works on both the 08M2 and the 18M2.
Code:
#picaxe 08m2
#no_data

Symbol IOCAP = $F1 ; $391
Symbol IOCAN = $F2 ; $392
Symbol IOCAF = $F3 ; $393


Initialise:
PokeSfr IOCAP, %00000010    'Set up latch on rising on pin c.1
PokeSfr IOCAN, %00000000    'No latch on any pin for falling edge
PokeSfr IOCAF, %00000000    'Where to see the flag

setfreq m32

do
    '------------ wait for initial idle period at end of pulse train
    b0=0
    do
        if pinc.1=0 then
            inc b0
        else
            b0=0
        endif
    loop while b0<10    'wait for a low period at least 4 msecs long
    
    '------------ continuously loop around reading pulse widths and outputting serial values until sync is lost
    do
        pulsin c.1,1,w6
        pulsin c.1,1,w7
        pulsin c.1,1,w8
        pulsin c.1,1,w9
        pulsin c.1,1,w10
        pulsin c.1,1,w11
        pulsin c.1,1,w12
        pulsin c.1,1,w13
    
        PokeSfr IOCAF, 0            'Reset all the latch flags
    
        bptr=12   
        serout c.4,N38400_32,(@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc)
    
        PeekSfr IOCAF, b0    'check to see if any input pins have gone high
        
    loop while bit1=0    'keep looping while nothing received on pin c.1 when sending serial data
        
loop    'loop back to resyncronise if sync is lost
The third 08M2 again waits for a quiet period to synchronise with the previous 08M2 before reading in the digitized data on its pin c.1 and calculating the new width using the formula:- New width=(Old Width-1msec)*0.6+0.8msecs. These calculated new pulse widths are then pulsed out using pulsout on pin c.4. Again, pin c.1 is checked to determine if any data arrived while it was producing the 8 pulses. If none has, then it can go back and wait for a new data stream, otherwise re-synchronising is required.
Code:
#picaxe 08m2
#no_data

Symbol IOCAP = $F1 ; $391
Symbol IOCAN = $F2 ; $392
Symbol IOCAF = $F3 ; $393


Initialise:
PokeSfr IOCAP, %00000010    'Set up latch on rising on pin c.1
PokeSfr IOCAN, %00000000    'No latch on any pin for falling edge
PokeSfr IOCAF, %00000000    'Where to see the flag

setfreq m32

do
    '------------ wait for initial idle period at end of pulse train
    b0=0
    do
        if pinc.1=0 then
            inc b0
        else
            b0=0
        endif
    loop while b0<10    'wait for a low period at least 4 msecs long

    '------------ continuously loop around reading pulse widths and outputting serial values until sync is lost
    do
        bptr=12   
        serin c.1,N38400_32,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc

        PokeSfr IOCAF, 0            'Reset all the latch flags

        W6=W6-800**39322+640 '(New width=(Old Width-1msec)*0.6+0.8msecs)
        W7=W7-800**39322+640
        W8=W8-800**39322+640
        W9=W9-800**39322+640
        W10=W10-800**39322+640
        W11=W11-800**39322+640
        W12=W12-800**39322+640
        W13=W13-800**39322+640
        
        pulsout c.4,w6
        pauseus 213            '0.4    msecs
        pulsout c.4,w7
        pauseus 213
        pulsout c.4,w8
        pauseus 213
        pulsout c.4,w9
        pauseus 213
        pulsout c.4,w10
        pauseus 213
        pulsout c.4,w11
        pauseus 213
        pulsout c.4,w12
        pauseus 213
        pulsout c.4,w13

        PeekSfr IOCAF, b0    'check to see if any input pins have gone high
        
    loop while bit1=0    'keep looping while nothing received on pin c.1 when sending serial data
        
loop    'loop back to resyncronise if sync is lost
#endrem
The pictures below show the initial pulse stream, the digitized data and the final shortened pulse stream. First an overview of a number of cycles and then a close up. The close up shows the sequence with a pulse train from the radio receiver arriving at the top right, the digitized data in the middle and the generated shortened sequence at bottom right.

24418

24419

I hope I've interpreted your requirements correctly but get back to me if I haven't.
 

Attachments

AllyCat

Senior Member
Hi,

I would normally leave it for the OP to reply but as he is not using his native language, perhaps I can "interpret" what I believe to be the problem. I think he has achieved his first paragraph and the problem is in paragraph 2:
Then I wanted to read pulses between 1.0 to 2.0 ms and uses those values to dynamically adjust first 8 pulses. I tried several approaches so far. None of them worked.
I think the (unwritten) issue is that the "pulses" may be on different channels (PICaxe pins) and/or with a very short gap (some microseconds) between the end of the first and start of the second pulse. Thus, when the second PULSIN is executed, the second pulse has already started and the instruction has to wait 25 ms (the frame period) before the second pulse can be read. I don't know why a second 25 ms appears to be "lost" but it may be a miunderstanding about the sequence of events (Basic instructions). That is why I suggested he insert additional "marker" instructions/pulses on a spare pin, to show the sequence of events.

I believe it might be possible to "solve" the issue either by using two PICaxes working in unison to measure the (alternate) pulses, or a single PICaxe using both a PULSIN and "Timer 1" enabled by the Timer1 Gate Hardware. But that needs quite "Advanced" Programming to solve only a secondary issue, associated with his "work around" to the fundamental problem described in his other thread.

I believe the fundamental issue is that the OP wants to decode (the output from) a commercial Radio Control system which transmits 27 (or 35) concatonated bytes sent at a 115 kbaud rate. That should be possible with a PICaxe X2 chip, but the OP was trying to use an M2, which is (almost) "impossible". Therefore, he has now purchased an X2 and I hope we will be able to help him in that other thread. However, I have done a lot of work with the M2's HSERIN command and look on it as an "interesting challenge" to see if what he wants can be done with an M2 (but it certainly won't meet the Title/Subject of "SIMPLE ...."). So here is my "analysis" of the task:

Each (concatonated) byte at 115 kbaud has a nominal duration of 87 us, which is hardly more than the duration of a single PICaxe Instruction at 32 MHz SETFREQ. The (M2) HSERIN command is too "undefined" (and/or Buggy) to be used but a PEEKSFR RCREG , ... is known to work reliably in about 75 us (at 32 MHz). Thus it should be (just) possible to "keep up with" data coming into the receive buffer, but only with a block of linear code (no "loop" or any type of "decision-making"). This raises (at least) two fundamental problems: (A) There is no time to read the "New Byte Received" flag (in the PIR1 SFR), let alone act on its value, so some of the "received" bytes will be repeated in the received data block. (B) It's necessary to "decide" when to Start transferring data into the (RAM) buffer:

The M2's Hardware buffer is only 2 bytes deep, so we have up to about 200 us to read the first byte after the first Start pulse (much less if reading a flag from a SFR value). Note that a "Conditional Jump" (i.e. a program "branch" or "decision") takes about 150 us, so I've considered three possible solutions:

(1) It might be possible to "predict" when the data burst is due to start (i.e. a PAUSE after the previous frame ) but that needs to be quite accurate to work with a rate of 11 bytes/ms, because the program subsequently needs to "search" the RAM buffer to find the actual starting byte.

(2) If the "main" part of the program is executing a PAUSE then an Interrupt is supposed to be executed "immediately", but the time increment of a Pause is 125us (at 32 MHz) so that might be the "polling" rate for the interrupt, and then a subroutine Call takes about another 125 us. Therefore, I would expect the Interrupt to take a similar time (i.e. a potential total up to 250 us). So something that calls for a Hardware test. ;)

(3) Thus, I suggest an ultra-tight polling loop of just one instruction:
Code:
    bptr = 28   ; Start of buffer
WaitForStart:  
     IF receivepin = 1 THEN {GOTO} WaitForStart ; Else fall through (Note HSERIN is always Idle-High in M2s)
     PEEKSFR RCREG , @bptr          ; Read the first byte     
     PEEKSFR RCREG , @bptrINC    ; Bug causes a Pre-Increment AND a Post-Increment of bptr
     PEEKSFR RCREG , @bptr          ; Repeat for about 40 - 50 bytes of RAM
; ... etc .
But there is a problem (which also applies with an Interrupt) that the M2's IF can't directly read any SFR flags (only a Pin) and the Serial Data level may have returned to the "non-start" level when it is read. Therefore, we need a "Latch" function; the "SR-Latch" is a possibility but its output needs to be fed onto another (input) pin. That needs 3 pins (in addition to the normal HSERIN pin), so I propose a simple external diode and capacitor to "stretch" the Start pulse onto another input pin.

Then, assuming that all the bytes can be received into a RAM buffer, we need to solve issue (A) above, that there will be spurious repeated bytes in the RAM list. A "first pass" can work through the buffer deleting (or ignoring) all repeated byte values, but there is the possibility that the "real" data did contain repeated bytes. So it would be necessary to abandon that particular block of data and/or attempt a "second pass" to identify where the repeated byte(s) occurred.

EDIT: The PEEKSFR code I posted in #10 does not have valid syntax, but it's possible to "work around" the double-incrementing bug, so I've changed the code in this thread.

Cheers, Alan.
 
Last edited:

FunFlyer

New Member
High Alan and Bill,

thanks very much for Your efforts. But as I said in post #11, I´ll go back to my original idea. Oh and by the way, there´s no requirement, that the solution must work on a 08M2 chip. It was just the one, that I had readily available. So don´t try to make a Piper Cub fly supersonic. I´ll keep You informed about my progress.

regards
Herbert

PS. What does "OP" stand for?
 

AllyCat

Senior Member
Hi,

Sorry, "OP" = Original Post or Original Poster (i.e. the person asking the question).

Yes, it's just that I find it "amusing" to write code for a chip which uses only just over 1 mW of power and requires only 1 cm2 of PCB area. It also happens to be the fastest PICaxe for a given clock speed (!) and the one that I had "to hand". My current project has the capability to drive up to 6 micro-stepper motors with an 08M2 (without using any "expander" chips). ;)

Cheers, Alan.
 

BillBWann

Member
Hi Herbert and Alan,

I’m concerned that I didn’t sufficiently explain a crucial point about the concept of the programs I submitted yesterday.

In your first post Herbert you say:-
I want one of the chips to generate a signal with 8 pulses between 0.8 and 1.4 ms and a pause of 0.4ms in between. A ninth pulse is added to complete a frame of 25ms. I got this running when the chip is set to 32Mhz and a constant pulse length of 1.1ms is used. It´s all done by "PULSEOUT" and "PAUSEUS" commands.

Then I wanted to read pulses between 1.0 to 2.0 ms and uses those values to dynamically adjust first 8 pulses. I tried several approaches so far. None of them worked.
The point of my programs yesterday was to demonstrate that there is no need to generate a ninth pulse to complete the 25ms frame. That is because you said that both your 1-2 ms input channel (or is it channels?) and your 0.8-1.4ms output have 25ms frames so by synchronizing the two, you can simply use your input channel to generate the 25ms output frame. And that saves you having to both calculate how long that 9th pulse has to be and then trying to implement it while doing other things like “dynamically adjust first 8 pulses”

I believe that synchronizing the output pulse frame with at least one of the 1-2ms input pulse frames (if there is more than 1) would be much easier to implement compared to your "ninth pulse" approach and that would apply to whichever method for measuring input pulses you end up using.

I suspect that even with a 20X2, the purely digital approach will be nontrivial.

Bill
 
Top