iowarrior-c-programmierung unter linux(1)

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

nomad
Posts: 30
Joined: Tue Dec 11, 2007 5:01 pm
Location: switzerland

iowarrior-c-programmierung unter linux(1)

Post by nomad »

Ref: iowarrior-c-programmierung unter linux(1)

hi,
entschuldigt wenn ich euch schon wieder nerve.
bei mir gehts jetzt um die programmierung eines ersten c-testprogramms
unter linux fuer den iowarrior56.
ich habe gestern im forum, alles durchforstet was fuer eine c-programm
relevant ist.

da ich im forum keine progs speziell fuer linux gefunden habe (nur windows-prog)
habe ich das untenstehende c-prog geschrieben, es kann compiliert werden,
ist aber noch nicht getestet.
werde das heute machen.

Funktion des Programms:
- setzen der bits in einem port (input)
- iowarrior-simpleWrite
- zuruecksetzen aller ports auf <0>

Was ich herausgefunden habe:
1) es werden alle ports (also port0 bis port6) == 7 bytes == 56 bits auf einmal gesetzt
2) das schreiben (write) auf die ports erfolgt fortlaufend beginnend mit port0 bis port6

Grundlagen:

1) in meiner anwendung wird nur geschrieben (ouput)
es ist keine rueckmeldung des iowarrior erforderlich.

2) da ich insgesammt 32 output-bits benoetige,
werden nur port0 bis port3 benutzt. also 4 bytes.

Dazu einige Fragen:

1) um die ports zu testen, wuerde ich gerne eine led-reihe
an die entsprechenden ports anschliessen.
ist das problemlos moeglich?

2) ist das programm ueberhaupt korrekt:

3) im posting "IO-Warrior Ports einzeln ansteuern...
(32 Bit/ULONG)" vom 4.11.2006 von CCrueger

== taucht folgende bemerkung auf:
<Wenn du alle Porte beschreiben willst, muss du die funktion ändern
oder gleich mit IowKitWrite() arbeiten.
da kannst du dann report.Byte[0] bis report.Byte[3] selber setzten,
wenn du alle Ports bewchreiben willst.>

- heisst dass nun: dass report.Byte[0] den Port 0 bis report.Byte[3] den port 3
anspricht
- kann ich da also wenn ich report.Byte[0] anspreche auch gleichzeit die bits setzen?
- beispiel: ULONG bitsPattern0 = 0x10101010

- ich waere froh, wenn ich von Ihnen ein kleines Code-schnippsel bekommen
koennte.
die diese funktion kurz umreist

4) oder waere es sinnvoller das schreiben aller 6 ports wie folgt vorzunehmen:
(port5 port4 port3 port2 port1
-> ULONG bitPorts = 0x 00000000 00000000 10101010 01010101 11110000
port0)
00001111
- port3 - port0 werden von mir benutzt.
(die aufteilung in 8bit seqmente dient nur zur uebersichtlichkeit)

so, das waers fuers erste.

ueber jede hilfe, hinweise, tips und korrekturen wuerde ich mich sehr freuen.
ich brauch im grunde genommen nur einen grundstock, damit ich in den naechsten
tagen das programm weiter entwickeln und testen kann.


hier nun der c-code:

Code: Select all

//=========================================================================// 
//    ioWarriorWrite_10.c 
//    --------------------------------   
//    compile with :                   
//    gcc -Wall -g -liowkit ioWarriorWrite_10.c -o ioWarriorWrite_10      
//                                                                         
//    start with   : ./ioWarriorWrite_10                                   
//                                                                          
//****************************************************************************/
#include "iowkit.h"

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> 
#include <fcntl.h> 
#include <string.h> 
#include <ctype.h> 
#include <setjmp.h> 

#include <unistd.h> 
#include <sys/signal.h> 
#include <sys/types.h> 
#include <errno.h> 

#define _POSIX_SOURCE 1  	  // POSIX compliant source  
#define FALSE 0 
#define TRUE 1 

typedef unsigned char byte; 

int STOP=FALSE; 
int command;
int i;

IOWKIT_HANDLE iows[IOWKIT_MAX_DEVICES];
int i, j;
ULONG bits;
int numIows;
unsigned short sn[9];
char snt[9];
ULONG rc;
DWORD pid;
IOWKIT_HANDLE devHandle;
IOWKIT56_IO_REPORT report56;

ULONG bitsPattern0 = 0x00000001;
ULONG bitsPattern1 = 0x00000010;
ULONG bitsPattern2 = 0x00000100;
ULONG bitsPattern3 = 0x00000011;
ULONG bitsPattern4 = 0x00000111;
ULONG bitsPattern5 = 0x00000110;
ULONG bitsPattern6 = 0x00000101;

ULONG bitsPattern;

/***************************************************************************/ 

// from conio.h
// delay (nnn)
void delay(long millisek)
{
   int mikrosek = millisek*1000;
   struct timeval  timeout;
   
   timeout.tv_sec  = mikrosek / 1000000L;
   timeout.tv_usec = mikrosek % 1000000L;
   select(0, NULL, NULL, NULL, &timeout);
}

void gotoxy(int x, int y) { printf("\033[%d;%dH", y, x); fflush(stdout); }
void clrscr(void)         { printf("\033[H\033[J");      fflush(stdout); }

/******************************************************************************/

