Let's Make Robots! | RobotShop

Arduino I2C Picaxe

Make servo/whatever controller out of Picaxe 28x1 and control it from Arduino over I2C
i2c_servocontroller.bas574 bytes
i2c_masterforpicaxe.pde487 bytes

While working on my first Arduino project I found out that servo library is not compatible with software serial library which is very bad for my project. So, I thought: What about making my own servo controller of say... Picaxe 28x1 chip??? Which will communicate over serial...Doh!... servo command won't do... hmmm... I2C!!! Quick search trough manual, and.... TARAM!!!    hi2csetup command just gives you all you need!!! :

  • Ability to configure Picaxe as I2C slave (for 20x2, 28x1, 28x2, 40x1 and 40x2 chips only)
  • I2C functions absolutely automatic (i.e. should not be any interference with servo command for example)
  • Giving all 128 (X1, 20X2) or 256 (X2) bytes of scratchpad area for memory transfer
  • hi2cflag flag set when master writes to our chip

Sounds very promising to me! So lets get started. My setup: Picaxe 28x1 on breadboard + Arduino Duemilanove.

Test Setup

To connect 2 mCUs you need just 2 wires: Picaxe 28x1 pin 14 (i2c clock) to Arduino analog input 5 and Picaxe pin 15 (i2c data) to Arduino analog input 4. Arduino has pullup resistors for I2C built-in, so you do not need to mess around with resistors.

My Picaxe I2C slave code for use of byte 0 of scratchpad to control servo on outpin 0. You can add more controls by just adding case branches for other servos or whatever you desire!


1 'Servo controller for IMP21

2 '6-jun-2010 by Isotope

3 'v1.0

4 '


6 #no_data

7 #no_table


9 'addr | control

10 '--------------------

11 '0 | servo @ pin 0

12 '

13 '


15 hi2csetup i2cslave, 160 '80 on arduino


17 put 0, 150 'initial position

18 servo 0, 150


20 main:


22 if hi2cflag = 0 then

23    goto main ' poll flag, else loop

24 else


26   hi2cflag = 0 ' reset flag

27   get hi2clast,b1 ' get last byte written


29   select case hi2clast 'what address in scratchpad it was written to

30   case 0 'ok, address was 0

31      servopos 0, b1 'which is our servo 0 slot. Move it.

32   endselect


34   goto main

35 endif


Ok, little bit of explanation here:

line 15: setup Picaxe as I2C slave with adress 80. We have 160 there as bit0 of address is read/write flag which is ignored in our case, so to shift 80 one bit to the left we have to muliply it by 2, that gives us 160.

line 17-18: initialize scratchpad byte 0 with value of 150 (servo center position) and move servo into that pos.

line 22: We continiously poll the hi2cflag to see if master wrote something to us. when it becomes 1, first we have to clear the flag by ourselves (line 26) then we can get last written byte to b1 (line 27) and deside what to do with it upon address it was written to (lines 29-32). Thats it! My servo controller code for one servo is ready.

Now lets move to Master (Arduino) code:

#include "Wire.h" //We need this library to operate I2C

byte pos; //Position of servo

void setup(){
 Wire.begin(); //Initialize I2C

void loop(){
  for(pos = 100; pos <= 200; pos++){
   Wire.beginTransmission(80); //Init transmission to address 80
   Wire.send(0); //scratchpad address we want write into
   Wire.send(pos); //data we write - position of servo 
   Wire.send(0); //Just add this
   Wire.endTransmission(); //finalize transmission

What we do here is pretty much explained in comments to code. Just one thing to mention is format of messages: First byte to transmit is the scratchpad address we want to write to, second is data byte. I figured out by trial and error that communication won't take place if you specify just address and data byte, you need to write 3rd byte of whatever (I did write 0) for all of this to work.

Now we have our very own servo controller!!! Just add more servos, LEDs, motors, whatever and controll it all over I2C from Your Arduino board! :)

I have tested it with just one servo and it worked perfectly :)

Enjoy! :D



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Here is a link to other I2C examples for Arduino.

I have also struggled with the servo library not working with software serial library. The strange thing is that it works in build 0016 but not in 0017 or 0018 ?
In my current project I’m reading/writing to an SD card,  reading a GPS and writing to an LCD while controlling a servo. So I’m stuck with the Arduino 0016 IDE for the time being.

When i use a GPS with a Servo i use the new Arduino IDE but i copy the servo library from Arduino 0016 but you can only operate a servo on pin 9 and 10 in that case so this is very helpful.  But for me, all i want is a ESC and servo so 2 is enough in my case. :).

I am getting a 18M2 PICAXE chip and want to use it as a co-processor with a Aruino (Uno or Duemilanove) to make my "Phoenix" a very smart/capable robot. (I was hoping it would work with 0022....). Great details, great stuff (and needless to say, great website). 

My plans also might include an XBee or some form of computer-robot connection (maybe with even more processing happening at the PC side, like even a remote webcam.) Oooooh, this is sending warm tingles down this old mans back! :-)

Keep me "in the loop" and keep going! Awesome!

BTW fritslmaybe if I had seen your first "try this one first" robot sooner I would have saved me building a fairly expensive POP-BOT (168) that blew up (smoked h-bridge) and has been rebuilt into my "Phoenix". Consider that a great compliment.