Forum: Analoge Elektronik und Schaltungstechnik Unklarheit Auslesen Zeilensensor LF1401


von Christian M. (Gast)


Lesenswert?

Habe vor Jahren folgenden Zeilensensor gekauft:

http://static.mercateo.com/8c/6996b3ad28464d939bc17e037ed63c99/pdf/tpIC-Haus_Zeilensensor-LF1401_DE.pdf?v=2

Hier im Forum gibt's genau EINEN Post, wo dieser Sensor als einfach 
erwähnt wird:

Beitrag "Re: Linienerkennung"

Zwar ist das Datenblatt auf Deutsch, aber sogar für mich als 
deutschsprechender nicht eindeutig. Oder ich bin zu blöd...

Das fängt schon damit an, dass VCC und VDD in den Kenndaten sind, aber 
nur VDD herausgeführt sind, komischerweise aber AGND und GND separat. 
Wennschon umgekehrt, oder?

Wie auch immer, habe AGND und GND zusammen an GND und VDD an +5V.

Ueber USB4ALL und XProfan versuche ich nun auszulesen, so gut es mit der 
Prosa und Diagramm geht. Hier mal ein Ausschnitt (Pseudo-)Code:
1
'Pin: Name: USB4All:
2
'
3
'  1  SI      RB5    (Proc integrationsstart)
4
'  2  CLK     RB4    (Proc takteingang)
5
'  3  AO      RA0
6
'  4  VCC     +5V
7
'  5  RSET    GND
8
'  6  AGND    GND
9
'  7  GND     GND
10
'  8  DIS     GND
11
12
Repeat
13
14
  integrationsstart(1)
15
16
  Repeat
17
  
18
    takteingang(1)
19
    If loop% = 0
20
      integrationsstart(0)
21
    EndIf
22
    If loop% = 127
23
      integrationsstart(1)
24
    EndIf
25
    takteingang(0)
26
27
    analogread()
28
    datum$ = "Sensor# ";@Format$("000",loop%);": ";analogwert%;
29
    DrawText 20+((loop%\32)*150), 50+((loop% MOD 32)*8), datum$
30
    
31
    Inc loop%
32
  Until loop% >= 128
33
  
34
  loop% = 0
35
  WaitInput
36
37
Until %Key = 27
38
integrationsstart(0)
39
takteingang(0)

Resultat ist, dass im Ersten Durchgang analogread immer 0 liefert bis 
auf den letzten Pixel, der zeigt schon ~830. Und ab dem zweiten 
Durchgang sind alle Pixel immer voll (+/-930 von 1023). Auch 
abgedunkelt.

Was mache ich falsch in der Ansteuerung? Shutter ist doch sowas wie die 
Verschlusszeit, oder? Muss ich da was beachten? Machts das automatisch?

Wer im Text drauskommt ist gebeten, mir das auf Verständlich zu 
übersetzen :-))

Danke und Gruss Chregu

Edit: BTW: Kann jemand einen anderen, höherauflösenden (Pixelbreite 
<10µm) Zeilensensor empfehlen?

von Christian M. (Gast)


Lesenswert?

Jetzt habe ich das Ganze auf einem Arduino Nano umgesetzt:
1
int SI = 9;
2
int CLK = 8;
3
int analogPin = 0;
4
int val = 0;
5
int incomingByte = 0;   // für dummy read
6
7
void setup() {
8
  pinMode(CLK, OUTPUT);
9
  pinMode(SI, OUTPUT);
10
  Serial.begin(115200);
11
  delay(100);
12
  Serial.println("Drücke Enter für Datenempfang!");
13
}
14
15
void loop() {
16
  if (Serial.available() > 0) {      // nur wenn was empfangen
17
    incomingByte = Serial.read();    // dummy read
18
    digitalWrite(SI, HIGH);          // starte Integration
19
20
    for (int i=0; i <= 127; i++){
21
      digitalWrite(CLK, HIGH);       // setze Clock High
22
      if (i == 0) digitalWrite(SI, LOW);
23
      if (i == 127) digitalWrite(SI, HIGH);
24
      digitalWrite(CLK, LOW);        // setze Clock Low
25
      val = analogRead(analogPin);   // lies den Eingang
26
      Serial.print(val);             // und gib ihn aus
27
      if (i == 127)
28
      {
29
        Serial.println();
30
      }
31
      else
32
      {
33
        Serial.print(",");
34
      }
35
    }   
36
  }
37
38
}

Das Resultat ist wieder genau das Gleiche! Und die Zykluszeit ist jetzt 
im ms-Bereich!

Kann der Sensor immer noch übersteuern?

Muss ich den Shutter-Pin (DIS) verwenden (momentan auf GND)?

Gruss Chregu

von Joe F. (easylife)


Lesenswert?

Ich sehe keine Angaben im Datenblatt, dass der Sensor die Belichtung 
automatisch regeln kann.
Stutzig macht natürlich, dass auch bei abgedunkeltem Sensor noch das 
hohe Signal herauskommt.

Allerdings ist in deinem Code nichts zu sehen, was die Timingconstraints 
des Digitalinterfaces einhalten würde.

1)
CLK ist auf max. 5 MHz spezifiziert, d.h. aber auch dass sowohl HIGH als 
auch LOW Phase nicht kürzer als 100ns sein darf.
Miss mal deine HIGH Phase der CLK...

2)
Bild 3 "Zeitdiagramm" und die darüber befindliche Tabelle geben Zeiten 
vor für SI in Bezug zur CLK (tset und thold).
Insbesondere "thold >= 50ns" sehe ich bei dir nicht implementiert.
SI geht bei dir evtl. viel zu früh auf LOW.

