Chip to Chip, Serial, Questions

Jarubell

Senior Member
I would like to have only two chips communication with the serial commands. To keep things simple, I would like to have one discrete input into one chip, transmit a variable to the second one, and turn on/off a LED. I see the examples in the manual but I'm still unsure.

Can I have the first chip in a loop constantly performing the serout command and the second one waiting to receive. But that's where I'm confused, does the second chip just wait on the serin command till a variable is received?

I need a little direction, I would like to expand this little project to a couple analog inputs, along with a half dozen discrete inputs.

BTW, I'm looking at serial because I need to be hardwired between the chips (~30m) and will expand this project to RS485 using the MAX485 ic, but I still need to look into this setup.
 

lbenson

Senior Member
The "SERIN" command is "blocking"--that is, your program doesn't advance past it until its input is received (unless you code it with a timeout).

You can use hardware serial input for receive in the background. For the M2 devices, the background receive buffer is only 2 bytes long, but for the need which you have described, that wouldn't seem to be a problem. The following snippet assumes that you will never send $FF as a valid code.

Code:
#picaxe 14m2
symbol command = b4
hsersetup b2400_4,%01100 ' hserout pin normal, N (hserin pin active low)
main:
  do
    command = $FF ' non-valid command
    hserin command ' if no bytes ready, no change
    select command
      case "1":
         ' your code here
      case "2":
         ' your code here
      case $FF: ' no input, so do nothing
    end select
  loop
 

lbenson

Senior Member
Can you explain what you want to do a little more?

With the X2 devices, you can send many bytes in the background; with the M2, only 2 at a time until the two are processed.

If you are just turning LEDs (or anything) on and off, an 8-bit byte can contain the on/off status of 8 LEDs/outputs. Combine that with an initial command and you can get many more.
 

Jarubell

Senior Member
I have three switches into a 18m2 where I would like to send to another 18m2, then have that one display the results on an Axe033.

For now I'm just trying to toggle outputs but I would like to build up to PWM or even Servo.

I do have a 20x2
 

inglewoodpete

Senior Member
If you want to send binary information from 3 switches, you only need one byte to transmit this information.

Eg, for an 18M2, assuming all three switches are connected to one port (C,0, C.1 & C.7 in this case), pull down resistors and the switches pull the pin high when operated:
Code:
#PICAXE 18M2
b5 = pinsC And %10000011  'Ignore inputs C.2 to C.6
SerOut [I][COLOR="#B22222"]pin[/COLOR][/I], N4800_4, (b5)
 

Jarubell

Senior Member
Thank you inglewoodpete.

After I send the byte, is there a way to break up that one byte into separate variables?
 
Last edited:

Circuit

Senior Member
After I send the byte, is there a way to break up that one byte into separate variables?
Very easy; bring the byte into b0 then reference bit1, bit2, bit3 etc. See manual 2 page 13 for a fuller explanation.

b0 = bit7: bit6: bit5: bit4: bit3: bit2: bit1: bit0
 

lbenson

Senior Member
Note that with 2-byte background serial receive you can, in theory, issue 65536 unique commands or specify 65536 unique conditions (minus 256 for the invalid $FF command code and another 256 for the invalid $FF subcommand code).
Code:
#picaxe 14m2
symbol command = b4
symbol subcommand = b5
hsersetup b2400_4,%01100 ' hserout pin normal, N (hserin pin active low)
main:
  do
    command = $FF ' non-valid command
    hserin command ' if no bytes ready, no change
    if command <> $FF then
      pause 10 ' allow time for second byte to arrive
      subcommand = $FF ' non-valid subcommand
      hserin subcommand ' if no bytes ready, no change
      if subcommand <> $FF then
        select command         ' non-$FF command and subcommand arrived
          case 0:
            select subcommand
              case 0:
                 ' your code here
              case 1:
                 ' your code here
              ' additional cases through 254
            endselect
          case 1:
            select subcommand
              case 0:
                 ' your code here
              case 1:
                 ' your code here
              ' additional cases through 254
            endselect
          case $FF: ' no input, so do nothing
        end select
      endif
    endif
    ' other code can go here
  loop
Of course, you would run out of code space before you processed that many.

If you wanted 254 commands/conditions or fewer, with some added assurance that you had received the data correctly, you could send the code and its inverse, and compare them, e.g., send the two-byte sequence %00000001 and %11111110 (omitting $ff and its inverse, 0).
 
Last edited:

Jarubell

Senior Member
Thank you guys for the replies, I'll be looking (reading) into them for the next few days with limited internet on Big Tancook Island.
 

lbenson

Senior Member
My wife is familiar with Big Tancook Island from her sailing days out of Prospect Bay. She says she hopes you don't freeze.
 

Jarubell

Senior Member
I tried to get my wife on board for getting a sail boat, but she's not interest. She would go for an old lobster boat converted to a cruiser, works for me!

I tried figuring out how to reference a bit of a byte but really couldn't find anything, so I just tried something in AXEpad, syntax checked okay, and it seems to work. But I'm still not sure if I did it correctly. If I received two variables, how can I reference a certain bit of a certain byte?

I tried using the 'hser' but I couldn't get it to work yet, so I tried 'ser' and had something happen. I then thought of my hook up, went to the manual and could only find hooking up a PicAxe to a computer. Tried that, worked for a while then weird things happened on the receiving end, changed the setup, works again for now. So, what is the proper way to connect two picaxes with serial communication?(just one way for now) What's the difference between 'ser' and 'hser'?

Here's my code for the first 18M2 (still working on how to keep my code tidy)

Code:
#PICAXE 18M2 ;Transmit 
init:pause 500

Main:
b0 = pinsB And %00001011  
if bit0=1 then:high c.1:else:low c.1:endif
if bit1=1 then:high c.1:else:low c.1:endif
if bit3=1 then:high c.1:else:low c.1:endif

serout b.2,n2400,(b0)

goto main
And my code for the second

Code:
#PICAXE 18M2 ;Receive 

init:pause 500
serout c.0,n2400_4,(254,1):pause 30



Main:

serin b.2,n2400,b0

	if bit0=1 then
		SerOut c.0, N2400_4, (254,128,"ONE   ")
		high b.1
	else
		serout c.0,n2400_4,(254,128,"one   ")
		low b.1
	endif
			
	if bit1=1 then
		SerOut c.0, N2400_4, (254,134,"TWO  ")
		high b.0
	else
		serout c.0,n2400_4,(254,134,"two  ")
		low b.0
	endif
	
	if bit3=1 then
		SerOut c.0, N2400_4, (254,139,"THREE")
		high b.3
	else
		serout c.0,n2400_4,(254,139,"three")
		low b.3
	endif
	
goto main
I guess I might as well include a photo.
IMG_20160110_204239.jpg
 
Last edited:

hippy

Ex-Staff (retired)
Your general idea seems sound but there is a risk that the receiving PICAXE may get out of sync with the sending PICAXE, may begin reading a sent byte halfway through. It would be best to use a qualifier to synchronise the data ...

SerOut B.2, N2400, ( "XYZ", b0 )

SerIn B.2, N2400, ( "XYZ" ), b0
 

Jarubell

Senior Member
Thanks Hippy.

Well I've played a little with this project, applied Hippy's suggestions as well as change my code a little. Things seem to be working okay, I now have 5 switches, one LDR, and one pot inputting into one 18M2 then sending those variables to another 18M2. The receiving Picaxe then outputs data to a Axe033 and toggles three LEds (well, one RGB).

I don't have much experience with Picaxe and I know my code is simple but it's funny how much I smile when I finally got this part working.

My question is how do I properly connect the two Picaxes together? Are resistors required?

Code:
#PICAXE 18M2 ;Transmit 
init:pause 500


Main:

if pinb.0=1 then:b0=1:high c.1:else:b0=0:low c.1:endif	;Switch One
if pinb.1=1 then:b1=1:high c.1:else:b1=0:low c.1:endif	;Switch Two 
if pinb.3=1 then:b3=1:high c.1:else:b3=0:low c.1:endif	;Switch Three
if pinb.7=1 then:b7=1:high c.1:else:b7=0:low c.1:endif	;Switch Four
if pinb.6=1 then:b6=1:high c.1:else:b6=0:low c.1:endif	;Switch Five

