Picaxe as a Slave device

hi, i am trying to communicate picaxe with arduino using i2c, I want to use picaxe as a slave and arduino as a Master. i got an example of writing data to slave picaxe, but i am struggling to read data from it. There are a very few information about using picaxe as a slave. and few parts for it (X1 and X2) as well. Can anyone please help me to read data from picaxe to arduino. i mean what should be the code for picaxe .
 

hippy

Ex-Staff (retired)
Untested, but the following should emulate a byte addressed Eeprom with 8-bit Device Address $A0 -

Code:
HI2cSetup I2CSLAVE, $A0

Put 0, "H"
Put 1, "e"
Put 2, "l"
Put 3, "l"
Put 4, "o"

Do
  Pause 1000
Loop
Reading location 0 onwards from Device Address $A0 (8-bit) or $50 (7-bit) should return the values which have previously been put to Scratchpad by the PICAXE program.
 
Untested, but the following should emulate a byte addressed Eeprom with 8-bit Device Address $A0 -

Code:
HI2cSetup I2CSLAVE, $A0

Put 0, "H"
Put 1, "e"
Put 2, "l"
Put 3, "l"
Put 4, "o"

Do
  Pause 1000
Loop
Reading location 0 onwards from Device Address $A0 (8-bit) or $50 (7-bit) should return the values which have previously been put to Scratchpad by the PICAXE program.

Thanks Hippy, but how arduino can read data from picaxe scratchpad. please don't mind for my ignorance about that. i am a beginner.
 

hippy

Ex-Staff (retired)
The Arduino should be configured and read the PICAXE just as it would for an I2C Eeprom with 256 bytes of byte memory.

I personally have no idea what the specific code would be. It is probably better to ask on an Ardunio forum though some PICAXE users may know the code to use.

What the PICAXE puts into or gets from scratchpad is what the I2C master can read or write.
 

oracacle

Senior Member
the picaxe, while in slave mode should behave as any i2c device, once the picaxe has its address established as per hippys' example its down to the Arduino to do the rest. Arduino has a forum so you maybe better off asking over there

Edit: Ninja'd by hippy
 

lbenson

Senior Member
Don't ask on arduino forum about picaxe--ask about reading/writing an I2C Eeprom with 256 bytes, addressed at $50 (7-bit), which is what the picaxe looks like when an i2c slave.
 

Simmicht

Senior Member
I too, am trying to use my ever-loving 28X1 as a I2C slave for my Arduino project.
So far no luck, but I will do my best to get this to happen.

Basically I have a ESP8266 Arduino core and I want to read a MQ-7 Carbon Monoxide sensor. The ESP8266 has only one analogue input and it has a max of 1V.
So I will try to use a 28X1 to read the analogue values and present them to the ESP8266 when it wants them. There are already HTU21 (Temp and humidty) BMP180 for atmospheric pressure and BH1750 for light values.

Connections be like :
Picaxe28X1 pin 14 SCL to Arduino pin A5 SCL
Picaxe28X1 pin 15 SDA to Arduino pin A4 SDA
4K7 pullups to 5V on both line

The Arduino code be like:
#include <Wire.h>

voidsetup(){
Wire.begin();// join i2c bus (address optional for master)
Serial.begin(9600);// start serial for output
}

voidloop(){
Wire.requestFrom(8,6);// request 6 bytes from slave device #8

while(Wire.available()){// slave may send less than requested
char c = Wire.read();// receive a byte as character
Serial.print(c);// print the character
}

delay(500);
}



Terry
 
Last edited:

lbenson

Senior Member
I'm not entirely certain what this code means, and I don't know the arduino code, but I don't see anywhere that the slave picaxe address of $50 is mentioned, and the comment "slave may send less than requested" is not applicable to the process of reading a fixed number of bytes from an i2c 128-byte eeprom (what a slave picaxe looks like).
 

Simmicht

Senior Member
the $50 is %1010 000 the 7 bit form which is the right I2C address when the slave is set to %10100000 .
The arduino will shift left and add bit0 to be read/write.

28X1 code
Code:
#picaxe 28X1
#terminal 9600
#no_data
#no_table


setfreq EM8


pause 2000
Sertxd("START",cr,lf)
'do
'pause 2000
'Sertxd("START",cr,lf)
'loop


init: hi2csetup i2cslave, %10100000




