illuminance on env shield seems not to be working

Hi,

I'm using a MKR WIFI 1010 and the ENV shield. I try to read the illuminance value amongst others.
The Board is positioned on a shelf in a bathroom. The bathroom has no windows and only a light, which is mostly turned off. The lux value doesn't seem to have any correspondence to the actual lighting situation in the room. I even tried to shine some led light of my mobile phone on the sensor which hadn't any effect at all.

I attached two screenshots of the lux value that I read in my code. The picture with the smaller time span has for sure a light turned on in that room at 7:19. On the larger time scale several people used the bathroom with the light turned on. In the night the room is dark even with opened door.

Am I doing something wrong here? Do I need to average that value? I would suppose to see a difference between turned on light and the night. Could the sensor be broken? Hope someone can help me out here.

#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
#include <Arduino_MKRENV.h>
#include <WiFiUdp.h>

int status = WL_IDLE_STATUS;                     // the Wifi radio's status
int backoff = 5000;

// Specify IP address or hostname
int humidity, lux, pressure, uva;
float temperature;

unsigned int localPort = 2390;      // local port to listen on
unsigned int remotePort = 2392;
unsigned int timelocalPort = 2391;      // local port to listen on
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte timepacketBuffer[ NTP_PACKET_SIZE];
WiFiUDP measDataUdp;
WiFiUDP TimeUdp;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  Serial.println("Current Firmware:");
  Serial.println(fv);
  Serial.println("Required Firmware");
  Serial.println(WIFI_FIRMWARE_LATEST_VERSION);
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(SECRET_SSID);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(SECRET_SSID, SECRET_PASS);

    delay(backoff);
  }

  // you're connected now, so print out the data:
  Serial.println("You're connected to the network");
  printCurrentNet();
  printWiFiData();

  //setup sensors
  if (!ENV.begin()) {
    Serial.println("Failed to initialize MKR ENV shield!");
    while(1);
 }

  //start udp
  Serial.println("Starting connection to data server...");
  // if you get a connection, report back via serial:
  measDataUdp.begin(localPort);

  Serial.println("Starting ntp udp socket...");
  TimeUdp.begin(timelocalPort);
}

void loop() {
  String meas_string, time_string, str_seconds = "";
  String hours, minutes, seconds = "";
  // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
  const unsigned long seventyYears = 2208988800UL;
  unsigned long secsSince1900, lowWord, highWord, epoch;

  Serial.println("Retrieving Time");
  sendNTPpacket(); // send an NTP packet to a time server
  // wait to see if a reply is available
  delay(1000);
  if (TimeUdp.parsePacket()) {
    Serial.println("packet received");
    // We've received a packet, read the data from it
    TimeUdp.read(timepacketBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    highWord = word(timepacketBuffer[40], timepacketBuffer[41]);
    lowWord = word(timepacketBuffer[42], timepacketBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    secsSince1900 = highWord << 16 | lowWord;
    Serial.print("Seconds since Jan 1 1900 = ");
    Serial.println(secsSince1900);

    // now convert NTP time into everyday time:
    Serial.print("Unix time = ");
    // subtract seventy years:
    epoch = secsSince1900 - seventyYears;
    // print Unix time:
    Serial.println(epoch);

    // print the hour, minute and second:
    hours = String((epoch  % 86400L) / 3600 + 2);
    minutes = String((epoch % 3600) / 60);
    seconds = String(epoch % 60);
    time_string = hours + ":" + minutes + ":" + seconds;
    Serial.println(time_string);
  }

  // wait ten seconds before asking for the time again
  delay(10000);
  Serial.println("Reading sensors...");
  humidity = int(ENV.readHumidity()); //in percent
  lux = int(ENV.readIlluminance());
  pressure = int(ENV.readPressure()); //in kPa
  temperature = ENV.readTemperature();
  uva = int(ENV.readUVA());

  Serial.print("Humidity relative[%]: ");
  Serial.println(humidity);
  Serial.print("Lux : ");
  Serial.println(lux);
  Serial.print("Pressure [kPa]: ");
  Serial.println(pressure);
  Serial.print("Temperature [C]: ");
  Serial.println(temperature);
  Serial.print("uva : ");
  Serial.println(uva);
  Serial.println("--------------");

  // send a reply, to the IP address and port that sent us the packet we received
  measDataUdp.beginPacket("buechse", remotePort);
  meas_string = String(epoch) + ";" + String(humidity) + ";" + String(lux) + ";" + String(pressure) + ";" + String(temperature) + ";" + String(uva) + ";" + 999; //999 is a placeholder for the infrared sensor
  measDataUdp.println(meas_string);
  measDataUdp.endPacket();
  delay(10000);
}

void printWiFiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP address : ");
  Serial.println(ip);

  Serial.print("Subnet mask: ");
  Serial.println((IPAddress)WiFi.subnetMask());

  Serial.print("Gateway IP : ");
  Serial.println((IPAddress)WiFi.gatewayIP());

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);
  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI): ");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type: ");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

