mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Farbsensor BH1745NUC


Autor: C-manager (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo miteinander
Ich nehme momentan den BH1745NUC Fahrbsensor von ROHM in betrieb. Das 
Programm habe ich dafür schon geschrieben wo wie es eigentlich das 
datenblatt verlangt. Mit diesem Code gelang mir auch die je 2 8Bit werte 
auszulesen und zu einem 16Bit Wert zu konvertieren. Jedoch bemerkte ich 
schnell das dise Werte nicht stimmen konnten. Bei genauerer Analyse, 
bemerkte ich das die beiden 8Bit Werte je an einem Anschlag sind und 
immer für einen Überlauf sorgen. Das hat zur vollge das die werte immer 
herumzapplen von dem einten extrem ins andere. Meine Frage hatte jemand 
mit dem Sensor schon erfahrung oder sieht jemand au fer seite 12 im 
Datenblatt ob ich diesen Ablauf falsch verstanden habe. Oder hat einer 
eine mögliche erklährung für die Falsche Wertausgabe? Datenblatt im 
Anhang und Code folgt.

int main(void)
{
    InitDriverColor();            //Einstellungen initialisieren
  i2c_init();            
  clear_lcd_f();
  
  unsigned char RedLow = 0;
  unsigned char RedHigh = 0;
  int Redfine = 0;
  unsigned char GreenLow = 0;
  unsigned char GreenHigh = 0;
  int Greenfine = 0;
  unsigned char BlueLow = 0;
  unsigned char BlueHigh = 0;
  int Bluefine = 0;
  
  unsigned char noGreen = 0;
  unsigned char noRed = 0;
  unsigned char noBlue = 0;
  
  
    while(1)
    {
    
      i2c_start(0x70,0);      //Adress
     i2c_write(0x41);      //Config1
      i2c_write(0x00);
    
    i2c_write(0x42);      //config2
    i2c_write(0x11);
    
    i2c_write(0x44);      //config3
    i2c_write(0x02);  
    i2c_stop();
    
    i2c_start(0x70,0);      //Adress
    i2c_write(0x50);      //register begin
    wait_5ms(1);
  
    i2c_start(0x70,1);      //read register
    wait_5ms(10);
    RedLow = i2c_read(1);    //Register 50
    RedHigh = i2c_read(1);    //Register 51
  
    GreenLow = i2c_read(1);    //Register 52
    GreenHigh = i2c_read(1);  //Register 53
    
    BlueLow = i2c_read(1);    //Register 54
    BlueHigh = i2c_read(0);    //Register 55

    i2c_stop();
    
    
    Redfine = ((RedHigh <<8) | RedLow);
    Greenfine = ((GreenHigh <<8) | GreenLow);
    Bluefine = ((BlueHigh <<8) | BlueLow);
    
    write_zahl(3,1,RedHigh,4,0,0);
    write_zahl(3,7,RedLow,4,0,0);
    
    write_text(1,0,"R");
    write_zahl(1,1,Redfine,4,0,0);
    
    write_text(1,6,"G");
    write_zahl(1,7,Greenfine,4,0,0);
    
    write_text(1,12,"B");
    write_zahl(1,13,Bluefine,4,0,0);
  
  }      
}


Autor: void (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C-manager schrieb:
> sieht jemand au fer seite 12 im Datenblatt

Dies:
"main write format
BH1745NUC continues to receive data with address increments until master 
issues stop condition.
Write cycle is 40h -41h -42h -43h ...57h -58h [...]"

hätte ich so verstanden, dass du nicht immer die nächste Register 
Adresse mitgeben musst, wegen automatischem Increment.
Alternativ eben ein Stop einfügen.
i2c_start(0x70,0);      //Adress
i2c_write(0x41);      //Config1
i2c_write(0x00);
i2c_stop();

i2c_start(0x70,0);      //Adress
i2c_write(0x42);      //config2
i2c_write(0x11);
i2c_stop();

i2c_start(0x70,0);      //Adress
i2c_write(0x44);      //config3
i2c_write(0x02);  
i2c_stop();

oder
i2c_start(0x70,0);      //Adress
i2c_write(0x41);      //Config1 - register address 41
i2c_write(0x00);      // Config 1 value (for reg addr 41)
i2c_write(0x11);      // Config 2 value (for reg addr 42)
i2c_write(0x00);      // dummy (value for register address 43)
i2c_write(0x02);      // Config 3 value (for reg addr 44)
i2c_stop();


C-manager schrieb:
> unsigned char RedHigh = 0;
> int Redfine = 0;
> [...]
> Redfine = ((RedHigh <<8) | RedLow);

Bist du sicher das beim Schieben von unsigned char RedHigh etwas übrig 
bleibt?

Autor: C-manager (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem automatischen increment hab ich jetzt mal so gemacht. so 
zählt es automatisch ja hoch. hat aber an der Ausgabe nicht geändert. 
werde mal das ansehen mit dem unsigned typ das ist ein guter Hinweis. 
werde wieder zurück kommen wen es nicht läuft.

Autor: C-manager (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich ausprobiert mit den Datentypen jedoch mit int funktioniert dies 
auch nicht. schon die Werte die von dem Sensor kommen sind eigenartig.

Autor: ÄXl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C-manager schrieb:
> Ich nehme momentan den BH1745NUC Fahrbsensor von ROHM in betrieb.
> ...
> Bei genauerer Analyse, bemerkte ich das die beiden 8Bit Werte je an
> einem Anschlag sind und immer für einen Überlauf sorgen. Das hat zur
> vollge das die werte immer herumzapplen von dem einten extrem ins andere.

Da bist du den Werbefuzies auf den Leim gegangen. Der Sensor ist kein 
Farbsensor, sondern ein vierkanaliger Helligkeitssensor, der die 
integrale Beleuchtungssträrke für vier verschiedenen Spektralbereichen 
bestimmt.

Stabile Helligkeitswerte auf den Einzelkanälen bekommst du nur, wenn du 
den Sensor mit sauberem Gleichlicht beleuchtest, dem kein 
Wechsellichtanteil überlagert ist. Stabile Farbwerte erhälst du erst, 
wenn du Verhältnisse der gemessenen Werte betrachtest.

Autor: C-manager (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Sensor liefert 4 Bereiche diese sind auch im Datenblatt festgehalten 
max und min. Doch die werte die ich direkt aus dem Sensor entnehme sind 
bei 0 oder 255 wen man diese noch schiebt liegt der bereich bei 0 und 
65000. und nicht bei ca 2000 und 3800. Vorallem springen die Werte immer 
über den Überlauf, so das immer der maximale oder minimale wert 
angegeben wird.

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C-manager schrieb:
> Ich nehme momentan den BH1745NUC Fahrbsensor von ROHM in betrieb. Das
> Programm habe ich dafür schon geschrieben wo wie es eigentlich das
> datenblatt verlangt.

Warum probierst du es nicht erstmal mit einer (höchstwahrscheinlich) 
funktionsfähigen Bibliothek, bevor du das Rad neu erfindest.
https://github.com/jgromes/RohmMultiSensor

Autor: C-manager (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil Arduino mit verpackten eingebundenen Funktionen. Deswegen.

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C-manager schrieb:
> weil Arduino mit verpackten eingebundenen Funktionen. Deswegen.

Um zu gucken, ob deine HW vernünftig läuft und die von dir generierte 
I2C-Steuersequenz irgendwelche Ähnlichkeiten mit einer funktionierenden 
Ansteuerung hatte, sollte das ziemlich egal sein.
Es hält dich auch keiner auf, die "verpackten eingebundenen Funktionen" 
durch eigenen zu ersetzen, wenn es dann läuft.

Autor: void (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sehe ich ähnlich wie Wolfgang. Nur weil irgendwo Arduino 
drangeschrieben wurde, sollte dich das nicht davon abhalten dir mal 
anzuschauen wie der Sensor dort angesprochen wird.

Um konkret zu sein, diese Datei zweit sehr einfach wie es gehen sollte. 
Auch liesse sich die Datei mit einem Fingerstrich in ein 'normalen' 
C-Code verwandeln.

https://github.com/jgromes/RohmMultiSensor/blob/ma...

Auf den relevanten Teil gekürzt (s.u.) zeigt sich auch gleich wie 
ähnlich der Code zu dem von C-manager (Gast) ist.
Einzig die Gain Einstellung ist bei Faktor 16, im oben stehenden Code 
ist diese Faktor 2.
//Initialization function
    uint8_t init(uint8_t measurementTime = BH1745NUC_MEAS_TIME_160_MS) {
    //check manufacturer and part ID
    [...]    
    //set control registers according to datasheet and user settings
    setRegValue(_address, BH1745NUC_REG_MODE_CONTROL_1, measurementTime, 2, 0);
    setRegValue(_address, BH1745NUC_REG_MODE_CONTROL_2, BH1745NUC_RGBC_ON | BH1745NUC_ADC_GAIN_16, 4, 0);
    setRegValue(_address, BH1745NUC_REG_MODE_CONTROL_3, BH1745NUC_MODE_CONTROL_3);;
    [...]
    }
[...]   
    //Measurement function
    uint8_t measure(void) {
    //TODO: implement interrupt
     
    //read measured RGBC value
    red = ((uint16_t)getRegValue(_address, BH1745NUC_REG_RED_DATA_MSB) << 8) | getRegValue(_address, BH1745NUC_REG_RED_DATA_LSB);
    green = ((uint16_t)getRegValue(_address, BH1745NUC_REG_GREEN_DATA_MSB) << 8) | getRegValue(_address, BH1745NUC_REG_GREEN_DATA_LSB);
    blue = ((uint16_t)getRegValue(_address, BH1745NUC_REG_BLUE_DATA_MSB) << 8) | getRegValue(_address, BH1745NUC_REG_BLUE_DATA_LSB);
    clear = ((uint16_t)getRegValue(_address, BH1745NUC_REG_CLEAR_DATA_MSB) << 8) | getRegValue(_address, BH1745NUC_REG_CLEAR_DATA_LSB);
}

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.