Need help with sketch?

Hi.

I have written a sketch for an Arduino Uno R3 + UV sensor (UVMS0A) Part myself, and part borrowed for an educational site on the web, this is the final sensor for my weather station, i have successfully read a BME 280 Temp, Humidity & Air Pressure, this would be the icing on the cake.

The problem i have is i cannot get the LCD to display the UV Index correctly, and what is displayed seems to be scrolling?i have tried many things, but now my brain is on overload. i need help with the sketch.

I have uploaded my sketch, and a j peg of what the LCD is displaying.

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity
 
void setup()
{
   
lcd.begin(20,4);
lcd.backlight();
lcd.setCursor(0,0 );        //Third column, first row
lcd.print("UV :");

delay (2000);               //delay 2 seconds

}

void loop() {

  int sensorValue;
  sensorValue = analogRead(A0);   //connect UV sensors to Analog A0    
  lcd.println(sensorValue);       //print the value to serial  
  
  delay(2000);      

 
  String readSensor();
  String UVIndex = "0";
  sensorValue = analogRead(A0);                             //connect UV sensor to Analog A0   
  int voltage = (sensorValue * (5.0 / 1023.0))*1000;        //Voltage in miliVolts
  
  if(voltage<50)
  {
    UVIndex = "0";
  }else if (voltage>50 && voltage<=227)
  {
    UVIndex = "0";
  }else if (voltage>227 && voltage<=318)
  {
    UVIndex = "1";
  }
  else if (voltage>318 && voltage<=408)
  {
    UVIndex = "2";
  }else if (voltage>408 && voltage<=503)
  {
    UVIndex = "3";
  }
  else if (voltage>503 && voltage<=606)
  {
    UVIndex = "4";
  }else if (voltage>606 && voltage<=696)
  {
    UVIndex = "5";
  }else if (voltage>696 && voltage<=795)
  {
    UVIndex = "6";
  }else if (voltage>795 && voltage<=881)
  {
    UVIndex = "7";
  }
  else if (voltage>881 && voltage<=976)
  {
    UVIndex = "8";
  }
  else if (voltage>976 && voltage<=1079)
  {
    UVIndex = "9";
  }
  else if (voltage>1079 && voltage<=1170)
  {
    UVIndex = "10";
  }else if (voltage>1170)
  {
  
    UVIndex = "11";
  }
  return UVIndex;
}

That sketch is very odd. You spend a lot of effort in the main loop() working out "UVIndex" and then you never use it for anything. The only thing you send to the LCD is sensorvalue and you send that every time round loop().

I have a feeling that all that UVIndex stuff should be in separate function (in which case the "return UVIndex") would make more sense). Then perhaps the result from that function should be on the LCD...but it's a bit difficult to see what on earth you were intending.

Steve

Hi slipstick.

Thanks for responding, my intention is to display the UV index on the LCD screen, so i do i read the sensor ?

Regards

Ray

Sorry I have no idea what "so i do i read the sensor?" means.

Did you write this code yourself or cut and paste it from somewhere? If so, where? Generally if you want to display a variable UVIndex then it should appear in an lcd.print somewhere. It doesn't.

Steve

So, first i would slow your loop down so you can see what is on the lcd.

You send the raw count value from the ADC to the LCD. Does that count value look correct to you?

Your resolution is not good. Your uv index from 0 to 9 is 234 counts out of a possibliity of 1023. So I would
try to change your reference voltage to 2.5volts instead of 5.

lcd.println(sensorValue);

The LiquidCrystal library does not support the println() function. Thus the strange characters (CR/LF). Use lcd.print().

Hi groundFungus.

I did as you suggested and altered the lcd.printin(sensorValue)) to lcd.print(sensorValue); and the screen changed, i have uploaded another j peg with the difference to the first j peg.

Ray

Hi noweare.

How do i slow done the Loop ?

I have lowered the reference voltage to 2.5 as you suggested, it made no difference.

I am not sure what you mean by "You send the raw count value from the ADC to the LCD. Does that count value look correct to you?"

The input from the sensor is on pin A0, the lcd readout is on the Jpegs i have uploaded, they look wrong to me.

Ray

How do i slow done the Loop ?

Temporarily insert delay()s to slow execution.

I have lowered the reference voltage to 2.5 as you suggested, it made no difference.
Did you set analogReference() to external? Pay attention to this warning:

If you’re using an external reference on the AREF pin, you must set the analog reference to EXTERNAL before calling analogRead().

I am not sure what you mean by "You send the raw count value from the ADC to the LCD. Does that count value look correct to you?"

lcd.print(analogRead(A0));

When you make changes to your code, please post the revised code so that we all remain "on the same page". Can't comment further till I see the new version of the code.

Hi groundFungus,

I have inserted lcd.print(analogRead(A0)); as you requested still no difference to the display read out.

Am i right in saying your reference to analogReference is the voltage the sensor sends to pin A0, If yes, please advise how to alter my sketch.

