IRout at other then 38Khz

profmason

Member
infrain and infraout are dandy if you have a 38Khz remote and use the sony protocol. In fact in the US the 99 cents only chain sells universal remotes that can be programmed to the sony standard for 99 cents. These work great with the picaxe.

However, I have a device (A Wowee Robosapien) that wants a 1200 baud 39.2 Khz ir signal. No problem, I setup the pwmout to provide close enough to 39.2 kHz and feed that into an AND gate. The other input of the AND gate is an output from the picaxe. I send T1200 signals out from the output and into the AND gate which results in a 39.2 Khz carrier modulated at 1200 baud. Great so far!

BUT! The Wowee protocol wants a header that looks like this %11111111 followed by a time spaced pattern where a high is 0001 and a low is 01. If I code up a typical pattern for say "Walk forward" or $86 it looks like %11111111,%000101010,%01010001,%00010100

It took me the longest time, but I think I know what isn't working. Looking at the output on a scope there is a single low to high transition between each 8 bit transmission. This is messing up all my timing. I assume this is the "1 stop bit" in the 8n1.

Anyone have any ideas how I can modulate that pwm signal at 1200 baud continuously for 2 words with no stop bits? I have fiddled with pulsout without much success.

I have searched the forums on this without much success. I know I could do it with a raw pic, but what would be the fun of that!

Here is a link to my quick writeup of the work so far: http://profmason.com/?p=448

Thanks for any help!
profmason
 

hippy

Senior Member
1200 baud is approx 833uS per bit, so it should be possible to bit bang the line you are using for SEROUT, but you'll need a spare I/O line to put dummy pulses out ...

- HIGH IR
- PULSOUT DUMMY,83
- LOW IR
- PULSOUT DUMMY,83

etc. You'll have to fiddle with the PULSOUT timing. Luckily you have a scope :)

You can also control IR directly by using "SYMBOL IR=pinX" and then you can use "IR=0" and "IR=1", the =0 and =1 can be "=bit0" to "=bit15". You can simply write the command you want to send into b0 ...

- b0 = $B0
- IR=1
- PULSOUT DUMMY,664 ' 83*8
- IR=bit0
- PULSOUT DUMMY,83
- IR=bit1
- PULSOUT DUMMY,83
- IR=bit2
- PULSOUT DUMMY,83

etc

You can also avoid needing the AND gate; connect the pointy end ( cathode ) of the LED to the PWM, the other end via an R to the 'SEROUT' pin. Only when SEROUT is high will the LED send modulated IR.
 

profmason

Member
That makes sense

thanks hippy, I like the idea of using a dummy pin to do the timing.
I was trying

high IR
pulsout IR,83
etc.

When I pulsout'ed the same pin it inverted that pin and I was getting no where!

I will report back tonight if there is progress after work.

have fun!
 

profmason

Member
Working at last

So at almost 2 am SoCal time it is working. Thanks for the suggestion Hippy! I had to spend quite a bit of time sorting out the Wowee protocol. Here is the code:

'RoboSapien IR control using picaxe 08M
'Pass commands at 4800 baud 8N1 from your terminal


setfreq m8

'IR is modulated by channel 1
symbol IR = 1
'This is a dummy variable to make pulsout work
symbol dum = 4

'These are values to make the timing work
symbol duration = 88
symbol start = 1203
symbol highbit = 560
'start the pwm module
pwmout 2,50,100
main:
low ir
'refresh the pwm module
pwmout 2,50,100
pause 50
'Get a value from the terminal
serin 4,N2400,b0
pause 10

'Init and WAKEUP sequence
high IR
pulsout dum,start
'RSV2 header is always 0011 0
low IR
pulsout dum,duration
high IR
pulsout dum,duration
'This bit is low 0
low IR
pulsout dum,duration
high IR
pulsout dum,duration
'This bit is high 1
low IR
pulsout dum,highbit
high IR
pulsout dum,duration
'This bit is high 1
low IR
pulsout dum,highbit
high IR
pulsout dum,duration
'END HEADER

'logic


if bit7 = 0 then
gosub lowsignal
else
gosub highsignal
endif
if bit6 = 0 then
gosub lowsignal
else
gosub highsignal
endif
if bit5 = 0 then
gosub lowsignal
else
gosub highsignal
endif
if bit4 = 0 then
gosub lowsignal
else
gosub highsignal
endif
if bit3 = 0 then
gosub lowsignal
else
gosub highsignal
endif
if bit2 = 0 then
gosub lowsignal
else
gosub highsignal
endif
if bit1 = 0 then
gosub lowsignal
else
gosub highsignal
endif
if bit0 = 0 then
goto finallowsignal
else
goto finalhighsignal
endif

goto main

highsignal:
'This bit is high 1
low IR
pulsout dum,highbit
high IR
return

lowsignal:
'This bit is low 0
low IR
pulsout dum,duration
high IR
return


finalhighsignal:
'This bit is high 1
low IR
pulsout dum,highbit
high IR
pulsout dum,2
goto main

finallowsignal:
'This bit is low 0
low IR
pulsout dum,duration
high IR
pulsout dum,2
goto main

The writeup (such as it is) is at :

http://profmason.com/?p=448
 

hippy

Senior Member
You can probably save quite a few bytes of code by changing all ...

- if bit7 = 0 then
- gosub lowsignal
- else
- gosub highsignal
- endif

to ...

- bit7 = bit7 : gosub signal ' Can drop the assignment
- bit7 = bit6 : gosub signal
- bit7 = bit5 : gosub signal
- bit7 = bit4 : gosub signal
- bit7 = bit3 : gosub signal
- bit7 = bit2 : gosub signal
- bit7 = bit1 : gosub signal
- bit7 = bit0 : gosub signal

