185 lines
4 KiB
C++
185 lines
4 KiB
C++
#include <Arduino.h> /* Just in case of using the vscode ide for arduino programming, not needed if using the commom arduino ide */
|
|
#include <RotaryEncoder.h>
|
|
#include <IRremote.hpp> // library for the IR receiver
|
|
|
|
#define PPR 29
|
|
#define RPWM 5
|
|
#define LPWM 6
|
|
#define RIGHT false
|
|
#define LEFT true
|
|
|
|
/*
|
|
Pins connected to aduino
|
|
|
|
IBT-2 pin 1 (RPWM) to Arduino pin 5(PWM)
|
|
IBT-2 pin 2 (LPWM) to Arduino pin 6(PWM)
|
|
IBT-2 pins 3 (R_EN), 4 (L_EN), 7 (VCC) to Arduino 5V
|
|
IBT-2 pin 8 (GND) to Arduino's GND
|
|
IBT-2 pins 5 (R_IS) and 6 (L_IS) not connected
|
|
*/
|
|
|
|
// rotary encoder pins
|
|
//const int DT = 2;
|
|
//const int CLK = 3;
|
|
#define PIN_IN1 2
|
|
#define PIN_IN2 3
|
|
|
|
// potentiometer pin
|
|
const int pot = A0;
|
|
float vel = 30;
|
|
|
|
// declaration of encoder object
|
|
//RotaryEncoder encoder(DT, CLK, RotaryEncoder::LatchMode::TWO03);
|
|
RotaryEncoder *encoder = nullptr;
|
|
|
|
// variable to angle control
|
|
float angle = 0;
|
|
|
|
// ON/OFF codes
|
|
const int code1 = 0xAA1; // on
|
|
const int code2 = 0xAA2; // first sequence signal
|
|
const int code3 = 0xAA3; // second sequence signal
|
|
const int code4 = 0xAA4; // third sequence signal
|
|
const int code5 = 0xAA5; // second sequence signal
|
|
const int code6 = 0xAA6; // off
|
|
|
|
// IR receive parameters
|
|
const int IR = 9;
|
|
IRrecv IrReceiv(IR);
|
|
decode_results result;
|
|
int code = 0;//0xAA1;
|
|
|
|
void checkPosition()
|
|
{
|
|
encoder->tick(); // just call tick() to check the state.
|
|
}
|
|
|
|
void stopMotor() // function to stop the motor rotation
|
|
{
|
|
analogWrite(RPWM, 0);
|
|
analogWrite(LPWM, 0);
|
|
}
|
|
|
|
void turn(bool state, int speed)
|
|
{
|
|
if(state)
|
|
{
|
|
analogWrite(RPWM, speed);
|
|
analogWrite(LPWM, 0);
|
|
}
|
|
else
|
|
{
|
|
analogWrite(RPWM, 0);
|
|
analogWrite(LPWM, speed);
|
|
}
|
|
}
|
|
|
|
int turns = 0;
|
|
void getAngle() // printing data function
|
|
{
|
|
static int pos = 0;
|
|
encoder->tick();
|
|
int newPos = encoder->getPosition();
|
|
if (pos != newPos)
|
|
{
|
|
angle = ((float)newPos / PPR * 360);
|
|
Serial.print("Actual angle: ");
|
|
Serial.print(angle);
|
|
int turns = 0;
|
|
if (abs(angle)>=360)
|
|
{
|
|
turns = angle/360;
|
|
angle = angle - turns*360;
|
|
}
|
|
Serial.print(" Corrected angle: ");
|
|
Serial.print(angle);
|
|
Serial.print(" || Direction: ");
|
|
Serial.print((int)(encoder->getDirection()));
|
|
Serial.print(" || RPM: ");
|
|
Serial.println((int)(encoder->getRPM()));
|
|
pos = newPos;
|
|
}
|
|
}
|
|
|
|
bool moveTo(float target) // function to rotate the motor to specific angles
|
|
{
|
|
getAngle();
|
|
if((angle<=target+360/29)&&((angle>=target-360/29)))
|
|
{
|
|
stopMotor();
|
|
return false;
|
|
}
|
|
else if (angle < target)
|
|
{
|
|
analogWrite(LPWM, 0);
|
|
analogWrite(RPWM, vel); // right rotation
|
|
return true;
|
|
}
|
|
else if (angle > target)
|
|
{
|
|
analogWrite(RPWM, 0);
|
|
analogWrite(LPWM, vel); // left rotation
|
|
return true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void setup()
|
|
{
|
|
Serial.begin(9600);
|
|
IrReceiv.enableIRIn();
|
|
pinMode(RPWM, OUTPUT);
|
|
pinMode(LPWM, OUTPUT);
|
|
encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);
|
|
attachInterrupt(digitalPinToInterrupt(PIN_IN1), checkPosition, CHANGE);
|
|
attachInterrupt(digitalPinToInterrupt(PIN_IN2), checkPosition, CHANGE);
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
if (IrReceiv.decode(&result))
|
|
{
|
|
Serial.print(result.bits);
|
|
Serial.print(": ");
|
|
Serial.println(result.value, HEX);
|
|
IrReceiv.resume();
|
|
code = result.value;
|
|
}
|
|
switch (code)
|
|
{
|
|
case code1:
|
|
//stopMotor();
|
|
break;
|
|
case code2:
|
|
// 1st signal is received
|
|
//while (moveTo(-180));
|
|
while (moveTo(90));
|
|
//delay(1000);
|
|
break;
|
|
case code3:
|
|
// 2nd signal is received
|
|
turn(RIGHT, 20);
|
|
//delay(10000);
|
|
break;
|
|
case code4:
|
|
// 2nd signal is received
|
|
//turn(false);
|
|
//delay(20000);
|
|
break;
|
|
case code5:
|
|
// 2nd signal is received
|
|
while (moveTo(90));
|
|
//delay(20000);
|
|
break;
|
|
case code6:
|
|
// 4th signal is received, 4th signal is ignored
|
|
while (moveTo(180));
|
|
break;
|
|
default:
|
|
//stopMotor();
|
|
//Serial.println("ERROR");
|
|
break;
|
|
}
|
|
code = 0;//0xAA1;
|
|
//if (code<0xAA7) code++;
|
|
} |