Go Down

Topic: I2C SCL duty cycle problems (Read 2 times) previous topic - next topic

0xandy

Hi!

I have followed this tutorial step by step : http://www.instructables.com/id/I2C-between-Arduinos/#step1 but the outcome is not good. The communication does not work. I used program called DigiView to analyse the problems and the outcome looks like this : https://lh5.googleusercontent.com/-b71Do8bA-CM/TzEm__GYC6I/AAAAAAAAAbg/uPt4VI5AElg/s912/problem.jpg  . The SCL duty cycle looks very weird. Has anybody ever had this kind of problem? Can it be hardware problem ?

Regards

PaulS

Quote
The SCL duty cycle looks very weird.

The SCL "duty cycle" is the pin clocking out the data. What data are you sending, and why do you think the SCL pin's "duty cycle" is weird?

0xandy

Hi

When I was reading about I2C from Wikipedia, then I found this : http://upload.wikimedia.org/wikipedia/commons/6/64/I2C_data_transfer.svg , from this image I conclude that the duty cycle has to be 50%. here is the code for master:
Code: [Select]
#include <Wire.h>

#define LED_PIN 13
byte x = 0;

void setup()
{
  Wire.begin(); // Start I2C Bus as Master
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

}
void loop()
{
 
  Wire.beginTransmission(9); // transmit to device #9
  Wire.send(x);              // sends x
  Wire.endTransmission();    // stop transmitting
  x++;
  if (x > 5) x=0;
  delay(450);
}


and here is the code for slave:

Code: [Select]


#include <Wire.h>

#define LED_PIN 13
#define LED_1 12
#define LED_2 11

int x;

void setup() {
  Wire.begin(9);                // Start I2C Bus as a Slave (Device Number 9)
  Wire.onReceive(receiveEvent); // register event
 
  pinMode(LED_PIN, OUTPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_2, OUTPUT);
 
  digitalWrite(LED_PIN, LOW);
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
 
  x = 0;
}

void loop() {
  //If value received is 0 blink LED 1
  if (x == 0) {
    digitalWrite(LED_1, HIGH);
    delay(200);
    digitalWrite(LED_1, LOW);
    delay(200);
  }
  //If value received is 1 blink LED 2
  if (x == 1) {
    digitalWrite(LED_2, HIGH);
    delay(200);
    digitalWrite(LED_2, LOW);
    delay(200);
  }
}

void receiveEvent(int howMany) {
  x = Wire.receive();    // receive byte as an integer
}

Nick Gammon


The communication does not work.


What do you mean by that exactly? I tested it and the LEDs flash, but not exactly how you expect. This is because you don't clear x to some other value. In other words, here:

Code: [Select]
void loop() {
  //If value received is 0 blink LED 1
  if (x == 0) {
    digitalWrite(LED_1, HIGH);
    delay(200);
    digitalWrite(LED_1, LOW);
    delay(200);
  }

...


If x is zero you flash the LED. Then next time through the loop x is still zero so it flashes twice. Then the other LED flashes. So apart from that, it works fine.

In practice you wouldn't use delay() because you are potentially making delay so much it will not get the communication from the other end. Or, more accurately, you will miss some.
http://www.gammon.com.au/electronics

0xandy

Hi

In my case none of the leds blinks. There are also problems with Arduino Wire library examples, although I assume that these examples are 100% functioning.. For example  The code for master reader :
Code: [Select]


// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

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

void loop()
{
  Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2

  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);
}


and the code for the slave sender

Code: [Select]

// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onRequest(requestEvent); // register event
}

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  Wire.write("hello "); // respond with message of 6 bytes
                       // as expected by master
}


The master should output "hello " to serial monitor, but it does not. If I edit the code a little bit and add a "Serial.println("abc")" before "Wire.requestFrom(2, 6);" then it prints the "abc" but nothing else. I have been reading about similar problems from the Arduino forum and this one looks exactly like mine : http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1283002358/0 . He' s last post contained a sentece :"I don't bother the forum further I think the problem must be something trivial like lots of novice issues.". Should I leave it aswell? :) Regards

Nick Gammon


In my case none of the leds blinks.


How have you wired it up? Photo perhaps?

Quote
The master should output "hello " to serial monitor, but it does not.


This is version 1.0 of the IDE, right? (because you are using Wire.write() not Wire.send() ).

Anyway, I tested exactly what you posted and it works. You must have a wiring issue.

It all works, don't worry about that. More information about I2C here:

http://gammon.com.au/i2c
http://www.gammon.com.au/electronics

0xandy

Yes Sir, there was a wiring error!! Stupid me, I did not see that I had accidentally connected the SDA resistor to GND.... Now everything is working as it should.. Thanx for prompt replies !

Go Up