Hi everyone. I have a project that I am working on that works as follows:
When started the leds light to check if they work.
I am using an OLED instead of termimnal to display messages, to check the code works properly.
When connected to WiFi and the MQTT broker the Blue LED lights.
I send a number between 1 and 5 via mqtt from my phone to a broker.
The ESP32 running arduino is a client, listening to the topic "Jumps".
When the message is recieved the stepper motor moves to one of 5 positions.
When the stepper reaches its position. the height is recorded into non volatile memory.
The battery level is checked and the appropriate LED turns on.
The part that I cant figure out is I want to push a button within a time frame at the start to recalibrate the lowest height if needed. It seems to see the delay but dosent go to the calibrate() function. There is a yellow led to turn on if it makes it to the function.The rest I have been able to figure out by looking at lots of tutorials. Can anyone see what i havent done properly?
Also I am sure that the code is probably not as efficient as it could be, so any suggestions to make it better would be appreciated.
Here is the code:
#include <EEPROM.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//SDA -> D21
//SCL -> D22
#define EEPROM_SIZE 1
// ***************************** Set ADC pin for battery health *****
const int Analog_channel_pin= 32;
//********************************Buttons ***************************************
const int buttn7 = 4;
const int buttn6 = 2;
const int buttn5 = 15;
const int buttn4 = 35;
const int buttn3 = 34;
//const int buttn2 = 39;
//const int buttn1 = 36;
//************************************* LEDS ************************************
const int LedRed = 13;
const int LedYellow = 12;
const int LedBlue = 26;
const int LedGreen = 27;
//*************************************Stepper motor controller pins ************************
const int sleepPin = 19;
const int stepPin = 18;
const int dirPin = 5;
//************************************************ MQTT logon ***********************
const char* brokerUser = "BRKRUSR";
const char* brokerPass = "XXXXXXXX";
const char* broker = "XXX.XXX.XXX.XXX";
const char* mqTopic = "Jumps";
int heightStored;
int j;
int k;
//***************************************** Variables for handling large number of pulses**********
unsigned long int i;
unsigned long int heightActual = 1000;
unsigned long int heightMove = 0;
unsigned long int stepActual = 0;
unsigned long int heightVal = 0;
unsigned long startMillis = millis();
unsigned long elapsedMillis;
int adcVal = 0;
float voltVal = 0;
int setCal;
int direction = 0;
int LedBlink = 750;
int stepPulseTime = 350;
int buttnCalVal;
int upBttn;
LiquidCrystal_I2C lcd(0x27,16,2); // Set LCD screen parameters
WiFiClient espClient;
PubSubClient client(espClient);
//***********************************************************************************************************
void calibrate()
{
digitalWrite(LedYellow, HIGH); //check if function called ************************************
while (digitalRead(buttn7) == 1 || digitalRead(buttn5) == 1)
{
if (digitalRead(buttn7) == 0) // move up one pulse
{
direction == 0;
digitalWrite(stepPin, HIGH);
delayMicroseconds(stepPulseTime);
digitalWrite(stepPin, LOW);
delayMicroseconds(stepPulseTime);
}
if (digitalRead(buttn5) == 0) // move down one pulse
{
direction = 1;
digitalWrite(stepPin, HIGH);
delayMicroseconds(stepPulseTime);
digitalWrite(stepPin, LOW);
delayMicroseconds(stepPulseTime);
}
return;
}
}
//********************************************************************************************************************************************************************************
void setup()
{
pinMode(buttn7, INPUT_PULLUP);
pinMode(buttn6, INPUT_PULLUP);
pinMode(buttn5, INPUT_PULLUP);
pinMode(buttn4, INPUT_PULLUP);
pinMode(buttn3, INPUT_PULLUP);
//pinMode(buttn2, INPUT_PULLUP);
//pinMode(buttn1, INPUT_PULLUP);
pinMode(LedRed, OUTPUT);
pinMode(LedYellow, OUTPUT);
pinMode(LedBlue, OUTPUT);
pinMode(LedGreen, OUTPUT);
pinMode(sleepPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
//*********************************get previous stored value from non volatile memory *********
EEPROM.begin(EEPROM_SIZE);
//******************************** Set stepper driver pins *******************
digitalWrite(stepPin,0);
digitalWrite(dirPin,0);
digitalWrite(sleepPin, LOW); // only enable when ready to move to save power
//***************************** System check *******************************
digitalWrite(LedBlue, HIGH);
delay(LedBlink);
digitalWrite(LedBlue,LOW);
digitalWrite(LedGreen, HIGH);
delay(LedBlink);
digitalWrite(LedGreen,LOW);
digitalWrite(LedYellow, HIGH);
delay(LedBlink);
digitalWrite(LedYellow,LOW);
digitalWrite(LedRed, HIGH);
delay(LedBlink);
digitalWrite(LedRed,LOW);
//*********************************Start WiFi and LCD Screen ***********************************************
lcd.begin();
WiFi.disconnect();
delay(100);
// *********************************************************
// ******************************* detect button push for calibration
elapsedMillis = millis();
while(elapsedMillis < 8000)
{
lcd.setCursor(0, 0);
setCal = digitalRead(buttn7);
if(setCal == 0)
{
digitalWrite(LedRed, HIGH);
delay(2000);
digitalWrite(sleepPin, HIGH);
void calibrate();
}
elapsedMillis = millis();
digitalWrite(LedRed, LOW);
}
digitalWrite(LedRed, LOW);
digitalWrite(sleepPin, LOW);
lcd.clear();
adcVal = analogRead(Analog_channel_pin); // read voltage on analog pin
lcd.setCursor(0, 0);
lcd.print("Battery Voltage");
voltVal = (adcVal * 13.5) / (4095); // get battery voltage
lcd.setCursor(5, 1);
//lcd.print(adcVal); // get ADC Value
lcd.print(voltVal); // get voltage value
delay(1000);
lcd.clear();
//************************************* Turn on WiFi **********************
lcd.setCursor(5, 0);
lcd.print("START");
WiFi.begin("ROUTER","XXXX");
while ((!(WiFi.status() == WL_CONNECTED)))
{
delay(300);
}
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("CONNECTED");
lcd.setCursor(4, 1);
lcd.print("TO WIFI");
delay(1000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("YOUR IP IS:");
lcd.setCursor(1, 1);
lcd.print((WiFi.localIP()));
delay(1000);
lcd.clear();
client.setServer(broker,1883);
client.setCallback(callback);
}
void loop() //*************** Main loop to run MQTTsever *****
{
if (!client.connected())
{
reconnect();
}
client.loop();
}
void reconnect() // ******************MQTT initialisation *******
{
while(!client.connected())
{
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("CONNECT TO MQTT");
if(client.connect("jump1", brokerUser, brokerPass))
{
lcd.setCursor(4, 1);
lcd.print("CONNECTED");
client.subscribe(mqTopic);
digitalWrite(LedBlue, HIGH); //Turn on LED to signify online
}
else
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("CONNECTING...");
digitalWrite(LedBlue, LOW);
delay(1000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length)
{
payload[length] = '\0'; // Make payload a string by NULL terminating it.
int heightVal = atoi((char *)payload); //convert to variable
//***************** check previous position when shut down ***********
heightStored = EEPROM.read(0);
lcd.clear();
lcd.setCursor(4, 0);
lcd.print(heightStored); //Should be "MESSAGE" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
lcd.setCursor(4, 1);
//***************************************************** Set pulses to get correct height
lcd.print(heightVal);
if (heightVal == 1) {heightMove = 1000;}
if (heightVal == 2) {heightMove = 2000;}
if (heightVal == 3) {heightMove = 3000;}
if (heightVal == 4) {heightMove = 4000;}
if (heightVal == 5) {heightMove = 5000;}
if (heightStored == 1) {heightActual = 1000;}
if (heightStored == 2) {heightActual = 2000;}
if (heightStored == 3) {heightActual = 3000;}
if (heightStored == 4) {heightActual = 4000;}
if (heightStored == 5) {heightActual = 5000;}
if (heightMove > heightActual) // if its higher, go up
{
direction = 1;
stepActual = (heightMove - heightActual); // calculate how many steps to move between actual height of jump and new height
}
else
{
direction = 0; // if lower, go down
stepActual = (heightActual - heightMove); // calculate how many steps to move between actual height of jump and new height
}
if (heightMove == heightActual) // check if same as last height
{
loop(); // No movement. Back to loop
}
digitalWrite(sleepPin, HIGH); // only enable when ready to move to save power
delay(100);
digitalWrite(dirPin, direction);
for(i=1;i<stepActual;i++)
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(stepPulseTime);
digitalWrite(stepPin, LOW);
delayMicroseconds(stepPulseTime);
}
digitalWrite(sleepPin, LOW); // only enable when ready to move to save power
heightActual = heightMove;
EEPROM.write(0, heightVal); // change value in non volatile memory for shutdown
EEPROM.commit();
//*********************************************** Battery check *******************************
delay(100);
adcVal = analogRead(Analog_channel_pin);
if(adcVal > 3800)
{
digitalWrite(LedGreen, HIGH);
digitalWrite(LedYellow, LOW);
digitalWrite(LedRed, LOW);
}
else if(adcVal <= 3800 and adcVal > 3300)
{
digitalWrite(LedGreen, LOW);
digitalWrite(LedYellow, HIGH);
digitalWrite(LedRed, LOW);
}
else
{
digitalWrite(LedGreen, LOW);
digitalWrite(LedYellow, LOW);
digitalWrite(LedRed, HIGH);
}
}