// Write simple value
BOOLEAN WriteSimple(IOWKIT_HANDLE devHandle, DWORD value)
  {
     // Init report
     switch(IowKitGetProductId(devHandle))
        { 
           // Write simple value to IOW56
           case IOWKIT_PRODUCT_ID_IOW56:
              memset(&report56, 0xff, sizeof(report56));
              report56.ReportID = 0;
              report56.Bytes[6] = (UCHAR) value;
          
              return IowKitWrite(devHandle, IOW_PIPE_IO_PINS,
			            (PCHAR) &report56, IOWKIT56_IO_REPORT_SIZE) ==          
                                      IOWKIT56_IO_REPORT_SIZE;
           
           default:
           return FALSE;
        }
  }

int initIO_device()
  {
     devHandle = IowKitOpenDevice();
     if(devHandle == NULL)
        {
          printf("Failed to open device\n");
          goto out;
        }
     else
        {
           gotoxy(5,2);
           printf("Open Device is Done\n");
        }   

     // Get number of IOWs in system
     numIows = IowKitGetNumDevs();
     gotoxy(5,3);
     printf("%d IOWs in system\n", numIows);

     // Get all IOW handles
     for(i = 0; i < numIows; i++)
        {
           // Get device handle and init object
           iows[i] = IowKitGetDeviceHandle(i + 1);
           // Get serial number
           IowKitGetSerialNumber(iows[i], sn);
           pid = IowKitGetProductId(iows[i]);

           for(j = 0; j < 9; j++)
	           {
                 snt[j] = sn[j];
                 // printf("%d PID %x, S/N \"%s\"\n", i + 1, (unsigned int) pid, snt);
              }
 
           IowKitSetWriteTimeout(iows[i], 1000);
        }
     gotoxy(5,4);
     printf("Initialitions is Done\n");

     out:
     return(0);
  }

void setAllPortsOff()
  {
     gotoxy(5,8);
     printf("Set all Ports off\n");
     
     for(i = 0; i < numIows; i++) 
        {
          // Write to simple endpoint
          WriteSimple(iows[i], 0xFFFFFFFF);
          usleep(20000);
        }
     
     usleep(1000000);

     gotoxy(5,8);
     printf("                   ");
     
  }

int writePorts() 
  {
     gotoxy(5,9);
     printf("Write Port\n"); 

     report56.ReportID=0; 

     // Setzen der Portbits 
     report56.Bytes[3] = 4; 

     gotoxy(5,10);
     printf("Setzen des Port 3 mit %d\n", report56.Bytes[3]); 
       
     // Write to simple endpoint
     // only 1 devices 
     // set manuell the bitPattern 0 to 7

    rc = WriteSimple(iows[0], bitsPattern);

    usleep(20000);
	
     // Sleep for 250ms
     usleep(250000);
    
     gotoxy(5,11);
     printf("Set_Bits complete\n");
 
     usleep(1000000);
     
     gotoxy(5,9);
     printf("                   ");
     gotoxy(5,10);
     printf("                   ");
     gotoxy(5,11);
     printf("                   ");

     return 0;
  }

int inputCommand()
  {
     gotoxy(5,6);
     printf("Set Bits-Command: \n");
     gotoxy(30,6);
     scanf("%d",&command);
  
     gotoxy(30,6);
     printf("   ");

     if(command==0) IowKitCloseDevice(devHandle);
     if(command==1) bitsPattern = bitsPattern0;   // = 0x00000001 
     if(command==2) bitsPattern = bitsPattern1;   // = 0x00000010
     if(command==3) bitsPattern = bitsPattern2;   // = 0x00000100
     if(command==4) bitsPattern = bitsPattern3;   // = 0x00000011
     if(command==5) bitsPattern = bitsPattern4;   // = 0x00000111
     if(command==6) bitsPattern = bitsPattern5;   // = 0x00000110
     if(command==7) bitsPattern = bitsPattern6;   // = 0x00000101
     // if(command==8) 
     // if(command==9) 

     gotoxy(5,7);
     printf(" %ld\n",bitsPattern);

     setAllPortsOff();
     
     return 0;
  }

int main(int argc, char* argv[])
  {
     clrscr();
     gotoxy(5,1);
     printf("The IO_WarriorWrite Version 0.10. \n"); 

     // Open ioWarrior-Device
     initIO_device();
                       
     do
        {
           inputCommand();

           writePorts();

       
        }while(command > 0);
      

     // Close device
     // IowKitCloseDevice(devHandle);

     // out:
     
     gotoxy(5,15);
     printf("IO-Warrior56 Device is closed, and Exit, Bye...\n");

     return 0;
  }

/*******************************************************************************/
nomad
Posts: 30
Joined: Tue Dec 11, 2007 5:01 pm
Location: switzerland

Post by nomad »

hi,
also das ging in die Hose:
programm laeuft durch:
auf Port0 - bit0 = ON

also ganz einfach:
moechte ein programm entwickeln

- only write to port
- no read
- no press button

1) initialisieren und oeffnen von iowarrior56
2) alle outports auf <0> = low
3) in while(command > 0)
{
- input in binaeren oder decimalen wert fuer die ports 0 - 3 entgegennehmen
- schreiben der bytes auf die ports
- solange warten bis wieder input (durch scanf) vorhanden
}
4) closeDevice and exit

fuer mich sind nur die port0,port1,port2,port3 = 4 bytes von intresse.

also versuch ich jetzt mal folgendes: (aus thread IO-Warrior Ports einzeln ansteuern)

IOWKIT56_REPORT report56;

// init report
report56.ReportID = 0; // ermoeglicht write

report56.Bytes[0] = 1; // port0 write = 0x00000001
report56.Bytes[1] = 2; // port1 write = 0x00000010
report56.Bytes[2] = 3; // port2 write = 0x00000011
report56.Bytes[3] = 4; // port3 write = 0x00000100
report56.Bytes[4] = 0; // port4 write = 0x00000000 (uninteressant)
report56.Bytes[5] = 0; // port5 write = 0x00000000 (uninteressant)

frage koennte es auch so aussehen:
report56.Bytes[0] = 0x00000001;

mehr faellt mir im augenblick nicht ein.

und ueber eine hilfestellung waere in s e h r dankbar.
gruss
stephan
User avatar
Christoph Jung
Posts: 673
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Post by Christoph Jung »

Dem Programm, bzw. Kompiler ist es egal, ob du nun den

Binärcode 0x00000001
Hex: 0x01
Dezimal: 1

nimmst, da im Prinzip überall das selbe rauskommt. Für manche ist es einfacher, die Binär-daten zu sehen und zu kontrollieren (8 Bits = 8 LED).

Der Code (der zweite) sollte funktionieren und die Ports setzen.

Aus dem ersten Code sollte klargestellt werde, dass die Funtion

Code: Select all

// Write simple value
BOOLEAN WriteSimple(IOWKIT_HANDLE devHandle, DWORD value)
  {
     // Init report
     switch(IowKitGetProductId(devHandle))
        {
           // Write simple value to IOW56
           case IOWKIT_PRODUCT_ID_IOW56:
              memset(&report56, 0xff, sizeof(report56));
              report56.ReportID = 0;
              report56.Bytes[6] = (UCHAR) value;
         
              return IowKitWrite(devHandle, IOW_PIPE_IO_PINS,
                     (PCHAR) &report56, IOWKIT56_IO_REPORT_SIZE) ==         
                                      IOWKIT56_IO_REPORT_SIZE;
           
           default:
           return FALSE;
        }
  } 

Nur einen Port anspricht (Report.Byte[6] !)
Somit übergeht er einfach die anderen Ports bei schreiben.
Software developer
nomad
Posts: 30
Joined: Tue Dec 11, 2007 5:01 pm
Location: switzerland

Post by nomad »

hallo herr jung
vielen dank fuer die antwort.

also unterdessen, konnte ich mit dem neuen untenstehenden
neuen programm einen 1.erfolg (vermut ich mal) verbuchen.

ergebnisse:

also 1.test mit multimeter:
- clearAllPorts = multimeter on Port[0] bit 1 == off 0.0volt

- setPorts:
- port[0] = 1.bit = ON also 0x00000001
- port[0] = 2.bit = OFF

- port[1] = 2.bit = ON also 0x00000010
- port[1] = 1.bit = OFF

- clearAllPorts after Write
- test mit multimeter on Port 0 1.bit = off

doch recht komische output:
- nach Bitte Taster betaetigen
- passiert gar nichts - > prog exit dafuer
- test multimeter on port 0 1.bit off
- then exit
- ports sind und bleiben low

Consolen-Output
Starting
IO-Warrior 56 gefundenIO-Warrior Kit V1.5
Clear Ports
Clear All Ports Clear is Done
Setzen des Port 0 mit 1
Setzen des Port 2 mit 2
Setzen des Port 3 mit 4
Setzen des Port 4 mit 0
Setzen des Port 5 mit 0
Setzen des Port 6 mit 255
Setzen des Port 7 mit 255
Clear All Ports after Write is Done
Bitte Taster betätigen!

Frage ist der stuff nach "Bitte Taster betaetigen ueberhaupt notwendig?

Ich weiss, dass meine fragen und die programme etwas komisch aussehen.
aber im augenblick stochere ich einfach im Nebel herum.
ich versuche einfach mein programm durch versuch und irrtum zum laufen zu bekommen,

da mir noch die Frage
1) um die ports zu testen, wuerde ich gerne eine led-reihe an die entsprechenden ports
anschliessen. ist das problemlos moeglich?

leider noch nicht bewortet wurde, bin ich auf das verhalten der restlich Bits eines Portes
auf vermutungen angewiesen.

da mir das verhalten der progs noch einwenig obskur erscheint, waere, fuer hinweise, und korrekturen
und tips dankbar.

mit ihren anregungen werden ich morgen frueh weitermachen,
nochmals dank fuer ihre antwort <hier wird ihnen geholfen> ;-)


Gruss
stephan morf

hier nun der code:

Code: Select all

// ioWarriorWrite_11.c dd. 19.12.2007
// compile with:
// gcc -Wall -g -liowkit ioWarriorWrite_11.c -o ioWarriorWrite_11  

/*****************************************************************/

#include "iowkit.h"

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> 
#include <fcntl.h> 
#include <string.h> 
#include <ctype.h> 
#include <setjmp.h> 

#include <unistd.h> 
#include <sys/signal.h> 
#include <sys/types.h> 
#include <errno.h> 

#define _POSIX_SOURCE 1  	  // POSIX compliant source  
#define FALSE 0 
#define TRUE 1 

typedef unsigned char byte; 

int STOP=FALSE; 


int command;
int i;
int cnt;

IOWKIT_HANDLE iows[IOWKIT_MAX_DEVICES];
int i, j;
ULONG bits;
int numIows;
unsigned short sn[9];
char snt[9];
ULONG rc;
DWORD pid;
IOWKIT_HANDLE devHandle;
IOWKIT56_IO_REPORT report56;

ULONG bitsPattern0 = 0x00000001; // dec 1
ULONG bitsPattern1 = 0x00000010; // dec 2
ULONG bitsPattern3 = 0x00000011; // dec 3
ULONG bitsPattern4 = 0x00000100; // dec 4
ULONG bitsPattern5 = 0x00000101; // dec 5
ULONG bitsPattern6 = 0x00000110; // dec 6
ULONG bitsPattern7 = 0x00000111; // dec 7

