Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with uv.begin(VEML6070_x_T); #8

Open
eryk4pdh opened this issue May 12, 2019 · 16 comments
Open

Problem with uv.begin(VEML6070_x_T); #8

eryk4pdh opened this issue May 12, 2019 · 16 comments
Assignees

Comments

@eryk4pdh
Copy link

eryk4pdh commented May 12, 2019

Setting the integration time doesn't seem to make an effect on the output value.
changing VEML6070_1_T -> VEML6070_2_T should yield in doubling of the output, but it doesn't in my case.

Tested against a simple code which changes the Integration Time every time it's uploaded...

#include <Wire.h>

#define VEML6070_ADDR_ARA       (0x18 >> 1)
#define VEML6070_ADDR_CMD       (0x70 >> 1)
#define VEML6070_ADDR_DATA_LSB  (0x71 >> 1)
#define VEML6070_ADDR_DATA_MSB  (0x73 >> 1)

// VEML6070 command register bits
#define VEML6070_CMD_WDM        0x02
#define VEML6070_CMD_SD         0x01
#define VEML6070_CMD_IT_0_5T    0x00
#define VEML6070_CMD_IT_1T      0x04
#define VEML6070_CMD_IT_2T      0x08
#define VEML6070_CMD_IT_4T      0x0C
#define VEML6070_CMD_DEFAULT (VEML6070_CMD_WDM | VEML6070_CMD_IT_1T)

byte cmd = VEML6070_CMD_DEFAULT;

void setup()
{
  
  Serial.begin(9600); 
  while(!Serial);
  Serial.println(cmd,BIN);

  Wire.begin(); 
  Wire.requestFrom(VEML6070_ADDR_ARA,1);

  Wire.beginTransmission(VEML6070_ADDR_CMD);
  Wire.write(cmd);
  Serial.println(Wire.endTransmission());

  
}

void loop()
{
  uint8_t X0,X1;
  
  Wire.requestFrom(0x39,1); 
  X0 = Wire.read(); 
  
  Wire.requestFrom(0x38,1);  
  X1 = Wire.read();   
  
  Wire.endTransmission();
  
  Serial.print("X0= ");
  Serial.print(X0);
  Serial.print("   X1= ");
  Serial.println(X1);
  
  delay(500);
}
@eecharlie
Copy link

eecharlie commented May 13, 2019

Hi, I just took a quick glance at your code and wanted to offer the following:

-Why are you using code in which you define all the VEML6070 registers & commands yourself, and in fact don't use the VEML6070 library at all? I'd recommend you create a failing example case using the library. This lets us maximally leverage code that's been validated, instead of re-checking all your definitions. While you may be following the same steps as the library's uv.begin(), everyone looking at your code has to re-confirm that for themselves.

-Do you have a more common board like the Arduino Uno you can test with, in the unlikely case it's actually a processor idiosyncrasy?

-Can you please provide an example that can be run as-is (without changing a compile-time constant and re-running) to reveal the erroneous behavior, and include in comments or in println() what you expect and what the actual output is? For your example, it looks like you'll need to call begin() at least twice to change the integration time.

@eryk4pdh
Copy link
Author

eryk4pdh commented May 13, 2019

Sorry I maybe didn't make it clear:

  1. I made his sample code as it was trying to find the issue with the library (quick and dirty to see it it was a hardware issue or software) -> this allowed me to prove my Hardware is ok and the issue is with the VEML6070 library

  2. I need to have a look for ATMEGA328P based board, but I wanted it to work in the M0 core as I need some if the processing power and memory for the other part of the project I am doing (I need a nice GUI with a screen)

  3. Not sure if I understand the question but originally I tried to use this

velmtest.ino example;

#include "Adafruit_VEML6070.h"

Adafruit_VEML6070 uv = Adafruit_VEML6070();

void setup() {
  Serial.begin(9600);
  Serial.println("VEML6070 Test");
  uv.begin(VEML6070_4_T);  
}


