A range sensor is reading distances. Just with the serial monitor, it works great. Although, now I need to have it output readings on an LCD screen. (There is a slide switch that enables this function.)
It wasn't outputting a display for the LCD screen. So I tried putting a delay with millis() in there:
#include <LiquidCrystal.h>
#include <TimeLib.h>
/* LCD/menu */
#define ENCODER_INTERRUPT_PIN 2 // MUST keep pin 2.
#define ENCODER_B_PIN A0
#define BUTTON_PIN A1
#define LCD_ENABLE_PIN 13
#define LCD_RS_PIN 12
#define HEART_BEAT_PIN A15
#define LCD_D1 5 // New ↓
#define LCD_D2 4
#define LCD_D3 3
#define LCD_D4 7
unsigned long timeoutTime = 0; // this is set and compared to millis to see when the user last did something.
const int menuTimeout = 10000; // time to timeout in a menu when user doesn't do anything.
const int contrast = 20; // min. PWM value
unsigned long startMillis;
unsigned long currentMillis;
unsigned long currentMillisA;
unsigned long currentMillisD;
unsigned long currentMillis1;
const unsigned long period = 1000;
const byte txPin3 = 14;
const byte rxPin3 = 15;
const byte txPin2 = 16;
const byte rxPin2 = 17;
const byte pinAnalog = 42; // If high, reads voltage from A7.
const byte pinDigital = 44; // Reads and displays range.
const byte pinOneWire = 46; // Displays temp.
const byte oneWireBus = 31;
const byte pinAnalogW = 22; //
const byte pinDigitalW = 24; //
const byte pinOneWireW = 26; // ----------------
const byte doAnalogW = 28; // Sweeps voltage 0-5V to datalogger.
const byte doDigitalW = 30; // Emulates range.
const byte doOneWireW = 32; // Emulates temp.
volatile int diffFromParagon = 0;
volatile int inch = 0;
volatile int current_range_reading = -99;
volatile int incomingByte = 0; // for incoming serial data
// volatile https://forum.arduino.cc/index.php?topic=418692.0
LiquidCrystal lcd( 12, 13, 5, 4, 3, 7); // Arduino pins. Creates object.
// LCD:GND,5V(RS=2 en=3 11 12 13 14) 16=GND
void setup() {
startMillis = millis(); // Initial start time
Serial.begin(115200); // IMPORTANT: Set your serial monitor to this.
Serial1.begin(9600); // This is the baud rate needed for MaxBotics TTL sonar.
// RX1 pin 19
// LCD code:
pinMode(8,HIGH); // LCD pin 15: backlight (anode)
// pinMode(11,OUTPUT);
// analogWrite(11,700);
analogWrite(6,contrast); // PWM~ pins: 3,5,(6),9,10,11
lcd.begin(20, 4); // Creates LCD object.
// pinMode not needed for INPUT (default) operator
pinMode(doAnalogW, OUTPUT);
pinMode(doDigitalW, OUTPUT);
pinMode(doOneWireW, OUTPUT);
pinMode(15, OUTPUT);
pinMode(2, OUTPUT);
pinMode(pinAnalog, INPUT_PULLUP);
pinMode(pinDigital, INPUT_PULLUP);
pinMode(pinOneWire, INPUT_PULLUP);
pinMode(pinAnalogW, INPUT_PULLUP);
pinMode(pinDigitalW, INPUT_PULLUP);
pinMode(pinOneWireW, INPUT_PULLUP);
delay(1500); // For LCD screen to boot up.
lcd.setCursor(0, 0);
lcd.print("Welcome.");
lcd.setCursor(0, 1);
lcd.print("Ready, make choice");
lcd.setCursor(0, 2);
lcd.print("by flipping switch.");
lcd.setCursor(0, 3);
lcd.print("Flip back when done.");
}
void loop(){
byte digitalSelection = digitalRead(pinDigital); // 44
currentMillis = millis();
if(digitalSelection == HIGH)
digitalR();
}
void digitalR(){
lcd.clear();
if (Serial1.available() > 5) // Then at least one complete range, 6 characters long, is stored in the RX buffer.
{
int inByte = Serial1.read(); // Examine the first stored character and decide what to do.
if(inByte == 'R')
{
int thousands = (Serial1.read() - '0') * 1000; // Take and convert each range digit to human-readable integer format.
int hundreds = (Serial1.read() - '0') * 100;
int tens = (Serial1.read() - '0') * 10;
int units = (Serial1.read() - '0') * 1;
int cr = Serial1.read(); // Don't do anything with this, just clear it out of the buffer with the rest.
// Assemble the digits into the range integer.
current_range_reading = thousands + hundreds + tens + units;
if(current_range_reading <= 300) //This is the minimum reading for the HRXL MaxSonar WR 7380, not the actual distance
{
while(millis() < currentMillis + 500)
{
Serial.println("too close!");
lcd.print("too close!");
}
}
else if(current_range_reading >= 5000) //This is the max reading for the HRXL MaxSonar WR 7380, not the actual distance
{
while(millis() < currentMillis + 500)
{
Serial.println("too close!");
lcd.print("too close!");
}
}
else
{
while(millis() < currentMillis + 500)
{
Serial.print("Range (mm): ");
Serial.println(current_range_reading);
lcd.print("Range (mm): ");
lcd.println(current_range_reading);
}
}
}
}
}
Attached is a text document that includes the Serial Monitor's output. I had it run regularly (reading a good 764 mm) for two seconds. Then put my hand under the sensor (should have read "too close!") for two seconds. Then I took my hand away, and just got garbage readings for the next ten seconds. (So the text document is 14 seconds of reading.)
For a time, it says it's reading 3407 mm, 1040 mm and 3403 mm. Although, that's impossible; 764 mm is the max I have set up.
I think it's an issue with timing (using millis). But I don't know what to fix!
serialMonitor.txt (179 KB)