C++ Code für digitale I2C-Baugruppen

den Code hat Andreas P. freundlicherweise zur Verfügung gestellt.

Ich habe zur Ansteuerung der Bausteine Digital Input und Digital Output ein kleine Demo in C++ für den PI geschrieben.

Auf http://www.netzmafia.de/skripten/hardware/RasPi/RasPi_I2C.html gibt es eine gute Beschreibung zur Installation der Device Treiber und der Development Header für i2c.

Danach müssen nur mehr die Adressen für die Bausteine (Zeile 21 und 22 in ft.cxx im Anhang)

const int DEF_IN = 0x38;            // addr digital Input device

const int DEF_OUT = 0x23;           // addr digital Output device

angepasst und das Programm mit g++ -Wall -O -o ft ft.cxx Compiliert werden.

 

Download ft.cxx als zip-Datei
C++ Code für I2C-DI und I2C-DO Baugruppen (1757 Downloads)

 

#include <bitset>
#include <errno.h>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/i2c-dev.h>
 
// ------------------------------------------------------------------
// I2C-Userspace Driver:
// Compile: g++ -Wall -O -o ft ft.cxx
// ------------------------------------------------------------------
const int SET = 1;
const int CLEAR = 0;
 
const int DEF_IN = 0x38;            // addr digital Input device
const int DEF_OUT = 0x23;           // addr digital Output device
const size_t BUFSIZE  = 1;          // data buffer size for both 8bit
const char *I2CADDR = "/dev/i2c-1"; // I2C device
 
// ------------------------------------------------------------------
// -- C++ Wrapper to communicate with a I2C device.
// -- In case of errors messages are witten to stderr
// ------------------------------------------------------------------
class I2cDevice
{
public:
  /** opens a channel to the device and initiates communication
    * with a device at the given addr.
    * @param name... a user friendly name only used in log output
    * @param addr... the addr of the I2C device
    */
  I2cDevice(const char *name, int addr);
 
  ///closes the channel to the device
  ~I2cDevice();
 
public:
  /// @returns true if the device was initialized succesfully, else false
  bool ok() { return(dev_ > 0); }
 
  /** reads a byte from the device and writes the result to stdout.
    * @param label... a text printed in front of the value.
    *                 e.g. old value
    */
  unsigned char read(const char *label);
 
  /** writes a byte to the device.
    * @param data... the value.
    */
  unsigned char write(unsigned char data);
 
  /** set / clear a bit on the device.
    * this operation writes two lines to stdout
    *      old value: <value>
    *      new value: <value>
    * @param op   ... SET / CLEAR.
    * @param bitNo... the number ot the bit (1..8) to set / clear
    */
  unsigned char write(int op, unsigned int bitNo);
 
private:
  int dev_;
  std::string name_;
};
 
// ------------------------------------------------------------------
// --
// ------------------------------------------------------------------
I2cDevice::I2cDevice(const char *name, int addr)
: name_(name)
{
  // open a channel to the I2C device
  dev_ = open(I2CADDR, O_RDWR);
 
  if (dev_ < 0)
  {
    std::cerr << "Could not load I2C-Module! "
      << I2CADDR << " "
      << strerror(errno) << std::endl;
  }
  else
  {
    // bind channel to the given addr
    if (ioctl(dev_, I2C_SLAVE, addr) < 0)
    {
      std::cerr << name_.c_str()
        << " addr: 0x" << std::hex << addr << std::dec
        << " error: " << strerror(errno) << std::endl;
    }
    else
    {
      std::cout << "Channel #" << dev_
        << " for " << name_.c_str()
        << "0x" << std::hex << addr << std::dec
        << " is open." << std::endl;
    }
  }
}
 
// ------------------------------------------------------------------
// --
// ------------------------------------------------------------------
I2cDevice::~I2cDevice()
{
  if (dev_ > 0)
  {
    close(dev_);
    dev_ = -1;
  }
}
 
 
// ------------------------------------------------------------------
// --
// ------------------------------------------------------------------
unsigned char I2cDevice::write(unsigned char data)
{
  if(::write(dev_, &data, 1) != 1)
  {
    std::cerr << "Device " << name_.c_str()
      << " value: " << std::bitset<8>(data)
      << " write error: " << strerror(errno) << std::endl;
  }
  else
  {
    std::cout << "new value: " << std::bitset<8>(data) << std::endl;
  }
 
  return(data);
}
 
 
// ------------------------------------------------------------------
// --
// ------------------------------------------------------------------
unsigned char I2cDevice::write(int op, unsigned int bitNo)
{
  unsigned char  mask = (unsigned char)(1 << (bitNo - 1));
  unsigned char data = read("old value: ");
 
  if (op == CLEAR)
    data = data & (~mask);
  else
    data = data | mask;
 
  return(write(data));
}
 
 
// ------------------------------------------------------------------
// --
// ------------------------------------------------------------------
unsigned char I2cDevice::read(const char *label)
{
  char data = '\0';
  if (::read(dev_, &data, 1) != 1)
  {
    std::cerr << "Device " << name_.c_str()
      << " value: " << std::bitset<8>(data)
      << " read error: " << strerror(errno) << std::endl;
  }
  else
  {
    std::cout << label << std::bitset<8>(~data) << std::endl;
  }
  return(data);
}
 
 
// ------------------------------------------------------------------
// -- write a menue an read the user input
// ------------------------------------------------------------------
static char getCommand(unsigned int &bitNo)
{
  std::cout << "\n"
    << "\n  r... Read inputs "
    << "\n  s... Set output bit <n>   z.B. s 3"
    << "\n  c... Clear Output bit <n> z.B. c 5"
    << "\n  ----------------------------------"
    << "\n  e... Exit "
    << std:: endl;
 
  char cmd;
  scanf("%c", &cmd);
  if (cmd == 's' || cmd == 'c')
  {
    scanf("%d", &bitNo);
  }
 
  char dummy;
  scanf("%c", &dummy);
 
  return(cmd);
}
 
// ==================================================================
// ==================================================================
// ==================================================================
int main()
{
  // this example communicates to two I2C devices
  I2cDevice dIn("Digital Input", DEF_IN);
  I2cDevice dOut("Digital Output", DEF_OUT);
 
  dIn.write(0xff);           // set all inputs to active
 
  if (dIn.ok() && dOut.ok()) // check if communication is established
  {
    char cmd = ' ';
    do
    {
      unsigned int bitNo;
      cmd = getCommand(bitNo);  // write menue and get user input
 
                                // execute the users input
      switch(cmd)
      {
      case 'r':  dIn.read("Inputs: "); break;
      case 's':  dOut.write(SET, bitNo); break;
      case 'c':  dOut.write(CLEAR, bitNo); break;
      default :  break;
      }
 
    }
    while (cmd != 'e');         // leave if the user pressed e
 
  }
}

 

 

 

Speichere in deinen Favoriten diesen permalink.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert