#include "HD44780_LCD_PCF8574.h"
#include <Keypad.h>
// I2C LCD at address 0x27, 16 columns x 2 rows
HD44780LCD lcd(2, 16, 0x27, &Wire);
int finalTrialValue = 0; // Retain the final value globally
int trialValue = 0;
int userInput = 0; // Value input by user through keypad
// Shift register pins
const int latchPin = 10; // ST_CP (Latch Pin)
const int clockPin = 11; // SH_CP (Clock Pin)
const int dataPin = 12; // DS (Data Pin)
// Button pin
const int buttonPin = 2; // Push button connected to pin 2
const int buttonEnable = 3;
// Keypad setup
const byte ROW_NUM = 4; // four rows
const byte COLUMN_NUM = 3; // three columns
char keys[ROW_NUM][COLUMN_NUM] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte pin_rows[ROW_NUM] = {4, 5, 6, 7};
byte pin_column[COLUMN_NUM] = {8, 9, 13};
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );
// Store last displayed values to prevent unnecessary updates
int lastDisplayedVin = -1;
int lastDisplayedVout = -1;
void setup() {
lcd.PCF8574_LCDInit(lcd.LCDCursorTypeOff);
lcd.PCF8574_LCDClearScreen();
lcd.PCF8574_LCDBackLightSet(true);
lcd.PCF8574_LCDGOTO(lcd.LCDLineNumberTwo, 0);
lcd.PCF8574_LCDSendString("SAR ADC Demo");
Serial.begin(9600);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(buttonEnable, INPUT_PULLUP);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
shiftOutData(0); // Ensure LEDs are off initially
}
void loop() {
char key = keypad.getKey();
if (key) {
if (key >= '0' && key <= '9') {
userInput = userInput * 10 + (key - '0'); // Build the input number
} else if (key == '#') {
// Start simulation when "#" is pressed
finalTrialValue = sarApproximation(userInput); // Run SAR ADC simulation
} else if (key == '*') {
// Reset the user input when "*" is pressed
userInput = 0;
}
}
// Read and scale input value
int rawValue = userInput;
int scaledValue = rawValue;
// Only update Vin display if value has changed
if (scaledValue != lastDisplayedVin) {
char buffer[16];
sprintf(buffer, "Vin: %d", scaledValue);
lcd.PCF8574_LCDGOTO(lcd.LCDLineNumberOne, 0);
lcd.PCF8574_LCDSendString(" ");
lcd.PCF8574_LCDGOTO(lcd.LCDLineNumberOne, 0);
lcd.PCF8574_LCDSendString(buffer);
lastDisplayedVin = scaledValue;
}
// Start simulation if enabled
if (digitalRead(buttonEnable) == LOW) {
finalTrialValue = sarApproximation(trialValue); // Run SAR ADC simulation
}
// Display retained final value only if it has changed
if (finalTrialValue != lastDisplayedVout) {
char buffer[16];
sprintf(buffer, "Vout: %d", finalTrialValue);
lcd.PCF8574_LCDGOTO(lcd.LCDLineNumberTwo, 0);
lcd.PCF8574_LCDSendString(" ");
lcd.PCF8574_LCDGOTO(lcd.LCDLineNumberTwo, 0);
lcd.PCF8574_LCDSendString(buffer);
lastDisplayedVout = finalTrialValue;
}
delay(100); // Debounce delay
}
int sarApproximation(int rawValue) {
int scaledValue = rawValue; // Scale raw value to 8 bits (0–255)
int approxValue = 0; // Start approximation with 0
int finalStepValue = 0; // Variable to store the final trialValue
shiftOutData(0); // Clear Shift Register
// Wait for the enable button to start the simulation
while (digitalRead(buttonEnable) == LOW) {
for (int bit = 7; bit >= 0; bit--) {
int trialValue = approxValue | (1 << bit); // Try setting the current bit
shiftOutData(trialValue); // Show the current trial value on LEDs
delay(100); // Pause to demonstrate the step
int rawValue = userInput;
int scaledValue = rawValue;
char buffer[16];
sprintf(buffer, "Stp: %d Vref: %d", 8 - bit, trialValue);
lcd.PCF8574_LCDGOTO(lcd.LCDLineNumberTwo, 0);
lcd.PCF8574_LCDSendString(" "); // Clear the line
lcd.PCF8574_LCDGOTO(lcd.LCDLineNumberTwo, 0);
lcd.PCF8574_LCDSendString(buffer);
// Retain the current bit if the trialValue is valid
if (trialValue < scaledValue) {
approxValue = trialValue;
}
// Retain the final trialValue at the 8th step
if (bit == 0) {
finalStepValue = trialValue; // Save the 8th step trialValue
}
// Wait for button press to advance the next bit
while (digitalRead(buttonPin) == HIGH) {
// Wait for button to be pressed (LOW state)
}
delay(200); // Small debounce delay
}
}
return finalStepValue; // Return the final trial value from the 8th step
}
void shiftOutData(byte data) {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, data);
digitalWrite(latchPin, HIGH);
}(1) Vin გასაზომი ძაბვა.
(2) გაზომვის დაწყება (დააკლიკეთ ერთხელ)
(3) რვა ეტაპი (დააკლიკეთ რვაჯერ)
ორობითი სასინჯი კოდი
აკრიფეთ რიცხვი 0 დან 255 მდე და დააკლიკეთ #-ს.
დააკლიკეთ *-ს Vin-ის გასანულებლად.