Onderstaande code van het programma I²C scanner loopt alle 127 adressen van de bus af om te kijken welke chips er op de bus aanwezig zijn. Het adres van de gevonden chip wordt via het serieel kanaal getoond op de seriële monitor.

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>

void setup()
{
  Wire.begin();

  Serial.begin(115200);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

Oefeningen basis 1

Maak een schakeling met een PCF8574AN I/O expander en twee drukknoppen. Wanneer de ene drukknop ingedrukt wordt, moet op de uitgang van de PCF8574 een linkslopende volloper getoond worden. Bij indrukken van de andere knop moet dit een rechtslopende volloper zijn. Maak gebruik van de Wire bibliotheek.

Bepaal eerst welk adres je moet gebruiken om de PCF8574AN aan te sturen.

wat is een volloper?

Een volloper is een lichteffect waarbij eerst de uiterste led gaat branden, daarna de twee uiterste leds, daarna de drie uiterste leds enz... tot alle leds uiteindelijk branden. Daarna gaan alle leds uit en begint alles opnieuw

opgelet! domme gebruikers!

Ga er altijd van uit dat een gebruiker domme dingen gaat doen. Dat betekent dat de gebruiker bijvoorbeeld ook beide knoppen tegelijk kan indrukken. In dat geval moeten alle leds gedoofd blijven.

Je vindt meer info over de Wire bibliotheek en functies op https://www.arduino.cc/en/Reference/Wire

volgend

Oefeningen basis 2

Sluit enkele drukknoppen aan op de PCF8574 en lees hun toestand in op de Leonardo. Geef daarna de toestand weer via de seriële monitor.

Oefeningen gevorderd 1

sluit 4 drukschakelaars en 4 leds aan op de PCF8574. Laat elke schakelaar één led bedienen om de led te kunnen aan- en uitschakelen.

 

bibliotheken en Arduino

Eén van de sterke punten van de Arduino programmeeromgeving is het grote aanbod aan software bibliotheken. Het is mogelijk om grote stukken ingewikkelde code in een bibliotheek onder te brengen. Een andere gebruiker kan dan die bibliotheek integreren in zijn/haar programma en hoeft dus alleen maar de functies te kennen die de bibliotheek aanbiedt. We bekijken als voorbeeld de Wire bibliotheek, waarmee het mogelijk is om I²C elektronica aan te sturen.

bibliotheek toevoegen aan programma.

Om een bibliotheek te gebruiken moet deze eerst toegevoegd zijn aan de Arduino omgeving. De Wire bibliotheek is standaard al geïnstalleerd dus toevoegen is hier niet aan de orde. Om andere bibliotheken toe te voegen is de gemakkelijkste manier om gebruik te maken van de optie "bibiotheken beheren". Deze optie is te vinden via het menu: "Schets->Bibliotheek gebruiken". Via hetzelfde menu kunnen we de bibliotheek Wire kiezen.

In het programma zien we dan in het begin een regel toegevoegd:

#include <Wire.h>

Welke functies allemaal te vinden zijn in deze bibliotheek kan achterhaald worden via de officiële Arduino site. Via "Software->Reference" komen we op het overzicht van alle instructies. Onderaan deze pagina staat een link naar de libraries pagina, waar je een overzicht van de meeste bibliotheken terug kan vinden. Kiezen we daar de Wire bibliotheek, dan komen we op de specifieke pagina voor deze bibliotheek terecht, en zien we rechts een lijst van beschikbare functies.

bibliotheekfuncties gebruiken.

Door de #include instructie zijn al deze functies beschikbaar in ons eigen programma. Voor het aansturen van een PCF8574 is het bijvoorbeeld voldoende om in de setup een Wire.begin() functie op te nemen, en in de loop functie de combinatie

Wire.beginTransmission();
Wire.Write();
Wire.endTransmission();

op te nemen. Elk van deze functies moet natuurlijk nog de nodige parameters meekrijgen. Zo moet de functie beginTransmission() als parameter het adres van de chip meekrijgen waar men naar wil schrijven.

De Write() functie moet dan de waarde meekrijgen die moet geschreven worden.

De endTransmission() functie zorgt er voor dat de I²C-communicatie opgestart en uitgevoerd wordt.

voorbeeldprogramma's.

Elke goeie bibliotheek (ja, er zijn er ook slechte) bevat tevens een aantal voorbeeldprogramma's. Deze kunnen dikwijls als leidraad dienen om te zien hoe de functies best kunnen geïmplementeerd worden. Deze voorbeeldprogramma's zijn terug te vinden via "bestand->voorbeelden->naam van de bibliotheek".

 

 

potentiometer bestuurt looplicht

const int ds = 2;
const int stclk = 3;
const int shclk = 4;
const int analogIn = A0;

void setup()
{
  for(int i=2; i<=4;i++) {
      pinMode(i, OUTPUT);
  }
  pinMode(analogIn,INPUT);
}

void loop()
{
  int patroon=1;
  // bepaal de analoge waarde
  int analogeWaarde = analogRead(analogIn);
  if(analogeWaarde>127) { patroon=2; }
  if(analogeWaarde>255) { patroon=4; }
  if(analogeWaarde>383) { patroon=8; }
  if(analogeWaarde>511) { patroon=16; }
  if(analogeWaarde>639) { patroon=32; }
  if(analogeWaarde>767) { patroon=64; }
  if(analogeWaarde>895) { patroon=128; }
 
  for(int bit=0;bit<8;bit++) {
    if(bitRead(patroon,bit)==1) {
      digitalWrite(ds,HIGH);
    }
    else
    {
      digitalWrite(ds,LOW);
    }
    digitalWrite(shclk,HIGH);
    digitalWrite(shclk,LOW);
  }
  digitalWrite(stclk,HIGH);
  digitalWrite(stclk,LOW);
  // delay(500);
}