I2C Reed Contacts (Micro - Leonardo)

Hi,

so i just started to program with arduino. My program consists of 2 arduino boards (Micro) and a (Leonardo + Ethernet Shield ( later for php))....

So i want to put 2 Reed and 2 magnets (1 on the top, 1 on the bottom of the window) between the window so i can see if the window is closed, tilted or open.

This information should be gathered from the Arduino Micro and should be send to the Leonardo. Unforunatly my skript has some mistakes but i dont find them...

I am new to Arduino programing and i would really appreciate it if you could look at my skript and help me.


Slave Code

//i2c Slave (Micro)
#include <Wire.h>

int Window_Led_Pin1 = 13;
//int Window_Led_Pin2 = 12;
int Window_Top_Pin = 6;
int Window_Bot_Pin = 5;
int val = Serial.read() - '0';
int x = 0;

void setup() {
  pinMode(Window_Led_Pin1, OUTPUT);
  pinMode(Window_Led_Pin1, OUTPUT);
  pinMode(Window_Top_Pin, INPUT);
  pinMode(Window_Bot_Pin, INPUT);
  Wire.begin(5);
  Wire.onRequest(requestEvent);  
  
}

void loop()
{
  while (digitalRead(Window_Bot_Pin))
  {
    Serial.println("Das Fenster ist gekippt");
    digitalWrite(Window_Led_Pin1, HIGH);
    x = 1;
  }   
  if(!digitalRead(Window_Top_Pin))
  {
    digitalWrite(Window_Led_Pin1, LOW);
  }

  while (digitalRead(Window_Top_Pin))
  { 
    Serial.println("Das Fenster ist geschlossen");    
    digitalWrite(Window_Led_Pin1, HIGH);
    x = 2;
  }   
  if(!digitalRead(Window_Bot_Pin))
  {
    digitalWrite(Window_Led_Pin1, LOW);
    Serial.println("Das Fenster ist offen");
    x = 3;
  }

}

void requestEvent()
{
  if (x == 1)
  {
    Wire.write ("Das Fenster ist gekippt");
  }
  if (x == 2)
  {
    Wire.write ("Das Fenster ist geschlossen");
  }
  if (x == 3)
  {
    Wire.write ("Das Fenster ist offen");
  }
}

//i2c Master (Leonardo + Ethernet Shield)
#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
}

void loop()
{
  Wire.requestFrom(5);

  while(Wire.available())
  { 
    char c = Wire.read();
    Serial.print(c);
  }

  delay(500);
}

How far is the Micro from the Leonardo? I2C is a local bus and not usable for long distance transmissions (<~50cm).

In the request handler you can send 1 Byte, you cannot send multiple bytes in one run.

I guess for your project an RS485 connection is better suited or at least a UART connection (depends on the distance between the two Arduinos).

At first glance, I noticed a few things.

Initializing a variable with a function is not good: int val = Serial.read() - '0';

You can call Wire.write() only once in the requestEvent() function. You have that, that is okay. However, it would be simpler to send a single number (one byte).

In the Master, you call: Wire.requestFrom(5);
Without the quantity parameter.
Are you sure that is valid ?

If you would use only one byte with a number, it would be: Wire.requestFrom(5, 1);

Initializing a variable with a function is not good: int val = Serial.read() - '0';

Excuse me but this is just an assertion and in my opinion, it's wrong. I see absolutely no problem in initializing a variable with the result of a function. In this special case you're right, but the problem is not the initialization with a function result but that there is no check for a correct return value.

Have you got pull up resistors on the I2C lines?

Yes, okay. I ment initializing a global variable outside the setup() or loop() functions. Any class or variable initialization is done before the setup() is run, so reading Serial data before Serial.begin() ... I don't know what that will do, perhaps undefined. Where is the "Serial.begin()" in the Slave sketch anyway ?