I need some help understanding Picaxe serial communication

smolder

New Member
Hey there, I am working on some robots that will use an IR picaxe network. I plan on using 3x 08M2s, each having its own IR LED and receiver.
The robots will signal to each other that they want to send a byte message by sending a short high pulse, and then follow with the serial data.
What I need help with is figuring out how long (in seconds) a picaxe data frame is so that I can set the signal pulses length to be greater, and then check it with pulsein.

This is the serial frame as I understand it:
My chips will be talking with a N2400 baud rate, meaning that they will transmit 2400 bits per second. Thus each bit is 417 microseconds long (1/2400 = .000417 seconds.)
A single byte frame would be 10 bits long: 1 start bit, 8 data bits, and 1 stop bit.
Therefore, a one byte frame should be 4.17 milliseconds long.

So, I should set pulsein to check the IR receiver for a high pulse that is longer than 5 milliseconds. The receiver IC will then know that it is about to receive a message and will turn on its serin command.

Does this make sense? Are my numbers correct? I would certainly appreciate any and all help and suggestions.

I made this here picture to illustrate what I think the frame looks like. Is this right? Please correct me if I'm wrong (quite likely :p )

picaxe frame1-01.png
 

PaulRB

Senior Member
Hi smolder, yes, makes sense, although I've never used ir and serial like that, maybe a more experienced picaxer will comment.

To test your timing theory, write a short test program to send the "time" special function variable, using the sertxd command, to the pc, then loop 100 times, performing a serout of 20 characters each loop, then after the loop, send the time to the pc again. If your theory is right, the difference in the 2 times should be around 5ms x 20 x 100 = 10 seconds. Then try looping 1000 times for a more accurate measurement.

Paul

PS, I've had troubles before using pin c.3 for ir input on an 08m2 with the Rev Ed ir sensor. Apparently c.3 is more sensitive to noise. As soon as I moved the ir sensor to another pin, the problems vanished. But you don't have many other pins on an 08m2, and using c.3 seems a logical choice because its input only.
 
Last edited:

smolder

New Member
Sweet, that is a great ideal Paul! I ran some test using your concept, I modified it a little to use 10 frames as a base:

Code:
symbol counter = b1	; define the variable b1 as a counter
symbol countten = b2 	; define the variable b2 as a counter
main:
	if pinC.4 = 1 then transmit	; if button is pressed goto transmit
	pause 100				; debounce
	goto main				
			
transmit:
	sertxd(#time)			; send time in seconds
	for counter = 1 to 100 		; start a 100x for...next loop
		for countten = 1 to 100	; start another 100x for...next loop
		sertxd("UUUUUUUUUU")	; send the frame "1010101011" ten times
		next countten		
	next counter
	sertxd(#time)			; send time in seconds
	goto main
And these were the results:
10x "U" looped 1000 times at 4800 baud took 20 seconds. Frame = 2mS = (20 seconds / (10 frames * 1000 loops))
10x "U" looped 10,000 times at 4800 baud took 200 seconds. Frame = 2mS =(200 seconds / (10 frames *10000 loops))

Now since it is transmitting at 4800 it is transmitting twice as fast as the 2400 I plan on using. A 2mS frame then becomes 4mS, which is close perdy close to the original 4.3mS estimate.
But,... I ran another test, and instead of sending ten "U"s, I sent one and looped it 10 times:

Code:
symbol counter = b1	; define the variable b1 as a counter
symbol counter2 = b2 	; define the variable b2 as a counter
symbol counter3 = b3 	; define the variable b2 as a counter

main:
	if pinC.4 = 1 then transmit	; if button is pressed goto transmit
	pause 100				; debounce
	goto main				
			
transmit:
	sertxd(#time)			; send time in seconds
	for counter = 1 to 100 		; start a 100x for...next loop
		for counter2 = 1 to 100	; start another 100x for...next loop
			for counter3 = 1 to 10	; start a 10x for...next loop
			sertxd("U")	; send the frame "1010101011" once
			next counter3			
		next counter2		
	next counter
	sertxd(#time)			; send time in seconds
	goto main
The result:
"U" looped 100,000 times at 4800 baud took 440 seconds. Frame = 4.4mS = (440 seconds / (1 frames * 100,000 loops))

That means that a 2400 baud frame would be 8.8ms... the results are contrary to the previous test. :*(
It seems PieM is correct in there being a delay between frames, I also think that there has to be some delay for processing, but I don't know enough about it.
Or maybe when you send 10 "U"s at once it expands the frame and uses just one start and one stop bit for them all, instead of for each one. This would partially explain why it is slower to send them individually.

I plan on having access to an oscilloscope soon and some tests with it will solve this riddle, which is a good thing because I think my head is about to explode.

Thanks for the help fellas, I'll post some solid results when I have them
 
Last edited:

PaulRB

Senior Member
Yes Smolder, its processing overheads. That's why I suggested 20 characters and fewer repetitions, to minimise their effect on the timing calculation. Try that code again with the sertxd command replaced with a simple "let b0 = 1". That should give you an estimate for the overheads involved. And let us know what you find out with the 'scope.

Also, will you be using sertxd, hserout or serout in the robots? The frame should be the same length for the same baud rate, but the overheads my be different, if that matters.
 
Last edited:

hippy

Technical Support
Staff member
The robots will signal to each other that they want to send a byte message by sending a short high pulse, and then follow with the serial data.
Before getting into building things and its design it might be worth attempting to role play what you are imagining in your mind or even with real people, see what problems that throws up.

It seems a bit like having three people sat round a dinner table, each going "bing" and saying a letter, the others waiting to hear "bing" and writing that letter down. Things might go wrong quite quickly when two or more try to talk over each other and others get confused as to what's actually going on, miss hearing "bing" or the letter said, are writing things down when another "bing" or letter occurs.

Trying to marshal two or more people into coherent conversations without any marshalling can be quite difficult.
 

smolder

New Member
Ah, Overheads. I knew there had to be a term for it :p
Ok, so as per Paul's advice I replaced the sertxd with let b0=1 and it took 199 seconds to process all the looping.
Subtract that from the 440 seconds used to transmit single "U"s and with the other maths it results in a frame length of 2.41 milliseconds. Again, very close to the original estimate of 2.08mS.
I think this tells me enough to accomplish my goal: a frame at 2400 baud is less than 5ms.

I am working on some swarm type robots and I want them to be able to recognize and interact with each other.
Since the robots wont always be in range of each other they need to be ready to deal with catching only part of a transmission and not interrupting one another.
I am going to try having the bots listen for 5ms. If they hear(see) nothing then no one is talking and they can send their heads-up pulse (a 6ms out on the IR) followed by their serout data.
If they hear something, but it is not a solid 5ms pulse (the "heads-up I want to talk pulse) then they missed the full message and should start listening again.
If they hear something and it is the heads-up pulse they turn on serin and receive the message.

I am not too concerned about the speed; I kinda figure that all this processing will mean that they only get a message across every second or so, even if it is just one byte. I can always time lapse the video on youtube, right?
After I get it working, slowly, I can start optimizing. Thanks for the link, Pie, it is going to take me a week or so to process all that info, but it is exactly what I'll need to speed everything up.

I've been testing this idea in stages starting with having one 08M2 sending a serout over an infra-red LED and another receiving it with a sensor.
I've gotten that to work on breadboards and working out this, I guess it could be called a protocol, is the next step. I would love to eventually have at least a dozen of these robots chirping away at each other, but I definitely have a truckload of testing ahead of me before that happens. If your interested, the picture below is the current plan for pulling this off. I will likely break this down into several smaller milestones, and it in itself is a step into more complex behavior. Hopefully.
Pingbotv2 Networkv10-04.png

Thanks again for the help and for letting me think out loud a bit. I've been obsessed with this concept for the last month or so and my dreams exceed my knowledge. This tutorial has help understand master to slave communication, but this idea is some kind of weird master and slave mashup with mobile transceivers :O I am clearly in over my head, but I wouldn't find it fun otherwise.
 
Last edited:

smolder

New Member
:O That is exactly it Jim! I want to use a "Carrier Send Multiple Access 1-Persistent" protocol for these robots. I can't believe how spot on that description is, it even has a random time element which I was thinking might be too chaotic.
It's a relief to know I am not yet chasing a rabbit down a hole and won't need to reinvent the wheel here. I'm all pumped up, this is exciting!
 

smolder

New Member
I've taken some oscilloscope readings and have found that a 1 byte frame is roughly 4.2ms long. However, it doesn't look like I imagined it would and it suddenly occurred to me that I may not know how to read an oscilloscope properly :p
Here is the reading I got from sending a "U":
Picaxe Frame.jpg

That doesn't seem to have a start bit. I also think it may be inverted... I don't know. Can anyone explain to me why? (I don't need to know to accomplish my goal, but this is one of those things that will keep me up at night until I know whats going on.
Thanks again for the help.
 

JimPerry

Senior Member
:O That is exactly it Jim! I want to use a "Carrier Send Multiple Access 1-Persistent" protocol for these robots. I can't believe how spot on that description is, it even has a random time element which I was thinking might be too chaotic.
It's a relief to know I am not yet chasing a rabbit down a hole and won't need to reinvent the wheel here. I'm all pumped up, this is exciting!
It feels good to not reinvent the wheel!

What is your scope and what/where are you measuring? .. and what are you trying to find? :confused:
 

hippy

Technical Support
Staff member
View attachment 12242

That doesn't seem to have a start bit. I also think it may be inverted... I don't know. Can anyone explain to me why?
Looks okay to me. I first suspected it's AC coupled and you've got some noise on the probe but could it be the probes haven't been calibrated and you're also looking at a pin which is both input and output ?

I'd guess you are using an Nxxxx baud rate. The start bit is the first rising pulse after the wobbly run-in, followed by bits 0 to 7, then a stop bit and is the pin then made an input ?
 

smolder

New Member
Wow, you can tell all that just from that picture? You are correct that the pin is made an input after sending the serial data. What I don't get is why the scope reading looks like 0101010101 when it should be 1010101011.
The strange ripples are from the 38kHz carrier frequency used for the IR led. Here is the schematic (C1 is where I tested):
IR TX.jpg
and the code:
Code:
init:
	pwmout 2, 25, 53 		'turn pwm on for output 2 at 38kHz, set dutycycle to 50%
					'the IR LED needs to transmit at this frequency to match the 38kHz receiver
main:
	if pinC.4 = 1 then transmit	; if button is pressed goto transmit
	goto main
	
transmit:	
	output 1			'set C.1 as output for the pulsout command
	pause 600		        'sends the heads-up pulse
	input 1			'set C.1 as input, this turns the IR LED off
	pause 1
	serout 1,N2400,("U")	'transmit the bite "U" out on output 1.
	input 1			'set C.1 as input, this turns the IR LED off
	pause 500			'debounce
	goto main			'loop to main
See, when the serial data is sent it sets C.1 as an output pin. When the transmission stops this new output sinks the IR LED current thus leaving the IR LED on (I'm pretty sure that's why it stays lit.) I set C.1 back to an input and the LED turns off.
This is is probably a terrible way to achieve my goal, perhaps I should just set C.1 high when I want to turn the IR LED off.

Jim: I'm trying to find the length of a one byte serial frame so that I can send a 6ms "heads-up" pulse out before the data. The receiver will see this heads-up pulse, measure its length, and if it is longer than 5ms it knows to turn on its serin. The scope I'm using is a Velleman HPS140 handheld.
 

JimPerry

Senior Member
I'm trying to find the length of a one byte serial frame so that I can send a 6ms "heads-up" pulse out before the data. The receiver will see this heads-up pulse, measure its length, and if it is longer than 5ms it knows to turn on its serin. The scope I'm using is a Velleman HPS140 handheld.
Surely the serin needs to be on all the time - if nothing is coming in then safe to transmit - but if the "Heads Up" is detected in the serin then start doing something with the serin data? You also need a "Finished" sequence so it knows when to stop and proceed on the received data. :rolleyes:
 

hippy

Technical Support
Staff member
Wow, you can tell all that just from that picture?
Years of practice. Much like a physician can look at an ECG trace and tell many things where most of us could only tell if the patient were alive or not!

What I don't get is why the scope reading looks like 0101010101 when it should be 1010101011.
When sent using a Txxxx baud rate the signal will be idle high, each bit of the byte sent is low for 0 and high for 1, the start bit (S) is opposite idle ( ie 0 ) and the stop bit (P) is the same as idle ( ie 1 ). So if you start as input, have a short delay to show the idle, send the byte, delay then make an input again you should see -

Code:
   ___   _   _   _   _   ____
---   |_| |_| |_| |_| |_|    --- 

       S 0 1 2 3 4 5 6 7 P
If you use Nxxxx everything is inverted, except of course where the pin is an input, which stays floating in the middle -

Code:
       _   _   _   _   _
---___| |_| |_| |_| |_| |____--- 

       S 0 1 2 3 4 5 6 7 P
With just a short delay between the pin being input, sending, and back to input the trace will look more like this ... which is what I see on your scope ...

Code:
       _   _   _   _   _
------' |_| |_| |_| |_| |_------ 

       S 0 1 2 3 4 5 6 7 P
 

smolder

New Member
Oh ho! No wonder it didn't make sense to me, I thought that Txxxx was inverted and that Nxxxx was "normal". I was also working under the assumption that start and stop bits were always high, I didn't know about the opposite/same as idle part.

In other news I've tested this all out on some breadboards and it is working! I really appreciate everybodys help, I now have a much better understanding of how picaxes' serial data works. Now I can move on to making a two way communication, and then on to multiple transceivers, and then world domination (muhaha).

Surely the serin needs to be on all the time - if nothing is coming in then safe to transmit - but if the "Heads Up" is detected in the serin then start doing something with the serin data? You also need a "Finished" sequence so it knows when to stop and proceed on the received data. :rolleyes:
These transmitters and receivers will be on mobile robots. I can't leave serin on all the time because the robots need to move around to find each other. So what they will do is move a little and then check their IR sensors for the Heads-up to ensure that they don't move into range and read just a piece of the serout that the other robots are shooting out. So far it seems that the stop bit of the transmission is enough to end the serin command and continue with the program.
 

JimPerry

Senior Member
Flawed logic - if they randomly check - they will almost never get the proper HEADS UP signal - think about it.
 

SAborn

Senior Member
then check their IR sensors for the Heads-up to ensure that they don't move into range and read just a piece of the serout that the other robots are shooting out.
Would it not be better to use a qualifier in the serial data so each robot knows if the data is for it and would also identify which robot sent the data.

SERIN pin,baudmode,(qualifier,qualifier...)
SERRXD (qualifier,qualifier...)
 

smolder

New Member
Flawed logic - if they randomly check - they will almost never get the proper HEADS UP signal - think about it.
I'm hoping that I can use an interrupt triggered when the IR receiver picks up a signal to start checking for the serin data.

Would it not be better to use a qualifier in the serial data so each robot knows if the data is for it and would also identify which robot sent the data.
Hmm, uh, yeah I think so lol. I could simply use a very short heads-up pulse to trigger the interrupt on the receivers and just add a timeout to the serin for the times that the bots pick up part of a transmission. Yeah, I think that is going to work. I'll report back when I've completed some more testing.
 

hippy

Technical Support
Staff member
Would it be possible to change the initial high pulse originally mentioned and change that for an 1800hz pwm signal?
A pulse is being output before the serial data is sent so that pulse can trigger an interrupt in the receiver which then executes SERIN to read that data.

If PWM were put before the data sent the interrupt routine would have to ensure that the PWM had ended before executing the SERIN.

It could potentially be done but the question would be why you would want to do that ?
 

Ghostbear

Member
A pulse is being output before the serial data is sent so that pulse can trigger an interrupt in the receiver which then executes SERIN to read that data.

If PWM were put before the data sent the interrupt routine would have to ensure that the PWM had ended before executing the SERIN.

It could potentially be done but the question would be why you would want to do that ?
In short, backwards compatibility.

I'm working an a variant laser tag larp combat system with integrated sci fi medical/healing boxes that I want to talk to the sensor.

The legacy kit uses an 1800hz (modulated with 56k carrier) pulse to indicate a hut so I want to make sure the sensors can read a signal that's either pure 1800hz hit or a 1800hz hit followed by data
 

slimplynth

Senior Member
Laser Quest? brilliant :)... note of caution: (i saw a guy break his neck once playing this... don't use fog machines near cramped tunnels.. he just ran in to it.. was horrible to see someone hurt like that.. )
 

Ghostbear

Member
Laser Quest? brilliant :)... note of caution: (i saw a guy break his neck once playing this... don't use fog machines near cramped tunnels.. he just ran in to it.. was horrible to see someone hurt like that.. )
Outdoor sf Larp... let's see, I could list the number of times I've injured myself..... but it'd take a while :)
 

hippy

Technical Support
Staff member
The legacy kit uses an 1800hz (modulated with 56k carrier) pulse to indicate a hut so I want to make sure the sensors can read a signal that's either pure 1800hz hit or a 1800hz hit followed by data
It could work. You could also send a pulse, serial data, then the 1800Hz signal. Or just loop waiting for SERIN using qualifiers, no need for pulses or interrupts.
 

Ghostbear

Member
It could work. You could also send a pulse, serial data, then the 1800Hz signal. Or just loop waiting for SERIN using qualifiers, no need for pulses or interrupts.
Would if we could, that'd be the easy route. The problem is the older kit only sends out the 1800hz signal so to have the new stuff work with "legacy" kit it needs to be able to accept the frequency based hit as well.

It also makes it easier for those that are not so confident with microprocessors to be able to build an emitter/gun circuit using thing like 555 based frequency generators and the like. The idea for that bring to make it as accessible as possible to as many as possible. Even if the sensors need microprocessors we could supply those preprogrammed in a kit.
 

hippy

Technical Support
Staff member
Would if we could, that'd be the easy route. The problem is the older kit only sends out the 1800hz signal so to have the new stuff work with "legacy" kit it needs to be able to accept the frequency based hit as well.
I think the main problem here is you resurrected a near six year old thread related to solving a particular problem to ask if you could do something else to solve an entirely different problem.

It would probably be best to start a new thread where you can detail what you are trying to do, what the full requirements are, and discuss the best way of implementing and achieving that.
 

Ghostbear

Member
Fair point. It was because the thread was relatively close and I had thought that perhaps all it needed was a slight mod to the code on gb this one
 
Top