PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] SF10 an Raspi mit Perl über I2C auslesen



Hectic
24.06.2021, 14:19
Hallo liebe Gemeinde,

seit ein paar Tagen beschäftige ich mich mit dem I2C-Bus und finde das eigentlich auch recht einfach. So habe ich z. B. schon problemlos zwei Motoren über den MD25 Dual-Motortreiber an's Laufen bekommen. Beim Ultraschallsensor SRF10 stoße ich jedoch auf Probleme.

- Ich greife unter Linux mit Perl und dem Modul Device::I2C auf den I2C-Bus zu.
- In der Beschreibung des Sensors steht, dass eine Messung ca. 65ms benötigt und vorher nichts brauchbares raus kommt. Also schreibe ich die 81 (für Antwort in cm) an Register 0 (Befehlsregister), warte 100ms (lieber mehr als zu wenig) und lese dann ein Byte von Register 2 (Hi Byte) und ein Byte von Register 3 (Lo Byte).
- ( Hi Byte * 256 ) + Lo Byte = Range in cm ( sollte so sein, oder? )
- Die erste Messung beim Programmaufruf ist korrekt ( Hindernis in 30cm Entfernung aufgestellt, zeigt ca. 29cm an). Alles folgende sind viel zu große Zahlen. Sogar die Software Revision ist beim zweiten Mal falsch! :confused:

Ich stelle diese Frage im Bereich Sensoren / Sensorik, weil alles andere bei mir bisher läuft. Dennoch kann ich nicht ausschließen, dass es auch am Treiber unter Linux oder an einer Eigenheit von Perl liegen könnte. So hatte ich im Internet schon recherchiert, dass es wohl mal ein Problem mit einem Linux-Treiber gab, der keine wiederholte Befehle an den I2C-Bus schicken konnte ohne den vorherigen abzuschließen (?). Habe das ehrlich gesagt nicht wirklich verstanden :confused:. Ich könnte mir auch vorstellen, das Perl die Bytes intern in signed integer umwandelt und deshalb was falsches dabei raus kommt. Das glaube ich aber weniger, weil die erste Messung ja stimmt.

Ich stehe gerade voll an der Wand und finde keinen Weg, darum frage ich einfach mal hier, wo sich die ganzen Profis treffen ;)
Hatte hier schon mal jemand das Problem, dass Folgemessungen am SRF10 nicht stimmen und wenn ja, wie wurde das gelöst?

Ich sag schon mal Danke für's lesen und antworten.
Hectic

Edit: SF10 geändert in SRF10

Defiant
25.06.2021, 09:46
Erste Frage: Welcher Rpi ist das? 1,2,3 oder 4?
Den SF10 kenne ich leider nicht, das Protokoll klingt aber ähnlich zu dem SRF8 oder 10, macht dein Sensor manchmal Clock Stretching?

Hectic
25.06.2021, 10:08
Ey, danke für die Antwort!

Erstmal muss ich mich korrigieren: Es handelt sich natürlich um einen SRF10 von Devantech und NICHT um einen SF10. Kein Wunder dass ich mich mit der Internetrecherche so schwer getan habe.
Beim Raspi handelt es sich um den 3er.
Ob der Sensor Clock Stretching macht ... puh,.. im Datenblatt habe ich dazu nichts finden können. Wie bekommt man sowas raus?

Defiant
25.06.2021, 10:33
Clock Stretching: z.B. durch ein Oszilloskop, hat aber zugegeben nicht jeder. Ist aber auch praktisch um z.B. herauszufinden ob die I2C-Signale sauber sind und nicht irgendwie verwaschen durch zu lange Kabel, falsche Pullup-Werte etc.

Dein Verfahren mit 81 schreiben, warten, zwei Byte lesen ist jedenfalls korrekt für den Sensor. Magst du vielleicht mal den Code online stellen und dann gucke ich was bei mir raus kommt?

Es gibt wohl auch offizielle Beispiele in C: https://www.robot-electronics.co.uk/htm/raspberry_pi_examples.htm - was kommt bei denen bei dir raus?

Hectic
25.06.2021, 11:50
Gerne, bin für jede Hilfe dankbar ;)



#!/usr/bin/perl

use warnings;
use strict;
use Time::HiRes ('usleep');
use RPi::I2C;

my $SF10 = RPi::I2C->new(0x70);
my $version = undef;
my $loopcount = 0;

while(1) {
system('clear');
$loopcount++;
printf("Loop: %d\n", $loopcount);

$version = $SF10->read_byte(0);
printf("SF10 Version: %d (0x%X)\n", $version, $version);

usleep(65000);

last if($loopcount > 100);
}


Ich bin vom Modul Device::I2C zum Modul RPi::I2C gewechselt, da dies wohl neuer ist und einfach um auszuprobieren ob es daran lag. Hat aber am Verhalten nichts geändert.
Momentan wird nur die Version des Sensors ausgelesen. Aber auch bei Entfernungen verhält es sich gleich. Nach der selben Zeit erscheinen völlig falsche Werte (jup, scheint Zeitabhängig, nicht Abhängig von den Zugriffen).
Oszilloskop habe ich leider keines. Evtl. habe ich auch einfach nur den Sensor geschossen, wüsste aber nicht wodurch :confused:

Bei dem Beispielprogramm in C kommen bei mir die selben schrägen Werte raus wie wenn mein Programm ein paar Leseversuche hinter sich hat (cooler Link übrigens!)

**** SRF02/10/235 example program ****
Software v: 133
Range was: 32768


- - - Aktualisiert - - -

Was mir noch einfällt: Evtl. könnte noch die Art meiner Stromversorgung eine Rolle spielen.

Das Ganze wird durch einen 12V Bleigelakku versorgt.
MD25 (Motortreiber) hängt direkt am Akku.
SRF10 und Raspi hängen über einen Step Down Wandler auf 5V dran.
Es werden also sämtliche "Geräte" individuell mit Strom versorgt. Aber es hängen natürlich alle drei am selben Bus.
Naiv wie ich bin, dachte ich, dass das schon so laufen sollte :cool: (abgesehen vom SRF10 tut es das ja auch).

Defiant
25.06.2021, 16:59
ok, ich probier das Montag mal aus. Ich kann zwar kein Perl, aber Programm sieht soweit gut aus.

Defiant
28.06.2021, 17:40
Witzig, ich habe das jetzt zwar auch nicht auf dem Oszi analysiert, aber diese Lesefehler riechen stark nach dem Clock stretching Bug [1]. Das Problem ist nicht neu, das Herabsetzen des I2C-Taktes bringt hier Abhilfe ohne Garantien zu geben, der Autor des Perl I2C-Modus beschreibt wie das geht und reduziert den Takt sogar auf 10kHz [2].


[1] http://www.advamation.de/technik/raspberrypi/rpi-i2c-bug.html
[2] https://metacpan.org/pod/RPi::I2C#Raspberry-Pi

Hectic
28.06.2021, 19:24
Super! Also eigentlich nicht, aber super, dass du dir so viel Mühe gegeben hast! Ich werde der Sache in diese Richtung weiter folgen und berichten wenn ich Erfolg hatte. Das kann aber etwas dauern. Vielen Dank, das hilft mir schon sehr weiter.

Hectic
29.06.2021, 18:31
Hi nochmal,

die Lösung, die Baudrate zu reduzieren funktioniert einwandfrei! Eine niedrige Baudrate stört wohl in den wenigsten Fällen weshalb dadurch zumindest mein Problem komplett behoben wird. Vielen Dank nochmal, dass du dir die Mühe gemacht hast! :)

oberallgeier
01.07.2021, 23:00
.. die Lösung, die Baudrate zu reduzieren funktioniert einwandfrei .. weshalb dadurch zumindest mein Problem komplett behoben wird ..Na gut dass es funktioniert (auch wenn ich als Fehlerquelle die Baudrate nicht sooo ganz verstehe). Frage: mit welcher Frequenz betreibst Du den I²C-Bus? Ich hatte mit meiner langen Busleitung auch mal Probleme (siehe hie (https://www.roboternetz.de/community/threads/59388-I%C2%B2C-mit-Bitrate-100-kHz-nur-mit-Treiber?p=565338&viewfull=1#post565338)r) und konnte den Fehler eindeutig mit den schlappen I²C-Flanken (-spitzen) bei hohen Frequenzen identifizieren. Ich nehme mal an, dass Du Deine Busaktivitäten nicht mit nem Oszi kontrolliert hast.

Defiant
02.07.2021, 07:26
Siehe obigen Link zu advamation.de. Ist der Takt für einen I2C-Slave zu schnell (er kann die Daten nicht rechtzeitig liefern) kann er diesen auf Low ziehen, das nennt man Clock stretching. Bei dem Raspberry Pi < 4 gibt es halt einen Bug, der Rpi erkennt das nicht und liest entsprechend falsche Daten. Das Problem konnte ich noch bei 100kHz nachstellen, bei 10kHz nicht.

Hectic
02.07.2021, 18:07
Huhu,

ich habe die Baudrate aus dem Beispiel (10000 Baud? / Hz?) übernommen. Ich betreibe derzeit nur 2 Slaves und das reicht mir dicke. Ich kann ja mal ausprobieren ab wann mein Sensor aussteigt. Könnte aber etwas dauern, bin zur Zeit etwas "zeitlos". Ein Oszi um das Signal zu prüfen steht mir leider nicht zur Verfügung. Meine Kabel sind recht kurz: Um die 10cm pro Slave.

Grüßle,
Hectic