Hello, I'm having an issue using an arduino Uno (circa 2007?) with a pair of 16x2 LCDs of different uncertain origins. neither has the little serial interface board.
I thought I'd make a little servo calibration device to that reads a potentiometer, calculates a number of microseconds for the servo motor pulse width, and then display it on the screen, so I could center the servos and write down the number. And it worked. Except that the code freezes after a few seconds. At first I thought maybe EMI from the servo was throwing something off, so I took out the servo, and then I moved to 8 bit mode instead of 4 bit mode. Neither helped. I had it also blink the built in LED, and that stops blinking at the same time as the LCD freezes, so it seems like the program is stopping.
I used a "MemoryFree" library I found to print out the free memory, which does not seem to change at all.
I'm a bit puzzled as to why it stops. I could use it like this I guess, by just pressing reset every few seconds, but I'd like to know what I've gotten wrong here.
////Libraries/////////////////////////////////////////////////////////
#include <LiquidCrystal.h> // includes the LiquidCrystal Library
#include <MemoryFree.h> //troubleshooting memory leak
//#include <Servo.h>
////Definitions/////////////////////////////////////////////////////////
//#define DEBUG 1
//const int lcd_rs = 2;
//const int lcd_en = 3;
//const int lcd_rw = 4;
const int rheostatPin = A0;
////Global variables/////////////////////////////////////////////////////////
int rheostatVal = 0;
int dutyMicros = 0;
int lastDutyMicros = 0;
int lastFrameMillis = 0;
int lastResetMillis = 0;
int frameDelay = 200; //how long between updating the screen and servos
int resetDelay = 1000; //how long between resetting the LCD
bool statusLED = false;
LiquidCrystal lcd(2, 4, 3, 5, 6, 7, 8, 9, 10, 11, 12);
// rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7
//Parameters:
//(rs, enable, d4, d5, d6, d7)
//(rs, rw, enable, d4, d5, d6, d7)
//(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
//(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
//in addition, A and VDD go to +5v, K and VSS go to gnd.
//V0 goes to the wiper of a potentiometer between 5v and ground, for setting LCD contrast.
//RW goes to ground if a mode that uses it hasn't been selected.
//Servo testservo;
////Setup/////////////////////////////////////////////////////////
void setup()
{
//pinMode(a0, INPUT); //not needed for analogRead();
Serial.begin(9600); //just for debugging
Serial.println("Serial Ready");
pinMode(LED_BUILTIN,OUTPUT);
lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display }
//testservo.attach(12); //attaches a servo at digital pin 9
//testservo.writeMicroseconds(1500); //nominal midpoint
delay(300);
}
////Main/////////////////////////////////////////////////////////
void loop()
{
rheostatVal = analogRead(rheostatPin); //read the potentiometer
dutyMicros = ServoMicroseconds(rheostatVal);
//so next we need to make a function that turns the potentiometer value into microseconds for the servo duty cycle
//and then we display that on the screen instead of the analog read value
//and then we write that to the servo.
if ( millis() >= (lastFrameMillis + frameDelay) ) //check if the value changed and if it's been at least 0.1 seconds
{
lcd.clear(); //clear the LCD
lcd.print(dutyMicros); //print the value
lastFrameMillis = millis(); //record the current millis()
lastDutyMicros = dutyMicros; //record the current read value
//Serial.println(dutyMicros);
}
//testservo.writeMicroseconds(dutyMicros);
if (millis() >= (lastResetMillis + resetDelay) )
{
lcd.begin(16,2);
//lcd.setCursor(0, 0);
Serial.println("resetting cursor");
statusLED = !statusLED;
digitalWrite(LED_BUILTIN, statusLED);
lastResetMillis = millis();
Serial.print("freeMemory()=");
Serial.println(freeMemory());
}
}
////functions/////////////////////////////////////////////////////////
int ServoMicroseconds(int a)
{
int m = -1;
m = map(a, 0, 1023, 475, 2550 ); //map(value, fromLow, fromHigh, toLow, toHigh)
return m;
}