dinsdag 18 september 2012

Interchip communicatie 2: I2C

I2C, uitgesproken als I-kwadraat-C (persoonlijk noem ik het uit gemak I-twee-C en schrijf ik vaak I2C) is een communicatiemethode tussen meerdere IC's. Het is ontwikkeld door Philips in de jaren 70, als goedkope inter-IC-bus. I2C gebruikt een bus-topologie, meerdere IC's kunnen hierop worden aangesloten. Zie ook http://nl.wikipedia.org/wiki/I2C.

De eerste stap.


Als eerste heb ik een eerdere schakeling van stal gehaald, namelijk de ATMega8/LCD-schakeling. Wat deze schakeling doet: de informatie die serieel wordt ontvangen, weergeven op het LCD-scherm.
Zie de Arduino-website voor details omtrent deze schakeling.

Deze schakeling is ook gebruikt in "Interchip communicatie 1: Seriële communicatie". De code die op de ATMega8 draait is eigenlijk gelijk aan het SerialDisplay-voorbeeld dat bij de Arduino-software wordt geleverd:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available()) {
    delay(100);
    lcd.clear();
    while (Serial.available() > 0) {
      lcd.write(Serial.read());
    }
  }
}

of als de LCD zelf ook een I2C-chip heeft (er vanuitgaande dat de LCD een eigen verbinding heeft met de ATMega8):

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
void setup()
{
  lcd.init();                      // initialize the lcd 
  lcd.backlight();
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available()) {
    delay(100);
    lcd.clear();
    while (Serial.available() > 0) {
      lcd.write(Serial.read());
    }
  }
}

(De LiquidCrystal_I2C-libary kan je hier vinden.)

De tweede stap.


Op een breadboard zet ik een schakeling op die de meeste functionaliteiten van een Arduino biedt. Zie hiervoor ook "Setting up an Arduino on a breadboard". Hiervoor heb ik een extern 16MHz kristal, een inductor en een ATMega328 gebruikt. De schakeling ziet er ongeveer uit zoals in onderstaand figuur.



Op de ATMega328 zet ik de code die geinspireerd is op het slave_receiver voorbeeld. Wat deze schakeling doet: Via I2C informatie ontvangen en deze serieel doorsturen naar de ATMega8-schakeling.

#include <Wire.h>
void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop()
{
  delay(100);
}

void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

 De derde stap.

 De derde stap doe ik gewoon op de Arduino UNO. Hierop zetten we de master_writer code:

#include <Wire.h>

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(4); // transmit to device #4
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
}

De Arduino wordt aangelosten op de I2C-bus met poorten A4(SCK) en A5(SDA). De Arduino stuurt nu getallen over de I2C-bus naar de I2C-slave. Deze stuurt ze door middel van seriële communicatie naar de ATMega8, die ze vervolgens weergeeft op het LCD-scherm.

Uitbreiden


Omdat de I2C een bustopologie gebruikt, kunnen meerdere schakelingen aan de bus worden toegevoegd. Zo is het denkbaar om met een vierde schakeling te maken en ook deze te laten reageren op informatie van de I2C-master. Voorbeelden kunnen zijn:
  • een ATMega-schakeling met een sketch o.b.v de Wire-library
  • een ATTiny-schakeling met een sketch o.b.v. de TinyWire-library
  • een PCF8575 of MCP23016 I2C-pin expander met daarachter weer andere mogelijkheden


donderdag 6 september 2012

Interchip communicatie 1: Seriële communicatie

Seriële communicatie voor communicatie tussen chips onderling is de meest eenvoudige methode om interchip communicatie met Arduino te bewerkstelligen. Seriële communicatie heeft als grootste nadeel dat het alleen tussen twee chips kan plaatsvinden. Het heeft als voordeel, dat door de hardware UART op de verschillende ATMega-chips, snel gecommuniceerd kan worden. Tevens kan met de SoftwareSerial ook nog een tweede of derde seriële aangestuurd worden vanaf een ATMega chip, of kan seriële communicatie worden bewerkstelligd op chips zonder hardware UART, zoals de ATTiny-familie.

Seriële communicatie wordt ook door veel andere hardware gebruikt. Diverse draadloze communicatie-hardware is in feite niets anders dan een radiografisch protocol dat de seriële poort verlengt. Voorbeelden hiervan zijn de diverse Bluetooth-modules voor de Arduino en de Xbee.

Bij seriële communicatie vindt de communicatie over twee lijnen plaats. De ene lijn is de RX. Hierover wordt data ontvangen. De tweede lijn is de TX, hierover wordt data verzonden. Deze vorm van communicatie vindt feitelijk ook plaats tussen de Arduino en de PC, op het moment dat de USB-kabel wordt aangesloten. In dit artikel worden een Arduino UNO en een ATMega8-schakeling gebruikt die via seriële communicatie gegevens uitwisselen.

Eerst de ATMega8-schakeling. Dit is feitelijk een Arduino op een breadboard. Iedere ATMega-chip moet de klus kunnen klaren, ik heb een ATMega8 genomen omdat deze simpelweg nog in ongebruikt in de kast lag.

Op de ATMega8 sluit ik een LCD aan. Mijn LCD heeft een I2C-chip op de achterkant waardoor ik vier draden aansluit: (VCC (+5V), GND, SCK (de kloklijn van de I2C-verbinding) en SDA (de datalijn van de I2C-verbinding). Op de verdere werking van I2C ga ik nu niet in, zie hiervoor wikipedia. Mocht je LCD hebben zonder I2C-chip, kijk dan op de website van Arduino voor aansluitvoorbeelden.

Mijn aansluitingen:


Voor de aanluitingen van de klok en de ATMega, zie de Arduino-site voor meer informatie.

Op de ATMega8 zetten we de sketch uit de voorbeelden van de Arduino-software: de SerialDisplay (let op, voor I2C-aangestuurde LCD's is een andere sketch benodigd). In deze sketch zetten we de baudrate op 9600bps.

Vervolgens nemen we de Arduino UNO. Hierop zetten we de SoftwareSerialExample, we passen de baudrate van beide seriële verbindingen aan in 9600bps Vervolgens sluiten we pin 2 en 3 aan op de TX en de RX van de ATMega8.

Als we dan via de seriële console van de Arduino-software een stukje tekst sturen, stuurt de Arduino dit door naar de ATMega8. (Dat is de interchip-communicatie!) De ATMega8 stuurt dit vervolgens naar de LCD.

Tot slot nog een plaatje van de setup:


Bijgewerkt 8 sept:
Wat grammatica- en spelfouten eruit gehaald


Bijgewerkt 13 sept:
Foto toegevoegd