[Info] K8000 velleman et arduino uno

Bonjour la communauté,

J'ai recement reçu deux Kit K8000 de chez velleman et je cherchais a piloter ses cartes via le protocole I2C (library wires)

http://www.hekkers.net/domotica/Images/DSC_3907.JPG
http://www.jlelectroniq.com/mag/imgN/k8000_t.jpg

Je voulais partager mon projet qui pour l'instant n'est qu'en beta test mais fonctionne a 90%

Tout d'abord j'ai installer un module Ethernet pour lire les états via le net a distance, car j'aimerais a l'avenir l'utilisé pour monter une station météo et une surveillance alarme bâtiment avec différents capteur, porte, fenêtre, PIR.

Je vous propose le code de base pour utiliser déjà les K8000. Il faut savoir que le couplage de plusieurs carte est possible et un scanner I2C pour toujours retrouver les adresses des contrôleurs. ont peut coupler 4 cartes k8000 sur l'arduino et ont peut avoir 64 entrées sorties plus les fonctions convertisseur AD et DA qui en découlent.

#include <SPI.h>
    #include <Ethernet.h>
    #include <Wire.h> 

    byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x11 };
    int K8000[8];

    EthernetServer server(80);
    byte c = 0;
    void setup()
    {       
      bool DHCP = false;
      int i = 0;
      while(DHCP == 0 && i<10) {
         if(Ethernet.begin(mac) == 1){
            DHCP = true;
            i = 10;
         }
         i++;
         delay(2000);
        Wire.begin(); // join i2c bus (address optional for master)
      }
      if(!DHCP){
         Serial.println("DHCP FAILED");
         for(;;);
      }
      server.begin();
    }

void loop()
    {
      // listen for incoming clients
      EthernetClient client = server.available();
      if (client) {
        boolean currentLineIsBlank = true;
        while (client.connected()) {
          if (client.available()) {
            char c = client.read();
            if (c == '\n' && currentLineIsBlank) {
              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: text/html");
              client.println("<html>");
              client.println("<head>");
              client.println("<title>I2C K8000</title>");
              client.println("<meta http-equiv=\"refresh\" content=\"5\">");
              client.println("</head>");
              client.println("<body bgcolor='#666666' text='yellow' link='lime' vlink='lime' alink='red'>");
              client.println("<table align='center' border='1'><tr><td width='938' colspan='4'><p align='center'><font size='3' face='Tahoma'><b>I2C K8000</b></font></p></td></tr></table>");
              client.println("<hr>");
            
              byte error, address;
  int nDevices;

  client.print("Scanning");
  //client.println("
");
  int adr=0;
  nDevices = 0;
  for(address = 0; address <= 127; address++ )
  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      if (address<16)
            Wire.requestFrom((address,HEX), 6);    
            while(Wire.available())   
            { 
            char c = Wire.read(); 
            }
            client.print(c);
            //client.println("
");   
            delay(60);
      K8000[adr]=(address);
      nDevices++;
      adr++;
      client.print("x");
    }
    else if (error==4)
    {
      client.print("Unknow error at address 0x");
      if (address<16)
       client.print("0");
      client.println(address);
    }    
  }
  if (nDevices == 0)
    client.println("No I2C devices found\n");
  else
    client.println(" done\n");
    client.println("<hr>");
   
            
            
            for (int adr = 0; adr < 8; adr++) {
            Wire.beginTransmission(K8000[2]);
            Wire.write(255-K8000[adr]);
            Wire.endTransmission();
            Wire.beginTransmission(K8000[3]);
            Wire.write(255-adr);
            Wire.endTransmission();
            Wire.beginTransmission(K8000[5]);
            Wire.write(255-K8000[adr]);
            Wire.endTransmission();
            Wire.beginTransmission(K8000[4]);
            Wire.write(255-adr);
            Wire.endTransmission();
            client.print("I2C input ");
            client.print(K8000[adr]);
            client.print(" value is ");
            Wire.requestFrom(K8000[adr], 6);  
            while(Wire.available())    
            { 
            char c = Wire.read(); 
            }
            client.print(c);
            client.println("
");   
            delay(60);
            }
            client.println("<hr>");  
              // output the value of each analog input pin
              for (int analogChannel = 0; analogChannel < 4; analogChannel++) {
                client.print("analog input ");
                client.print(analogChannel);
                client.print(" is ");
                client.print(analogRead(analogChannel));
                client.println("
");
              }
              break;
            }
            if (c == '\n') {
              currentLineIsBlank = true;
            }
            else if (c != '\r') {
              currentLineIsBlank = false;
            }
          }
        }
        client.println("<hr>");
        client.println("</body></html>");
        delay(1);
        client.stop();
      }
    }

J'ai un soucis ont peut voir dans le code que je scan les tous les contrôleurs pour recup les données mais je n'arrive pas a lire les valeurs

Ceux ou celles qui voient des améliorations possible je suis a l'écoute. Y a toujours moyen de raccourcir certaine choses.... l'avenir m'en dira peut être plus....

Merci, bonne lecture

Je suis également propriétaire d'une K8000 qui est en service depuis plusieurs années chez moi.
Elle me permet d'allumer et/ou éteindre des appareils depuis mon serveur.