I have uploaded my up to date sketch for your perusal.

Ray

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity


int analogPin = A0;     // UV Sensor (middle pin) connected to analog pin A0
                       
int val = 0; 

void setup()
{
   
lcd.begin(20,4);
lcd.backlight();
lcd.setCursor(0,0 );        //Third column, first row
lcd.print("UV INDEX :");
lcd.setCursor(10,0 ); 
lcd.print(analogRead(A0));

delay (2000);               //delay 2 seconds

}

void loop() {

  double index_act = 0.0, press_act = 0.0,hum_act=0.0;
  signed long int temp_cal;

  val = analogRead(analogPin);     // read the input pin
  Serial.println(val);             // debug value
  
  int sensorValue;
  sensorValue = analogRead(A0);   //connect UV sensors to Analog A0    
  lcd.print(sensorValue);       //print the value to serial  
  
  delay(2000);      

 
  String readSensor();
  String UVIndex = "0";
  sensorValue = analogRead(A0);                             //connect UV sensor to Analog A0   
  int voltage = (sensorValue * (2.5 / 1023.0))*1000;        //Voltage in miliVolts
  
  if(voltage<50)
  {
    UVIndex = "0";
  }else if (voltage>50 && voltage<=227)
  {
    UVIndex = "0";
  }else if (voltage>227 && voltage<=318)
  {
    UVIndex = "1";
  }
  else if (voltage>318 && voltage<=408)
  {
    UVIndex = "2";
  }else if (voltage>408 && voltage<=503)
  {
    UVIndex = "3";
  }
  else if (voltage>503 && voltage<=606)
  {
    UVIndex = "4";
  }else if (voltage>606 && voltage<=696)
  {
    UVIndex = "5";
  }else if (voltage>696 && voltage<=795)
  {
    UVIndex = "6";
  }else if (voltage>795 && voltage<=881)
  {
    UVIndex = "7";
  }
  else if (voltage>881 && voltage<=976)
  {
    UVIndex = "8";
  }
  else if (voltage>976 && voltage<=1079)
  {
    UVIndex = "9";
  }
  else if (voltage>1079 && voltage<=1170)
  {
    UVIndex = "10";
  }else if (voltage>1170)
  {
   UVIndex = "11";
  }
  return UVIndex;


}

I have inserted lcd.print(analogRead(A0)); as you requested still no difference to the display read out.

I beg to differ. In the photo in post #1 there are characters with 4 horizontal lines. Those are the CR and LF characters as represented by the LCD. Those characters are not present in the photo in post #6.

There are several things wrong with the code.
slipstick pointed out that "String readSensor()" should be a function (that is called from loop).

This demonstrates the readSensor() function. I could not test with an LCD but it should work. To watch the serial prints in serial monitor, make sure to set the baud rate to 115200.

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity


int analogPin = A0;     // UV Sensor (middle pin) connected to analog pin A0

void setup()
{
   Serial.begin(115200);
   lcd.begin(20, 4);
   lcd.backlight();
   lcd.setCursor(0, 0 );       //Third column, first row
   lcd.print("UV INDEX :");
   lcd.setCursor(10, 0 );
   lcd.print(analogRead(A0));
   delay (2000);              //delay 2 seconds

}

void loop()
{ 
   String val = readSensor();
   Serial.print("UV Index is ");
   Serial.println(val);
   lcd.clear();
   lcd.print("UV INDEX : ");
   lcd.print(val); 
   delay(2000);
}

String readSensor()
{
   String UVIndex = "0";
   int sensorValue = analogRead(A0);                             //connect UV sensor to Analog A0
   int voltage = (sensorValue * (2.5 / 1023.0)) * 1000;      //Voltage in miliVolts
   Serial.print("raw sensorValue  ");
   Serial.print(sensorValue);
   Serial.print("   voltage  ");
   Serial.println(voltage);
   if (voltage < 50)
   {
      UVIndex = "0";
   }
   else if (voltage > 50 && voltage <= 227)
   {
      UVIndex = "0";
   }
   else if (voltage > 227 && voltage <= 318)
   {
      UVIndex = "1";
   }
   else if (voltage > 318 && voltage <= 408)
   {
      UVIndex = "2";
   }
   else if (voltage > 408 && voltage <= 503)
   {
      UVIndex = "3";
   }
   else if (voltage > 503 && voltage <= 606)
   {
      UVIndex = "4";
   }
   else if (voltage > 606 && voltage <= 696)
   {
      UVIndex = "5";
   }
   else if (voltage > 696 && voltage <= 795)
   {
      UVIndex = "6";
   }
   else if (voltage > 795 && voltage <= 881)
   {
      UVIndex = "7";
   }
   else if (voltage > 881 && voltage <= 976)
   {
      UVIndex = "8";
   }
   else if (voltage > 976 && voltage <= 1079)
   {
      UVIndex = "9";
   }
   else if (voltage > 1079 && voltage <= 1170)
   {
      UVIndex = "10";
   }
   else if (voltage > 1170)
   {
      UVIndex = "11";
   }
   return UVIndex;


}

