Newsgroup: it.hobby.elettronica.digitale
Titolo: Quattro relè - quattro comandi

Ciao a tutti,
vorrei interfacciare il mio pc a quattro relè in maniera che ciascuno di 
essi possa lanciare un diverso comando (essendo su Linux vorrei lanciare 
quattro script bash, sotto altri sistemi operativi magari quattro file 
batch...).
Pensavo di collegarmi agli "status" pin (15-13-12-11) della porta 
parallela perche' mi sembrerebbe piu' facile, ma dovrei anche 
"coinvolgere" il pin 10 che genera l'interrupt...
Come software avrei trovato questo che mi sembra adatto (parlo sempre di 
ambiente Linux):
http://xenoscope.net/weblog/2008/09/16/how-to-monitor-parallel-port-
interrupts-in-user-space-in-linux/
Qualcuno potrebbe indicarmi dove trovare qualche schema da poter adattare 
alle mie necessita'?
Grazie anticipatamente a chi vorra' rispondere.
-- 
hamr...@toglimi.quipo.it
ANTI-SPAM: please cut "toglimi." for my real e-mail address.
AMD Athlon64 3200+ Linux 2.6.32-5-amd64 on Debian GNU/Linux squeeze/sid
Registered Linux user #291116 
http://counter.li.org

 alle mie necessita'?
Il primo link restituito da google per "interfaccia parallela rele" mi 
sembra già valido...
http://www.salvitti.it/geo/rele/index.html
Anche perché non c'è molto da inventare.
Devi utilizzare un buffer per pilotare i rele. Quale utilizzare va anche 
a gusti...
Ciao!
Marco

 pilotare i rele. Quale utilizzare va anche a gusti...
