UVM30 sensor for esp32 (code)

I use a UVM30 sensor to measure UV measurements. The code on the internet is more for 5V and analog max 1023. However, I want to use it on ESP32, which goes to 3.3V and uses analog up to 4095. Does anyone have a code for the UVM30 sensor?

int uvAnalog=0;
float uvNapeti, uvIndex;
int uvIndexPole [12] = { 50, 227, 318, 408, 503, 606, 696, 795, 881, 976, 1079, 1170};

uvAnalog = analogRead(32);

  uvNapeti = uvAnalog * (3300.0 / 4095.0);
  if (uvNapeti > 1170) {
    uvNapeti = 1170;
  }
  int p;
  for (p = 0; p < 12; p++)
  {
    if (uvNapeti <= uvIndexPole[p]) 
    {
      uvIndex = p;
      break;
    }
  }
  if (p>0) {
    float rozdilIndexu=uvIndexPole[p]-uvIndexPole[p-1];
    float rozdilHodnot=uvNapeti-uvIndexPole[p-1];
    uvIndex+=(1.0/rozdilIndexu)*rozdilHodnot-1.0;
  }
  if (uvIndex < 0) {
    uvIndex = 0;
  } 

  Serial.println("UV index: " + String(uvIndex));

Hi @cevepe,

see if this link helps.

RV mineirin

If the sensor requires 5V, then use a voltage divider to bring the V's down.

I have a situation putting a 5V analog into a ESP32. I used a 10K to 10K divider.

I recommend using the ESP32's A:D API over using the Arduino ESP32 core functions.

Here is some code that you might use as a model.

#include <driver/adc.h>

void setup()
{
adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);// using GPIO 34 wind direction
  adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_11);// using GPIO 39 current
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);// using GPIO 36 battery volts
}

void fReadBattery( void * parameter )
{
  //float ADbits = 4096.0f;
  //float ref_voltage = 3.3f;
  float ADscale = 3.3f / 4096.0f;
  float adcValue = 0.0f;
  float offSET = 0.0f;
  const float r1 = 50500.0f; // R1 in ohm, 50K
  const float r2 = 10000.0f; // R2 in ohm, 10k potentiometer
  //float Vscale = (r1+r2)/r2;
  float Vbatt = 0.0f;
  int printCount = 0;
  float vRefScale = (3.3f / 4096.0f) * ((r1 + r2) / r2);
  uint64_t TimePastKalman  = esp_timer_get_time(); // used by the Kalman filter UpdateProcessNoise, time since last kalman calculation
  SimpleKalmanFilter KF_ADC_b( 1.0f, 1.0f, .01f );
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 1000; //delay for mS
  for (;;)
  {
    adc1_get_raw(ADC1_CHANNEL_0); //read and discard
    adcValue = float( adc1_get_raw(ADC1_CHANNEL_0) ); //take a raw ADC reading
    KF_ADC_b.setProcessNoise( (esp_timer_get_time() - TimePastKalman) / 1000000.0f ); //get time, in microsecods, since last readings
    adcValue = KF_ADC_b.updateEstimate( adcValue ); // apply simple Kalman filter
    Vbatt = adcValue * vRefScale;
    xSemaphoreTake( sema_CalculatedVoltage, portMAX_DELAY );
    CalculatedVoltage = Vbatt;
    xSemaphoreGive( sema_CalculatedVoltage );
    /*
      printCount++;
      if ( printCount == 3 )
      {
      log_i( "Vbatt %f", Vbatt );
      printCount = 0;
      }
    */
    TimePastKalman = esp_timer_get_time(); // time of update complete
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    //log_i( "fReadBattery %d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete( NULL );
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.