mikrocontroller.net

Forum: Analoge Elektronik und Schaltungstechnik Unklarheit Auslesen Zeilensensor LF1401


Autor: Christian Müller (Firma: magnetmotor.ch) (chregu) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe vor Jahren folgenden Zeilensensor gekauft:

http://static.mercateo.com/8c/6996b3ad28464d939bc1...

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:
'Pin: Name: USB4All:
'
'  1  SI      RB5    (Proc integrationsstart)
'  2  CLK     RB4    (Proc takteingang)
'  3  AO      RA0
'  4  VCC     +5V
'  5  RSET    GND
'  6  AGND    GND
'  7  GND     GND
'  8  DIS     GND

Repeat

  integrationsstart(1)

  Repeat
  
    takteingang(1)
    If loop% = 0
      integrationsstart(0)
    EndIf
    If loop% = 127
      integrationsstart(1)
    EndIf
    takteingang(0)

    analogread()
    datum$ = "Sensor# ";@Format$("000",loop%);": ";analogwert%;
    DrawText 20+((loop%\32)*150), 50+((loop% MOD 32)*8), datum$
    
    Inc loop%
  Until loop% >= 128
  
  loop% = 0
  WaitInput

Until %Key = 27
integrationsstart(0)
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?

: Bearbeitet durch User
Autor: Christian Müller (Firma: magnetmotor.ch) (chregu) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt habe ich das Ganze auf einem Arduino Nano umgesetzt:
int SI = 9;
int CLK = 8;
int analogPin = 0;
int val = 0;
int incomingByte = 0;   // für dummy read

void setup() {
  pinMode(CLK, OUTPUT);
  pinMode(SI, OUTPUT);
  Serial.begin(115200);
  delay(100);
  Serial.println("Drücke Enter für Datenempfang!");
}

void loop() {
  if (Serial.available() > 0) {      // nur wenn was empfangen
    incomingByte = Serial.read();    // dummy read
    digitalWrite(SI, HIGH);          // starte Integration

    for (int i=0; i <= 127; i++){
      digitalWrite(CLK, HIGH);       // setze Clock High
      if (i == 0) digitalWrite(SI, LOW);
      if (i == 127) digitalWrite(SI, HIGH);
      digitalWrite(CLK, LOW);        // setze Clock Low
      val = analogRead(analogPin);   // lies den Eingang
      Serial.print(val);             // und gib ihn aus
      if (i == 127)
      {
        Serial.println();
      }
      else
      {
        Serial.print(",");
      }
    }   
  }

}

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

Autor: Joe F. (easylife)
Datum:

Bewertung
0 lesenswert
nicht 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
digitalWrite(CLK, HIGH);       // setze Clock High
und
digitalWrite(CLK, LOW);        // setze Clock Low


einzubauen

: Bearbeitet durch User
Autor: Joe F. (easylife)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian Müller (Firma: magnetmotor.ch) (chregu) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

: Bearbeitet durch User
Autor: Christian Müller (Firma: magnetmotor.ch) (chregu) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
int SI = 9;
int CLK = 8;
int DIS = 10;
int analogPin = 0;
int val = 0;
int incomingByte = 0;                // für dummy read
unsigned long zeit;

void setup() {
  pinMode(CLK, OUTPUT);
  pinMode(SI, OUTPUT);
  pinMode(DIS, OUTPUT);
  digitalWrite(DIS, HIGH);            // setze Disable auf High
  Serial.begin(115200);
  delay(100);
  Serial.println("Drücke Enter für Datenempfang!");
}

void loop() {
  if (Serial.available() > 0) {      // nur wenn was empfangen
    incomingByte = Serial.read();    // dummy read
    digitalWrite(SI, HIGH);          // starte Integration

    for (int i=0; i <= 127; i++){
      digitalWrite(CLK, HIGH);       // setze Clock High
      if (i == 0) digitalWrite(SI, LOW);
      if (i == 127) digitalWrite(SI, HIGH);
      if (i == 125)
      {
        digitalWrite(DIS, LOW);
        zeit = micros();
      }
      if (i == 126)
      {
        digitalWrite(DIS, HIGH);
        zeit = micros() - zeit;
      }
      digitalWrite(CLK, LOW);        // setze Clock Low
      val = analogRead(analogPin);   // lies den Eingang
      Serial.print(val);             // und gib ihn aus
      if (i == 127)
      {
        Serial.println();
      }
      else
      {
        Serial.print(",");
      }
    }
    Serial.println(zeit);
  }

}

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.