ULONG bitsPattern;


 
int main(int argc, char* argv[]) 
  { 
     IOWKIT_HANDLE ioHandle; 
     IOWKIT56_IO_REPORT report56; 
     ULONG res; 
     DWORD bits; 

     printf("Starting\n");
     
     ioHandle = IowKitOpenDevice();  // Öffnen der Device
      
     if(ioHandle!=NULL)    
        {
           if(IowKitGetProductId(ioHandle)==IOWKIT_PRODUCT_ID_IOW56) 
              {
                 printf("IO-Warrior 56 gefunden"); 
              }
        }
     else 
        { 
           printf("IO-Warrior nicht gefunden!"); 
           goto out; 
        }
        
     printf("%s\n",IowKitVersion()); 
 
     report56.ReportID=0;   // ermoeglicht write
 
     printf("Clear Ports\n");

     //clear all ports
     for(cnt = 0; cnt <= 7; cnt++)
        {
           report56.Bytes[cnt] = 255;//0x00000000;
        }  
     
     printf("Clear All Ports Clear is Done\n"); 

     usleep(2000000); // wait 2 secs

     // Set port-bits

     report56.Bytes[0] = 1; // port0 write = 0x00000001
     report56.Bytes[1] = 2; // port1 write = 0x00000010
     report56.Bytes[2] = 3; // port2 write = 0x00000011
     report56.Bytes[3] = 4; // port3 write = 0x00000100
     report56.Bytes[4] = 0; // port4 write = 0x00000000 (uninteressant)
     report56.Bytes[5] = 0; // port5 write = 0x00000000 (uninteressant)

     // old stuff report.Bytes[3] = 4; 
    
     printf("Setzen des Port 0 mit %d\n",report56.Bytes[0]); 
     printf("Setzen des Port 2 mit %d\n",report56.Bytes[1]); 
     printf("Setzen des Port 3 mit %d\n",report56.Bytes[3]); 
     printf("Setzen des Port 4 mit %d\n", report56.Bytes[4]); 
     printf("Setzen des Port 5 mit %d\n", report56.Bytes[5]); 
     printf("Setzen des Port 6 mit %d\n", report56.Bytes[6]); 
     printf("Setzen des Port 7 mit %d\n", report56.Bytes[7]); 
        
     res=IowKitWrite(ioHandle, IOW_PIPE_IO_PINS, (PCHAR)&report56, IOWKIT56_IO_REPORT_SIZE); 
    
     if(res!=IOWKIT56_IO_REPORT_SIZE) 
        { 
           printf("Ein Fehler ist aufgetreten! Bitte erneut versuchen!"); 
           goto out; 
        }
 
     usleep(20000000); // wait 20 secs
 
     // Zurück-Setzen der Portbits 
     // clear all ports
     for(cnt = 0; cnt <= 7; cnt++)
        {
           report56.Bytes[cnt] = 0x00000000;
        }  
     
     printf("Clear All Ports after Write is Done\n"); 
    
     res=IowKitWrite(ioHandle, IOW_PIPE_IO_PINS, (PCHAR)&report56, IOWKIT56_IO_REPORT_SIZE); 

     if(res!=IOWKIT56_IO_REPORT_SIZE) 
        { 
           printf("Ein Fehler ist aufgetreten! Bitte erneut versuchen!"); 
           goto out; 
        } 
 
     printf("Bitte Taster betätigen!\n"); 
     
     usleep(2000000); //2 sekunden zeit zum drücken 
     
     // Nun alle reports aus dem internen puffer lesen, Taster 
     // drücken und loslassen sollte auch irgendwann dabei sein 

     while(IowKitReadImmediate(ioHandle, &bits))
        {  
          // Fehler <%x> printf("Bits: %x",bits);
          // compile fehler: warning : format '%x' expects type 
          // unsigned int, but argument 2 has type 'DWORD'
        }  
         
     IowKitCloseDevice(ioHandle); 
     
     out: 
     usleep(1000000); // wait 1 sec

     return 0;
  }
 
/*****************************************/
Guido Körber
Site Admin
Posts: 2876
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Post by Guido Körber »

nomad wrote:da mir noch die Frage
1) um die ports zu testen, wuerde ich gerne eine led-reihe an die entsprechenden ports
anschliessen. ist das problemlos moeglich?
Im Prinzip ja, Vorwiderstand nicht vergessen und besonders hell werden die LEDs nicht, da die Portpins nur ein paar Milliamps pro Stück können.
nomad
Posts: 30
Joined: Tue Dec 11, 2007 5:01 pm
Location: switzerland

Post by nomad »

hallo herr koerber,
vielen dank fuer die antwort,
4.7Kohm sollten ja reichen?
mit freundlichen gruessen
stephan
Guido Körber
Site Admin
Posts: 2876
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Post by Guido Körber »

4k7 sind deutlich zu viel, ich würde mal bei wenigen 100Ω anfangen.
nomad
Posts: 30
Joined: Tue Dec 11, 2007 5:01 pm
Location: switzerland

Post by nomad »

hi

@herrn koerber, vielen dank fuer den hinweis.
im augenblick gehts schneller ohne leds,nur mit dem multimeter bewaffnet.

heute morgen hab ich probiert, das prog weiter zu entwickeln.

also folgende sachen gehen:

bei ioWarriorWrite_12.c (ss. letztes posting von mir)
- Set port-bits
report56.Bytes[0] = 166; // port0 write = 0x10100110
report56.Bytes[1] = 166; // port1 write = 0x10100110
report56.Bytes[2] = 166; // port2 write = 0x10100110
report56.Bytes[3] = 166; // port3 write = 0x10100110
report56.Bytes[4] = 1; // port4 write = 0x00000001 (uninteressant)
report56.Bytes[5] = 1; // port5 write = 0x00000001 (uninteressant)

ergebnis: mit multimeter: alle ports zeigen die richtigen BitMuster.
fein.

nun zu meinen jetzigen problem:

bei ioWarrioWrite_13.c ss. unten:
moechte ich ein mehrmaliges write to ports umsetzen:
PortOutput ist aber fehlerhaft!!!

bei decleration von bitsPattern als int (port0)
z.b. input command <7> sollte bit7 = ON alle andern OFF sein
output = bit0,bit1,bit2 = ON
= restliche bits = OFF

bei decleration von bitsPattern als ULONG (port0)
z.b. input command <7> sollte bit7 = ON, alle andern = OFF sein
- output alle bits = OFF

liegt dieses fehlverhalten an der programmstruktur, oder den statements ??
oder auch an einen fehler von mir???

ich habe in den threads mal gelesen, dass man es ev. so machen muesste
mit XOR-Vergleichen: also:

1.durchlauf gesetztes setbit = dec 1 = 0x0001
2.durchlauf gewuenschtes setbit = dec 3 = 0x0011

oldbitsPattern = 0x0001 dec 1
XOR
xor_bitsPattern = 0x0010 dec 2
-------------
new_bitsPattern = 0x0011 dec 3

um das xor-bitsPattern dec zu berechnen muesste man als 3-1 = 2 == xorPattern
trifft diese ueberlegung zu.

oder ist im meinem programm ein fehler:??

um hinweise tips und tricks waer ich froh
gruss stephan

mein code:
entschuldigt, dass ich immer den ganzen code poste, aber ich finde,
fuer's verstaendnis ist das besser.

Code: Select all

//=========================================================================// 
//    ioWarriorWrite_13.c                                                   
//    -------------------                                                   
//    compile with :                                                        
//    gcc -Wall -g -liowkit ioWarriorWrite_13.c -o ioWarriorWrite_13       
/**************************************************************************/ 

#include "iowkit.h"

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> 
#include <fcntl.h> 
#include <string.h> 
#include <ctype.h> 
#include <setjmp.h> 

#include <unistd.h> 
#include <sys/signal.h> 
#include <sys/types.h> 
#include <errno.h> 

#define _POSIX_SOURCE 1  	  // POSIX compliant source  
#define FALSE 0 
#define TRUE 1 

typedef unsigned char byte; 

int STOP=FALSE; 
int command;
int i;
int cnt;

IOWKIT_HANDLE iows[IOWKIT_MAX_DEVICES];
int i, j;
ULONG bits;
int numIows;
unsigned short sn[9];
char snt[9];
ULONG rc;
DWORD pid;

IOWKIT_HANDLE ioHandle; 
IOWKIT56_IO_REPORT report56; 
ULONG res; 
DWORD bits; 

ULONG bitsPattern0 = 1;  // 0x00000001
ULONG bitsPattern1 = 2;  // 0x00000010 
ULONG bitsPattern3 = 3;  // 0x00000011
ULONG bitsPattern4 = 4;  // 0x00000100
ULONG bitsPattern5 = 5;  // 0x00000101
ULONG bitsPattern6 = 6;  // 0x00000110
ULONG bitsPattern7 = 7;  // 0x00000111

ULONG bitsPattern;
/*
int bitsPattern0 = 1;  // 0x00000001
int bitsPattern1 = 2;  // 0x00000010 
int bitsPattern3 = 3;  // 0x00000011
int bitsPattern4 = 4;  // 0x00000100
int bitsPattern5 = 5;  // 0x00000101
int bitsPattern6 = 6;  // 0x00000110
int bitsPattern7 = 7;  // 0x00000111

int bitsPattern;
*/
/***************************************************************************/ 

// delay (nnn)
void delay(long millisek)
{
   int mikrosek = millisek*1000;
   struct timeval  timeout;
   
   timeout.tv_sec  = mikrosek / 1000000L;
   timeout.tv_usec = mikrosek % 1000000L;
   select(0, NULL, NULL, NULL, &timeout);
}

void gotoxy(int x, int y) { printf("\033[%d;%dH", y, x); fflush(stdout); }
void clrscr(void)         { printf("\033[H\033[J");      fflush(stdout); }

/****************************************************************************/

int initIO_device()
  {
     gotoxy(5,2);
     printf("Starting Initialitions and open Device\n");
     
     ioHandle = IowKitOpenDevice();  // Öffnen der Device
      
     if(ioHandle!=NULL)    
        {
           if(IowKitGetProductId(ioHandle)==IOWKIT_PRODUCT_ID_IOW56) 
              {
                 gotoxy(5,3);
                 printf("IO-Warrior 56 gefunden"); 
              }
        }
     else 
        { 
           printf("IO-Warrior nicht gefunden!"); 
           goto out; 
        }
     gotoxy(5,4);   
     printf("Version: %s\n",IowKitVersion()); 
 
     report56.ReportID=0;   // ermoeglicht write
     
     gotoxy(5,5);
     printf("Clear Ports\n");

     //clear all ports
     for(cnt = 0; cnt <= 7; cnt++)
        {
           report56.Bytes[cnt] = 255;//0x00000000;
        }  
     
     gotoxy(5,6);
     printf("Clear All Ports Clear is Done\n"); 

     usleep(2000000); // wait 2 secs

     out: 

     return 0;
     
  }

/************************************************************************************/
int setAllPortsOff()
  {
     gotoxy(5,10);
     printf("Clear Ports\n");

     //clear all ports
     for(cnt = 0; cnt <= 7; cnt++)
        {
           report56.Bytes[cnt] = 255;//0x00000000;
        }  
     
     gotoxy(5,11);
     printf("Clear All Ports Clear is Done\n"); 

     //usleep(2000000); // wait 2 secs

     return 0;

  }

/************************************************************************************/
int inputCommand()
  {
     gotoxy(5,7);
     printf("Set Bits-Command: \n");
     gotoxy(30,7);
     scanf("%d",&command);
  
     gotoxy(30,7);
     printf("   ");

     if(command==0) // IowKitCloseDevice(ioHandle);
     if(command==1) bitsPattern = bitsPattern0;   // = 0x00000001 = dec 1
     if(command==2) bitsPattern = bitsPattern1;   // = 0x00000010 = dec 2
     if(command==3) bitsPattern = bitsPattern3;   // = 0x00000011 = dec 3
     if(command==4) bitsPattern = bitsPattern4;   // = 0x00000100 = dec 4
     if(command==5) bitsPattern = bitsPattern5;   // = 0x00000101 = dec 5
     if(command==6) bitsPattern = bitsPattern6;   // = 0x00000110 = dec 6
     if(command==7) bitsPattern = bitsPattern7;   // = 0x00000111 = dec 7
     // if(command==8) 
     // if(command==9) 

     gotoxy(5,8);
     printf("BitsPattern: %ld\n",bitsPattern);

     usleep(1000000);

     gotoxy(5,9);
     printf("              ");

     setAllPortsOff();
     
     return 0;
  }

/************************************************************************************/

int writePorts()
  {
     // Set port-bits
     report56.Bytes[0] = bitsPattern;  // port0 write 
     report56.Bytes[1] = 1;            // port1 write 
     report56.Bytes[2] = 1;            // port2 write 
     report56.Bytes[3] = 1;            // port3 write 
     report56.Bytes[4] = 1;            // port4 write (uninteressant)
     report56.Bytes[5] = 1;            // port5 write (uninteressant)
               
     gotoxy(5,12);
     printf("Setzen des Port 0 mit %d\n",report56.Bytes[0]);
     gotoxy(5,13);
     printf("Setzen des Port 1 mit %d\n",report56.Bytes[1]);
     gotoxy(5,14);
     printf("Setzen des Port 2 mit %d\n",report56.Bytes[2]);
     gotoxy(5,16);
     printf("Setzen des Port 3 mit %d\n",report56.Bytes[3]); 
     gotoxy(5,17); 
     printf("Setzen des Port 4 mit %d\n",report56.Bytes[4]);
     gotoxy(5,18); 
     printf("Setzen des Port 5 mit %d\n",report56.Bytes[5]); 
       
     res=IowKitWrite(ioHandle, IOW_PIPE_IO_PINS, (PCHAR)&report56, IOWKIT56_IO_REPORT_SIZE); 
         
     if(res!=IOWKIT56_IO_REPORT_SIZE) 
        { 
           printf("Ein Fehler ist aufgetreten! Bitte erneut versuchen!"); 
           goto out; 
        }

     usleep(30000000);  // wait 30 secs 
      
     // Zurück-Setzen der Portbits 
     // clear all ports
     for(cnt = 0; cnt <= 7; cnt++)
        {
           report56.Bytes[cnt] = 0x00000000;
        }  
           
     gotoxy(5,19);
     printf("Clear All Ports after Write is Done\n"); 
     
     res=IowKitWrite(ioHandle, IOW_PIPE_IO_PINS, (PCHAR)&report56, IOWKIT56_IO_REPORT_SIZE); 
      
     if(res!=IOWKIT56_IO_REPORT_SIZE) 
        { 
           printf("Ein Fehler ist aufgetreten! Bitte erneut versuchen!"); 
           goto out; 
        }

     usleep(1000000); // wait 1 sec
  
     // Nun alle reports aus dem internen puffer lesen, Taster 
     // drücken und loslassen sollte auch irgendwann dabei sein 

     while(IowKitReadImmediate(ioHandle, &bits))
        { 
          gotoxy(5,21);
          printf("Read\n"); 
          // Fehler <%x> printf("Bits: %x",bits);
          // compile fehler: warning : format '%x' expects type 
          // unsigned int, but argument 2 has type 'DWORD'
        }  
     out:

     return 0;
 
  }

/************************************************************************************/
int main(int argc, char* argv[]) 
  { 
     clrscr();
     gotoxy(5,1);
     printf("The IO_WarriorWrite Version 0.10.   (c) 2007 RCI\n"); 

     initIO_device();

     do
        {
           // nowSetting Ports for test only Port 0
           inputCommand();
   
           if(command > 0)
              {
                 writePorts();        
              } 
        }while(command > 0); // end while  

     gotoxy(5,20); 
     printf("Outside while: Bitte Taster betätigen!\n"); 
     
     usleep(2000000); //2 sekunden zeit zum drücken 
     
     // Nun alle reports aus dem internen puffer lesen, Taster 
     // drücken und loslassen sollte auch irgendwann dabei sein 

     while(IowKitReadImmediate(ioHandle, &bits))
        { 
          gotoxy(5,21);
          printf("Read\n"); 
          // Fehler <%x> printf("Bits: %x",bits);
          // compile fehler: warning : format '%x' expects type 
          // unsigned int, but argument 2 has type 'DWORD'
        }  
         
     IowKitCloseDevice(ioHandle); 
     
     usleep(1000000); // wait 1 sec

     //out: 

     gotoxy(5,22);
     printf("IO-WarriorDevice is closed and Exit, ....Bye\n");

     return 0;
  }
 
/***********************************************************************************************/
User avatar
Christoph Jung
Posts: 673
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Post by Christoph Jung »

Ich gleube die Rangehensweise ist nicht ganz richtig.

Springt das Programm denn in einer der Fehlerroutinen? Gibt er irgendwelche Fehlermeldungen aus oder passiert garnichts?
Bleibt das Programm eventuell hängen?


Tipps:
Zum einen würde ich persöhnlich die if(command==....) methode durch einen switch(command) ersetzen. Das beugt eventuelle Fehler vor.

also:

Code: Select all

switch(command)
{
  case 0:
    bitsPattern = bitsPattern0; 
  break;
   
  case 1:
    //usw

}
Dann würde ich bei der Write-Routine noch die ReportID mit angeben.

Code: Select all

Report.ID = 0x00;
Nur für die Übersicht und den Zusammenhang.

Dann UNBEDINGT die gotos abgewöhnen. Sowas kann ganz böse in die Hose gehen. Ist aber evtl. im moment nicht wichtig.

Dann in der Function "inputCommand":

Nach der Auswahl des Bitmusters kommen folgende Zeilen:

Code: Select all

   gotoxy(5,8);
     printf("BitsPattern: %ld\n",bitsPattern);

     usleep(1000000);

     gotoxy(5,9);
     printf("              ");

     setAllPortsOff();
     
     return 0; 
setAllPortsOff(), bewikt doch bestimmt, dass alle Ports auf NULL gesetzt werden. einfach mal auskommentieren und versuchen.


Durch die ganzen "gotoxy" verliehrt man total den Überblick.
Software developer
nomad
Posts: 30
Joined: Tue Dec 11, 2007 5:01 pm
Location: switzerland

Post by nomad »

hallo herr jung, or better christoph ?

zitat
< Ich gleube die Rangehensweise ist nicht ganz richtig.>

was soll ich denn sonst machen,;-)

also:
zitat:
<
Springt das Programm denn in einer der Fehlerroutinen? Gibt er irgendwelche Fehlermeldungen aus oder passiert garnichts?
Bleibt das Programm eventuell hängen?
>

- kein einsprunkg in fehler-routinen.
- keine fehlermeldung ss. consolen-output
- kein haenger

- hier der consolen-output nach input <7>

Code: Select all

  The IO_WarriorWrite Version 0.10.   (c) 2007 RCI
    Starting Initialitions and open Device
    IO-Warrior 56 gefunden
    Version: IO-Warrior Kit V1.5
    Clear Ports
    Clear All Ports Clear is Done
    Set Bits-Command:
    BitsPattern: 7

    Clear Ports
    Clear All Ports Clear is Done
    Setzen des Port 0 mit 7
    Setzen des Port 1 mit 1
    Setzen des Port 2 mit 1

    Setzen des Port 3 mit 1
    Setzen des Port 4 mit 1
    Setzen des Port 5 mit 1
    Clear All Ports after Write is Done
-------------------------
nach input <0> 

  The IO_WarriorWrite Version 0.10.   (c) 2007 RCI
    Starting Initialitions and open Device
    IO-Warrior 56 gefunden
    Version: IO-Warrior Kit V1.5
    Clear Ports
    Clear All Ports Clear is Done
    Set Bits-Command:
    BitsPattern: 7

    Clear Ports
    Clear All Ports Clear is Done
    Setzen des Port 0 mit 7
    Setzen des Port 1 mit 1
    Setzen des Port 2 mit 1

    Setzen des Port 3 mit 1
    Setzen des Port 4 mit 1
    Setzen des Port 5 mit 1
    Clear All Ports after Write is Done
    Outside while: Bitte Taster betätigen!

    IO-WarriorDevice is closed and Exit, ....Bye
hier koennte ev. ein fehler sein, nach command <0>
- - - - - - - - - - - - - - - - - - - - -
............
BitsPattern: 7

Clear Ports
Clear All Ports Clear is Done
Setzen des Port 0 mit 7
........
- - - - - - -- - - - - - -- --

ihre tipps werd ich morgen frueh, ins programm aufnehmen.also:
<
switch(command)
{
case 0:
bitsPattern = bitsPattern0;
break;

case 1:
//usw

}
>
zitat
<
Dann würde ich bei der Write-Routine noch die ReportID mit angeben.
Code:
Report.ID = 0x00;
>
hatte die urspruengliche form: report56.ID = 0;
aus den foren. hat in version 0.12. gefunnzzt.

die gotos find ich auch nicht ganz in ordnung, ist ja fast wie in basic.
werd sie rausnehmen.
waren aber in den beispielcodes drinn.

Dann in der Function "inputCommand":

- function: setAllPortsOff();

==> hat in ioWarriorWrite_12.c gut funktioniert. ??
werd's ausprobieren.
und die gotos nehm ich fuer sie auch mal raus:
grund: scanf("%d",&command)
ohne gotoxy landet der cursor sonstwo.

was mich erstaunt, dass, wenn, wie in ioWarriorWrite_12.c ohne while-loop
gearbeitet wird, der ganze output korrekt ist.

muss man ev. sich den letzten bitsPattern-wert merken,????
und was halten sie von XOR ???
bin mir da nicht so sicher

werd mich jedenfalls morgen frueh ans werk machen, und sobald
ich 1. ergebnisse hab. alles posten.

ich danke ihnen fuer ihre hilfe
schoenen abend noch.
gruss
nomad
nomad
Posts: 30
Joined: Tue Dec 11, 2007 5:01 pm
Location: switzerland

Post by nomad »

nachtrag 20.12. 19.15