und
3) Seite 7/9
"Das Löschen der Integrations-Kapazitäten geschieht mit einem einen Takt 
langen Reset-Signal (NRCI=0) ..."

Sehe ich auch nicht in deinem Code.
Das erklärt dann, warum sich die Kapazitäten einfach nur aufladen...

---
Update zu 3): sorry, das ist natürlich Quatsch. NRCI muss ein internes 
Signal sein, gibt ja keinen Pin dafür.

Ich würde zunächst mal versuchen ein 100ns Delay nach
1
digitalWrite(CLK, HIGH);       // setze Clock High
und
1
digitalWrite(CLK, LOW);        // setze Clock Low


einzubauen

: Bearbeitet durch User
von Joe F. (easylife)


Lesenswert?

Achso, nochwas:
Die Integrationszeit bestimmt sich offenbar über die CLK Geschwindigkeit 
und der Integrationsvorgang wird immer automatisch neu gestartet.

D.h. deine Zykluszeit von im ms-Bereich ist natürlich viel zu lang.

Die Serial.print() Aufrufe müssen aus der Auslese-Funktion raus.
Die Pixelwerte müssen erstmal zwischengespeichert weden, um sie dann 
hinterher langsam per Serial.print() zu übertragen.

Du musst dann zum Auslesen der Pixel jeweils 2x direkt hintereinander 
auslesen.
Beim ersten Auslesen wirst du wieder ein komplett überbelichtetes Bild 
bekommen (da die Serial.print() dazwischen waren), und erst beim 2. 
Auslesen stimmt die Belichtung.
Wenn du die CLK nicht schnell genug hinbekommst, musst du die 
Integrationszeit mit Hilfe von DIS verkürzen.

von Christian M. (Gast)


Lesenswert?

Joe F. schrieb:
> Miss mal deine HIGH Phase der CLK...

Joe F. schrieb:
> Insbesondere "thold >= 50ns" sehe ich bei dir nicht implementiert.
> SI geht bei dir evtl. viel zu früh auf LOW.

Ja messen kann ich hier nicht. Bin extern. Aber ich habe gedacht, dass 
das Arduino-Framework auch auf dem digitalWrite() genug Overhead hat für 
die nötige Verzögerung.

Joe F. schrieb:
> NRCI muss ein internes
> Signal sein, gibt ja keinen Pin dafür.

Schon das finde ich verwirrend, diese gemischten Signale intern und 
extern.

Joe F. schrieb:
> Die Integrationszeit bestimmt sich offenbar über die CLK Geschwindigkeit
> und der Integrationsvorgang wird immer automatisch neu gestartet.

Soweit habe ich das begriffen.

Joe F. schrieb:
> D.h. deine Zykluszeit von im ms-Bereich ist natürlich viel zu lang.

Dass ich mir eine Vorstellung machen kann: In welchem Bereich bewegt 
sich so eine Belichtungszeit dass man bei Zimmerhelligkeit ein 
ausgewogenes "Bild" bekommt?

Danke Gruss Chregu

Edit: +Habe mal schnell zwei micros() reingemacht. Zykluszeit ist ca. 
40ms

von Christian M. (Gast)


Lesenswert?

Joe F. schrieb:
> Wenn du die CLK nicht schnell genug hinbekommst, musst du die
> Integrationszeit mit Hilfe von DIS verkürzen.

Genau das wars! Habe jetzt den DIS auch implementiert:
1
int SI = 9;
2
int CLK = 8;
3
int DIS = 10;
4
int analogPin = 0;
5
int val = 0;
6
int incomingByte = 0;                // für dummy read
7
unsigned long zeit;
8
9
void setup() {
10
  pinMode(CLK, OUTPUT);
11
  pinMode(SI, OUTPUT);
12
  pinMode(DIS, OUTPUT);
13
  digitalWrite(DIS, HIGH);            // setze Disable auf High
14
  Serial.begin(115200);
15
  delay(100);
16
  Serial.println("Drücke Enter für Datenempfang!");
17
}
18
19
void loop() {
20
  if (Serial.available() > 0) {      // nur wenn was empfangen
21
    incomingByte = Serial.read();    // dummy read
22
    digitalWrite(SI, HIGH);          // starte Integration
23
24
    for (int i=0; i <= 127; i++){
25
      digitalWrite(CLK, HIGH);       // setze Clock High
26
      if (i == 0) digitalWrite(SI, LOW);
27
      if (i == 127) digitalWrite(SI, HIGH);
28
      if (i == 125)
29
      {
30
        digitalWrite(DIS, LOW);
31
        zeit = micros();
32
      }
33
      if (i == 126)
34
      {
35
        digitalWrite(DIS, HIGH);
36
        zeit = micros() - zeit;
37
      }
38
      digitalWrite(CLK, LOW);        // setze Clock Low
39
      val = analogRead(analogPin);   // lies den Eingang
40
      Serial.print(val);             // und gib ihn aus
41
      if (i == 127)
42
      {
43
        Serial.println();
44
      }
45
      else
46
      {
47
        Serial.print(",");
48
      }
49
    }
50
    Serial.println(zeit);
51
  }
52
53
}

Die Shutter-Zeit liegt jetzt bei 340µs und die Belichtung liegt bei 
düsterem Zimmer im mittleren Bereich!

Jetzt könnte ich noch mit Zwischenspeichern optimieren, aber 1. kommt 
die Software in einen PIC implementiert und 2. kann ich jetzt auf dem 
Host-PC rumspielen, ob das auch als als Dickenmessung (von 
3D-Drucker-Filament) taugt...

Vielen Dank für die Tipps!

Gruss Chregu

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.