Credo che qui serva il contrario: monitorare il cambio di stato dei rele.
Secondo me non conviene impazzire con gli interrupt: se l'input dei 
contatti sono dei rele', un polling va piu' che bene. Sotto Linux, 
occorre impostare il setuserid bit del file eseguibile (chmod u+s) e 
cambiare l'owner a root (o eseguire il programma direttamente da root).
A livello hardware, colleghi la massa o uno dei pin di output dati (2-9) 
con un contatto del rele, e l'altro contatto del rele con uno dei 5 pin 
di input (10->ACK, 11->BUSY, 12->PE, 13->SLCT, 15->ERROR, attenzione che 
il pin 11 [BUSY] viene invertito => 5V==0, 0V==1). Quando il rele' e' 
aperto, i pin non sono collegati e vedono il livello "1", quando il rele' 
e' invece chiuso i pin vedono il livello "0" (per BUSY e' l'opposto).
Il programma e' sulla falsa riga del seguente: quando lo stato del rele' 
passa da aperto a chiuso, viene eseguito il comando indicato nell'array 
"cmd"  (viene gestito anche l'antirimbalzo).
====================================
#include <stdio.h>
#include <sys/io.h>
#define POUT    0x378
/* D7(9) D6(8) D5(7) D4(6) D3(5) D2(4) D1(3) D0(2) */
#define PIN     (POUT+1)
/* -BUSY(11) ACK(10) PE(12) SLCT(13) ERROR(15) xxx xxx xxx */
#define PCTRL   (POUT+2)
/* xxx xxx xxx xxx -SLCTIN(17) INIT(16) -AUTOFD(14) -STROBE(1) */
#define SLEEP_USEC      1000
#define ANTIRIMB_MSEC   100
#define MASK_IN 0x7f
#define NRELE   4
int mask[NRELE]={0x80, 0x20, 0x10, 0x08};
char *cmd[NRELE]={"shell1.sh","shell2.sh","shell3.sh","shell4.sh"};
int main(int argc,char *argv[]) {
  int i,b,last,current;
  int antirimbalzo[NRELE];
  ioperm(POUT,3,1);
  setuid(getuid());
  b=0x00;
  outb(b,POUT);
  for(i=0;i<NRELE;i++) antirimbalzo[i]=0;
  last=inb(PIN) ^ MASK_IN;
  while(1) {
    current=inb(PIN) ^ MASK_IN;
    if(last!=current) {
      printf("%02X\n",current);
      b=current ^ last;
      for(i=0;i<NRELE;i++) {
        if((b & mask[i]) &&
           (current & mask[i]) &&
           antirimbalzo[i]==0) {
          antirimbalzo[i]=ANTIRIMB_MSEC;
          system(cmd[i]);
        }
      }
    }
    last=current;
    for(i=0;i<NRELE;i++) {
      if(antirimbalzo[i]>0) antirimbalzo[i]--;
    }
    usleep(SLEEP_USEC);
  }
}
====================================
Ciao!
  Luca

 Credo che qui serva il contrario: monitorare il cambio di stato dei rele.
Avevo capito che volesse pilotare i rele.
Ok in questo caso cambia poco, ma è corretta la tua osservazione.
Ciao!
Marco

 "cmd"  (viene gestito anche l'antirimbalzo).
[snip]
Se hai scritto questo codice C apposta per me dovrei come minimo offrirti 
una pizza e birra!
Ora però, non essendo un programmatore C (fino ad ora ho solo scritto 
script bash, e neanche tanto complicati), devo prima studiare e capire il 
tuo programmino...
Nel frattempo mi è anche venuta l'idea di smontare una semplice tastiera 
e collegare i miei relè al posto di alcuni tasti, per poi usare un 
programma tipo xbindkeys (anche se non dovrebbe lavorare sotto X ma in 
console) per "mappare" gli script ai tasti...


 console) per "mappare" gli script ai tasti...
Mi sembra piu' complicato, soprattutto dal punto di vista hardware... 
Comunque, se proprio vuoi seguire questa strada, puoi usare il seguente 
programmino che restituisce il codice ascii del carattere premuto, che 
puoi leggere in una shell con $? (il programma e' preso da qui: http://
www.linuxforums.org/forum/programming-scripting/40146-getch-gcc.html
 ):
================================
#include <termios.h>
#include <unistd.h>
int main(void)
{
struct termios oldt,newt;
int ch;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
================================
Ciao!
  Luca

 millisecondo, e la CPU rimane praticamente sempre in idle).
Ciao Luca,
ho provato ad impostare SLEEP_USEC a 10000 anziche' 1000 nel tentativo di 
"alleggerire" il seppur lieve carico del sistema, pero' cosi' capita che 
a volte non rileva la chiusura del contatto...
Poi vorrei chiederti se serve a qualcosa impostare a zero le uscite D0-D7 
o se ci sono controindicazioni nel commentare queste due righe:
b=0x00;
outb(b,POUT);
(In verita' l'ho gia' fatto e *sembrerebbe* funzionare ugualmente bene...)
Infatti dovrei anche gestire tali uscite, contemporaneamente ed 
indipendentemente dagli ingressi S3-S4-S5-S7, e per questo compito stavo 
gia' usando il semplice programma che incollo alla fine di questo post 
(
http://parashell.sourceforge.net
).
In ogni caso il tuo programma funziona egregiamente gia' cosi' com'e' e 
non ti avro' mai ringraziato a sufficienza (se capiti dalle mie parti - 
Bari - pizza, birra, gelato assicurati!).
/*
	* parashell  -- Brett Carroll @ 2002
	* Write data to the parallel port as recieved from the cmdline.
	* Usage: parashell [PORT] [DATA]
	* DATA can be decimal (0...255) or hexadecimal (0x00...0xff)
	* snippets taken from Tomi Engdahl's (
tomi.e...@hut.fi
)
	* Simple parallel port output control program for Linux
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/io.h>
main(int argc, char **argv)
{                    
  int par_data;
  int PORT;
  if (argc!=3) 
      printf("USAGE: parashell [PORT] [DATA]\n ie., parashell 0x378 128
\n"), exit(1); 
 
  sscanf(argv[1],"%i",&PORT); // Get PORT value (ie. 0x378)
  if (sscanf(argv[2],"%i",&par_data)!=1)
      fprintf(stderr, "ERROR: DATA entered is not a number.\n"), exit(1);
  if ((par_data<0) || (par_data>255))
      fprintf(stderr, "ERROR: DATA  must be between 0 and 255\nUSAGE: 
parashell [PORT] [DATA]\n"), exit(1); 	
  if (ioperm(PORT,1,1)) 
      fprintf(stderr, "ERROR: Can't gain access to port %x\n", PORT), exit
(1);
  outb((unsigned char)par_data, PORT); 	// Output Data to the Parallel 
Port
//  inb(PORT);	// Input Parallel Port Data
}
-- 
toglimi....@toglimi.quipo.it
ANTI-SPAM: please cut "toglimi." for my real e-mail address.
Core2 E8400 3.00GHz, Linux 2.6.32-5-amd64 on Debian GNU/Linux 6.0


 (
http://parashell.sourceforge.net
).
Ottimo programma!!! Va benissimo, fa anche una gestione piu' accurata 
degli errori.
Ciao!
  Luca

 essere troppo nel caso di cambio di stato veloci.
Quindi il mio errore era forse di portare SLEEP_USEC a 10000 lasciando 
ANTIRIMB_MSEC a 100. Ora ho impostato SLEEP_USEC a 10000 e ANTIRIMB_MSEC 
a 10 e per le mie necessita' sembra funzionare davvero bene (non ho cambi 
di stato veloci), ed il suo "consumo di risorse" non compare quasi mai in 
"top".
Cosi' come e' stato *molto utile* a me penso che questo tuo programmino 
possa essere utile ad altri hobbysti, hai mai considerato l'idea di 
pubblicarlo su 
sourceforge.net
?
Se mi permettessi un consiglio sul nome, io l'ho chiamato "parapiglia" 
dato che "piglia" i comandi dalla parallela :-)
A presto e grazie mille!
