Area SX srl - Informatica e Microelettronica
0
Torna a: Home Page Soluzioni Microcontrollori Linux Embedded Controllare la scheda SX16-RF con la scheda FOX

Controllare la scheda SX16-RF con la scheda FOX

Data di pubblicazione: 13-07-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 ad una FOX board (http://www.acmesystems.it/) la scheda d'espansione INPUT/OUTPUT SX16 in configurazione stand alone prodotta da AreaSX S.r.l. (http://www.areasx.com) .

La FOX è una board di ridotte dimensioni (66 x 72 mm) basata su micro ETRAX LX100 MCM 4+16 prodotto da AXIS che racchiude al suo interno un sistema Linux embedded dotato di server WEB, FTP, SSH, TELNET ecc.
La scheda FOX è programmabile in linguaggio C e i sorgenti realizzati 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.

Per maggiori informazioni sulla FOX e su come programmarla si consiglia di consultare il sito del produttore: http://www.acmesystems.it/.

La SX16 è una scheda di espansione 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)

    sei uscite a relè che consentono di operare tensioni fino a 125V (30W di carico)  e un sensore di temperatura digitale DS1621.



    La configurazione Stand Alone è caratterizzata dalla presenza, a bordo, di un microprocessore PIC  già programmato con un firmware che semplifica notevolmente l'interfacciamento con un PC o un sistema capace di gestire una comunicazione seriale. Oltre al micro è presente anche un modulo RF modello ER400 che rende la SX16 completamente libera da fili (wireless) che la collegano al sistema che la controlla. L'ER400, prodotto dalla LPRS, è un completo sistema per incapsulare una comunicazione seriale bidirezionale su una portante in radiofrequenza di 433MHz e capace di coprire distanze, in condizioni ottimali, di 250mt.

    Per consentire alla scheda FOX di comunicare via onde radio con la scheda SX16 dobbiamo collegare su una delle due porte USB di cui è dotata la FOX un modulo RF04.



    RF04 è un modulo di ridotte dimensioni che integra un convertitore USB - Seriale della FTDI (compatibile con il Kernel 2.4 e superiore) e un ER400 per trasmettere e ricevere il segnale segnale su portante a 433MHz.

    Il riconoscimento del RF04 da parte del sistema Linux è immediato, il device è visibile ed accessibile alla directory /dev/ con il nome ttyUSB0.

    Nei paragrafi che seguono oltre ad essere descritto il protocollo di comunicazione con la SX16 stand alone, viene fornito un semplice  d'esempio scritto in C che può essere compilato usando l'utility 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

    Comandare i Relè della SX16

    Il protocollo per attivare i relè della SX16, prevede l'invio di un comando composto da sei byte e ritorna altrettanti byte ad operazione eseguita, per indicare lo stato dei relè.



    Nella tabella che segue viene descritto byte a byte il comando da inviare

    Byte

    Descrizione

    Esadecimale

    1

    START

    0x33

    2

    INDIRIZZO

    0x01

    3

    COMANDO

    0x03

    4

    RELE'

    da 0x01 a 0x06

    5

    STATO

    0x00 OFF - 0x01 ON

    6

    ZERO

    0x00

    Analisi dei byte che compongono la risposta inviata dalla SX16 al nostro PC ad operazione completata:

    Byte

    Descrizione

    Esadecimale

    1

    SOR

    0x22

    2

    INDIRIZZO

    0x01

    3

    COMANDO

    0x03

    4

    STATO RELE'

    da 0x00 a 0x63

    5

    ZERO

    0x00

    6

    ZERO

    0x00

    Sorgente d'esempio in C:

  • #include <stdio.h>    
    #include <string.h>   
    #include <unistd.h>   
    #include <fcntl.h>    
    #include <termios.h>  
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <signal.h>
    #include <stdlib.h>

    #define BAUDRATE B19200
    #define DEVICE "/dev/ttyUSB0"
    //COMUNCAZIONE CON SX16
    #define START 0x33
    #define RETURN_START 0x22
    #define ADDR 0x01
    #define WRITE_CMD 0x03
    #define ALL_CMD 0xFF
    #define CH 0x01
    #define ON 0x01
    #define OFF 0x00
    #define ZERO_CHAR 0x00

    ///////////////////////
    //PROTOTIPI
    ///////////////////////
    int read_key();
    int send2sx16 (int _fd, char *cmd2sx16, char *sx16return);

    ///////////////////////
    //FUNZIONI
    ///////////////////////
    //Legge l'input da tastiera
    int read_key(){
        int cmd;
        while ((cmd = getchar())!=0){
          if (cmd!=10) break;
        }
        return cmd;
    }
    //Invia un comando alla SX16
    int send2sx16 (int _fd, char *cmd2sx16, char *sx16return){
      int res;
     
      if (write(_fd, cmd2sx16, 6) < 0) {
        //Invio sulla seriale fallito
        return 0;
      } else {
        //Invio del comando riuscito
        usleep(100000); //sleep per 100mSec
        res = read(_fd,sx16return,6);
        sx16return[res]=0;
        return 1;
      }
    }

    ////////////////////////////////
    //
    // MAIN
    //
    ////////////////////////////////
    int main (int argc, char * argv[]) {
      int fd, res, i;
      int b;
      int line_rele;
      int state_rele;
      struct termios oldtio,newtio;
      char buf[7];
     
      system("clear"); //Pulizia della console
      printf("----------------------------\n");
      printf(" FOX 2 SX16\n\n");
      printf(" Ver: 1.0\n");
      printf(" Author: Daniele De Santis\n");
      printf(" E-Mail:
    [email protected]\n\n");
      printf(" Test RELE'\n");
      printf("----------------------------\n");
     
      printf("Apertua Porta COM\n");
      fd = open(DEVICE, O_RDWR | O_NOCTTY);
      if (fd < 0 ) {
        printf("Device %s non pesente su questo sistema\n\n", DEVICE);
        exit(-1);
      }
      printf("Inizializzazione della comunicazione seriale\n");
     
      tcgetattr(fd,&oldtio); /* Salva i precedenti settaggi */
     
      bzero(&newtio, sizeof(newtio));
      newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
      newtio.c_iflag = IGNPAR;
      newtio.c_oflag = 0;
      newtio.c_lflag = 0;
      newtio.c_cc[VTIME]    = 0;
      newtio.c_cc[VMIN]     = 6;
     
      tcflush(fd, TCIFLUSH);
      tcsetattr(fd,TCSANOW,&newtio);
      //Inizializzazione device seriale terminata
     
     
      printf("Seleziona il relè da settare [1 - 6]\n");
      line_rele = read_key();
      if(line_rele < 49 && line_rele > 54) line_rele=49;
     
      printf("Seleziona lo stato [1 ON - 0 OFF]\n");
      state_rele = read_key();
      if ((state_rele<48) || (state_rele > 49)) state_rele = 48;
      printf ("STATO %d\n", state_rele);
      //FORMATTO IL PACCHETTO DA MANDARE ALLA SERIALE
      buf[0]=0;
      buf[0]=START;
      buf[1]=ADDR;
      buf[2]=WRITE_CMD;
      buf[3]=(line_rele - 48);
      if(state_rele==49)
        buf[4]=ON;
      else
        buf[4]=OFF;
      buf[5]=ZERO_CHAR;
      res=send2sx16 (fd, buf, buf);
      if (res) {
        if((buf[0]==RETURN_START) && (buf[1]==ADDR) && (buf[2]==WRITE_CMD)) {
          printf("----------------------------\n");
          printf(" STATO DEI RELE SULLA SX 16 \n");
          printf("----------------------------\n");
          res = buf[3];
          for (i=0; i<6; i++){
            b = res & 1;
            res >>=1;
           
            if(b){
              printf("RELE' %d   [X]  ON\n", (i + 1) );
            } else {
              printf("RELE' %d   [ ]  OFF\n", (i + 1));
            }
          }
        }
      }
      printf("\nChiusura comunicazione seriale...\n");
      tcsetattr(fd,TCSANOW,&oldtio);
      printf("Arrivederci :)\n");
      close(fd);
      exit(0);
    }

    Eseguendo il programma da una console a video avremo una schermata come quella che segue

    dove sarà possibile selezionare il relè che si vuole settare da 1 a 6 e impostare il valore ON o OFF.A comando terminato a video avremo un lo stato di ogni singolo relè.

    Lettura della temperatura:

    Sulla SX16 è montato un sensore di temperatura di tipo digitale a 8bit della Dallas DS1621 con renge di lettura compreso tra -55 e + 128 con una precisione di 0.5 °C  

    Il comando da inviare per effettuare l'acquisizione della temperatura è il seguente:

    Byte

    Descrizione

    Esadecimale

    1

    START

    0x33

    2

    INDIRIZZO

    0x01

    3

    COMANDO

    0x02

    4

    ZERO

    0x00

    5

    ZERO

    0x00

    6

    ZERO

    0x00

    La risposta che riceveremo dalla SX16 ad acquisizione terminata:

    Byte

    Descrizione

    Esadecimale

    1

    SOR

    0x22

    2

    INDIRIZZO

    0x01

    3

    COMANDO

    0x02

    4

    TEMPERATURA

    da 0x00 a 0xC9

    5

    TEMPERATURA

    0x00 o 0x80

    6

    ZERO

    0x00

    il 4 byte rappresenta la parte intera del valore della temperatura ed è positivo per valori esadecimali che vanno da 0x00 fino a 0x80 superata questa soglia le letture della temperatura sono negative.
    Il quinto byte rappresenta il valore decimale della lettura è può avere solo due valori 0x00 che rappresenta ",0" o 0x80 che rappresenta il mezzo grado ",5".

    Sorgente d'esempio in C:

    #include <stdio.h>    
    #include <string.h>   
    #include <unistd.h>   
    #include <fcntl.h>    
    #include <termios.h>  
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <signal.h>
    #include <stdlib.h>

    #define BAUDRATE B19200
    #define DEVICE "/dev/ttyUSB0"
    #define DELAY_LOOP 10 //In sec
    //COMUNCAZIONE CON SX16
    #define START 0x33
    #define RETURN_START 0x22
    #define ADDR 0x01
    #define WRITE_CMD 0x03
    #define TMP_CMD 0x02
    #define READ_CMD 0x01
    #define ALL_CMD 0xFF
    #define CH 0x01
    #define ON 0x01
    #define OFF 0x00
    #define ZERO_CHAR 0x00
    #define TEST 0x80

    ///////////////////////
    //PROTOTIPI
    ///////////////////////
    int send2sx16 (int _fd, char *cmd2sx16, char *sx16return);

    //Invia un comando alla SX16
    int send2sx16 (int _fd, char *cmd2sx16, char *sx16return){
      int res;
      if (write(_fd, cmd2sx16, 6) < 0) {
        //Invio sulla seriale fallito
        return 0;
      } else {
        //Invio del comando riuscito
        usleep(500000); //sleep per 500mSec
        res = read(_fd,sx16return,6);
        return 1;
      }
    }

    ////////////////////////////////
    //
    // MAIN
    //
    ////////////////////////////////
    int main (int argc, char * argv[]) {
      int fd, res;
      auto float temp;
      struct termios oldtio,newtio;
      unsigned char buf[20];
     
      system("clear"); //Pulizia della console
      printf("Apertua Porta COM\n");
      fd = open(DEVICE, O_RDWR | O_NOCTTY);
      if (fd < 0 ) {
        printf("Device %s non pesente su questo sistema\n\n", DEVICE);
        exit(-1);
      }
      printf("Inizializzazione della comunicazione seriale\n");
      tcgetattr(fd,&oldtio); /* Salva i precedenti settaggi */
     
      bzero(&newtio, sizeof(newtio));
      newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
      newtio.c_iflag = IGNPAR;
      newtio.c_oflag = 0;
      newtio.c_lflag = 0;
      newtio.c_cc[VTIME]    = 0;
      newtio.c_cc[VMIN]     = 5;
     
      tcflush(fd, TCIFLUSH);
      tcsetattr(fd,TCSANOW,&newtio);
      //Inizializzazione device seriale terminata
      while (1){
        system("clear");
        //FORMATTO IL PACCHETTO DA MANDARE ALLA SERIALE
        buf[0]=0;
        buf[0]=START;
        buf[1]=ADDR;
        buf[2]=TMP_CMD;
        buf[3]=ZERO_CHAR;
        buf[4]=ZERO_CHAR;
        buf[5]=ZERO_CHAR;
        res=send2sx16 (fd, buf, buf);
        if (res) {
          if((buf[0]==RETURN_START) && (buf[1]==ADDR) && (buf[2]==TMP_CMD)) {
            printf("---------------------------------------\n");
            printf(" FOX 2 SX16\n\n");
            printf(" Ver: 1.0\n");
            printf(" Author: Daniele De Santis\n");
            printf(" E-Mail:
    [email protected]\n\n");
            printf(" LETTURA DELLA TEMPERATURA DALLA SX 16 \n");
            printf("---------------------------------------\n");
            printf("Temperatura letta dal sensore DS1621: ");

            temp=0;
            // Imposto il mezzo grado
            if (buf[4]==0x80) temp=0.5;
            if (buf[3] & 0x80) {
              // Temperatura negativa
              temp+=(!buf[3])+1;
              temp=-temp;
            } else {
              // Temperatura >0
              temp+=buf[3];
            }
            printf("%.2f °C\n", temp);
          }  else {
            printf("ERRORE -Risposta dalla SX16 non valida\n");
          }
          printf("\nCTRL+C per uscire\n");
          usleep(1000000 * DELAY_LOOP);
        } else {
          printf("ERRORE -Comunicazione con il device %s fallito\n", DEVICE);
          exit(-1);
        }
      }
      printf("\nChiusura comunicazione seriale...\n");
      tcsetattr(fd,TCSANOW,&oldtio);
      printf("Arrivederci :)\n");
      close(fd);
      exit(0);
    }

    eseguendo il programma avremo una videata come quella che segue

    Acquisizione dello stato dai 24 ingressi:

    I 24 ingressi sono divisi a blocchi di otto ed ognuno di questi  è caratterizzato da una tipologia d'ingresso specifica.
    I primi otto (punto 1 nella foto che segue) sono di tipo optoisolato, ideali per collegare segnali elettrici con tensioni superiori ai 5V fino ad un massimo di 24V.
    Il secondo blocco (punto 2 nella foto che segue) è composto da ingressi di tipo TTL a su cui è possibile applicare livelli di tensione compresi tra 0V e massimo 5V.  
    Il terzo blocco (punto 3) è identico per quanto riguarda i livelli di tensione al secondo blocco con la sola differenza che su ogni linea è presente un filtro antidisturbo del tipo CLC.

    La lettura dei 24 ingressi viene effettuata con un unico comando il cui protocollo è descritto nella tabella che segue:

    Byte

    Descrizione

    Esadecimale

    1

    START

    0x33

    2

    INDIRIZZO

    0x01

    3

    COMANDO

    0x01

    4

    ZERO

    0x00

    5

    ZERO

    0x00

    6

    ZERO

    0x00

    come risposta dalla SX16 si avrà un pacchetto, sempre di sei byte, rispettante il seguente protocollo:

    Byte

    Descrizione

    Esadecimale

    1

    SOR

    0x22

    2

    INDIRIZZO

    0x01

    3

    COMANDO

    0x01

    4

     INPUT CTC

    da 0x00 a 0xFF

    5

    INPUT TTL

    da 0x00 a 0xFF

    6

    INPUT OPT

    da 0x00 a 0xFF

    Sorgente d'esempio in C:

    #include <stdio.h>    
    #include <string.h>   
    #include <unistd.h>   
    #include <fcntl.h>    
    #include <termios.h>  
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <signal.h>
    #include <stdlib.h>

    #define BAUDRATE B19200
    #define DEVICE "/dev/ttyUSB0"
    #define DELAY_LOOP 10 //In sec
    //COMUNCAZIONE CON SX16
    #define START 0x33
    #define RETURN_START 0x22
    #define ADDR 0x01
    #define WRITE_CMD 0x03
    #define READ_CMD 0x01
    #define ALL_CMD 0xFF
    #define CH 0x01
    #define ON 0x01
    #define OFF 0x00
    #define ZERO_CHAR 0x00

     
    ///////////////////////
    //PROTOTIPI
    ///////////////////////
    int send2sx16 (int _fd, char *cmd2sx16, char *sx16return);

    //Invia un comando alla SX16
    int send2sx16 (int _fd, char *cmd2sx16, char *sx16return){
      int res;
     
      if (write(_fd, cmd2sx16, 6) < 0) {
        //Invio sulla seriale fallito
        return 0;
      } else {
        //Invio del comando riuscito
        usleep(100000); //sleep per 100mSec
        res = read(_fd,sx16return,6);
        sx16return[res]=0;
        return 1;
      }
    }
    ////////////////////////////////
    //
    // MAIN
    //
    ////////////////////////////////
    int main (int argc, char * argv[]) {
      int fd, res, i;
      int b;
     
      struct termios oldtio,newtio;
      char buf[7];
     
      system("clear"); //Pulizia della console
      printf("Apertua Porta COM\n");
      fd = open(DEVICE, O_RDWR | O_NOCTTY);
      if (fd < 0 ) {
        printf("Device %s non pesente su questo sistema\n\n", DEVICE);
        exit(-1);
      }
      printf("Inizializzazione della comunicazione seriale\n");
     
      tcgetattr(fd,&oldtio); /* Salva i precedenti settaggi */
     
      bzero(&newtio, sizeof(newtio));
      newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
      newtio.c_iflag = IGNPAR;
      newtio.c_oflag = 0;
      newtio.c_lflag = 0;
      newtio.c_cc[VTIME]    = 0;
      newtio.c_cc[VMIN]     = 6;
     
      tcflush(fd, TCIFLUSH);
      tcsetattr(fd,TCSANOW,&newtio);
      //Inizializzazione device seriale terminata
      while (1){
        system("clear");
        //FORMATTO IL PACCHETTO DA MANDARE ALLA SERIALE
        buf[0]=0;
        buf[0]=START;
        buf[1]=ADDR;
        buf[2]=READ_CMD;
        buf[3]=ZERO_CHAR;
        buf[4]=ZERO_CHAR;
        buf[5]=ZERO_CHAR;
        res=send2sx16 (fd, buf, buf);
        if (res) {
          if((buf[0]==RETURN_START) && (buf[1]==ADDR) && (buf[2]==READ_CMD)) {
            printf("---------------------------------------\n");
            printf(" FOX 2 SX16\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");

            printf("Stato degli ingressi CLC:\n");
            for (i=0; i<=7; i++){
              b = buf[3] & 1;
              buf[3] >>=1;
              if(b)
                printf("LINEA CLC %d    [X]  ON\n", (i + 1) );
              else
                printf("LINEA CLC %d    [ ]  OFF\n", (i + 1));
            }
            printf("Stato degli ingressi TTL:\n");
            for (i=0; i<=7; i++){
              b = buf[4] & 1;
              buf[4] >>=1;
              if(b)
                printf("LINEA TTL %d    [X]  ON\n", (i + 1) );
              else
                printf("LINEA TTL %d    [ ]  OFF\n", (i + 1));
            }
            printf("Stato degli ingressi OPTOISOLATE:\n");
            for (i=0; i<=7; i++){
              b = buf[5] & 1;
              buf[5] >>=1;
              if(b)
                printf("LINEA OPTO %d   [X]  ON\n", (i + 1) );
              else
                printf("LINEA OPTO %d   [ ]  OFF\n", (i + 1));
            }
           
          }  else {
            printf("ERRORE -Risposta dalla SX16 non valida\n");
          }
          printf("\nCTRL+C per uscire\n");
          usleep(1000000 * DELAY_LOOP);
        } else {
          printf("ERRORE -Comunicazione con il device %s fallito\n", DEVICE);
          exit(-1);
        }
      }
      printf("\nChiusura comunicazione seriale...\n");
      tcsetattr(fd,TCSANOW,&oldtio);
      printf("Arrivederci :)\n");
      close(fd);
      exit(0);
    }

    Sulla console, lanciando il programma, apparirà una videata come a quella che segue

    Per ogni sorgente è possibile modificare il device di lettura cambiando il valore #define DEVICE "/dev/ttyUSB0"


    Segnala questo articolo: 



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

    Data di pubblicazione: 13-07-2005Hits: 68435
    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;SX16-EXT;SX16-EXT-RF;BUN-FOX-18-16;FOX-SX18;SX18;FOX8+32;KIT_RELE_DIN
    Tutti i prezzi indicati sono espressi in Euro con IVA e spese di trasporto escluse. I prezzi si riferiscono al singolo pezzo
    DescrizioneCodicePrezzo
    Per maggiori informazioniRelè di potenza da barra DIN
    Il Kit Relè da barra DIN è la soluzione ideale per controllare carichi con potenza massima di 10A e tensioni fino a 400V tramite le schede: SX16, FLEXOUTPUT e SXPY.

    Caratteristiche tecniche:
    • Tensione bobina: 12V c.c.
    • Corrente massima sui contatti: 10A
    • Tensione massima sui contatti: 400V c.a.
    • Resistenza bobina: 300ohm
    • Isolamento bobina - contatto: 6000V c.a.
    • Contatto unipolare COMUNE N.A. N.C.
    • Montaggio: DIN rail socket
    • Dimensioni: 354x158x75


    Prodotto compliant RoHs
    KIT_RELE_DIN€ 25.00
    Per maggiori informazioniPer maggiori informazioni

    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