void loop() {
  Serial.print("UV light level: "); Serial.println(uv.readUV());
  
  delay(1000);
}```

I also just tried to use uv.begin(xxx) twice in this code and it didn't seem to have an effect.

@eryk4pdh
Copy link
Author

When running uv.begin(VEML6070_2_T); i see this on I2C:
Screenshot 2019-05-13 at 09 38 18

When I run my example I see this:
Screenshot 2019-05-13 at 09 38 46

It seems like the uv.begin() doesn't actually send the 2T value 0x0A to the configuration register?

@eecharlie
Copy link

It looks like an Adafruit developer has been assigned to this so I will probably step back.

I didn't completely follow your last two comments. The I2C bus capture is really helpful though - what tool is that?
I agree that something seems wrong if the library appears to setup a write to the command register but then doesn't write. From the source code, it's clear that's not what it should be doing. I'm also confident that in my use of the library, this basic feature has worked.
In your I2C capture, what's the significance of "Setup Write to [0xNN]" versus "Write [0xNN]"?

Do the unit tests included with the library work for you?

You might consider writing another unit test that passes in a dummy i2c bus object (must be defined by you) you can then use to capture and check the i2c bus activity, and then you can compare exactly what the library sends to the bus compared to what you expect, and what is sent in your example code.

@eryk4pdh
Copy link
Author

Hey I use a logic analyser and software from here: http://saleae.com

I stand to be corrected but I think the difference is that setup write usually points to the register to were you want to write / read, almost like setting a pointer to a specific i2c device, and then you need to write the data to that register.

However the VEML607x family seem to work in slightly different way (this is my understanding of the data sheet, might be wrong) they expose the registers as device address... try doing an I2C bus scan and you will see the registers sitting on the bus the device with a dedicated address which is a bit odd. So I skip the setup write and just dump data with a write

I didn't try anything else so far

@eecharlie
Copy link

eecharlie commented May 17, 2019

I think you are correct. Most I2C devices follow a process where you address the device, then specify the address of a register on the device, then do a read or write operation. The VEML6070 simplifies this by using multiple device addresses instead of internal register addresses, and I think this is technically a simpler derivative protocol than full I2C. The difference may be in start/stop signaling. I'm not immediately finding a reference on this. However, I asked because shouldn't your bus analyzer label the transactions the same way in both cases?

What I would do in your shoes is start with a complete known working configuration (code+hardware) from the unit tests or example code, and then make the most marginal modifications possible one at a time, until you find out exactly what smallest change breaks expected behavior. This should include running the code on an ATMega platform to start with if at all possible. When you get to the simplest small change to a familiar example that breaks it, post the complete working example & steps to cause failure.

I do not have time right now to do this myself to help you troubleshoot. I highly recommend starting from the unit tests included with the library. I notice you still haven't answered my question about whether the unit tests pass for you. Please run /examples/unittests/unittests.ino and see what you get.

@jorisvervuurt
Copy link

jorisvervuurt commented Dec 24, 2020

I know this is an old (but still open) issue, but I’m running into the same issue. Looking at the code, I see that the writeCommand always writes the value of _commandRegister.reg. There is a struct (_commandRegister.bit) in which values are set, but they are never used when writing to the I2C device. The value of reg is set to 0x02 in the constructor but never updated anywhere, so this is the only value that gets written to the device.

Note that I’m not really a C developer, so if I’m overlooking something please let me know...

Looking through the code, it seems it isn’t a finished piece (e.g. the shutdown feature won’t work either). @ladyada is there any chance of this getting finished properly? Thanks! :-)

@ladyada
Copy link
Member

ladyada commented Dec 24, 2020

if someone can submit a PR that would be ideal, we can review it!

@jorisvervuurt
Copy link

if someone can submit a PR that would be ideal, we can review it!

Unfortunately I think I’m not the right person for that task, perhaps you or a colleague at Adafruit can look at it, @ladyada? Thanks and happy holidays! ;-)

@ladyada
Copy link
Member

ladyada commented Dec 24, 2020

we'll add to our list but there's no ETA... this chip got discontinued :(

@jorisvervuurt
Copy link

we'll add to our list but there's no ETA... this chip got discontinued :(

Hmm, I didn’t notice that. Do you know of any alternative for UVA measurement?

@ladyada
Copy link
Member

ladyada commented Dec 24, 2020

we think the LTR-390 is the last i2c UV chip, we're working on the breakout right now! very frustrating, UV chips are constantly being discontinued

@jorisvervuurt
Copy link

@ladyada Okay, thanks. Unfortunately, the LTR-390 is not usable in our project due to the different sensitivity of the sensor. The VEML6070 is ideal though... :-(

@eecharlie
Copy link

If you’d like to tell me more about your application I can see if I have source code or documented solutions to unreliable device behavior. I put this sensor (or the 6075, I forget) in a commercial product a few years ago. Please direct message or email.

@jorisvervuurt
Copy link

If you’d like to tell me more about your application I can see if I have source code or documented solutions to unreliable device behavior. I put this sensor (or the 6075, I forget) in a commercial product a few years ago. Please direct message or email.

Thanks for the offer, but that's not needed. I'm currently writing my own implementation in Node.js (using the i2c-bus package). Will release it once it's finished.

@jorisvervuurt
Copy link

jorisvervuurt commented Jan 1, 2021

@ladyada @eecharlie Just published my own implementation as a Node.js package to npm: https://www.npmjs.com/package/jvsveml6070

It implements everything per the datasheet and Application Note and works with any breakout (including the Adafruit one) or custom VEML6070 implementation. Even supports different RSET resistor values. ;-)

Happy 2021!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants