Simple-IO C# Beispiel umstricken

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

Moderator: Guido Körber

Post Reply
smatei
Posts: 77
Joined: Sat Apr 25, 2009 12:57 am

Simple-IO C# Beispiel umstricken

Post by smatei »

Hi,

ursprünglich habe ich mit der C#-Library von org.wayoda.csiow gearbeitet. Weil diese Library jetzt aber nicht mehr mein IOW-Board erkennt (keine Ahnung wieso), wollte ich das Simple-IO Beispiel (funktioniert) aus der SDK an meine Bedürfnisse umstricken. Ich möchte damit einen Sensirion SHT-71 auslesen.

Um Sensibus zu aktivieren und die Messung zu initialisieren benutze ich folgenden Code:

Code: Select all

byte[] report = new byte[9];
handle = IOWarrior.Functions.IowKitOpenDevice();
IOWarrior.Functions.IowKitSetTimeout(handle, 1000);

report[0] = 0x01;
report[1] = 0x01;
report[2] = 0x40;
ret = IOWarrior.Functions.IowKitWrite(handle, 0, report, IOWarrior.Defines.IOWKIT24_IO_REPORT_SIZE);
Console.WriteLine("sensibus initialisiert");
Thread.Sleep(200);

report[0] = 0x02;//i²C Report ID Write
report[1] = 0xC1;//i²C Start-Stop Signal und Control-Byte
report[2] = 0x1E;//i²C Adresse des Max und Write-Bit
ret = IOWarrior.Functions.IowKitWrite(handle, 0, report, IOWarrior.Defines.IOWKIT24_IO_REPORT_SIZE);
Console.WriteLine("messung gestartet");
Thread.Sleep(200);

report[0] = 0x03;//i²C Report ID Read
report[1] = 0x03;//i²C 2-Byte lesen
report[2] = 0x03;//i²C Control-Byte und Read-Bit//05
ret = IOWarrior.Functions.IowKitWrite(handle, 0, report, IOWarrior.Defines.IOWKIT24_IO_REPORT_SIZE);
Console.WriteLine("temperaturmessung");
Thread.Sleep(200);
Berechnet wird der Temperaturwert folgendermaßen:

Code: Select all

ret = IOWarrior.Functions.IowKitRead(handle, 0, report, IOWarrior.Defines.IOWKIT24_IO_REPORT_SIZE);
double dTemperatur = -40.1 + (0.01 * (report[1] * 256 + report[2]));
Jetzt bekomme ich aber nur Nullen als Ergebnis zurück. Wo ist mein Fehler, was mache ich falsch?
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Simple-IO C# Beispiel umstricken

Post by Christoph Jung »

Zum einen sollte man bei I2C nach jedem Schreibbefehl eine Lesebefehl hinterherschieben um evtl. Fehlerreports auszuwerten. Also
immer Paarweise (außer beim initialisieren des Special-Modes, da bekommt man keine Rückmeldung)

Code: Select all

IowKitWrite();
IowKitRead();
Und die IowKitWrite() Funktion ist falsch. I2C ist ein Special Mode und da muss man einen anderen Endpoint des IO-Warriors ansprechen.

So sollte es aussehen (das selbe bei IowKitRead()):

Code: Select all

ret = IOWarrior.Functions.IowKitWrite(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
Ansonsten sieht der Code in Ordnung aus. Ich habe zwar eine etwas andere Funktion zum Berechner der Temperatur und Luftfeuchte aber das ist ja erstmal nebensächlich.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
smatei
Posts: 77
Joined: Sat Apr 25, 2009 12:57 am

Re: Simple-IO C# Beispiel umstricken

Post by smatei »

Danke für die Antwort und den Stubser in die richtige Richtung. Ich werd es heute Abend gleich mal ausprobieren.
Ein grosses Lob nochmal an das gesamte Forum. Der Support für den IOW ist erstklassig. Dankeschön.
smatei
Posts: 77
Joined: Sat Apr 25, 2009 12:57 am

Re: Simple-IO C# Beispiel umstricken

Post by smatei »

Hmmmm...leider war es das noch nicht ganz. Ich habe den Code nun folgendermaßen umgestrickt.

Code: Select all

        static void Main(string[] args)
        {
            IntPtr handle = IntPtr.Zero;                    //Handle to IO-Warrior device
            StringBuilder sn = new StringBuilder();         //Serialnumber
            uint ret = 0;
            byte[] report = new byte[9];                    //Report Bytes for simple i/o function

            handle = IOWarrior.Functions.IowKitOpenDevice();    //Open IO-Warrior device
            
            Console.WriteLine("\nTaste drücken zum starten der Messung");
            Console.ReadKey();
            
            report[0] = 0x01;
            report[1] = 0x01;
            report[2] = 0x40;
            ret = IOWarrior.Functions.IowKitWrite(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            Console.WriteLine("sensibus initialisiert");
            Thread.Sleep(200);

            report[0] = 0x02;
            report[1] = 0xC1;
            report[2] = 0x1E;
            ret = IOWarrior.Functions.IowKitWrite(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            Console.WriteLine("messung gestartet");
            Thread.Sleep(200);

            report[0] = 0x03;
            report[1] = 0x02;
            report[2] = 0x03;
            ret = IOWarrior.Functions.IowKitWrite(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            Console.WriteLine("temperaturmessung");
            Thread.Sleep(500);

            ret = IOWarrior.Functions.IowKitRead(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            double dTemperatur = -40.1 + (0.01 * (report[1] * 256 + report[2]));

            Console.WriteLine(dTemperatur.ToString());

            IOWarrior.Functions.IowKitCloseDevice(handle);

            Console.WriteLine("\nTaste zum Beenden drücken...");
            Console.ReadKey();
        }
Als Ergebnis erhalte ich immer 287,58. Auch wenn ich probiere nach jedem Write ein Read durchzuführen, stürzt meine Anwendung ab. Wenn ich aber alles wie oben laufen lasse, läuft es wenigstens durch. Das Ergebnis passt aber nicht. :( :( :(
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Simple-IO C# Beispiel umstricken

Post by Christoph Jung »

Könnten Sie mir das komplette C# Projekt einmal schicken an jung@codemercs.com
Dann schau ich morgen mal drüber.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Simple-IO C# Beispiel umstricken

Post by Christoph Jung »

So ich hab die Fehler gefunden

Zum einen wurden zu wenige Reports abgefragt beim Lesen.

Code: Select all

  
report[0] = 0x03;
report[1] = 0x02;
report[2] = 0x03;
ret = IOWarrior.Functions.IowKitWrite(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
ret = IOWarrior.Functions.IowKitRead(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
es müsste heißen

Code: Select all

report[1] = 0x03;

Zum anderen waren die ausgewerteten Reports Falsch

Code: Select all

double dTemperatur = -40.1 + (0.01 * (report[1] * 256 + report[2]));
Das muss so aussehen

Code: Select all

double dTemperatur = -40.1 + (0.01 * (report[2] * 256 + report[3]));
Weil report[0] ist die ReportID und report[1] ist die Anzahl an gelesenen Bytes. In report[2] und [3] stehen die Daten

Hier nochmal die ganze Main-Funktion (etwas abgespeckt)

Code: Select all

        static void Main(string[] args)
        {
            IntPtr handle = IntPtr.Zero;                    //Handle to IO-Warrior device
            uint ret = 0;
            byte[] report = new byte[9];                    //Report Bytes for simple i/o function

            handle = IOWarrior.Functions.IowKitOpenDevice();    //Open IO-Warrior device
            IOWarrior.Functions.IowKitSetTimeout(handle, 1000); //Timout for Read
            
            Console.WriteLine("\nTaste drücken zum starten der Messung");
            Console.ReadKey();
            
            report[0] = 0x01;
            report[1] = 0x01;
            report[2] = 0x40;
            ret = IOWarrior.Functions.IowKitWrite(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            Console.WriteLine("sensibus initialisiert");
            

            report[0] = 0x02;
            report[1] = 0xC1;
            report[2] = 0x1E;
            ret = IOWarrior.Functions.IowKitWrite(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            ret = IOWarrior.Functions.IowKitRead(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            Console.WriteLine("messung gestartet");
            

            report[0] = 0x03;
            report[1] = 0x03;
            report[2] = 0x03;
            ret = IOWarrior.Functions.IowKitWrite(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            ret = IOWarrior.Functions.IowKitRead(handle, 1, report, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            Console.WriteLine("temperaturmessung");
            
            double dTemperatur = -40.1 + (0.01 * (report[2] * 256 + report[3]));

            Console.WriteLine(dTemperatur.ToString());

            IOWarrior.Functions.IowKitCloseDevice(handle);

            Console.WriteLine("\nTaste zum Beenden drücken...");
            Console.ReadKey();
        }
Ich habe auch mal ein Beipiel in C# mit einem Dialog erstellt und hier angehangen.
Attachments
Hunidity SHT75.zip
Beispiel zum SHT75 in C#
(520.92 KiB) Downloaded 297 times
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
smatei
Posts: 77
Joined: Sat Apr 25, 2009 12:57 am

Re: Simple-IO C# Beispiel umstricken

Post by smatei »

Wow. Das ganze macht nun ein wenig mehr Sinn. :) :) :)
Kanns kaum abwarten das heute Abend auszuprobieren.
Danke.
smatei
Posts: 77
Joined: Sat Apr 25, 2009 12:57 am

Re: Simple-IO C# Beispiel umstricken

Post by smatei »

Ich habe meine Platine nun um einen Max127 erweitert. Mit den Beispielprogrammen von der CD-Rom kriege ich diesen auch wunderbar ausgelesen. In meiner eigenen Anwendung stimmt aber etwas nicht. Das ganze mal wieder in C#.

Code: Select all

//Init I2C Mode 
            bReport[0] = 0x01;
            bReport[1] = 0x01;
            bReport[2] = 0x00;
            bReport[3] = 0x00;
            ret = IOWarrior.Functions.IowKitWrite(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);

            bReport[0] = 0x02;
            bReport[1] = 0xC2;
            bReport[2] = 0x50;
            bReport[3] = 0x88;
            ret = IOWarrior.Functions.IowKitWrite(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);

            bReport[0] = 0x03;
            bReport[1] = 0x02;
            bReport[2] = 0x51;
            bReport[3] = 0x00;
            ret = IOWarrior.Functions.IowKitWrite(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            ret = IOWarrior.Functions.IowKitRead(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);

            int nDecRead = (bReport[1] << 8) | bReport[2];
            nDecRead = nDecRead >> 4;
            return nDecRead * 10.0 / 4096.0;
Die Ergebnisse sind immer 2 x 0,0078125, dann 3 x 5. Immer in dieser Reihenfolge.
Wem fällt da was auf?
smatei
Posts: 77
Joined: Sat Apr 25, 2009 12:57 am

Re: Simple-IO C# Beispiel umstricken

Post by smatei »

Okay, ich habe meine Funktion zum auslesen nun erweitert. Nachdem ich den Max ansteuere lese ich Ihn auch gleich aus.

Code: Select all

//Init I2C Mode 
            bReport[0] = 0x01;
            bReport[1] = 0x01;
            bReport[2] = 0x00;
            bReport[3] = 0x00;
            ret = IOWarrior.Functions.IowKitWrite(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);

            bReport[0] = 0x02;
            bReport[1] = 0xC2;
            bReport[2] = 0x50;
            bReport[3] = 0x88;
            ret = IOWarrior.Functions.IowKitWrite(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
NEU ->> ret = IOWarrior.Functions.IowKitRead(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);

            bReport[0] = 0x03;
            bReport[1] = 0x02;
            bReport[2] = 0x51;
            bReport[3] = 0x00;
            ret = IOWarrior.Functions.IowKitWrite(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            ret = IOWarrior.Functions.IowKitRead(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);

            int nDecRead = (bReport[1] << 8) | bReport[2];
            nDecRead = nDecRead >> 4;
            return nDecRead * 10.0 / 4096.0;
Jetzt kriege ich konstant 0,078125V wenn keine Spannung anliegt und 0,1147...V wenn ca. 9V anliegen.
Ich habe bestimmt einen Umrechnungsfehler, nur sehe ich den nicht.
smatei
Posts: 77
Joined: Sat Apr 25, 2009 12:57 am

Re: Simple-IO C# Beispiel umstricken

Post by smatei »

FEHLER GEFUNDEN!!! Es muss das zweite und dritte Byte weiterverarbeitet werden. So gehts richtig:

Code: Select all

bReport[0] = 0x02;
            bReport[1] = 0xC2;
            bReport[2] = 0x50;
            bReport[3] = 0x88;
            ret = IOWarrior.Functions.IowKitWrite(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            ret = IOWarrior.Functions.IowKitRead(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);

            bReport[0] = 0x03;
            bReport[1] = 0x02;
            bReport[2] = 0x51;
            bReport[3] = 0x00;
            ret = IOWarrior.Functions.IowKitWrite(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            ret = IOWarrior.Functions.IowKitRead(m_ioHandle, IOWarrior.Defines.IOW_PIPE_SPECIAL_MODE, bReport, IOWarrior.Defines.IOWKIT_SPECIAL_REPORT_SIZE);
            
            int nDecRead = (bReport[2] << 8) | bReport[3];
            nDecRead = nDecRead >> 4;
            return nDecRead * 10.0 / 4096.0;
Mann, Mann, Mann. Irgendwie ist an dieser Point-of-no-return Geschichte was dran. :D
Post Reply