08M2 I/O limits with I2C

wabernat

New Member
Hey all. I've been enjoying my learning endeavors with the PICAXE 08M2. I have an application in mind which more or less requires the smallest form factor I can work with, and 08M2 has so far seemed promising (re-learning BASIC has been worth it no matter what!). I'm trying to feed 4 switch states into the 08M2, and this has worked fine so far. However, getting the switch states as bits off of the PICAXE and on down the I2C bus is looking to be more problematic. I have run into two problems that give me pause before I plunge in.

  1. The pinout says that physical pins 5 and 6 (C.2 and C.1) are reserved for I2C operations, and physical 7, C.0 is OUT only. Does this mean I can only input on 3 pins if I'm using I2C on a 08M2?
  2. My understanding from other posts on this forum is that the 08M2 cannot operate in I2C slave mode. If this is true, what's the smallest form-factor PICAXE I can get that will run as a slave?

Thanks,

--William
 

Jeremy Harris

Senior Member
You only need 2 pins as inputs to be able to use switches to indicate four states, as you can utilise both high and low. You can have, for example, a 2 pole rotary switch with four positions, and arrange it to take the 2 inputs low as required to get the four switch states, using the weak internal pull up feature so that you only need three wires from the picaxe to the switch (0V and the two inputs). The trick is to wire the switch to get the four states:

high high
high low
low low
low high

and then decode that in software to get the one of four states you're after.

Your're right, the 08M2 can only operate as an I2C master, not a slave. The smallest picaxe that allows I2C slave operation is the 20X2 I think.
 

wabernat

New Member
I haven't spoken clearly, and for this I apologize. I am running four physical switches. Counting both on and off, I get *eight* states, not four (duh). I can wire this and do tricks with the input as long as I limit myself to one or two outputs. The I2C bus looks to be hogging two of my inputs. Any way around this?


Edited to set the record straight: four switches = 16 logic states. Did I mention I'm still learning?
 
Last edited:

Jeremy Harris

Senior Member
You could try the analogue switch technique, where you use a resistor chain and your switches connected to one ADC capable picaxe input. In effect your switches then send different voltages to the picaxe and a bit of code can determine which switch (or switches) have been selected. This has been used as a way to use a small number of picaxe pins to read a keypad, for example (see this thread for some ideas that may help: http://www.picaxeforum.co.uk/showthread.php?24850-Converting-a-digital-keypad-to-an-ADC-keypad )
 

hippy

Technical Support
Staff member
Two I/O lines will be required for I2C interfacing and it's usually not at all easy to use those for other purposes as well.

The 08M2 cannot be an I2C Slave Device so the issue may be moot. You would need an X2 to be an I2C Slave, and the smallest would be the 20X2.

There is no way to use less than two I/O for I2C but it may be possible to use a one I/O pin serial bus to pass data instead.
 

wabernat

New Member
Hippy: My understanding (and I welcome you to disabuse me of it I labor under a misconception) is that implementing inter-chip communications over a serial line is not for the faint of heart or new at coding. Isn't there a lot of work associated with, essentially, cooking up my own communication protocol? Or has somebody blazed this trail for me? I'm ultimately trying to get the smallest chip to use the least wires to get 4 bits of data to an Arduino (or pi, or whatever) about 2 wire yards away.
 

Buzby

Senior Member
Use the PICAXE commands 'serout' from one, to 'serin' on the other.

Only needs 1 wire ( and ground ), and no complex coding, the PICAXE does all the comms protocol itself.
 
Last edited:

lbenson

Senior Member
This program appears to me to do what you want. It works in the simulator.

It uses pins 1-4 for input, and 0 for output. It sets up the pin directions with "dirs = %00001", and reads the state of the inputs with "newVal = pins", giving a value of 0-15. This is compared to "oldVal". If different, it is output. You can use the commented out line "serout 0, N2400, (newVal)" to output the binary value at 2400 baud, or use the code which follows to convert to a human-readable hexadecimal value of "0"-"9" and "A"-"F" (a hexadecimal digit has one of the values 0-15 represented by the characters in this string "0123456789ABCDEF"). I did this conversion only for the benefit of being able to read the value which is output--you could send the binary value to your receiving program. A hexadecimal digit can represent all possible values of 4 logic-level switches--4 picaxe digital input pins.

The conversion to hex first shifts the read value to the right with division by 2 (assuming most significant bit is on the left). This is necessary because the program is using pin0 for output, but its "place" is still reserved and will have the value of 0 (so the result of the statement, "newVal = pins" will have a value between 0 and 30 instead of between 0 and 15.
Code:
' 08input4 reads & reports value of 4 switches when changed
#picaxe 08M2

symbol oldVal = b4
symbol newVal = b5
symbol hexVal = b6

dirs = %00001 ' pins 1-4 input, 0 output
oldVal = 255 ' first read of pins will be reported

do
  newVal = pins ' get the states of pins 1-4
  if oldVal <> newVal then
    oldVal = newVal
'    serout 0, N2400, (newVal)
' convert to hex & use serout
    hexVal = newVal /2 + "0" ' shift right
    if hexVal > "9" then ' should be hex A-F
      hexVal = hexVal + 7 ' values 10-15 become A-F
    endif
    sertxd(hexVal)
  endif
  pause 2000 ' for simulation; remove to run on chip
loop
You can run this code in the simulator. Toggle the inputs 1-4 to see what the output will be. Run it in single step mode if you want to see exactly what it is doing.

For running on real chips and sending the output in hex, note that sertxd runs at 4800 baud. If you send in hex, the receiving program would need to reconvert it to binary to determine the pin values, for instance "val = val - "0" : if val > 9 then : val = val - 7 : endif". If val is defined as "symbol val = b0", then the 4 pin values would be in bit0, bit1, bit2, bit3.
 
Last edited:

hippy

Technical Support
Staff member
I would have done similar as lbenson but even simpler. By transmitting it as a readable binary number that makes it easier to debug, and also provides start and end of data markers for the receiver. The #bitN variables can be re-ordered to match whatever order the switches are wired -

Code:
#Picaxe 08M2
#Terminal 4800
Do
  b0 = pinsC & %000011110
  If b0 <> b1 Then
    b1 = b0
    SerOut C.0, N4800, ( "%", #bit4, #bit3, #bit2, #bit1, CR, LF )
  End If
Loop
 

lbenson

Senior Member
As ever, it is instructive to see how hippy does things.

Sending decimal byte-for-bit values is tops for clarity and human readability, and would work well, on the receiving end, with an X2 picaxe using background receive. If your receiving picaxe is an M2 device, then background receive is limited to 2 bytes, so the one-byte transmission might be more convenient, depending on what the rest of the program is doing.
 
Top