okay so in my code i have a function called drawarea() that's moves two servos motor holding a Lazer pointer to draw and area.
i have also a lcd menu in this project and an encoder.
what i am experiencing: when the drawarea() function is running if i try and activate my interrupt function doencoder() by rotating the encoder nothing happens and the drawarea() function keeps running.
what i expect to happen: when the drawarea() function is active and i am rotating the encoder i will exit the drawarea function and will go to the doencoder() function.
this is my full code :
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h>
#include <Servo.h>
// all the servo stuff intelazing
Servo x_servo;
Servo y_servo;
int min_x = 40;
int max_x = 95;
int min_y = 106;//was 115
int max_y = 180;//was 180
int area=0;
int Play=0;
int min_freeze = 200;
int max_freeze = 3000;
float minimal_movement = 5;
int random_delay;
float x_position = min_x + (max_x - min_x)/2;
float y_position = min_y + (max_y - min_y)/2;
float x_old_position = x_position;
float y_old_position = y_position;
float x_new_position;
float y_new_position;
float x_speed;
float y_speed;
int movement_time;
// all the servo stuff intelazing
//all screen stuff
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//all screen stuff
// Define pins for the encoder
const int encoderPinA = 2;
const int encoderPinB = 3;
const int buttonPin =4 ;
const int lazser= 7;
//define pins
//menu stuff
int menuIndex = 0;
int minValue = 0;
int maxValue = 180;
int* menuItemValues[] = {&min_x, &max_x, &min_y, &max_y, &area, &Play};
//menu stuff
//rotarty stuff
volatile int valRotary, lastValRotary, encoder0Pos;
//rotarty stuff
void setup() {
y_servo.attach(10); // attaches the y servo on pin 10 to the servo object
x_servo.attach(9);
y_servo.write(y_position);
x_servo.write(x_position);
delay(1000);
Serial.begin(9600);
pinMode(encoderPinA, INPUT_PULLUP);
pinMode(encoderPinB, INPUT_PULLUP);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(lazser,OUTPUT);
digitalWrite(lazser, HIGH);
attachInterrupt(0, doEncoder, CHANGE);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);//init lcd
display.setTextSize(2);//init lcd
display.setTextColor(WHITE);//init lcd
display.display();
}
void loop() {
displayMenu();
MenuLogic();
}
void MenuLogic() {
if (valRotary != lastValRotary) {
if (menuIndex == 4 || menuIndex == 5) {
*menuItemValues[menuIndex] = (valRotary > lastValRotary) ? 1 : 0;
} else {
*menuItemValues[menuIndex] += valRotary - lastValRotary;
*menuItemValues[menuIndex] = constrain(*menuItemValues[menuIndex], minValue, maxValue);
}
displayMenu();
}
if (digitalRead(buttonPin) == LOW) {
menuIndex = (menuIndex + 1) % 6;
displayMenu();
delay(150);
}
if (1 == *menuItemValues[4] && menuIndex==4 ) {
drawArea();
*menuItemValues[4]=0;
}
if (1 == *menuItemValues[5] && menuIndex==5) {
play();
}
lastValRotary = valRotary;
}
void play()
{
generateRandomMovement();
adjustForSmallMovement(y_new_position, y_old_position);
adjustForSmallMovement(x_new_position, x_old_position);
x_speed = (x_new_position - x_old_position) / movement_time;
y_speed = (y_new_position - y_old_position) / movement_time;
for (int pos = 0; pos < movement_time; pos += 1)
{
x_position = x_position + x_speed;
y_position = y_position + y_speed;
x_servo.write(x_position);
y_servo.write(y_position);
delay(10);
}
x_old_position = x_new_position;
y_old_position = y_new_position;
delay(random_delay);
}
void generateRandomMovement() {
movement_time = random(10, 40);
random_delay = random(min_freeze, max_freeze);
x_new_position = random(min_x + minimal_movement, max_x - minimal_movement);
y_new_position = random(min_y + minimal_movement, max_y - minimal_movement);
}
void adjustForSmallMovement(float& newPos, float& oldPos) {
if (abs(newPos - oldPos) < 5) {
newPos += (newPos > oldPos) ? minimal_movement : -minimal_movement;
}
}
void drawArea() {
int adj_delay = 40; // Adjust the delay as needed
unsigned long previousMillis = 0; // Variable to store the last time the servo was updated
unsigned long interval = adj_delay; // Interval between servo updates
// Move the laser to the top-left corner of the square
y_servo.write(min_y);
int x = min_x;
while (x <= max_x) {
if (millis() - previousMillis >= interval) {
x_servo.write(x);
previousMillis = millis();
x++;
}
}
// Move the laser to the top-right corner of the square
x_servo.write(max_x);
int y = min_y;
while (y <= max_y) {
if (millis() - previousMillis >= interval) {
y_servo.write(y);
previousMillis = millis();
y++;
}
}
// Move the laser to the bottom-right corner of the square
y_servo.write(max_y);
x = max_x;
while (x >= min_x) {
if (millis() - previousMillis >= interval) {
x_servo.write(x);
previousMillis = millis();
x--;
}
}
// Move the laser to the bottom-left corner of the square
x_servo.write(min_x);
y = max_y;
while (y >= min_y) {
if (millis() - previousMillis >= interval) {
y_servo.write(y);
previousMillis = millis();
y--;
}
}
}
void displayMenu() {
display.clearDisplay();
display.setCursor(0, 0);
// Menu items 0 to 3: Min and Max Values
if (menuIndex == 0) {
display.print("Min_x:");
display.println(*menuItemValues[0]);
x_servo.write(*menuItemValues[0]);
}
if (menuIndex == 1) {
display.print("Max_x=");
display.println(*menuItemValues[1]);
x_servo.write(*menuItemValues[1]);
}
if (menuIndex == 2) {
display.print("min_y=");
display.println(*menuItemValues[2]);
y_servo.write(*menuItemValues[2]);
}
if (menuIndex == 3) {
display.print("Max_y=");
display.println(*menuItemValues[3]);
y_servo.write(*menuItemValues[3]);
}
if (menuIndex == 4) {
display.print("Area=");
display.println(*menuItemValues[4]);
}
if (menuIndex == 5) {
display.print("Play=");
display.println(*menuItemValues[5]);
}
display.display();
}
void doEncoder()
{
// unsigned long currentMillis = millis();
if (digitalRead(encoderPinA) == digitalRead(encoderPinB))
{
encoder0Pos++;
}
else
{
encoder0Pos--;
}
valRotary =- encoder0Pos/2.5;
if (valRotary<lastValRotary)
{
*menuItemValues[4]=0;
*menuItemValues[5]=0;
}
}