Go Down

Topic: connect pushbutton and led using I2C (Read 2472 times) previous topic - next topic

hi and good morning,
i'm a newbie in embedded programing and arduino, and now, i'm using arduino uno for my study, the problem is, i dont know how/where to begin for i2c,
i already look for tutorial at arduino tutorial/forum and http://www.gammon.com.au/forum/?id=10896, but i don't understand it.

i want to connect arduino 1 and arduino 2, where's arduino 1 have a switch, when the swicth is press it can give a signal to arduino 2 to on the led, when the switch is release the led at arduino 2 will off.

below is my program( i refer from arduino tutorial) :

Master:-

Code: [Select]

#include <Wire.h>

int buttonState = 0;   // variable for reading the pushbutton status
 

void setup()
{
   // initialize the LED pin as an output:
  pinMode(13, OUTPUT);     
  // initialize the pushbutton pin as an input:
  pinMode(2, INPUT); 
  Wire.begin(); // join i2c bus (address optional for master)
 
}


void loop()
{
  buttonState = digitalRead(2);


     if (buttonState == HIGH){
     
         
    // turn LED on:   
      digitalWrite(13,HIGH); 
      Wire.beginTransmission(4); // transmit to device #4
      Wire.send(buttonState);         
      Wire.endTransmission();
     
    }
}



Slave:-

Code: [Select]
#include <Wire.h>

const int ledPin =  12;      // the number of the LED pin

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
  pinMode(ledPin, OUTPUT);
}

void loop()
{
 
  delay(500); //Wait 2 Second before re-excute
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{

  int x = Wire.receive();    // receive byte come un integer
     if (x == HIGH) {   
    // turn LED on:   
      digitalWrite(ledPin, HIGH);
      Serial.println(x);
   
  }
     else {
     // turn LED off:
      digitalWrite(ledPin, LOW);
      Serial.println(x);
   }
}


i really appreciate your help.. thank you :p

Grumpy_Mike

#1
Dec 08, 2011, 11:53 pm Last Edit: Dec 08, 2011, 11:56 pm by Grumpy_Mike Reason: 1
So does this code work If not what does it do? Have you got pull ups on the two lines and are you using the analog inputs 4 & 5 not the digital ones?

1. the program at aduino 1 is master, and arduino 2 is slave, when i push the pushbutton at master(arduino1), nothing happen at slave(i mean no led on at arduino 2,) the led at arduino 1 to indicate if the pushbutton is push at master, and the arduino 2 appear the result with led on or off

2. yes, i connected with analog input 4 and 5 master to slave.

Grumpy_Mike

A few things,
Are the grounds connected together?

The master code sends a HIGH but never sends a LOW.
It also sends lots and lots of HIGHs for as long as the button returns HIGH.
How are the buttons wired? It is best to wire then between input and ground and enable the internal pull up resistors.
Also do something at the master end so you can see it is sending something, like toggle the LED.

Did you mean ground at master and slave must be connected together? not just analog 4 and 5 only?

Grumpy_Mike

Quote
Did you mean ground at master and slave must be connected together?

Yes, and put a 4K7 resistor from A4 to +5V and another one from A5 to +5V

Quote
did you mean I2C always send high only?

Yes, the code still does, you need to send LOW when the switch CHANGES to a low state.

Quote
/ i dont understand in this part, it is boolean or math expression?

Boolean IS maths.

Quote
//what != it use be?

It means " not equal to "

Quote
if (digitalRead(BUTTON) != last_state){

Means if what you read is not equalt to what it was last time. Now that code is wrong, you need to set last_state to the current state at the end of the loop. That loop function should look like:-

Code: [Select]
boolean last_state = HIGH;                                         
void loop() {   
int button_state = digitalRead(BUTTON)                                                     
  if (button_state != last_state){                     
    last_state = button_state;
    Serial.println("Start");
    Wire.beginTransmission(ADDRESS);
    Serial.println("Beginning transmission");
    Wire.send(button_state);
    Serial.println("Sent Data");
    Wire.endTransmission();
    Serial.println("Ended transmission");
  }
}


thanks to you guy for explanation.

i just follow this picture/tutorial, so the picture is not correct? i must connected A4 and A5 with resistor and supply is it?



hardware i follow before http://www.gammon.com.au/forum/?id=10896

Grumpy_Mike

Look you are asking for advice and I am giving it.
Yes that photo is insufficient. Why do you think I told you about pull up resistors.
If you don't want to believe me then don't bother asking.
Read the details here if you can understand it.
http://www.dsscircuits.com/articles/effects-of-varying-i2c-pull-up-resistors.html

yes, i believe with you, i don't mean to not trust you,

i appreciate your help, thanks for give and help me to study i2C.

i will follow your guide..

thanks for the help, and sorry for my poor english

Grumpy_Mike

Quote
for this recievEvent function it is compulsary to add void receiveEvent(int howMany)

Yes it is known as a call back function, it is triggered when the I2C circuits detect something arriving.

Quote
and to write the while (Wire.available() > 0)

The while is a command that causes a loop to happen, it is used here to ensure that you gather all the bytes that are currently waiting in the I2C buffer. So it is not compulsory but you need to replace it with something that will do the same job.

Code: [Select]
boolean b = Wire.receive();    // this also
This creates a variable of type boolean to put the received byte from the I2C interface into. It needs to go somewhere and in this example you only need a logic variable (boolean) that is high or low.


kunalk

hello,
i refere following tutorial for i2c co mmunication in arduino uno
http://garagelab.com/profiles/blogs/tutorial-arduino-i-o-port-expander-with-pcf8574

i write data to pcf8574p is 0, then read data from it but getting 255(11111111)
i dont know how i can do the above tutorial work for me

thanks

Grumpy_Mike

You need a pull up resistor on each of the I2C lines. That tutorial has none.
Do the LEDs change state?

kunalk

hello,
i able to write data on pcf8574p port, but unable to read port data of pcf8574p using wire.h wire library in i2c interface. using arduino uno.

Nick Gammon

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up