Help with uno+stepper+relay+timer+menu+rotary encoder

Hello all

I am kind of new (noob) with arduino programing and i whant to try an ambitious project.

The project:

I want to build a Whashing + Curing station for SLA 3D Prints.

Objectives:

To have an OLED display and a Rotary encoder to be used on a menu that has 2 options:

-> Washing (stepper rotates at 100rpm, UV light is OFF)
-> 5 min
-> 10 min
-> 15 min
-> Curing (stepper rotates at 10rpm, UV light is ON)
-> 5 min
-> 10 min
-> 15 min

Hardware

  • Arduino Uno
  • Oled SH1106 1.3" display
  • Roraty encoder
  • Relay (to turn on the UV Light)
  • Stepper motor ( to turn the base )
  • Buzzer to alert when time is up
  • Switch on the door (to pause the timer when door is opened)

I have a small sketsh base on existing system tha boots up and has a counter, a button and a oled.
When you press the button the countdown starts (value is hardcoded to 15sec) and the relay is on.

It works for my intention but when i import the code for the stepper and run it, the display stays at 00:00 the relay turns on and the stepper turns on but it ignores the 15 sec timer (hard coded) and only stops after 30 sec and the when it stops, the display starts the countdown.

The code

#define name "Curing/Washing 1.0"

#define RelayPin 8        //Porta do Arduino que irá acionar o relé  
#define RelayLevel LOW   //Nivel lógico de ACIONAMENTO do relé

#define pinStartButton  7 //Porta do Arduino em que o botao Start esta ligado (o second terminal do botao deve ser ligado em GND)

#define ResetTime     2000  //define o time em que o botao Start deve ficar apertado para efetuar o reset (em miliseconds)
#define CounterValue  5    //define o time do counter (em seconds)

//*********************** Stepper motor *******************************************
#include <Stepper.h>

// Define number of steps per rotation:
const int stepsPerRevolution = 2048;

//LIBS
#include <Arduino.h>
#include <Wire.h>
#include <MicroLCD.h>
#include <TimerOne.h>
//OLED DISPLAY MICRO LCD CONFIG
LCD_SH1106 lcd; /* for SH1106 OLED module */ 
//LCD_SSD1306 lcd; /* for SSD1306 OLED module */  /* if SPI (CLK, DC, RST, CS) */

const PROGMEM uint8_t DOT[8 * 24 / 8] = {
0x00, 0xC0, 0xE0, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x81, 0xC3, 0xC3, 0xC3, 0x81, 0x00, 0x00,
0x00, 0x03, 0x07, 0x07, 0x07, 0x03, 0x00, 0x00  };
const PROGMEM uint8_t DOT_OFF[8 * 24 / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  };
const PROGMEM uint8_t DIGIT_OFF[20 * 24 / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  };
//********************* CONFIG STEPPER *****************
Stepper myStepper = Stepper(stepsPerRevolution, 2, 3, 4, 5);// Create stepper object called 'myStepper', note the pin order:
//GLOBAL FUNTIONS
byte StartButtonPressed();
void showDOT(bool Blink);
void showcounter();
void CountTime();
void stepper1();

//PUBLIC VARS
int time = CounterValue;
int counter = 0;
byte colcounter[4] = {28,46,72,90};
byte counterStatus = 0; //0=Pause, 1=Run
byte line = 11;

void setup()
{

  pinMode(RelayPin, OUTPUT);
  digitalWrite(RelayPin, !RelayLevel);

  pinMode(pinStartButton, INPUT_PULLUP);
   
	lcd.begin();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.setFontSize(FONT_SIZE_SMALL);
  lcd.print(name);

  //START TIMER
  
  Timer1.initialize(1000);   //TIMER WILL START AND RUN EVERY SECOND
  Timer1.attachInterrupt(CountTime); 
  // Begin Serial communication at a baud rate of 9600:
  Serial.begin(9600);
}
//***********************************************************************************************
void loop()
{

   if (counterStatus == 1) { 
      digitalWrite(RelayPin, RelayLevel);
      stepper1();

     } else {
      digitalWrite(RelayPin, !RelayLevel);
      
   }

   byte StartButtonStatus = StartButtonPressed();

   if ( StartButtonStatus == 1 ) {
        if (time > 0) {
         if (counterStatus == 0) {

           if (counter == 0) {
              counter = time;              
           }
            //START COUNT AGAIN
            Timer1.start();
            Timer1.attachInterrupt(CountTime);
            counterStatus = 1;       
         } else {
            //STOP COUNTER
            Timer1.stop();
            counterStatus = 0; 
         }
      }
   }
   if ( StartButtonStatus == 2 ) {
      #if EnableDebugSerial == true
        Serial.println("RESET");  
      #endif

      if (time > 0) {
         Timer1.stop();
         counterStatus = 0;  
         counter = 0;
      }
   }  
   showDOT(counterStatus); 
   showcounter();  
}

