Harri Sapto WIJAYA

22 March 2008

Build Your Own I2C Header File

Filed under: microcontroller, tutorial - Administrator @ 1:08 am

In order to keep my blog useful, I create the microcontroller category. So we* can share our knowledge and experience.emoticon

* : I means, myself and readers

Let’s go.

———-

I learn about I2C protocol when I did my academic project of Embedded System lecture, I built a digital phone book. It only device that capable to store and manage some data, that all. (Apologize I can’t include my device photo, imagine it as a device with keypad, LCD display, and some additional buttons).

 

I²C is a multi-master serial computer bus invented by Philips that is used to attach low-speed peripherals to a motherboard, embedded system, or cellphone. The name stands for Inter-Integrated Circuit and is pronounced I-squared-C and also, incorrectly, I-two-C. As of October 1, 2006, no licensing fees are required to implement the I²C protocol. However, fees are still required in order to obtain I²C slave addresses.[1] SMBus is a subset of I²C that defines stricter electrical and protocol conventions. One purpose of SMBus is to promote robustness and interoperability. Accordingly, modern I²C systems incorporate policies and rules from SMBus, and the line between these two standards is often blurred in practice. (ref.: wiki/I2c)

Hardware 

The I2C bus physically consists of 2 active wires and a ground connection. The active wires, called SDA and SCL, are both bi-directional. SDA is the Serial DAta line, and SCL is the Serial CLock line. Every device hooked up to the bus has its own unique address, no matter whether it is an MCU, LCD driver, memory, or ASIC. Each of these chips can act as a receiver and/or transmitter, depending on the functionality. Obviously, an LCD driver is only a receiver, while a memory or I/O chip can be both transmitter and receiver. (ref.: esacademy.com)

I2C bus [figure 1 I2C bus design]

If you wonder why the default state is in high logic, one of the reasons is to prevent voltage drop due to long wire. If the default state is low logic, when device transmit the high logic bit, it’s no guarantee that it will be kept high logic along wire.

Communication 

As you can see in Figure 2, the master begins the communication by issuing 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. 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. (ref.: embedded.com)

I2C protocol  [figure 2 Structur of I2C data protocol]

Let’s Code It 

After introduced how I2C bus is configured and how data protocol is arranged, let’s code it! In my implementation, I use AT89S52 microcontroller and SDCC as C compiler.

From above explanation, so we need to built at least 4 elements, i.e. START bit, ADDRESS byte, ACKNOWLEGDE bit, DATA byte (similar to ADDRESS byte), and STOP bit.

Preparation

Before go to code to produce i2c signal, let’s make some initializations. 

#define    SCL    P3_6
#define    SDA    P3_7
#define    I2C_DELAY    0x0F

That is we allocate two pin for SCL pin and SDA pin, and a delay constant. We will need a delay to tuning the speed, I just use looping method. Notice that another compiler use different way to access bit, e.g. Franklin use P1^0 instead of P1_0 to access bit-0 of port P1.

/* memberi delay pada sinyal I2C */
void i2c_delay(void)
{
    unsigned char i;
    for(i=0;i<I2C_DELAY;i++);
}

START and STOP bits

START bit [figure 3 START bit] STOP bit [figure 4 STOP bit]

Figure 3 show how to geneate a START bit, that is drop the SDA low while SCL is high, then drop the SCL low too. Figure 4 show how to generate a STOP bit, that is rise up SCL while SDA low then rise up SDA too.

So the code to generate such signal is like below.

/* START bit */ 

// SDA = H-to-L saat SCL = H, kemudian LOW-kan keduanya
void i2c_start(void)
{
    if(SCL) SCL = 0; // pastikan LOW
   
    // high-kan dulu keduanya
    SDA = 1;
    SCL = 1;
   
    i2c_delay();
    SDA = 0;
    i2c_delay();
    SCL = 0;
}

/* STOP bit */
// SDA = L-to-H saat SCL = H, kemudian HIGH-kan keduanya
void i2c_stop(void)
{
    if(SCL) SCL = 0;
   
    // low-kan dulu keduanya
    SDA = 0;
   
    i2c_delay();
    SCL = 1;
    i2c_delay();
    SDA = 1;
}

ADDRESS and DATA byte

Once START bit has been sent, then we ready to send ADDRESS byte. ADDRESS and DATA are similar, the different only in purpose, write mode or read mode, relative to slave. In write mode (slave write data into bus), the bit-0 of ADDRESS byte is set to ‘1′; in read mode (slave read data from bus), the bit-0 of ADDRESS byte is set to ‘0′.

So there will be two function, write and read. Figure 5 show how SCL signal in every bits in SDA.

I2C Data byte  [figure 5 Wave form in data transmission]