// send an NTP request to the time server at the given address
void sendNTPpacket() {
  //Serial.println("1");
  // set all bytes in the buffer to 0
  memset(timepacketBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  //Serial.println("2");
  timepacketBuffer[0] = 0b11100011;   // LI, Version, Mode
  timepacketBuffer[1] = 0;     // Stratum, or type of clock
  timepacketBuffer[2] = 6;     // Polling Interval
  timepacketBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  timepacketBuffer[12]  = 49;
  timepacketBuffer[13]  = 0x4E;
  timepacketBuffer[14]  = 49;
  timepacketBuffer[15]  = 52;

  //Serial.println("3");

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  TimeUdp.beginPacket("pool.ntp.org", 123); //NTP requests are to port 123
  //Serial.println("4");
  TimeUdp.write(timepacketBuffer, NTP_PACKET_SIZE);
  //Serial.println("5");
  TimeUdp.endPacket();
  //Serial.println("6");
}

Are the other values OK? Post the serial output of let's say one minute!

Maybe I will be able to deliver these values tomorrow as this takes some effort on my side.
Yesterday I rearranged the env board so that it faces the light bulb directly, this should lead to 90 degree angle of the light rays and the board. I attached the time plot of that data which seems to show the adjustment of the position at 23:00 on 25 th of august. The value's amplitude oscillating around 700 seems bigger to me. The "pinch" shortly after 12 is actually where the light was on and I took a shower where the humidity was above 100% (at least that is what the humidity sensor said).

Do you suspect some crazy stuff happens on the udp transfer side or on the casting to string?

Do you suspect some crazy stuff happens on the udp transfer side or on the casting to string?

The UDP transfer isn't of interest yet as we're (hopefully) talking about the serial output only. The string conversion (casting is something different!) shouldn't pose problems.

Maybe I will be able to deliver these values tomorrow as this takes some effort on my side.

Why? You can make graphs of hours of sketch output but you cannot post the output of one minute? Please explain.

pylon:
Why? You can make graphs of hours of sketch output but you cannot post the output of one minute? Please explain.

Actually these plots are pretty easy to create. The data is send via udp and received on the pc via netcat which is one cmdline call. The csv is then read in a python script that barely has 80 lines of code where half of it is just copied and pasted for the different variables. It hosts the webserver and delivers these fancy graphs. Whereas my laptop is attached to a lot of cables and not easy too reach. I didn't want too really interrupt the temperature and moisture measurement also.

So here we go I saved some data via serial.

Here is the code that makes these graphs if you're interested.

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
import datetime
import pytz

app = dash.Dash()

temp_df = pd.read_csv('./temp_logging.log',sep=';')


pd.to_datetime(temp_df.epoch.values,unit='s').tz_localize('UTC').tz_convert('Europe/Berlin')

temp_df.epoch = pd.to_datetime(temp_df.epoch.values,unit='s').tz_localize('UTC').tz_convert('Europe/Berlin')
tz_aware_df = temp_df.set_index('epoch')


my_timezone = pytz.timezone('Europe/Berlin')
upper_boundary = my_timezone.localize(datetime.datetime.now())
lower_boundary = my_timezone.localize(datetime.datetime(2020,8,1))

outlier_filt = (temp_df.epoch > lower_boundary) & (temp_df.epoch < upper_boundary)
new_temp_df = temp_df.loc[outlier_filt]



app.layout = html.Div([
    html.Div([
    dcc.Graph(
        id='room_temp',
        figure={
            'data': [
                go.Scatter(
                    x=new_temp_df.epoch,
                    y=new_temp_df.room_temperature,
                    text='room_temp',

                )
            ]
        }
    )
    ]),
    html.Div([
    dcc.Graph(
        id='humidity',
        figure={
            'data': [
                go.Scatter(
                    x=new_temp_df.epoch,
                    y=new_temp_df.humidity,
                    text='humidity',

                )
            ]
        }
    )
    ]),
    html.Div([
    dcc.Graph(
        id='lux',
        figure={
            'data': [
                go.Scatter(
                    x=new_temp_df.epoch,
                    y=new_temp_df.lux,
                    text='lux',

                )
            ]
        }
    )
    ])
                      ])

if __name__ == '__main__':
    app.run_server(host='0.0.0.0', debug=True)

In serial_direct.log is what I logged on the serial, nothing changed on the setup in the bathroom. Same position of the controller and the board just the laptop attached (light was on)

In serial_float_direct.log you can see the same thing but the lux variable was a float.
After half the time I turned the light off, which made the room not completely dark but should be notable on the value.

serial_direct.txt (1.98 KB)

serial_float_direct.txt (5.5 KB)

Given that the illumination during these times was more or less constant I would say your sensor is broken.

I ordered another one to see if this one works better. The Board is only a couple of weeks old so warranty should help here. Thx for your support.