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
 

FunFlyer

New Member
Update

Still no reply from Hippy, so I came back to this thread.

I got the 20X2 chips, programmed the follwing code, which you can find also in the attched file.

Code:
; Versionierung
; V0:    Original aus dem Forum von Hippy
; V0.1: Ergaenzt um fehlende Anteile
; V0.2: CRC auskommentiert

#Picaxe 20X2
#Terminal 38400
#No_Data
#No_Table

Symbol reserveW0 = w0  ; b1:b0
Symbol servo1    = w1  ; b3:b2
Symbol servo2    = w2  ; b5:b4
Symbol servo3    = w3  ; b7:b6
Symbol servo4    = w4  ; b9:b8
Symbol servo5    = w5  ; b11:b10
Symbol servo6    = w6  ; b13:b12
Symbol servo7    = w7  ; b15:b14
Symbol servo8    = w8  ; b17:b16
Symbol servo9    = w9  ; b19:b18
Symbol servo10   = w10 ; b21:b20
Symbol servo11   = w11 ; b23:b22
Symbol servo12   = w12 ; b25:b24
Symbol servo13   = w13 ; b27:b26
Symbol servo14   = w14 ; b29:b28
Symbol servo15   = w15 ; b31:b30
Symbol servo16   = w16 ; b33:b32
Symbol crc       = w17 ; b35:b34
Symbol rxCrc     = w18 ; b37:b36
Symbol rxCrc.lsb = b36
Symbol rxCrc.msb = b37
Symbol header    = b38

#Macro GetByte(bVar)
  Do : Loop While ptr = hSerPtr
  bVar = @ptrInc
#EndMacro

#Macro GetWord(wVar)
  Do : Loop While ptr = hSerPtr
;  Gosub CalcCrcFromAtPtr
  wVar = @ptrInc
  Do : Loop While ptr = hSerPtr
;  Gosub CalcCrcFromAtPtr
  wVar = wVar << 8 | @ptrInc
#EndMacro

#Macro ShowHexByte(bVar)
  b1 = bVar : Gosub ShowHexByteMsb
#EndMacro

#Macro ShowHexWord(wVar)
  w0 = wVar : Gosub ShowHexByteMsb
  b0 = wVar : Gosub ShowHexByteLsb
#EndMacro

PowerOnReset:
  SetFreq M64
  HSerSetup B115200_64, %001 ; or %111

MainLoop:
  Do
    Do
      GetByte(header)
    Loop Until header = $A1 Or header = $A2
