Arduino, Raspberry Pi, i2c , pushbutton & led

Hi guys!

I recently tried connecting my Arduino to a Raspberry pi via i2c to control an LED on the Arduino and it was successful. :D Before that I controlled the LED on the Arduino using just a pushbutton... (no i2c or any Raspberry pi). It was also a success.... :) It wasn't much actually when you know how to debounce.

:( The problem I face now is when I try to connect those two methods together. I want to control the LED on the Arduino by using a pushbutton on the Arduino and also should be able to control the same LED through the Raspberry pi via i2c. Actually the python code for the raspberry pi is no big deal but the Arduino sketch. I know what the problem with my current sketch is but I have no idea how to handle it correctly.

I really appreciate if you guys could help me out on this one.(please share the code as well)

I know what the problem with my current sketch is but I have no idea how to handle it correctly.

I would keep it a secret by not posting it. In that way no one will know what the solution is.

Post your code

I recently tried connecting my Arduino to a Raspberry pi via i2c to control an LED on the Arduino and it was successful.

But did you disable the internal pull ups on the Arduino side? If not you will damage your raspberry Pi.

Oh… Here’s the code.

#include <Wire.h>
const int ADDRESS = 0x30;

const int ledRed = 13;
const int button = 2;

boolean lastButton = LOW;
boolean currentButton = LOW;

boolean ledOn = false;

void setup(){
  pinMode(button, INPUT);
  pinMode(ledRed, OUTPUT);
  
Wire.begin(ADDRESS);
Wire.onReceive(processMessage);

Serial.begin(9600);
}

void loop(){
light();
}

void processMessage(int n){
 Serial.println("Processing Message");
char ch = Wire.read();
   if (ch == 'H'){
    digitalWrite(ledRed, HIGH);
    boolean red = digitalRead(ledRed);
    Serial.println(red);
   }else if(ch == 'L'){
     digitalWrite(ledRed, LOW);
     boolean red = digitalRead(ledRed);
    Serial.println(red);
  
}
}

boolean debounce1(boolean last1){
 boolean current1 = digitalRead(button);

if(last1 != current1){
  delay(2);
  current1 = digitalRead(button);
}

return current1;
}

void light(){
 currentButton = debounce1(lastButton);
if (lastButton == LOW && currentButton == HIGH){
 ledOn = !ledOn;
} else{
lastButton = currentButton;
digitalWrite(ledRed,ledOn);
}
}

The process message function is going to be run under an interrupt therefore you should not be using any serial print commands in this routine.

Otherwise you have to say what the code does and what you want it to do. Have you actually read the how to use this forum sticky post?

I just read the “How to” post and looks like I’ve made some mistakes…

#include <Wire.h>
const int ADDRESS = 0x30; //arduino slave address

const int ledRed = 13; //led attached to pin 13 or the default led
const int button = 2; //button attached to pin 2

boolean lastButton = LOW;  //holds the last button state(high or low)
boolean currentButton = LOW; //holds the current button state (high or low)

boolean ledOn = false; //led state (off by default)

void setup(){
  pinMode(button, INPUT);
  pinMode(ledRed, OUTPUT);
  
Wire.begin(ADDRESS); //initialize i2c communication as slave
Wire.onReceive(processMessage); //for receive event


}

void loop(){
light(); // this method is to control the led (on and off) through the button attached to the arduino on pin 2
}

//method for controlling the led via i2c

void processMessage(int n){
 
char ch = Wire.read();
   if (ch == 'H'){
    digitalWrite(ledRed, HIGH);
    boolean red = digitalRead(ledRed);
    
   }else if(ch == 'L'){
     digitalWrite(ledRed, LOW);
     boolean red = digitalRead(ledRed);
    
  
}
}
//button debouncing method
boolean debounce1(boolean last1){
 boolean current1 = digitalRead(button);

if(last1 != current1){
  delay(2);
  current1 = digitalRead(button);
}

return current1;
}

void light(){
 currentButton = debounce1(lastButton);
if (lastButton == LOW && currentButton == HIGH){
 ledOn = !ledOn;
} else{
lastButton = currentButton;
digitalWrite(ledRed,ledOn);
}
}

Thank you for your reply. I have commented what the codes above does for easy reference but you might have figured it out already.
I tried removing the Serial print as you suggested but it didn’t solve the problem.

I think the problem is in my logic. It’s in the light() method. Because the arduino executes the commands correctly but there is no variable to hold the state of the ledRed pin. This is no problem when operating using the button attached to the arduino but it becomes a problem when communicating via i2c.
Actually the LED lights up and turns off at the same time in a fraction of a second when turned on via i2c. So I think the problem is in the light() method and the thing is I have no idea how to address it.

digitalWrite(ledRed, HIGH);
    boolean red = digitalRead(ledRed);

Why read the digital pin you have just set it so you know what it is. As you declare the variable 'red' inside the function processMessage, when that function is exited then that variable goes away so you can never access the variable again.

In the light function all you do when the button is pressed is toggle a variable ledOn. Then you repeatedly write that value to the digital port.

In popular parlance 'you need to get your shit together'. You need to set or clear the ledOn variable in the processMessage function, don't bother writing to the LED that will happen automatically on the next light function call. The lastButton variable needs updating at the end of the light function EVERY time not just when some condition applies.