byte StartButtonPressed() {
   #define timeDebounce 50 //(time para eliminar o efeito Bounce EM MILIsecondS)

   static bool PrevButtonState; 
   static unsigned long ButtonDelay = 0;
   static unsigned long ButtonPressed;
   static byte fase = 0;

   bool ButtonStatus;
   byte ButtonNormal;

   ButtonNormal = 0;  
   if ( (millis() - ButtonDelay) > timeDebounce ) {
       ButtonStatus = digitalRead(pinStartButton);
       if ( !ButtonStatus && (ButtonStatus != PrevButtonState) ) {
          ButtonDelay = millis();          
          ButtonPressed = millis();
          fase = 1;
       } 

       if ( (fase == 1) && ((millis() - ButtonPressed) > ResetTime) ) {
          fase = 0;
          ButtonNormal = 2;
       }
       
       if ( ButtonStatus && (ButtonStatus != PrevButtonState) ) {
          ButtonDelay = millis();

          if ( fase == 1 ) {
             ButtonNormal = 1;
          } 
          fase = 0;
       } 
       
       PrevButtonState = ButtonStatus;
   }

   return ButtonNormal;
}

void showDOT(bool Blink) {
static bool BlinkAnt = !Blink;
static bool LED_On = true;
static bool LED_OnAnt = !LED_On;
static unsigned long delayBlink;
  #define timeBlink 500

  if (!Blink && BlinkAnt) {
     lcd.setCursor(64, line);
     lcd.draw(DOT, 8, 24);     
  }

  if (Blink) {
     if ( (millis() - delayBlink) < timeBlink) {
        LED_On = true;
    
     } else {
        LED_On = false;        
     }

     if ( (millis() - delayBlink) >= (timeBlink * 2)) {
        delayBlink = millis();
     }

     if (LED_On != LED_OnAnt) {
        if (LED_On) {               
          lcd.setCursor(64, line);
          lcd.draw(DOT, 8, 24); 
        } else {
          lcd.setCursor(64, line);
          lcd.draw(DOT_OFF, 8, 24);                 
        }
     }

     LED_OnAnt = LED_On;
     
  }

  BlinkAnt = Blink;
}


void showcounter() {
static bool LED_On = false;
static bool LED_OnAnt = !LED_On;
static int counterAnt = counter + 1;
static byte DigitsAnt[4] = {99,99,99,99};

int second;
int minute;
byte Digits[4];

  if (counter != counterAnt) {

     second = counter % 60;
     minute  = counter / 60; 
   
     Digits[0] = minute / 10;
     Digits[1] = minute % 10;
     Digits[2] = second / 10;
     Digits[3] = second % 10;

     for (int nL=0; nL < 4; nL++) {
       if ( DigitsAnt[nL] != Digits[nL] ) {
         lcd.setFontSize(FONT_SIZE_XLARGE);
         lcd.setCursor(colcounter[nL], line);
         lcd.printLong(Digits[nL]); 
           
       }

       DigitsAnt[nL] = Digits[nL];
     }
  }
  counterAnt = counter;
}

void CountTime() {
  if (counterStatus == 1) { 
     counter--;

     if (counter <= 0) {
        counter = 0;
        counterStatus = 0;
     }
  }
}

void stepper1 () {
  myStepper.setSpeed(22);

  myStepper.step(stepsPerRevolution);
  }

Is there anyone that can help me get this project of the groung ??

Thank you all

Xmodpt

What stepper motor and stepper motor driver are you using?

The standard stepper library may not be suitable as it blocks the Arduino until it completes a move. The AccelStepper library can do non-blocking moves.

I am not familiar with the Timer library so I have no idea whether it is suitable. I do all my timing using millis() as illustrated in Several Things at a Time. And see Using millis() for timing. A beginners guide if you need more explanation.

...R
Stepper Motor Basics

Hello m8

Thank you for your reply.

I am usin a Deeks Robot L293D Buy L293D - two-channel motor controller - 25V / Botland - Robotic Shop

I have all the bits needed, but in seperat files and i dont know how to put them to together.

I have a Menu file that works with the roraty encoder
I have the above file that works with the oled, timer and relay
i have other file for the workings of the stepper.

Thank you

Maybe have a look at Planning and Implementing a Program

...R

thank you for the help

now i am to control the correct amount of time the reley and stepper ar on but now the ldc does not update

lets say 00:05 for start... click the button and the relay and stepper starts and the display shows 00:04 then 00:02 and 00:00 and all stop.

any ideas?

NOTE: i have updated the code above to get it all in english.

Your timer.... is it counting in millis or micromillis? Because 1 second in millis is 1000 not 1000000

timer 1 is in millis ... when i pasted the code for some reason i got more "000" then it should.

  Timer1.initialize(1000);   //TIMER WILL START AND RUN EVERY SECOND

now after some testing i reasilez that if i press strat the code "runs" (kind of, the displayed couter still doesn't work correctly) but if i press it agin to pause it doesn't Pause.

regards

const int stepsPerRevolution = 2048;

Are you trying to use a 28BYJ-48 stepper with an L293 driver?

nop i have the L293 driver working with my own stepper

I am usin a Deeks Robot L293D and it works

xmodpt:
nop i have the L293 driver working with my own stepper

You were asked back in reply #1, what stepper that is.

i did... so my bad ... i didn't the question then.. :frowning:

xmodpt:
i did... so my bad ... i didn't the question then.. :frowning:

What is preventing you now?