Send string using i2c

Hi,

I am relatively new to arduino and RPi. I want to uses multiple arduino's connected to the Pi using i2c because it is cheap. I want to use the the arduino to turn stuff on and off as well as monitor a home then send that information back to the Pi and host a web server. I figured the best way to do it is by sending strings of data back and forth between the arduino and Pi.

Does anybody know how to do this? I compiled some code to gather the data I need and send that back. Everything works up until the point where a wire.write or wire.read a string, it works with integers. Can anybody maybe tell me what is wrong with the code below?

If I may be so bold as to ask for help with Python on the Pi, can someone maybe provide me with a link to a good python tutorial to help me on this?

Thank you in advance.

#include <Wire.h>

#define SLAVE_ADDRESS 0x04

String command = "";
int state = 0;
String report = "";
String pinStatus = "";

//Enter pin numbers used here; it will be used to compile the feedback report later.
//Do not enter light sensor, temp sensors etc.
int pinsUsed[] = {13, 22, 24, 26};  

void setup() 
{
  pinMode(13, OUTPUT);
  
  Serial.begin(9600);         // start serial for output
  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);

  Serial.println("Ready!");
}

void loop() 
{
  delay(100);
  report = getPinStatus();
  Serial.println("Report:");
  Serial.println(report);
}

// callback for received data
void receiveData(int byteCount)
{
  while(Wire.available()) 
  {
    command = Wire.read();
    Serial.print("Command: ");
    Serial.println(command);

    if (command == "1")
    {
      if (state == 0)
      {
        digitalWrite(13, HIGH); // set the LED on
        state = 1;
      }
      else
      {
        digitalWrite(13, LOW); // set the LED off
        state = 0;
      }
    }
  }
}

// callback for sending data
void sendData()
{
  Wire.write(report);
}

String getPinStatus(void)
{
  String pinStatus = "0x04,";
  for(int x = 0; x < (sizeof(pinsUsed)/2); x++)
  {
    if (digitalRead(x) == HIGH)
    {
      pinStatus = pinStatus + pinsUsed[x] + ",1,";
    }
    else
    {
      pinStatus = pinStatus + pinsUsed[x] + ",0,";
    }
  }
  return(pinStatus);
}

I figured the best way to do it is by sending strings of data back and forth between the arduino and Pi.

So, why don't you?

String command = "";
int state = 0;
String report = "";
String pinStatus = "";

Those are NOT strings.

Everything works up until the point where a wire.write or wire.read a string

Probably because that is NOT what you are doing.

Hi PaulS,

Thank you for the reply.

Can you please provide some guidance or point me in the right direction?
Can I send the "report" as one long string? Should it be done as char? Are the variables not declared correctly?

Thanks!

For future humans reading this who are having this issue but still don't understand why PaulS is saying that Strings aren't strings, here is a more verbose explanation:

Arduino nomenclature uses the word "string" (little s) as a shorthand method of denoting an array of chars. This is distinctly different from the class "String" (big S).

http://www.arduino.cc/en/Reference/String (it really doesn't help that the URL uses big S...)
String() - Arduino Reference

Humans who use phonetic pronunciations to derive meaning (or machines that have the ignoreCase flag set :wink: ) might not understand at first that these two things are very different. You can concatenate a String very easily with concat(). You can not do the same operation with a string. Functions that say they want a string input actually want a char array input, and will get very fussy if you try to give them a String.

The main point of confusion (for me, at least) came from the Wire.write() doc page:

It very clearly states that you can send a string using this function. This, however, does NOT mean that you can send a String (believe me, I've tried - you get about a thousand lines of error messages).

So, the solution to this is to convert your String to a string, like so:

Big_S_String.toCharArray(little_s_string, 8);
Wire.write(little_s_string);

I would personally love it if they changed the documentation to say "char array" instead of "string", since it is not intuitively obvious when first starting out down with an Arduino.

As a side note, I'm replying to this year old topic since it was the most relevant to the issue I was facing in hopes that other people who have the same problem and stumble across this thread will understand why their Wire.write() function isn't working. Izak, I hope you've figured all of this out by now. :smiley: