Hi there,
I am trying to make a roller blind using arduino nano and 28byj stepmotor with accelstepper library and ir remote.
Ir remote will use 4 buttons that will function as ;
- roll the blind up
- roll the blind down
- stop the roll up or down functions
- save the max and min positions and save the data to eeprom.
When i push the roll the blind up button, I also want to stop the motor while pressing the stop button. But it does not work. I need help on this.
Below is the code.
// Include the AccelStepper Library
#include <AccelStepper.h>
#include <EEPROM.h>
#include <IRremote.hpp>
// define constants for IR remote control buttons
#define DECODE_NEC
#define IR_RECEIVE_PIN 11
#define BUTTON_UP 0x7 //0xFFA857
#define BUTTON_DOWN 0x15 //0xFFE01F
#define BUTTON_SET 0x46 //0xFF629D
#define BUTTON_STOP 0x9 //0xFF906F
#define BUTTON_RESET 0x52 //0xFF4AB5
// Define IR sensor pins
#define IR_RECEIVE_PIN 11
// Define step constant
// Creates an instance
// Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
#define FULLSTEP 4
AccelStepper stepper(FULLSTEP, 2, 4, 3, 5);
bool moving = false;
// Define EEPROM addresses for storing maximum and minimum positions
#define EEPROM_ADDR_MAX_POSITION 50
#define EEPROM_ADDR_MIN_POSITION 0
// define variables for saving the maximum and minimum positions
unsigned long maxPos;
unsigned long minPos;
long testPos;
void(* resetFunc) (void) = 0;
void setup() {
Serial.begin(115200);
delay(100);
// set the maximum speed, acceleration factor,
// initial speed and the target position
stepper.setMaxSpeed(500.0);
stepper.setAcceleration(50.0);
stepper.setSpeed(200.0);
// Start the IR receiver
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
Serial.print(F("Ready to receive IR signals of protocols: "));
printActiveIRProtocols(&Serial);
maxPos = EEPROM_readlong(EEPROM_ADDR_MAX_POSITION);
minPos = EEPROM_readlong(EEPROM_ADDR_MIN_POSITION);
Serial.println("maxPos EEPROM: " + String(maxPos));
Serial.println("minPos EEPROM: " + String((minPos)));
testPos = -minPos;
Serial.println("testPos EEPROM: " + String((testPos)));
// check if the maximum position has been set
if (isnan(maxPos) | (maxPos == 0)) {
Serial.println("maxPos 0 ya da bilgi yok");
maxPos = 99999;
EEPROM_writelong(EEPROM_ADDR_MAX_POSITION, maxPos);
Serial.println("maxPos:" + String(maxPos));
}
// check if the minimum position has been set
if (isnan(minPos) | (minPos == 0)) {
Serial.println("minPos 0 ya da bilgi yok");
minPos = 99999;
EEPROM_writelong(EEPROM_ADDR_MIN_POSITION, minPos);
Serial.println("minPos:" + String(minPos));
}
}
void loop() {
receive_ir_data();
}
void receive_ir_data() {
// check if there is an IR code available
if (IrReceiver.decode()) {
/*
* Print a short summary of received data
*/
IrReceiver.printIRResultShort(&Serial);
IrReceiver.printIRSendUsage(&Serial);
if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
// We have an unknown protocol here, print more info
IrReceiver.printIRResultRawFormatted(&Serial, true);
}
Serial.println();
//IrReceiver.resume(); // Enable receiving of the next value
//Serial.println(stepper.currentPosition());
//Serial.println(minPos);
//Serial.println(maxPos);
// check which button was pressed on the remote
switch(IrReceiver.decodedIRData.command) {
case BUTTON_UP:
// move the roller blind up
if (stepper.currentPosition() < maxPos ) {
stepper.moveTo(maxPos);
while (stepper.distanceToGo() != 0) {
IrReceiver.resume();
Serial.println(String(IrReceiver.decodedIRData.command));
if (IrReceiver.decodedIRData.command == BUTTON_STOP) {
// Stop the stepper motor
stepper.stop();
break;
}
stepper.run();
}
stopPowerToCoils();
}
break;
case BUTTON_DOWN:
// move the roller blind down
if (stepper.currentPosition() > (testPos)) {
while (stepper.currentPosition() > (testPos)) {
Serial.println(stepper.currentPosition());
stepper.moveTo((testPos));
stepper.run();
}
stopPowerToCoils();
}
break;
case BUTTON_SET:
// set the maximum or minimum position
if (stepper.currentPosition() > (testPos)) {
maxPos = stepper.currentPosition();
EEPROM_writelong(EEPROM_ADDR_MAX_POSITION, maxPos);
} else {
minPos = stepper.currentPosition();
EEPROM_writelong(EEPROM_ADDR_MIN_POSITION, minPos);
}
stopPowerToCoils();
break;
case BUTTON_STOP:
Serial.println("Şu an durdum. Konumum : " + stepper.currentPosition());
stepper.stop();
stopPowerToCoils();
break;
case BUTTON_RESET:
minPos = 0;
maxPos = 0;
EEPROM_writelong(EEPROM_ADDR_MAX_POSITION, maxPos);
EEPROM_writelong(EEPROM_ADDR_MIN_POSITION, minPos);
Serial.println("Minpos " + String(minPos)+ "olarak ve MaxPos da " + String(maxPos) + "olarak ayarlandı.");
delay(1000) ;
resetFunc();
break;
}
// reset the IR receiver
Serial.println("reset the IR receiver");
IrReceiver.resume(); // Enable receiving of the next value
}
}
/**
Turn of power to coils whenever the blind
is not moving
*/
void stopPowerToCoils() {
Serial.println("stopPowerToCoils()");
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
// read double word from EEPROM, give starting address
unsigned long EEPROM_readlong(int address) {
//use word read function for reading upper part
unsigned long dword = EEPROM_readint(address);
//shift read word up
dword = dword << 16;
// read lower word from EEPROM and OR it into double word
dword = dword | EEPROM_readint(address+2);
return dword;
}
//write word to EEPROM
void EEPROM_writeint(int address, int value) {
EEPROM.write(address,highByte(value));
EEPROM.write(address+1 ,lowByte(value));
}
//write long integer into EEPROM
void EEPROM_writelong(int address, unsigned long value) {
//truncate upper part and write lower part into EEPROM
EEPROM_writeint(address+2, word(value));
//shift upper part down
value = value >> 16;
//truncate and write
EEPROM_writeint(address, word(value));
}
unsigned int EEPROM_readint(int address) {
unsigned int word = word(EEPROM.read(address), EEPROM.read(address+1));
return word;
}