Identifying bytes sent by IR?

WhiteSpace

Well-known member
Some of you may have seen my two recent posts, https://picaxeforum.co.uk/threads/dual-ssd1306-displays.32305/ on the subject of setting up two separate OLED displays off the same Picaxe, and https://picaxeforum.co.uk/threads/scanning-tof10120-with-output-to-oled.32283/ on using a stepper motor to rotate a laser time-of-flight sensor and sending the output to an OLED to create a radar-like range display, using range and angle to run sine and cosine calculations to give x,y that then plots to the OLED. Both parts are now working nicely. The next step in this over the top project is to send the TOF10120 data from the scanner (mounted on a vehicle) to the control unit, which will have two OLEDs, one for the LIDAR image and one for the IR motor control back the other way, so that the controller can see obstacles and navigate round them. Predictably, it's starting to get tricky! The TOF scanner outputs two bytes of range data up to 255, and there will also be the angle byte from the stepper to allow the sine/cosine calculation. If I understand correctly, IROUT can only send up to 127, so I can't send the TOF data in its original format. So the best solution seems to be to do some pre-processing on the vehicle and send the x (0 to 127) and y (0 to 63). There are two obstacles. Firstly , is there any way of identifying which byte is which? If I send irout PIN, device, variable, is there any way in which the receiver can identify that the byte that it receives is the x or the y? With serial it would be possible to use a qualifier to identify x and y (in fact presumably I could use "x" and "y" as qualifiers to make it very clear). But if I send via IR, I can send only one byte at a time and there's no guarantee that two consecutive bytes that are received are related, because one byte might not have been received. Any solutions from others who have tried something similar? And secondly, transmitting the data via IR really slows down the stepper, to the extent that the scanner will scan too slowly to produce usable data. Again, any solutions, please? Are there any better methods for transmitting data from A to B quickly? Should I look at RF? Am I just being too ambitious? Any suggestions would be gratefully received! Thanks
 
Last edited:

AllyCat

Senior Member
Hi,

There are so many possibilities that it's difficult to know where to start. Possibly RFOUT and RFIN with a Radio Link, but I believe somebody on the forum (Eric?) said also it could be used with IR. RFOUT transmits a block of 8 bytes (fully data-checked), which would easily meet your requirements. But for good IR range and reliability, I'd expect to need a (40kHz) pulse carrier. However, that could be implemented with a "wired OR" gate (or a couple of diodes) in association with one of the PWM outputs. Or for many "communication" applications the on-chip Data Signal Modulator (DSM) can be very useful; it can be used only with SFR commands, but I've posted an annotated diagram and sample program in THIS CODE SNIPPET.

The Sony IR protocol (used by IROUT and IRIN) actually supports 128 (commands) for each of a large number of different "devices" (or channels), but unfortunately IROUT/IN only supports one (i.e. "TV"). Similarly, the NEC protocol supports 32 bits (4 bytes) in each transmission; again there are Code "Snippets" on the forum from PhilHornby and InglewoodPete (and me), for example HERE. Alternatively, you could divide the 128 IROUT commands into 8 groups of 16 "symbols"; each symbol could transmit one "nibble" (half a byte), so two symbols would send one "labelled" byte, e.g. codes (or symbols) 0 - 15 could send the Low nibble of "Byte1", 16 - 31 the High nibble and then 32 - 47 the Low nibble of "Byte2", etc..

But the problem with all the above methods is that they involve "Bit Banging" by either the program-writer or the PICaxe Interpreter, which are "slow" and may conflict with other processor tasks such as stepper or servo-driving. The PICaxe IR and RF commands specifically drop the clock frequency to 4 MHz. Which leads to the added complications of considering a multi-processor solution (that might include the NKM2401 Encoder/Decoder chip).

Personally, I'd probably use HSEROUT (preferably coded to transmit only one byte at a time) at about 1200 baud. Perhaps modulated at ~40 kHz from a PWM Output (or internal CCP Latch) via the DSM (or an external "gate", or internal Comparator), with some sort of simple "DIY" byte structure/protocol. Or a simple "brute force" method might set up a background PWM IR transmission system (itself possibly modulated), where the "data" is carried in both the frequency and the duty cycle of the "square wave" (perhaps 16 frequencies and 64 duty cycles?).

