Area SX srl - Informatica e Microelettronica
0
Torna a: Home Page Soluzioni Microcontrollori Linux Embedded Controllare la SX16-BASE dalla FOX board

Controllare la SX16-BASE dalla FOX board

Data di pubblicazione: 17-08-2005 | Versione Italiana  | (No English Version)The English version of this article does not exists
Parole chiave: - How-To - Linux - Schede Area SX -

In quest'articolo vediamo come collegare la board FOX prodotta da Acme System alla scheda d'espansione SX16, di AreaSX, nella configurazione BASE.

La SX16-BASE si differenzia dai modelli superiori non è dotata: del circuito di stabilizzazione della tensione d'alimentazione, del micro PIC e del modulo RF Easy Radio; ed è stata ideata per essere accoppiata direttamente a schede di sviluppo.
La SX16-BASE è comunque equipaggiata con:

- 24 ingressi di cui

  • 8 ingressi diretti a livelli TTL (0V-5V)
  • 8 ingressi filtrati (filtro CLC) a livelli TTL (0V-5V)
  • 8 ingressi optiosolati a cui è possibile collegare tensioni fino a 24V CC, configurabili anche come ingressi TTL (0V-5V)

- 6 uscite a relè che consentono di operare con tensioni fino a 125V (30W di carico) 
- 1 sensore di temperatura DS1621 con precisione 1/2 grado e range compreso tra -55 a + 128°C

I sistema di comunicazione  tra micro e SX16-BASE è di tipo shift register per il controllo dei relè e la lettura degli ingressi, mentre è di tipo I2C Bus per la lettura della temperatura acquisita dal chip DS1621.

Nei paragrafi che seguono vengono forniti gli schemi dei collegamenti elettrici tra board FOX e SX16-BASE e un esempio di programma in C per comunicare con i blocchi relè, ingressi e temperatura che compongono la scheda d'espansione di AreaSX.

I sorgenti in C d'esempio possono essere compilati tramite apposito SDK, disponibile al momento solo per ambiente Linux, scaricabile gratuitamente dal sito AXIS all'URL: http://developer.axis.com/download/compiler/old/
o in alternativa usando WebCompiler alla pagina http://www.acmesystems.it/?page=webcompiler.

Il file .out che otterremo al termine della compilazione, potrà essere caricato nella memoria RAM o FLASH della FOX via FTP.

Per salvare il nostro programma in RAM, bisogna attraverso un Client FTP, collegarsi alla FOX Board per default all'IP 192.168.0.90, username root e password acme, e trasferire il file .out nella directory /var/state Questa posizione permette di provare i propri programmi ma appena viene tolta l'alimentazione alla scheda, i file caricati vengono cancellati. Per Salvare il nostro programma in FLASH, bisogna collegarsi in FTP come precedentemente visto e salvare il file .out nella directory /mnt/flash/ Per rendere eseguibile in programma bisogna modificare i permessi come segue:

chmod +x programma.out

a questo punto possiamo lanciare il nostro esempio precedendo al nome dell'eseguibile un "./"

./programma.out

Gestione dello stadio relè

Per pilotare i sei relè (2) presenti sulla SX16, è necessario collegare il connettore a vaschetta denominato JP2  (1), visibile nella foto riportata di seguito,

 

alla scheda FOX secondo lo schema riportato nella tabella ed immagine che seguono.

FOX

 

SX16-BASE

OG1 (pin 23)

-->

OCL (pin 6)

OG2 (pin 21)

-->

ODA (pin 8)

OG4 (pin 25)

-->

STR (pin 7)

VCC +5V (pin 12)

---

VCC +5V (pin 9)

GND (pin 40)

---

GND (pin 10)

Terminati i collegamenti elettrici tra le due schede, possiamo alimentare la FOX board con una tensione continua di 5V.

Il sorgente d'esempio  in C che segue va compilato e caricato nella FOX board come descritto all'inizio dell'articolo.

#include "stdio.h"    
#include "unistd.h"   
#include "sys/ioctl.h"
#include "fcntl.h"    
#include "time.h"    
#include "asm/etraxgpio.h"

#define OG1  1<<1
#define OG2  1<<2
#define OG3  1<<3
#define OG4  1<<4
#define CLOCK       ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS),OG1);ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),OG1);
#define STROBE      ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS),OG4);ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),OG4);
#define SET_DATA    ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS),OG2);
#define CLEAR_DATA  ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),OG2);
#define IO_SETGET_OUTPUT  0x13

int read_key(){
    char _buff[4];
    int _ch;
    int _char_count;

    _ch = getchar();
    _char_count = 0;
    while((_ch != 10)  &&  (_char_count < 3)) {
      _buff[_char_count++] = _ch;
      _ch = getchar();
    }
    _buff[_char_count] = 0x00;     
    return atoi(_buff); 
}

int main(void) {
  int fdg;
  int iomask_g;
  int i;
  int outstatus;

  if ((fdg = open("/dev/gpiog", O_RDWR))<0) {
    printf("Open error on /dev/gpiog\n");
    return 1;
  }

  // Set all the availables IOG lines on port G as output
  iomask_g = OG1 | OG2 | OG4;
  ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_OUTPUT),&iomask_g);
  ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),iomask_g); //Tutte le linee a OFF
 
  while(1) {
   system("clear");
   printf("---------------------------------------\n");
   printf(" FOX 2 SX16base\n\n");
   printf(" Ver: 1.0\n");
   printf(" Author: Daniele De Santis\n");
   printf(" E-Mail: [email protected]\n\n");
   printf(" COMANDARE I RELE' SULLA SX 16 \n");
   printf("---------------------------------------\n");
    printf("Valore decimale per comandare i rele' [da 0 a 63]\n");
    outstatus = read_key();
 
  for (i=7;i>=0;i--) {
    if (outstatus & (0x01<<i) ) {
      SET_DATA;
    } else {
      CLEAR_DATA;
    }
    CLOCK;
  }
 
  STROBE;
  }
  close(fdg);
  return 0;
}

Eseguendo il programma da una console a video avremo una schermata dove sarà possibile inserire un valore decimale compreso tra 0 (tutti i relè spenti) a 63 (tutti i relè accesi).

Per esempio, inserendo 10 in decimale, equivalente a 1010 in binario, sulla SX16 saranno attivi soltanto il relè K2 e K4.

Gestione dello stadio input:

La SX16, come precedentemente detto, è dotata di ben 24 linee d'ingresso separate a blocchi di otto come visibile in foto

otto ingressi optiosolati (vedi foto punto 2) a cui è possibile collegare tensioni fino a 24V CC
otto ingressi diretti (vedi foto punto 3) a livelli TTL (0V-5V)
e otto ingressi filtrati (vedi foto punto 4) (filtro CLC) a livelli TTL (0V-5V) .

I collegamenti elettrici tra la FOX e la SX16-BASE devono rispettare lo schema che segue

FOX

 

SX16-BASE

OG5 (pin 22)

-->

IPL (pin 5)

IG1 (pin 24)

<--

IDA (pin 4)

OG3 (pin 26)

-->

ICL (pin 3)

VCC +5V (pin 12)

---

VCC +5V (pin 9)

GND (pin 40)

---

GND (pin 10)

Una volta realizzati i collegamenti elettrici ed alimentto la scheda FOX, possiamo compilare e caricare in memoria il programma di test il cui sorgente completo è riportato di seguito:

#include "stdio.h"    
#include "unistd.h"   
#include "sys/ioctl.h"
#include "fcntl.h"    
#include "time.h"    
#include "asm/etraxgpio.h"
#include "stdlib.h"

#define OG5  1<<5
#define OG3  1<<3
#define IG1  1<<1
#define CLOCK       ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),OG3);ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS),OG3);
#define STROBE      ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),OG5);ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS),OG5);
#ifndef IO_SETGET_INPUT
  #define IO_SETGET_INPUT   0x12
#endif
#ifndef IO_SETGET_OUTPUT
  #define IO_SETGET_OUTPUT  0x13
#endif

int main(void) {
  int fdg;
  int iomask_g;
  int i;
  int value;
 
 
if ((fdg = open("/dev/gpiog", O_RDWR))<0) {
    printf("ERRORE di apertura del device /dev/gpiog\n");
    return 1;
  }
 
 
iomask_g = OG5 | OG3;
  ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_OUTPUT),&iomask_g);
  ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),iomask_g); //Tutte le linee a OFF
  iomask_g = IG1;
  ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_INPUT),&iomask_g);

  while(1) {
   system("clear");
   printf("---------------------------------------\n");
   printf(" FOX 2 SX16base\n\n");
   printf(" Ver: 1.0\n");
   printf(" Author: Daniele De Santis\n");
   printf(" E-Mail:
[email protected]\n\n");
   printf(" STATO DELLE LINEE D'INPUT SULLA SX 16 \n");
   printf("---------------------------------------\n");
    STROBE
    for (i=0;i<24;i++) {
      value=ioctl(fdg, _IO(ETRAXGPIO_IOCTYPE, IO_READBITS));
      if (i>=0 && i<=7) {
        if ((value&(IG1))==0) {
          printf("LINEA OPTO %d [X]\n", (8-i));
        } else {
          printf("LINEA OPTO %d [ ]\n", (8-i));
        }
      } else if (i>=8 && i<=15) {
        if ((value&(IG1))==0) {
          printf("LINEA TTL  %d [X]\n", (16-i));
        } else {
          printf("LINEA TTL  %d [ ]\n", (16-i));
        }
      } else if (i>=16 && i<=23) {
        if ((value&(IG1))==0) {
          printf("LINEA RC   %d [X]\n", (24-i));
        } else {
          printf("LINEA RC   %d [ ]\n", (24-i));
        }
      }
      CLOCK
    }
    sleep(5);
  }
  close(fdg);
  return 0;
}

All'esecuzione del programma a video avremo una schermata come quella che segue:

alla chiusura di un contratto vedremo comparire una X tra le parentesi "[ ]" alla fine della riga che descrive il contatto stesso.

Es:
LINEA RC 5 [X]  equivale alla chiusura del 5° ingresso filtrato sulla SX16

Lettura della temperatura:

Su ogni SX16 è montato un sensore digitale di tempetatura DS1621(2) (datasheet) con range di lettura compreso tra -55°C e +125°C.
Il tipo di comunicazione usato dal DS1621 è di tipo I2C bus.

Lo schema dei collegamenti elettrici per controllare il sensore della SX16 sono riportati nella tabella che segue

FOX

 

SX16-BASE

PB7 (pin 37)

-->

SCL (pin 2)

PB6 (pin 38)

<->

SDA (pin 1)

VCC +5V (pin 12)

---

VCC +5V (pin 9)

GND (pin 40)

---

GND (pin 10)

Il sorgente d'esempio riportato di seguito, dopo aver inizializzato il chip DS1621, esegue la lettura ciclica della temperatura.

#include "stdio.h"    
#include "unistd.h"   
#include "sys/ioctl.h"
#include "fcntl.h"    
#include "time.h"    
#include "asm/etraxgpio.h"

#define I2C_DATA_LINE     1<<6
#define I2C_CLOCK_LINE    1<<7
#define IO_SETGET_INPUT   0x12
#define IO_SETGET_OUTPUT  0x13

int i2c_fd;

// Software delay in us
void udelay(int us) {
  int a;
  int b;
  int delayvar=1111;
  for (b=0;b<33;b++) {
    for (a=0;a<us;a++) {
      delayvar*=3;
      delayvar/=3;
    }
  } 
}  

// Get the SDA line state
int i2c_getbit(void) {
  unsigned int value;
  value=ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_READBITS));
  if ((value&(I2C_DATA_LINE))==0)
    return 0;
  else
    return 1;
}

// Set the SDA line state
void i2c_data(int state) {
  if (state==1)
    ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS), I2C_DATA_LINE);
  else
    ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS), I2C_DATA_LINE);
}

// Set the SCL line state
void i2c_clk(int state) {
  if (state==1)
    ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS), I2C_CLOCK_LINE);
  else
    ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS), I2C_CLOCK_LINE);
}

// Set the SDA line as output
void i2c_dir_out(void) {
  int iomask;
  iomask = I2C_DATA_LINE;
  ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_OUTPUT), &iomask);
}

// Set the SDA line as input
void i2c_dir_in(void) {
  int iomask;
  iomask = I2C_DATA_LINE;
  ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_INPUT), &iomask);
}

// Open the GPIOB dev
int i2c_open(void) {
  i2c_fd = open("/dev/gpiob", O_RDWR);
  i2c_data(1);
  i2c_dir_out();
  i2c_clk(1);
  i2c_data(1);
  udelay(100);
  return i2c_fd;
}

// Close the GPIOB dev
void i2c_close(void) {
  close(i2c_fd);
}

// Read a byte from I2C bus and send the ack sequence
unsigned char i2c_inbyte(void) {
  unsigned char value = 0;
  int bitvalue;
  int i;
 
  // Read data byte
  i2c_dir_in();
  for (i=0;i<8;i++) {
    i2c_clk(1);
    udelay(5);
    bitvalue = i2c_getbit();
    value |= bitvalue;
    if (i<7) value <<= 1;
    i2c_clk(0);
    udelay(5);
  }
  // Send Ack
  i2c_dir_out();
  i2c_data(0);
  i2c_clk(1);
  udelay(5);
  i2c_clk(0);
  udelay(200); 
  return value;
}

// Send a start sequence to I2C bus
void i2c_start(void){
  i2c_dir_out();
  i2c_clk(1);
  i2c_data(1);
  udelay(5);
  i2c_data(0);
}

// Send a stop sequence to I2C bus
void i2c_stop(void) {
  i2c_dir_out();
  i2c_clk(1);
  i2c_data(0);
  udelay(5);
  i2c_data(1);
}

// Send a byte to the I2C bus and return the ack sequence from slave
// rtc
// 0 = Nack, 1=Ack
int i2c_outbyte(unsigned char x) {
  int i;
  int ack;

  i2c_clk(0);
  for (i=0;i<8;i++) {
    if (x & 0x80)
      i2c_data(1);
    else
      i2c_data(0);
    i2c_clk(1);
    udelay(5);
    i2c_clk(0);
    udelay(5);
    x <<= 1;
  }
  i2c_data(0);
  i2c_dir_in();
  i2c_clk(1);
  ack=i2c_getbit();
  i2c_clk(0);
  i2c_dir_out();
  if (ack==0)
    return 1;
  else
    return 0;
}

int DS1621Init(unsigned char address){
  i2c_start();
  if (i2c_outbyte(0x90 + (address<<1))==0) {
    printf("NACK received\n");
  }
  if (i2c_outbyte(0xAC)==0) {
    printf("NACK received\n");
  }
  if (i2c_outbyte(0x02)==0) {
    printf("NACK received\n");
  }
  i2c_stop();
  //Avvia la conversione
  i2c_start();
  if (i2c_outbyte(0x90 + (address<<1))==0) {
    printf("NACK received\n");
  }
  if (i2c_outbyte(0xEE)==0) {
    printf("NACK received\n");
  }
  i2c_stop();
}

float DS1621Read(unsigned char address) {
  unsigned char value = 0;
  auto float temp=0;

  i2c_stop();
  //Lettura ultima acquisizione
  i2c_start();
  if (i2c_outbyte(0x90 + (address<<1))==0) {
    printf("NACK received\n");
  }
  if (i2c_outbyte(0xAA)==0) {
    printf("NACK received\n");
  }
  i2c_stop();
  i2c_start();
  if (i2c_outbyte(0x91 + (address<<1))==0) {
    printf("NACK received\n");
  }
  value=i2c_inbyte(); // Current conversion result
  if (value & 0x80) {
    temp+=(!value)+1;
    temp=-temp;
  } else {
    // Temperatura >0
    temp+=value;
  }
  value=i2c_inbyte(); // Current conversion result
  if (value==0x80) temp+=0.5;
  i2c_stop();
  i2c_start();
  i2c_outbyte(0x91 + (address<<1));
  i2c_stop();
  return (temp);
}

//PROGRAMMA PRINCIPALE
int main(void) {

  if (i2c_open()<0) {
    printf("i2c open error\n");
    return 1;
  }

  DS1621Init(0x00);
  sleep(1);
  while(1) {
   system("clear");
   printf("---------------------------------------\n");
   printf(" FOX 2 SX16base\n\n");
   printf(" Ver: 1.0\n");
   printf(" Author: Daniele De Santis\n");
   printf(" E-Mail: [email protected]\n\n");
   printf(" LETTURA DELLA TEMPERATURA SULLA SX 16 \n");
   printf("---------------------------------------\n");
   printf ("Temperatura sulla SX16  %.1f\n", DS1621Read(0x00));
   sleep(2);
  }

  i2c_close();
  return 0;
}

la videata a console

Link utili:

Schema elettrico della SX16-BASE
Piedinatura della FOX board  

Sorgenti:

Tutti i sorgenti visti in quest'articolo FOX_SX16BASE.zip

 


Segnala questo articolo: 



Parole chiave: - How-To - Linux - Schede Area SX -

Data di pubblicazione: 17-08-2005Hits: 63903
I marchi citati sono propriet� dei titolari dei relativi diritti. Le caratteristiche tecniche e i prezzi riportati sono indicativi e soggetti a variazioni senza preavviso. Le foto non hanno valore contrattuale. Nonostante accurate verifiche, il presente documento pu� contenere prezzi o specifiche errati. Area SX si scusa in anticipo e si impegna ad evitare tali imprecisioni.

 Area SX store
In questa sezione puoi ordinare direttamente i prodotti descritti in questo articolo
SX16-BASE;BUN-FOX-18-16;FOX-SX18;SX18,FLEX-OUTPUT;FOX8+32
Tutti i prezzi indicati sono espressi in Euro con IVA e spese di trasporto escluse. I prezzi si riferiscono al singolo pezzo
DescrizioneCodicePrezzo

Rivenditori Social Contatti Condizioni
Area SX s.r.l
Via Stefano Longanesi 25
00146 Roma

Tel: +39.06.99.33.02.57
Fax: +39.06.62.20.27.85
P.IVA 06491151004
Condizioni di vendita
Procedura di rientro in garanzia
Condizioni per i rivenditori