- Signal:
- if bit7 = 1 Then HighSignal
-
- LowSignal:
- :
- return
-
- HighSignal:
- :
- return

You may have to tweak the timing again. Save a backup so you can revert if you run into problems :)
 

profmason

Member
Thanks for the suggestion!

I knew there had to be a better way of doing it! Right now I am in the middle of getting the computer vision software bridged into the robosapien through the picaxe. It is working pretty well, but I am still fumbling around with the serin and serout.

It seems like the 08M wants the receive pin grounded when you are doing a serin on any other pin. The other chips don't all seem to share this feature. I will have to search the forum on this.


More updating will come when I don't have to work a half day.(12 hours)

have fun!
 

hippy

Senior Member
It seems like the 08M wants the receive pin grounded when you are doing a serin on any other pin.
I haven't noticed that being a problem myself. Like other PICAXE's, the 08M should ignore the levels on any pins it is not referencing in a command.
 

papaof2

Senior Member
"It seems like the 08M wants the receive pin grounded when you are doing a serin on any other pin. "

Standard practice on the PICAXE chips is for unused input pins to be grounded (preferably via a resistor, to protect pins that can be both input & output).

The serin pin is an input so it should be grounded (or connected to a download circuit).

Isn't serin held high to put the chip in download mode? If so, then a floating serin could go high long enough to trigger download mode - which would prevent any program from working.

John
 

BeanieBots

Moderator
Hmm, like papof2, I'm thinking the "receive" pin might be referring to the download serin pin. In which case it MUST be pulled low on ALL PICAXE variants, not just the 08M.
It is certainly 'good practice' to hold unused pins either high or low via a resistor but it is NOT essential. Whether or not a pin is high or low should have no effect on any serin command. If it does, it would imply either a code or hardware error. If interrupts are being used to detect the arrival of serial data then any used pins would need to be tied down.

Can you please explain what you mean by "receive" pin?
 

profmason

Member
"Receive Pin"

Sorry for the confusion! I meant the "Serial In" Pin namely pin 2 on the 08M. Is there some easy shortcut to
1. Unplug ground on Serial in pin
2. Plug 22K resistor into Serial In pin
3. Program
4. Move 22K resistor to pin I want to receive serial in from PC.
5. Ground Serial in pin.
6. Realize there is something wrong with the code and repeat

There is no real cause to complain here, since it used to be 1. Long process of burning EPROM.
2. Realize there was a bug and put under the UV lamp. etc etc

As long as we are on this topic, If I use serin 4,N2400,b0, I can input ascii characters and get the decimal equivalent. I don't quite know what to do to send it ASCII 1-31 or >128 since these are not character codes. Right now I am just subtracting 32 from my variable IE b0 = b0 -32 which means I can work with Decimal 0 - 96 which give me access to HEX $00 to $60 (This means I can't send a $AA which is the stop command and somewhat important!)

thanks for all the help folks!
 

BeanieBots

Moderator
Your current sequence will not be reliable as you have already found out.
The serin pin must NEVER be left floating.
Fit the 10k/22k to BOTH pins. Then just use a switch or a second socket to select between the two 10k/22k input nodes.

The serin command can read a string of ASCII characters and convert them into a number. Hippy posted how to do it a while back. I can't remember the exact syntax but I think it was something along the lines of using the # on the input. It uses the CR/LF to determine end of string.
eg serin,pin,baud,(#b0) but not 100% sure.
 

profmason

Member
Couldn't get anything with the # on the input

Thanks for the hint.

I ended up using this:
Code:
main:

	'Input 3 digits between 000 and 255
	serin 4,N2400,b0,b1,b2
	
	'Convert b0 to hundreds 
	b0 = b0 - 48
	b0 = b0 * 100
	'Convert b1 to tens
	b1 = b1 - 48
	b1 = b1 * 10
	'b2 is 1 place
	b2 = b2 - 48
	'Add up the digits
	b0 = b0 + b1 + b2
	
	serout 0,N2400, (#b0,13,10)

goto main
It takes three digits in ascii and turns them into a decimal value IE sending 242 sets the variable b0 to 242

There has to be an easier way!
 

hippy

Senior Member
Untested, but this should work ( 5328 = 4800 + 480 + 48 ) ...

serin 4,N2400,b0,b1,b2
b0 = b0 * 10 + b1 * 10 + b2 - 5328
serout 0,N2400, (#b0,13,10)
 

papaof2

Senior Member
Definitely untested and probably done at a caffeine low - unless you've found a way to put more than 255 into a byte: "- 5328"

John
 

profmason

Member
Ja, i didn't mention the hours I wasted.

I had started off with
b0 = 100 * b0 + 10 * b1 + b2

which of course ran into the "Unique" way the picaxe compiler treats order of operations!

Entering a 132 would result in an overflow because 100 + 10 = 110 *3 = 330 + 2 = 332

Now Hippy's suggestion should word great with a word variable and even cleverly avoid the @##@$ order of operations problem.

have fun!
 

hippy

Senior Member
My untested code is always perfect :)

Definitely untested and probably done at a caffeine low - unless you've found a way to put more than 255 into a byte: "- 5328"
Now Hippy's suggestion should word great with a word variable and even cleverly avoid the @##@$ order of operations problem.
The clever thing about a PICAXE is that it does all maths at 16-bit ( word size ) internally and only shrinks the result back to a byte once it comes to store the result :)

That "b0*10 + b1*10" rather than "b0*100 + b1*10" has caught me out a few times. It just looks plain wrong.
 
Top