Hi groundFungus.

Thanks for the sketch, it seems to work perfectly, i have take my sensor outside and the reading is 2, the reading is stable now, no scrolling.

I have checked my local Meteorology web site, and they say the UV index is in deed level 2, many thanks for your guidance, patients and understanding.

May i pick your brains again, the sketch you gave me works in the serial monitor and on my LCD, now i want the UV Index on line 3, but i do not seem to be able to move it there, where should i alter where it reads on the LCD?

Regards

Ray

   lcd.clear();
   lcd.setCursor(0, 2);
   lcd.print("UV INDEX : ");
   lcd.print(val);

The lcd.setCursor() function.

And here is the reference for the LiquidCrystal library.

Hi again groundFungus.

One last question (i hope) everything was great until i went for a cup of coffee, when i returned i ran my sketch again, now i have another error, i have uploaded it, will you take a look please, i think it may be
the library i am using, the error is "Positive" was not declared in this scope, would i be right, library was downloaded from github

Arduino: 1.8.5 (Windows 7), Board: "Arduino/Genuino Uno"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\dell\Documents\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\dell\Documents\Arduino\libraries -fqbn=arduino:avr:uno -ide-version=10805 -build-path C:\Users\dell\AppData\Local\Temp\arduino_build_569622 -warnings=none -build-cache C:\Users\dell\AppData\Local\Temp\arduino_cache_385405 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\dell\Documents\Arduino\sketch_uvokrhs\sketch_uvokrhs.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\dell\Documents\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\dell\Documents\Arduino\libraries -fqbn=arduino:avr:uno -ide-version=10805 -build-path C:\Users\dell\AppData\Local\Temp\arduino_build_569622 -warnings=none -build-cache C:\Users\dell\AppData\Local\Temp\arduino_cache_385405 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\dell\Documents\Arduino\sketch_uvokrhs\sketch_uvokrhs.ino
Using board 'uno' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Using core 'arduino' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Detecting libraries used...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "C:\Users\dell\AppData\Local\Temp\arduino_build_569622\sketch\sketch_uvokrhs.ino.cpp" -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src" "C:\Users\dell\AppData\Local\Temp\arduino_build_569622\sketch\sketch_uvokrhs.ino.cpp" -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src" "-IC:\Users\dell\Documents\Arduino\libraries\LiquidCrystal_I2C-master" "C:\Users\dell\AppData\Local\Temp\arduino_build_569622\sketch\sketch_uvokrhs.ino.cpp" -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src" "-IC:\Users\dell\Documents\Arduino\libraries\LiquidCrystal_I2C-master" "C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\Wire.cpp" -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src" "-IC:\Users\dell\Documents\Arduino\libraries\LiquidCrystal_I2C-master" "C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c" -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src" "-IC:\Users\dell\Documents\Arduino\libraries\LiquidCrystal_I2C-master" "C:\Users\dell\Documents\Arduino\libraries\LiquidCrystal_I2C-master\LiquidCrystal_I2C.cpp" -o "nul"
Generating function prototypes...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src" "-IC:\Users\dell\Documents\Arduino\libraries\LiquidCrystal_I2C-master" "C:\Users\dell\AppData\Local\Temp\arduino_build_569622\sketch\sketch_uvokrhs.ino.cpp" -o "C:\Users\dell\AppData\Local\Temp\arduino_build_569622\preproc\ctags_target_for_gcc_minus_e.cpp"
"C:\Program Files (x86)\Arduino\tools-builder\ctags\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\Users\dell\AppData\Local\Temp\arduino_build_569622\preproc\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src" "-IC:\Users\dell\Documents\Arduino\libraries\LiquidCrystal_I2C-master" "C:\Users\dell\AppData\Local\Temp\arduino_build_569622\sketch\sketch_uvokrhs.ino.cpp" -o "C:\Users\dell\AppData\Local\Temp\arduino_build_569622\sketch\sketch_uvokrhs.ino.cpp.o"
sketch_uvokrhs:6: error: 'POSITIVE' was not declared in this scope

 LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity

                                                     ^

Using library Wire at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire 
Using library LiquidCrystal_I2C-master at version 1.1.4 in folder: C:\Users\dell\Documents\Arduino\libraries\LiquidCrystal_I2C-master 
exit status 1
'POSITIVE' was not declared in this scope

It was working before? What did you change? Look at the examples that come with the Liquidcrystal library that you are using. What is the constructor syntax?

There are several libraries named LiquidCrystal and they are not all the same so you have to be mindful of the syntax.

I have been using the hd44780 library. It is actually easier to use and has some nice features like auto address and I2C expander wiring detection. And there is only one named hd44780, so no confusion. Use the hd44780_I2Cexp class for your lcd. Plenty of examples and the wiki has lots of information.