Cheers, Alan.
 

WhiteSpace

Well-known member
Alan, that’s really useful, thanks. I’ll need to go away and do a lot of reading and experimenting! I wondered if it was possible to transmit serial via an IR LED. Presumably that’s more or less what you are suggesting with the HSEROUT in your final para. I have used plain SEROUT before but not HSEROUT so I’ll go and have a look at that.
 

AllyCat

Senior Member
Hi,

First a minor correction: it appears that IROUT actually transmits all 12 bits of the Sony protocol, i.e. 5 bits of the "device" code and 7 bits of data, but IRIN returns only 7 bits of data in a byte. But it might be worth testing with a word value in case "the manual" is wrong. However, it could be quite easy to receive all 12 bits, the coding appears very simple, approximately 0.5 ms "gaps" in the carrier pulses, between "0" bits 0.5 ms long and "1" bits 1 ms long ; the 7 Data bits with LSB first, then the 5 bits of the "device" code. So it would be quite easy to receive the 12 bits and decode as either a single (1.5 bytes) value, or as 16 "individually labelled" bytes.

As I happen to have my cheapo Chinese "24 MHz, 8bit Logic Analyser" (Saleae clone with Open-Source PulseView/Sigrok app.) connected to a 20M2 on a solderless breadboard, I thought it would be interesting to compare the various data transfer formats: I2C read (6 bytes), HSEROUT, SEROUT (2 bytes each at 4800 baud), RFOUT (8 bytes encoded), IROUT (12 bits Sony Protocol) and "DEBUG"/SERTXD (lots of data perhaps around 4800 baud). Below is my test code and a screenshot.
Code:
; Comparison of Transmission Protols.  AllyCat March 2021
#picaxe 20m2
#no_data 
symbol SDA = b.5
symbol SCL = b.4                ; Linked to Hardware pin b.7
symbol I2CGND = b.3
symbol I2CVdd = b.2
    b1 = "A"
    b2 = "1"
    low c.0                                        ; Prepare HSEROUT
    low b.3                                        ; Ground for I2C
    high b.2                                        ; Supply for I2C
    pullup $30                                    ; For I2C
    hsersetup B4800_4,2                        ; On pin b.6
    hi2csetup i2cmaster,$88,i2cslow,i2cbyte        ; SHT30
    pause 100
do
    hi2cout ($24,$00)                            ; Initiaise SHT30
    sertxd($55)                                    ; Marker
    hserout 0,(b1,b2)                            ; 2 bytes (no break)
    serout c.1,n4800_4,(b1,b2)                ; 2 bytes
    rfout b.6,(b1,b2,b3,b4,b5,b6,b7,b8)    ; 8 bytes Manchester coded
    irout c.5,5,30                                ; 5 bits device, 7 bits data
    debug
    hi2cin (b3,b4,b5,b6,b7,b8)                ; Read SHT30
loop
The I2C is too fast to resolve (at the same screen resolution as the other data); the 6 bytes take about 1.5ms in total (marked with the grey "cursor") but more than half of the time (even with I2CSLOW) is "dead space" between each data byte being received and the PICaxe sending an "Acknowledge" reply bit and clocking more data). The two HSEROUT bytes are fully concatonated (Stop and Start bits touching), so they take the expected time (4.25 ms). But the program doesn't start to execute the next instruction (the SEROUT) until the "final" (i.e second) byte has been loaded into the hardware. Therefore, the SEROUT starts about half-way through the second HSEROUT byte and there is a small gap between its Stop and (second) Start bits.

Then the RFOUT is relatively slow at about 35 ms because of the complexity of achieving reliable operation over a radio link. The IROUT is rather shorter than (I) expected (at about 15 - 20 ms), much less than the NEC protocol (~60 ms) but then it's transmitting only 12 bits compared with NEC's 32. Finally the DEBUG takes about 130 ms, not all shown, but it runs from about 70 ms to the end of each loop of 200 ms. The "decoders" for I2C and UART are shown at the bottom of the screenshot, but there don't appear to be decoders for the Sony IR protocol or (less surprisingly) for the RFOUT or DEBUG packets.

