// https://forum.arduino.cc/t/loop-development-for-dac/967224/20
//Based on YWROBOT's LiquidCrystal_I2C library, Library version:1.1
//Also based on the Debounce.ino sketch that comes with Arduino IDE
#include <Wire.h> // Companion for I2C
#include <LiquidCrystal_I2C.h> //I2C library for LCD
//#include <Adafruit_MCP4725.h> // MCP4725 library from adafruit
// Rotary Encoder Inputs
#define CLK 13
#define DT 12
#define SW 11
// set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
//Intialize DAC
//Adafruit_MCP4725 MCP4725;
int C_select;
int WhichScreen = 1; // This variable stores the current Screen number
boolean hasChanged = true;
const int buttonPin = 11; // the number of the pushbutton pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
float I_Act; //Will be used as analog read from Current sense resistor.
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir = "";
unsigned long lastButtonPress = 0;
int csele;
float I_Set;
float I_Set_previous;
float dac_volt;
int dac_ADC;
//Current (A) setpoints array options
float cur_opt[] = {0, 0.25, 0.5, 0.75,
1, 1.25, 1.5, 1.75,
2, 2.25, 2.5, 2.75,
3, 3.25, 3.5, 3.75,
4, 4.25, 4.5, 4.75,
5, 5.25, 5.5, 5.75,
6, 6.25, 6.5, 6.75,
7, 7.25, 7.5, 7.75, 8
};
void setup()
{
// Setup Serial Monitor
Serial.begin(9600);
Serial.println("Hello loopDAC World!\n");
// intialize MCP4725 DAC
// MCP4725.begin(0x60);
//Normalizes I_Set
I_Set = I_Set_previous;
//0-5 V = 0-8 A. 5/8 = 0.625 V/A
dac_volt = (0.625 * I_Set);
dac_ADC = (4096.0 / 5) * dac_volt; // ***
// Set encoder pins as inputs
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
// Read the initial state of CLK
lastStateCLK = digitalRead(CLK);
// initialize Current set and Current actual
I_Set = 0;
I_Act = 1; // Will change into mV / A from current sense resistor.
// initialize the LCD
lcd.init();
lcd.backlight();
pinMode(buttonPin, INPUT_PULLUP); // ***
//Boot screen (Happens on startup)
lcd.clear();
lcd.setCursor(0, 0); // Column, line
lcd.print("LP fiber laser!");
lcd.setCursor(0, 1); // Column, line
lcd.print("Booting up...");
delay(3000);
lcd.clear();
WhichScreen = 0;
}
void loop() {
if (hasChanged == true) {
switch (WhichScreen) {
case 1:
{
firstScreen();
}
break;
case 2:
{
secondScreen();
}
break;
case 0:
{
}
break;
}
}
//-------------------------------
// BEGIN of the switch debouncing code
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
hasChanged = true;
WhichScreen++;
}
} else {
hasChanged = false;
}
}
lastButtonState = reading;
// END of the switch Debouncing code
// --------------------------------------
if (WhichScreen > 2) {
WhichScreen = 1;
}
}
void firstScreen() //Main function. Displays current set / current actual. Click rotary to set current
{
lcd.clear();
lcd.setCursor(0, 0); // Column, line
lcd.print(" I_Set: ");
lcd.setCursor(10, 0);
lcd.print(I_Set);
lcd.setCursor(0, 1);
lcd.print(" I_Act: ");
lcd.setCursor(10, 1);
lcd.print(I_Act);
}
//Second screen = Adjust current (A) function. Displays current set / current actual.
//Spin to Adjust - auto updates. Click to confrim. MCP only chages on click.
void secondScreen()
{
lcd.clear();
lcd.setCursor(0, 0); // Column, line
lcd.print(" Set current:");
lcd.setCursor(0, 1); // Column, line
lcd.print(" I_Set: ");
lcd.setCursor(10, 1);
lcd.print(I_Set);
while (WhichScreen = 1) { //While loop to display current set as adjusted. Prevents MCP from setting voltage until break
// Read the current state of CLK
currentStateCLK = digitalRead(CLK);
// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK != lastStateCLK && currentStateCLK == 1) {
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK) {
counter ++;
currentDir = "CW";
} else {
// Encoder is rotating CW so increment
counter --;
currentDir = "CCW";
}
//Perhaps unecessary
csele = counter;
//Current select Array
I_Set = cur_opt[csele];
//0-8 A I set = 0-5 V V_in.
dac_volt = (0.625) * I_Set;
//ADC to volts
dac_ADC = (4096.0 / 5) * dac_volt; // ***
if (counter < 0) {
counter = 0, I_Set = 0, csele = 0;
}
if (counter > 31) {
counter = 31, I_Set = 8.00, csele = 32;
delay (100);
}
//Serial debug
Serial.println("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);
Serial.print("I_Set:");
Serial.println(I_Set);
Serial.print("Csele:");
Serial.println(csele);
Serial.println("dac_volt");
Serial.println((dac_volt));
Serial.println("dac_ADC");
Serial.println((dac_ADC));
//update current select
lcd.clear();
lcd.setCursor(0, 0); // Column, line
lcd.print(" Set current:");
lcd.setCursor(0, 1); // Column, line
lcd.print(" I_Set: ");
lcd.setCursor(10, 1);
lcd.print(I_Set);
}
// Remember last CLK state
lastStateCLK = currentStateCLK;
// Read the button state
int btnState = digitalRead(SW);
//If we detect LOW signal, button is pressed
if (btnState == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
//intiate check for MCP coltage set.
if (millis() - lastButtonPress > 50) {
// *** Serial.println("Button pressed!");
// *** delay(100);
if (I_Set_previous != I_Set) {
// MCP4725.setVoltage(dac_ADC, false);
Serial.print(dac_ADC); Serial.println(" false setVoltage to MCP");
I_Set_previous = I_Set;
WhichScreen = 1;
//Serial debug for loop.
Serial.println("End While");
}
// Remember last button press event
lastButtonPress = millis();
if (WhichScreen = 1) { //if statement may be unecessary. Break on click instead.
break;
}
}
// Put in a slight delay to help debounce the reading
delay(1);
}
}
WhichScreen = 1;
}