Forum: Mikrocontroller und Digitale Elektronik Farbsensor BH1745NUC


von C-manager (Gast)


Angehängte Dateien:

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.
1
int main(void)
2
{
3
    InitDriverColor();            //Einstellungen initialisieren
4
  i2c_init();            
5
  clear_lcd_f();
6
  
7
  unsigned char RedLow = 0;
8
  unsigned char RedHigh = 0;
9
  int Redfine = 0;
10
  unsigned char GreenLow = 0;
11
  unsigned char GreenHigh = 0;
12
  int Greenfine = 0;
13
  unsigned char BlueLow = 0;
14
  unsigned char BlueHigh = 0;
15
  int Bluefine = 0;
16
  
17
  unsigned char noGreen = 0;
18
  unsigned char noRed = 0;
19
  unsigned char noBlue = 0;
20
  
21
  
22
    while(1)
23
    {
24
    
25
      i2c_start(0x70,0);      //Adress
26
     i2c_write(0x41);      //Config1
27
      i2c_write(0x00);
28
    
29
    i2c_write(0x42);      //config2
30
    i2c_write(0x11);
31
    
32
    i2c_write(0x44);      //config3
33
    i2c_write(0x02);  
34
    i2c_stop();
35
    
36
    i2c_start(0x70,0);      //Adress
37
    i2c_write(0x50);      //register begin
38
    wait_5ms(1);
39
  
40
    i2c_start(0x70,1);      //read register
41
    wait_5ms(10);
42
    RedLow = i2c_read(1);    //Register 50
43
    RedHigh = i2c_read(1);    //Register 51
44
  
45
    GreenLow = i2c_read(1);    //Register 52
46
    GreenHigh = i2c_read(1);  //Register 53
47
    
48
    BlueLow = i2c_read(1);    //Register 54
49
    BlueHigh = i2c_read(0);    //Register 55
50
51
    i2c_stop();
52
    
53
    
54
    Redfine = ((RedHigh <<8) | RedLow);
55
    Greenfine = ((GreenHigh <<8) | GreenLow);
56
    Bluefine = ((BlueHigh <<8) | BlueLow);
57
    
58
    write_zahl(3,1,RedHigh,4,0,0);
59
    write_zahl(3,7,RedLow,4,0,0);
60
    
61
    write_text(1,0,"R");
62
    write_zahl(1,1,Redfine,4,0,0);
63
    
64
    write_text(1,6,"G");
65
    write_zahl(1,7,Greenfine,4,0,0);
66
    
67
    write_text(1,12,"B");
68
    write_zahl(1,13,Bluefine,4,0,0);
69
  
70
  }      
71
}

von void (Gast)


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.
1
i2c_start(0x70,0);      //Adress
2
i2c_write(0x41);      //Config1
3
i2c_write(0x00);
4
i2c_stop();
5
6
i2c_start(0x70,0);      //Adress
7
i2c_write(0x42);      //config2
8
i2c_write(0x11);
9
i2c_stop();
10
11
i2c_start(0x70,0);      //Adress
12
i2c_write(0x44);      //config3
13
i2c_write(0x02);  
14
i2c_stop();

oder
1
i2c_start(0x70,0);      //Adress
2
i2c_write(0x41);      //Config1 - register address 41
3
i2c_write(0x00);      // Config 1 value (for reg addr 41)
4
i2c_write(0x11);      // Config 2 value (for reg addr 42)
5
i2c_write(0x00);      // dummy (value for register address 43)
6
i2c_write(0x02);      // Config 3 value (for reg addr 44)
7
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?

von C-manager (Gast)


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.

von C-manager (Gast)


Lesenswert?

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

von ÄXl (Gast)


Lesenswert?


von Wolfgang (Gast)


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.

von C-manager (Gast)


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.

von Wolfgang (Gast)


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

von C-manager (Gast)


Lesenswert?

weil Arduino mit verpackten eingebundenen Funktionen. Deswegen.

von Wolfgang (Gast)


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.

von void (Gast)


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/master/src/sensors/BH1745NUC.cpp

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.
1
//Initialization function
2
    uint8_t init(uint8_t measurementTime = BH1745NUC_MEAS_TIME_160_MS) {
3
    //check manufacturer and part ID
4
    [...]    
5
    //set control registers according to datasheet and user settings
6
    setRegValue(_address, BH1745NUC_REG_MODE_CONTROL_1, measurementTime, 2, 0);
7
    setRegValue(_address, BH1745NUC_REG_MODE_CONTROL_2, BH1745NUC_RGBC_ON | BH1745NUC_ADC_GAIN_16, 4, 0);
8
    setRegValue(_address, BH1745NUC_REG_MODE_CONTROL_3, BH1745NUC_MODE_CONTROL_3);;
9
    [...]
10
    }
11
[...]   
12
    //Measurement function
13
    uint8_t measure(void) {
14
    //TODO: implement interrupt
15
     
16
    //read measured RGBC value
17
    red = ((uint16_t)getRegValue(_address, BH1745NUC_REG_RED_DATA_MSB) << 8) | getRegValue(_address, BH1745NUC_REG_RED_DATA_LSB);
18
    green = ((uint16_t)getRegValue(_address, BH1745NUC_REG_GREEN_DATA_MSB) << 8) | getRegValue(_address, BH1745NUC_REG_GREEN_DATA_LSB);
19
    blue = ((uint16_t)getRegValue(_address, BH1745NUC_REG_BLUE_DATA_MSB) << 8) | getRegValue(_address, BH1745NUC_REG_BLUE_DATA_LSB);
20
    clear = ((uint16_t)getRegValue(_address, BH1745NUC_REG_CLEAR_DATA_MSB) << 8) | getRegValue(_address, BH1745NUC_REG_CLEAR_DATA_LSB);
21
}

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.