TX-Protocols.png
TX-Protocols.png

So it looks as if either IROUT (with custom receiver code) or {H}SEROUT (with some hardware/SFR configuration) offer possible solutions for you.

Cheers, Alan.
 
Last edited:

WhiteSpace

Well-known member
@AllyCat that's amazing - thank you for taking so much trouble. I think I'll start with HSEROUT - that seems to provide the quickest method of sending a series of bytes so that there is some prospect of being able to identify them. If I understand correctly, I can send the HSEROUT either via RF or an IR LED. I have a spare 38kHz receiver. To transmit, I'll need to modulate the signal. I can't use PWM from the Picaxe because that will be in use for motor control (unless I use a second Picaxe). Can I create an AND gate with 2 transistors, the base of one connected to a 555 timer chip to generate a 38kHz carrier and the base of the other to HSEROUT to send the data to the IR LED? Thanks again!
 
Last edited:

WhiteSpace

Well-known member
...which makes no sense, of course. Rather than drive myself demented trying to work out what combination of resistors and caps will give 38 kHz on a 555 timer, I’ll be sensible and use an 08m2 where the Wizard will do the maths and I’ll need a lot fewer external components.
 

Goeytex

Senior Member
You could also use a separate Picaxe chip to drive the stepper motor so that it is not affected by other operations.

More expensive but I would consider RF over IR. Not cheap ASK modules but, smart transceivers That use FSK or GFSK and that are UART enabled. These have built in protocol and error-checking and will provide a much more robust link than IR.
 
Last edited:

WhiteSpace

Well-known member
Thanks @Goeytex I’ll give that some thought. My immediate reaction is that the stepper needs to be tied in with the other operations because the step position (how many steps along its scan from L to R) is essential to the plot, because it provide the angle that, in conjunction with range, allows calculation of x and y. So the stepper can’t go any faster than the angle and range at each step (or 7-step) can be exported and processed. Unfortunately my most reliable stepper is the slowest (0.18 degrees/step) - I have a couple with 0.9 and 1.25 degree step angles but they are more temperamental and keep sticking even when run in isolation without collecting the data. Still working on it, but will certainly consider your suggestion.
 

AllyCat

