Thursday, April 30, 2015

Arduino I2C and Proteus ISIS simulation

 

Hi! today I want to talk about I2C protocol. This protocol was invented by Philips Semiconductor and it is a  multi-slave, multi-master, single-ended, serial computer bus.

This protocol is simple when you know what it does and how it does it. The best way to compare the I2C is with pipes (3 specifically) one is SDA that stands for Serial Data Line and SCL that means Serial Clock Line and last but not least Ground.


The reason why I say 3 is because we always have to have a reference when working on electronic to know what logic zero or a logic one is. Some people talk about only SDA and SCL but you must connect all GND together in order to communicate with the peripherals.

The following pictures how the devices should be connected.

            Connection

 

Each line (SDA and SCL) should be connected to "pull-up" resistors. This is necessary because all devices SDA and SCL connections are "open drain" lines: they can force the voltage on the line to 0V, or "low", but can’t raise it to 5V, or "high". High and low are the electrical representations of the 1s and 0s that are the fundamental components of digital information. Adding these two resistors – and the bus needs only two, no matter how many devices are connected to it – ensures the voltage rises back to 5V without a short circuit.

As you can see in next picture, the master begins the communication by sending the start condition (S). The master continues by sending a unique 7-bit slave device address, with the most significant bit (MSB) first. The eighth bit after the start, read/not-write (), specifies whether the slave is now to receive (0) or to transmit (1). This is followed by an ACK bit issued by the receiver, acknowledging receipt of the previous byte. Then the transmitter (slave or master, as indicated by the bit) transmits a byte of data starting with the MSB. At the end of the byte, the receiver (whether master or slave) issues a new ACK bit. This 9-bit pattern is repeated if more bytes need to be transmitted.


            Bits

 

In a write transaction (slave receiving), when the master is done transmitting all of the data bytes it wants to send, it monitors the last ACK and then issues the stop condition (P). In a read transaction (slave transmitting), the master does not acknowledge the final byte it receives. This tells the slave that its transmission is done. The master then issues the stop condition.

That is some information to have into account when working with I2C but the reality is that Arduino libraries handles everything for us and it makes it easier to talk to other devices via I2C protocol.

the next big thing is the schematic that we need to setup in order to make this happen, we´ll do it in Proteus ISIS and it should look like this:

Schematics

 

As you can see I have in the schematics the following components:

1 x Arduino board

1 x DS1307 Real Time Clock

1 x 16x2 Character LCD display

1 x DS1621 Temperature sensor

2 x 4k7 Resistor

1 x Terminal debugger

1 x I2C debugger

 

After I have connected all the components, I have to tell Proteus how to simulate the code I want the Arduino to run and I did it in the option that says “source code”. You can see the window on the following picture:

 

code

 

This is the code I used:

 

/*
////////////////////////////////////////////////////////////////////////////////////////////////////
AUTOR: JUAN BIONDI FECHA: FEBRERO/2014
PROGRAMA: TERMOMETRO I2C DS1621 VERSION: 1.0
DISPOSITIVO: ATMEL 328P COMPILADOR: AVR
ENTORNO: PROTEUS SIMULADOR: VSM
TARJETA DE PROGRAMACION: DEBUGGER:
////////////////////////////////////////////////////////////////////////////////////////////////////

The DS1621 is an Analog to digital converter for temperature
////////////////////////////////////////////////////////////////////////////////////////////////////
*/


////////////////////////////////////////////////////////////////////////////////////////////////////
// LIBRERIAS //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Let´s include the libraries needed for the skecth
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>

////////////////////////////////////////////////////////////////////////////////////////////////////
// VARIABLES GLOBALES //
////////////////////////////////////////////////////////////////////////////////////////////////////
//Let´s declare the variables needed for the sketch


//int tempC = 0;
//int tempF = 0;
//int direccion = 0x48;

RTC_DS1307 rtc;
LiquidCrystal lcd(12,11,5,4,3,2);

////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCIONES //
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
// CONFIGURACION //
////////////////////////////////////////////////////////////////////////////////////////////////////

void setup()
{
/*
Serial.begin (9600);
//Initiate the Serial communication

Wire.begin(); // Enable the communication
//Let´s cpnfigure the sensor
Wire.beginTransmission(direccion); //Start the device
Wire.write(0xAC); //Write configuration command
Wire.write(0x02); //Continue conversion
Wire.endTransmission(); //Stop the device
Wire.beginTransmission(direccion); 		//Restart the device
Wire.write(0xEE); //Start temperature conversion command
Wire.endTransmission();				//Stop the device
*/

lcd.begin(16,2);
Serial.begin (9600);
Wire.begin();
rtc.begin();

if (! rtc.isrunning())
{
Serial.println("RTC is NOT running");
rtc.adjust(DateTime(__DATE__,__TIME__));
}

}


////////////////////////////////////////////////////////////////////////////////////////////
// PRINCIPAL //
// //
////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{

/*

//Delay to separate the communication and the measuring
delay(100);
Wire.beginTransmission(0x48); //Start the device
Wire.write (0xAA); //Read temperature command
Wire.endTransmission(); //Stop the device
Wire.requestFrom(0x48,1); // We ask for a byte
tempC = Wire.read(); //We save the temperature in centigrades
tempF = tempC * 9 / 5 + 32; //Make the conversion to Faranheit

//Let’s write the data to the terminal windows
Serial.print("Temperatura: ");
Serial.print(tempC);
Serial.print(" C/ ");
Serial.print(tempF);
Serial.println(" F");
*/

lcd.clear();
DateTime now = rtc.now();
lcd.setCursor (0,0);

lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.print('/');
lcd.setCursor (0,1);
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.println();

///////////////////////////////////////////////////////////////////////////////////////

Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print("/");
Serial.print(now.hour(), DEC);
Serial.print("/");
Serial.print(now.minute(), DEC);
Serial.print("/");
Serial.print(now.second(), DEC);
Serial.print("/");
Serial.println();

Serial.print(" since midnight 1/1/1970 = ");
Serial.print(now.unixtime());
Serial.print("s = ");
Serial.print(now.unixtime() / 86400L);
Serial.print("d");

}

 


Once you have the schematic and the code, you can click on the play button to test the code running with the Terminal debugger and the I2C debugger, it should look like this:


Virtual_terminal-I2C_debugger


With these two debuggers you can check the data that it is being sent or received in the two protocols. This is why I spend some time writing about I2C protocol.


If you click on the “Schematic Capture” window you can the the display working and you can also change the simulated temperature.


 


Code_running


 


You can download the files in this link:


https://drive.google.com/folderview?id=0B7dtMeeMPK5rfnJCSVlRVTkxRzdSeHBMWDJ6THVPWmdHdm1kZ3NwNTYzSEJ5b0ZmdlFoMG8&usp=sharing


File name: Temperature_I2C.zip


Version of Proteus 8.1

No comments:

Post a Comment