readadc b.4,b4 												;LDR Input
readadc b.5,b5 												;Pot Input

serout b.2,n2400,("XYZ",b0,b1,b3,b4,b5,b6,b7)			

goto main
Code:
#PICAXE 18M2 ;Receive 

init:pause 500
serout c.0,n2400_4,(254,1)



Main:

serin b.2,n2400,("XYZ"),b0,b1,b3,b4,b5,b6,b7

;Switch One 
	if b3=1 then
		SerOut c.0, N2400_4, (254,128,"1"):high b.1
	else
		Serout c.0,n2400_4,(254,128,"0"):low b.1
	endif
	
;Switch Two		
	if b1=1 then
		SerOut c.0, N2400_4, (254,130,"1"):high b.0
	else
		serout c.0,n2400_4,(254,130,"0"):low b.0
	endif

;Switch Three	
	if b0=1 then
		SerOut c.0, N2400_4, (254,132,"1"):high b.3
	else
		serout c.0,n2400_4,(254,132,"0"):low b.3
	endif

;Switch Four	
	if b7=1 then
		SerOut c.0, N2400_4, (254,134,"1")
	else
		serout c.0,n2400_4,(254,134,"0")
	endif

;Switch Five	
	if b6=1 then
		SerOut c.0, N2400_4, (254,136,"1")
	else
		serout c.0,n2400_4,(254,136,"0")
	endif
	
	
;LDR	
	Serout c.0,N2400_4,(254,193,#b4,"  ")
	
;Pot	
	Serout c.0,N2400_4,(254,198,#b5,"  ")
	
goto main
Now, while I wait for new components, I'll try to tidy up my code.
 

erco

Senior Member
If you're using 18M2+ chips, another option might be using RFOUT and RFIN commands, using direct wired connection instead of radio link. Per other discussions here, that uses Manchester coding to send 8 bytes at a time and should work with direct connection. Something like serial, but all the comm protocols & sync are predefined and ready to go. Only implemented in 18M2+, 14M2 and 20M2.
 

lbenson

Senior Member
330R to 1K (or more) between serout and serin will protect against failures and mistakes in programming.

Note that since your b0,b1,b3,b6,b7 variables are just reflecting the value of the pins on port b, you can use the bit variables, bit0-bit31 (which are the constituent bits of b0-b3):

Code:
if pinb.0=1 then:bit0=1:high c.1:else:bit0=0:low c.1:endif	;Switch One
if pinb.1=1 then:bit1=1:high c.1:else:bit1=0:low c.1:endif	;Switch Two 
if pinb.3=1 then:bit3=1:high c.1:else:bit3=0:low c.1:endif	;Switch Three
if pinb.7=1 then:bit7=1:high c.1:else:bit7=0:low c.1:endif	;Switch Four
if pinb.6=1 then:bit6=1:high c.1:else:bit6=0:low c.1:endif	;Switch Five
Then you just need to send 3 bytes and decode the bits in b0 on the other end: serout b.2,n2400,("XYZ",b0,b4,b5)

Since all the pins you want to read are on port b, you can achieve the same as above with: "b0 = pinsB" -- and then set c.1 high or low as needed:

b4 = b0 & %11001011 ' mask the pins you didn't want to read: pinb.2,4,5
if b4 > 0 then high c.1 : else : low c.1 endif
 

Jarubell

Senior Member
Right now I have chip "A" sending variables to chip "B", I would like chip "B" to send info back. Is it as simple as adding another wire to different ports and using serout?
 

lbenson

Senior Member
You probably need either some form of handshaking to avoid lockouts (since serin is blocking), and/or use timeouts in your serin statements and handle any failure to receive expected transmissions.
 

erco

Senior Member
Right now I have chip "A" sending variables to chip "B", I would like chip "B" to send info back. Is it as simple as adding another wire to different ports and using serout?
You can only send or receive at any given time, never both. You can add a second connection, or just as easily use the existing connection in reverse for bidirectional communication. As lbenson says, you need to work out handshaking in either case to figure out who's talking and who's listening.
 
Top