Ton travail m'intéresse et pourrait peut-être donner une seconde vie à la K8000 ?

De mémoire je sais qu'on ne peux pas avoir les infos de l'état des sorties, je sais qu'on peut envoyer une commande, mais après ce qui ce passe derière on ne maitrise pas. que ça fonctionne ou pas on n'a pas d'infos pour savoir si l'ordre a bien été executé ou pas.

J'attends avec impatience plus d'infos sur le sujet, car ça me dérangerais de devoir la mettre au rebus....

Je suis en ce moment même en train de potasser pour la remplacer par un système arduino, mais si je peux combiner les deux ce sera encore mieux!

Pourrais-tu détailler le montage "hardware" ? Quels pins de l'arduino tu connectes à quel endroit sur la K8000?

Est-il possible de monter une librairie spéciale K8000?

:grin:

bonjour,
peut être une piste avec Stantor http://stantor.free.fr/telechargement.html

Bonjour,

Bien vu Mr infobarquee pour le lien.

En ce qui concerne le système arduino et k8000 je connecte l'arduino sur ses sorties habituel donc A4 et A5 et le GND vers le petit connecteur de la carte K8000 qui est en fait le bus I2C et l'alimentation 5V qui l'on peut recup pour faire fonctionner l'arduino.

Personnellement j'utilise 2 carte K8000 avec mon arduino possibilité de brancher jusqu’à 4 cartes.

Config perso :

http://www.on3vmc.be/images/k8000.jpg

2x k8000 velleman commander en i2c

32 entrées ou sorties
16 dac converters
8 adc converters

En plus des entré analogique de l'arduino et les digitales

En programmation j'ai donc décide d'attribuer carte 01 et carte 02

Au démarrage du programme il scan les adresses du bus I2C comme elle sont toujours dans le même ordre il est simple de definir qui fais quoi de la carte 1 et 2. Par carte ont a si tout va bien ont a 4 adresses I2C.

Qui a dis que l'on ne pouvais pas lire l'état des in/out ? Il suffit pour cela de lire la doc technique du CI PCF8574P pour savoir gérer les signaux de commandes ce que je suis occupé a faire. Leurs envoyer des signaux pour commander des sortie ca fonctionne. la lecture va bientôt arriver.

Attention lorsque l'on utilise les PCF8574p En sortie il faut inverser les signaux car si l'on envoie un 0 en valeur il vous donnera comme résultat que toutes les led du chipset en question seront allumer. donc simplement (255-x) et voila...

Pour les ADC il suffit de recup les Byte de chaque convertisseur a l'adresse du chipset pareil pour le DAC

Je cogite sur le sujet j'ai eu l'occasion de voir quelques sources concernant le K8000 et sur la photo que l'on peut voir lier a ce post les deux carte fonctionne en mode sortie et l'arduino pilote le tout.... je sais que le programme du premier post est une ébauche mais je pense que a plusieurs ont pourrait arriver a quelques choses. Si quelqu'un est spécialiste en bibliothèque pourquoi pas essayer d'en faire une....

Pour l'instant je joue avec la bibliothèque WIRES d'origine de l'arduino et ça a l'air de fonctionner....

Merci pour votre intérêt a ce projet.... essayons de construire quelques choses avec nos recup....

Pour commencer raccorder vos cartes K8000 a l'arduino par le bus I2C via le petit connecteur de la K8000 la borne

SCL > Arduino A5
SDA > Arduino A4
GDN > Arduino GND

Ensuite si cela est bien raccordé tu test ce programme :

// --------------------------------------
// i2c_scanner
//
// 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.
//
// This sketch tests the standard 7-bit addresses
// from 0 to 127. Devices with higher bit address
// might not be seen properly.
//
// Adapted to be as simple as possible by Arduino.cc user Krodal
//
// June 2012
// Using Arduino 1.0.1
//

#include <Wire.h>


void setup()
{
  Wire.begin();

  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}


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

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

  nDevices = 0;
  for(address = 0; 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(8000);           // wait 8 seconds for next scan
}

Si tu as un résultat d'adresse note les et voila si tu branche 1 carte tu auras 4 adresses. Et a partir de la il suffit de faire la suite du programme et lire chaque byte de chaque adresses.

Voila l'idée de depart.

Datasheet PCF8574AP => PCF8574AP Fiche Technique Datasheet pdf - Extenseur de 8 bits à distance d'cI/o pour I2C-bus - Philips
Datasheet PCF8591P => PCF8591P Fiche Technique Datasheet pdf - PCF8591; convertisseur de 8 bits ANALOGIQUE-numérique et de D/a - Philips
Datasheet TDA8444P => TDA8444P Datasheet catalog

Et pour finir le schema de l'interface :


Ont peut voir les dipswitch de configuration d'adresse I2C sur chaque contrôleurs. Je n'avais jamais joué avec l'I2C et j'ai appris pas mal de choses avec cette carte....

Est ce que tu peux remettre tes images aux dimensions données dans la charte STP .

Bonjour,

Avec le scan I2C les deux cartes k8000 branchés j'obtiens ceci