That is when try to write/red ‘1′ (or ‘0′) bit, rise up (or pull down) SDA while SCL is low, rise up SCL for a while depend on speed then fall it down. When SCL bit is low, SDA changing is allowed. So the code is like below.

/* menulis data I2C */
// kirim dat bit-per-bit, RETURN : bit ACK
bit i2c_write(unsigned char dat)
{
    bit data_bit;
    unsigned char i;
   
    for(i=0;i<8;i++)
    {
        data_bit = dat & 0x80; // ambil MSB
        SDA = data_bit; // kirim
        i2c_clock(); // beri clock pada SCL
        dat = dat<<1; // geser 1 bit ke kiri (arah MSB)
    }
   
    // high-kan kembali kedua wire
    SDA = 1;
    i2c_delay();
    SCL = 1;
    i2c_delay();
   
    data_bit = SDA; // baca sinyal ACK, 0 jika OK
    SCL = 0;
   
    i2c_delay();
   
    return data_bit; // return ACK, 0 jika valid
}

 /* membaca data I2C */
// membaca bit-per-bit, RETURN : byte data
unsigned char i2c_read(void)
{
    bit rd_bit;
    unsigned char i, dat;
    
    dat = 0x00;
    
    for(i=0;i<8;i++)
    {
        i2c_delay();
        SCL = 1; // high-kan, agar SCL = H-to-L
        i2c_delay();
        rd_bit = SDA; // ambil bit
        dat = dat<<1; // geser data
        dat = dat | rd_bit; // ubah bit yg bersesuaian
        SCL = 0; // baca bit selesai, SDA boleh berubah
    }
    
    return dat;    
}

Oops! I skip something, i.e. ACK. It’s ok, now on it’s turn.

ACKnowledge bit

When an address or data byte has been transmitted onto the bus then this must be ACKNOWLEDGED by the slave(s). In case of an address: If the address matches its own then that slave and only that slave will respond to the address with an ACK. In case of a byte transmitted to an already addressed slave then that slave will respond with an ACK as well. The slave that is going to give an ACK pulls the SDA line low immediately after reception of the 8th bit transmitted, or, in case of an address byte, immediately after evaluation of its address. In practical applications this will not be noticeable*. (ref.: esacademy.com)

* : In my project too ;)

Figure 6 show how ACK bit take an action.

ACK bit  [figure 6 ACK bit]

If you need, here below can generate such condition.

/* memberi sinyal ACKnowlegdment*/
// sinyal SDA L-to-H
void i2c_ack()
{
    SDA = 0;
    i2c_delay();
    i2c_clock; // tanda send data
    SDA = 1;
}

void i2c_noack()
{
    SDA = 1;
    i2c_delay();
    i2c_clock();
    SCL = 1;
}

 

Bliss Them 

That’s all! Put them all together in i2c.h for instance, then include it in your application. Here below is a chop of my code to accessing a byte of memory in EEPROM.

#include <i2c.h>
#define    EEPROM_ID    0xA0    // ID eeprom Atmel24C02 + address = 000

unsigned char eeprom_get(unsigned char addr)
{
    unsigned char dat;
   
    i2c_start();        // start bit, mulai I2C
    i2c_write(EEPROM_ID);    // alamati EEPROM AT24Cxx untuk Write
    i2c_write(addr);
   
    i2c_start();
    i2c_write(EEPROM_ID+1);    // alamati EEPROM untuk Read
    dat = i2c_read();    // ambil data
   
    i2c_noack();
    i2c_stop();        // stop i2c bus
   
    return dat;
}

 

Have a nice coding ;) !

14 March 2008

Development of Tele-operation Mobile Robot

Filed under: microcontroller - Administrator @ 1:23 pm

It’s topic of my final project. I built a robot (in car form) that can be controlled from PC through radio frequency (RF). An interesting point (I think) from my robot is we can program the robot without make any modification to the robot itself. It’s possible by using tele-operation concept, i.e. the robot’s brain is the remote computer, so we only need to write program in PC, not "disturb" the robot at all.

As example, I write the program using image processing method so that the robot can follow the only red coloured ball. It’s fun! My robot follow red ball, when I move the ball, he* chase it! So he can play with red ball. I try to confuse him with miscelanious coloured balls, and still he chase for red ball.

*: I assume that my robot is male 

Here below is the abstract of my final project.

Unmanned vehicle, in mobile robot manifestation, is widely used in monitoring and exploration purpose. Also robotics is widely developed field that grow in computer science trend so that it needs high level data processing (many data and fast processing). Generally microcontroller has not enough memory and MIPS (million instructions per second) to perform high level data processing, but a computer is so weight to be embedded into small robot. Therefore, tele-processing robot has been developed in this final project; robot only process motoric motion while data processing is done in separated computer.

Developed robot system consist of (i) host computer with interface hardware and software to the RF transmitter, and (ii) the robot, it consist of body that capable to crossing the rough surface, RF receiver, DC motor controller, power supply, and transmitter wireless camera.

Testing had been done to obtain information about robot’s performance and to test tele-processing ability. Robot can be controlled up to 44.8 m in open space, able to ascend diagonal plane up to 22.2° in elevation and stair-case up to 2.7 cm in height. Program base on image processing for black line follower robot and red ball follower robot had been made to test the tele-processing ability. Robot follows black line and red ball successfully with other four colored balls in background.

 

You can download my complete final project report here.

 

click to enlarge [figure 1 Manual control window]

click to enlarge [figure 2 Environment as seen by robot, also image processing result]

click to enlarge [figure 3 Body of robot, not so bad ;) ]

With hope and courage… 

-academica memoria- 

9 March 2008

catch up using cache

Filed under: tips & tricks - Administrator @ 2:52 am

May be this trick is old, and many people know it already. But, it’s ok, at least keep my blog vibrate ;)

When browsing, you may experience some website displays interesting flash animation, or you watch a video on YouTube, liputan6.com or  something else, but you can’t right click to grab the video. Uh…

I found some softwares offer capabilities to grab flash content in website, one of them i found is free, but only run under IE. But how about video or picture.

Actually, you need no any add-ins softwares but browser. Here I show you how to use mozzila firefox to grab the website contents, without installing any software. This just browser’s habit.

When you browse using firefox (other browser also), the browser "buffering" the contents on your local system (i.e. your computer). So when you watch video, flash animation, view picture, actually these data has saved already on your local. In my computer, firefox cache the website contents here:

C:\Users\Harri Sapto WIJAYA\AppData\Local\Mozilla\Firefox\Profiles\qtbd84b2.default\Cache

in your computer may be slightly different, no problema, just find Cache folder. 

(EDIT,add): For firefox user, there’s easy way to find out the cache folder, just write "about:cache?device=disk" in address bar.

When your browser completed already the buffering process of a video (or flash), you can find it under Cache folder, but unfortunately it’s saved without extension. So what you can do is find the large size file and try to append extention to file name using appropriate extension. Commonly is .avi, .swf, for video and flash. Make sure your explorer display extension (check it out under folder option).

You can try to grab content from YouTube or liputan6.com

How about picture? May you want grab some picture without the owner know what you’ve done. Friendster may be ;)

Because there are so many small size files, it’s hard to find the cache picture. It’s ok, just remove other cache files before you surf to website contains contents you want. May be you don’t want delete them, so just remove to other folder.

click to enlarge [figure 1 Keep the file in red rectangle] 

Remove all files under Cache except file with _CACHE_, I put a red rectangle to indicate on picture above. Now browse the website that contains such as picture that you want, may be http://www.friendster.com/photos/23501xxx/0/238637xxx is good :) , after load completely, back to Cache folder and find new file has created under it.

There is a way to cheat the file’s extension of unextensioned file, just drag-and-drop the file to notepad and find some recognizable information in bytecode jungle. Here below for example. [this way not recommended for large size file (above 1 or 2 MB) or your notepad going to not responding status]

click to enlarge [figure 2 Cheating the extension for unextensioned file]
 

You find some recognizable info, that is JFIF and JPG, both are image file extension. 

So just append appropriate extension, e.g. 0A9D6C30d01.jfif, open it, and…. TADAA….. you got what you want…

click to enlarge [figure 3 Result]
 

You never grab it, because your firefox grab it for you… (you just pick it from almost-trash ;)

 

Hehe, sorry ya chick, fs-mu ku jadikan sample ;)  

 

Have a nice surfing! 

15 February 2008

SDCC, Free C Compiler for MCU

Filed under: microcontroller, tips & tricks - Administrator @ 3:00 pm

SDCC, Small Device C Compiler, is a free C compiler for small device, i.e. microcontroller. Writed firstly by Sandeep Dutta. SDCC is a retargettable, optimizing ANSI - C compiler that targets the Intel 8051, Maxim 80DS390, Zilog Z80 and the Motorola 68HC08 based MCUs. Work is in progress on supporting the Microchip PIC16 and PIC18 series. SDCC is Free Open Source Software, distributed under GNU General Public License (GPL).

… [will be updated later] 

Basic of Microcontroller (part 1)

Filed under: microcontroller, tutorial - Administrator @ 2:49 pm

Microcontroller (or MCU, microcontroller unit), is a computer-on-a-chip [1]. A system could be called a computer if it has at least processor, memory, and input/output (I/O) device; lack one of the three, it never be a computer. Lack of processor, it can not do any logical or arithmetic in order to process the information. Lack of memory, so where the program would take a place. Lack of I/O device, it can’t interact with "outside world", and will be useless, can’t take any advantages from it.

… [will be updated later]

Get free blog up and running in minutes with Blogsome
Theme designed by Alex King