Senior Member
Hi,
.. I can't use PWM from the Picaxe because that will be in use for motor control (unless I use a second Picaxe).
Which PICaxe are you using? I thought that most (except the 8 pin devices) had more than one PWM channel (usually 4 but with some potential interactions in frequency). Personally, I always try to avoid adding any "unnecessary" external components. Also, the IR modulation frequency may need to be quite accurate (so the PIC's PWM hardware is desirable), whist a PWM motor speed control can be potentially "cobbled up" from an (internal) Comparator and Ramp Generator (perhaps even the "Touch" pins driver). However, you seem to have adopted a more "sensible" approach now, anyway. ;)

As it's quite a useful comparison, I'm attaching a "zoomed" version of my Communication Interfaces screenshot above (which can be further zoomed in a suitable app.). However, a single screenshot still can't show all the fine detail of the I2C, IR Modulation Pulses or the Debug data (which appears to be largely "Nul"/undefined).

TX-ProtocolsZ.png

But back to the Original Topic of this thread; I've never actually used the IR facilities and was quite surprised that IROUT transmits 12 bits, but IRIN detects only 7. Also, the protocol is remarkably simple and short (compared with the NEC or RC5/RC6, etc. systems), so could be easily decoded by a PICaxe at 32 MHz. However, I always try to design my "fast" programs to run at only 16 MHz, because that is the highest clock frequency which is normally compatible with Servos and the (M2) "time" variable, etc.. I "nearly" managed this for a NEC decoder, but the 32 bits sequence was making the code quite complex, so I put it "on the back burner".

However, the same ideas have worked very well with the Sony IR Protocol, so I've devised a "simple" program to fully decode it into either a 12-bit data field, or the "official" 5 + 7 bits, or for 16 individual "labelled" bytes, etc.. That should appear in the Code Snippets section of the forum soon, but I could post a "preview" if it would be useful. Putting the "$10 Logic Analyser" into use again, here's a taster:

SIRC decode16MHz.png

The IROUT data (from another PICaxe) is somewhat "faster" (at 1.1 ms "0" period and 42 kHz modulation) than the nominal specification (1.2 ms, 40 kHz) but the demodulator may stretch the data pulses a little (I've used only a simple R-C low-pass filter). The code is fast enough to accept Marker pulses, which indicate just before the sampling of each pulse and a second, wider pulse just after each "1" data bit is detected. The test program SERTXDs the data values (in decimal) followed by the individual (ASCII) bit values in the sequence received (i.e. LSB first and CR, LF terminator) and then Echoes the data (not shown) via an IROUT.

Cheers, Alan.
 

WhiteSpace

Well-known member
Thanks again @AllyCat - that's very useful. I'm using a 28x2. I had understood that I was stuck with the same period for all PWM pins, hence the idea of using a separate 08m2 to create the 38 kHz carrier wave (although on reading the manual more closely, it looks as though only some of the pins are tied to the same period, so I might try getting rid of the second Picaxe on the transmitter side when I have everything working). I tried to communicate between the transmitter and receiver with hserin/hserin, but in spite of spending a couple of hours reading and re-reading the manual and various threads here last night, I'm still baffled. Background receive to scratchpad seems like the way to go, because the Picaxe can be getting on with other stuff (like running the display) while the data is being received. For the moment I have the two Picaxes connected by a single wire from the hserout pin to the hserin pin, just while I test. I've set up the following lines on the transmitter:

Rich (BB code):
hsersetup B4800_16, %10
      
      let b7 = 123
      
      hserout 0, (b7)
My understanding is that the high bit 1 inverts the signal so that it pulses high. That is what I will need when I eventually plug it into the IR LED.

At the receiver end, I have
Rich (BB code):
hsersetup B4800_16, %101
High bit 0 sets for background receive to scratchpad. High bit 2 inverts the signal, corresponding to the inverted signal at the transmitter end. As an aside, the TSOP 4838 IR receiver is active low, so I think that means I'll need to un-invert the hserin at the pin when I get to that stage.

But then I don't understand how to get at whatever is being received into scratchpad. The manual says this:

"In automatic background mode the hardware serial input is fully automated. Serial data received by the hardware pin is saved into the scratchpad memory area as soon as it is received. Upon the hsersetup command the serial pointer (hserptr) is reset to 0. When a byte is received it is saved to this scratchpad address, the hserptr variable is incremented and the hserinflag flag is set (must be cleared by user software). Therefore the value ‘hserptr -1’ indicates the last byte written, and ‘hserinflag = 1’ indicates a byte has been received (see also the setintflags command). The scratchpad is a circular buffer that overflows without warning."

I tried this, with no success:

Rich (BB code):
let b10 = hserptr
    
    pause 1000
    
    SerTXD ("b10 = ", #b10, CR, LF)
Would someone be able to point me in the right direction, please? I have used ordinary scratchpad to save and then access the character codes for an OLED display, but I don't understand how the hardware serial scratchpad relates to the general one, and how to get at what is placed there. I see that the scratchpad overflows, but I'm not sure how many bytes it holds.

Thanks very much.
 

AllyCat

Senior Member
Hi,

The hserptr is a "pointer" to the address of the byte(s) in RAM. For the "normal" RAM you use PEEK and POKE commands (e.g. PEEK pointer,b10) or access the byte directly with, e.g. @bptr (e.g. you can write SERTXD(#@bptr). For the Scratchpad memory the equivalent commands are GET and PUT and probably @hserptr or @ptr. Note that you can only use the @ prefix with the special pointers, not with any other variables

For the 28X2 the scratchpad is 1024 bytes and it doesn't exactly "overflow", it wraps back to its beginning. So it can continue receiving data, but your program must recover the original bytes before they get overwritten.

Cheers, Alan.
 

julianE

Senior Member
Alan, thanks for sharing your adventures with the chinese logic analyzer. Mine came in yesterday and after some issues with missing files and driver installation I have it working. I am shocked how well it works for being so inexpensive. I'll give your sample program a try, i can see a lot of use for the analyzer. Thus far all i've done is monitor the UART and it works well.
All the best.
 

Goeytex

Senior Member
@WhitesSpace

Your code example will print the memory address (0?) and not the byte value that resides at at that address. Try this instead.
Code:
Let b10 = @Hserptr
Pause 1000
SerTxd ("b10 = ",#b10,  CR, LF)
 

WhiteSpace

Well-known member
@Goeytex

Thanks very much. I have just tried that. It doesn't allow me to use @hserptr - I get this:
"let b10 = @hserptr
^
Syntax error on line 229 at/before position 11
Error: Unknown symbol - @hserptr"

I tried this (more out of desperation than out of any real understanding of what I'm doing):

Rich (BB code):
hsersetup B4800_16, %101
      
      pause 1000
      
      ptr = 0
      hserptr = 0
      
      main:
      
      let b10 = hserptr
      let b11 = @bptr
      
      
      SerTXD ("received #b10 = ", #b10, " ; @bptr = ", #@bptr, " ; bll = ", #b11, CR, LF)
      
            
      pause 1000
      
      
      goto main
On the hserout side, I have this:

Rich (BB code):
hsersetup B4800_16, %10
      
      Main:
      
      ;SerTXD ("Start Main", CR, LF)
      
            
      
      
      For b39 = 1 to 50
            ;let b40 = 123
            hserout 0, (b39)
      
      ;SerTXD ("b39 = ", #b39, CR, LF)
      
      pause 10
      
      next b39
I just get 0 for everything. I must confess that I don't really understand how the background hardware serial works - I understand that any bytes received go into scratchpad, but I don't really understand what hserptr does, or how it differs from ptr or bptr. I've spent a couple evenings looking through various threads, but without enlightenment. Some threads refer to a loop to compare ptr and hserptr, but again I don't understand why. Any light shed on all of this would be very welcome!
 

Buzby

Senior Member
Code:
ptr = hserptr        ' Initialise pointer to start at current position of hserptr

do
    if ptr <> hserptr        ' If chr received, hserprt will be greater than ptr
         b0 = @ptrinc        ' get character, and move ptr
         sertxd (#b0)        ' show rxed chr
    endif
loop
 

WhiteSpace

Well-known member
Many thanks to @AllyCat @Goeytex and @Buzby - I'm making some progress with this now. For a long time hserin was receiving nothing. I think it may have been something to do with a adcsetup instruction left at the start of the program, that (if I understand correctly) set the relevant pins to analogue rather than digital. There may also be a wrong connection that I need to find - in the end I started with two 28x2s on a separate breadboard and started from scratch with just hserin, at which point I started to see results.

Anyway I have got here:

Rich (BB code):
hsersetup B9600_64, %101
      
      pause 1000
      
      hserptr = 0
      
      ptr = hserptr ; ' Initialise pointer to start at current position of hserptr
      
      do
            
            ;SerTXD ("Start loop", CR, LF)
            SerTXD ("#ptr = ", #ptr, " ; #hserptr = ", #hserptr, CR, LF)
            if ptr <> hserptr then
                  ;let b10 = @ptrinc
            
                  SerTXD ("received #@ptrinc, #@ptrinc: ", #@ptrinc, ", ", #@ptrinc, CR, LF)
                              
            endif
            
      pause 2000
      
      loop
The transmitter is sending 2 bytes - one incs from 1 to 100 and the other decs from 100 to 1. The SerTXD on the receiving side looks like this:

#ptr = 0 ; #hserptr = 0
#ptr = 0 ; #hserptr = 2
received #@ptrinc, #@ptrinc: 4, 96
#ptr = 2 ; #hserptr = 4
received #@ptrinc, #@ptrinc: 5, 95
#ptr = 4 ; #hserptr = 6
received #@ptrinc, #@ptrinc: 6, 94
#ptr = 6 ; #hserptr = 8
received #@ptrinc, #@ptrinc: 7, 93
#ptr = 8 ; #hserptr = 10
received #@ptrinc, #@ptrinc: 8, 92
#ptr = 10 ; #hserptr = 12
received #@ptrinc, #@ptrinc: 9, 91
#ptr = 12 ; #hserptr = 14
received #@ptrinc, #@ptrinc: 10, 90

If I understand correctly, the #hserptr is the scratchpad address at which the incoming byte is posted. It incs on each post. I read the scratchpad entry with @ptr/@ptrinc in the usual way for scratchpad, and inc it to move it onward to the next address. A difference between #ptr and #hserptr means that there are unread new bytes received. So in the second SerTXD line, #ptr = 0; #serptr = 2 show the value of those addresses, showing that the serial pointer has inc'd by 2, because 2 bytes have arrived. If I have a shorter delay in the receiver circuit, the ptr catches up with the hserptr, so the values are not read until there is again a difference, like this:

#ptr = 0 ; #hserptr = 0
#ptr = 0 ; #hserptr = 0
#ptr = 0 ; #hserptr = 2
received #@ptrinc, #@ptrinc: 72, 28
#ptr = 2 ; #hserptr = 2
#ptr = 2 ; #hserptr = 2
#ptr = 2 ; #hserptr = 2
#ptr = 2 ; #hserptr = 4
received #@ptrinc, #@ptrinc: 73, 27.

If I have a much longer delay in the receiver circuit, the hserptr moves on faster than the ptr, so there are received but unread bytes. There's a brief confusion when the hserptr laps the ptr and overwrites the values (in this case the hserptr has just started on its third cycle from 0 to 1023 and the ptr has just started on its second):

received #@ptrinc, #@ptrinc: 41, 59
#ptr = 44 ; #hserptr = 42
received #@ptrinc, #@ptrinc: 42, 58
#ptr = 46 ; #hserptr = 46
#ptr = 46 ; #hserptr = 50
received #@ptrinc, #@ptrinc: 55, 45
#ptr = 48 ; #hserptr = 54
received #@ptrinc, #@ptrinc: 56, 44
#ptr = 50 ; #hserptr = 58
received #@ptrinc, #@ptrinc: 57, 43

That seems likely to be a problem only if the missing values are important in some way. The answer is to ensure that the receiver runs faster than the transmitter, I think.

I hope this is useful to anyone else trying to find their way round hardware serial.

Next steps - see how fast this will go, and see whether it will work via infrared, before building it back into the project (and finding why it didn't work in the project before).
 

Buzby

Senior Member
You are definatley getting the hang of background receive now.

Regarding the overrun when the ptr advances slower than the hserptr, there is no solution to this other than making sure it never happens !.

In real life it is very rare for it to overrun. The main use is to capture bursts of fast data, then process them at a more leisurly rate. These bursts could be from a device which, for example, sends a block of 250 bytes at 115,000 baud every 5 seconds. There is no way a PICAXE could process those 250 bytes in 'real time', so they collect in the scratchpad. Now the PICAXE has no problem handling them at the rate it can handle, easily processing them in the 5 sec before the next burst arrives.

So, as long as the 'average processing time' is less than the 'average data rate' then the pointers will never overlap.

The downside to the background receive method shown in the code above is that it uses the whole scratchpad. This can be a problem if you want to use the scratchpad for anything else.

If you need to reserve some scratchpad bytes for your code, but still have buffered background RX, then you need to manipulate 'ptr' and 'hserptr' on-the-fly to allow this. This can be tricky if the source can send bytes at anytime, but is easy if you know the timing of the incoming data.

Cheers,

Buzby
 

erco

Senior Member
As Allycat mentioned above, I sent IR commands over a 433 Mhz radio link, deets at https://picaxeforum.co.uk/threads/sending-ir-commands-over-radio-comms.31566/

I'm always looking for quick & dirty workarounds. The jist of my findings is that RFIN is a blocking command but IRIN is not. Specifically, I needed servo commands to continue even while the robot is waiting for input. So I could use IRIN but not RFIN directly (but possibly with some of the AXE213 modules).

I used the cheapest 433mhz modules, but as I've posted elsewhere, the ones I get on Ebay for $1 are mostly junk. Over half of them are useless, so I have to individually test every regen receiver and every transmitter. I finally wised up and switched to superhet receivers, which work great. Still quite cheap at $2 for the pair.
 
Last edited:

WhiteSpace

Well-known member
Thanks again @Buzby and @erco - slowly getting there I think! The objective still being to get my LIDAR data from A to B. Meanwhile I see that @AllyCat has posted his 12-bit decoder for IROUT, which I will try to get my head round, although in the first instance having got this far with hserin I'll try the hserin via IR, I think.

Meanwhile, staying on the subject of hardware serial @westaust55 and/or other mods, would it be useful for me to post the conclusions etc on hserin/hserout and hsersetup in a separate thread with a more descriptive heading? It took me hours and a lot of help on the way from senior members to get here. I couldn't see any code examples for background serial receive in the manual, so I'm happy to pay it back and give others a pointer (no pun intended) if you think it would be useful. But I don't want to clutter the forum with partial duplicates if not.
 

WhiteSpace

Well-known member
Good progress with this! I've managed to get hardware serial transmitting via IR (thanks again to @AllyCat for pointing me in this direction). It's now sending the TOF10120 data from one board to another. On the hardware side, I've made things a lot simpler than posted above. The 28x2 creates a 38 kHz carrier signal off one pin. A two-transistor AND gate combines that with the hserout from Pin C.6. No need to mess about with a 555 timer or even a separate 08m2 to generate the carrier. I've put a red LED in parallel with the IR LED so that I can see when it's on.

On the receiver side, I had some trouble receiving no data to start with, until I remembered that the TSOP 4838 IR receiver is active low, so I needed to set bit2 of the hsersetup mode on the receiver side to 0 when bit1 on the transmitter side was set to 1

To answer my own question from the thread title, I am sending 3 bytes of data, a "qualifier" byte value 255 (binary 11111111 to make a nice clear break from no byte) and then the x and y values. It's worth experimenting a bit with different time delays, sending all bytes together or in separate commands etc.

This code on the receiver side identifies the qualifier and then receives the two bytes that I'm looking for.

Rich (BB code):
do
            
      hserptr = 0 ; set hardware serial pointer to 0
      
      ptr = hserptr ; Initialise pointer to start at current position of hserptr
      
      do while hserptr <= 127
            
                  
            if ptr <> hserptr then
                  do until @ptrinc = 255; ensures that the first of the
                        ;three bytes received is the qualifier" 255
                        ;@ptrinc then incs the scratchpad pointer on so that the next byte is
                        ;received as xCoord
                        let CheckByte = @ptr
                  loop
                  
                  let xCoord = @ptrinc ; then incs on to yCoord
                  let yCoord = @ptr ; no inc after this one, so that when it goes back
                  ;to the start of this loop, it can check for the CheckByte again
                  SerTXD (#CheckByte, ", ", #xCoord, ", ", #yCoord, CR, LF)
                  gosub OLEDdisplay
            
            endif
      
      loop
      
      loop
On the transmitter side, it's quicker than IROUT, allowing a full scan in about 4.5 seconds, perhaps because I can run the Picaxe at 64 MHz rather than the slower speed to which IROUT limits the Picaxe? On the receiver side, it outputs quickly to the OLED - a lot faster than with IRIN that I initially tried. It can also handle a full byte up to value 255 rather than the half byte that you get with IRIN. Because it receives in the background, the program can be getting on with other stuff while receiving - in this case filling the display. The CheckByte works well - when I initially tested the hserout/hserin via IR I was getting the byte crossed over quite frequently. Here's a test pattern without:

IMG_16161616465948.jpg

and with the CheckByte:

24566

Next steps: to see if I can speed up the stepper to move the scanner faster, and also to experiment with transmission over a longer distance. Also to try two-way transmissions.
 
Top