Scanning...
I2C device found at address 0x20 !
I2C device found at address 0x22 !
I2C device found at address 0x38 !
I2C device found at address 0x39 !
I2C device found at address 0x3C !
I2C device found at address 0x3D !
I2C device found at address 0x48 !
I2C device found at address 0x4A !
done

Alors la configuration Carte 00 dip swtich 1 sur OFF et 2 sur OFF

Premier PCF8574 => 0x38
Second PCF8574 => 0x39
DAC => 0x20
ADC => 0x48

Si je ne me trompe pas depuis cela ont peut utiliser les commande habituel :

  Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2

  while(Wire.available())    // slave may send less than requested
  {
    char c = Wire.read();    // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
  Wire.beginTransmission(44); // transmit to device #44 (0x2c)
                              // device address is specified in datasheet
  Wire.write(val);             // sends value byte  
  Wire.endTransmission();     // stop transmitting

Attention je pense si j'ai bien vu la datasheet du DAC il faut lui écrire une configuration suivant l'utilisation de celui ci.

Les entrée sortie pour écrire il suffit de lui envoyer la valeur entre 0 et 255 et pour les lires il suffit d'un Wire.read() qui vous renvoie la valeur qui lui est apposé sur ses entrées

Pour le DAC voila une source

//
// Title        : ADDA-Umsetzer mit PCF8591
// Author       : Claus Kühnel
// Date         : 2010-03-14
// Id		: PCF8591.pde
// Version      : 0018
// Micro        : Arduino 2009 w/ ATmega328
//
// DISCLAIMER:
// The author is in no way responsible for any problems or damage caused by
// using this code. Use at your own risk.
//
// LICENSE:
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
// -----------------------------------------------------------------------------------------
// Verbindungen I2C-Analog - Arduino
//             SCL     SDA     GND     +5V
// I2C-Analog  ST1-SCL ST1-SDA ST1-GND ST1-5V
// Arduino     A5      A4      GND     5  
// 
#include <Wire.h>

#define PCF8591 (0x9E >> 1)      // Deviceadresse = 7       
#define PCF8591_DAC_ENABLE 0x40
#define PCF8591_ADC_CH0 0x40
#define PCF8591_ADC_CH1 0x41
#define PCF8591_ADC_CH2 0x42
#define PCF8591_ADC_CH3 0x43

#define PURPOSE "Test of PCF8591"

const byte LED = 13;

byte adc_value, dac_value=0;

void putDAC(byte dac_value)
{
  Wire.beginTransmission(PCF8591);
  Wire.send(PCF8591_DAC_ENABLE);
  Wire.send(dac_value);
  Wire.endTransmission();
}    

byte getADC(byte config)
{
  Wire.beginTransmission(PCF8591);
  Wire.send(config);
  Wire.endTransmission();
  
  Wire.requestFrom((int) PCF8591,2);
  while (Wire.available()) 
  {
    adc_value = Wire.receive();
    adc_value = Wire.receive();
  }
  return adc_value;
}

void setup()
{
  pinMode(LED, OUTPUT);
  Serial.begin(19200);
  Wire.begin();
  Serial.println(PURPOSE);
  Serial.println("DAC\tADC\tADC-DAC");
}

void loop()
{
  putDAC(dac_value);                      // DAC Wert setzen
  digitalWrite(LED, 1);                   // LED ein
  delay(10);
  adc_value = getADC(PCF8591_ADC_CH0);    // ADC Wert von Kanal0 auslesen
  digitalWrite(LED, 0);                   // LED aus
  Serial.print(dac_value, HEX);          // DAC Wert ausgeben
  Serial.print("\t");
  Serial.print(adc_value, HEX);          // ADC Wert ausgeben
  Serial.print("\t");
  Serial.println(dac_value - adc_value);  // Abweichung berechnen und ausgeben
  dac_value++; 
  delay(200);
}

Qui a une idée de base tout ce qui a été donnée ici ?

Intéressant tout ça.
Dès que j'ai fini mon projet sur Arduino, je testerais ces informations pour faire fonctionner la K8000 avec un arduino.
Il y a déjà beaucoup de documentation à lire...
Merci beaucoup pour ces précieuses informations.

As-tu vu ce lien (Aurélien Jarno - New website, or kind of...) concernant le fonctionnement du bus I2C, il y fait référence au PCF8574

Bonjour,

Merci pour l'information du bus I2C, j'ai encore découvert quelques bonne choses en lisant cette page.

Je continue sur l'avancer de mon projet K8000 arduino.... chaque avancé sera disponible....

A la fin ont aura un programme qui j’espère fonctionnera

Bonjours à tous,

Très sympathique le projet, je ne me suis pas pencher plus que cela sur le code.
Cependant, j'ai aussi un projet "dom" en tête et je n'ai pas opté pour la couche ethernet de l'arduino ...

Simple ... c'est un peu limité sus la couche HTTP.
Une piste serais de faire comme moi :slight_smile:

http://arduino.cc/forum/index.php/topic,146427.0.html

Pour ma part, je récupère les valeurs sans problème.
Juste une piste qui contourne le problème ...

Merci pour tes infos,