I have written a program that works until I output a value to a LCD,
#include <LiquidCrystal.h>
int sensorPin = A0; // select the input pin for the potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor
int led_pin=6;
LiquidCrystal lcd(8, 7, 5, 4, 3, 2);
I am using an Arduino Nano and a standard 16:2 LCD, My output goes through a transistor as the voltage and current is too high for the arduino to deal with it on it's own. the LED output method is the only way I have found to output a pwm at 100hz.
I expect that the LCD operations are interfering with your timing. I doubt that you can read anything on the display anyway with that refresh rate. Try using millis to refresh the display at a less frequent interval, perhaps once a second.
The LiquidCrystal libraries that I know of need a lcd.begin(row, col) to work. Which library are you using?
Read the how to use this forum-please read sticky to see how to properly post code. Remove useless white space and format the code with the IDE autoformat tool (crtl-t or Tools, Auto Format) before posting code.
I am reading a analog pin for a pressure sensor,
outputing a PWM at 100hz for a motor speed control
I wish to display the pressure and PWM speed (ie 80%... 90% etc)
any ideas how best to accomplish this?
yes the LCD refresh rate is to high and it interferes with the PWM frequency which stops the motor from running.
You can use a hardware PWM timer to generate the PWM independent of things happening in the code.
In the example below, I set up timer 1 to generate a PWM of 244Hz (basically achieved with a CLKio of 16MHz /256 prescaler). Using Fast PWM mode, I use an output compare so the hardware toggles the OC1A pin. On my MEGA 2560 this is pin '11'; on the Nano I think it's pin 12.
This will give a pretty smooth PWM versus your stepped code. Does it need to be stepped or is "continuous" okay?
You code appears to constrain the PWM from ~10Hz to ~90% so I added that as well.
The millis() timing is setup to sample the ADC channel every 20mS (50Hz) and to update the LCD every 500mS (2Hz). I don't really see the need to update the LCD faster than this. One time saver that you might note is that the screen needn't be cleared every update and the "Sensor Value" string needn't be re-printed. I use the sprintf() method to format the output string though you don't need to do that (adding sprintf() adds to the code size; if you're space sensitive you can use another method.)
#include <LiquidCrystal.h>
#define ADC_MAX 1023
#define SAMPLE_PERIOD 20ul
#define LCD_UPDATE_PER 500ul
uint16_t
adcValue,
cadcValue,
pwmValue;
uint8_t
sensorPin = A0,
ledPin = 11;
uint32_t
timeSample,
timeLCD,
timeNow;
char
szStr[10];
LiquidCrystal
lcd(8, 7, 5, 4, 3, 2);
void setup()
{
pinMode( sensorPin, INPUT );
pinMode( ledPin, OUTPUT );
TCCR1A = (1 << COM1A1) | (1 << WGM11) | (1 << WGM10 ); // set up OC1A pin to set on BOTTOM; waveform generator mode 7
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // prescaler 16MHz/256 or 250kHz; gives ~244Hz PWM
OCR1A = 0x0000; // initialize output compare to zero
//initialize screen
lcd.clear();
lcd.setCursor( 0, 0 );
lcd.print("Sensor Value:");
//initialize timers
timeSample = millis();
timeLCD = timeSample;
}//setup
void loop()
{
//get current millis count
timeNow = millis();
//time for a sensor reading update?
if( (timeNow - timeSample) >= SAMPLE_PERIOD )
{
//yes; set up to time the next ADC sample
timeSample = timeNow;
//read the ADC; OP wants low readings -> high duty cycle
adcValue = analogRead(sensorPin);
cadcValue = constrain( (ADC_MAX - adcValue), 10, 920 );
//write constrained value to OCR1A to set new duty cycle
OCR1A = cadcValue;
}//if
//time for an LCD update?
if( (timeNow - timeLCD) >= LCD_UPDATE_PER )
{
//yes; set up to time next LCD update
timeLCD = timeNow;
//for a simple string 4-characters wide to be filled with " 0" to "1023"; raw value is used (not constrained)
sprintf( szStr, "%4d", adcValue );
//set cursor to second line, under "Sensor Value:" and print value there
lcd.setCursor( 0, 1 );
lcd.print( szStr );
}//if
}//loop