Results 1 to 7 of 7

Thread: Parallel Port Script kompilieren ?

  1. #1

    Unhappy Parallel Port Script kompilieren ?

    Hallo,

    ich scheitere gerade dabei eine "Relaiskarte" die am Parallel-Port des WL500G
    hängt entsprechend anzusteuern. Ich habe folgenden Source-Code gefunden,
    der diese Aufgabe übernehmen soll gefunden:

    Code:
    /*
     *	Parallel port control program
     *	
     *	Copyright 2002 Stefan Bachmaier <stefan@tracefog.de>
     *
     *	This program is free software; you can redistribute it and/or modify
     *	it under the terms of the GNU General Public License as published by
     *	the Free Software Foundation; either version 2 of the License, or
     *	(at your option) any later version.
     *
     *	This program is distributed in the hope that it will be useful,
     *	but WITHOUT ANY WARRANTY; without even the implied warranty of
     *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *	GNU General Public License for more details.
     *
     *	You should have received a copy of the GNU General Public License
     *	along with this program; if not, write to the Free Software
     *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     *
     */
    
    /*
     This program can read and write the control, data and status bits on the parallel port.
    */
    #include <string.h>
    #include <sys/io.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <getopt.h>
    
    #define DATA 0x378		/*
    				 * printer port base address 
    				 */
    #define STATUS DATA+1		/*
    				 * status bits are 1 byte behind 
    				 */
    #define CONTROL DATA+2		/*
    				 * control bits are 2 bytes behind 
    				 */
    /*
    
    <= in   DB25    Cent    Name of         Reg
    => out  pin     pin     Signal          Bit     Function Notes
    ------  ----    ----    --------        ---     -----------------------------
    =>       2       2      Data 0          D0      Set to least significant data
    =>       3       3      Data 1          D1      ...
    =>       4       4      Data 2          D2      ...
    =>       5       5      Data 3          D3      ...
    =>       6       6      Data 4          D4      ...
    =>       7       7      Data 5          D5      ...
    =>       8       8      Data 6          D6      ...
    =>       9       9      Data 7          D7      Set to most significant data
    
    <=      15      32      /Error          S3+     Low for Error/Offline/PaperEnd
    <=      13      13      Select          S4+     High for printer selected
    <=      12      12      PaperEnd        S5+     High for out of paper
    <=      10      10      /Ack            S6+     IRQ Low Pulse ~ 5 uS, after accept
    <=      11      11      Busy            S7-     High for Busy/Offline/Error
    
    =>       1       1      /Strobe         C0-     Set Low pulse >0.5 us to send
    =>      14      14      /AutoFd         C1-     Set Low to autofeed one line
    =>      16      31      /Init           C2+     Set Low pulse > 50uS to init
    =>      17      36      /SelectIn       C3-     Set Low to select printer
    
    ==      18-25   19-30,  Ground
                   33,17,16
    
    */
    
    
    short data = 0;
    short status = 0;
    short control = 0;
    short x = 0, y = 0;
    
    int c = 0, cr = 0;
    int set_status = 0;
    short quiet_mode = 0;
    
    void printparams ();
    void printbits ();
    
    int main (int argc, char *argv[])
    {
    
    	if (ioperm (DATA, 3, 1))
    	{
    		fprintf (stderr, "Couldn't get the port at %x\ntry it as root.\n", DATA);
    		exit (1);
    	}
    
    	data = inb (DATA);
    	control = inb (CONTROL);
    
    
    	// invert bit 0, 2 and 3 (1101)
    	control ^= 0x0b;
    
    
    	while (1)
    	{
    		cr = getopt (argc, argv, "q");
    		if (cr == -1)
    			break;
    		switch (cr)
    		{
    		case 'q':
    			quiet_mode = 1;
    			break;
    		}
    	}
    
    	if (argc < 2)
    	{
    		printparams ();
    		printbits ();
    		return 0;
    	}
    
    	if ((argc - optind) != 2)
    	{
    		printf ("wrong params!\n");
    		printparams ();
    		return 0;
    	}
    
    	c = argv[optind][0];
    
    	if (argv[optind][1] != 0 || !((c >= '0' && c <= '8') || c == 'q' || c == 'w' || c == 'e' || c == 'r' || c == 't'))
    	{
    		printf ("wrong params!\n");
    		printparams ();
    		return 0;
    	}
    
    	set_status = 1;
    	if (strcmp (argv[optind + 1], "on") != 0)
    	{
    		set_status = 0;
    		if (strcmp (argv[optind + 1], "off") != 0)
    		{
    			set_status = 2;
    			if (strcmp (argv[optind + 1], "toggle") != 0)
    			{
    				printf ("you must provide the status (on|off|toggle)!\n");
    				return 0;
    			}
    		}
    	}
    
    
    	if (!quiet_mode)
    		printf ("Pin #%c, status: %s (%d)\n", c, argv[optind + 1], set_status);
    
    
    	x = -1;
    
    	// DATA pins 2-9
    	if (c == '0')
    	{
    		x = 1;
    	}
    	if (c == '1')
    	{
    		x = 2;
    	}
    	if (c == '2')
    	{
    		x = 4;
    	}
    	if (c == '3')
    	{
    		x = 8;
    	}
    	if (c == '4')
    	{
    		x = 16;
    	}
    	if (c == '5')
    	{
    		x = 32;
    	}
    	if (c == '6')
    	{
    		x = 64;
    	}
    	if (c == '7')
    	{
    		x = 128;
    	}
    	if (c == '8')
    	{
    		x = 255;
    	}
    
    
    	// SELECT, INIT, /AUTO_FEED, /STROBE at pins 17, 16, 14 and 1   
    
    	y = -1;
    
    	if (c == 'q')
    	{
    		y = 15;
    	}
    	if (c == 'w')
    	{
    		y = 1;
    	}
    	if (c == 'e')
    	{
    		y = 2;
    	}
    	if (c == 'r')
    	{
    		y = 4;
    	}
    	if (c == 't')
    	{
    		y = 8;
    	}
    
    	if (x != -1)
    	{
    
    		switch (set_status)
    		{
    		case 0:
    			// put off
    
    			if (x == 255)
    				data = 0;
    			else
    				data = (data & (~x));
    
    			break;
    		case 1:
    			// set to on
    
    			if (x == 255)
    				data = 255;
    			else
    				data = (data | x);
    
    			break;
    		case 2:
    			// toggle
    			if (x == 255)
    			{
    				data ^= 255;
    			}
    			else
    			{
    				// bit schon gesetzt?      falls schon ausmask.  falls nicht einmask.
    				data = ((data & x) == x) ? (data & (~x)) : (data | x);
    			}
    
    			break;
    		default:
    			printf ("you must provide the status (on|off|toggle)!\n");
    			return 0;
    			break;
    		}
    
    		outb (data, DATA);
    
    	}
    
    
    
    	if (y != -1)
    	{
    
    		switch (set_status)
    		{
    		case 0:
    			// put off
    
    			if (y == 0)
    				control = 15;
    			else
    				control = (control & (~y));
    
    			break;
    		case 1:
    			// set to on
    
    			if (y == 15)
    				control = 15;
    			else
    				control = (control | y);
    
    			break;
    		case 2:
    			// toggle
    			if (y == 15)
    			{
    				control ^= 15;
    			}
    			else
    			{
    				// bit schon gesetzt?      falls schon ausmask.  falls nicht einmask.
    				control = ((control & y) == y) ? (control & (~y)) : (control | y);
    			}
    
    			break;
    		default:
    			printf ("you must provide the status (on|off|toggle)!\n");
    			return 0;
    			break;
    		}
    
    		outb (control ^ 0x0b, CONTROL);
    
    	}
    
    
    	if (!quiet_mode)
    		printbits ();
    
    	ioperm (DATA, 3, 0);
    	return 0;
    }
    
    
    void printparams ()
    {
    	printf ("usage: lpic [-q] <pin number> <off|on|toggle>\n");
    	printf ("toggles level of pin\n");
    	printf ("where <number> is from 0-8 (8=all) or one of q,w,e,r,t (q=all), pin on, off or toggle.\n");
    	
    	return;
    }
    
    
    
    void printbits ()
    {
    	int db = 0;
    	int pb = 0;
    	int cb = 0;
    
    
    	status = inb (STATUS);
    	// invert bit 7 (1000000)
    	status ^= 128;
    	
    	
    	if (data & 1)
    		db += 1;
    	if (data & 2)
    		db += 10;
    	if (data & 4)
    		db += 100;
    	if (data & 8)
    		db += 1000;
    	if (data & 16)
    		db += 10000;
    	if (data & 32)
    		db += 100000;
    	if (data & 64)
    		db += 1000000;
    	if (data & 128)
    		db += 10000000;
    
    	if (status & 8)
    		pb += 1;
    	if (status & 16)
    		pb += 10;
    	if (status & 32)
    		pb += 100;
    	if (status & 64)
    		pb += 1000;
    	if (status & 128)
    		pb += 10000;
    
    	if (status & 1)
    		cb += 1;
    	if (control & 2)
    		cb += 10;
    	if (control & 4)
    		cb += 100;
    	if (control & 8)
    		cb += 1000;
    
    	printf ("-------------\n");
    	printf ("Data Bits: [%08d] (%d)\n", db, data);
    	printf ("Data0:\t\t0(pin 2)\t%s\n", data & 1 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("Data1:\t\t1(pin 3)\t%s\n", data & 2 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("Data2:\t\t2(pin 4)\t%s\n", data & 4 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("Data3:\t\t3(pin 5)\t%s\n", data & 8 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("Data4:\t\t4(pin 6)\t%s\n", data & 16 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("Data5:\t\t5(pin 7)\t%s\n", data & 32 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("Data6:\t\t6(pin 8)\t%s\n", data & 64 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("Data7:\t\t7(pin 9)\t%s\n", data & 128 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("-------------\n");
    	printf ("Control Bits: [%04d] (%d)\n", cb, control);
    	printf ("/Strobe:\tw(pin 1)\t%s\n", control & 1 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("/Auto_feed:\te(pin 14)\t%s\n", control & 2 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("Init:\t\tr(pin 16)\t%s\n", control & 4 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("/SelectIn:\tt(pin 17)\t%s\n", control & 8 ? "HIGH\t(+5V)" : "LOW\t(GND)");
    	printf ("-------------\n");
    	printf ("Input Bits: [%05d] (%d)\n", pb, status);
    	printf ("Error:\t\t(pin 15)\t%s\n", status & 8 ? "OPEN\t(N/C)" : "CLOSE\t(GND)");
    	printf ("Select:\t\t(pin 13)\t%s\n", status & 16 ? "OPEN\t(N/C)" : "CLOSE\t(GND)");
    	printf ("Paperend:\t(pin 12)\t%s\n", status & 32 ? "OPEN\t(N/C)" : "CLOSE\t(GND)");
    	printf ("Ack:\t\t(pin 10)\t%s\n", status & 64 ? "OPEN\t(N/C)" : "CLOSE\t(GND)");
    	printf ("/Busy:\t\t(pin 11)\t%s\n", status & 128 ? "OPEN\t(N/C)" : "CLOSE\t(GND)");
    	printf ("-------------\n");
    
    
    	return;
    
    }
    Da ich über keine tiefgehenden Linux Kenntnisse verfüge und auch kein
    weiterer Linux Rechner vorhanden ist, möchte ich das Programm auf dem
    WL500G kompilieren.

    Dazu habe ich die Pakete "optware-devel" und "buildroot" auf dem Router
    installiert.

    Code:
    [admin@WL500G comptest]$ gcc -Wall pport.c -opport
    pport.c:32:20: error: sys/io.h: No such file or directory
    pport.c: In function 'main':
    pport.c:89: warning: implicit declaration of function 'ioperm'
    pport.c:95: warning: implicit declaration of function 'inb'
    pport.c:267: warning: implicit declaration of function 'outb'
    [admin@WL500G comptest]$
    Leider fehlt offensichtlich <sys/io.h>.

    Es wäre schön, wenn mir da jemand weiterhelfen könnte.

    Vielen Dank im Voraus.

    Viele Grüße,
    Markus

  2. #2
    Join Date
    Feb 2007
    Location
    Moscow, Russia
    Posts
    3,805
    Code:
    find /opt/include -name io.h
    zeigt die Liste von io.h Datein im System. Aus dem glaube ich die folgende sehen interessant aus:
    Code:
    /opt/include/asm/io.h
    /opt/include/asm-mips/io.h
    Versuch statt
    Code:
    #include <sys/io.h>
    das:
    Code:
    #include <asm/io.h>
    oder das:
    Code:
    #include <asm-mips/io.h>
    zu nutzen

  3. #3
    Hallo,

    "find" liefert folgendes:

    Code:
    [admin@WL500G comptest]$ find /opt/include -name io.h
    /opt/include/asm/io.h
    /opt/include/asm-alpha/io.h
    /opt/include/asm-arm/arch-anakin/io.h
    /opt/include/asm-arm/arch-arc/io.h
    /opt/include/asm-arm/arch-cl7500/io.h
    /opt/include/asm-arm/arch-clps711x/io.h
    /opt/include/asm-arm/arch-ebsa110/io.h
    /opt/include/asm-arm/arch-ebsa285/io.h
    /opt/include/asm-arm/arch-epxa10db/io.h
    /opt/include/asm-arm/arch-integrator/io.h
    /opt/include/asm-arm/arch-l7200/io.h
    /opt/include/asm-arm/arch-mx1ads/io.h
    /opt/include/asm-arm/arch-nexuspci/io.h
    /opt/include/asm-arm/arch-rpc/io.h
    /opt/include/asm-arm/arch-sa1100/io.h
    /opt/include/asm-arm/arch-shark/io.h
    /opt/include/asm-arm/arch-tbox/io.h
    /opt/include/asm-arm/io.h
    /opt/include/asm-cris/io.h
    /opt/include/asm-i386/io.h
    /opt/include/asm-ia64/io.h
    /opt/include/asm-ia64/sn/io.h
    /opt/include/asm-m68k/io.h
    /opt/include/asm-mips/io.h
    /opt/include/asm-mips64/dec/io.h
    /opt/include/asm-mips64/io.h
    /opt/include/asm-mips64/ip32/io.h
    /opt/include/asm-mips64/mips-boards/io.h
    /opt/include/asm-mips64/sgi/io.h
    /opt/include/asm-mips64/sibyte/io.h
    /opt/include/asm-mips64/sn/io.h
    /opt/include/asm-parisc/io.h
    /opt/include/asm-ppc/io.h
    /opt/include/asm-ppc64/io.h
    /opt/include/asm-s390/io.h
    /opt/include/asm-s390x/io.h
    /opt/include/asm-sh/io.h
    /opt/include/asm-sparc/io.h
    /opt/include/asm-sparc64/io.h
    /opt/include/asm-x86_64/io.h
    [admin@WL500G comptest]$
    Ein erneutes kompilieren mit "#include <asm/io.h>" liefert dann folgendes:
    Code:
    [admin@WL500G comptest]$ gcc -Wall pport.c -opport
    In file included from /opt/include/linux/sched.h:13,
                     from /opt/include/linux/mm.h:4,
                     from /opt/include/linux/pagemap.h:10,
                     from /opt/include/asm/io.h:15,
                     from pport.c:32:
    /opt/include/linux/times.h:5: error: expected specifier-qualifier-list before 'clock_t'
    In file included from /opt/include/linux/sched.h:18,
                     from /opt/include/linux/mm.h:4,
                     from /opt/include/linux/pagemap.h:10,
                     from /opt/include/asm/io.h:15,
                     from pport.c:32:
    /opt/include/asm/semaphore.h:31: error: expected specifier-qualifier-list before 'wait_queue_head_t'
    /opt/include/asm/semaphore.h: In function 'sema_init':
    /opt/include/asm/semaphore.h:67: error: 'struct semaphore' has no member named 'wait'
    .
    .
    .
    Auch mit "#include <asm-mips/io.h>" schauts nicht besser aus:
    Code:
    [admin@WL500G comptest]$ gcc -Wall pport.c -opport
    In file included from /opt/include/linux/sched.h:13,
                     from /opt/include/linux/mm.h:4,
                     from /opt/include/linux/pagemap.h:10,
                     from /opt/include/asm-mips/io.h:15,
                     from pport.c:32:
    /opt/include/linux/times.h:5: error: expected specifier-qualifier-list before 'clock_t'
    In file included from /opt/include/linux/sched.h:18,
                     from /opt/include/linux/mm.h:4,
                     from /opt/include/linux/pagemap.h:10,
                     from /opt/include/asm-mips/io.h:15,
                     from pport.c:32:
    /opt/include/asm/semaphore.h:31: error: expected specifier-qualifier-list before 'wait_queue_head_t'
    /opt/include/asm/semaphore.h: In function 'sema_init':
    /opt/include/asm/semaphore.h:67: error: 'struct semaphore' has no member named 'wait'
    In file included from /opt/include/linux/signal.h:4,
                     from /opt/include/linux/sched.h:26,
                     from /opt/include/linux/mm.h:4,
                     from /opt/include/linux/pagemap.h:10,
                     from /opt/include/asm-mips/io.h:15,
                     from pport.c:32:
    /opt/include/asm/signal.h: At top level:
    /opt/include/asm/signal.h:20: error: conflicting types for 'sigset_t'
    /opt/include/sys/select.h:38: error: previous declaration of 'sigset_t' was here
    In file included from /opt/include/linux/signal.h:5,
                     from /opt/include/linux/sched.h:26,
                     from /opt/include/linux/mm.h:4,
                     from /opt/include/linux/pagemap.h:10,
                     from /opt/include/asm-mips/io.h:15,
                     from pport.c:32:
    .
    .
    .


    Viele Grüße,
    Markus

  4. #4
    Join Date
    Jul 2007
    Location
    Austria
    Posts
    1,336
    Ich vermute das wird nicht mit diesem Programm gehen - z.Bspl. fällt mir auf, dass die "printer port base address" von einer PC-Architektur stammt.


    Zumindest erste Versuche sollten auch auf der Kommandozeile gehen:
    Verwende z.Bspl. mc und suche in /dev einen Eintrag lp0
    dann kannst du mit
    Code:
    echo -e \\101>/dev/lp0
    ein Bitmuster ausgeben (Oktal)

    Referenz: (Bitte lesen)
    http://www.meinews.net/showpost.php?...58&postcount=4

    Mit einem USB zu Parallel-Kabel geht es vielleicht leichter.

    Viel Glück....
    Alle HowTo's, all howto's

    RT-N16 1.9.2.7-rtn-r3121, Samba, VSFTP, Lightthpd, PHP, Perl, MySQL, Serendipity, Aria2web, HDD 640GB
    RT-N66U, 16GB MicroSD/ 2 Partitions, 2,5" HDD 1TB, running with Merlin's FW and Entware, 16 Mbit A1,
    Netgear DGND 3700V2, QNAP TS119PII 4 TB, QNAP TS209 2 TB Raid1, Backup Synology DS107+ 1 TB, HP CP1515n

  5. #5
    Hallo,

    hmm,... ok schade...

    aber ich habe ein anderes Stückchen C-Code im Netz gefunden, das ich für
    meine Bedürfnisse angepasst habe:

    Code:
    // Example on how to access the port lines of WL500g from userspace
    // Martin Schultze 11/2005, schultze@irt.de
    
    // Compile wilth ". ./build.sh"
    
    #include <stdio.h>
    #include <sys/mman.h>   // for mmap()
    #include <fcntl.h>      // for open() switches
    #include <string.h>
    
    #define LPT_ADDR 0x1f800000
    #define FALSE 0
    #define TRUE  1
    
    
    unsigned char* oleg_fn(void)
    // The LPT is mapped into memeory, NOT I/O port (as on x86),
    // therefore we dont't access it by the I/O fn writeb()!
    // Oleg showed us how to map the LPT mem space
    // into our mem space.
    // Use "man mmap" to get more information.
    {
       void *map;
    
       int fd = open("/dev/mem", O_RDWR);
    
       if (fd < 0)
       {
          perror("/dev/mem");
          return NULL;
       }
       map = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, LPT_ADDR);
       if (map == NULL)
       {
          perror("mmap");
          return NULL;
       }
       #ifdef DEBUG
       printf("Device memory mapped ok\n");
       #endif
    
         //base = ((unsigned char *)map) + 0x10;
         return (unsigned char *) (map + 0x10);
    }
    
    void parport_write_data(unsigned char d, unsigned char* base)
    // Write "d" to the data lines addressed by base pointer
    {
       *base = d;
    }
    
    unsigned char parport_read_data(unsigned char* base)
    // Read the data lines addressed by base pointer.
    {
       return *base;
    }
    
    unsigned char parport_read_status(unsigned char* base)
    // Read the status lines, addressed by base pointer + offset.
    {
       return *(base+1);
    }
    
    int bin2dec(char *bin)
    {
      int  b, k, m, n;
      int  len, sum = 0;
      //printf("Test: %s\n", bin);
      len = strlen(bin) - 1;
      for(k = 0; k <= len; k++)
      {
        n = (bin[k] - '0'); // char to numeric value
        if ((n > 1) || (n < 0))
        {
           puts("\n\n ERROR! BINARY has only 1 and 0!\n");
           return (0);
        }
        for(b = 1, m = len; m > k; m--)
        {
           // 1 2 4 8 16 32 64 ... place-values, reversed here
           b *= 2;
        }
        // sum it up
        sum = sum + n * b;
        //printf("%d*%d + ",n,b);  // uncomment to show the way this works
      }
      return(sum);
    }
    
    int getopt(char *argument,char *option)
    {
      if( argument[0]=='-' && argument[1]==option[0] )
        return TRUE;
      return FALSE;
    }
    
    int main(int argc, char *argv[] )
    {
      if ( argc == 1 ) /* argc should be 1 or 2 for correct execution */
      {
        /* We print argv[0] assuming it is the program name */
        printf( "usage: %s -s 10101010 | -r\n", argv[0] );
      }
      else
      {
        if(getopt(argv[1],"s") == TRUE)
        {
          unsigned char *base=NULL;
    
          base = oleg_fn();
          if(base==NULL) return 1;
    
          #ifdef DEBUG
          printf("LPT data lines: 0x%x\n", parport_read_data(base) );
          printf("LPT status lines: 0x%x\n", parport_read_status(base) );
          #endif
    
          parport_write_data(bin2dec(argv[2]), base);
          printf("%s\n", argv[2] );
        }
        if(getopt(argv[1],"r") == TRUE)
        {
          unsigned char *base=NULL;
    
          base = oleg_fn();
          if(base==NULL) return 1;
    
          printf("0x%x\n", parport_read_data(base) );
        }
      }
    return 0;
    }
    Die "PC Relaiskarte K8 IO" von Pollin lässt sich damit ansteuern.

    Vielen Dank & viele Grüße,
    Markus

  6. #6
    Join Date
    Jul 2007
    Location
    Austria
    Posts
    1,336
    Das Progi scheint zu funktionieren. Zumindest am 500gP lässt es sich problemlos compilieren. Leider kann ich es nicht testen, da ich keinen 500g habe.
    Wäre interessant, ob das ausgegebene Bitmuster direkt am Port erhalten bleibt, denn dann kann man auch ganz einfach ein Halbleiterrelais anhängen. Wenn du mir deine Ergebnisse berichtest, nehme ich es in "Alle HowTo's" auf.

    Ein Aufruf bringt jedenfalls die Ausgabe:
    usage: ./parallelprg -s 10101010 | -r

    Freut mich, dass es scheinbar funzt.
    Newbiefan
    Last edited by newbiefan; 16-01-2010 at 21:02.
    Alle HowTo's, all howto's

    RT-N16 1.9.2.7-rtn-r3121, Samba, VSFTP, Lightthpd, PHP, Perl, MySQL, Serendipity, Aria2web, HDD 640GB
    RT-N66U, 16GB MicroSD/ 2 Partitions, 2,5" HDD 1TB, running with Merlin's FW and Entware, 16 Mbit A1,
    Netgear DGND 3700V2, QNAP TS119PII 4 TB, QNAP TS209 2 TB Raid1, Backup Synology DS107+ 1 TB, HP CP1515n

  7. #7
    Hallo,

    so, das Programm funktioniert auf dem WL500G.

    ./pport -s 01010101

    Schaltet z. B. die Relais 2,4,6 und 8 ein, sowie die Relais 1,3,5 und 7 aus.

    ./pport -r liest den Schaltzustand der Relais aus. Der Rückgabe wert ist
    hexadezimal und muss dann halt noch ins Binärformat umgewandelt werden.

    Beim "Einbau" des Programmes in eine PHP Seite (zur Fernsteuerung) bin ich
    noch auf folgendes Problem gestossen:

    Das Programm greift direkt auf /dev/mem zu. Hat man jetzt z. B. thttpd
    installiert, läuft dieser unter dem user "nobody" (siehe /opt/etc/thttpd.conf).
    Ein Zugriff auf /dev/mem benötigt aber root-Rechte. Ändert man den user
    "nobody" in der /opt/etc/thttpd.conf jetzt auf admin (bzw. denjenigen
    Benutzernamen den man in der WL500G Konfiguration angegeben hat),
    dann lässt sich das Programm auch über das Web ausführen.

    Hier noch ein kleinwenig PHP:

    Code:
    <?php
    //DEBUG
    /*
    echo "<pre>";
    print_r($_GET);
    echo "</pre>";
    */
    
    if ($_GET['submit'] == "Absenden"){
      //$bitmuster = hex2bin($rtmp).'0000';
      $bitmuster = '00000000';
      if ($_GET['relais1'] == '1') $bitmuster = substr_replace($bitmuster, '1', 0, 1);  
      if ($_GET['relais2'] == '1') $bitmuster = substr_replace($bitmuster, '1', 1, 1);  
      if ($_GET['relais3'] == '1') $bitmuster = substr_replace($bitmuster, '1', 2, 1);  
      if ($_GET['relais4'] == '1') $bitmuster = substr_replace($bitmuster, '1', 3, 1);  
      if ($_GET['relais5'] == '1') $bitmuster = substr_replace($bitmuster, '1', 4, 1);  
      if ($_GET['relais6'] == '1') $bitmuster = substr_replace($bitmuster, '1', 5, 1);  
      if ($_GET['relais7'] == '1') $bitmuster = substr_replace($bitmuster, '1', 6, 1);  
      if ($_GET['relais8'] == '1') $bitmuster = substr_replace($bitmuster, '1', 7, 1);  
      //echo $bitmuster."<br>";
      //Relais setzen
      exec('/opt/bin/pport -s '.$bitmuster.' 2>&1 1> /dev/null');
      //Bitmuster sichern (Reboot)
      $dateiname = "/opt/bin/pport-boot.sh"; // Name der Datei
      // Datei öffnen,
      // wenn nicht vorhanden dann wird die Datei erstellt.
      $handler = fOpen($dateiname , "w");
      // Dateiinhalt in die Datei schreiben
      fWrite($handler , "#!/bin/sh\n/opt/bin/pport -s ".$bitmuster."\n");
      chmod ($dateiname, 0755 );
      fClose($handler); // Datei schließen
    }
    else {
      $rtmp = exec('/opt/bin/pport -r', $retval);
      //echo "hex: ".$rtmp."<br>";
      $rtmp = hexdec($rtmp);
      //echo "dec: ".$rtmp."<br>";
      $rtmp = decbin($rtmp);
      $bitmuster = $rtmp;
      //echo "bin: ".str_pad($rtmp,8,"0",STR_PAD_LEFT)."<br>";
    }
      
    ?>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
           "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>WL500G IO-K8</title>
    </head>
    <body>
     <form action="./index.php" enctype="multipart/form-data" method="get" name="relais1-8">
      <table border="0" cellpadding="0" cellspacing="0" width="240">
       <tr><td><h4 style="font-family:arial;font-size:12pt;">IO-8-Kanal Settings</h4></td></tr> 
       <tr><hr width="240"></td></tr>
       <tr><td style="font-family:arial;font-size:10pt"><input type="checkbox" name="relais1" value="1" <?if (substr($bitmuster, 0, 1) == '1') echo "checked"?>> Relais 1 - Heizung (1 KW)</td></tr>
       <tr><td style="font-family:arial;font-size:10pt"><input type="checkbox" name="relais2" value="1" <?if (substr($bitmuster, 1, 1) == '1') echo "checked"?>> Relais 2 - Heizung (2 KW)</td></tr>
       <tr><td style="font-family:arial;font-size:10pt"><input type="checkbox" name="relais3" value="1" <?if (substr($bitmuster, 2, 1) == '1') echo "checked"?>> Relais 3 - Heizung (Gas)</td></tr>
       <tr><td style="font-family:arial;font-size:10pt"><input type="checkbox" name="relais4" value="1" <?if (substr($bitmuster, 3, 1) == '1') echo "checked"?>> Relais 4 - Car-PC</td></tr
       <tr><td style="font-family:arial;font-size:10pt"><input type="checkbox" name="relais5" value="1" <?if (substr($bitmuster, 4, 1) == '1') echo "checked"?>> Relais 5 - 12V Versorung</td</tr>
       <tr><td style="font-family:arial;font-size:10pt"><input type="checkbox" name="relais6" value="1" <?if (substr($bitmuster, 5, 1) == '1') echo "checked"?>> Relais 6 - 12V/220V Wandler</d></tr>
       <tr><td style="font-family:arial;font-size:10pt"><input type="checkbox" name="relais7" value="1" <?if (substr($bitmuster, 6, 1) == '1') echo "checked"?>> Relais 7 - Dachklima</td></tr>    <tr><td style="font-family:arial;font-size:10pt"><input type="checkbox" name="relais8" value="1" <?if (substr($bitmuster, 7, 1) == '1') echo "checked"?>> Relais 8 - frei</td></tr>
       <tr><td><hr width="240"></td></tr>
       <tr><td style="font-family:arial;font-size:10pt"><input type="reset"    value="Abbrechen">&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit"   name="submit"  value="Absenden"></td></tr>
       <tr><td><hr width="240"></td></tr>
      </table>
     </form>
    </body>
    </html>
    Bei mir soll das ganze z. B. zur "Fernsteuerung" verschiedener Geräte in
    meinem Wohnmobil verwendet werden...

    Bei jeder Änderung der Schaltzustände schreibe ich noch ein kleines
    Shellscript pport-boot.sh. Dieses wird im laufe des Boot-Vorgangs ausgeführt,
    und stellt sicher, dass die Relais nach einem "Neustart" des Wl500G wieder dieselben
    Schaltzustände haben wie vorher...

    Viele Grüße,
    Markus
    Last edited by kuchlerm; 17-01-2010 at 12:53.

Similar Threads

  1. transmission 134-1
    By edelknecht in forum German Discussion - Deutsch (DE)
    Replies: 13
    Last Post: 19-09-2008, 09:15

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •