Lab_interaccio/2023/Baleliteral/sculpture6/sculpture6.ino
2025-02-25 21:29:42 +01:00

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++;
}