;    Gosub InitCrc
    GetWord(w1) ; Servo 1
    GetWord(w2)
    GetWord(w3)
    GetWord(w4)
    GetWord(w5)
    GetWord(w6)
    GetWord(w7)
    GetWord(w8)
    GetWord(w9)
    GetWord(w10)
    GetWord(w11)
    GetWord(w12)
    If header = $A1 Then
      GetByte(rxCrc.msb)
      GetByte(rxCrc.lsb)
      SerTxd( "12 = ", #w1,  TAB, #w2,  TAB, #w3,  TAB, #w4,  CR, LF )
      SerTxd( "     ", #w5,  TAB, #w6,  TAB, #w7,  TAB, #w8,  CR, LF )
      SerTxd( "     ", #w9,  TAB, #w10, TAB, #w11, TAB, #w12, CR, LF )
    Else
      GetWord(w13)
      GetWord(w14)
      GetWord(w15)
      GetWord(w16)
      GetByte(rxCrc.msb)
      GetByte(rxCrc.lsb)
      SerTxd( "16 = ", #w1,  TAB, #w2,  TAB, #w3,  TAB, #w4,  CR, LF )
      SerTxd( "     ", #w5,  TAB, #w6,  TAB, #w7,  TAB, #w8,  CR, LF )
      SerTxd( "     ", #w9,  TAB, #w10, TAB, #w11, TAB, #w12, CR, LF )
      SerTxd( "     ", #w13, TAB, #w14, TAB, #w15, TAB, #w16, CR, LF )
    End If
;    If crc <> rxCrc Then
;      SerTxd( "FAIL - Got" )
;      ShowHexWord(crc)
;      SerTxd( " Should be" )
;      ShowHexWord(rxCrc)  
;      SerTxd( CR, LF )
;    End If
  Loop

;InitCrc:
;  crc = $0000
;  b0 = header
;  Goto CalcCrcFromB0
;
;CalcCrcFromAtPtr:
;  b0 = [USER=70770]@ptr[/USER]
;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

ShowHexByteMsb:
  SerTxd(" $")
  b0 = b1
ShowHexByteLsb:
  b1 = b0 >>  4 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
  b0 = b0 & $0F + "0" : If b0 > "9" Then : b0 = b0 + 7 : End If
  SerTxd( b1, b0 )
  Return
The signal frm the RC-receiver is feed into pin B.6 (hserin). After successful programming the 20X2 the terminal window starts.

I was expecting to see the vaules the receiver transmits on its serial output grouped in 4 values per row, separated by TABs. 4 rows at a time and then start over. Instead I get this, which makes no sense to me at all.

24591

The settings (38400/N/8/1) seem OK to me. Changing between ASCII and Raw doesn´t make any difference.

Any Idea, what I´m doing wrong?
 

Attachments

Last edited:

AllyCat

Senior Member
Hi,

AFAIK the default SERTXD is 4800 baud with a SETFREQ clock of 4 MHz, so it should be #Terminal 76800 when you're using SETFREQ M64.

Do you really need to use 115200 baud? IMHO you may be creating problems for yourself; PICaxe is just not a "fast" processor. :(

EDIT: Why are you using an HSERSETUP B115200 and then not using any HSEROUT instructions?

And please put your programs within [code ] ... [/code] tags. ;)

Cheers, Alan.
 
Last edited:

FunFlyer

New Member
Thanks Alan,

that works. No it looks like expected

24592

Now I can start thinking about implemeting what to do with these numbers. That terminal is awful slow, but I assume, since I´m not going to use it in the end, it´s OK for now.

Thanks again


Herbert
 
Last edited:

WhiteSpace

Well-known member
I regularly get the same stream of nonsense when the SetFreq and #Terminal settings don’t match, and/or I have a different baudrate set in the terminal window. Where you change the frequency to 64 MHz half way down, do you also need to change the #terminal setting, but then I’m not sure how at that point you also change the rate in the window? I sometimes also find that I need to close and reopen the terminal window if I set a new speed.
 

FunFlyer

New Member
Hi,

AFAIK the default SERTXD is 4800 baud with a SETFREQ clock of 4 MHz, so it should be #Terminal 76800 when you're using SETFREQ M64.

Do you really need to use 115200 baud? IMHO you may be creating problems for yourself; PICaxe is just not a "fast" processor. :(

EDIT: Why are you using an HSERSETUP B115200 and then not using any HSEROUT instructions?

And please put your programs within [code ] ... [/code] tags. ;)

Cheers, Alan.
Hi Alan,

I hope I fixed the "code" stuff.

The "Hsersetup" command was is in the original code Hippy provided. I left it in there, since I thought it is needed for "hserin". In Manual 2 I found the following pragraph:

Hardware serial input can be configured in two ways:
1) via hserin command only (mode bit0 = 0)
2) automatic in the background (mode bit0 = 1) (not M2 parts)
Does that imply I could remove the "Hsersetup" command? Are there any drawbacks if I just leave it in?

regards

Herbert
 

AllyCat

Senior Member
Hi,
Does that imply I could remove the "Hsersetup" command? Are there any drawbacks if I just leave it in?
Personally, I never use X2 chips so I'm not the best person to ask. But yes, you need a HSERSERUP command (only) if you are using the HSERIN command (or background receive). Personally, I would normally remove any "unnecessary" commands, if only to avoid confusion (to myself, or any other reader of the program).

There are (at least) two "drawbacks" that I can foresee: If the HSERSETUP is setting up "background receive" with a parameter %xxxxxxx1 (which I believe it is), then "serial data" on the HSERIN pin (which in practice could be any digital level changes) will be written to the "scratchpad" buffer/memory. Therefore, that memory cannot be used for any other purpose. Secondly, there is the possibility that the HSERIN pin will not operate correctly as an Output pin (and maybe an ADC Input pin).

Cheers, Alan.
 

FunFlyer

New Member
I´m almost afraid to ask....

before getting into forming the output signal i´ll need, I wanted to try to just turn a LED (connected to c.0 from there via a 300 ohm resistor to +5V) on and of, depending on one of the received values, in my case memory "servo1"(w1). Here´s the extended code:

Code:
; Versionierung
; V0:    Original aus dem Forum von Hippy
; V0.1: Ergaenzt um fehlende Anteile
; V0.2: CRC auskommentiert
; V0.3: Speicher f?r rxCrc.lsb, rxCrc.msb und header korrigiert
; V0.4: bereinigt um nicht ben?tigten Code



#Picaxe 20X2
#Terminal 76800
#No_Data
#No_Table

Symbol reserveW0 = w0  ; b1:b0
Symbol servo1    = w1  ; b3:b2
Symbol servo2    = w2  ; b5:b4
Symbol servo3    = w3  ; b7:b6
Symbol servo4    = w4  ; b9:b8
Symbol servo5    = w5  ; b11:b10
Symbol servo6    = w6  ; b13:b12
Symbol servo7    = w7  ; b15:b14
Symbol servo8    = w8  ; b17:b16
Symbol servo9    = w9  ; b19:b18
Symbol servo10   = w10 ; b21:b20
Symbol servo11   = w11 ; b23:b22
Symbol servo12   = w12 ; b25:b24
Symbol servo13   = w13 ; b27:b26
Symbol servo14   = w14 ; b29:b28
Symbol servo15   = w15 ; b31:b30
Symbol servo16   = w16 ; b33:b32
Symbol crc       = w17 ; b35:b34
Symbol rxCrc     = w18 ; b37:b38
Symbol rxCrc.lsb = b39
Symbol rxCrc.msb = b40
Symbol header    = b41

#Macro GetByte(bVar)
  Do : Loop While ptr = hSerPtr
  bVar = @ptrInc
#EndMacro

#Macro GetWord(wVar)
  Do : Loop While ptr = hSerPtr
  wVar = @ptrInc
  Do : Loop While ptr = hSerPtr
  wVar = wVar << 8 | @ptrInc
#EndMacro


PowerOnReset:
  SetFreq M64
  HSerSetup B115200_64, %001
  high c.0

MainLoop:
  Do
    Do
      GetByte(header)
    Loop Until header = $A1 Or header = $A2
    GetWord(w1) ; Servo 1
    GetWord(w2)
    GetWord(w3)
    GetWord(w4)
    GetWord(w5)
    GetWord(w6)
    GetWord(w7)
    GetWord(w8)
    GetWord(w9)
    GetWord(w10)
    GetWord(w11)
    GetWord(w12)
    If header = $A1 Then
      GetByte(rxCrc.msb)
      GetByte(rxCrc.lsb)
      SerTxd( "12 = ", #w1,  TAB, #w2,  TAB, #w3,  TAB, #w4,  CR, LF )
      SerTxd( "     ", #w5,  TAB, #w6,  TAB, #w7,  TAB, #w8,  CR, LF )
      SerTxd( "     ", #w9,  TAB, #w10, TAB, #w11, TAB, #w12, CR, LF )
    Else
      GetWord(w13)
      GetWord(w14)
      GetWord(w15)
      GetWord(w16)
      GetByte(rxCrc.msb)
      GetByte(rxCrc.lsb)
      SerTxd( "16 = ", #w1,  TAB, #w2,  TAB, #w3,  TAB, #w4,  CR, LF )
      SerTxd( "     ", #w5,  TAB, #w6,  TAB, #w7,  TAB, #w8,  CR, LF )
      SerTxd( "     ", #w9,  TAB, #w10, TAB, #w11, TAB, #w12, CR, LF )
      SerTxd( "     ", #w13, TAB, #w14, TAB, #w15, TAB, #w16, CR, LF )
    End If

if servo1 < 1900 then ; blink once
    low c.0
    pause 1000
    high c.0
    pause 5000
Else if servo1 > 2100 then ; blink threetimes
    low c.0
    pause 1000
    high c.0
    pause 2000
    low c.0
    pause 1000
    high c.0
    pause 2000
    low c.0
    pause 5000
Else ; blink twice
    low c.0
    pause 1000
    high c.0
    pause 2000
    low c.0
    pause 1000
    high c.0
    pause 5000
end if

  Loop
the received values as shown in the terminal range from 0 to 4000. I don´t get any reaction from the LED. Commenting out the "teminal" and "sertxd" statements doesn´t help.

Even if I comment out the IF statement for the "blinking", except for the lines in the last "else branch" , so no reference to any variables, the LED doesn´t show any reaction.

the simple program


high c.0

main:
low c.0
pause 1000
high c.0
pause 2000
low c.0
pause 1000
high c.0
pause 5000
goto main


works.

So why do the values/variables get displayed correctly in the terminal, but I can´t use those variables in the code?

I´m confused. On one hand I know, that the scratchpad is a separate area of memory, which can be accessed by the "Put" and "Get" command. I can´t get that to work properly. Doesn´t the statement "Symbol servo1 = w1" declare a variable in normal RAM memory? The statement "GetWord(w1)" suggested to me that the received value was stored in that "RAM variable" w1, and could therefore be used in the "sertxd" statement.

regards

Herbert
 
Last edited:

AllyCat

Senior Member
Hi,

Yes, "Getword( var )" is a Macro, defined higher in the program and servo1 and w1 should be equivalent, so it looks as if it should all work. But....

Your "simple" program doesn't include a SETFREQ M64 which will make the LED flash 8 times faster (i.e. 125 ms). Are you sure the LED isn't just flashing faster than you can see?

Cheers, Alan.
 

FunFlyer

New Member
High Alan,

thanks for the hint.
- I increased the "pauses" by a factor of ten. No change
- added the SetFreq m64 in the simple program and increased the "pauses" as well. Still works fine
- commentet out the "IF" statement again, leaving just LED turn ON/OFF. No result.

unfortunately that didn´t do the trick. I checked with my oszilloscope. With the simple programm c.0 changes from 0 to 5V. With the origial c.0 just stays at 5V.

regards

Herbert
 

AllyCat

Senior Member
Hi,

Port.pin C.0 is HSEROUT on a 20X2 ! You need to disable HSEROUT in the HSERSETUP command (set bit 3, i.e. change to %1001) if you want to use it as a "normal" output pin.

Cheers, Alan.
 

FunFlyer

New Member
High Alan,

that works just fine. Since this is just a test, I used c.2 instead of c.0, but I´ll keep your advice in mind for the future.

thanks a lot. On to the next step....

regards

Herbert
 

FunFlyer

New Member
O well...

not getting anywhere. I think I´ll start at the beginning. Below are two pictures, that show the pulsetrain I´m trying to create. Top one shows several frames. Bottom one details.

24596

24597

This is the output of an older MULTIPLEX transmitter, that had a trainerjack, where you had access to the signal. If I feed this into the transmitter, that "speaks" the DSMX protocoll, which my tiny receiver understands, everything works just fine.

So this is what I´m trying to create. So far I´m getting the values from my MULTIPLEX receiver as a stream. The values for each channel are stored in the variables "servo1" to "Servo16"

showing them in the terminal works fine. Using them in in an IF statement, to switch a LED works fine.

To create the signaltrain I added some Variables, constants and code (Bold in the sourcecode).

Code:
; Versionierung
; V0:    Original aus dem Forum von Hippy
; V0.1: Ergaenzt um fehlende Anteile
; V0.2: CRC auskommentiert
; V0.3: Speicher f?r rxCrc.lsb, rxCrc.msb und header korrigiert
; V0.4: bereinigt um nicht ben?tigten Code
; V0.5: Testroutine mit "LED-Blinker" implementiert, Terminal auskommentiert



#Picaxe 20X2
#Terminal 76800
#No_Data
#No_Table

Symbol reserveW0 = w0  ; b1:b0
Symbol servo1    = w1  ; b3:b2
Symbol servo2    = w2  ; b5:b4
Symbol servo3    = w3  ; b7:b6
Symbol servo4    = w4  ; b9:b8
Symbol servo5    = w5  ; b11:b10
Symbol servo6    = w6  ; b13:b12
Symbol servo7    = w7  ; b15:b14
Symbol servo8    = w8  ; b17:b16
Symbol servo9    = w9  ; b19:b18
Symbol servo10   = w10 ; b21:b20
Symbol servo11   = w11 ; b23:b22
Symbol servo12   = w12 ; b25:b24
Symbol servo13   = w13 ; b27:b26
Symbol servo14   = w14 ; b29:b28
Symbol servo15   = w15 ; b31:b30
Symbol servo16   = w16 ; b33:b32
Symbol crc       = w17 ; b35:b34
Symbol rxCrc     = w18 ; b37:b38
Symbol rxCrc.lsb = b39
Symbol rxCrc.msb = b40
Symbol header    = b41

SYMBOL Ruhezeit = w21        `Rest of the Frame without pulses and low periods between them
SYMBOL PPM      = C.2        `port assignment for PPM signaltrain
SYMBOL Impulspause = 360    ;low intervall between Pulses
SYMBOL Framesize     = 15000      `total framelength



#Macro GetByte(bVar)
  Do : Loop While ptr = hSerPtr
  bVar = @ptrInc
#EndMacro

#Macro GetWord(wVar)
  Do : Loop While ptr = hSerPtr
  wVar = @ptrInc
  Do : Loop While ptr = hSerPtr
  wVar = wVar << 8 | @ptrInc
#EndMacro


PowerOnReset:
  SetFreq M64
  HSerSetup B115200_64, %001
  High PPM
;
MainLoop:
  Do
    Do
      GetByte(header)
    Loop Until header = $A1 Or header = $A2
    GetWord(w1) ; Servo 1
    GetWord(w2)
    GetWord(w3)
    GetWord(w4)
    GetWord(w5)
    GetWord(w6)
    GetWord(w7)
    GetWord(w8)
    GetWord(w9)
    GetWord(w10)
    GetWord(w11)
    GetWord(w12)
    If header = $A1 Then
      GetByte(rxCrc.msb)
      GetByte(rxCrc.lsb)
      SerTxd( "12 = ", #w1,  TAB, #w2,  TAB, #w3,  TAB, #w4,  CR, LF )
      SerTxd( "     ", #w5,  TAB, #w6,  TAB, #w7,  TAB, #w8,  CR, LF )
      SerTxd( "     ", #w9,  TAB, #w10, TAB, #w11, TAB, #w12, CR, LF )
    Else
      GetWord(w13)
      GetWord(w14)
      GetWord(w15)
      GetWord(w16)
      GetByte(rxCrc.msb)
      GetByte(rxCrc.lsb)
      SerTxd( "16 = ", #w1,  TAB, #w2,  TAB, #w3,  TAB, #w4,  CR, LF )
      SerTxd( "     ", #w5,  TAB, #w6,  TAB, #w7,  TAB, #w8,  CR, LF )
      SerTxd( "     ", #w9,  TAB, #w10, TAB, #w11, TAB, #w12, CR, LF )
      SerTxd( "     ", #w13, TAB, #w14, TAB, #w15, TAB, #w16, CR, LF )
    End If

    low PPM
    pauseus impulspause

    Pulsout PPM, servo3
    Ruhezeit = Framesize - servo3
    pauseus Impulspause

    Pulsout PPM, servo2
    Ruhezeit = ruhezeit - servo2
    pauseus Impulspause

    Pulsout PPM, servo1
    Ruhezeit = Ruhezeit - servo1
    pauseus Impulspause

    Pulsout PPM, servo4
    Ruhezeit = Ruhezeit - servo4
    pauseus Impulspause

    Pulsout PPM, servo5
    Ruhezeit = Ruhezeit - servo5
    pauseus Impulspause

    Pulsout PPM, servo6
    Ruhezeit = Ruhezeit - servo6
    pauseus Impulspause

    Pulsout PPM, servo7
    Ruhezeit = Ruhezeit - servo7
    pauseus 180

    low PPM
    pauseus 180

    high PPM
    pauseus Ruhezeit

  Loop
I get a signaltrain, but it´s nothing usable at all. Pulslength changes by itself, frames have any number of pulses (0 to7), framelength differs considerably. When I feed this signal into my "DSMX"-transmitter the servo on the receiver goes crazy turning back and forth, sometimes even responding to my stick-movements on th MULTIPLEX transmitter (I think). Same with the motor. Since I couldn´t find a mistake in my code, I went back to look at the readin values on the terminal. This is what I got:

24598

values shoul be between 800 and about 4000. But there are numbers over 65000 and as low as 7!!! I can´t find out why the values are OK, when I just display them in the terminal, but go way off, when I use them in the signal creation process. Any ideas?

regards

Herbert
 
Last edited by a moderator:

AllyCat

Senior Member
Hi,

You need to take into account that PICaxe Basic is an "interpreted" language so every instruction takes a considerable time to decode and execute. I prefer to work in "base PIC" Instruction Cycles which each take 1us with a normal 4MHz (M2 PICaxe) clock and 62.5 ns with an X2 running at 64MHz. For example the "overhead" on a PAUSEUS or PULSOUT (which are very similar) is about 700 ICs, or around 44 us at 64 MHz. Many of these details are discussed in an old (and long) thread by Westaust55 (and me from post #12) and I have written some recent "Code Snippets", for example showing how to measure PICaxe execution times (only for M2s because I don't use X2 chips).

I can't see from your code what time delays you are attempting to create, but your "SYMBOL Impulspause = 360 ;low intervall between Pulses" is almost certainly incorrect and may indicate that what you are trying to do is impossible with a PICaxe. Remember that ALL PULSIN, PULSOUT, PAUSEUS and SERTXD commands are implemented by "Bit Banging", so the PICaxe System/Interpreter cannot do anything else at the same time. Only HSERIN and HSEROUT process data partly by using "Hardware Assistance".

There are other complications: your SERTXDs appear to be transmitting around 100 characters, per frame which even at 76000 baud will take a significant (and probably variable) time (I guess more than 10 ms). Also, the PICaxe System generates Interrupts at "random" times during the execution of the User's Program and (I was quite surprised to discover) these are NOT disabled during execution of the PULSIN and PULSOUT commands, so sometimes their values contain errors. If you list all the time ranges and tolerances (in English please ;) ) that you're trying to achieve, I might be able to indicate if there is any possibility of a PICaxe being able to do what you want.

Cheers, Alan.
 

AllyCat

Senior Member
Hi,

I've now read through (most of) the whole thread again and had "forgotten" some of the details from more than two months ago. Also a lot has not yet been described ! IMHO, the complete Program (or programs) must fully execute in a Single Frame (of 25 ms). The reason is that, for example, if an output (Servo) pulse over-runs into the HSERIN data-receiving time, then its interrupts will corrupt the (bit-banged) pulse-width (or the interrupt-driven pulses if the PICaxe's embedded SERVO command is being used).

So we must put some "numbers" into the program design: Firstly, you appear to be receiving 25 or 33 bytes at 115200 baud which will take a minimum of 2.9ms if fully concatonated (touching) and perhaps twice as long if generated by another PICaxe (because of the inter-character gaps). A scope trace of that waveform could be useful.

You originally spoke of "8 pulses between 0.8 and 1.4 ms and a pause of 0.4ms in between." in post #1, but I think that was your proposed "inter-PICaxe" protocol? It seems you actually want to transmit (up to?) 10 "Servo" pulses which (normally) have a maximum width of 2.25 ms and (I think you said) gaps of 400 us? That comes to 26.5 ms !? Also you are using PULSOUT values up to (at least) 2054 (post #19) which with a 64 MHz clock will each take 2054 * 1.25 us = 2.57 ms (+0.4 ms gap?). But you could never have generated 10 Servo Pulses (or any more than 4) from an 08M2 (in the original title). :confused:

Of course these figures alone leave no time to transmit any "diagnostics" serial data, so that can only be sent in a "test" mode and must be "patched out" (e.g. using #IFDEFs) to run the actual program. Therefore, we (or at least I) need a "real" specification with details such as :

+ How many serial input bytes are there, and how long will they take to arrive?
+ How many of these bytes will actually be used ? (There's no point in wasting time on processing any that aren't needed).
+ How many (Servo) pulses are to be generated ?
+ What is the resolution of the output pulses ? Normal servo pulses are less than 8 bits (75 - 225) but you are receiving 12 bits (0 - 4095) !
+ What "processing" of the data bytes is required between the serial input and pulse(s) output ?

Then we can consider whether 1 or 2 PICaxes might be adequate for the task. 4 - 6 servo pulses might be possible with a single 20X2, but any more probably need (at least) two PICaxes. Receiving the serial data (into an X2 with background receive) seems relatively straightforward, but processing (all of) that data in any way may take a considerable time. But (except for test/debugging) there is no need to do anything with it initially. The data bytes are already sitting there in the scratchpad ! You might calculate the CRC, but it's not fundamentally needed, PICaxe Basic probably can't calculate it fast enough, and your present code looks wrong! But if you DO want to calculate the CRC, then start another thread, because anyone who can help probably won't be reading this one. ;)

Probably the best way to organise the Program(s) is the reset the (scratchpad) ptrs before the start of each frame. Then, the main program can wait until the pointer moves (DO : LOOP WHILE ptr = hSerPtr) and then pull the required bytes directly out of the scratchpad and "process" them "on the fly" because the processing will probably be (much) slower than the speed of data-arrival). I guess it's probably "scaling" the values and maybe setting range limits (e.g. to 75 - 225), which is perhaps all there's time for a PICaxe to do.

If there are only a few pulses to output, then they can probably be generated (e.g. by PULSOUTs), but if there is a higher number then the processed data bytes could be sent to another PICaxe (probably at a lower baud rate, up to 38400) . This second processor would be receiving "processed" bytes, so it can spend nearly all its time outputting the data. The second processor might even be an M2 and/or using the SERVO command(s) which are NOT specified to be used with a 64 MHz clock. The "normal" Servo commands use a 20ms frame, but that can easily be fixed. ;)

Cheers, Alan.
 

FunFlyer

New Member
High Alan,

Where to start?

I posted a trace of the waveform I´m trying to create in #29. Only differrence ist that I only really need 4 pulses, however I don´t know, whether the transmitter I´m trying to feed is OK with 4 or needs 7 pulses, since it´s a 7-channel transmitter. If that is the case, the additional 3 pulses can be of fixed length (1.2ms), which should need no data processing at all.

Here´s a trace of the incoming SRXL stream at different scope settings

24603

24604



Timing specifications for the output:

framelength: 25ms

I remeseared the pulselengths: minimum 0.6ms, center 1.2ms, maximum 1.8ms

pause between pulses: 0.4ms

rest of the frame outputlevel is high.

So for 4 pulses we have 4x1.2+5x0.4 = 6.8ms leaving 18.2ms high level

and for 7 pulses we have 7x1.2 + 8x0.4 = 11.6ms leaving 13.ms high level

the above computations are for all pulses "center" length. If any pulses are different the high level time must be adjusted accordingly.

I attached the SRXL protocoll specification (german and english). The only information I need from that datastream is the information for channels 13-16. Those are the 4 pulses to be retransmitted. The pulselength are transmitted as 12 bits (resolution 4096 steps). For my project I need only 10 bit (resolution 1024). So these 4 numbers must be processed to represent the pulselengths to be transmitted.


I hope I answered Your questions.


regards

Herbert
 

Attachments

Last edited:

AllyCat

Senior Member
Hi,
Where to start?
.... the waveform I´m trying to create in #29 [which shows 10 pulses] . Only difference is that I only really need 4 pulses, however I don´t know, whether the transmitter I´m trying to feed is OK with 4 or needs 7 pulses,
The starting point should always be a "Requirements Specification", or at least a Project Plan, preferably with a "Block Diagram". ;) There's a lot of difference in the time required for 4 pulses compared with 10 ! And I thought you were trying to decode the output from a receiver, not encode data for a transmitter?

Normally, you should calculate the "worst case" conditions, so the 4 pulses could take 1.8 + 0.4 = 2.2 * 4 = 8.8 ms (or 10.4 ms, see below?) but the 3 extra pulses could be set to "nominal" or even "minimum", so maybe another 3 ms to make a total of around 12 ms, thus your 13 ms "free time" looks about right. However, for PICaxe, Servo pulses are normally considered to have a range of 750 - 2250 us ?

Your new photos are useful, but don't tell the "full story", we really need another at the bit/byte scale and ideally a full sample of the byte values (to verify the CRC), but that may need a Logic Analyser rather than a scope. However, it appears that your 115.2 kbaud data burst lasts 2.4 ms so there cannot be more than about 276 bits or 27 bytes (at 10 bits/byte including Start and Stop bits). So presumably this is the "A1" data format with 27 bytes (including the CRC) and a tiny gap between bytes ; but the specification refers to cycle times of 14 or 21 ms? Again, a requirement for 25 data bytes is very different to 33, particularly when calculating the CRC ! Incidentally, I've been looking at the CRC code, which I've now posted in the other thread.

However, then you refer to "channels 13 - 16", having decided that the data you've shown is the "A1" format which has only 12 channels! :confused:

You say that you only need 10-bit resolution to generate the additional pulses, but is that for the full pulse width range (0 - 1800 us) or only for 800 - 2200 us which (IMHO rather strangely) is defined in the SRXL specification ? In principle the calculation is quite easy, you just need to "scale down" the 12 bit value (stored within the two 8-bit bytes which make up the word) to the range that you need. But I'm not clear if that range is 1400, 1800 or 2200 us, or something else? Nor if you need to add in a minimum value of 750 or 800 us? However the scaling itself is very easy by using the ** {word} operator, which directly multiplies by the fraction {word} / 65536 where the {word} value can be calculated on a pocket calculator (or a phone).

Cheers, Alan.
 
Last edited:

FunFlyer

New Member
Hope this qualifies as a block diagram

24615

The MULTIPLEX transmitter shall be used to control the HAPPY HUNTER and the DINGHI. The MULTIPLEX receiver and the T1-transmitter sit on the HAPPY HUNTER (so does the DINGHI, when it´s not in the water). The DELTANG receiver sits in the DINGHI.

The MULTIPLEX transmitter talks to the MULTIPLEX Receiver via the M-LINK protocoll.

The T1-transmitter talks to the DELTANG receiver via DSMX

The MULTIPLEX Receiver has 16 channels. 12 of those channels are used to control the HAPPY HUNTER. The remaining 4 channels taken from the SRXL protocoll, control the DINGHI. They have to be converted from the SRXL protocoll to the pulsetrain I´m trying to create. This pulsetrain is feed into the T1-transmitter, which in turn controls the DINGHI. That pulsetrain is not ment to control servos, therefore its timing specs are slightly different from the pulses that control servos.

Specs and a picture for the pulsetrain are in posts #29 and32# (I hope).

Unfortunately I don´t have a logic analyser, so I can´t provide You with any further traces of the SRXL protocoll data stream.

Do we need crc-calculation?, I thought You said, that we do not really need it?

The receiver I´m eventually going to use has 16 channels and the A2-protocoll. For the developement I´m using a 9 channel receiver, which only transmits the A1 protocoll. So right now I´m working with the first 4 channels of that receiver.

The pulsewidth of the pulsetrain to be generated can take valus from 600µs to 1800µs, which makes for a range of 1200µs. Whereas the values in the SRXL data stream can range from 800µs (0x000) to 2200µs (0xFFF). That way the resolution for the servos is 4096 steps, which I don´t really need for this project.

That part in Your last post about the calculation threw me off. After reading the manual about "**" I´m even more confused. So I got out my EXCEL spreadsheet and did some number crunching. Here´s what I came up with:

Column 2 shows the pulselengths MPX transmitter sends

Coulmn 3 shows their values in the SRXL stream

Column 4 shows which values I have to feed into the T1-transmitter

Clolumn 5 shows the values I have to use in the "pulseout" or "pauseus" commands to get those values. What strikes me is the value for "break between pulses" value of 180 in compaisn to the 960 for the min pulselength.

MPX [µs]SRXLT1 Input [µs]PICAXE Output
Min
1000​
584​
600​
960​
Center
1500​
2048​
1200​
1920​
Max
2000​
3512​
1800​
2880​
break between pulses
400​
180​

I used those values in the latest version of the sourcecode (which I translated completely to English)


; version histoty
; V0: 0riginal from Hippy taken from PICAXE forum
; V0.1: added additional segments
; V0.2: CRC commentd out
; V0.3: memory for rxCrc.lsb, rxCrc.msb and header corrected
; V0.4: scrapped unused code
; V0.5: Testroutine using "LED-blinkin" implemented, Terminal commented out
; V0.6: experiments with different timing values
; V0.7: translated everything to English, crc commented out



#Picaxe 20X2
;#Terminal 76800
#No_Data
#No_Table

Symbol reserveW0 = w0 ; b1:b0
Symbol servo1 = w1 ; b3:b2
Symbol servo2 = w2 ; b5:b4
Symbol servo3 = w3 ; b7:b6
Symbol servo4 = w4 ; b9:b8
Symbol servo5 = w5 ; b11:b10
Symbol servo6 = w6 ; b13:b12
Symbol servo7 = w7 ; b15:b14
Symbol servo8 = w8 ; b17:b16
Symbol servo9 = w9 ; b19:b18
Symbol servo10 = w10 ; b21:b20
Symbol servo11 = w11 ; b23:b22
Symbol servo12 = w12 ; b25:b24
Symbol servo13 = w13 ; b27:b26
Symbol servo14 = w14 ; b29:b28
Symbol servo15 = w15 ; b31:b30
Symbol servo16 = w16 ; b33:b32
;Symbol crc = w17 ; b35:b34
;Symbol rxCrc = w18 ; b37:b38
;Symbol rxCrc.lsb = b39
;Symbol rxCrc.msb = b40
Symbol header = b41

Symbol rest_of_frame = w21 `rest of frame without pulselengths and pauses
Symbol PPM = C.2 `port assignment for PPM signal (the pulsetrain)
Symbol breaktime = 180 `breaktime between pulses (0.4ms)
Symbol total_breaktime = 8 * breaktime `sum of breaktimes for 7 pulses
Symbol framelength = 20000 `framelength (25ms)
Symbol min_pulse = 960 ;0.6ms
Symbol center_pulse = 1920 ;1.2ms
Symbol max_pulse = 2880 ;1.8ms



#Macro GetByte(bVar)
Do : Loop While ptr = hSerPtr
bVar = @ptrInc
#EndMacro

#Macro GetWord(wVar)
Do : Loop While ptr = hSerPtr
wVar = @ptrInc
Do : Loop While ptr = hSerPtr
wVar = wVar << 8 | @ptrInc
#EndMacro


PowerOnReset:
SetFreq M64
HSerSetup B115200_64, %001
; low PPM
rest_of_frame = framelength - total_breaktime

MainLoop:
Do
Do
GetByte(header)
Loop Until header = $A1 Or header = $A2
GetWord(w1) ; Servo 1
GetWord(w2)
GetWord(w3)
GetWord(w4)
GetWord(w5)
GetWord(w6)
GetWord(w7)
GetWord(w8)
GetWord(w9)
GetWord(w10)
GetWord(w11)
GetWord(w12)
If header = $A1 Then
; GetByte(rxCrc.msb)
; GetByte(rxCrc.lsb)
; SerTxd( "12 = ", #w1, TAB, #w2, TAB, #w3, TAB, #w4, CR, LF )
; SerTxd( " ", #w5, TAB, #w6, TAB, #w7, TAB, #w8, CR, LF )
; SerTxd( " ", #w9, TAB, #w10, TAB, #w11, TAB, #w12, CR, LF )
Else
GetWord(w13)
GetWord(w14)
GetWord(w15)
GetWord(w16)
; GetByte(rxCrc.msb)
; GetByte(rxCrc.lsb)
; SerTxd( "16 = ", #w1, TAB, #w2, TAB, #w3, TAB, #w4, CR, LF )
; SerTxd( " ", #w5, TAB, #w6, TAB, #w7, TAB, #w8, CR, LF )
; SerTxd( " ", #w9, TAB, #w10, TAB, #w11, TAB, #w12, CR, LF )
; SerTxd( " ", #w13, TAB, #w14, TAB, #w15, TAB, #w16, CR, LF )
End If

Pulsout PPM, min_pulse
rest_of_frame = rest_of_frame - min_pulse
pauseus breaktime

Pulsout PPM, center_pulse
rest_of_frame = rest_of_frame - center_pulse
pauseus breaktime

Pulsout PPM, max_pulse
rest_of_frame = rest_of_frame - max_pulse
pauseus breaktime

Pulsout PPM, min_pulse
rest_of_frame = rest_of_frame - min_pulse
pauseus breaktime

Pulsout PPM, center_pulse
rest_of_frame = rest_of_frame - center_pulse
pauseus breaktime

Pulsout PPM, max_pulse
rest_of_frame = rest_of_frame - max_pulse
pauseus breaktime

Pulsout PPM, center_pulse
rest_of_frame = rest_of_frame - center_pulse
pauseus breaktime

Pulsout PPM, rest_of_frame
pauseus breaktime

Loop



and here´s a trace of that program running with the static values for the pulses

24613

So those values seem to work, but on another scale You can see, that there is no consistency in framelength

24614


hope this helps to further tackle the problem.

regards

Herbert
 
Last edited:

AllyCat

Senior Member
Hi,

Yes, that helps a lot and generally looks quite "possible". I can't deal with all the issues immediately so here are just a few "notes" for now:

The "important" part is obviously the PICaxe 20X2 and the T1 transmitter. If I understand correctly, the input to the 20X2 will be a (concatonated) burst of 35 bytes at 115.2 kbaud every 25 ms (which should take about 3.1 ms) ? Then the X2 output to T1 is 4 (or maybe 7) pulses which may take up to about 8.8 ms (or 12 ms for 7 pulses), on the (one pin/wire) green "DSMX" path. That leaves around 10 ms for the 20X2 to "process" all the data, which looks possible, but means that you must NOT attempt to send any "test/diagnostics" serial data to the Terminal.

Personally, I believe the key to making this work well is for the whole program loop to execute within a single frame of 25 ms. I think failure to do this is the cause of many of the problems you've seen in this project. One of the "tricks" to try, is to (temporarily) reserve a PICaxe pin for "Marker" pulses. By using Low, High, Toggle and/or PULSOUT commands (perhaps with different pulse lengths for identification) the program can mark the stage that it has reached. You could put the marker pulses on "channel 2" of the 'scope, but for now it would be useful to use that channel to show the time when the burst of data is input to the PICaxe. The target is to ensure that they're ALL included within each/every Frame cycle ! Of course to do this you may have to ensure that the program isn't wasting time doing any "unnecessary" operations. ;)

Furthermore, you then don't need to concern yourself with the "framelength" variable in your program; just complete all the "tasks" for each frame and then wait for another burst (of 115.2 kbaud data) from the Receiver to "trigger" a new loop. In practice it might not be possible to fit everything into a single cycle, and/or "continuous" data from the receiver might be temporarily "lost", but those are problems that we can look at later if necessary.

I can't see why there appears to be a "random" delay between your frames, but I think it might be related to the use of the (Background HSERIN) "Circular buffer". As I mentioned recently in the other thread, try resetting the pointer(s) before the start of each 115 kbaud burst is "expected". There might be "complications" if the program starts to "look" during the burst, but we can probably ignore that for now. So try changing the "waiting" loop near the start of your main program to:
Code:
Do
   hSerPtr = 0
   ptr = 0
   GetByte(header)
Loop Until header = $A1 Or header = $A2
That's certainly not "ideal", but it might prove if we're on the right track.

Finally, no we don't need the CRC, which is just as well, because I think my analysis in the other thread "proved" that the PICaxe cannot do it sufficiently quickly. So you don't need a Logic Analyser, but you might be interested that the Logic Analyser that I've shown in some of my recent posts such as Post #4 HERE or posts #9, #10 and #13 HERE costs only about 10 Euros, not necessarily even from China, but directly from Amazon !

ADDED:
Code:
    Pulsout PPM, center_pulse
    rest_of_frame = rest_of_frame - center_pulse
    pauseus breaktime
    Pulsout PPM, rest_of_frame
For the instruction timings, you must take into account that ALL instructions have a significant execution time and that "measurement instructions" such as PULSIN/OUT need to "Bit Bang" (i.e. count) the measured time, apart from a few exceptions such as PWMOUT, SERVO (which can't be used at 64 MHz) and instructions which start with an "H" (for Hardware). In particular, PAUSEUS and PULSOUT have a very similar "Overhead" of about 700 "Base PIC Instruction Cycles":

The "Base PIC Instruction time" corresponds to the master clock frequency divided by 4, so it's 1us for an M2 with a 4MHz clock and 0.0625 us for an X2 at 64 MHz. Then, the "Unit measurement time" for PULSOUT and PAUSEUS is 10 "PIC Instruction Cycles" and their Overhead is about 700 * 0.0625 = 43.75 us. Also a simple addition or subtraction (e.g. W0 = W0 - W1) takes about 600 ICs or perhaps 37.5 us. However, I don't know the exact execution times (because I never use X2s) and don't know how much of the Overhead occurs before or after each pulse (but it doesn't matter because one of each will occur during your "breaktime").

Therefore, we can calculate that the minimum "break-time" (with a zero parameter) must be about : (700 + 700 + 600) = 2000 * 0.0625 = 125 us. To stretch this to 400 us, I would expect to need a value of (400 - 125) = 275 / 0.625 = 440, so I cannot explain why you appear to need a value of 180. But perhaps the X2s are much slower than the M2s (at any specific clock rate); they are definitely somewhat slower because there are more instructions to choose from and they are more complex (for example a larger address range must be included). However, the actual "PULSE" times do accurately represent the parameter's value, because that is the purpose of the instruction. :)

Cheers, Alan.
 
Last edited:

FunFlyer

New Member
Hi Alan,

before I get into the software, is this the logic analyzer You´re talking about?

24616

there´s different types on Amazon. They look all very similar, but reading the descriptions there are slight differences. At that price I´m very willing to invest in such a piece of hardware, if possible the right one.

regards

Herbert
 

AllyCat

Senior Member
Hi,

Firstly, as you have quite a good 'scope, a logic Analyser is not essential for this project, but it can be a useful tool.

Yes, I believe all the versions on Amazon and ebay, etc. are basically the same. "Saleae" is actually an American company that developed some excellent PC software a few years ago, that allowed them to sell a relatively low-cost Logic Analyser (but around 200 Euros, not 10), because it basically used only one silicon chip. However, "The Chinese" recognised a good product, produced a very cheap copy using the same chip and made it known that it would work with the Saleae software (which was being constantly updated so available for "free" download). Saleae tried to "protect" their software but there was no mechanism in the hardware, so they could only use a few "tricks" to make the "copy" hardware work less reliably.

In those days, I occasionally used one of the "Chinese Copies", but didn't advertise or encourage the "theft" of the Saleae software. However, now there is an Open Source Project called "PulseView" or "Sigrok" which works with the same hardware and is thus completely "Legal". Saleae have now gone "Up Market" with their hardware, which is much more expensive, so in that respect the item you've shown is a "fake" (because it has the name Saleae written on it). But as far as I know they all work quite well with the Open Source software, at least up to a few MHz, which is sufficient for many purposes. The software installation/FAQs suggest that the "24MHz" (samples/sec) is optimistic, because of the USB hardware capabilities and the "very poor quality" of the supplied USB cable.

So, I suggest you download the software first (which has a default Demonstration Mode) and look for whichever seller's hardware has the best price/availability for your requirements. However, there are two slightly different versions, the original (which I have) has 8 data wires and two "ETH" connections, but most of the latest versions have one of the ETHs now labelled as "CLK". I don't know whether that actually adds a ninth "signal" connection, but I've recently ordered one to find out. ;)

Cheers, Alan.
 

AllyCat

Senior Member
Hi,

Just a quick thought, I've read the "M-Link" data sheet and Googled "DSMX" (which didn't seem to add much) and am surprised that although the "normal" Servo specification has a 20 ms pulse-period, those data sheets mention 11, 14, 21, 22 ms and you a 25 ms "frame". I know that the period of Servo Motor pulses is not particularly critical, so I hope that you don't need to have different periods for your "input" and "output" signals?

Using different input and output periods is not completely impossible, but would be much more difficult (because of potential conflicts with the interrupts). For example, it might need two PICaxes which "co-operate" to pass data between themselves at a mutually convenient time. Also, of course a longer period between pulses gives the PICaxe(s) more time to complete the data-processing.

Cheers, Alan.
 

FunFlyer

New Member
Hi Alan,

I don´t think the period is that critical. E.g. the pulse from my old MPX radio has 25ms (see post 29, 1. trace). That´s what I´ve considered a "reference", because I know that that signal works. The SRXL spec states 21ms, which also seems to work, since I don´t think that that signalperiod gets changed before it gets to the servo.

regards

Herbert
 
Top