Put 0, "H"
Put 1, "e"
Put 2, "l"
Put 3, "l"
Put 4, "o"
Put 5, "W"
Put 6, "O"
Put 7, "R"
Put 8, "L"
Put 9, "D"
Put 10, "1"
Put 11, "2"
Put 12, "3"
Put 13, "4"
Put 14, "5"
Put 15, "6"


Do
  Pause 1000
  
LOOP

Arduino code
Code:
#include <Wire.h>
 
void setup(){
  Serial.begin(115200);


  delay(1000);
  Serial.println(F("I2C TEST Starting"));


Wire.begin();


Serial.println("oK");
}






 
void loop(){
Serial.print("\n>");


//Wire.beginTransmission(80); // transmit to device #80
//Wire.write("A");           // queue one byte
//Wire.endTransmission();    // send by transmitting


  Wire.requestFrom(0x50, 16,false);    // request 16 bytes from slave device #8
  delay(400);
  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    if (c<32) Serial.print(".");
    else      Serial.print(c);         // print the character
  }




delay(5000);
 
}

and the output
Code:
>HelloWORLD123456
>................
>................
>................
>................
>................
>................
>................
>HelloWORLD123456
>................
>................
>................
>................
>................
>................
>................
>HelloWORLD123456
>................
>................
Seems like the read is just looping through the 28X1 memory.
How can I tell it where to read?

Terry
 

inglewoodpete

Senior Member
and the output
Code:
>HelloWORLD123456
>................
>................
>................
>................
>................
>................
>................
>HelloWORLD123456
>................
>................
>................
>................
>................
>................
>................
>HelloWORLD123456
>................
>................
Seems like the read is just looping through the 28X1 memory.
How can I tell it where to read?

Terry
It looks like the 28x1 slave is working perfectly. Your question needs to be addressed to an Arduino forum.

When reading from an i2c slave, you need 3 parameters: (1) The slave device's address (2) The start point in the slave's memory map (3) The number of bytes to be read. Of course, at some point the master must know how big a memory the slave has - and therefore use an 8-bit (max 256 bytes) or 16-bit address (max 65536 bytes) as the start point for pointing into the slave's memory map.
 

Simmicht

Senior Member
ok i found the way.

the Arduino code needed a write to the address the subsequent reads are to be from.

Arduino code
Code:
#include <Wire.h>
void setup(){
  Serial.begin(115200);


  delay(1000);
  Serial.println(F("I2C TEST Starting"));


Wire.begin();


Serial.println("oK");
 
}


void loop(){
 


Serial.print("\n>");


Wire.beginTransmission(0x50); // transmit to device #80
Wire.write(0);           // queue one byte
Wire.endTransmission();    // send by transmitting


  Wire.requestFrom(0x50, 16);    // request 16 bytes from slave device #8
  delay(400);
  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    if (c<32) Serial.print(".");
    else      Serial.print(c);         // print the character
  }




delay(5000);
 
}
 
Last edited:

Simmicht

Senior Member
A working example, usinf Arduino to get a WORD from 28X1 as I2C slave.

Arduino
Code:
#include <Wire.h>


 
void setup(){
  Serial.begin(115200);


  delay(1000);
  Serial.println(F("I2C TEST Starting"));


Wire.begin();


Serial.println("oK");
}
 
void loop(){
Serial.print("\n>");


Wire.beginTransmission(0x50); // transmit to device #80
Wire.write(100);           // queue one byte from Picaxe SP=100
Wire.endTransmission();    // send by transmitting


Wire.requestFrom(0x50, 2);    // request 16 bytes from slave device #8
delay(400);


uint16_t t = Wire.read();
t  += Wire.read() *256 ;
 //t  = t2*256 + t1;
Serial.print(t);     // print the integer


delay(5000);
 
}
28X1
Code:
#picaxe 28X1
#terminal 9600
#no_data
#no_table


setfreq EM8


pause 2000
Sertxd("START",cr,lf)
'do
'pause 2000
'Sertxd("START",cr,lf)
'loop


init: hi2csetup i2cslave, %10100000




Do
  Pause 2000
  inc w2
  put 100, WORD w2
  Sertxd(#w2,cr,lf)
  
LOOP
Output
Code:
>512
>518
>523
>529
>534
>540
 

stevercarter

New Member
I wish to use say a 20m as master and serial connect say 4 20m as slave units
I want the slave units to replicate the master outputs
 
Top