hallo herr jung,

damit wir uns richtig verstehen:

ich entwickle unter suse-linux 10.1 64bit, in c.

1) das endgueltige programm dient als communication-interface
zu 2 32-bit microcontroller, diese steuern 12 hochleistungs-servos an.
- es ist nur ein teil eines groessen c-programmes (so ungefaehr 20-30_000 zeilen)

2) die 32-Output-Bits der Ports[0] bis PORT[3] liefern die notwendigen
servoImpulse (ca. 80 ms) = usleep(80000)

3) die Output-Pins (also die 32-Output-Bits) muessen bei der initialisierung
des iowarrior56 unbedingt auf <0> gesetzt werden, sonst haben die controller
troubles!! und servos-bewegung ist undefiniert.

hier in pseudo code das vorgehen des iowarrior-codes:

Code: Select all


MAIN: 
  1) start iowarrior56
  2)  - initialisierung iowarrior56 (openDevice etc)
       - ClearAllPortsToZero();  (report56.Bytes[0] = 0; // ox0000 dec 0
       - usleep(1000000); // wait 1 sec

     do
      {
        inputCommands();  // z.b. bitsPattern = nnn (values 1 to 255)
                                         // values aendern sich bei jedem durchlauf)
       
        if(commands > 0)
          {
             WritePorts();     // z.b. report56.Bytes[n] = bitsPattern;
             usleep(80000); // impuls-erzeugung
             ClearAllPortsToZero() // z.b. report56.Bytes[n] = 0; = 0x0000 dec 0
                                                 // Muss unbedingt sein, sonst hats keinen zweck!!!
          }
      }while(command > 0)

     usleep(1000000); // wait 1 sec
     closeDevice();

     return = 0;
  }       


ich hoffe, dass sie wegen dieser zeilen nicht boese sind :-), ich will damit
nur einwenig klarheit schaffen.

ueber ihre antworten freue ich mich schon
Gruss
nomad
supachris
Posts: 124
Joined: Tue Mar 16, 2004 12:30 am
Location: Dresden

Post by supachris »

nomad wrote:nachtrag 20.12. 19.15

2) die 32-Output-Bits der Ports[0] bis PORT[3] liefern die notwendigen
servoImpulse (ca. 80 ms) = usleep(80000)
Ui, das ist aber sehr gewagt, das direkt über USB zu machen. Auch unter Linux. Oder hat dein Linux eine Echtzeit-Erweiterung?
Gruß SupaChris
blip
Posts: 12
Joined: Sun May 09, 2004 11:49 am
Location: Winznau, Switzerland
Contact:

Post by blip »

Ich denke, selbst wenn das Linux eine Echtzeit-Erweiterung hat, haut das
über USB wohl nicht recht hin mit Präzision im Millisekundenbereich.
Bei Servos wird doch die Position über die Pulsweite gesteuert ?
Ich erinnere mich dunkel, dass bei USB/HID die Anzahl der Requests pro
Sekunde ein Limit hat, vielleicht kann Herr Körber da einen Hinweis geben?
Jedenfalls wäre das dann die Anzahl der Requests im Idealfall, aber man
sich nicht drauf verlassen. Würde mich jedenfalls auf gelegentliches Zucken
der Servos vorbereiten, wenn diese direkt vom IOW angesteuert werden
sollen...

Viele Grüsse,

Blip
Last edited by blip on Wed May 28, 2008 9:38 pm, edited 1 time in total.
Guido Körber
Site Admin
Posts: 2876
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Post by Guido Körber »

Also beim IOW56 kann jede Millisekunde ein Report übertragen werden, pro Endpoint. Allerdings liegt es beim Betriebssystem wann innerhalb der Millisekunde der Report übertragen wird. Allerdings ist das meist relativ stabil von der Zeit her, nur wenn neue Geräte hinzukommen oder welche wegfallen, oder eine Menge Datenübertragungen hinzukommen kommt es zu größeren Variationen.

Was die Initialisierung der Ports betrifft: Alle IO-Warrior initialisieren sich auf high an den Ports. Dass lässt sich von aussen nicht beeinflussen.
nomad
Posts: 30
Joined: Tue Dec 11, 2007 5:01 pm
Location: switzerland

Post by nomad »

hi an alle,
vielen dank fuer die antworten:

zu den impulsen:
vermutlich ein kleines missverstaendnis

also:
- im testbetrieb der 2 microcontroller
mit den 12 servos, werden die bewegungen der
servos ueber taster gesteuert.
jeweils 2 taster fuer jede servco-drehbewegung.
- die microcontroller uebernehmen intern das
genaue timing und die pulseweiten-modulation.

- also wenn zb. taster 1 gedrueckt
dann servo 1 = 1 step nach links

- die output-Pins des iowarrior simulieren
also einen tasten-druck.
- die controller lauschen also auf den pins
ob eine taste gedrueckt wurden ist.

- wenn keine taste gedrueckt bleibt der servo
auf seiner urspruenglichen position.

also keine timing probleme.
die pulsweiten modulation uebernehmen die
controller.

@herrn kroeber:
betr: initialisierung,alle ports auf high
-> kann dass vermutlich durch einen laengeren
wait-zyklus bein den controllern auffangen,
denn die muessen sich ja auch initialisieren.

nochmals vielen dank fuer diese hinweise.
waere aber sehr froh, wenn sich jemand, der
frage annehmen wuerde, wie ich den iowarrior
dazu bekomme. das verhalten des codes im
nachtrag (pseudo-code) zu uebernehmen.

werde mich jetzt, an weitere versuche machen
vielen dank
stephan
Post Reply